Remove cachine mechanism.
diff --git a/lib/bcc/Compiler.cpp b/lib/bcc/Compiler.cpp
index f131023..938b3a1 100644
--- a/lib/bcc/Compiler.cpp
+++ b/lib/bcc/Compiler.cpp
@@ -312,11 +312,6 @@
: mpResult(result),
mUseCache(false),
mCacheNew(false),
- mCacheFd(-1),
- mCacheMapAddr(NULL),
- mCacheHdr(NULL),
- mCacheSize(0),
- mCacheDiff(0),
mCacheLoadFailed(false),
mCodeDataAddr(NULL),
mpSymbolLookupFn(NULL),
@@ -350,12 +345,13 @@
long bitcodeFileCRC32,
const BCCchar *resName,
const BCCchar *cacheDir) {
- GlobalInitialization();
+#if 0
this->props.mNoCache = getProp("debug.bcc.nocache");
if (this->props.mNoCache) {
resName = NULL;
}
+#endif
// Compute the SHA1 hash of the input bitcode. So that we can use the hash
// to decide rather to update the cache or not.
@@ -440,322 +436,6 @@
}
-// interface for bccLoadBinary()
-int Compiler::loadCacheFile() {
- // Check File Descriptor
- if (mCacheFd < 0) {
- LOGE("loading cache from invalid mCacheFd = %d\n", (int)mCacheFd);
- goto giveup;
- }
-
- // Check File Size
- struct stat statCacheFd;
- if (fstat(mCacheFd, &statCacheFd) < 0) {
- LOGE("unable to stat mCacheFd = %d\n", (int)mCacheFd);
- goto giveup;
- }
-
- mCacheSize = statCacheFd.st_size;
-
- if (mCacheSize < sizeof(oBCCHeader) ||
- mCacheSize <= MaxCodeSize + MaxGlobalVarSize) {
- LOGE("mCacheFd %d is too small to be correct\n", (int)mCacheFd);
- goto giveup;
- }
-
- if (lseek(mCacheFd, 0, SEEK_SET) != 0) {
- LOGE("Unable to seek to 0: %s\n", strerror(errno));
- goto giveup;
- }
-
- // Part 1. Deal with the non-codedata section first
- {
- // Read cached file and perform quick integrity check
-
- off_t heuristicCodeOffset = mCacheSize - MaxCodeSize - MaxGlobalVarSize;
- LOGW("@loadCacheFile: mCacheSize=%x, heuristicCodeOffset=%llx",
- (unsigned int)mCacheSize,
- (unsigned long long int)heuristicCodeOffset);
-
- mCacheMapAddr = (char *)malloc(heuristicCodeOffset);
- if (!mCacheMapAddr) {
- flock(mCacheFd, LOCK_UN);
- LOGE("allocation failed.\n");
- goto bail;
- }
-
- size_t nread = TEMP_FAILURE_RETRY1(read(mCacheFd, mCacheMapAddr,
- heuristicCodeOffset));
- if (nread != (size_t)heuristicCodeOffset) {
- LOGE("read(mCacheFd) failed\n");
- goto bail;
- }
-
- mCacheHdr = reinterpret_cast<oBCCHeader *>(mCacheMapAddr);
- // Sanity check
- if (mCacheHdr->codeOffset != (uint32_t)heuristicCodeOffset) {
- LOGE("assertion failed: heuristic code offset is not correct.\n");
- goto bail;
- }
- LOGW("mCacheHdr->cachedCodeDataAddr=%x", mCacheHdr->cachedCodeDataAddr);
- LOGW("mCacheHdr->rootAddr=%x", mCacheHdr->rootAddr);
- LOGW("mCacheHdr->initAddr=%x", mCacheHdr->initAddr);
- LOGW("mCacheHdr->codeOffset=%x", mCacheHdr->codeOffset);
- LOGW("mCacheHdr->codeSize=%x", mCacheHdr->codeSize);
-
- // Verify the Cache File
- if (memcmp(mCacheHdr->magic, OBCC_MAGIC, 4) != 0) {
- LOGE("bad magic word\n");
- goto bail;
- }
-
- if (memcmp(mCacheHdr->magicVersion, OBCC_MAGIC_VERS, 4) != 0) {
- LOGE("bad oBCC version 0x%08x\n",
- *reinterpret_cast<uint32_t *>(mCacheHdr->magicVersion));
- goto bail;
- }
-
- if (mCacheSize < mCacheHdr->relocOffset +
- mCacheHdr->relocCount * sizeof(oBCCRelocEntry)) {
- LOGE("relocate table overflow\n");
- goto bail;
- }
-
- if (mCacheSize < mCacheHdr->exportVarsOffset +
- mCacheHdr->exportVarsCount * sizeof(uint32_t)) {
- LOGE("export variables table overflow\n");
- goto bail;
- }
-
- if (mCacheSize < mCacheHdr->exportFuncsOffset +
- mCacheHdr->exportFuncsCount * sizeof(uint32_t)) {
- LOGE("export functions table overflow\n");
- goto bail;
- }
-
- if (mCacheSize < mCacheHdr->exportPragmasOffset +
- mCacheHdr->exportPragmasSize) {
- LOGE("export pragmas table overflow\n");
- goto bail;
- }
-
- if (mCacheSize < mCacheHdr->codeOffset + mCacheHdr->codeSize) {
- LOGE("code cache overflow\n");
- goto bail;
- }
-
- if (mCacheSize < mCacheHdr->dataOffset + mCacheHdr->dataSize) {
- LOGE("data (global variable) cache overflow\n");
- goto bail;
- }
-
- long pagesize = sysconf(_SC_PAGESIZE);
- if (mCacheHdr->codeOffset % pagesize != 0) {
- LOGE("code offset must aligned to pagesize\n");
- goto bail;
- }
- }
-
- // Part 2. Deal with the codedata section
- {
- long pagesize = sysconf(_SC_PAGESIZE);
-
- if (mCacheHdr->cachedCodeDataAddr % pagesize == 0) {
- char *addr = reinterpret_cast<char *>(mCacheHdr->cachedCodeDataAddr);
-
- // Try to allocate context (i.e., mmap) at cached address directly.
- mCodeDataAddr = allocateContext(addr, mCacheFd, mCacheHdr->codeOffset);
- // LOGI("mCodeDataAddr=%x", mCodeDataAddr);
-
- if (!mCodeDataAddr) {
- // Unable to allocate at cached address. Give up.
- flock(mCacheFd, LOCK_UN);
- goto bail;
- }
-
- // Above: Already checked some cache-hit conditions:
- // mCodeDataAddr && mCodeDataAddr != MAP_FAILED
- // Next: Check cache-hit conditions when USE_RELOCATE == false:
- // mCodeDataAddr == addr
- // (When USE_RELOCATE == true, we still don't need to relocate
- // if mCodeDataAddr == addr. But if mCodeDataAddr != addr,
- // that means "addr" is taken by previous mmap and we need
- // to relocate the cache file content to mcodeDataAddr.)
-
-#if !USE_RELOCATE
- if (mCodeDataAddr != addr) {
- flock(mCacheFd, LOCK_UN);
- goto bail;
- }
-#else // USE_RELOCATE == true
-
-#endif // End of #if #else !USE_RELOCATE
-
- // Check the checksum of code and data
- {
- uint32_t sum = mCacheHdr->checksum;
- uint32_t *ptr = (uint32_t *)mCodeDataAddr;
-
- for (size_t i = 0; i < BCC_CONTEXT_SIZE / sizeof(uint32_t); ++i) {
- sum ^= *ptr++;
- }
-
- if (sum != 0) {
- LOGE("Checksum check failed\n");
- goto bail;
- }
-
- LOGI("Passed checksum even parity verification.\n");
- }
-
- flock(mCacheFd, LOCK_UN);
- return 0; // loadCacheFile succeed!
- } // End of "if(mCacheHdr->cachedCodeDataAddr % pagesize == 0)"
- } // End of Part 2. Deal with the codedata section
-
-// Execution will reach here only if (mCacheHdr->cachedCodeDataAddr % pagesize != 0)
-
-#if !USE_RELOCATE
- // Note: If Android.mk set USE_RELOCATE to false, we are not allowed to
- // relocate to the new mCodeDataAddr. That is, we got no
- // choice but give up this cache-hit case: go ahead and recompile the code
-
- flock(mCacheFd, LOCK_UN);
- goto bail;
-
-#else
-
- // Note: Currently, relocation code is not working. Give up now.
- flock(mCacheFd, LOCK_UN);
- goto bail;
-
- // The following code is not working. Don't use them.
- // Rewrite them asap.
-#if 0
- {
- // Try to allocate at arbitary address. And perform relocation.
- mCacheMapAddr = (char *) mmap(0,
- mCacheSize,
- PROT_READ | PROT_EXEC | PROT_WRITE,
- MAP_PRIVATE,
- mCacheFd,
- 0);
-
- if (mCacheMapAddr == MAP_FAILED) {
- LOGE("unable to mmap .oBBC cache: %s\n", strerror(errno));
- flock(mCacheFd, LOCK_UN);
- goto giveup;
- }
-
- flock(mCacheFd, LOCK_UN);
- mCodeDataAddr = mCacheMapAddr + mCacheHdr->codeOffset;
-
- // Relocate
- mCacheDiff = mCodeDataAddr -
- reinterpret_cast<char *>(mCacheHdr->cachedCodeDataAddr);
-
- if (mCacheDiff) { // To relocate
- if (mCacheHdr->rootAddr) {
- mCacheHdr->rootAddr += mCacheDiff;
- }
-
- if (mCacheHdr->initAddr) {
- mCacheHdr->initAddr += mCacheDiff;
- }
-
- oBCCRelocEntry *cachedRelocTable =
- reinterpret_cast<oBCCRelocEntry *>(mCacheMapAddr +
- mCacheHdr->relocOffset);
-
- std::vector<llvm::MachineRelocation> relocations;
-
- // Read in the relocs
- for (size_t i = 0; i < mCacheHdr->relocCount; i++) {
- oBCCRelocEntry *entry = &cachedRelocTable[i];
-
- llvm::MachineRelocation reloc =
- llvm::MachineRelocation::getGV((uintptr_t)entry->relocOffset,
- (unsigned)entry->relocType, 0, 0);
-
- reloc.setResultPointer(
- reinterpret_cast<char *>(entry->cachedResultAddr) + mCacheDiff);
-
- relocations.push_back(reloc);
- }
-
- // Rewrite machine code using llvm::TargetJITInfo relocate
- {
- llvm::TargetMachine *TM = NULL;
- const llvm::Target *Target;
- std::string FeaturesStr;
-
- // Create TargetMachine
- Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
- if (hasError())
- goto bail;
-
- if (!CPU.empty() || !Features.empty()) {
- llvm::SubtargetFeatures F;
- F.setCPU(CPU);
- for (std::vector<std::string>::const_iterator I = Features.begin(),
- E = Features.end(); I != E; I++)
- F.AddFeature(*I);
- FeaturesStr = F.getString();
- }
-
- TM = Target->createTargetMachine(Triple, FeaturesStr);
- if (TM == NULL) {
- setError("Failed to create target machine implementation for the"
- " specified triple '" + Triple + "'");
- goto bail;
- }
-
- TM->getJITInfo()->relocate(mCodeDataAddr,
- &relocations[0], relocations.size(),
- (unsigned char *)mCodeDataAddr+MaxCodeSize);
-
- if (mCodeEmitter.get()) {
- mCodeEmitter->Disassemble(llvm::StringRef("cache"),
- reinterpret_cast<uint8_t*>(mCodeDataAddr),
- 2 * 1024 /*MaxCodeSize*/,
- false);
- }
-
- delete TM;
- }
- } // End of if (mCacheDiff)
-
- return 0; // Success!
- }
-#endif // End of #if 0
-
-#endif // End of #if #else USE_RELOCATE
-
-bail:
- if (mCacheMapAddr) {
- free(mCacheMapAddr);
- }
-
- if (mCodeDataAddr) {
- deallocateContext(mCodeDataAddr);
- }
-
- mCacheMapAddr = NULL;
- mCacheHdr = NULL;
- mCodeDataAddr = NULL;
-
-giveup:
- if (mCacheFd >= 0) {
- close(mCacheFd);
- mCacheFd = -1;
- }
-
- mUseCache = false;
- mCacheLoadFailed = true;
-
- return 1;
-}
-
// interace for bccCompileBC()
int Compiler::compile() {
llvm::TargetData *TD = NULL;
@@ -1068,6 +748,7 @@
if (TM)
delete TM;
+#if 0
if (mError.empty()) {
if (mUseCache && mCacheFd >= 0 && mCacheNew) {
genCacheFile();
@@ -1077,6 +758,7 @@
return false;
}
+#endif
// LOGE(getErrorMessage());
return true;
@@ -1084,6 +766,7 @@
Compiler::~Compiler() {
+#if 0
if (!mCodeMemMgr.get()) {
// mCodeDataAddr and mCacheMapAddr are from loadCacheFile and not
// managed by CodeMemoryManager.
@@ -1099,6 +782,7 @@
mCodeDataAddr = 0;
mCacheMapAddr = 0;
}
+#endif
delete mModule;
delete mContext;
@@ -1118,627 +802,4 @@
}
-
-// Design of caching EXE:
-// ======================
-// 1. Each process will have virtual address available starting at 0x7e00000.
-// E.g., Books and Youtube all have its own 0x7e00000. Next, we should
-// minimize the chance of needing to do relocation INSIDE an app too.
-//
-// 2. Each process will have ONE class static variable called BccCodeAddr.
-// I.e., even though the Compiler class will have multiple Compiler objects,
-// e.g, one object for carousel.rs and the other for pageturn.rs,
-// both Compiler objects will share 1 static variable called BccCodeAddr.
-//
-// Key observation: Every app (process) initiates, say 3, scripts (which
-// correspond to 3 Compiler objects) in the same order, usually.
-//
-// So, we should mmap to, e.g., 0x7e00000, 0x7e40000, 0x7e80000 for the 3
-// scripts, respectively. Each time, BccCodeAddr should be updated after
-// JITTing a script. BTW, in ~Compiler(), BccCodeAddr should NOT be
-// decremented back by CodeDataSize. I.e., for 3 scripts: A, B, C,
-// even if it's A -> B -> ~B -> C -> ~C -> B -> C ... no relocation will
-// ever be needed.)
-//
-// If we are lucky, then we don't need relocation ever, since next time the
-// application gets run, the 3 scripts are likely created in the SAME order.
-//
-//
-// End-to-end algorithm on when to caching and when to JIT:
-// ========================================================
-// Prologue:
-// ---------
-// Assertion: bccReadBC() is always called and is before bccCompileBC(),
-// bccLoadBinary(), ...
-//
-// Key variable definitions: Normally,
-// Compiler::BccCodeAddr: non-zero if (USE_CACHE)
-// | (Stricter, because currently relocation doesn't work. So mUseCache only
-// | when BccCodeAddr is nonzero.)
-// V
-// mUseCache: In addition to (USE_CACHE), resName is non-zero
-// Note: mUseCache will be set to false later on whenever we find that caching
-// won't work. E.g., when mCodeDataAddr != mCacheHdr->cachedCodeDataAddr.
-// This is because currently relocation doesn't work.
-// | (Stricter, initially)
-// V
-// mCacheFd: In addition, >= 0 if openCacheFile() returns >= 0
-// | (Stricter)
-// V
-// mCacheNew: In addition, mCacheFd's size is 0, so need to call genCacheFile()
-// at the end of compile()
-//
-//
-// Main algorithm:
-// ---------------
-// #if !USE_RELOCATE
-// Case 1. ReadBC() doesn't detect a cache file:
-// compile(), which calls genCacheFile() at the end.
-// Note: mCacheNew will guard the invocation of genCacheFile()
-// Case 2. ReadBC() find a cache file
-// loadCacheFile(). But if loadCacheFile() failed, should go to Case 1.
-// #endif
-
-// Note: loadCacheFile() and genCacheFile() go hand in hand
-void Compiler::genCacheFile() {
- if (lseek(mCacheFd, 0, SEEK_SET) != 0) {
- LOGE("Unable to seek to 0: %s\n", strerror(errno));
- return;
- }
-
- bool codeOffsetNeedPadding = false;
-
- uint32_t offset = sizeof(oBCCHeader);
-
- // BCC Cache File Header
- oBCCHeader *hdr = (oBCCHeader *)malloc(sizeof(oBCCHeader));
-
- if (!hdr) {
- LOGE("Unable to allocate oBCCHeader.\n");
- return;
- }
-
- // Magic Words
- memcpy(hdr->magic, OBCC_MAGIC, 4);
- memcpy(hdr->magicVersion, OBCC_MAGIC_VERS, 4);
-
- // Timestamp
- hdr->sourceWhen = 0; // TODO(sliao)
- hdr->rslibWhen = 0; // TODO(sliao)
- hdr->libRSWhen = statModifyTime(libRSPath);
- hdr->libbccWhen = statModifyTime(libBccPath);
-
- // Copy the hash checksum
- memcpy(hdr->sourceSHA1, mSourceSHA1, 20);
-
- // Current Memory Address (Saved for Recalculation)
- hdr->cachedCodeDataAddr = reinterpret_cast<uint32_t>(mCodeDataAddr);
- hdr->rootAddr = reinterpret_cast<uint32_t>(mpResult->lookup("root"));
- hdr->initAddr = reinterpret_cast<uint32_t>(mpResult->lookup("init"));
-
- // Check libRS isThreadable
- if (!mCodeEmitter) {
- hdr->libRSThreadable = 0;
- } else {
- hdr->libRSThreadable =
- (uint32_t) mCodeEmitter->mpSymbolLookupFn(mpSymbolLookupContext,
- "__isThreadable");
- }
-
- // Relocation Table Offset and Entry Count
- hdr->relocOffset = sizeof(oBCCHeader);
- hdr->relocCount = mCodeEmitter->getCachingRelocations().size();
-
- offset += hdr->relocCount * sizeof(oBCCRelocEntry);
-
- // Export Variable Table Offset and Entry Count
- hdr->exportVarsOffset = offset;
- hdr->exportVarsCount = mpResult->mExportVars.size();
-
- offset += hdr->exportVarsCount * sizeof(uint32_t);
-
- // Export Function Table Offset and Entry Count
- hdr->exportFuncsOffset = offset;
- hdr->exportFuncsCount = mpResult->mExportFuncs.size();
-
- offset += hdr->exportFuncsCount * sizeof(uint32_t);
-
- // Export Pragmas Table Offset and Entry Count
- hdr->exportPragmasOffset = offset;
- hdr->exportPragmasCount = mpResult->mPragmas.size();
- hdr->exportPragmasSize = hdr->exportPragmasCount * sizeof(oBCCPragmaEntry);
-
- offset += hdr->exportPragmasCount * sizeof(oBCCPragmaEntry);
-
- for (ScriptCompiled::PragmaList::const_iterator
- I = mpResult->mPragmas.begin(),
- E = mpResult->mPragmas.end(); I != E; ++I) {
- offset += I->first.size() + 1;
- offset += I->second.size() + 1;
- hdr->exportPragmasSize += I->first.size() + I->second.size() + 2;
- }
-
- // Code Offset and Size
-
- { // Always pad to the page boundary for now
- long pagesize = sysconf(_SC_PAGESIZE);
-
- if (offset % pagesize > 0) {
- codeOffsetNeedPadding = true;
- offset += pagesize - (offset % pagesize);
- }
- }
-
- hdr->codeOffset = offset;
- hdr->codeSize = MaxCodeSize;
-
- offset += hdr->codeSize;
-
- // Data (Global Variable) Offset and Size
- hdr->dataOffset = offset;
- hdr->dataSize = MaxGlobalVarSize;
-
- offset += hdr->dataSize;
-
- // Checksum
-#if 1
- {
- // Note: This is an simple checksum implementation that are using xor
- // to calculate even parity (for code and data only).
-
- uint32_t sum = 0;
- uint32_t *ptr = (uint32_t *)mCodeDataAddr;
-
- for (size_t i = 0; i < BCC_CONTEXT_SIZE / sizeof(uint32_t); ++i) {
- sum ^= *ptr++;
- }
-
- hdr->checksum = sum;
- }
-#else
- hdr->checksum = 0; // Set Field checksum. TODO(all)
-#endif
-
- // Write Header
- sysWriteFully(mCacheFd, reinterpret_cast<char const *>(hdr),
- sizeof(oBCCHeader), "Write oBCC header");
-
- // Write Relocation Entry Table
- {
- size_t allocSize = hdr->relocCount * sizeof(oBCCRelocEntry);
-
- oBCCRelocEntry const*records = &mCodeEmitter->getCachingRelocations()[0];
-
- sysWriteFully(mCacheFd, reinterpret_cast<char const *>(records),
- allocSize, "Write Relocation Entries");
- }
-
- // Write Export Variables Table
- {
- uint32_t *record, *ptr;
-
- record = (uint32_t *)calloc(hdr->exportVarsCount, sizeof(uint32_t));
- ptr = record;
-
- if (!record) {
- goto bail;
- }
-
- for (ScriptCompiled::ExportVarList::const_iterator
- I = mpResult->mExportVars.begin(),
- E = mpResult->mExportVars.end(); I != E; I++) {
- *ptr++ = reinterpret_cast<uint32_t>(*I);
- }
-
- sysWriteFully(mCacheFd, reinterpret_cast<char const *>(record),
- hdr->exportVarsCount * sizeof(uint32_t),
- "Write ExportVars");
-
- free(record);
- }
-
- // Write Export Functions Table
- {
- uint32_t *record, *ptr;
-
- record = (uint32_t *)calloc(hdr->exportFuncsCount, sizeof(uint32_t));
- ptr = record;
-
- if (!record) {
- goto bail;
- }
-
- for (ScriptCompiled::ExportFuncList::const_iterator
- I = mpResult->mExportFuncs.begin(),
- E = mpResult->mExportFuncs.end(); I != E; I++) {
- *ptr++ = reinterpret_cast<uint32_t>(*I);
- }
-
- sysWriteFully(mCacheFd, reinterpret_cast<char const *>(record),
- hdr->exportFuncsCount * sizeof(uint32_t),
- "Write ExportFuncs");
-
- free(record);
- }
-
-
- // Write Export Pragmas Table
- {
- uint32_t pragmaEntryOffset =
- hdr->exportPragmasCount * sizeof(oBCCPragmaEntry);
-
- for (ScriptCompiled::PragmaList::const_iterator
- I = mpResult->mPragmas.begin(),
- E = mpResult->mPragmas.end(); I != E; ++I) {
- oBCCPragmaEntry entry;
-
- entry.pragmaNameOffset = pragmaEntryOffset;
- entry.pragmaNameSize = I->first.size();
- pragmaEntryOffset += entry.pragmaNameSize + 1;
-
- entry.pragmaValueOffset = pragmaEntryOffset;
- entry.pragmaValueSize = I->second.size();
- pragmaEntryOffset += entry.pragmaValueSize + 1;
-
- sysWriteFully(mCacheFd, (char *)&entry, sizeof(oBCCPragmaEntry),
- "Write export pragma entry");
- }
-
- for (ScriptCompiled::PragmaList::const_iterator
- I = mpResult->mPragmas.begin(),
- E = mpResult->mPragmas.end(); I != E; ++I) {
- sysWriteFully(mCacheFd, I->first.c_str(), I->first.size() + 1,
- "Write export pragma name string");
- sysWriteFully(mCacheFd, I->second.c_str(), I->second.size() + 1,
- "Write export pragma value string");
- }
- }
-
- if (codeOffsetNeedPadding) {
- // requires additional padding
- lseek(mCacheFd, hdr->codeOffset, SEEK_SET);
- }
-
- // Write Generated Code and Global Variable
- sysWriteFully(mCacheFd, mCodeDataAddr, MaxCodeSize + MaxGlobalVarSize,
- "Write code and global variable");
-
- goto close_return;
-
-bail:
- if (ftruncate(mCacheFd, 0) != 0) {
- LOGW("Warning: unable to truncate cache file: %s\n", strerror(errno));
- }
-
-close_return:
- free(hdr);
- close(mCacheFd);
- mCacheFd = -1;
-}
-
-
-// OpenCacheFile() returns fd of the cache file.
-// Input:
-// BCCchar *resName: Used to genCacheFileName()
-// bool createIfMissing: If false, turn off caching
-// Output:
-// returns fd: If -1: Failed
-// mCacheNew: If true, the returned fd is new. Otherwise, the fd is the
-// cache file's file descriptor
-// Note: openCacheFile() will check the cache file's validity,
-// such as Magic number, sourceWhen... dependencies.
-int Compiler::openCacheFile(const BCCchar *resName,
- const BCCchar *cacheDir,
- bool createIfMissing) {
- int fd, cc;
- struct stat fdStat, fileStat;
- bool readOnly = false;
-
- char *cacheFileName = genCacheFileName(cacheDir, resName, ".oBCC");
-
- mCacheNew = false;
-
-retry:
- /*
- * Try to open the cache file. If we've been asked to,
- * create it if it doesn't exist.
- */
- fd = createIfMissing ? open(cacheFileName, O_CREAT|O_RDWR, 0644) : -1;
- if (fd < 0) {
- fd = open(cacheFileName, O_RDONLY, 0);
- if (fd < 0) {
- if (createIfMissing) {
- LOGW("Can't open bcc-cache '%s': %s\n",
- cacheFileName, strerror(errno));
- mUseCache = false;
- }
- return fd;
- }
- readOnly = true;
- }
-
- /*
- * Grab an exclusive lock on the cache file. If somebody else is
- * working on it, we'll block here until they complete.
- */
- LOGV("bcc: locking cache file %s (fd=%d, boot=%d)\n",
- cacheFileName, fd);
-
- cc = flock(fd, LOCK_EX | LOCK_NB);
- if (cc != 0) {
- LOGD("bcc: sleeping on flock(%s)\n", cacheFileName);
- cc = flock(fd, LOCK_EX);
- }
-
- if (cc != 0) {
- LOGE("Can't lock bcc cache '%s': %d\n", cacheFileName, cc);
- close(fd);
- return -1;
- }
- LOGV("bcc: locked cache file\n");
-
- /*
- * Check to see if the fd we opened and locked matches the file in
- * the filesystem. If they don't, then somebody else unlinked ours
- * and created a new file, and we need to use that one instead. (If
- * we caught them between the unlink and the create, we'll get an
- * ENOENT from the file stat.)
- */
- cc = fstat(fd, &fdStat);
- if (cc != 0) {
- LOGE("Can't stat open file '%s'\n", cacheFileName);
- LOGV("bcc: unlocking cache file %s\n", cacheFileName);
- goto close_fail;
- }
- cc = stat(cacheFileName, &fileStat);
- if (cc != 0 ||
- fdStat.st_dev != fileStat.st_dev || fdStat.st_ino != fileStat.st_ino) {
- LOGD("bcc: our open cache file is stale; sleeping and retrying\n");
- LOGV("bcc: unlocking cache file %s\n", cacheFileName);
- flock(fd, LOCK_UN);
- close(fd);
- usleep(250 * 1000); // if something is hosed, don't peg machine
- goto retry;
- }
-
- /*
- * We have the correct file open and locked. If the file size is zero,
- * then it was just created by us, and we want to fill in some fields
- * in the "bcc" header and set "mCacheNew". Otherwise, we want to
- * verify that the fields in the header match our expectations, and
- * reset the file if they don't.
- */
- if (fdStat.st_size == 0) {
- if (readOnly) { // The device is readOnly --> close_fail
- LOGW("bcc: file has zero length and isn't writable\n");
- goto close_fail;
- }
- /*cc = createEmptyHeader(fd);
- if (cc != 0)
- goto close_fail;
- */
- mCacheNew = true;
- LOGV("bcc: successfully initialized new cache file\n");
- } else {
- // Calculate sourceWhen
- // XXX
- long sourceWhen = 0;
- uint32_t rslibWhen = 0;
- uint32_t libRSWhen = statModifyTime(libRSPath);
- uint32_t libbccWhen = statModifyTime(libBccPath);
- if (!checkHeaderAndDependencies(fd,
- sourceWhen,
- rslibWhen,
- libRSWhen,
- libbccWhen)) {
- // If checkHeaderAndDependencies returns 0: FAILED
- // Will truncate the file and retry to createIfMissing the file
-
- if (readOnly) { // Shouldn't be readonly.
- /*
- * We could unlink and rewrite the file if we own it or
- * the "sticky" bit isn't set on the directory. However,
- * we're not able to truncate it, which spoils things. So,
- * give up now.
- */
- if (createIfMissing) {
- LOGW("Cached file %s is stale and not writable\n",
- cacheFileName);
- }
- goto close_fail;
- }
-
- /*
- * If we truncate the existing file before unlinking it, any
- * process that has it mapped will fail when it tries to touch
- * the pages? Probably OK because we use MAP_PRIVATE.
- */
- LOGD("oBCC file is stale or bad; removing and retrying (%s)\n",
- cacheFileName);
- if (ftruncate(fd, 0) != 0) {
- LOGW("Warning: unable to truncate cache file '%s': %s\n",
- cacheFileName, strerror(errno));
- /* keep going */
- }
- if (unlink(cacheFileName) != 0) {
- LOGW("Warning: unable to remove cache file '%s': %d %s\n",
- cacheFileName, errno, strerror(errno));
- /* keep going; permission failure should probably be fatal */
- }
- LOGV("bcc: unlocking cache file %s\n", cacheFileName);
- flock(fd, LOCK_UN);
- close(fd);
- goto retry;
- } else {
- // Got cacheFile! Good to go.
- LOGV("Good cache file\n");
- }
- }
-
- assert(fd >= 0);
- return fd;
-
-close_fail:
- flock(fd, LOCK_UN);
- close(fd);
- return -1;
-} // End of openCacheFile()
-
-// Input: cacheDir
-// Input: resName
-// Input: extName
-//
-// Note: cacheFile = resName + extName
-//
-// Output: Returns cachePath == cacheDir + cacheFile
-char *Compiler::genCacheFileName(const char *cacheDir,
- const char *resName,
- const char *extName) {
- char cachePath[512];
- char cacheFile[sizeof(cachePath)];
- const size_t kBufLen = sizeof(cachePath) - 1;
-
- cacheFile[0] = '\0';
- // Note: resName today is usually something like
- // "/com.android.fountain:raw/fountain"
- if (resName[0] != '/') {
- // Get the absolute path of the raw/***.bc file.
-
- // Generate the absolute path. This doesn't do everything it
- // should, e.g. if resName is "./out/whatever" it doesn't crunch
- // the leading "./" out because this if-block is not triggered,
- // but it'll make do.
- //
- if (getcwd(cacheFile, kBufLen) == NULL) {
- LOGE("Can't get CWD while opening raw/***.bc file\n");
- return NULL;
- }
- // Append "/" at the end of cacheFile so far.
- strncat(cacheFile, "/", kBufLen);
- }
-
- // cacheFile = resName + extName
- //
- strncat(cacheFile, resName, kBufLen);
- if (extName != NULL) {
- // TODO(srhines): strncat() is a bit dangerous
- strncat(cacheFile, extName, kBufLen);
- }
-
- // Turn the path into a flat filename by replacing
- // any slashes after the first one with '@' characters.
- char *cp = cacheFile + 1;
- while (*cp != '\0') {
- if (*cp == '/') {
- *cp = '@';
- }
- cp++;
- }
-
- // Tack on the file name for the actual cache file path.
- strncpy(cachePath, cacheDir, kBufLen);
- strncat(cachePath, cacheFile, kBufLen);
-
- LOGV("Cache file for '%s' '%s' is '%s'\n", resName, extName, cachePath);
- return strdup(cachePath);
-}
-
-/*
- * Read the oBCC header, verify it, then read the dependent section
- * and verify that data as well.
- *
- * On successful return, the file will be seeked immediately past the
- * oBCC header.
- */
-bool Compiler::checkHeaderAndDependencies(int fd,
- long sourceWhen,
- uint32_t rslibWhen,
- uint32_t libRSWhen,
- uint32_t libbccWhen) {
- oBCCHeader optHdr;
-
- // The header is guaranteed to be at the start of the cached file.
- // Seek to the start position.
- if (lseek(fd, 0, SEEK_SET) != 0) {
- LOGE("bcc: failed to seek to start of file: %s\n", strerror(errno));
- return false;
- }
-
- // Read and do trivial verification on the bcc header. The header is
- // always in host byte order.
- ssize_t nread = read(fd, &optHdr, sizeof(optHdr));
- if (nread < 0) {
- LOGE("bcc: failed reading bcc header: %s\n", strerror(errno));
- return false;
- } else if (nread != sizeof(optHdr)) {
- LOGE("bcc: failed reading bcc header (got %d of %zd)\n",
- (int) nread, sizeof(optHdr));
- return false;
- }
-
- uint8_t const *magic = optHdr.magic;
- if (memcmp(magic, OBCC_MAGIC, 4) != 0) {
- /* not an oBCC file, or previous attempt was interrupted */
- LOGD("bcc: incorrect opt magic number (0x%02x %02x %02x %02x)\n",
- magic[0], magic[1], magic[2], magic[3]);
- return false;
- }
-
- uint8_t const *magicVer = optHdr.magicVersion;
- if (memcmp(magicVer, OBCC_MAGIC_VERS, 4) != 0) {
- LOGW("bcc: stale oBCC version (0x%02x %02x %02x %02x)\n",
- magicVer[0], magicVer[1], magicVer[2], magicVer[3]);
- return false;
- }
-
- // Check the file dependencies
- uint32_t val;
-
- val = optHdr.rslibWhen;
- if (val && (val != rslibWhen)) {
- LOGI("bcc: rslib file mod time mismatch (%08x vs %08x)\n",
- val, rslibWhen);
- return false;
- }
-
- val = optHdr.libRSWhen;
- if (val && (val != libRSWhen)) {
- LOGI("bcc: libRS file mod time mismatch (%08x vs %08x)\n",
- val, libRSWhen);
- return false;
- }
-
- val = optHdr.libbccWhen;
- if (val && (val != libbccWhen)) {
- LOGI("bcc: libbcc file mod time mismatch (%08x vs %08x)\n",
- val, libbccWhen);
- return false;
- }
-
- if (memcmp(optHdr.sourceSHA1, mSourceSHA1, 20) != 0) {
- LOGE("Bitcode SHA1 mismatch. Cache is outdated.\n");
-
-#define PRINT_SHA1SUM(PREFIX, POSTFIX, D) \
- LOGE(PREFIX "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" POSTFIX, \
- D[0], D[1], D[2], D[3], D[4], D[5], D[6], D[7], D[8], D[9], \
- D[10], D[11], D[12], D[13], D[14], D[15], D[16], D[17], D[18], D[19]);
-
- PRINT_SHA1SUM("Note: Bitcode sha1sum: ", "\n", mSourceSHA1);
- PRINT_SHA1SUM("Note: Cached sha1sum: ", "\n", optHdr.sourceSHA1);
-
-#undef PRINT_SHA1SUM
-
- return false;
- }
-
- // Check the cache file has __isThreadable or not. If it is set,
- // then we have to call mpSymbolLookupFn for __clearThreadable.
- if (optHdr.libRSThreadable && mpSymbolLookupFn) {
- mpSymbolLookupFn(mpSymbolLookupContext, "__clearThreadable");
- }
-
- return true;
-}
-
} // namespace bcc
diff --git a/lib/bcc/Compiler.h b/lib/bcc/Compiler.h
index d3bfb5f..f76d71e 100644
--- a/lib/bcc/Compiler.h
+++ b/lib/bcc/Compiler.h
@@ -66,8 +66,6 @@
// be a list of strings starting with '+' (enable) or '-' (disable).
static std::vector<std::string> Features;
- static void GlobalInitialization();
-
static void LLVMErrorHandler(void *UserData, const std::string &Message);
static const llvm::StringRef PragmaMetadataName;
@@ -85,11 +83,6 @@
bool mUseCache; // Set by readBC()
bool mCacheNew; // Set by readBC()
- int mCacheFd; // Set by readBC()
- char *mCacheMapAddr; // Set by loadCacheFile() if mCacheNew is false
- oBCCHeader *mCacheHdr; // Set by loadCacheFile()
- size_t mCacheSize; // Set by loadCacheFile()
- ptrdiff_t mCacheDiff; // Set by loadCacheFile()
bool mCacheLoadFailed; // Set by loadCacheFile() used by readBC()
char *mCodeDataAddr; // Set by CodeMemoryManager if mCacheNew is true.
// Used by genCacheFile() for dumping
@@ -113,6 +106,8 @@
public:
Compiler(ScriptCompiled *result);
+ static void GlobalInitialization();
+
// interface for BCCscript::registerSymbolCallback()
void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext) {
mpSymbolLookupFn = pFn;
@@ -124,7 +119,6 @@
CodeEmitter *createCodeEmitter();
int readModule(llvm::Module *module) {
- GlobalInitialization();
mModule = module;
return hasError();
}
@@ -138,9 +132,6 @@
int linkBC(const char *bitcode, size_t bitcodeSize);
- // interface for bccLoadBinary()
- int loadCacheFile();
-
// interace for bccCompileBC()
int compile();
@@ -158,45 +149,11 @@
private:
void computeSourceSHA1(char const *bitcode, size_t size);
- // Note: loadCacheFile() and genCacheFile() go hand in hand
- void genCacheFile();
-
- // OpenCacheFile() returns fd of the cache file.
- // Input:
- // BCCchar *resName: Used to genCacheFileName()
- // bool createIfMissing: If false, turn off caching
- // Output:
- // returns fd: If -1: Failed
- // mCacheNew: If true, the returned fd is new. Otherwise, the fd is the
- // cache file's file descriptor
- // Note: openCacheFile() will check the cache file's validity,
- // such as Magic number, sourceWhen... dependencies.
- int openCacheFile(const BCCchar *resName,
- const BCCchar *cacheDir,
- bool createIfMissing);
char *genCacheFileName(const char *cacheDir,
const char *fileName,
const char *subFileName);
- /*
- * Read the oBCC header, verify it, then read the dependent section
- * and verify that data as well.
- *
- * On successful return, the file will be seeked immediately past the
- * oBCC header.
- */
- bool checkHeaderAndDependencies(int fd,
- long sourceWhen,
- uint32_t rslibWhen,
- uint32_t libRSWhen,
- uint32_t libbccWhen);
-
-
- struct {
- bool mNoCache;
- } props;
-
private:
diff --git a/lib/bcc/Script.cpp b/lib/bcc/Script.cpp
index a53377a..e7cc628 100644
--- a/lib/bcc/Script.cpp
+++ b/lib/bcc/Script.cpp
@@ -23,6 +23,69 @@
#include <new>
+namespace {
+
+// Input: cacheDir
+// Input: resName
+// Input: extName
+//
+// Note: cacheFile = resName + extName
+//
+// Output: Returns cachePath == cacheDir + cacheFile
+char *genCacheFileName(const char *cacheDir,
+ const char *resName,
+ const char *extName) {
+ char cachePath[512];
+ char cacheFile[sizeof(cachePath)];
+ const size_t kBufLen = sizeof(cachePath) - 1;
+
+ cacheFile[0] = '\0';
+ // Note: resName today is usually something like
+ // "/com.android.fountain:raw/fountain"
+ if (resName[0] != '/') {
+ // Get the absolute path of the raw/***.bc file.
+
+ // Generate the absolute path. This doesn't do everything it
+ // should, e.g. if resName is "./out/whatever" it doesn't crunch
+ // the leading "./" out because this if-block is not triggered,
+ // but it'll make do.
+ //
+ if (getcwd(cacheFile, kBufLen) == NULL) {
+ LOGE("Can't get CWD while opening raw/***.bc file\n");
+ return NULL;
+ }
+ // Append "/" at the end of cacheFile so far.
+ strncat(cacheFile, "/", kBufLen);
+ }
+
+ // cacheFile = resName + extName
+ //
+ strncat(cacheFile, resName, kBufLen);
+ if (extName != NULL) {
+ // TODO(srhines): strncat() is a bit dangerous
+ strncat(cacheFile, extName, kBufLen);
+ }
+
+ // Turn the path into a flat filename by replacing
+ // any slashes after the first one with '@' characters.
+ char *cp = cacheFile + 1;
+ while (*cp != '\0') {
+ if (*cp == '/') {
+ *cp = '@';
+ }
+ cp++;
+ }
+
+ // Tack on the file name for the actual cache file path.
+ strncpy(cachePath, cacheDir, kBufLen);
+ strncat(cachePath, cacheFile, kBufLen);
+
+ LOGV("Cache file for '%s' '%s' is '%s'\n", resName, extName, cachePath);
+ return strdup(cachePath);
+}
+
+} // namespace anonymous
+
namespace bcc {
Script::~Script() {
@@ -38,54 +101,31 @@
long bitcodeFileCRC32,
const BCCchar *resName,
const BCCchar *cacheDir) {
- if (mStatus == ScriptStatus::Unknown) {
- mCompiled = new (nothrow) ScriptCompiled(this);
-
- if (!mCompiled) {
- mErrorCode = BCC_OUT_OF_MEMORY;
- return 1;
- }
-
- mStatus = ScriptStatus::Compiled;
- }
-
- if (mStatus != ScriptStatus::Compiled) {
+ if (mStatus != ScriptStatus::Unknown) {
mErrorCode = BCC_INVALID_OPERATION;
+ LOGE("Invalid operation: %s\n", __func__);
return 1;
}
- if (mpExtSymbolLookupFn) {
- mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
- mpExtSymbolLookupFnContext);
- }
+ cacheFile = genCacheFileName(cacheDir, resName, ".oBCC");
- return mCompiled->readBC(bitcode, bitcodeSize,
- bitcodeFileModTime, bitcodeFileCRC32,
- resName, cacheDir);
+ sourceBC = bitcode;
+ sourceResName = resName;
+ sourceSize = bitcodeSize;
+
+ return 0;
}
int Script::readModule(llvm::Module *module) {
if (mStatus != ScriptStatus::Unknown) {
mErrorCode = BCC_INVALID_OPERATION;
+ LOGE("Invalid operation: %s\n", __func__);
return 1;
}
- mCompiled = new (nothrow) ScriptCompiled(this);
-
- if (!mCompiled) {
- mErrorCode = BCC_OUT_OF_MEMORY;
- return 1;
- }
-
- mStatus = ScriptStatus::Compiled;
-
- if (mpExtSymbolLookupFn) {
- mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
- mpExtSymbolLookupFnContext);
- }
-
- return mCompiled->readModule(module);
+ sourceModule = module;
+ return 0;
}
@@ -99,22 +139,46 @@
}
-int Script::loadCacheFile() {
- if (mStatus != ScriptStatus::Compiled) {
- mErrorCode = BCC_INVALID_OPERATION;
- return 1;
- }
-
- return mCompiled->loadCacheFile();
-}
-
-
int Script::compile() {
- if (mStatus != ScriptStatus::Compiled) {
+ if (mStatus != ScriptStatus::Unknown) {
mErrorCode = BCC_INVALID_OPERATION;
+ LOGE("Invalid operation: %s\n", __func__);
return 1;
}
+ // Load Cache File
+ // TODO(logan): Complete this.
+
+ // Compile
+ mCompiled = new (nothrow) ScriptCompiled(this);
+
+ if (!mCompiled) {
+ mErrorCode = BCC_OUT_OF_MEMORY;
+ LOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+
+ mStatus = ScriptStatus::Compiled;
+
+ if (mpExtSymbolLookupFn) {
+ mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
+ mpExtSymbolLookupFnContext);
+ }
+
+ if (sourceBC) {
+ int ret = mCompiled->readBC(sourceBC, sourceSize, 0, 0, sourceResName, 0);
+ if (ret != 0) {
+ return ret;
+ }
+ } else if (sourceModule) {
+ int ret = mCompiled->readModule(sourceModule);
+ if (ret != 0) {
+ return ret;
+ }
+ }
+
+ // TODO(logan): Link
+
return mCompiled->compile();
}
diff --git a/lib/bcc/Script.h b/lib/bcc/Script.h
index 3e5f74e..8e174fe 100644
--- a/lib/bcc/Script.h
+++ b/lib/bcc/Script.h
@@ -19,6 +19,8 @@
#include <bcc/bcc.h>
+#include "Compiler.h"
+
namespace llvm {
class Module;
}
@@ -46,11 +48,23 @@
ScriptCached *mCached;
};
+ char *cacheFile;
+
+ // ReadBC
+ char const *sourceBC;
+ char const *sourceResName;
+ int sourceSize;
+
+ // ReadModule
+ llvm::Module *sourceModule;
+
+ // Register Symbol Lookup Function
BCCSymbolLookupFn mpExtSymbolLookupFn;
BCCvoid *mpExtSymbolLookupFnContext;
public:
Script() : mErrorCode(BCC_NO_ERROR), mStatus(ScriptStatus::Unknown) {
+ Compiler::GlobalInitialization();
}
~Script();
@@ -62,11 +76,11 @@
const BCCchar *resName,
const BCCchar *cacheDir);
+ int readModule(llvm::Module *module);
+
int linkBC(const char *bitcode, size_t bitcodeSize);
- int loadCacheFile();
-
- int compile();
+ int compile(); // deprecated
char const *getCompilerErrorMessage();
@@ -94,8 +108,6 @@
void registerSymbolCallback(BCCSymbolLookupFn pFn, BCCvoid *pContext);
- int readModule(llvm::Module *module);
-
void setError(BCCenum error) {
if (mErrorCode == BCC_NO_ERROR && error != BCC_NO_ERROR) {
diff --git a/lib/bcc/ScriptCompiled.h b/lib/bcc/ScriptCompiled.h
index e271042..e769500 100644
--- a/lib/bcc/ScriptCompiled.h
+++ b/lib/bcc/ScriptCompiled.h
@@ -76,10 +76,6 @@
return mCompiler.linkBC(bitcode, bitcodeSize);
}
- int loadCacheFile() {
- return mCompiler.loadCacheFile();
- }
-
int compile() {
return mCompiler.compile();
}
diff --git a/lib/bcc/bcc.cpp b/lib/bcc/bcc.cpp
index e2a4be6..776f3d1 100644
--- a/lib/bcc/bcc.cpp
+++ b/lib/bcc/bcc.cpp
@@ -97,17 +97,8 @@
}
extern "C" int bccLoadBinary(BCCscript *script) {
- BCC_FUNC_LOGGER();
- int result = script->loadCacheFile();
-
-#if defined(USE_DISASSEMBLER_FILE)
- LOGI("[LoadBinary] result=%d", result);
-#endif
- if (result) {
- script->setError(BCC_INVALID_OPERATION);
- }
-
- return result;
+ LOGE("bccLoadBinary is deprecated **************************\n");
+ return 1;
}
extern "C" int bccCompileBC(BCCscript *script) {