Revert "Introduce RSInfo and its reader/extractor/writer."
This reverts commit 255cbc8a78131fd828de0fac3ff70baeaa2f032f.
Conflicts:
lib/ExecutionEngine/RSInfoExtractor.cpp
Change-Id: I533398c25cd7fde2a76418101d29374b6e1d2b27
diff --git a/lib/ExecutionEngine/Android.mk b/lib/ExecutionEngine/Android.mk
index 430f872..c3566e5 100644
--- a/lib/ExecutionEngine/Android.mk
+++ b/lib/ExecutionEngine/Android.mk
@@ -34,10 +34,6 @@
MCCacheWriter.cpp \
MCCacheReader.cpp \
OutputFile.cpp \
- RSInfo.cpp \
- RSInfoExtractor.cpp \
- RSInfoReader.cpp \
- RSInfoWriter.cpp \
RSScript.cpp \
BCCRuntimeStub.c \
Script.cpp \
diff --git a/lib/ExecutionEngine/MCCacheReader.cpp b/lib/ExecutionEngine/MCCacheReader.cpp
index dc4ba92..1a74ed3 100644
--- a/lib/ExecutionEngine/MCCacheReader.cpp
+++ b/lib/ExecutionEngine/MCCacheReader.cpp
@@ -289,16 +289,17 @@
}
vector<char const *> &strPool = mpResult->mStringPool;
- map<string, unsigned char const *>::iterator dep;
+ map<string, pair<uint32_t, unsigned char const *> >::iterator dep;
dep = mDependencies.begin();
for (size_t i = 0; i < mpCachedDependTable->count; ++i, ++dep) {
string const &depName = dep->first;
- unsigned char const *depSHA1 = dep->second;
+ uint32_t depType = dep->second.first;
+ unsigned char const *depSHA1 = dep->second.second;
MCO_Dependency *depCached =&mpCachedDependTable->table[i];
char const *depCachedName = strPool[depCached->res_name_strp_index];
- //uint32_t depCachedType = depCached->res_type;
+ uint32_t depCachedType = depCached->res_type;
unsigned char const *depCachedSHA1 = depCached->sha1;
if (depName != depCachedName) {
@@ -325,6 +326,11 @@
return false;
}
+
+ if (depType != depCachedType) {
+ ALOGE("Cache dependency %s resource type mismatch.\n", depCachedName);
+ return false;
+ }
}
return true;
diff --git a/lib/ExecutionEngine/MCCacheReader.h b/lib/ExecutionEngine/MCCacheReader.h
index e2d10c5..39e438b 100644
--- a/lib/ExecutionEngine/MCCacheReader.h
+++ b/lib/ExecutionEngine/MCCacheReader.h
@@ -50,7 +50,8 @@
llvm::OwningPtr<ScriptCached> mpResult;
- std::map<std::string, unsigned char const *> mDependencies;
+ std::map<std::string,
+ std::pair<uint32_t, unsigned char const *> > mDependencies;
bool mIsContextSlotNotAvail;
@@ -67,9 +68,11 @@
~MCCacheReader();
- void addDependency(std::string const &resName,
+ void addDependency(MCO_ResourceType resType,
+ std::string const &resName,
unsigned char const *sha1) {
- mDependencies.insert(std::make_pair(resName, sha1));
+ mDependencies.insert(std::make_pair(resName,
+ std::make_pair((uint32_t)resType, sha1)));
}
ScriptCached *readCacheFile(InputFile &objFile, InputFile &infoFile, Script *s);
diff --git a/lib/ExecutionEngine/MCCacheWriter.cpp b/lib/ExecutionEngine/MCCacheWriter.cpp
index c667c19..7809234 100644
--- a/lib/ExecutionEngine/MCCacheWriter.cpp
+++ b/lib/ExecutionEngine/MCCacheWriter.cpp
@@ -122,12 +122,13 @@
tab->count = mDependencies.size();
size_t i = 0;
- for (map<string, unsigned char const *>::iterator
+ for (map<string, pair<uint32_t, unsigned char const *> >::iterator
I = mDependencies.begin(), E = mDependencies.end(); I != E; ++I, ++i) {
MCO_Dependency *dep = &tab->table[i];
dep->res_name_strp_index = addString(I->first.c_str(), I->first.size());
- memcpy(dep->sha1, I->second, 20);
+ dep->res_type = I->second.first;
+ memcpy(dep->sha1, I->second.second, 20);
}
return true;
diff --git a/lib/ExecutionEngine/MCCacheWriter.h b/lib/ExecutionEngine/MCCacheWriter.h
index 47f1e40..1f462b3 100644
--- a/lib/ExecutionEngine/MCCacheWriter.h
+++ b/lib/ExecutionEngine/MCCacheWriter.h
@@ -36,7 +36,8 @@
std::vector<std::pair<char const *, size_t> > mStringPool;
- std::map<std::string, unsigned char const *> mDependencies;
+ std::map<std::string,
+ std::pair<uint32_t, unsigned char const *> > mDependencies;
MCO_Header *mpHeaderSection;
MCO_StringPool *mpStringPoolSection;
@@ -64,9 +65,11 @@
bool writeCacheFile(OutputFile &objFile, OutputFile &infoFile,
RSScript *S, uint32_t libRS_threadable);
- void addDependency(std::string const &resName,
+ void addDependency(MCO_ResourceType resType,
+ std::string const &resName,
unsigned char const *sha1) {
- mDependencies.insert(std::make_pair(resName, sha1));
+ mDependencies.insert(std::make_pair(resName,
+ std::make_pair((uint32_t)resType, sha1)));
}
private:
diff --git a/lib/ExecutionEngine/RSInfo.cpp b/lib/ExecutionEngine/RSInfo.cpp
deleted file mode 100644
index d351d36..0000000
--- a/lib/ExecutionEngine/RSInfo.cpp
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//#define LOG_NDEBUG 0
-#include "RSInfo.h"
-
-#include <cstring>
-#include <new>
-
-#include "FileBase.h"
-#include "DebugHelper.h"
-#include "Sha1Helper.h"
-
-using namespace bcc;
-
-const char RSInfo::LibBCCPath[] = "/system/lib/libbcc.so";
-const char RSInfo::LibRSPath[] = "/system/lib/libRS.so";
-uint8_t RSInfo::LibBCCSHA1[20];
-uint8_t RSInfo::LibRSSHA1[20];
-
-void RSInfo::LoadBuiltInSHA1Information() {
- static bool loaded = false;
-
- if (loaded) {
- return;
- }
-
- // Read SHA-1 checksum of libbcc from hard-coded patch
- // /system/lib/libbcc.so.sha1.
- readSHA1(LibBCCSHA1, 20, "/system/lib/libbcc.so.sha1");
-
- // Calculate the SHA-1 checksum of libRS.so.
- calcFileSHA1(LibRSSHA1, LibRSPath);
-
- loaded = true;
-
- return;
-}
-
-android::String8 RSInfo::GetPath(const FileBase &pFile) {
- android::String8 result(pFile.getName().c_str());
- result.append(".info");
- return result;
-}
-
-#define PRINT_DEPENDENCY(PREFIX, N, X) \
- ALOGV("\t" PREFIX "Source name: %s, " \
- "SHA-1: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", \
- (N), (X)[ 0], (X)[ 1], (X)[ 2], (X)[ 3], (X)[ 4], (X)[ 5], \
- (X)[ 6], (X)[ 7], (X)[ 8], (X)[ 9], (X)[10], (X)[11], \
- (X)[12], (X)[13], (X)[14], (X)[15], (X)[16], (X)[17], \
- (X)[18], (X)[19]);
-
-bool RSInfo::CheckDependency(const RSInfo &pInfo,
- const char *pInputFilename,
- const RSScript::SourceDependencyListTy &pDeps) {
- // Built-in dependencies are libbcc.so and libRS.so.
- static const unsigned NumBuiltInDependencies = 2;
-
- LoadBuiltInSHA1Information();
-
- if (pInfo.mDependencyTable.size() != (pDeps.size() + NumBuiltInDependencies)) {
- ALOGD("Number of dependencies recorded mismatch (%lu v.s. %lu) in %s!",
- static_cast<unsigned long>(pInfo.mDependencyTable.size()),
- static_cast<unsigned long>(pDeps.size()), pInputFilename);
- return false;
- } else {
- // Built-in dependencies always go first.
- const std::pair<const char *, const uint8_t *> &cache_libbcc_dep =
- pInfo.mDependencyTable[0];
- const std::pair<const char *, const uint8_t *> &cache_libRS_dep =
- pInfo.mDependencyTable[1];
-
- // Check libbcc.so.
- if (::memcmp(cache_libbcc_dep.second, LibBCCSHA1, 20) != 0) {
- ALOGD("Cache %s is dirty due to %s has been updated.", pInputFilename,
- LibBCCPath);
- PRINT_DEPENDENCY("current - ", LibBCCPath, LibBCCSHA1);
- PRINT_DEPENDENCY("cache - ", cache_libbcc_dep.first,
- cache_libbcc_dep.second);
- return false;
- }
-
- // Check libRS.so.
- if (::memcmp(cache_libRS_dep.second, LibRSSHA1, 20) != 0) {
- ALOGD("Cache %s is dirty due to %s has been updated.", pInputFilename,
- LibRSPath);
- PRINT_DEPENDENCY("current - ", LibRSPath, LibRSSHA1);
- PRINT_DEPENDENCY("cache - ", cache_libRS_dep.first,
- cache_libRS_dep.second);
- return false;
- }
-
- for (unsigned i = 0; i < pDeps.size(); i++) {
- const RSScript::SourceDependency &in_dep = *(pDeps[i]);
- const std::pair<const char *, const uint8_t *> &cache_dep =
- pInfo.mDependencyTable[i + NumBuiltInDependencies];
-
- if ((::strncmp(in_dep.getSourceName().c_str(),
- cache_dep.first,
- in_dep.getSourceName().length()) != 0) ||
- (::memcmp(in_dep.getSHA1Checksum(), cache_dep.second, 20) != 0)) {
- ALOGD("Cache %s is dirty due to the source it dependends on has been "
- "changed:", pInputFilename);
- PRINT_DEPENDENCY("given - ", in_dep.getSourceName().c_str(),
- in_dep.getSHA1Checksum());
- PRINT_DEPENDENCY("cache - ", cache_dep.first, cache_dep.second);
- return false;
- }
- }
- }
-
- return true;
-}
-
-RSInfo::RSInfo(size_t pStringPoolSize) : mStringPool(NULL) {
- ::memset(&mHeader, 0, sizeof(mHeader));
-
- ::memcpy(mHeader.magic, RSINFO_MAGIC, sizeof(mHeader.magic));
- ::memcpy(mHeader.version, RSINFO_VERSION, sizeof(mHeader.version));
-
- mHeader.headerSize = sizeof(mHeader);
-
- mHeader.dependencyTable.itemSize = sizeof(rsinfo::DependencyTableItem);
- mHeader.pragmaList.itemSize = sizeof(rsinfo::PragmaItem);
- mHeader.objectSlotList.itemSize = sizeof(rsinfo::ObjectSlotItem);
- mHeader.exportVarNameList.itemSize = sizeof(rsinfo::ExportVarNameItem);
- mHeader.exportFuncNameList.itemSize = sizeof(rsinfo::ExportFuncNameItem);
- mHeader.exportForeachFuncList.itemSize = sizeof(rsinfo::ExportForeachFuncItem);
-
- if (pStringPoolSize > 0) {
- mHeader.strPoolSize = pStringPoolSize;
- mStringPool = new (std::nothrow) char [ mHeader.strPoolSize ];
- if (mStringPool == NULL) {
- ALOGE("Out of memory when allocate memory for string pool in RSInfo "
- "constructor (size: %u)!", mHeader.strPoolSize);
- }
- }
-}
-
-RSInfo::~RSInfo() {
- delete [] mStringPool;
-}
-
-bool RSInfo::layout(off_t initial_offset) {
- mHeader.dependencyTable.offset = initial_offset +
- mHeader.headerSize +
- mHeader.strPoolSize;
- mHeader.dependencyTable.count = mDependencyTable.size();
-
-#define AFTER(_list) ((_list).offset + (_list).itemSize * (_list).count)
- mHeader.pragmaList.offset = AFTER(mHeader.dependencyTable);
- mHeader.pragmaList.count = mPragmas.size();
-
- mHeader.objectSlotList.offset = AFTER(mHeader.pragmaList);
- mHeader.objectSlotList.count = mObjectSlots.size();
-
- mHeader.exportVarNameList.offset = AFTER(mHeader.objectSlotList);
- mHeader.exportVarNameList.count = mExportVarNames.size();
-
- mHeader.exportFuncNameList.offset = AFTER(mHeader.exportVarNameList);
- mHeader.exportFuncNameList.count = mExportFuncNames.size();
-
- mHeader.exportForeachFuncList.offset = AFTER(mHeader.exportFuncNameList);
- mHeader.exportForeachFuncList.count = mExportForeachFuncs.size();
-#undef AFTER
-
- return true;
-}
-
-void RSInfo::dump() const {
- // Hide the codes to save the code size when debugging is disabled.
-#if !LOG_NDEBUG
-
- // Dump header
- ALOGV("RSInfo Header:");
- ALOGV("\tIs threadable: %s", ((mHeader.isThreadable) ? "true" : "false"));
- ALOGV("\tHeader size: %u", mHeader.headerSize);
- ALOGV("\tString pool size: %u", mHeader.strPoolSize);
-
-#define DUMP_LIST_HEADER(_name, _header) do { \
- ALOGV(_name ":"); \
- ALOGV("\toffset: %u", (_header).offset); \
- ALOGV("\t# of item: %u", (_header).count); \
- ALOGV("\tsize of each item: %u", (_header).itemSize); \
-} while (false)
- DUMP_LIST_HEADER("Dependency table", mHeader.dependencyTable);
- for (DependencyTableTy::const_iterator dep_iter = mDependencyTable.begin(),
- dep_end = mDependencyTable.end(); dep_iter != dep_end; dep_iter++) {
- PRINT_DEPENDENCY("", dep_iter->first, dep_iter->second);
- }
-
- DUMP_LIST_HEADER("Pragma list", mHeader.pragmaList);
- for (PragmaListTy::const_iterator pragma_iter = mPragmas.begin(),
- pragma_end = mPragmas.end(); pragma_iter != pragma_end; pragma_iter++) {
- ALOGV("\tkey: %s, value: %s", pragma_iter->first, pragma_iter->second);
- }
-
- DUMP_LIST_HEADER("RS object slots", mHeader.objectSlotList);
- for (ObjectSlotListTy::const_iterator slot_iter = mObjectSlots.begin(),
- slot_end = mObjectSlots.end(); slot_iter != slot_end; slot_iter++) {
- ALOGV("slot: %u", *slot_iter);
- }
-
- DUMP_LIST_HEADER("RS export variables", mHeader.exportVarNameList);
- for (ExportVarNameListTy::const_iterator var_iter = mExportVarNames.begin(),
- var_end = mExportVarNames.end(); var_iter != var_end; var_iter++) {
- ALOGV("name: %s", *var_iter);
- }
-
- DUMP_LIST_HEADER("RS export functions", mHeader.exportFuncNameList);
- for (ExportFuncNameListTy::const_iterator func_iter = mExportFuncNames.begin(),
- func_end = mExportFuncNames.end(); func_iter != func_end; func_iter++) {
- ALOGV("name: %s", *func_iter);
- }
-
- DUMP_LIST_HEADER("RS foreach list", mHeader.exportForeachFuncList);
- for (ExportForeachFuncListTy::const_iterator
- foreach_iter = mExportForeachFuncs.begin(),
- foreach_end = mExportForeachFuncs.end(); foreach_iter != foreach_end;
- foreach_iter++) {
- ALOGV("name: %s, signature: %05x", foreach_iter->first,
- foreach_iter->second);
- }
-#undef DUMP_LIST_HEADER
-
-#endif // LOG_NDEBUG
- return;
-}
-
-const char *RSInfo::getStringFromPool(rsinfo::StringIndexTy pStrIdx) const {
- // String pool uses direct indexing. Ensure that the pStrIdx is within the
- // range.
- if (pStrIdx >= mHeader.strPoolSize) {
- ALOGE("String index #%u is out of range in string pool (size: %u)!",
- pStrIdx, mHeader.strPoolSize);
- return NULL;
- }
- return &mStringPool[ pStrIdx ];
-}
-
-rsinfo::StringIndexTy RSInfo::getStringIdxInPool(const char *pStr) const {
- // Assume we are on the flat memory architecture (i.e., the memory space is
- // continuous.)
- if ((mStringPool + mHeader.strPoolSize) < pStr) {
- ALOGE("String %s does not in the string pool!", pStr);
- return rsinfo::gInvalidStringIndex;
- }
- return (pStr - mStringPool);
-}
-
-enum RSInfo::FloatPrecision RSInfo::getFloatPrecisionRequirement() const {
- // Check to see if we have any FP precision-related pragmas.
- static const char relaxed_pragma[] = "rs_fp_relaxed";
- static const char imprecise_pragma[] = "rs_fp_imprecise";
- bool relaxed_pragma_seen = false;
-
- for (PragmaListTy::const_iterator pragma_iter = mPragmas.begin(),
- pragma_end = mPragmas.end(); pragma_iter != pragma_end;
- pragma_iter++) {
- const char *pragma_key = pragma_iter->first;
- if (::strcmp(pragma_key, relaxed_pragma) == 0) {
- relaxed_pragma_seen = true;
- } else if (::strcmp(pragma_key, imprecise_pragma) == 0) {
- if (relaxed_pragma_seen) {
- ALOGW("Multiple float precision pragmas specified!");
- }
- // Fast return when there's rs_fp_imprecise specified.
- return Imprecise;
- }
- }
-
- // Imprecise is selected over Relaxed precision.
- // In the absence of both, we stick to the default Full precision.
- if (relaxed_pragma_seen) {
- return Relaxed;
- } else {
- return Full;
- }
- // unreachable
-}
diff --git a/lib/ExecutionEngine/RSInfo.h b/lib/ExecutionEngine/RSInfo.h
deleted file mode 100644
index d69d15e..0000000
--- a/lib/ExecutionEngine/RSInfo.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BCC_EXECUTION_ENGINE_RS_INFO_FILE_H
-#define BCC_EXECUTION_ENGINE_RS_INFO_FILE_H
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "RSScript.h"
-#include "DebugHelper.h"
-
-#include <utils/String8.h>
-#include <utils/Vector.h>
-
-namespace bcc {
-
-// Forward declarations
-class FileBase;
-class InputFile;
-class OutputFile;
-class Source;
-
-namespace rsinfo {
-
-/* RS info file magic */
-#define RSINFO_MAGIC "\0rsinfo\n"
-
-/* RS info file version, encoded in 4 bytes of ASCII */
-#define RSINFO_VERSION "003\0"
-
-struct __attribute__((packed)) ListHeader {
- // The offset from the beginning of the file of data
- uint32_t offset;
- // Number of item in the list
- uint32_t count;
- // Size of each item
- uint8_t itemSize;
-};
-
-/* RS info file header */
-struct __attribute__((packed)) Header {
- // Magic versus version
- uint8_t magic[8];
- uint8_t version[4];
-
- uint8_t isThreadable;
- uint8_t hasDebugInformation;
-
- uint16_t headerSize;
-
- uint32_t strPoolSize;
-
- struct ListHeader dependencyTable;
- struct ListHeader pragmaList;
- struct ListHeader objectSlotList;
- struct ListHeader exportVarNameList;
- struct ListHeader exportFuncNameList;
- struct ListHeader exportForeachFuncList;
-};
-
-typedef uint32_t StringIndexTy;
-// Use value -1 as an invalid string index marker. No need to declare with
-// 'static' modifier since 'const' variable has internal linkage by default.
-const StringIndexTy gInvalidStringIndex = static_cast<StringIndexTy>(-1);
-
-struct __attribute__((packed)) DependencyTableItem {
- StringIndexTy id;
- // SHA-1 checksum is stored as a string in string pool (and has fixed-length
- // 20 bytes)
- StringIndexTy sha1;
-};
-
-struct __attribute__((packed)) PragmaItem {
- // Pragma is a key-value pair.
- StringIndexTy key;
- StringIndexTy value;
-};
-
-struct __attribute__((packed)) ObjectSlotItem {
- uint32_t slot;
-};
-
-struct __attribute__((packed)) ExportVarNameItem {
- StringIndexTy name;
-};
-
-struct __attribute__((packed)) ExportFuncNameItem {
- StringIndexTy name;
-};
-
-struct __attribute__((packed)) ExportForeachFuncItem {
- StringIndexTy name;
- uint32_t signature;
-};
-
-// Return the human-readable name of the given rsinfo::*Item in the template
-// parameter. This is for debugging and error message.
-template<typename Item>
-inline const char *GetItemTypeName();
-
-template<>
-inline const char *GetItemTypeName<DependencyTableItem>()
-{ return "rs dependency info"; }
-
-template<>
-inline const char *GetItemTypeName<PragmaItem>()
-{ return "rs pragma"; }
-
-template<>
-inline const char *GetItemTypeName<ObjectSlotItem>()
-{ return "rs object slot"; }
-
-template<>
-inline const char *GetItemTypeName<ExportVarNameItem>()
-{ return "rs export var"; }
-
-template<>
-inline const char *GetItemTypeName<ExportFuncNameItem>()
-{ return "rs export func"; }
-
-template<>
-inline const char *GetItemTypeName<ExportForeachFuncItem>()
-{ return "rs export foreach"; }
-
-} // end namespace rsinfo
-
-class RSInfo {
-public:
- typedef android::Vector<std::pair<const char *,
- const uint8_t *> > DependencyTableTy;
- typedef android::Vector<std::pair<const char*, const char*> > PragmaListTy;
- typedef android::Vector<uint32_t> ObjectSlotListTy;
- typedef android::Vector<const char *> ExportVarNameListTy;
- typedef android::Vector<const char *> ExportFuncNameListTy;
- typedef android::Vector<std::pair<const char *,
- uint32_t> > ExportForeachFuncListTy;
-
-public:
- // Calculate or load the SHA-1 information of the built-in dependencies.
- static void LoadBuiltInSHA1Information();
-
- // Return the path of the RS info file corresponded to the given output
- // executable file.
- static android::String8 GetPath(const FileBase &pFile);
-
- static const char LibBCCPath[];
- static const char LibRSPath[];
-
-private:
- // SHA-1 of the built-in dependencies. Will be initialized in
- // LoadBuiltInSHA1Information().
- static uint8_t LibBCCSHA1[20];
- static uint8_t LibRSSHA1[20];
-
- static bool CheckDependency(const RSInfo &pInfo,
- const char *pInputFilename,
- const RSScript::SourceDependencyListTy &pDeps);
- static bool AddBuiltInDependencies(RSInfo &pInfo);
-
- rsinfo::Header mHeader;
-
- char *mStringPool;
-
- // In most of the time, there're 4 source dependencies stored (libbcc.so,
- // libRS.so, libclcore and the input bitcode itself.)
- DependencyTableTy mDependencyTable;
- PragmaListTy mPragmas;
- ObjectSlotListTy mObjectSlots;
- ExportVarNameListTy mExportVarNames;
- ExportFuncNameListTy mExportFuncNames;
- ExportForeachFuncListTy mExportForeachFuncs;
-
- // Initialize an empty RSInfo with its size of string pool is pStringPoolSize.
- RSInfo(size_t pStringPoolSize);
-
- // layout() assigns value of offset in each ListHeader (i.e., it decides where
- // data should go in the file.) It also updates fields other than offset to
- // reflect the current RSInfo object states to mHeader.
- bool layout(off_t initial_offset);
-
-public:
- ~RSInfo();
-
- // Implemented in RSInfoExtractor.cpp.
- static RSInfo *ExtractFromSource(
- const Source &pSource, const RSScript::SourceDependencyListTy &pDeps);
-
- // Implemented in RSInfoReader.cpp.
- static RSInfo *ReadFromFile(InputFile &pInput,
- const RSScript::SourceDependencyListTy &pDeps);
-
- // Implemneted in RSInfoWriter.cpp
- bool write(OutputFile &pOutput);
-
- void dump() const;
-
- // const getter
- inline bool isThreadable() const
- { return mHeader.isThreadable; }
- inline bool hasDebugInformation() const
- { return mHeader.hasDebugInformation; }
- inline const DependencyTableTy &getDependencyTable() const
- { return mDependencyTable; }
- inline const PragmaListTy &getPragmas() const
- { return mPragmas; }
- inline const ObjectSlotListTy &getObjectSlots() const
- { return mObjectSlots; }
- inline const ExportVarNameListTy &getExportVarNames() const
- { return mExportVarNames; }
- inline const ExportFuncNameListTy &getExportFuncNames() const
- { return mExportFuncNames; }
- inline const ExportForeachFuncListTy &getExportForeachFuncs() const
- { return mExportForeachFuncs; }
-
- const char *getStringFromPool(rsinfo::StringIndexTy pStrIdx) const;
- rsinfo::StringIndexTy getStringIdxInPool(const char *pStr) const;
-
- // setter
- inline void setThreadable(bool pThreadable = true)
- { mHeader.isThreadable = pThreadable; }
-
-public:
- enum FloatPrecision {
- Full,
- Relaxed,
- Imprecise,
- };
-
- // Return the minimal floating point precision required for the associated
- // script.
- enum FloatPrecision getFloatPrecisionRequirement() const;
-};
-
-} // end namespace bcc
-
-#endif // BCC_EXECUTION_ENGINE_RS_INFO_FILE_H
diff --git a/lib/ExecutionEngine/RSInfoExtractor.cpp b/lib/ExecutionEngine/RSInfoExtractor.cpp
deleted file mode 100644
index a90becc..0000000
--- a/lib/ExecutionEngine/RSInfoExtractor.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//===----------------------------------------------------------------------===//
-// This file implements RSInfo::ExtractFromSource()
-//===----------------------------------------------------------------------===//
-#include "RSInfo.h"
-
-#include <llvm/Constants.h>
-#include <llvm/Metadata.h>
-#include <llvm/Module.h>
-
-#include "DebugHelper.h"
-#include "Source.h"
-
-using namespace bcc;
-
-namespace {
-
-// Name of metadata node where pragma info resides (should be synced with
-// slang.cpp)
-const llvm::StringRef pragma_metadata_name("#pragma");
-
-/*
- * The following names should be synced with the one appeared in
- * slang_rs_metadata.h.
- */
-// Name of metadata node where exported variable names reside
-const llvm::StringRef export_var_metadata_name("#rs_export_var");
-
-// Name of metadata node where exported function names reside
-const llvm::StringRef export_func_metadata_name("#rs_export_func");
-
-// Name of metadata node where exported ForEach name information resides
-const llvm::StringRef export_foreach_name_metadata_name("#rs_export_foreach_name");
-
-// Name of metadata node where exported ForEach signature information resides
-const llvm::StringRef export_foreach_metadata_name("#rs_export_foreach");
-
-// Name of metadata node where RS object slot info resides (should be
-const llvm::StringRef object_slot_metadata_name("#rs_object_slots");
-
-inline llvm::StringRef getStringFromOperand(const llvm::Value *pString) {
- if ((pString != NULL) && (pString->getValueID() == llvm::Value::MDStringVal)) {
- return static_cast<const llvm::MDString *>(pString)->getString();
- }
- return llvm::StringRef();
-}
-
-template<size_t NumOperands>
-inline size_t getMetadataStringLength(const llvm::NamedMDNode *pMetadata) {
- if (pMetadata == NULL) {
- return 0;
- }
-
- size_t string_size = 0;
- for (unsigned i = 0, e = pMetadata->getNumOperands(); i < e; i++) {
- llvm::MDNode *node = pMetadata->getOperand(i);
- if ((node != NULL) && (node->getNumOperands() >= NumOperands)) {
- // Compiler try its best to unroll this loop since NumOperands is a
- // template parameter (therefore the number of iteration can be determined
- // at compile-time and it's usually small.)
- for (unsigned j = 0; j < NumOperands; j++) {
- llvm::StringRef s = getStringFromOperand(node->getOperand(j));
- if (s.size() > 0) {
- // +1 is for the null-terminator at the end of string.
- string_size += (s.size() + 1);
- }
- }
- }
- }
-
- return string_size;
-}
-
-// Write a string pString to the string pool pStringPool at offset pWriteStart.
-// Return the pointer the pString resides within the string pool.
-const char *writeString(const llvm::StringRef &pString, char *pStringPool,
- off_t *pWriteStart) {
- if (pString.empty()) {
- return pStringPool;
- }
-
- char *pStringWriteStart = pStringPool + *pWriteStart;
- // Copy the string.
- ::memcpy(pStringWriteStart, pString.data(), pString.size());
- // Write null-terminator at the end of the string.
- pStringWriteStart[ pString.size() ] = '\0';
- // Update pWriteStart.
- *pWriteStart += (pString.size() + 1);
-
- return pStringWriteStart;
-}
-
-bool writeDependency(const std::string &pSourceName, const uint8_t *pSHA1,
- char *pStringPool, off_t *pWriteStart,
- RSInfo::DependencyTableTy &pDepTable) {
- const char *source_name = writeString(pSourceName, pStringPool, pWriteStart);
-
- uint8_t *sha1 = reinterpret_cast<uint8_t *>(pStringPool + *pWriteStart);
-
- // SHA-1 is special. It's 20-bytes long without null-terminator.
- ::memcpy(sha1, pSHA1, 20);
- // Record in the result RSInfo object.
- pDepTable.push(std::make_pair(source_name, sha1));
- // Update the string pool pointer.
- *pWriteStart += 20;
-
- return true;
-}
-
-} // end anonymous namespace
-
-RSInfo *RSInfo::ExtractFromSource(const Source &pSource,
- const RSScript::SourceDependencyListTy &pDeps)
-{
- const llvm::Module &module = pSource.getModule();
- const char *module_name = module.getModuleIdentifier().c_str();
-
- const llvm::NamedMDNode *pragma =
- module.getNamedMetadata(pragma_metadata_name);
- const llvm::NamedMDNode *export_var =
- module.getNamedMetadata(export_var_metadata_name);
- const llvm::NamedMDNode *export_func =
- module.getNamedMetadata(export_func_metadata_name);
- const llvm::NamedMDNode *export_foreach_name =
- module.getNamedMetadata(export_foreach_name_metadata_name);
- const llvm::NamedMDNode *export_foreach_signature =
- module.getNamedMetadata(export_foreach_metadata_name);
- const llvm::NamedMDNode *object_slots =
- module.getNamedMetadata(object_slot_metadata_name);
-
- // Always write a byte 0x0 at the beginning of the string pool.
- size_t string_pool_size = 1;
- off_t cur_string_pool_offset = 0;
-
- RSInfo *result = NULL;
-
- // Handle legacy case for pre-ICS bitcode that doesn't contain a metadata
- // section for ForEach. We generate a full signature for a "root" function.
- if ((export_foreach_name == NULL) || (export_foreach_signature == NULL)) {
- export_foreach_name = NULL;
- export_foreach_signature = NULL;
- string_pool_size += 5; // insert "root\0" for #rs_export_foreach_name
- }
-
- string_pool_size += getMetadataStringLength<2>(pragma);
- string_pool_size += getMetadataStringLength<1>(export_var);
- string_pool_size += getMetadataStringLength<1>(export_func);
- string_pool_size += getMetadataStringLength<1>(export_foreach_name);
-
- // Don't forget to reserve the space for the dependency informationin string
- // pool.
- string_pool_size += ::strlen(LibBCCPath) + 1 + 20;
- string_pool_size += ::strlen(LibRSPath) + 1 + 20;
- for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
- const RSScript::SourceDependency *source_dep = pDeps[i];
- if (source_dep != NULL) {
- // +1 for null-terminator
- string_pool_size += source_dep->getSourceName().length() + 1;
- // +20 for SHA-1 checksum
- string_pool_size += 20;
- }
- }
-
- // Allocate result object
- result = new (std::nothrow) RSInfo(string_pool_size);
- if (result == NULL) {
- ALOGE("Out of memory when create RSInfo object for %s!", module_name);
- goto bail;
- }
-
- // Check string pool.
- if (result->mStringPool == NULL) {
- ALOGE("Out of memory when allocate string pool in RSInfo object for %s!",
- module_name);
- goto bail;
- }
-
- // First byte of string pool should be an empty string
- result->mStringPool[ cur_string_pool_offset++ ] = '\0';
-
- // Populate all the strings and data.
-#define FOR_EACH_NODE_IN(_metadata, _node) \
- for (unsigned i = 0, e = (_metadata)->getNumOperands(); i != e; i++) \
- if (((_node) = (_metadata)->getOperand(i)) != NULL)
- //===--------------------------------------------------------------------===//
- // #pragma
- //===--------------------------------------------------------------------===//
- // Pragma is actually a key-value pair. The value can be an empty string while
- // the key cannot.
- if (pragma != NULL) {
- llvm::MDNode *node;
- FOR_EACH_NODE_IN(pragma, node) {
- llvm::StringRef key = getStringFromOperand(node->getOperand(0));
- llvm::StringRef val = getStringFromOperand(node->getOperand(1));
- if (key.empty()) {
- ALOGW("%s contains pragma metadata with empty key (skip)!",
- module_name);
- } else {
- result->mPragmas.push(std::make_pair(
- writeString(key, result->mStringPool, &cur_string_pool_offset),
- writeString(val, result->mStringPool, &cur_string_pool_offset)));
- } // key.empty()
- } // FOR_EACH_NODE_IN
- } // pragma != NULL
-
- //===--------------------------------------------------------------------===//
- // #rs_export_var
- //===--------------------------------------------------------------------===//
- if (export_var != NULL) {
- llvm::MDNode *node;
- FOR_EACH_NODE_IN(export_var, node) {
- llvm::StringRef name = getStringFromOperand(node->getOperand(0));
- if (name.empty()) {
- ALOGW("%s contains empty entry in #rs_export_var metadata (skip)!",
- module_name);
- } else {
- result->mExportVarNames.push(
- writeString(name, result->mStringPool, &cur_string_pool_offset));
- }
- }
- }
-
- //===--------------------------------------------------------------------===//
- // #rs_export_func
- //===--------------------------------------------------------------------===//
- if (export_func != NULL) {
- llvm::MDNode *node;
- FOR_EACH_NODE_IN(export_func, node) {
- llvm::StringRef name = getStringFromOperand(node->getOperand(0));
- if (name.empty()) {
- ALOGW("%s contains empty entry in #rs_export_func metadata (skip)!",
- module_name);
- } else {
- result->mExportFuncNames.push(
- writeString(name, result->mStringPool, &cur_string_pool_offset));
- }
- }
- }
-
- //===--------------------------------------------------------------------===//
- // #rs_export_foreach and #rs_export_foreach_name
- //===--------------------------------------------------------------------===//
- // It's a little bit complicated to deal with #rs_export_foreach (the
- // signature of foreach-able function) and #rs_export_foreach_name (the name
- // of function which is foreach-able). We have to maintain a legacy case:
- //
- // In pre-ICS bitcode, forEach feature only supports non-graphic root()
- // function and only one signature corresponded to that non-graphic root()
- // was written to the #rs_export_foreach metadata section. There's no
- // #rs_export_foreach_name metadata section.
- //
- // Currently, not only non-graphic root() is supported but also other
- // functions that are exportable. Therefore, a new metadata section
- // #rs_export_foreach_name is added to specify which functions are
- // for-eachable. In this case, #rs_export_foreach (the function name) and
- // #rs_export_foreach metadata (the signature) is one-to-one mapping among
- // their entries.
- if ((export_foreach_name != NULL) && (export_foreach_signature != NULL)) {
- unsigned num_foreach_function;
-
- // Should be one-to-one mapping.
- if (export_foreach_name->getNumOperands() !=
- export_foreach_signature->getNumOperands()) {
- ALOGE("Mismatch number of foreach-able function names (%u) in "
- "#rs_export_foreach_name and number of signatures (%u) "
- "in %s!", export_foreach_name->getNumOperands(),
- export_foreach_signature->getNumOperands(), module_name);
- goto bail;
- }
-
- num_foreach_function = export_foreach_name->getNumOperands();
- for (unsigned i = 0; i < num_foreach_function; i++) {
- llvm::MDNode *name_node = export_foreach_name->getOperand(i);
- llvm::MDNode *signature_node = export_foreach_signature->getOperand(i);
-
- llvm::StringRef name, signature_string;
- if (name_node != NULL) {
- name = getStringFromOperand(name_node->getOperand(0));
- }
- if (signature_node != NULL) {
- signature_string = getStringFromOperand(signature_node->getOperand(0));
- }
-
- if (!name.empty() && !signature_string.empty()) {
- // Both name_node and signature_node are not NULL nodes.
- uint32_t signature;
- if (signature_string.getAsInteger(10, signature)) {
- ALOGE("Non-integer signature value '%s' for function %s found in %s!",
- signature_string.str().c_str(), name.str().c_str(), module_name);
- goto bail;
- }
- result->mExportForeachFuncs.push(std::make_pair(
- writeString(name, result->mStringPool, &cur_string_pool_offset),
- signature));
- } else {
- // One or both of the name and signature value are empty. It's safe only
- // if both of them are empty.
- if (name.empty() && signature_string.empty()) {
- ALOGW("Entries #%u at #rs_export_foreach_name and #rs_export_foreach"
- " are both NULL in %s! (skip)", i, module_name);
- continue;
- } else {
- ALOGE("Entries #%u at %s is NULL in %s! (skip)", i,
- (name.empty() ? "#rs_export_foreach_name" :
- "#rs_export_foreach"), module_name);
- goto bail;
- }
- }
- } // end for
- } else {
- // To handle the legacy case, we generate a full signature for a "root"
- // function which means that we need to set the bottom 5 bits (0x1f) in the
- // mask.
- result->mExportForeachFuncs.push(std::make_pair(
- writeString(llvm::StringRef("root"), result->mStringPool,
- &cur_string_pool_offset), 0x1f));
- }
-
- //===--------------------------------------------------------------------===//
- // #rs_object_slots
- //===--------------------------------------------------------------------===//
- if (object_slots != NULL) {
- llvm::MDNode *node;
- FOR_EACH_NODE_IN(object_slots, node) {
- llvm::StringRef val = getStringFromOperand(node->getOperand(0));
- if (val.empty()) {
- ALOGW("%s contains empty entry in #rs_object_slots (skip)!",
- module.getModuleIdentifier().c_str());
- } else {
- uint32_t slot;
- if (val.getAsInteger(10, slot)) {
- ALOGE("Non-integer object slot value '%s' in %s!", val.str().c_str(),
- module.getModuleIdentifier().c_str());
- goto bail;
- }
- }
- }
- }
-#undef FOR_EACH_NODE_IN
-
- //===--------------------------------------------------------------------===//
- // Record built-in dependency information.
- //===--------------------------------------------------------------------===//
- LoadBuiltInSHA1Information();
-
- if (!writeDependency(LibBCCPath, LibBCCSHA1,
- result->mStringPool, &cur_string_pool_offset,
- result->mDependencyTable)) {
- goto bail;
- }
-
- if (!writeDependency(LibRSPath, LibRSSHA1,
- result->mStringPool, &cur_string_pool_offset,
- result->mDependencyTable)) {
- goto bail;
- }
-
- //===--------------------------------------------------------------------===//
- // Record dependency information.
- //===--------------------------------------------------------------------===//
- for (unsigned i = 0, e = pDeps.size(); i != e; i++) {
- const RSScript::SourceDependency *source_dep = pDeps[i];
- if (source_dep != NULL) {
- if (!writeDependency(source_dep->getSourceName(),
- source_dep->getSHA1Checksum(),
- result->mStringPool, &cur_string_pool_offset,
- result->mDependencyTable)) {
- goto bail;
- }
- }
- }
-
- //===--------------------------------------------------------------------===//
- // Determine whether the bitcode contains debug information
- //===--------------------------------------------------------------------===//
- // The root context of the debug information in the bitcode is put under
- // the metadata named "llvm.dbg.cu".
- result->mHeader.hasDebugInformation =
- static_cast<uint8_t>(module.getNamedMetadata("llvm.dbg.cu") != NULL);
-
- assert((reinterpret_cast<size_t>(cur_string_pool_offset) ==
- string_pool_size) && "Unexpected string pool size!");
-
- return result;
-
-bail:
- delete result;
- return NULL;
-}
diff --git a/lib/ExecutionEngine/RSInfoReader.cpp b/lib/ExecutionEngine/RSInfoReader.cpp
deleted file mode 100644
index a3eca5a..0000000
--- a/lib/ExecutionEngine/RSInfoReader.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//===----------------------------------------------------------------------===//
-// This file implements RSInfo::ReadFromFile()
-//===----------------------------------------------------------------------===//
-
-#include "RSInfo.h"
-
-#include <new>
-
-#include <utils/FileMap.h>
-
-#include "DebugHelper.h"
-#include "InputFile.h"
-
-using namespace bcc;
-
-namespace {
-
-template<typename ItemType, typename ItemContainer>
-inline bool helper_read_list_item(const ItemType &pItem,
- const RSInfo &pInfo,
- ItemContainer &pResult);
-
-// Process DependencyTableItem in the file
-template<> inline bool
-helper_read_list_item<rsinfo::DependencyTableItem, RSInfo::DependencyTableTy>(
- const rsinfo::DependencyTableItem &pItem,
- const RSInfo &pInfo,
- RSInfo::DependencyTableTy &pResult)
-{
- const char *id = pInfo.getStringFromPool(pItem.id);
- const uint8_t *sha1 =
- reinterpret_cast<const uint8_t *>(pInfo.getStringFromPool(pItem.sha1));
-
- if (id == NULL) {
- ALOGE("Invalid string index %d for source id in RS dependenct table.",
- pItem.id);
- return false;
- }
-
- if (sha1 == NULL) {
- ALOGE("Invalid string index %d for SHA-1 checksum in RS dependenct table.",
- pItem.id);
- return false;
- }
-
- pResult.push(std::make_pair(id, sha1));
- return true;
-}
-
-// Process PragmaItem in the file
-template<> inline bool
-helper_read_list_item<rsinfo::PragmaItem, RSInfo::PragmaListTy>(
- const rsinfo::PragmaItem &pItem,
- const RSInfo &pInfo,
- RSInfo::PragmaListTy &pResult)
-{
- const char *key = pInfo.getStringFromPool(pItem.key);
- const char *value =pInfo.getStringFromPool(pItem.value);
-
- if (key == NULL) {
- ALOGE("Invalid string index %d for key in RS pragma list.", pItem.key);
- return false;
- }
-
- if (value == NULL) {
- ALOGE("Invalid string index %d for value in RS pragma list.", pItem.value);
- return false;
- }
-
- pResult.push(std::make_pair(key, value));
- return true;
-}
-
-// Procee ObjectSlotItem in the file
-template<> inline bool
-helper_read_list_item<rsinfo::ObjectSlotItem, RSInfo::ObjectSlotListTy>(
- const rsinfo::ObjectSlotItem &pItem,
- const RSInfo &pInfo,
- RSInfo::ObjectSlotListTy &pResult)
-{
- pResult.push(pItem.slot);
- return true;
-}
-
-// Procee ExportVarNameItem in the file
-template<> inline bool
-helper_read_list_item<rsinfo::ExportVarNameItem, RSInfo::ExportVarNameListTy>(
- const rsinfo::ExportVarNameItem &pItem,
- const RSInfo &pInfo,
- RSInfo::ExportVarNameListTy &pResult)
-{
- const char *name = pInfo.getStringFromPool(pItem.name);
-
- if (name == NULL) {
- ALOGE("Invalid string index %d for name in RS export vars.", pItem.name);
- return false;
- }
-
- pResult.push(name);
- return true;
-}
-
-// Procee ExportFuncNameItem in the file
-template<> inline bool
-helper_read_list_item<rsinfo::ExportFuncNameItem, RSInfo::ExportFuncNameListTy>(
- const rsinfo::ExportFuncNameItem &pItem,
- const RSInfo &pInfo,
- RSInfo::ExportFuncNameListTy &pResult)
-{
- const char *name = pInfo.getStringFromPool(pItem.name);
-
- if (name == NULL) {
- ALOGE("Invalid string index %d for name in RS export funcs.", pItem.name);
- return false;
- }
-
- pResult.push(name);
- return true;
-}
-
-// Procee ExportForeachFuncItem in the file
-template<> inline bool
-helper_read_list_item<rsinfo::ExportForeachFuncItem, RSInfo::ExportForeachFuncListTy>(
- const rsinfo::ExportForeachFuncItem &pItem,
- const RSInfo &pInfo,
- RSInfo::ExportForeachFuncListTy &pResult)
-{
- const char *name = pInfo.getStringFromPool(pItem.name);
-
- if (name == NULL) {
- ALOGE("Invalid string index %d for name in RS export foreachs.", pItem.name);
- return false;
- }
-
- pResult.push(std::make_pair(name, pItem.signature));
- return true;
-}
-
-template<typename ItemType, typename ItemContainer>
-inline bool helper_read_list(const uint8_t *pData,
- const RSInfo &pInfo,
- const rsinfo::ListHeader &pHeader,
- ItemContainer &pResult) {
- const ItemType *item;
-
- // Out-of-range exception has been checked.
- for (uint32_t i = 0; i < pHeader.count; i++) {
- item = reinterpret_cast<const ItemType *>(pData +
- pHeader.offset +
- i * pHeader.itemSize);
- if (!helper_read_list_item<ItemType, ItemContainer>(*item, pInfo, pResult)) {
- return false;
- }
- }
- return true;
-}
-
-} // end anonymous namespace
-
-RSInfo *RSInfo::ReadFromFile(InputFile &pInput,
- const RSScript::SourceDependencyListTy &pDeps) {
- android::FileMap *map = NULL;
- RSInfo *result = NULL;
- const uint8_t *data;
- const rsinfo::Header *header;
- size_t filesize;
- const char *input_filename = pInput.getName().c_str();
- const off_t cur_input_offset = pInput.tell();
-
- if (pInput.hasError()) {
- ALOGE("Invalid RS info file %s! (%s)", input_filename,
- pInput.getErrorMessage().c_str());
- goto bail;
- }
-
- filesize = pInput.getSize();
- if (pInput.hasError()) {
- ALOGE("Failed to get the size of RS info file %s! (%s)",
- input_filename, pInput.getErrorMessage().c_str());
- goto bail;
- }
-
- // Create memory map for the file.
- map = pInput.createMap(/* pOffset */cur_input_offset,
- /* pLength */filesize - cur_input_offset);
- if (map == NULL) {
- ALOGE("Failed to map RS info file %s to the memory! (%s)",
- input_filename, pInput.getErrorMessage().c_str());
- goto bail;
- }
-
- data = reinterpret_cast<const uint8_t *>(map->getDataPtr());
-
- // Header starts at the beginning of the file.
- header = reinterpret_cast<const rsinfo::Header *>(data);
-
- // Check the magic.
- if (::memcmp(header->magic, RSINFO_MAGIC, sizeof(header->magic)) != 0) {
- ALOGV("Wrong magic found in the RS info file %s. Treat it as a dirty "
- "cache.", input_filename);
- goto bail;
- }
-
- // Check the version.
- if (::memcmp(header->version,
- RSINFO_VERSION,
- sizeof((header->version)) != 0)) {
- ALOGV("Mismatch the version of RS info file %s: (current) %s v.s. (file) "
- "%s. Treat it as as a dirty cache.", input_filename, RSINFO_VERSION,
- header->version);
- goto bail;
- }
-
- // Check the size.
- if ((header->headerSize != sizeof(rsinfo::Header)) ||
- (header->dependencyTable.itemSize != sizeof(rsinfo::DependencyTableItem)) ||
- (header->pragmaList.itemSize != sizeof(rsinfo::PragmaItem)) ||
- (header->objectSlotList.itemSize != sizeof(rsinfo::ObjectSlotItem)) ||
- (header->exportVarNameList.itemSize != sizeof(rsinfo::ExportVarNameItem)) ||
- (header->exportFuncNameList.itemSize != sizeof(rsinfo::ExportFuncNameItem)) ||
- (header->exportForeachFuncList.itemSize != sizeof(rsinfo::ExportForeachFuncItem))) {
- ALOGW("Corrupted RS info file %s! (unexpected size found)", input_filename);
- goto bail;
- }
-
- // Check the range.
-#define LIST_DATA_RANGE(_list_header) \
- ((_list_header).offset + (_list_header).count * (_list_header).itemSize)
- if (((header->headerSize + header->strPoolSize) > filesize) ||
- (LIST_DATA_RANGE(header->dependencyTable) > filesize) ||
- (LIST_DATA_RANGE(header->pragmaList) > filesize) ||
- (LIST_DATA_RANGE(header->objectSlotList) > filesize) ||
- (LIST_DATA_RANGE(header->exportVarNameList) > filesize) ||
- (LIST_DATA_RANGE(header->exportFuncNameList) > filesize) ||
- (LIST_DATA_RANGE(header->exportForeachFuncList) > filesize)) {
- ALOGW("Corrupted RS info file %s! (data out of the range)", input_filename);
- goto bail;
- }
-#undef LIST_DATA_RANGE
-
- // File seems ok, create result RSInfo object.
- result = new (std::nothrow) RSInfo(header->strPoolSize);
- if (result == NULL) {
- ALOGE("Out of memory when create RSInfo object for %s!", input_filename);
- goto bail;
- }
-
- // Make advice on our access pattern.
- map->advise(android::FileMap::SEQUENTIAL);
-
- // Copy the header.
- ::memcpy(&result->mHeader, header, sizeof(rsinfo::Header));
-
- if (header->strPoolSize > 0) {
- // Copy the string pool. The string pool is immediately after the header at
- // the offset header->headerSize.
- if (result->mStringPool == NULL) {
- ALOGE("Out of memory when allocate string pool for RS info file %s!",
- input_filename);
- goto bail;
- }
- ::memcpy(result->mStringPool, data + result->mHeader.headerSize,
- result->mHeader.strPoolSize);
- }
-
- // Populate all the data to the result object.
- if (!helper_read_list<rsinfo::DependencyTableItem, DependencyTableTy>
- (data, *result, header->dependencyTable, result->mDependencyTable)) {
- goto bail;
- }
-
- // Check dependency to see whether the cache is dirty or not.
- if (!CheckDependency(*result, pInput.getName().c_str(), pDeps)) {
- goto bail;
- }
-
- if (!helper_read_list<rsinfo::PragmaItem, PragmaListTy>
- (data, *result, header->pragmaList, result->mPragmas)) {
- goto bail;
- }
-
- if (!helper_read_list<rsinfo::ObjectSlotItem, ObjectSlotListTy>
- (data, *result, header->objectSlotList, result->mObjectSlots)) {
- goto bail;
- }
-
- if (!helper_read_list<rsinfo::ExportVarNameItem, ExportVarNameListTy>
- (data, *result, header->exportVarNameList, result->mExportVarNames)) {
- goto bail;
- }
-
- if (!helper_read_list<rsinfo::ExportFuncNameItem, ExportFuncNameListTy>
- (data, *result, header->exportFuncNameList, result->mExportFuncNames)) {
- goto bail;
- }
-
- if (!helper_read_list<rsinfo::ExportForeachFuncItem, ExportForeachFuncListTy>
- (data, *result, header->exportForeachFuncList, result->mExportForeachFuncs)) {
- goto bail;
- }
-
- // Clean up.
- map->release();
-
- return result;
-
-bail:
- if (map != NULL) {
- map->release();
- }
-
- delete result;
-
- return NULL;
-} // RSInfo::ReadFromFile
diff --git a/lib/ExecutionEngine/RSInfoWriter.cpp b/lib/ExecutionEngine/RSInfoWriter.cpp
deleted file mode 100644
index d54fb41..0000000
--- a/lib/ExecutionEngine/RSInfoWriter.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//===----------------------------------------------------------------------===//
-// This file implements RSInfo::write()
-//===----------------------------------------------------------------------===//
-
-#include "RSInfo.h"
-
-#include "DebugHelper.h"
-#include "OutputFile.h"
-
-using namespace bcc;
-
-namespace {
-
-template<typename ItemType, typename ItemContainer> inline bool
-helper_adapt_list_item(ItemType &pResult, const RSInfo &pInfo,
- const typename ItemContainer::const_iterator &pItem);
-
-template<> inline bool
-helper_adapt_list_item<rsinfo::DependencyTableItem, RSInfo::DependencyTableTy>(
- rsinfo::DependencyTableItem &pResult,
- const RSInfo &pInfo,
- const RSInfo::DependencyTableTy::const_iterator &pItem) {
- pResult.id = pInfo.getStringIdxInPool(pItem->first);
- pResult.sha1 =
- pInfo.getStringIdxInPool(reinterpret_cast<const char *>(pItem->second));
-
- if (pResult.id == rsinfo::gInvalidStringIndex) {
- ALOGE("RS dependency table contains invalid source id string '%s'.",
- pItem->first);
- return false;
- }
-
- if (pResult.sha1 == rsinfo::gInvalidStringIndex) {
- ALOGE("RS dependency table contains invalid SHA-1 checksum string in '%s'.",
- pItem->first);
- return false;
- }
-
- return true;
-}
-
-template<> inline bool
-helper_adapt_list_item<rsinfo::PragmaItem, RSInfo::PragmaListTy>(
- rsinfo::PragmaItem &pResult,
- const RSInfo &pInfo,
- const RSInfo::PragmaListTy::const_iterator &pItem) {
- pResult.key = pInfo.getStringIdxInPool(pItem->first);
- pResult.value = pInfo.getStringIdxInPool(pItem->second);
-
- if (pResult.key == rsinfo::gInvalidStringIndex) {
- ALOGE("RS pragma list contains invalid string '%s' for key.", pItem->first);
- return false;
- }
-
- if (pResult.value == rsinfo::gInvalidStringIndex) {
- ALOGE("RS pragma list contains invalid string '%s' for value.",
- pItem->second);
- return false;
- }
-
- return true;
-}
-
-template<> inline bool
-helper_adapt_list_item<rsinfo::ObjectSlotItem, RSInfo::ObjectSlotListTy>(
- rsinfo::ObjectSlotItem &pResult,
- const RSInfo &pInfo,
- const RSInfo::ObjectSlotListTy::const_iterator &pItem) {
- pResult.slot = *pItem;
- return true;
-}
-
-template<> inline bool
-helper_adapt_list_item<rsinfo::ExportVarNameItem, RSInfo::ExportVarNameListTy>(
- rsinfo::ExportVarNameItem &pResult,
- const RSInfo &pInfo,
- const RSInfo::ExportVarNameListTy::const_iterator &pItem) {
- pResult.name = pInfo.getStringIdxInPool(*pItem);
-
- if (pResult.name == rsinfo::gInvalidStringIndex) {
- ALOGE("RS export vars contains invalid string '%s' for name.", *pItem);
- return false;
- }
-
- return true;
-}
-
-template<> inline bool
-helper_adapt_list_item<rsinfo::ExportFuncNameItem,
- RSInfo::ExportFuncNameListTy>(
- rsinfo::ExportFuncNameItem &pResult,
- const RSInfo &pInfo,
- const RSInfo::ExportFuncNameListTy::const_iterator &pItem) {
- pResult.name = pInfo.getStringIdxInPool(*pItem);
-
- if (pResult.name == rsinfo::gInvalidStringIndex) {
- ALOGE("RS export funcs contains invalid string '%s' for name.", *pItem);
- return false;
- }
-
- return true;
-}
-
-template<> inline bool
-helper_adapt_list_item<rsinfo::ExportForeachFuncItem,
- RSInfo::ExportForeachFuncListTy>(
- rsinfo::ExportForeachFuncItem &pResult,
- const RSInfo &pInfo,
- const RSInfo::ExportForeachFuncListTy::const_iterator &pItem) {
- pResult.name = pInfo.getStringIdxInPool(pItem->first);
- pResult.signature = pItem->second;
-
- if (pResult.name == rsinfo::gInvalidStringIndex) {
- ALOGE("RS export foreach contains invalid string '%s' for name.",
- pItem->first);
- return false;
- }
-
- return true;
-}
-
-template<typename ItemType, typename ItemContainer>
-inline bool helper_write_list(OutputFile &pOutput,
- const RSInfo &pInfo,
- const rsinfo::ListHeader &pHeader,
- ItemContainer &pList) {
- ItemType item;
-
- for (typename ItemContainer::const_iterator item_iter = pList.begin(),
- item_end = pList.end(); item_iter != item_end; item_iter++) {
- // Convert each entry in the pList to ItemType.
- if (!helper_adapt_list_item<ItemType, ItemContainer>(item,
- pInfo,
- item_iter)) {
- return false;
- }
- // And write out an item.
- if (pOutput.write(&item, sizeof(item)) != sizeof(item)) {
- ALOGE("Cannot write out item of %s for RSInfo file %s! (%s)",
- rsinfo::GetItemTypeName<ItemType>(), pOutput.getName().c_str(),
- pOutput.getErrorMessage().c_str());
- return false;
- }
- }
-
- return true;
-}
-
-} // end anonymous namespace
-
-bool RSInfo::write(OutputFile &pOutput) {
- off_t initial_offset = pOutput.tell();
- const char *output_filename = pOutput.getName().c_str();
-
- if (pOutput.hasError()) {
- ALOGE("Invalid RS info file %s for output! (%s)",
- output_filename, pOutput.getErrorMessage().c_str());
- return false;
- }
-
- // Layout.
- if (!layout(initial_offset)) {
- return false;
- }
-
- // Write header.
- if (pOutput.write(&mHeader, sizeof(mHeader)) != sizeof(mHeader)) {
- ALOGE("Cannot write out the header for RSInfo file %s! (%s)",
- output_filename, pOutput.getErrorMessage().c_str());
- return false;
- }
-
- // Write string pool.
- if (static_cast<size_t>(pOutput.write(mStringPool, mHeader.strPoolSize))
- != mHeader.strPoolSize) {
- ALOGE("Cannot write out the string pool for RSInfo file %s! (%s)",
- output_filename, pOutput.getErrorMessage().c_str());
- return false;
- }
-
- // Write dependencyTable.
- if (!helper_write_list<rsinfo::DependencyTableItem, DependencyTableTy>
- (pOutput, *this, mHeader.dependencyTable, mDependencyTable)) {
- return false;
- }
-
- // Write pragmaList.
- if (!helper_write_list<rsinfo::PragmaItem, PragmaListTy>
- (pOutput, *this, mHeader.pragmaList, mPragmas)) {
- return false;
- }
-
- // Write objectSlotList.
- if (!helper_write_list<rsinfo::ObjectSlotItem, ObjectSlotListTy>
- (pOutput, *this, mHeader.objectSlotList, mObjectSlots)) {
- return false;
- }
-
- // Write exportVarNameList.
- if (!helper_write_list<rsinfo::ExportVarNameItem, ExportVarNameListTy>
- (pOutput, *this, mHeader.exportVarNameList, mExportVarNames)) {
- return false;
- }
-
- // Write exportFuncNameList.
- if (!helper_write_list<rsinfo::ExportFuncNameItem, ExportFuncNameListTy>
- (pOutput, *this, mHeader.exportFuncNameList, mExportFuncNames)) {
- return false;
- }
-
- // Write exportForeachFuncList.
- if (!helper_write_list<rsinfo::ExportForeachFuncItem, ExportForeachFuncListTy>
- (pOutput, *this, mHeader.exportForeachFuncList, mExportForeachFuncs)) {
- return false;
- }
-
- return true;
-}
diff --git a/lib/ExecutionEngine/RSScript.cpp b/lib/ExecutionEngine/RSScript.cpp
index 2ca97a5..d223eee 100644
--- a/lib/ExecutionEngine/RSScript.cpp
+++ b/lib/ExecutionEngine/RSScript.cpp
@@ -56,9 +56,10 @@
namespace bcc {
-RSScript::SourceDependency::SourceDependency(const std::string &pSourceName,
+RSScript::SourceDependency::SourceDependency(MCO_ResourceType pSourceType,
+ const std::string &pSourceName,
const uint8_t *pSHA1)
- : mSourceName(pSourceName) {
+ : mSourceType(pSourceType), mSourceName(pSourceName) {
::memcpy(mSHA1, pSHA1, sizeof(mSHA1));
return;
}
@@ -105,10 +106,11 @@
return true;
}
-bool RSScript::addSourceDependency(const std::string &pSourceName,
+bool RSScript::addSourceDependency(MCO_ResourceType pSourceType,
+ const std::string &pSourceName,
const uint8_t *pSHA1) {
SourceDependency *source_dep =
- new (std::nothrow) SourceDependency(pSourceName, pSHA1);
+ new (std::nothrow) SourceDependency(pSourceType, pSourceName, pSHA1);
if (source_dep == NULL) {
ALOGE("Out of memory when record dependency information of `%s'!",
pSourceName.c_str());
@@ -261,12 +263,13 @@
}
// Dependencies
- reader.addDependency(pathLibBCC_SHA1, sha1LibBCC_SHA1);
- reader.addDependency(pathLibRS, sha1LibRS);
+ reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
+ reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
for (unsigned i = 0; i < mSourceDependencies.size(); i++) {
const SourceDependency *source_dep = mSourceDependencies[i];
- reader.addDependency(source_dep->getSourceName(),
+ reader.addDependency(source_dep->getSourceType(),
+ source_dep->getSourceName(),
source_dep->getSHA1Checksum());
}
@@ -380,13 +383,14 @@
#ifdef TARGET_BUILD
// Dependencies
- writer.addDependency(pathLibBCC_SHA1, sha1LibBCC_SHA1);
- writer.addDependency(pathLibRS, sha1LibRS);
+ writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
+ writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
#endif
for (unsigned i = 0; i < mSourceDependencies.size(); i++) {
const SourceDependency *source_dep = mSourceDependencies[i];
- writer.addDependency(source_dep->getSourceName(),
+ writer.addDependency(source_dep->getSourceType(),
+ source_dep->getSourceName(),
source_dep->getSHA1Checksum());
}
diff --git a/lib/ExecutionEngine/RSScript.h b/lib/ExecutionEngine/RSScript.h
index 50a3eb3..6e4cd9f 100644
--- a/lib/ExecutionEngine/RSScript.h
+++ b/lib/ExecutionEngine/RSScript.h
@@ -38,7 +38,6 @@
}
namespace bcc {
- class RSInfo;
class ScriptCompiled;
class ScriptCached;
class Source;
@@ -65,13 +64,18 @@
public:
class SourceDependency {
private:
+ MCO_ResourceType mSourceType;
std::string mSourceName;
uint8_t mSHA1[20];
public:
- SourceDependency(const std::string &pSourceName,
+ SourceDependency(MCO_ResourceType pSourceType,
+ const std::string &pSourceName,
const uint8_t *pSHA1);
+ inline MCO_ResourceType getSourceType() const
+ { return mSourceType; }
+
inline const std::string &getSourceName() const
{ return mSourceName; }
@@ -109,8 +113,6 @@
llvm::SmallVector<SourceDependency *, 4> mSourceDependencies;
- const RSInfo *mInfo;
-
// External Function List
std::vector<char const *> mUserDefinedExternalSymbols;
@@ -132,19 +134,13 @@
// Add dependency information for this script given the source named
// pSourceName. pSHA1 is the SHA-1 checksum of the given source. Return
// false on error.
- bool addSourceDependency(const std::string &pSourceName,
+ bool addSourceDependency(MCO_ResourceType pSourceType,
+ const std::string &pSourceName,
const uint8_t *pSHA1);
const SourceDependencyListTy &getSourceDependencies() const
{ return mSourceDependencies; }
- // Set the associated RSInfo of the script.
- void setInfo(const RSInfo *pInfo)
- { mInfo = pInfo; }
-
- const RSInfo *getInfo() const
- { return mInfo; }
-
void markExternalSymbol(char const *name) {
mUserDefinedExternalSymbols.push_back(name);
}
diff --git a/lib/ExecutionEngine/bcc.cpp b/lib/ExecutionEngine/bcc.cpp
index 6baa3e0..7425d0a 100644
--- a/lib/ExecutionEngine/bcc.cpp
+++ b/lib/ExecutionEngine/bcc.cpp
@@ -114,7 +114,7 @@
if (need_dependency_check) {
uint8_t sha1[20];
calcSHA1(sha1, pBitcode, pBitcodeSize);
- if (!pScript->addSourceDependency(pName, sha1)) {
+ if (!pScript->addSourceDependency(BCC_APK_RESOURCE, pName, sha1)) {
return false;
}
}
@@ -164,7 +164,7 @@
if (need_dependency_check) {
uint8_t sha1[20];
calcFileSHA1(sha1, pPath);
- if (!pScript->addSourceDependency(pPath, sha1)) {
+ if (!pScript->addSourceDependency(BCC_APK_RESOURCE, pPath, sha1)) {
return false;
}
}