Home | History | Annotate | Download | only in ExecutionEngine
      1 /*
      2  * Copyright 2010, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "SourceInfo.h"
     18 
     19 #if USE_CACHE
     20 #if USE_OLD_JIT
     21 #include "OldJIT/CacheReader.h"
     22 #include "OldJIT/CacheWriter.h"
     23 #endif
     24 #if USE_MCJIT
     25 #include "MCCacheWriter.h"
     26 #include "MCCacheReader.h"
     27 #endif
     28 #endif
     29 
     30 #include "DebugHelper.h"
     31 #include "ScriptCompiled.h"
     32 #include "Sha1Helper.h"
     33 
     34 #include <bcc/bcc.h>
     35 #include <bcc/bcc_cache.h>
     36 
     37 #include <llvm/ADT/OwningPtr.h>
     38 #include <llvm/ADT/StringRef.h>
     39 #include <llvm/Support/MemoryBuffer.h>
     40 #include <llvm/Support/system_error.h>
     41 
     42 #include <stddef.h>
     43 #include <string.h>
     44 
     45 namespace bcc {
     46 
     47 
     48 SourceInfo *SourceInfo::createFromBuffer(char const *resName,
     49                                          char const *bitcode,
     50                                          size_t bitcodeSize,
     51                                          unsigned long flags) {
     52   SourceInfo *result = new SourceInfo();
     53 
     54   if (!result) {
     55     return NULL;
     56   }
     57 
     58   result->type = SourceKind::Buffer;
     59   result->buffer.resName = resName;
     60   result->buffer.bitcode = bitcode;
     61   result->buffer.bitcodeSize = bitcodeSize;
     62   result->flags = flags;
     63 
     64 #if USE_CACHE
     65   if (!resName && !(flags & BCC_SKIP_DEP_SHA1)) {
     66     result->flags |= BCC_SKIP_DEP_SHA1;
     67 
     68     LOGW("It is required to give resName for sha1 dependency check.\n");
     69     LOGW("Sha1sum dependency check will be skipped.\n");
     70     LOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
     71   }
     72 
     73   if (result->flags & BCC_SKIP_DEP_SHA1) {
     74     memset(result->sha1, '\0', 20);
     75   } else {
     76     calcSHA1(result->sha1, bitcode, bitcodeSize);
     77   }
     78 #endif
     79 
     80   return result;
     81 }
     82 
     83 
     84 SourceInfo *SourceInfo::createFromFile(char const *path,
     85                                        unsigned long flags) {
     86   SourceInfo *result = new SourceInfo();
     87 
     88   if (!result) {
     89     return NULL;
     90   }
     91 
     92   result->type = SourceKind::File;
     93   result->file.path = path;
     94   result->flags = flags;
     95 
     96 #if USE_CACHE
     97   memset(result->sha1, '\0', 20);
     98 
     99   if (!(result->flags & BCC_SKIP_DEP_SHA1)) {
    100     calcFileSHA1(result->sha1, path);
    101   }
    102 #endif
    103 
    104   return result;
    105 }
    106 
    107 
    108 SourceInfo *SourceInfo::createFromModule(llvm::Module *module,
    109                                          unsigned long flags) {
    110   SourceInfo *result = new SourceInfo();
    111 
    112   if (!result) {
    113     return NULL;
    114   }
    115 
    116   result->type = SourceKind::Module;
    117   result->module.reset(module);
    118   result->flags = flags;
    119 
    120 #if USE_CACHE
    121   if (! (flags & BCC_SKIP_DEP_SHA1)) {
    122     result->flags |= BCC_SKIP_DEP_SHA1;
    123 
    124     LOGW("Unable to calculate sha1sum for llvm::Module.\n");
    125     LOGW("Sha1sum dependency check will be skipped.\n");
    126     LOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
    127   }
    128 
    129   memset(result->sha1, '\0', 20);
    130 #endif
    131 
    132   return result;
    133 }
    134 
    135 
    136 int SourceInfo::prepareModule(ScriptCompiled *SC) {
    137   switch (type) {
    138   case SourceKind::Buffer:
    139     {
    140       llvm::OwningPtr<llvm::MemoryBuffer> MEM(
    141         llvm::MemoryBuffer::getMemBuffer(
    142           llvm::StringRef(buffer.bitcode, buffer.bitcodeSize)));
    143 
    144       if (!MEM.get()) {
    145         LOGE("Unable to MemoryBuffer::getMemBuffer(addr=%p, size=%lu)\n",
    146              buffer.bitcode, (unsigned long)buffer.bitcodeSize);
    147         return 1;
    148       }
    149 
    150       module.reset(SC->parseBitcodeFile(MEM.get()));
    151     }
    152     break;
    153 
    154   case SourceKind::File:
    155     {
    156       llvm::OwningPtr<llvm::MemoryBuffer> MEM;
    157 
    158       if (llvm::error_code ec = llvm::MemoryBuffer::getFile(file.path, MEM)) {
    159         LOGE("Unable to MemoryBuffer::getFile(path=%s)\n", file.path);
    160         return 1;
    161       }
    162 
    163       module.reset(SC->parseBitcodeFile(MEM.get()));
    164     }
    165     break;
    166 
    167   default:
    168     break;
    169   }
    170 
    171   return (module.get()) ? 0 : 1;
    172 }
    173 
    174 
    175 #if USE_CACHE
    176 template <typename T> void SourceInfo::introDependency(T &checker) {
    177   if (flags & BCC_SKIP_DEP_SHA1) {
    178     return;
    179   }
    180 
    181   switch (type) {
    182   case SourceKind::Buffer:
    183     checker.addDependency(BCC_APK_RESOURCE, buffer.resName, sha1);
    184     break;
    185 
    186   case SourceKind::File:
    187     checker.addDependency(BCC_FILE_RESOURCE, file.path, sha1);
    188     break;
    189 
    190   default:
    191     break;
    192   }
    193 }
    194 
    195 #if USE_OLD_JIT
    196 template void SourceInfo::introDependency<CacheReader>(CacheReader &);
    197 template void SourceInfo::introDependency<CacheWriter>(CacheWriter &);
    198 #endif
    199 
    200 #if USE_MCJIT
    201 template void SourceInfo::introDependency<MCCacheWriter>(MCCacheWriter &);
    202 template void SourceInfo::introDependency<MCCacheReader>(MCCacheReader &);
    203 #endif
    204 #endif // USE_CACHE
    205 
    206 
    207 } // namespace bcc
    208