blob: 024ac7e8a33a42264c5864b42d8bc3e2e5ae4387 [file] [log] [blame]
Logancf3e5212010-12-29 01:44:55 +08001/*
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
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,
189 ScriptObject::Relocatable, /* checkOnly */true) == 0)
190 return 0;
Joseph Wen34c600a2011-07-25 17:59:17 -0700191#endif
Zonr Chang2fcbd022012-01-06 21:04:31 +0800192
193 CompilerOption option;
Shih-wei Liao8afed382012-01-10 15:57:24 +0800194 option.RelocModelOpt = RelocModel;
Zonr Chang2fcbd022012-01-06 21:04:31 +0800195 option.LoadAfterCompile = false;
196 int status = internalCompile(option);
Joseph Wen34c600a2011-07-25 17:59:17 -0700197 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000198 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Joseph Wen34c600a2011-07-25 17:59:17 -0700199 }
200 return status;
201}
202
Logancf3e5212010-12-29 01:44:55 +0800203
Logan Chien311c26f2011-07-11 14:30:34 +0800204int Script::prepareExecutable(char const *cacheDir,
205 char const *cacheName,
206 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800207 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800208 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000209 ALOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800210 return 1;
211 }
212
Logan35849002011-01-15 07:30:43 +0800213#if USE_CACHE
Zonr Chang743dd712012-01-19 10:13:52 +0800214 if (internalLoadCache(cacheDir, cacheName,
215 ScriptObject::Executable, /* checkOnly */false) == 0)
216 return 0;
Logan35849002011-01-15 07:30:43 +0800217#endif
Loganecf4cbd2011-01-06 05:34:11 +0800218
Zonr Chang2fcbd022012-01-06 21:04:31 +0800219 CompilerOption option;
220 int status = internalCompile(option);
Stephen Hines27b35102011-05-11 17:58:48 -0700221 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000222 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Stephen Hines27b35102011-05-11 17:58:48 -0700223 }
224 return status;
Logan033f46e2011-01-06 05:51:24 +0800225}
226
227
Logan35849002011-01-15 07:30:43 +0800228#if USE_CACHE
Zonr Chang743dd712012-01-19 10:13:52 +0800229int Script::internalLoadCache(char const *cacheDir, char const *cacheName,
230 ScriptObject::ObjectType objectType,
231 bool checkOnly) {
232 mObjectType = objectType;
233
234 if ((cacheDir == NULL) || (cacheName == NULL))
235 return 1;
236
237 // Set cache file Name
238 mCacheName = cacheName;
239
240 // Santize the mCacheDir. Ensure that mCacheDir is end with '/'.
241 mCacheDir = cacheDir;
242 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/')
243 mCacheDir.push_back('/');
244
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800245 if (!isCacheable())
Logan033f46e2011-01-06 05:51:24 +0800246 return 1;
Logan04329712011-01-06 06:10:57 +0800247
Zonr Chang4ea08862012-01-17 17:26:49 +0800248 std::string objPath = getCachedObjectPath();
249 std::string infoPath = getCacheInfoPath();
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700250
Logan Chien311c26f2011-07-11 14:30:34 +0800251 FileHandle objFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700252 if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800253 // Unable to open the executable file in read mode.
Logan04329712011-01-06 06:10:57 +0800254 return 1;
255 }
256
Logan Chien311c26f2011-07-11 14:30:34 +0800257 FileHandle infoFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700258 if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800259 // Unable to open the metadata information file in read mode.
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700260 return 1;
261 }
262
Logan Chien311c26f2011-07-11 14:30:34 +0800263#if USE_OLD_JIT
264 CacheReader reader;
265#elif USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700266 MCCacheReader reader;
267
268 // Register symbol lookup function
269 if (mpExtSymbolLookupFn) {
270 reader.registerSymbolCallback(mpExtSymbolLookupFn,
271 mpExtSymbolLookupFnContext);
272 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700273#endif
Logan04329712011-01-06 06:10:57 +0800274
Logan9a5f8682011-01-07 06:09:57 +0800275 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700276 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700277 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logan9a5f8682011-01-07 06:09:57 +0800278
Logan474cbd22011-01-31 01:47:44 +0800279 for (size_t i = 0; i < 2; ++i) {
280 if (mSourceList[i]) {
281 mSourceList[i]->introDependency(reader);
282 }
Logan9a5f8682011-01-07 06:09:57 +0800283 }
284
Joseph Wen34c600a2011-07-25 17:59:17 -0700285 if (checkOnly)
Joseph Wen49281042011-07-26 10:04:09 -0700286 return !reader.checkCacheFile(&objFile, &infoFile, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700287
Logan9a5f8682011-01-07 06:09:57 +0800288 // Read cache file
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700289 ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700290
Logan04329712011-01-06 06:10:57 +0800291 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800292 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800293 return 1;
294 }
295
296 mCached = cached;
297 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800298
Loganf3c83ce2011-01-07 06:36:33 +0800299 // Dirty hack for libRS.
300 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800301 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800302 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
303 }
304
Loganf7f0ac52011-01-07 03:53:43 +0800305 return 0;
Logan033f46e2011-01-06 05:51:24 +0800306}
Logan35849002011-01-15 07:30:43 +0800307#endif
Logan033f46e2011-01-06 05:51:24 +0800308
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800309int Script::internalCompile(const CompilerOption &option) {
Logan033f46e2011-01-06 05:51:24 +0800310 // Create the ScriptCompiled object
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800311 mCompiled = new (std::nothrow) ScriptCompiled(this);
Loganecf4cbd2011-01-06 05:34:11 +0800312
313 if (!mCompiled) {
314 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000315 ALOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
Loganecf4cbd2011-01-06 05:34:11 +0800316 return 1;
317 }
318
319 mStatus = ScriptStatus::Compiled;
320
Logan033f46e2011-01-06 05:51:24 +0800321 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800322 if (mpExtSymbolLookupFn) {
323 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
324 mpExtSymbolLookupFnContext);
325 }
326
Zonr Changdf3fee42012-01-10 15:58:36 +0800327 if (!mSourceList[0]) {
328 ALOGE("Source bitcode is not set.\n");
Logan474cbd22011-01-31 01:47:44 +0800329 return 1;
330 }
331
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800332 // Parse Source bitcode file (if necessary)
333 if (mSourceList[0]->prepareModule() != 0) {
334 ALOGE("Unable to setup source module\n");
Zonr Changdf3fee42012-01-10 15:58:36 +0800335 return 1;
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800336 }
337
338 // Parse Library bitcode file (if necessary)
339 if (mSourceList[1]) {
340 if (mSourceList[1]->prepareModule(mSourceList[0]->getContext()) != 0) {
341 ALOGE("Unable to setup library module\n");
342 return 1;
343 }
344 }
Zonr Changdf3fee42012-01-10 15:58:36 +0800345
346 // Set the main source module
347 if (mCompiled->readModule(mSourceList[0]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000348 ALOGE("Unable to read source module\n");
Logan474cbd22011-01-31 01:47:44 +0800349 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800350 }
351
Logan3133c412011-01-06 06:15:40 +0800352 // Link the source module with the library module
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800353 if (mSourceList[1]) {
Zonr Changdf3fee42012-01-10 15:58:36 +0800354 if (mCompiled->linkModule(mSourceList[1]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000355 ALOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800356 return 1;
357 }
358 }
Loganecf4cbd2011-01-06 05:34:11 +0800359
Logan3133c412011-01-06 06:15:40 +0800360 // Compile and JIT the code
Zonr Chang2fcbd022012-01-06 21:04:31 +0800361 if (mCompiled->compile(option) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000362 ALOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800363 return 1;
364 }
365
Logan35849002011-01-15 07:30:43 +0800366#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800367 // Note: If we re-compile the script because the cached context slot not
368 // available, then we don't have to write the cache.
369
370 // Note: If the address of the context is not in the context slot, then
371 // we don't have to cache it.
372
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800373 if (
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700374#if USE_OLD_JIT
Logan1dc63142011-02-25 17:14:51 +0800375 !mIsContextSlotNotAvail &&
376 ContextManager::get().isManagingContext(getContext()) &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700377#endif
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800378 isCacheable()) {
Logan42598052011-01-26 22:41:13 +0800379
Zonr Chang4ea08862012-01-17 17:26:49 +0800380 std::string objPath = getCachedObjectPath();
381 std::string infoPath = getCacheInfoPath();
Logan Chien311c26f2011-07-11 14:30:34 +0800382
Jeff Brown937a0bc2011-01-26 23:20:14 -0800383 // Remove the file if it already exists before writing the new file.
384 // The old file may still be mapped elsewhere in memory and we do not want
385 // to modify its contents. (The same script may be running concurrently in
386 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700387 ::unlink(objPath.c_str());
Logan Chien311c26f2011-07-11 14:30:34 +0800388#if !USE_OLD_JIT && USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700389 ::unlink(infoPath.c_str());
390#endif
Jeff Brown937a0bc2011-01-26 23:20:14 -0800391
Logan Chien03a2e302011-07-13 21:46:32 +0800392 FileHandle objFile;
393 FileHandle infoFile;
394
395 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
396 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700397
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700398#if USE_OLD_JIT
Logan04329712011-01-06 06:10:57 +0800399 CacheWriter writer;
Logan Chien311c26f2011-07-11 14:30:34 +0800400#elif USE_MCJIT
401 MCCacheWriter writer;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700402#endif
Logana27a83f2011-01-07 10:25:48 +0800403
Joseph Wen2ca6e572011-06-24 14:12:23 -0700404#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800405 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700406 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700407 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800408#endif
Logana2e15af2011-01-07 11:46:08 +0800409
Logan474cbd22011-01-31 01:47:44 +0800410 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800411 if (mSourceList[i]) {
412 mSourceList[i]->introDependency(writer);
413 }
Logana2e15af2011-01-07 11:46:08 +0800414 }
415
Logana27a83f2011-01-07 10:25:48 +0800416 // libRS is threadable dirty hack
417 // TODO: This should be removed in the future
418 uint32_t libRS_threadable = 0;
419 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800420 libRS_threadable =
421 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
422 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800423 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700424
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700425 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700426 objFile.truncate();
427 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800428
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700429 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000430 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700431 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800432 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700433
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700434 infoFile.truncate();
435 infoFile.close();
436
437 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000438 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700439 infoPath.c_str(), strerror(errno));
440 }
Logan89eb47f2011-01-07 10:45:16 +0800441 }
442 }
Logan04329712011-01-06 06:10:57 +0800443 }
Logan35849002011-01-15 07:30:43 +0800444#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800445
446 return 0;
Logancf3e5212010-12-29 01:44:55 +0800447}
448
449
450char const *Script::getCompilerErrorMessage() {
451 if (mStatus != ScriptStatus::Compiled) {
452 mErrorCode = BCC_INVALID_OPERATION;
453 return NULL;
454 }
455
456 return mCompiled->getCompilerErrorMessage();
457}
458
459
460void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800461 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700462 case ScriptStatus::Compiled: {
463 return mCompiled->lookup(name);
464 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700465
Logan35849002011-01-15 07:30:43 +0800466#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700467 case ScriptStatus::Cached: {
468 return mCached->lookup(name);
469 }
Logan35849002011-01-15 07:30:43 +0800470#endif
Logan89eb47f2011-01-07 10:45:16 +0800471
Shih-wei Liaod50be322011-07-01 22:53:31 -0700472 default: {
473 mErrorCode = BCC_INVALID_OPERATION;
474 return NULL;
475 }
Logancf3e5212010-12-29 01:44:55 +0800476 }
Logancf3e5212010-12-29 01:44:55 +0800477}
478
479
Loganbe79ada2011-01-13 01:33:45 +0800480size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800481 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700482 case ScriptStatus::Compiled: {
483 return mCompiled->getExportVarCount();
484 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700485
Logan35849002011-01-15 07:30:43 +0800486#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700487 case ScriptStatus::Cached: {
488 return mCached->getExportVarCount();
489 }
Logan35849002011-01-15 07:30:43 +0800490#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700491
Shih-wei Liaod50be322011-07-01 22:53:31 -0700492 default: {
493 return 0;
494 }
Loganbe79ada2011-01-13 01:33:45 +0800495 }
496}
497
498
499size_t Script::getExportFuncCount() const {
500 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700501 case ScriptStatus::Compiled: {
502 return mCompiled->getExportFuncCount();
503 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700504
Logan35849002011-01-15 07:30:43 +0800505#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700506 case ScriptStatus::Cached: {
507 return mCached->getExportFuncCount();
508 }
Logan35849002011-01-15 07:30:43 +0800509#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700510
Shih-wei Liaod50be322011-07-01 22:53:31 -0700511 default: {
512 return 0;
513 }
Loganbe79ada2011-01-13 01:33:45 +0800514 }
515}
516
517
518size_t Script::getPragmaCount() const {
519 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700520 case ScriptStatus::Compiled: {
521 return mCompiled->getPragmaCount();
522 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700523
Logan35849002011-01-15 07:30:43 +0800524#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700525 case ScriptStatus::Cached: {
526 return mCached->getPragmaCount();
527 }
Logan35849002011-01-15 07:30:43 +0800528#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700529
Shih-wei Liaod50be322011-07-01 22:53:31 -0700530 default: {
531 return 0;
532 }
Loganbe79ada2011-01-13 01:33:45 +0800533 }
534}
535
536
537size_t Script::getFuncCount() const {
538 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700539 case ScriptStatus::Compiled: {
540 return mCompiled->getFuncCount();
541 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700542
Logan35849002011-01-15 07:30:43 +0800543#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700544 case ScriptStatus::Cached: {
545 return mCached->getFuncCount();
546 }
Logan35849002011-01-15 07:30:43 +0800547#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700548
Shih-wei Liaod50be322011-07-01 22:53:31 -0700549 default: {
550 return 0;
551 }
Loganbe79ada2011-01-13 01:33:45 +0800552 }
553}
554
555
Stephen Hines071288a2011-01-27 14:38:26 -0800556size_t Script::getObjectSlotCount() const {
557 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700558 case ScriptStatus::Compiled: {
559 return mCompiled->getObjectSlotCount();
560 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700561
Stephen Hines071288a2011-01-27 14:38:26 -0800562#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700563 case ScriptStatus::Cached: {
564 return mCached->getObjectSlotCount();
565 }
Stephen Hines071288a2011-01-27 14:38:26 -0800566#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700567
Shih-wei Liaod50be322011-07-01 22:53:31 -0700568 default: {
569 return 0;
570 }
Stephen Hines071288a2011-01-27 14:38:26 -0800571 }
572}
573
574
Loganbe79ada2011-01-13 01:33:45 +0800575void Script::getExportVarList(size_t varListSize, void **varList) {
576 switch (mStatus) {
577#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700578 case ScriptStatus::STATUS: \
579 m##STATUS->getExportVarList(varListSize, varList); \
580 break;
Logancf3e5212010-12-29 01:44:55 +0800581
Logan35849002011-01-15 07:30:43 +0800582#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700583 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800584#endif
585
Shih-wei Liaod50be322011-07-01 22:53:31 -0700586 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800587#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800588
Shih-wei Liaod50be322011-07-01 22:53:31 -0700589 default: {
590 mErrorCode = BCC_INVALID_OPERATION;
591 }
Logan89eb47f2011-01-07 10:45:16 +0800592 }
Logancf3e5212010-12-29 01:44:55 +0800593}
594
Joseph Wenf36637f2011-07-06 18:27:12 -0700595void Script::getExportVarNameList(std::vector<std::string> &varList) {
596 switch (mStatus) {
597 case ScriptStatus::Compiled: {
598 return mCompiled->getExportVarNameList(varList);
599 }
600
601 default: {
602 mErrorCode = BCC_INVALID_OPERATION;
603 }
604 }
605}
606
Logancf3e5212010-12-29 01:44:55 +0800607
Loganbe79ada2011-01-13 01:33:45 +0800608void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800609 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800610#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700611 case ScriptStatus::STATUS: \
612 m##STATUS->getExportFuncList(funcListSize, funcList); \
613 break;
Logancf3e5212010-12-29 01:44:55 +0800614
Logan35849002011-01-15 07:30:43 +0800615#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700616 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800617#endif
618
Shih-wei Liaod50be322011-07-01 22:53:31 -0700619 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800620#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800621
Shih-wei Liaod50be322011-07-01 22:53:31 -0700622 default: {
623 mErrorCode = BCC_INVALID_OPERATION;
624 }
Logan89eb47f2011-01-07 10:45:16 +0800625 }
Logancf3e5212010-12-29 01:44:55 +0800626}
627
Joseph Wenf36637f2011-07-06 18:27:12 -0700628void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
629 switch (mStatus) {
630 case ScriptStatus::Compiled: {
631 return mCompiled->getExportFuncNameList(funcList);
632 }
633
634 default: {
635 mErrorCode = BCC_INVALID_OPERATION;
636 }
637 }
638}
639
Logancf3e5212010-12-29 01:44:55 +0800640
Loganbe79ada2011-01-13 01:33:45 +0800641void Script::getPragmaList(size_t pragmaListSize,
642 char const **keyList,
643 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800644 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800645#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700646 case ScriptStatus::STATUS: \
647 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
648 break;
Logancf3e5212010-12-29 01:44:55 +0800649
Logan35849002011-01-15 07:30:43 +0800650#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700651 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800652#endif
653
Shih-wei Liaod50be322011-07-01 22:53:31 -0700654 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800655#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800656
Shih-wei Liaod50be322011-07-01 22:53:31 -0700657 default: {
658 mErrorCode = BCC_INVALID_OPERATION;
659 }
Logan89eb47f2011-01-07 10:45:16 +0800660 }
Logancf3e5212010-12-29 01:44:55 +0800661}
662
663
Loganf340bf72011-01-14 17:51:40 +0800664void Script::getFuncInfoList(size_t funcInfoListSize,
665 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800666 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800667#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700668 case ScriptStatus::STATUS: \
669 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
670 break;
Logancf3e5212010-12-29 01:44:55 +0800671
Logan35849002011-01-15 07:30:43 +0800672#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700673 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800674#endif
675
Shih-wei Liaod50be322011-07-01 22:53:31 -0700676 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800677#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800678
Shih-wei Liaod50be322011-07-01 22:53:31 -0700679 default: {
680 mErrorCode = BCC_INVALID_OPERATION;
681 }
Logan89eb47f2011-01-07 10:45:16 +0800682 }
Logancf3e5212010-12-29 01:44:55 +0800683}
684
Stephen Hines071288a2011-01-27 14:38:26 -0800685
686void Script::getObjectSlotList(size_t objectSlotListSize,
687 uint32_t *objectSlotList) {
688 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700689#define DELEGATE(STATUS) \
690 case ScriptStatus::STATUS: \
691 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
692 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800693
694#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700695 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800696#endif
697
Shih-wei Liaod50be322011-07-01 22:53:31 -0700698 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800699#undef DELEGATE
700
Shih-wei Liaod50be322011-07-01 22:53:31 -0700701 default: {
702 mErrorCode = BCC_INVALID_OPERATION;
703 }
Stephen Hines071288a2011-01-27 14:38:26 -0800704 }
705}
706
707
Logan Chiend2a5f302011-07-19 20:32:25 +0800708#if USE_OLD_JIT
Logana27a83f2011-01-07 10:25:48 +0800709char *Script::getContext() {
710 switch (mStatus) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700711
Logan35849002011-01-15 07:30:43 +0800712#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700713 case ScriptStatus::Cached: {
714 return mCached->getContext();
715 }
Logan35849002011-01-15 07:30:43 +0800716#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700717
Shih-wei Liaod50be322011-07-01 22:53:31 -0700718 case ScriptStatus::Compiled: {
719 return mCompiled->getContext();
720 }
Logana27a83f2011-01-07 10:25:48 +0800721
Shih-wei Liaod50be322011-07-01 22:53:31 -0700722 default: {
723 mErrorCode = BCC_INVALID_OPERATION;
724 return NULL;
725 }
Logan02286cb2011-01-07 00:30:47 +0800726 }
Logan02286cb2011-01-07 00:30:47 +0800727}
Logan Chiend2a5f302011-07-19 20:32:25 +0800728#endif
Logan02286cb2011-01-07 00:30:47 +0800729
Logancf3e5212010-12-29 01:44:55 +0800730
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800731int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800732 mpExtSymbolLookupFn = pFn;
733 mpExtSymbolLookupFnContext = pContext;
734
Logan7d2219f2011-01-06 06:19:25 +0800735 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800736 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000737 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800738 return 1;
Logancf3e5212010-12-29 01:44:55 +0800739 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800740 return 0;
Logancf3e5212010-12-29 01:44:55 +0800741}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700742
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800743bool Script::isCacheable() const {
744#if USE_CACHE
745 if (getBooleanProp("debug.bcc.nocache")) {
746 // Android system environment property: Disables the cache mechanism by
747 // setting "debug.bcc.nocache". So we will not load the cache file any
748 // way.
749 return false;
750 }
751
752 if (mCacheDir.empty() || mCacheName.empty()) {
753 // The application developer has not specified the cachePath, so
754 // we don't know where to open the cache file.
755 return false;
756 }
757
758 return true;
759#else
760 return false;
761#endif
762}
763
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700764#if USE_MCJIT
765size_t Script::getELFSize() const {
766 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700767 case ScriptStatus::Compiled: {
768 return mCompiled->getELFSize();
769 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700770
Shih-wei Liaod50be322011-07-01 22:53:31 -0700771 default: {
772 return 0;
773 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700774 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700775}
776
777const char *Script::getELF() const {
778 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700779 case ScriptStatus::Compiled: {
780 return mCompiled->getELF();
781 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700782
Shih-wei Liaod50be322011-07-01 22:53:31 -0700783 default: {
784 return NULL;
785 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700786 }
787}
788#endif
Logancf3e5212010-12-29 01:44:55 +0800789
790} // namespace bcc