blob: ddd9933ecc2ade0b7973558b4d9018de1abfc734 [file] [log] [blame]
Logancf3e5212010-12-29 01:44:55 +08001/*
Stephen Hinescc366e52012-02-21 17:22:04 -08002 * copyright 2010-2012, the android open source project
Logancf3e5212010-12-29 01:44:55 +08003 *
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
Logancf3e5212010-12-29 01:44:55 +080017#include "Script.h"
18
Logan35849002011-01-15 07:30:43 +080019#include "Config.h"
20
Logan Chiend2a5f302011-07-19 20:32:25 +080021#if USE_OLD_JIT
22#include "OldJIT/CacheReader.h"
23#include "OldJIT/CacheWriter.h"
24#endif
25
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -070026#include "MCCacheReader.h"
27#include "MCCacheWriter.h"
Zonr Chang2fcbd022012-01-06 21:04:31 +080028#include "CompilerOption.h"
Logan Chiend2a5f302011-07-19 20:32:25 +080029
30#if USE_OLD_JIT
31#include "OldJIT/ContextManager.h"
32#endif
33
Logan4dcd6792011-02-28 05:12:00 +080034#include "DebugHelper.h"
Logan04329712011-01-06 06:10:57 +080035#include "FileHandle.h"
Logancf3e5212010-12-29 01:44:55 +080036#include "ScriptCompiled.h"
Logan9a5f8682011-01-07 06:09:57 +080037#include "ScriptCached.h"
38#include "Sha1Helper.h"
Logan474cbd22011-01-31 01:47:44 +080039#include "SourceInfo.h"
Logancf3e5212010-12-29 01:44:55 +080040
Logan89eb47f2011-01-07 10:45:16 +080041#include <errno.h>
Logan474cbd22011-01-31 01:47:44 +080042#include <sys/stat.h>
43#include <sys/types.h>
Bhanu Chetlapallieb4509b2012-01-08 20:42:56 -080044#include <unistd.h>
Logancf3e5212010-12-29 01:44:55 +080045
Logan89eb47f2011-01-07 10:45:16 +080046#include <new>
47#include <string.h>
Logan033f46e2011-01-06 05:51:24 +080048#include <cutils/properties.h>
49
Logan89eb47f2011-01-07 10:45:16 +080050
Loganecf4cbd2011-01-06 05:34:11 +080051namespace {
52
Logan033f46e2011-01-06 05:51:24 +080053bool getBooleanProp(const char *str) {
Loganf340bf72011-01-14 17:51:40 +080054 char buf[PROPERTY_VALUE_MAX];
55 property_get(str, buf, "0");
56 return strcmp(buf, "0") != 0;
Logan033f46e2011-01-06 05:51:24 +080057}
58
Loganecf4cbd2011-01-06 05:34:11 +080059} // namespace anonymous
60
Logancf3e5212010-12-29 01:44:55 +080061namespace bcc {
62
63Script::~Script() {
Logan35849002011-01-15 07:30:43 +080064 switch (mStatus) {
65 case ScriptStatus::Compiled:
Logancf3e5212010-12-29 01:44:55 +080066 delete mCompiled;
Logan35849002011-01-15 07:30:43 +080067 break;
68
69#if USE_CACHE
70 case ScriptStatus::Cached:
Shih-wei Liaoc4cf6542011-01-13 01:43:01 -080071 delete mCached;
Logan35849002011-01-15 07:30:43 +080072 break;
73#endif
74
75 default:
76 break;
Logancf3e5212010-12-29 01:44:55 +080077 }
Logan474cbd22011-01-31 01:47:44 +080078
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -080079 for (size_t i = 0; i < 2; ++i) {
Logan474cbd22011-01-31 01:47:44 +080080 delete mSourceList[i];
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -080081 }
Logancf3e5212010-12-29 01:44:55 +080082}
83
84
Logan474cbd22011-01-31 01:47:44 +080085int Script::addSourceBC(size_t idx,
86 char const *resName,
87 const char *bitcode,
88 size_t bitcodeSize,
89 unsigned long flags) {
Shih-wei Liao898c5a92011-05-18 07:02:39 -070090
91 if (!resName) {
92 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +000093 ALOGE("Invalid argument: resName = NULL\n");
Shih-wei Liao898c5a92011-05-18 07:02:39 -070094 return 1;
95 }
96
Loganecf4cbd2011-01-06 05:34:11 +080097 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +080098 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +000099 ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800100 return 1;
101 }
102
Logan474cbd22011-01-31 01:47:44 +0800103 if (!bitcode) {
104 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000105 ALOGE("Invalid argument: bitcode = NULL\n");
Logan474cbd22011-01-31 01:47:44 +0800106 return 1;
107 }
108
109 mSourceList[idx] = SourceInfo::createFromBuffer(resName,
110 bitcode, bitcodeSize,
111 flags);
112
113 if (!mSourceList[idx]) {
114 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000115 ALOGE("Out of memory while adding source bitcode\n");
Logan474cbd22011-01-31 01:47:44 +0800116 return 1;
117 }
118
Loganecf4cbd2011-01-06 05:34:11 +0800119 return 0;
Logancf3e5212010-12-29 01:44:55 +0800120}
121
122
Logan474cbd22011-01-31 01:47:44 +0800123int Script::addSourceModule(size_t idx,
124 llvm::Module *module,
125 unsigned long flags) {
Logancf3e5212010-12-29 01:44:55 +0800126 if (mStatus != ScriptStatus::Unknown) {
127 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000128 ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800129 return 1;
130 }
131
Logan474cbd22011-01-31 01:47:44 +0800132 if (!module) {
133 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000134 ALOGE("Invalid argument: module = NULL\n");
Logan474cbd22011-01-31 01:47:44 +0800135 return 1;
136 }
137
138 mSourceList[idx] = SourceInfo::createFromModule(module, flags);
139
140 if (!mSourceList[idx]) {
141 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000142 ALOGE("Out of memory when add source module\n");
Logan474cbd22011-01-31 01:47:44 +0800143 return 1;
144 }
145
Loganecf4cbd2011-01-06 05:34:11 +0800146 return 0;
Logancf3e5212010-12-29 01:44:55 +0800147}
148
149
Logan474cbd22011-01-31 01:47:44 +0800150int Script::addSourceFile(size_t idx,
151 char const *path,
152 unsigned long flags) {
Logan3133c412011-01-06 06:15:40 +0800153 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800154 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000155 ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800156 return 1;
157 }
158
Logan474cbd22011-01-31 01:47:44 +0800159 if (!path) {
160 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000161 ALOGE("Invalid argument: path = NULL\n");
Logan474cbd22011-01-31 01:47:44 +0800162 return 1;
163 }
164
165 struct stat sb;
166 if (stat(path, &sb) != 0) {
167 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000168 ALOGE("File not found: %s\n", path);
Logan474cbd22011-01-31 01:47:44 +0800169 return 1;
170 }
171
172 mSourceList[idx] = SourceInfo::createFromFile(path, flags);
173
174 if (!mSourceList[idx]) {
175 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000176 ALOGE("Out of memory while adding source file\n");
Logan474cbd22011-01-31 01:47:44 +0800177 return 1;
178 }
179
Logan3133c412011-01-06 06:15:40 +0800180 return 0;
Logancf3e5212010-12-29 01:44:55 +0800181}
182
Shih-wei Liao6a60f4e2012-01-17 02:58:40 -0800183int Script::prepareRelocatable(char const *cacheDir,
184 char const *cacheName,
185 llvm::Reloc::Model RelocModel,
186 unsigned long flags) {
Joseph Wen34c600a2011-07-25 17:59:17 -0700187#if USE_CACHE
Zonr Chang743dd712012-01-19 10:13:52 +0800188 if (internalLoadCache(cacheDir, cacheName,
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800189 ScriptObject::Relocatable, /* checkOnly */ true) == 0) {
Zonr Chang743dd712012-01-19 10:13:52 +0800190 return 0;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800191 }
Joseph Wen34c600a2011-07-25 17:59:17 -0700192#endif
Zonr Chang2fcbd022012-01-06 21:04:31 +0800193
194 CompilerOption option;
Shih-wei Liao8afed382012-01-10 15:57:24 +0800195 option.RelocModelOpt = RelocModel;
Zonr Chang2fcbd022012-01-06 21:04:31 +0800196 option.LoadAfterCompile = false;
197 int status = internalCompile(option);
Joseph Wen34c600a2011-07-25 17:59:17 -0700198 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000199 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Joseph Wen34c600a2011-07-25 17:59:17 -0700200 }
201 return status;
202}
203
Logancf3e5212010-12-29 01:44:55 +0800204
Shih-wei Liaoa471ebb2012-02-05 00:49:58 -0800205int Script::prepareSharedObject(char const *cacheDir,
206 char const *cacheName,
207 char const *objPath,
208 char const *dsoPath,
209 unsigned long flags) {
210 // TODO: Support cached shared object.
211 return 1;
212}
213
214
Logan Chien311c26f2011-07-11 14:30:34 +0800215int Script::prepareExecutable(char const *cacheDir,
216 char const *cacheName,
217 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800218 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800219 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000220 ALOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800221 return 1;
222 }
223
Logan35849002011-01-15 07:30:43 +0800224#if USE_CACHE
Zonr Chang743dd712012-01-19 10:13:52 +0800225 if (internalLoadCache(cacheDir, cacheName,
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800226 ScriptObject::Executable, /* checkOnly */ false) == 0) {
Zonr Chang743dd712012-01-19 10:13:52 +0800227 return 0;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800228 }
Logan35849002011-01-15 07:30:43 +0800229#endif
Loganecf4cbd2011-01-06 05:34:11 +0800230
Zonr Chang2fcbd022012-01-06 21:04:31 +0800231 CompilerOption option;
232 int status = internalCompile(option);
Stephen Hines27b35102011-05-11 17:58:48 -0700233 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000234 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Stephen Hines27b35102011-05-11 17:58:48 -0700235 }
236 return status;
Logan033f46e2011-01-06 05:51:24 +0800237}
238
239
Logan35849002011-01-15 07:30:43 +0800240#if USE_CACHE
Zonr Chang743dd712012-01-19 10:13:52 +0800241int Script::internalLoadCache(char const *cacheDir, char const *cacheName,
242 ScriptObject::ObjectType objectType,
243 bool checkOnly) {
244 mObjectType = objectType;
245
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800246 if ((cacheDir == NULL) || (cacheName == NULL)) {
Zonr Chang743dd712012-01-19 10:13:52 +0800247 return 1;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800248 }
Zonr Chang743dd712012-01-19 10:13:52 +0800249
250 // Set cache file Name
251 mCacheName = cacheName;
252
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800253 // Santize mCacheDir. Ensure that mCacheDir ends with '/'.
Zonr Chang743dd712012-01-19 10:13:52 +0800254 mCacheDir = cacheDir;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800255 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
Zonr Chang743dd712012-01-19 10:13:52 +0800256 mCacheDir.push_back('/');
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800257 }
Zonr Chang743dd712012-01-19 10:13:52 +0800258
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800259 if (!isCacheable()) {
Logan033f46e2011-01-06 05:51:24 +0800260 return 1;
Shih-wei Liao32ef88b2012-02-04 23:33:11 -0800261 }
Logan04329712011-01-06 06:10:57 +0800262
Zonr Chang4ea08862012-01-17 17:26:49 +0800263 std::string objPath = getCachedObjectPath();
264 std::string infoPath = getCacheInfoPath();
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700265
Logan Chien311c26f2011-07-11 14:30:34 +0800266 FileHandle objFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700267 if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800268 // Unable to open the executable file in read mode.
Logan04329712011-01-06 06:10:57 +0800269 return 1;
270 }
271
Logan Chien311c26f2011-07-11 14:30:34 +0800272 FileHandle infoFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700273 if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800274 // Unable to open the metadata information file in read mode.
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700275 return 1;
276 }
277
Logan Chien311c26f2011-07-11 14:30:34 +0800278#if USE_OLD_JIT
279 CacheReader reader;
280#elif USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700281 MCCacheReader reader;
282
283 // Register symbol lookup function
284 if (mpExtSymbolLookupFn) {
285 reader.registerSymbolCallback(mpExtSymbolLookupFn,
286 mpExtSymbolLookupFnContext);
287 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700288#endif
Logan04329712011-01-06 06:10:57 +0800289
Logan9a5f8682011-01-07 06:09:57 +0800290 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700291 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700292 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logan9a5f8682011-01-07 06:09:57 +0800293
Logan474cbd22011-01-31 01:47:44 +0800294 for (size_t i = 0; i < 2; ++i) {
295 if (mSourceList[i]) {
296 mSourceList[i]->introDependency(reader);
297 }
Logan9a5f8682011-01-07 06:09:57 +0800298 }
299
Joseph Wen34c600a2011-07-25 17:59:17 -0700300 if (checkOnly)
Joseph Wen49281042011-07-26 10:04:09 -0700301 return !reader.checkCacheFile(&objFile, &infoFile, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700302
Logan9a5f8682011-01-07 06:09:57 +0800303 // Read cache file
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700304 ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700305
Logan04329712011-01-06 06:10:57 +0800306 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800307 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800308 return 1;
309 }
310
311 mCached = cached;
312 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800313
Loganf3c83ce2011-01-07 06:36:33 +0800314 // Dirty hack for libRS.
315 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800316 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800317 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
318 }
319
Loganf7f0ac52011-01-07 03:53:43 +0800320 return 0;
Logan033f46e2011-01-06 05:51:24 +0800321}
Logan35849002011-01-15 07:30:43 +0800322#endif
Logan033f46e2011-01-06 05:51:24 +0800323
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800324int Script::internalCompile(const CompilerOption &option) {
Logan033f46e2011-01-06 05:51:24 +0800325 // Create the ScriptCompiled object
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800326 mCompiled = new (std::nothrow) ScriptCompiled(this);
Loganecf4cbd2011-01-06 05:34:11 +0800327
328 if (!mCompiled) {
329 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000330 ALOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
Loganecf4cbd2011-01-06 05:34:11 +0800331 return 1;
332 }
333
334 mStatus = ScriptStatus::Compiled;
335
Logan033f46e2011-01-06 05:51:24 +0800336 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800337 if (mpExtSymbolLookupFn) {
338 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
339 mpExtSymbolLookupFnContext);
340 }
341
Zonr Changdf3fee42012-01-10 15:58:36 +0800342 if (!mSourceList[0]) {
343 ALOGE("Source bitcode is not set.\n");
Logan474cbd22011-01-31 01:47:44 +0800344 return 1;
345 }
346
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800347 // Parse Source bitcode file (if necessary)
348 if (mSourceList[0]->prepareModule() != 0) {
349 ALOGE("Unable to setup source module\n");
Zonr Changdf3fee42012-01-10 15:58:36 +0800350 return 1;
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800351 }
352
353 // Parse Library bitcode file (if necessary)
354 if (mSourceList[1]) {
355 if (mSourceList[1]->prepareModule(mSourceList[0]->getContext()) != 0) {
356 ALOGE("Unable to setup library module\n");
357 return 1;
358 }
359 }
Zonr Changdf3fee42012-01-10 15:58:36 +0800360
361 // Set the main source module
362 if (mCompiled->readModule(mSourceList[0]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000363 ALOGE("Unable to read source module\n");
Logan474cbd22011-01-31 01:47:44 +0800364 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800365 }
366
Logan3133c412011-01-06 06:15:40 +0800367 // Link the source module with the library module
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800368 if (mSourceList[1]) {
Zonr Changdf3fee42012-01-10 15:58:36 +0800369 if (mCompiled->linkModule(mSourceList[1]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000370 ALOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800371 return 1;
372 }
373 }
Loganecf4cbd2011-01-06 05:34:11 +0800374
Logan3133c412011-01-06 06:15:40 +0800375 // Compile and JIT the code
Zonr Chang2fcbd022012-01-06 21:04:31 +0800376 if (mCompiled->compile(option) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000377 ALOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800378 return 1;
379 }
380
Logan35849002011-01-15 07:30:43 +0800381#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800382 // Note: If we re-compile the script because the cached context slot not
383 // available, then we don't have to write the cache.
384
385 // Note: If the address of the context is not in the context slot, then
386 // we don't have to cache it.
387
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800388 if (
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700389#if USE_OLD_JIT
Logan1dc63142011-02-25 17:14:51 +0800390 !mIsContextSlotNotAvail &&
391 ContextManager::get().isManagingContext(getContext()) &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700392#endif
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800393 isCacheable()) {
Logan42598052011-01-26 22:41:13 +0800394
Zonr Chang4ea08862012-01-17 17:26:49 +0800395 std::string objPath = getCachedObjectPath();
396 std::string infoPath = getCacheInfoPath();
Logan Chien311c26f2011-07-11 14:30:34 +0800397
Jeff Brown937a0bc2011-01-26 23:20:14 -0800398 // Remove the file if it already exists before writing the new file.
399 // The old file may still be mapped elsewhere in memory and we do not want
400 // to modify its contents. (The same script may be running concurrently in
401 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700402 ::unlink(objPath.c_str());
Logan Chien311c26f2011-07-11 14:30:34 +0800403#if !USE_OLD_JIT && USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700404 ::unlink(infoPath.c_str());
405#endif
Jeff Brown937a0bc2011-01-26 23:20:14 -0800406
Logan Chien03a2e302011-07-13 21:46:32 +0800407 FileHandle objFile;
408 FileHandle infoFile;
409
410 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
411 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700412
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700413#if USE_OLD_JIT
Logan04329712011-01-06 06:10:57 +0800414 CacheWriter writer;
Logan Chien311c26f2011-07-11 14:30:34 +0800415#elif USE_MCJIT
416 MCCacheWriter writer;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700417#endif
Logana27a83f2011-01-07 10:25:48 +0800418
Joseph Wen2ca6e572011-06-24 14:12:23 -0700419#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800420 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700421 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700422 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800423#endif
Logana2e15af2011-01-07 11:46:08 +0800424
Logan474cbd22011-01-31 01:47:44 +0800425 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800426 if (mSourceList[i]) {
427 mSourceList[i]->introDependency(writer);
428 }
Logana2e15af2011-01-07 11:46:08 +0800429 }
430
Logana27a83f2011-01-07 10:25:48 +0800431 // libRS is threadable dirty hack
432 // TODO: This should be removed in the future
433 uint32_t libRS_threadable = 0;
434 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800435 libRS_threadable =
436 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
437 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800438 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700439
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700440 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700441 objFile.truncate();
442 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800443
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700444 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000445 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700446 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800447 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700448
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700449 infoFile.truncate();
450 infoFile.close();
451
452 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000453 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700454 infoPath.c_str(), strerror(errno));
455 }
Logan89eb47f2011-01-07 10:45:16 +0800456 }
457 }
Logan04329712011-01-06 06:10:57 +0800458 }
Logan35849002011-01-15 07:30:43 +0800459#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800460
461 return 0;
Logancf3e5212010-12-29 01:44:55 +0800462}
463
464
465char const *Script::getCompilerErrorMessage() {
466 if (mStatus != ScriptStatus::Compiled) {
467 mErrorCode = BCC_INVALID_OPERATION;
468 return NULL;
469 }
470
471 return mCompiled->getCompilerErrorMessage();
472}
473
474
475void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800476 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700477 case ScriptStatus::Compiled: {
478 return mCompiled->lookup(name);
479 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700480
Logan35849002011-01-15 07:30:43 +0800481#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700482 case ScriptStatus::Cached: {
483 return mCached->lookup(name);
484 }
Logan35849002011-01-15 07:30:43 +0800485#endif
Logan89eb47f2011-01-07 10:45:16 +0800486
Shih-wei Liaod50be322011-07-01 22:53:31 -0700487 default: {
488 mErrorCode = BCC_INVALID_OPERATION;
489 return NULL;
490 }
Logancf3e5212010-12-29 01:44:55 +0800491 }
Logancf3e5212010-12-29 01:44:55 +0800492}
493
494
Loganbe79ada2011-01-13 01:33:45 +0800495size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800496 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700497 case ScriptStatus::Compiled: {
498 return mCompiled->getExportVarCount();
499 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700500
Logan35849002011-01-15 07:30:43 +0800501#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700502 case ScriptStatus::Cached: {
503 return mCached->getExportVarCount();
504 }
Logan35849002011-01-15 07:30:43 +0800505#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700506
Shih-wei Liaod50be322011-07-01 22:53:31 -0700507 default: {
508 return 0;
509 }
Loganbe79ada2011-01-13 01:33:45 +0800510 }
511}
512
513
514size_t Script::getExportFuncCount() const {
515 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700516 case ScriptStatus::Compiled: {
517 return mCompiled->getExportFuncCount();
518 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700519
Logan35849002011-01-15 07:30:43 +0800520#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700521 case ScriptStatus::Cached: {
522 return mCached->getExportFuncCount();
523 }
Logan35849002011-01-15 07:30:43 +0800524#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700525
Shih-wei Liaod50be322011-07-01 22:53:31 -0700526 default: {
527 return 0;
528 }
Loganbe79ada2011-01-13 01:33:45 +0800529 }
530}
531
532
Stephen Hinescc366e52012-02-21 17:22:04 -0800533size_t Script::getExportForEachCount() const {
534 switch (mStatus) {
535 case ScriptStatus::Compiled: {
536 return mCompiled->getExportForEachCount();
537 }
538
539#if USE_CACHE
540 case ScriptStatus::Cached: {
541 return mCached->getExportForEachCount();
542 }
543#endif
544
545 default: {
546 return 0;
547 }
548 }
549}
550
551
Loganbe79ada2011-01-13 01:33:45 +0800552size_t Script::getPragmaCount() const {
553 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700554 case ScriptStatus::Compiled: {
555 return mCompiled->getPragmaCount();
556 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700557
Logan35849002011-01-15 07:30:43 +0800558#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700559 case ScriptStatus::Cached: {
560 return mCached->getPragmaCount();
561 }
Logan35849002011-01-15 07:30:43 +0800562#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700563
Shih-wei Liaod50be322011-07-01 22:53:31 -0700564 default: {
565 return 0;
566 }
Loganbe79ada2011-01-13 01:33:45 +0800567 }
568}
569
570
571size_t Script::getFuncCount() const {
572 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700573 case ScriptStatus::Compiled: {
574 return mCompiled->getFuncCount();
575 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700576
Logan35849002011-01-15 07:30:43 +0800577#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700578 case ScriptStatus::Cached: {
579 return mCached->getFuncCount();
580 }
Logan35849002011-01-15 07:30:43 +0800581#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700582
Shih-wei Liaod50be322011-07-01 22:53:31 -0700583 default: {
584 return 0;
585 }
Loganbe79ada2011-01-13 01:33:45 +0800586 }
587}
588
589
Stephen Hines071288a2011-01-27 14:38:26 -0800590size_t Script::getObjectSlotCount() const {
591 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700592 case ScriptStatus::Compiled: {
593 return mCompiled->getObjectSlotCount();
594 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700595
Stephen Hines071288a2011-01-27 14:38:26 -0800596#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700597 case ScriptStatus::Cached: {
598 return mCached->getObjectSlotCount();
599 }
Stephen Hines071288a2011-01-27 14:38:26 -0800600#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700601
Shih-wei Liaod50be322011-07-01 22:53:31 -0700602 default: {
603 return 0;
604 }
Stephen Hines071288a2011-01-27 14:38:26 -0800605 }
606}
607
608
Loganbe79ada2011-01-13 01:33:45 +0800609void Script::getExportVarList(size_t varListSize, void **varList) {
610 switch (mStatus) {
611#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700612 case ScriptStatus::STATUS: \
613 m##STATUS->getExportVarList(varListSize, varList); \
614 break;
Logancf3e5212010-12-29 01:44:55 +0800615
Logan35849002011-01-15 07:30:43 +0800616#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700617 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800618#endif
619
Shih-wei Liaod50be322011-07-01 22:53:31 -0700620 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800621#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800622
Shih-wei Liaod50be322011-07-01 22:53:31 -0700623 default: {
624 mErrorCode = BCC_INVALID_OPERATION;
625 }
Logan89eb47f2011-01-07 10:45:16 +0800626 }
Logancf3e5212010-12-29 01:44:55 +0800627}
628
Joseph Wenf36637f2011-07-06 18:27:12 -0700629void Script::getExportVarNameList(std::vector<std::string> &varList) {
630 switch (mStatus) {
631 case ScriptStatus::Compiled: {
632 return mCompiled->getExportVarNameList(varList);
633 }
634
635 default: {
636 mErrorCode = BCC_INVALID_OPERATION;
637 }
638 }
639}
640
Logancf3e5212010-12-29 01:44:55 +0800641
Loganbe79ada2011-01-13 01:33:45 +0800642void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800643 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800644#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700645 case ScriptStatus::STATUS: \
646 m##STATUS->getExportFuncList(funcListSize, funcList); \
647 break;
Logancf3e5212010-12-29 01:44:55 +0800648
Logan35849002011-01-15 07:30:43 +0800649#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700650 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800651#endif
652
Shih-wei Liaod50be322011-07-01 22:53:31 -0700653 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800654#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800655
Shih-wei Liaod50be322011-07-01 22:53:31 -0700656 default: {
657 mErrorCode = BCC_INVALID_OPERATION;
658 }
Logan89eb47f2011-01-07 10:45:16 +0800659 }
Logancf3e5212010-12-29 01:44:55 +0800660}
661
Joseph Wenf36637f2011-07-06 18:27:12 -0700662void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
663 switch (mStatus) {
664 case ScriptStatus::Compiled: {
665 return mCompiled->getExportFuncNameList(funcList);
666 }
667
668 default: {
669 mErrorCode = BCC_INVALID_OPERATION;
670 }
671 }
672}
673
Stephen Hinescc366e52012-02-21 17:22:04 -0800674void Script::getExportForEachList(size_t funcListSize, void **funcList) {
675 switch (mStatus) {
676#define DELEGATE(STATUS) \
677 case ScriptStatus::STATUS: \
678 m##STATUS->getExportForEachList(funcListSize, funcList); \
679 break;
680
681#if USE_CACHE
682 DELEGATE(Cached);
683#endif
684
685 DELEGATE(Compiled);
686#undef DELEGATE
687
688 default: {
689 mErrorCode = BCC_INVALID_OPERATION;
690 }
691 }
692}
693
694void Script::getExportForEachNameList(std::vector<std::string> &forEachList) {
695 switch (mStatus) {
696 case ScriptStatus::Compiled: {
697 return mCompiled->getExportForEachNameList(forEachList);
698 }
699
700 default: {
701 mErrorCode = BCC_INVALID_OPERATION;
702 }
703 }
704}
Logancf3e5212010-12-29 01:44:55 +0800705
Loganbe79ada2011-01-13 01:33:45 +0800706void Script::getPragmaList(size_t pragmaListSize,
707 char const **keyList,
708 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800709 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800710#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700711 case ScriptStatus::STATUS: \
712 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
713 break;
Logancf3e5212010-12-29 01:44:55 +0800714
Logan35849002011-01-15 07:30:43 +0800715#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700716 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800717#endif
718
Shih-wei Liaod50be322011-07-01 22:53:31 -0700719 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800720#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800721
Shih-wei Liaod50be322011-07-01 22:53:31 -0700722 default: {
723 mErrorCode = BCC_INVALID_OPERATION;
724 }
Logan89eb47f2011-01-07 10:45:16 +0800725 }
Logancf3e5212010-12-29 01:44:55 +0800726}
727
728
Loganf340bf72011-01-14 17:51:40 +0800729void Script::getFuncInfoList(size_t funcInfoListSize,
730 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800731 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800732#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700733 case ScriptStatus::STATUS: \
734 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
735 break;
Logancf3e5212010-12-29 01:44:55 +0800736
Logan35849002011-01-15 07:30:43 +0800737#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700738 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800739#endif
740
Shih-wei Liaod50be322011-07-01 22:53:31 -0700741 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800742#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800743
Shih-wei Liaod50be322011-07-01 22:53:31 -0700744 default: {
745 mErrorCode = BCC_INVALID_OPERATION;
746 }
Logan89eb47f2011-01-07 10:45:16 +0800747 }
Logancf3e5212010-12-29 01:44:55 +0800748}
749
Stephen Hines071288a2011-01-27 14:38:26 -0800750
751void Script::getObjectSlotList(size_t objectSlotListSize,
752 uint32_t *objectSlotList) {
753 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700754#define DELEGATE(STATUS) \
755 case ScriptStatus::STATUS: \
756 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
757 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800758
759#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700760 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800761#endif
762
Shih-wei Liaod50be322011-07-01 22:53:31 -0700763 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800764#undef DELEGATE
765
Shih-wei Liaod50be322011-07-01 22:53:31 -0700766 default: {
767 mErrorCode = BCC_INVALID_OPERATION;
768 }
Stephen Hines071288a2011-01-27 14:38:26 -0800769 }
770}
771
772
Logan Chiend2a5f302011-07-19 20:32:25 +0800773#if USE_OLD_JIT
Logana27a83f2011-01-07 10:25:48 +0800774char *Script::getContext() {
775 switch (mStatus) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700776
Logan35849002011-01-15 07:30:43 +0800777#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700778 case ScriptStatus::Cached: {
779 return mCached->getContext();
780 }
Logan35849002011-01-15 07:30:43 +0800781#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700782
Shih-wei Liaod50be322011-07-01 22:53:31 -0700783 case ScriptStatus::Compiled: {
784 return mCompiled->getContext();
785 }
Logana27a83f2011-01-07 10:25:48 +0800786
Shih-wei Liaod50be322011-07-01 22:53:31 -0700787 default: {
788 mErrorCode = BCC_INVALID_OPERATION;
789 return NULL;
790 }
Logan02286cb2011-01-07 00:30:47 +0800791 }
Logan02286cb2011-01-07 00:30:47 +0800792}
Logan Chiend2a5f302011-07-19 20:32:25 +0800793#endif
Logan02286cb2011-01-07 00:30:47 +0800794
Logancf3e5212010-12-29 01:44:55 +0800795
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800796int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800797 mpExtSymbolLookupFn = pFn;
798 mpExtSymbolLookupFnContext = pContext;
799
Logan7d2219f2011-01-06 06:19:25 +0800800 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800801 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000802 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800803 return 1;
Logancf3e5212010-12-29 01:44:55 +0800804 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800805 return 0;
Logancf3e5212010-12-29 01:44:55 +0800806}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700807
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800808bool Script::isCacheable() const {
809#if USE_CACHE
810 if (getBooleanProp("debug.bcc.nocache")) {
811 // Android system environment property: Disables the cache mechanism by
812 // setting "debug.bcc.nocache". So we will not load the cache file any
813 // way.
814 return false;
815 }
816
817 if (mCacheDir.empty() || mCacheName.empty()) {
818 // The application developer has not specified the cachePath, so
819 // we don't know where to open the cache file.
820 return false;
821 }
822
823 return true;
824#else
825 return false;
826#endif
827}
828
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700829#if USE_MCJIT
830size_t Script::getELFSize() const {
831 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700832 case ScriptStatus::Compiled: {
833 return mCompiled->getELFSize();
834 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700835
Shih-wei Liaod50be322011-07-01 22:53:31 -0700836 default: {
837 return 0;
838 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700839 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700840}
841
842const char *Script::getELF() const {
843 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700844 case ScriptStatus::Compiled: {
845 return mCompiled->getELF();
846 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700847
Shih-wei Liaod50be322011-07-01 22:53:31 -0700848 default: {
849 return NULL;
850 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700851 }
852}
853#endif
Logancf3e5212010-12-29 01:44:55 +0800854
855} // namespace bcc