Add BCC support for rs_object_slots metadata.
This is added to support proper cleanup of RS resources. We were leaking some
global resources because there was no way to tell which slots to clear.
Change-Id: I3e01ff4f7105444b7610d514f10dd56cb1b359b8
b: 3381615
diff --git a/lib/bcc/CacheReader.cpp b/lib/bcc/CacheReader.cpp
index 387e094..a8e252b 100644
--- a/lib/bcc/CacheReader.cpp
+++ b/lib/bcc/CacheReader.cpp
@@ -80,6 +80,7 @@
&& readExportFuncList()
&& readPragmaList()
&& readFuncTable()
+ && readObjectSlotList()
&& readContext()
&& checkContext()
//&& readRelocationTable()
@@ -384,6 +385,13 @@
}
+bool CacheReader::readObjectSlotList() {
+ CACHE_READER_READ_SECTION(OBCC_ObjectSlotList,
+ mpResult->mpObjectSlotList, object_slot_list);
+ return true;
+}
+
+
bool CacheReader::readFuncTable() {
CACHE_READER_READ_SECTION(OBCC_FuncTable, mpFuncTable, func_table);
diff --git a/lib/bcc/CacheReader.h b/lib/bcc/CacheReader.h
index 3f052d0..e66503e 100644
--- a/lib/bcc/CacheReader.h
+++ b/lib/bcc/CacheReader.h
@@ -74,6 +74,7 @@
bool readExportFuncList();
bool readPragmaList();
bool readFuncTable();
+ bool readObjectSlotList();
bool readContext();
bool readRelocationTable();
diff --git a/lib/bcc/CacheWriter.cpp b/lib/bcc/CacheWriter.cpp
index 6d3a104..27ffd6d 100644
--- a/lib/bcc/CacheWriter.cpp
+++ b/lib/bcc/CacheWriter.cpp
@@ -47,6 +47,7 @@
CHECK_AND_FREE(mpExportFuncListSection);
CHECK_AND_FREE(mpPragmaListSection);
CHECK_AND_FREE(mpFuncTableSection);
+ CHECK_AND_FREE(mpObjectSlotSection);
#undef CHECK_AND_FREE
}
@@ -68,6 +69,7 @@
&& prepareStringPool()
&& prepareExportVarList()
&& prepareExportFuncList()
+ && prepareObjectSlotList()
&& calcSectionOffset()
&& calcContextChecksum()
&& writeAll()
@@ -307,6 +309,29 @@
}
+bool CacheWriter::prepareObjectSlotList() {
+ size_t objectSlotCount = mpOwner->getObjectSlotCount();
+
+ size_t listSize = sizeof(OBCC_ObjectSlotList) +
+ sizeof(uint32_t) * objectSlotCount;
+
+ OBCC_ObjectSlotList *list = (OBCC_ObjectSlotList *)malloc(listSize);
+
+ if (!list) {
+ LOGE("Unable to allocate for object slot list\n");
+ return false;
+ }
+
+ mpObjectSlotSection = list;
+ mpHeaderSection->object_slot_list_size = listSize;
+
+ list->count = objectSlotCount;
+
+ mpOwner->getObjectSlotList(objectSlotCount, list->object_slot_list);
+ return true;
+}
+
+
bool CacheWriter::calcSectionOffset() {
size_t offset = sizeof(OBCC_Header);
@@ -330,6 +355,7 @@
OFFSET_INCREASE(export_func_list);
OFFSET_INCREASE(pragma_list);
OFFSET_INCREASE(func_table);
+ OFFSET_INCREASE(object_slot_list);
#undef OFFSET_INCREASE
@@ -388,6 +414,7 @@
WRITE_SECTION_SIMPLE(export_func_list, mpExportFuncListSection);
WRITE_SECTION_SIMPLE(pragma_list, mpPragmaListSection);
WRITE_SECTION_SIMPLE(func_table, mpFuncTableSection);
+ WRITE_SECTION_SIMPLE(object_slot_list, mpObjectSlotSection);
WRITE_SECTION(context, mpHeaderSection->context_offset, BCC_CONTEXT_SIZE,
mpOwner->getContext());
diff --git a/lib/bcc/CacheWriter.h b/lib/bcc/CacheWriter.h
index b6d05f6..3e3f0af 100644
--- a/lib/bcc/CacheWriter.h
+++ b/lib/bcc/CacheWriter.h
@@ -48,13 +48,14 @@
OBCC_ExportFuncList *mpExportFuncListSection;
OBCC_PragmaList *mpPragmaListSection;
OBCC_FuncTable *mpFuncTableSection;
+ OBCC_ObjectSlotList *mpObjectSlotSection;
public:
CacheWriter()
: mpHeaderSection(NULL), mpStringPoolSection(NULL),
mpDependencyTableSection(NULL), mpExportVarListSection(NULL),
mpExportFuncListSection(NULL), mpPragmaListSection(NULL),
- mpFuncTableSection(NULL) {
+ mpFuncTableSection(NULL), mpObjectSlotSection(NULL) {
}
~CacheWriter();
@@ -78,6 +79,7 @@
bool prepareExportFuncList();
bool preparePragmaList();
bool prepareFuncTable();
+ bool prepareObjectSlotList();
bool writeAll();
diff --git a/lib/bcc/Compiler.cpp b/lib/bcc/Compiler.cpp
index 05fe017..c8d9eb4 100644
--- a/lib/bcc/Compiler.cpp
+++ b/lib/bcc/Compiler.cpp
@@ -84,18 +84,21 @@
std::vector<std::string> Compiler::Features;
-// The named of metadata node that pragma resides (should be synced with
+// Name of metadata node where pragma info resides (should be synced with
// slang.cpp)
const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
-// The named of metadata node that export variable name resides (should be
+// Name of metadata node where exported variable names reside (should be
// synced with slang_rs_metadata.h)
const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
-// The named of metadata node that export function name resides (should be
+// Name of metadata node where exported function names reside (should be
// synced with slang_rs_metadata.h)
const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
+// Name of metadata node where RS object slot info resides (should be
+// synced with slang_rs_metadata.h)
+const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
//////////////////////////////////////////////////////////////////////////////
// Compiler
@@ -319,6 +322,7 @@
const llvm::NamedMDNode *PragmaMetadata;
const llvm::NamedMDNode *ExportVarMetadata;
const llvm::NamedMDNode *ExportFuncMetadata;
+ const llvm::NamedMDNode *ObjectSlotMetadata;
if (mModule == NULL) // No module was loaded
return 0;
@@ -378,6 +382,7 @@
ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
+ ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
#if 0
mHasLinked = false;
@@ -613,6 +618,28 @@
}
}
+ if (ObjectSlotMetadata) {
+ ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
+
+ for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
+ llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
+ if (ObjectSlot != NULL &&
+ ObjectSlot->getNumOperands() == 1) {
+ llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
+ if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
+ llvm::StringRef Slot =
+ static_cast<llvm::MDString*>(SlotMDS)->getString();
+ uint32_t USlot = 0;
+ if (Slot.getAsInteger(10, USlot)) {
+ setError("Non-integer object slot value '" + Slot.str() + "'");
+ goto on_bcc_compile_error;
+ }
+ objectSlotList.push_back(USlot);
+ }
+ }
+ }
+ }
+
on_bcc_compile_error:
// LOGE("on_bcc_compiler_error");
if (CodeGenPasses) {
diff --git a/lib/bcc/Compiler.h b/lib/bcc/Compiler.h
index 5f3961c..b90c9e1 100644
--- a/lib/bcc/Compiler.h
+++ b/lib/bcc/Compiler.h
@@ -71,6 +71,7 @@
static const llvm::StringRef PragmaMetadataName;
static const llvm::StringRef ExportVarMetadataName;
static const llvm::StringRef ExportFuncMetadataName;
+ static const llvm::StringRef ObjectSlotMetadataName;
friend class CodeEmitter;
friend class CodeMemoryManager;
diff --git a/lib/bcc/Script.cpp b/lib/bcc/Script.cpp
index 74b4793..23e8f41 100644
--- a/lib/bcc/Script.cpp
+++ b/lib/bcc/Script.cpp
@@ -367,6 +367,17 @@
}
+size_t Script::getObjectSlotCount() const {
+ switch (mStatus) {
+ case ScriptStatus::Compiled: return mCompiled->getObjectSlotCount();
+#if USE_CACHE
+ case ScriptStatus::Cached: return mCached->getObjectSlotCount();
+#endif
+ default: return 0;
+ }
+}
+
+
void Script::getExportVarList(size_t varListSize, void **varList) {
switch (mStatus) {
#define DELEGATE(STATUS) \
@@ -434,7 +445,7 @@
switch (mStatus) {
#define DELEGATE(STATUS) \
case ScriptStatus::STATUS: \
- m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList);
+ m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
break;
#if USE_CACHE
@@ -449,6 +460,28 @@
}
}
+
+void Script::getObjectSlotList(size_t objectSlotListSize,
+ uint32_t *objectSlotList) {
+ switch (mStatus) {
+#define DELEGATE(STATUS) \
+ case ScriptStatus::STATUS: \
+ m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
+ break;
+
+#if USE_CACHE
+ DELEGATE(Cached);
+#endif
+
+ DELEGATE(Compiled);
+#undef DELEGATE
+
+ default:
+ mErrorCode = BCC_INVALID_OPERATION;
+ }
+}
+
+
char *Script::getContext() {
switch (mStatus) {
#if USE_CACHE
diff --git a/lib/bcc/Script.h b/lib/bcc/Script.h
index a5ba058..64e4803 100644
--- a/lib/bcc/Script.h
+++ b/lib/bcc/Script.h
@@ -114,6 +114,7 @@
size_t getFuncCount() const;
+ size_t getObjectSlotCount() const;
void getExportVarList(size_t size, void **list);
@@ -125,6 +126,8 @@
void getFuncInfoList(size_t size, FuncInfo *list);
+ void getObjectSlotList(size_t size, uint32_t *list);
+
int registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext);
diff --git a/lib/bcc/ScriptCached.cpp b/lib/bcc/ScriptCached.cpp
index b4cf99d..1003163 100644
--- a/lib/bcc/ScriptCached.cpp
+++ b/lib/bcc/ScriptCached.cpp
@@ -37,6 +37,7 @@
if (mpStringPoolRaw) { free(mpStringPoolRaw); }
if (mpExportVars) { free(mpExportVars); }
if (mpExportFuncs) { free(mpExportFuncs); }
+ if (mpObjectSlotList) { free(mpObjectSlotList); }
}
void ScriptCached::getExportVarList(size_t varListSize, void **varList) {
@@ -89,6 +90,21 @@
}
+void ScriptCached::getObjectSlotList(size_t objectSlotListSize,
+ uint32_t *objectSlotList) {
+ if (objectSlotList) {
+ size_t objectSlotCount = getObjectSlotCount();
+
+ if (objectSlotCount > objectSlotListSize) {
+ objectSlotCount = objectSlotListSize;
+ }
+
+ memcpy(objectSlotList, mpObjectSlotList->object_slot_list,
+ sizeof(uint32_t) * objectSlotCount);
+ }
+}
+
+
void *ScriptCached::lookup(const char *name) {
FuncTable::const_iterator I = mFunctions.find(name);
return (I == mFunctions.end()) ? NULL : I->second.first;
diff --git a/lib/bcc/ScriptCached.h b/lib/bcc/ScriptCached.h
index c484546..26db663 100644
--- a/lib/bcc/ScriptCached.h
+++ b/lib/bcc/ScriptCached.h
@@ -54,6 +54,7 @@
OBCC_ExportVarList *mpExportVars;
OBCC_ExportFuncList *mpExportFuncs;
PragmaList mPragmas;
+ OBCC_ObjectSlotList *mpObjectSlotList;
FuncTable mFunctions;
@@ -67,7 +68,8 @@
public:
ScriptCached(Script *owner)
: mpOwner(owner), mpExportVars(NULL), mpExportFuncs(NULL),
- mContext(NULL), mpStringPoolRaw(NULL), mLibRSThreadable(false) {
+ mpObjectSlotList(NULL), mContext(NULL), mpStringPoolRaw(NULL),
+ mLibRSThreadable(false) {
}
~ScriptCached();
@@ -91,6 +93,9 @@
return mFunctions.size();
}
+ size_t getObjectSlotCount() const {
+ return mpObjectSlotList->count;
+ }
void getExportVarList(size_t varListSize, void **varList);
@@ -102,6 +107,8 @@
void getFuncInfoList(size_t funcInfoListSize, FuncInfo *funcNameList);
+ void getObjectSlotList(size_t objectSlotListSize,
+ uint32_t *objectSlotList);
char *getContext() {
return mContext;
diff --git a/lib/bcc/ScriptCompiled.cpp b/lib/bcc/ScriptCompiled.cpp
index 052d2a7..5fd45b6 100644
--- a/lib/bcc/ScriptCompiled.cpp
+++ b/lib/bcc/ScriptCompiled.cpp
@@ -117,5 +117,22 @@
}
}
+void ScriptCompiled::getObjectSlotList(size_t objectSlotListSize,
+ uint32_t *objectSlotList) {
+ if (objectSlotList) {
+ size_t objectSlotCount = getObjectSlotCount();
+
+ if (objectSlotCount > objectSlotListSize) {
+ objectSlotCount = objectSlotListSize;
+ }
+
+ for (ObjectSlotList::const_iterator
+ I = mObjectSlots.begin(), E = mObjectSlots.end();
+ I != E && objectSlotCount > 0; ++I, --objectSlotCount) {
+ *objectSlotList++ = *I;
+ }
+ }
+
+}
} // namespace bcc
diff --git a/lib/bcc/ScriptCompiled.h b/lib/bcc/ScriptCompiled.h
index 01af974..0e5c9fc 100644
--- a/lib/bcc/ScriptCompiled.h
+++ b/lib/bcc/ScriptCompiled.h
@@ -43,6 +43,7 @@
typedef std::list<void*> ExportVarList;
typedef std::list<void*> ExportFuncList;
typedef std::map<std::string, FuncInfo *> FuncInfoMap;
+ typedef std::list<uint32_t> ObjectSlotList;
private:
Script *mpOwner;
@@ -52,6 +53,7 @@
ExportVarList mExportVars;
ExportFuncList mExportFuncs;
PragmaList mPragmas;
+ ObjectSlotList mObjectSlots;
FuncInfoMap mEmittedFunctions;
@@ -111,6 +113,9 @@
return mEmittedFunctions.size();
}
+ size_t getObjectSlotCount() const {
+ return mObjectSlots.size();
+ }
void getExportVarList(size_t varListSize, void **varList);
@@ -123,6 +128,9 @@
void getFuncInfoList(size_t funcInfoListSize,
FuncInfo *funcInfoList);
+ void getObjectSlotList(size_t objectSlotListSize,
+ uint32_t *objectSlotList);
+
char *getContext() {
return mContext;
}
diff --git a/lib/bcc/bcc.cpp b/lib/bcc/bcc.cpp
index 294842b..11e3a95 100644
--- a/lib/bcc/bcc.cpp
+++ b/lib/bcc/bcc.cpp
@@ -242,3 +242,33 @@
unwrap(script)->getFuncInfoList(funcInfoListSize, funcInfoList);
}
}
+
+
+extern "C" size_t bccGetObjectSlotCount(BCCScriptRef script) {
+ BCC_FUNC_LOGGER();
+ return unwrap(script)->getObjectSlotCount();
+}
+
+
+extern "C" void bccGetObjectSlotList(BCCScriptRef script,
+ size_t objectSlotListSize,
+ uint32_t *objectSlotList) {
+ BCC_FUNC_LOGGER();
+
+ if (objectSlotList) {
+ unwrap(script)->getObjectSlotList(objectSlotListSize, objectSlotList);
+#if USE_DISASSEMBLER_FILE
+ size_t count = unwrap(script)->getObjectSlotCount();
+ LOGD("ObjectSlotCount = %lu\n", (unsigned long)count);
+
+ if (count > objectSlotListSize) {
+ count = objectSlotListSize;
+ }
+
+ for (size_t i = 0; i < count; ++i) {
+ LOGD("ObjectSlotList[%lu] = %d\n", (unsigned long)i, objectSlotList[i]);
+ }
+#endif
+ }
+}
+