blob: 04bed874e117434807d5cdde67d5acd12c29d000 [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) {
Zonr Chang4ea08862012-01-17 17:26:49 +0800187 mObjectType = ScriptObject::Relocatable;
Joseph Wen34c600a2011-07-25 17:59:17 -0700188#if USE_CACHE
189 if (cacheDir && cacheName) {
190 // Set Cache Directory and File Name
191 mCacheDir = cacheDir;
192 mCacheName = cacheName;
193
194 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
195 mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
196 }
197
198 // Check Cache File
199 if (internalLoadCache(true) == 0) {
200 return 0;
201 }
202 }
203#endif
Zonr Chang2fcbd022012-01-06 21:04:31 +0800204
205 CompilerOption option;
Shih-wei Liao8afed382012-01-10 15:57:24 +0800206 option.RelocModelOpt = RelocModel;
Zonr Chang2fcbd022012-01-06 21:04:31 +0800207 option.LoadAfterCompile = false;
208 int status = internalCompile(option);
Joseph Wen34c600a2011-07-25 17:59:17 -0700209 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000210 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Joseph Wen34c600a2011-07-25 17:59:17 -0700211 }
212 return status;
213}
214
Logancf3e5212010-12-29 01:44:55 +0800215
Logan Chien311c26f2011-07-11 14:30:34 +0800216int Script::prepareExecutable(char const *cacheDir,
217 char const *cacheName,
218 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800219 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800220 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000221 ALOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800222 return 1;
223 }
224
Zonr Chang4ea08862012-01-17 17:26:49 +0800225 mObjectType = ScriptObject::Executable;
Logan35849002011-01-15 07:30:43 +0800226#if USE_CACHE
Logan Chien311c26f2011-07-11 14:30:34 +0800227 if (cacheDir && cacheName) {
228 // Set Cache Directory and File Name
229 mCacheDir = cacheDir;
230 mCacheName = cacheName;
231
232 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
233 mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
234 }
235
236 // Load Cache File
Joseph Wen34c600a2011-07-25 17:59:17 -0700237 if (internalLoadCache(false) == 0) {
Logan Chien311c26f2011-07-11 14:30:34 +0800238 return 0;
239 }
Logan033f46e2011-01-06 05:51:24 +0800240 }
Logan35849002011-01-15 07:30:43 +0800241#endif
Loganecf4cbd2011-01-06 05:34:11 +0800242
Zonr Chang2fcbd022012-01-06 21:04:31 +0800243 CompilerOption option;
244 int status = internalCompile(option);
Stephen Hines27b35102011-05-11 17:58:48 -0700245 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000246 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Stephen Hines27b35102011-05-11 17:58:48 -0700247 }
248 return status;
Logan033f46e2011-01-06 05:51:24 +0800249}
250
251
Logan35849002011-01-15 07:30:43 +0800252#if USE_CACHE
Joseph Wen34c600a2011-07-25 17:59:17 -0700253int Script::internalLoadCache(bool checkOnly) {
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800254 if (!isCacheable())
Logan033f46e2011-01-06 05:51:24 +0800255 return 1;
Logan04329712011-01-06 06:10:57 +0800256
Zonr Chang4ea08862012-01-17 17:26:49 +0800257 std::string objPath = getCachedObjectPath();
258 std::string infoPath = getCacheInfoPath();
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700259
Logan Chien311c26f2011-07-11 14:30:34 +0800260 FileHandle objFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700261 if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800262 // Unable to open the executable file in read mode.
Logan04329712011-01-06 06:10:57 +0800263 return 1;
264 }
265
Logan Chien311c26f2011-07-11 14:30:34 +0800266 FileHandle infoFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700267 if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800268 // Unable to open the metadata information file in read mode.
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700269 return 1;
270 }
271
Logan Chien311c26f2011-07-11 14:30:34 +0800272#if USE_OLD_JIT
273 CacheReader reader;
274#elif USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700275 MCCacheReader reader;
276
277 // Register symbol lookup function
278 if (mpExtSymbolLookupFn) {
279 reader.registerSymbolCallback(mpExtSymbolLookupFn,
280 mpExtSymbolLookupFnContext);
281 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700282#endif
Logan04329712011-01-06 06:10:57 +0800283
Logan9a5f8682011-01-07 06:09:57 +0800284 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700285 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700286 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logan9a5f8682011-01-07 06:09:57 +0800287
Logan474cbd22011-01-31 01:47:44 +0800288 for (size_t i = 0; i < 2; ++i) {
289 if (mSourceList[i]) {
290 mSourceList[i]->introDependency(reader);
291 }
Logan9a5f8682011-01-07 06:09:57 +0800292 }
293
Joseph Wen34c600a2011-07-25 17:59:17 -0700294 if (checkOnly)
Joseph Wen49281042011-07-26 10:04:09 -0700295 return !reader.checkCacheFile(&objFile, &infoFile, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700296
Logan9a5f8682011-01-07 06:09:57 +0800297 // Read cache file
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700298 ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700299
Logan04329712011-01-06 06:10:57 +0800300 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800301 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800302 return 1;
303 }
304
305 mCached = cached;
306 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800307
Loganf3c83ce2011-01-07 06:36:33 +0800308 // Dirty hack for libRS.
309 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800310 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800311 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
312 }
313
Loganf7f0ac52011-01-07 03:53:43 +0800314 return 0;
Logan033f46e2011-01-06 05:51:24 +0800315}
Logan35849002011-01-15 07:30:43 +0800316#endif
Logan033f46e2011-01-06 05:51:24 +0800317
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800318int Script::internalCompile(const CompilerOption &option) {
Logan033f46e2011-01-06 05:51:24 +0800319 // Create the ScriptCompiled object
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800320 mCompiled = new (std::nothrow) ScriptCompiled(this);
Loganecf4cbd2011-01-06 05:34:11 +0800321
322 if (!mCompiled) {
323 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000324 ALOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
Loganecf4cbd2011-01-06 05:34:11 +0800325 return 1;
326 }
327
328 mStatus = ScriptStatus::Compiled;
329
Logan033f46e2011-01-06 05:51:24 +0800330 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800331 if (mpExtSymbolLookupFn) {
332 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
333 mpExtSymbolLookupFnContext);
334 }
335
Zonr Changdf3fee42012-01-10 15:58:36 +0800336 if (!mSourceList[0]) {
337 ALOGE("Source bitcode is not set.\n");
Logan474cbd22011-01-31 01:47:44 +0800338 return 1;
339 }
340
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800341 // Parse Source bitcode file (if necessary)
342 if (mSourceList[0]->prepareModule() != 0) {
343 ALOGE("Unable to setup source module\n");
Zonr Changdf3fee42012-01-10 15:58:36 +0800344 return 1;
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800345 }
346
347 // Parse Library bitcode file (if necessary)
348 if (mSourceList[1]) {
349 if (mSourceList[1]->prepareModule(mSourceList[0]->getContext()) != 0) {
350 ALOGE("Unable to setup library module\n");
351 return 1;
352 }
353 }
Zonr Changdf3fee42012-01-10 15:58:36 +0800354
355 // Set the main source module
356 if (mCompiled->readModule(mSourceList[0]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000357 ALOGE("Unable to read source module\n");
Logan474cbd22011-01-31 01:47:44 +0800358 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800359 }
360
Logan3133c412011-01-06 06:15:40 +0800361 // Link the source module with the library module
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800362 if (mSourceList[1]) {
Zonr Changdf3fee42012-01-10 15:58:36 +0800363 if (mCompiled->linkModule(mSourceList[1]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000364 ALOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800365 return 1;
366 }
367 }
Loganecf4cbd2011-01-06 05:34:11 +0800368
Logan3133c412011-01-06 06:15:40 +0800369 // Compile and JIT the code
Zonr Chang2fcbd022012-01-06 21:04:31 +0800370 if (mCompiled->compile(option) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000371 ALOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800372 return 1;
373 }
374
Logan35849002011-01-15 07:30:43 +0800375#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800376 // Note: If we re-compile the script because the cached context slot not
377 // available, then we don't have to write the cache.
378
379 // Note: If the address of the context is not in the context slot, then
380 // we don't have to cache it.
381
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800382 if (
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700383#if USE_OLD_JIT
Logan1dc63142011-02-25 17:14:51 +0800384 !mIsContextSlotNotAvail &&
385 ContextManager::get().isManagingContext(getContext()) &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700386#endif
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800387 isCacheable()) {
Logan42598052011-01-26 22:41:13 +0800388
Zonr Chang4ea08862012-01-17 17:26:49 +0800389 std::string objPath = getCachedObjectPath();
390 std::string infoPath = getCacheInfoPath();
Logan Chien311c26f2011-07-11 14:30:34 +0800391
Jeff Brown937a0bc2011-01-26 23:20:14 -0800392 // Remove the file if it already exists before writing the new file.
393 // The old file may still be mapped elsewhere in memory and we do not want
394 // to modify its contents. (The same script may be running concurrently in
395 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700396 ::unlink(objPath.c_str());
Logan Chien311c26f2011-07-11 14:30:34 +0800397#if !USE_OLD_JIT && USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700398 ::unlink(infoPath.c_str());
399#endif
Jeff Brown937a0bc2011-01-26 23:20:14 -0800400
Logan Chien03a2e302011-07-13 21:46:32 +0800401 FileHandle objFile;
402 FileHandle infoFile;
403
404 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
405 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700406
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700407#if USE_OLD_JIT
Logan04329712011-01-06 06:10:57 +0800408 CacheWriter writer;
Logan Chien311c26f2011-07-11 14:30:34 +0800409#elif USE_MCJIT
410 MCCacheWriter writer;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700411#endif
Logana27a83f2011-01-07 10:25:48 +0800412
Joseph Wen2ca6e572011-06-24 14:12:23 -0700413#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800414 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700415 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700416 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800417#endif
Logana2e15af2011-01-07 11:46:08 +0800418
Logan474cbd22011-01-31 01:47:44 +0800419 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800420 if (mSourceList[i]) {
421 mSourceList[i]->introDependency(writer);
422 }
Logana2e15af2011-01-07 11:46:08 +0800423 }
424
Logana27a83f2011-01-07 10:25:48 +0800425 // libRS is threadable dirty hack
426 // TODO: This should be removed in the future
427 uint32_t libRS_threadable = 0;
428 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800429 libRS_threadable =
430 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
431 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800432 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700433
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700434 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700435 objFile.truncate();
436 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800437
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700438 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000439 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700440 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800441 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700442
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700443 infoFile.truncate();
444 infoFile.close();
445
446 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000447 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700448 infoPath.c_str(), strerror(errno));
449 }
Logan89eb47f2011-01-07 10:45:16 +0800450 }
451 }
Logan04329712011-01-06 06:10:57 +0800452 }
Logan35849002011-01-15 07:30:43 +0800453#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800454
455 return 0;
Logancf3e5212010-12-29 01:44:55 +0800456}
457
458
459char const *Script::getCompilerErrorMessage() {
460 if (mStatus != ScriptStatus::Compiled) {
461 mErrorCode = BCC_INVALID_OPERATION;
462 return NULL;
463 }
464
465 return mCompiled->getCompilerErrorMessage();
466}
467
468
469void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800470 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700471 case ScriptStatus::Compiled: {
472 return mCompiled->lookup(name);
473 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700474
Logan35849002011-01-15 07:30:43 +0800475#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700476 case ScriptStatus::Cached: {
477 return mCached->lookup(name);
478 }
Logan35849002011-01-15 07:30:43 +0800479#endif
Logan89eb47f2011-01-07 10:45:16 +0800480
Shih-wei Liaod50be322011-07-01 22:53:31 -0700481 default: {
482 mErrorCode = BCC_INVALID_OPERATION;
483 return NULL;
484 }
Logancf3e5212010-12-29 01:44:55 +0800485 }
Logancf3e5212010-12-29 01:44:55 +0800486}
487
488
Loganbe79ada2011-01-13 01:33:45 +0800489size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800490 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700491 case ScriptStatus::Compiled: {
492 return mCompiled->getExportVarCount();
493 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700494
Logan35849002011-01-15 07:30:43 +0800495#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700496 case ScriptStatus::Cached: {
497 return mCached->getExportVarCount();
498 }
Logan35849002011-01-15 07:30:43 +0800499#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700500
Shih-wei Liaod50be322011-07-01 22:53:31 -0700501 default: {
502 return 0;
503 }
Loganbe79ada2011-01-13 01:33:45 +0800504 }
505}
506
507
508size_t Script::getExportFuncCount() const {
509 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700510 case ScriptStatus::Compiled: {
511 return mCompiled->getExportFuncCount();
512 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700513
Logan35849002011-01-15 07:30:43 +0800514#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700515 case ScriptStatus::Cached: {
516 return mCached->getExportFuncCount();
517 }
Logan35849002011-01-15 07:30:43 +0800518#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700519
Shih-wei Liaod50be322011-07-01 22:53:31 -0700520 default: {
521 return 0;
522 }
Loganbe79ada2011-01-13 01:33:45 +0800523 }
524}
525
526
527size_t Script::getPragmaCount() const {
528 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700529 case ScriptStatus::Compiled: {
530 return mCompiled->getPragmaCount();
531 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700532
Logan35849002011-01-15 07:30:43 +0800533#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700534 case ScriptStatus::Cached: {
535 return mCached->getPragmaCount();
536 }
Logan35849002011-01-15 07:30:43 +0800537#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700538
Shih-wei Liaod50be322011-07-01 22:53:31 -0700539 default: {
540 return 0;
541 }
Loganbe79ada2011-01-13 01:33:45 +0800542 }
543}
544
545
546size_t Script::getFuncCount() const {
547 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700548 case ScriptStatus::Compiled: {
549 return mCompiled->getFuncCount();
550 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700551
Logan35849002011-01-15 07:30:43 +0800552#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700553 case ScriptStatus::Cached: {
554 return mCached->getFuncCount();
555 }
Logan35849002011-01-15 07:30:43 +0800556#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700557
Shih-wei Liaod50be322011-07-01 22:53:31 -0700558 default: {
559 return 0;
560 }
Loganbe79ada2011-01-13 01:33:45 +0800561 }
562}
563
564
Stephen Hines071288a2011-01-27 14:38:26 -0800565size_t Script::getObjectSlotCount() const {
566 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700567 case ScriptStatus::Compiled: {
568 return mCompiled->getObjectSlotCount();
569 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700570
Stephen Hines071288a2011-01-27 14:38:26 -0800571#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700572 case ScriptStatus::Cached: {
573 return mCached->getObjectSlotCount();
574 }
Stephen Hines071288a2011-01-27 14:38:26 -0800575#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700576
Shih-wei Liaod50be322011-07-01 22:53:31 -0700577 default: {
578 return 0;
579 }
Stephen Hines071288a2011-01-27 14:38:26 -0800580 }
581}
582
583
Loganbe79ada2011-01-13 01:33:45 +0800584void Script::getExportVarList(size_t varListSize, void **varList) {
585 switch (mStatus) {
586#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700587 case ScriptStatus::STATUS: \
588 m##STATUS->getExportVarList(varListSize, varList); \
589 break;
Logancf3e5212010-12-29 01:44:55 +0800590
Logan35849002011-01-15 07:30:43 +0800591#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700592 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800593#endif
594
Shih-wei Liaod50be322011-07-01 22:53:31 -0700595 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800596#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800597
Shih-wei Liaod50be322011-07-01 22:53:31 -0700598 default: {
599 mErrorCode = BCC_INVALID_OPERATION;
600 }
Logan89eb47f2011-01-07 10:45:16 +0800601 }
Logancf3e5212010-12-29 01:44:55 +0800602}
603
Joseph Wenf36637f2011-07-06 18:27:12 -0700604void Script::getExportVarNameList(std::vector<std::string> &varList) {
605 switch (mStatus) {
606 case ScriptStatus::Compiled: {
607 return mCompiled->getExportVarNameList(varList);
608 }
609
610 default: {
611 mErrorCode = BCC_INVALID_OPERATION;
612 }
613 }
614}
615
Logancf3e5212010-12-29 01:44:55 +0800616
Loganbe79ada2011-01-13 01:33:45 +0800617void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800618 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800619#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700620 case ScriptStatus::STATUS: \
621 m##STATUS->getExportFuncList(funcListSize, funcList); \
622 break;
Logancf3e5212010-12-29 01:44:55 +0800623
Logan35849002011-01-15 07:30:43 +0800624#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700625 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800626#endif
627
Shih-wei Liaod50be322011-07-01 22:53:31 -0700628 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800629#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800630
Shih-wei Liaod50be322011-07-01 22:53:31 -0700631 default: {
632 mErrorCode = BCC_INVALID_OPERATION;
633 }
Logan89eb47f2011-01-07 10:45:16 +0800634 }
Logancf3e5212010-12-29 01:44:55 +0800635}
636
Joseph Wenf36637f2011-07-06 18:27:12 -0700637void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
638 switch (mStatus) {
639 case ScriptStatus::Compiled: {
640 return mCompiled->getExportFuncNameList(funcList);
641 }
642
643 default: {
644 mErrorCode = BCC_INVALID_OPERATION;
645 }
646 }
647}
648
Logancf3e5212010-12-29 01:44:55 +0800649
Loganbe79ada2011-01-13 01:33:45 +0800650void Script::getPragmaList(size_t pragmaListSize,
651 char const **keyList,
652 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800653 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800654#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700655 case ScriptStatus::STATUS: \
656 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
657 break;
Logancf3e5212010-12-29 01:44:55 +0800658
Logan35849002011-01-15 07:30:43 +0800659#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700660 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800661#endif
662
Shih-wei Liaod50be322011-07-01 22:53:31 -0700663 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800664#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800665
Shih-wei Liaod50be322011-07-01 22:53:31 -0700666 default: {
667 mErrorCode = BCC_INVALID_OPERATION;
668 }
Logan89eb47f2011-01-07 10:45:16 +0800669 }
Logancf3e5212010-12-29 01:44:55 +0800670}
671
672
Loganf340bf72011-01-14 17:51:40 +0800673void Script::getFuncInfoList(size_t funcInfoListSize,
674 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800675 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800676#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700677 case ScriptStatus::STATUS: \
678 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
679 break;
Logancf3e5212010-12-29 01:44:55 +0800680
Logan35849002011-01-15 07:30:43 +0800681#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700682 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800683#endif
684
Shih-wei Liaod50be322011-07-01 22:53:31 -0700685 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800686#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800687
Shih-wei Liaod50be322011-07-01 22:53:31 -0700688 default: {
689 mErrorCode = BCC_INVALID_OPERATION;
690 }
Logan89eb47f2011-01-07 10:45:16 +0800691 }
Logancf3e5212010-12-29 01:44:55 +0800692}
693
Stephen Hines071288a2011-01-27 14:38:26 -0800694
695void Script::getObjectSlotList(size_t objectSlotListSize,
696 uint32_t *objectSlotList) {
697 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700698#define DELEGATE(STATUS) \
699 case ScriptStatus::STATUS: \
700 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
701 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800702
703#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700704 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800705#endif
706
Shih-wei Liaod50be322011-07-01 22:53:31 -0700707 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800708#undef DELEGATE
709
Shih-wei Liaod50be322011-07-01 22:53:31 -0700710 default: {
711 mErrorCode = BCC_INVALID_OPERATION;
712 }
Stephen Hines071288a2011-01-27 14:38:26 -0800713 }
714}
715
716
Logan Chiend2a5f302011-07-19 20:32:25 +0800717#if USE_OLD_JIT
Logana27a83f2011-01-07 10:25:48 +0800718char *Script::getContext() {
719 switch (mStatus) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700720
Logan35849002011-01-15 07:30:43 +0800721#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700722 case ScriptStatus::Cached: {
723 return mCached->getContext();
724 }
Logan35849002011-01-15 07:30:43 +0800725#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700726
Shih-wei Liaod50be322011-07-01 22:53:31 -0700727 case ScriptStatus::Compiled: {
728 return mCompiled->getContext();
729 }
Logana27a83f2011-01-07 10:25:48 +0800730
Shih-wei Liaod50be322011-07-01 22:53:31 -0700731 default: {
732 mErrorCode = BCC_INVALID_OPERATION;
733 return NULL;
734 }
Logan02286cb2011-01-07 00:30:47 +0800735 }
Logan02286cb2011-01-07 00:30:47 +0800736}
Logan Chiend2a5f302011-07-19 20:32:25 +0800737#endif
Logan02286cb2011-01-07 00:30:47 +0800738
Logancf3e5212010-12-29 01:44:55 +0800739
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800740int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800741 mpExtSymbolLookupFn = pFn;
742 mpExtSymbolLookupFnContext = pContext;
743
Logan7d2219f2011-01-06 06:19:25 +0800744 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800745 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000746 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800747 return 1;
Logancf3e5212010-12-29 01:44:55 +0800748 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800749 return 0;
Logancf3e5212010-12-29 01:44:55 +0800750}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700751
Shih-wei Liaoabc7f512012-01-18 00:34:07 -0800752bool Script::isCacheable() const {
753#if USE_CACHE
754 if (getBooleanProp("debug.bcc.nocache")) {
755 // Android system environment property: Disables the cache mechanism by
756 // setting "debug.bcc.nocache". So we will not load the cache file any
757 // way.
758 return false;
759 }
760
761 if (mCacheDir.empty() || mCacheName.empty()) {
762 // The application developer has not specified the cachePath, so
763 // we don't know where to open the cache file.
764 return false;
765 }
766
767 return true;
768#else
769 return false;
770#endif
771}
772
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700773#if USE_MCJIT
774size_t Script::getELFSize() const {
775 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700776 case ScriptStatus::Compiled: {
777 return mCompiled->getELFSize();
778 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700779
Shih-wei Liaod50be322011-07-01 22:53:31 -0700780 default: {
781 return 0;
782 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700783 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700784}
785
786const char *Script::getELF() const {
787 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700788 case ScriptStatus::Compiled: {
789 return mCompiled->getELF();
790 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700791
Shih-wei Liaod50be322011-07-01 22:53:31 -0700792 default: {
793 return NULL;
794 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700795 }
796}
797#endif
Logancf3e5212010-12-29 01:44:55 +0800798
799} // namespace bcc