blob: 854e5a1020e23706d2baa004d3f638725945f4fb [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"
Logan Chiend2a5f302011-07-19 20:32:25 +080028
29#if USE_OLD_JIT
30#include "OldJIT/ContextManager.h"
31#endif
32
Logan4dcd6792011-02-28 05:12:00 +080033#include "DebugHelper.h"
Logan04329712011-01-06 06:10:57 +080034#include "FileHandle.h"
Logancf3e5212010-12-29 01:44:55 +080035#include "ScriptCompiled.h"
Logan9a5f8682011-01-07 06:09:57 +080036#include "ScriptCached.h"
37#include "Sha1Helper.h"
Logan474cbd22011-01-31 01:47:44 +080038#include "SourceInfo.h"
Logancf3e5212010-12-29 01:44:55 +080039
Logan89eb47f2011-01-07 10:45:16 +080040#include <errno.h>
Logan474cbd22011-01-31 01:47:44 +080041#include <sys/stat.h>
42#include <sys/types.h>
Bhanu Chetlapallieb4509b2012-01-08 20:42:56 -080043#include <unistd.h>
Logancf3e5212010-12-29 01:44:55 +080044
Logan89eb47f2011-01-07 10:45:16 +080045#include <new>
46#include <string.h>
Logan033f46e2011-01-06 05:51:24 +080047#include <cutils/properties.h>
48
Logan89eb47f2011-01-07 10:45:16 +080049
Loganecf4cbd2011-01-06 05:34:11 +080050namespace {
51
Logan033f46e2011-01-06 05:51:24 +080052bool getBooleanProp(const char *str) {
Loganf340bf72011-01-14 17:51:40 +080053 char buf[PROPERTY_VALUE_MAX];
54 property_get(str, buf, "0");
55 return strcmp(buf, "0") != 0;
Logan033f46e2011-01-06 05:51:24 +080056}
57
Loganecf4cbd2011-01-06 05:34:11 +080058} // namespace anonymous
59
Logancf3e5212010-12-29 01:44:55 +080060namespace bcc {
61
62Script::~Script() {
Logan35849002011-01-15 07:30:43 +080063 switch (mStatus) {
64 case ScriptStatus::Compiled:
Logancf3e5212010-12-29 01:44:55 +080065 delete mCompiled;
Logan35849002011-01-15 07:30:43 +080066 break;
67
68#if USE_CACHE
69 case ScriptStatus::Cached:
Shih-wei Liaoc4cf6542011-01-13 01:43:01 -080070 delete mCached;
Logan35849002011-01-15 07:30:43 +080071 break;
72#endif
73
74 default:
75 break;
Logancf3e5212010-12-29 01:44:55 +080076 }
Logan474cbd22011-01-31 01:47:44 +080077
78 for (size_t i = 0; i < 2; ++i) {
79 delete mSourceList[i];
80 }
Logancf3e5212010-12-29 01:44:55 +080081}
82
83
Logan474cbd22011-01-31 01:47:44 +080084int Script::addSourceBC(size_t idx,
85 char const *resName,
86 const char *bitcode,
87 size_t bitcodeSize,
88 unsigned long flags) {
Shih-wei Liao898c5a92011-05-18 07:02:39 -070089
90 if (!resName) {
91 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +000092 ALOGE("Invalid argument: resName = NULL\n");
Shih-wei Liao898c5a92011-05-18 07:02:39 -070093 return 1;
94 }
95
Loganecf4cbd2011-01-06 05:34:11 +080096 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +080097 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +000098 ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +080099 return 1;
100 }
101
Logan474cbd22011-01-31 01:47:44 +0800102 if (!bitcode) {
103 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000104 ALOGE("Invalid argument: bitcode = NULL\n");
Logan474cbd22011-01-31 01:47:44 +0800105 return 1;
106 }
107
108 mSourceList[idx] = SourceInfo::createFromBuffer(resName,
109 bitcode, bitcodeSize,
110 flags);
111
112 if (!mSourceList[idx]) {
113 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000114 ALOGE("Out of memory while adding source bitcode\n");
Logan474cbd22011-01-31 01:47:44 +0800115 return 1;
116 }
117
Loganecf4cbd2011-01-06 05:34:11 +0800118 return 0;
Logancf3e5212010-12-29 01:44:55 +0800119}
120
121
Logan474cbd22011-01-31 01:47:44 +0800122int Script::addSourceModule(size_t idx,
123 llvm::Module *module,
124 unsigned long flags) {
Logancf3e5212010-12-29 01:44:55 +0800125 if (mStatus != ScriptStatus::Unknown) {
126 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000127 ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800128 return 1;
129 }
130
Logan474cbd22011-01-31 01:47:44 +0800131 if (!module) {
132 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000133 ALOGE("Invalid argument: module = NULL\n");
Logan474cbd22011-01-31 01:47:44 +0800134 return 1;
135 }
136
137 mSourceList[idx] = SourceInfo::createFromModule(module, flags);
138
139 if (!mSourceList[idx]) {
140 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000141 ALOGE("Out of memory when add source module\n");
Logan474cbd22011-01-31 01:47:44 +0800142 return 1;
143 }
144
Loganecf4cbd2011-01-06 05:34:11 +0800145 return 0;
Logancf3e5212010-12-29 01:44:55 +0800146}
147
148
Logan474cbd22011-01-31 01:47:44 +0800149int Script::addSourceFile(size_t idx,
150 char const *path,
151 unsigned long flags) {
Logan3133c412011-01-06 06:15:40 +0800152 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800153 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000154 ALOGE("Bad operation: Adding source after bccPrepareExecutable\n");
Logancf3e5212010-12-29 01:44:55 +0800155 return 1;
156 }
157
Logan474cbd22011-01-31 01:47:44 +0800158 if (!path) {
159 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000160 ALOGE("Invalid argument: path = NULL\n");
Logan474cbd22011-01-31 01:47:44 +0800161 return 1;
162 }
163
164 struct stat sb;
165 if (stat(path, &sb) != 0) {
166 mErrorCode = BCC_INVALID_VALUE;
Steve Block10c14122012-01-08 10:15:06 +0000167 ALOGE("File not found: %s\n", path);
Logan474cbd22011-01-31 01:47:44 +0800168 return 1;
169 }
170
171 mSourceList[idx] = SourceInfo::createFromFile(path, flags);
172
173 if (!mSourceList[idx]) {
174 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000175 ALOGE("Out of memory while adding source file\n");
Logan474cbd22011-01-31 01:47:44 +0800176 return 1;
177 }
178
Logan3133c412011-01-06 06:15:40 +0800179 return 0;
Logancf3e5212010-12-29 01:44:55 +0800180}
181
Joseph Wen34c600a2011-07-25 17:59:17 -0700182int Script::prepareSharedObject(char const *cacheDir,
183 char const *cacheName,
184 unsigned long flags) {
185#if USE_CACHE
186 if (cacheDir && cacheName) {
187 // Set Cache Directory and File Name
188 mCacheDir = cacheDir;
189 mCacheName = cacheName;
190
191 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
192 mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
193 }
194
195 // Check Cache File
196 if (internalLoadCache(true) == 0) {
197 return 0;
198 }
199 }
200#endif
201 int status = internalCompile(true);
202 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000203 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Joseph Wen34c600a2011-07-25 17:59:17 -0700204 }
205 return status;
206}
207
Logancf3e5212010-12-29 01:44:55 +0800208
Logan Chien311c26f2011-07-11 14:30:34 +0800209int Script::prepareExecutable(char const *cacheDir,
210 char const *cacheName,
211 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800212 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800213 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000214 ALOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800215 return 1;
216 }
217
Logan35849002011-01-15 07:30:43 +0800218#if USE_CACHE
Logan Chien311c26f2011-07-11 14:30:34 +0800219 if (cacheDir && cacheName) {
220 // Set Cache Directory and File Name
221 mCacheDir = cacheDir;
222 mCacheName = cacheName;
223
224 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
225 mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
226 }
227
228 // Load Cache File
Joseph Wen34c600a2011-07-25 17:59:17 -0700229 if (internalLoadCache(false) == 0) {
Logan Chien311c26f2011-07-11 14:30:34 +0800230 return 0;
231 }
Logan033f46e2011-01-06 05:51:24 +0800232 }
Logan35849002011-01-15 07:30:43 +0800233#endif
Loganecf4cbd2011-01-06 05:34:11 +0800234
Joseph Wen34c600a2011-07-25 17:59:17 -0700235 int status = internalCompile(false);
Stephen Hines27b35102011-05-11 17:58:48 -0700236 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000237 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Stephen Hines27b35102011-05-11 17:58:48 -0700238 }
239 return status;
Logan033f46e2011-01-06 05:51:24 +0800240}
241
242
Logan35849002011-01-15 07:30:43 +0800243#if USE_CACHE
Joseph Wen34c600a2011-07-25 17:59:17 -0700244int Script::internalLoadCache(bool checkOnly) {
Joseph Wen76919072011-07-07 23:06:15 -0700245 if (getBooleanProp("debug.bcc.nocache")) {
Logan033f46e2011-01-06 05:51:24 +0800246 // Android system environment property disable the cache mechanism by
247 // setting "debug.bcc.nocache". So we will not load the cache file any
248 // way.
249 return 1;
250 }
251
Logan Chien311c26f2011-07-11 14:30:34 +0800252 if (mCacheDir.empty() || mCacheName.empty()) {
Loganf340bf72011-01-14 17:51:40 +0800253 // The application developer has not specify the cachePath, so
Logan04329712011-01-06 06:10:57 +0800254 // we don't know where to open the cache file.
255 return 1;
Logan033f46e2011-01-06 05:51:24 +0800256 }
Logan04329712011-01-06 06:10:57 +0800257
Logan Chien311c26f2011-07-11 14:30:34 +0800258#if USE_OLD_JIT
Logan Chien03a2e302011-07-13 21:46:32 +0800259 std::string objPath(mCacheDir + mCacheName + ".jit-image");
260 std::string infoPath(mCacheDir + mCacheName + ".oBCC"); // TODO: .info instead
Logan Chien311c26f2011-07-11 14:30:34 +0800261#elif USE_MCJIT
262 std::string objPath(mCacheDir + mCacheName + ".o");
263 std::string infoPath(mCacheDir + mCacheName + ".info");
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700264#endif
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
Joseph Wen34c600a2011-07-25 17:59:17 -0700324int Script::internalCompile(bool compileOnly) {
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
Logan474cbd22011-01-31 01:47:44 +0800342 // Parse Bitcode File (if necessary)
343 for (size_t i = 0; i < 2; ++i) {
344 if (mSourceList[i] && mSourceList[i]->prepareModule(mCompiled) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000345 ALOGE("Unable to parse bitcode for source[%lu]\n", (unsigned long)i);
Logan033f46e2011-01-06 05:51:24 +0800346 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800347 }
Logan474cbd22011-01-31 01:47:44 +0800348 }
349
350 // Set the main source module
351 if (!mSourceList[0] || !mSourceList[0]->getModule()) {
Steve Block10c14122012-01-08 10:15:06 +0000352 ALOGE("Source bitcode is not setted.\n");
Logan474cbd22011-01-31 01:47:44 +0800353 return 1;
354 }
355
356 if (mCompiled->readModule(mSourceList[0]->takeModule()) != 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
Logan474cbd22011-01-31 01:47:44 +0800362 if (mSourceList[1]) {
363 if (mCompiled->linkModule(mSourceList[1]->takeModule()) != 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
Joseph Wen34c600a2011-07-25 17:59:17 -0700370 if (mCompiled->compile(compileOnly) != 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
Logan Chien311c26f2011-07-11 14:30:34 +0800382 if (!mCacheDir.empty() &&
383 !mCacheName.empty() &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700384#if USE_OLD_JIT
Logan1dc63142011-02-25 17:14:51 +0800385 !mIsContextSlotNotAvail &&
386 ContextManager::get().isManagingContext(getContext()) &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700387#endif
Logan42598052011-01-26 22:41:13 +0800388 !getBooleanProp("debug.bcc.nocache")) {
389
Logan Chien311c26f2011-07-11 14:30:34 +0800390#if USE_OLD_JIT
Logan Chien03a2e302011-07-13 21:46:32 +0800391 std::string objPath(mCacheDir + mCacheName + ".jit-image");
392 std::string infoPath(mCacheDir + mCacheName + ".oBCC");
Logan Chien311c26f2011-07-11 14:30:34 +0800393#elif USE_MCJIT
Logan Chien311c26f2011-07-11 14:30:34 +0800394 std::string objPath(mCacheDir + mCacheName + ".o");
395 std::string infoPath(mCacheDir + mCacheName + ".info");
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700396#endif
Logan04329712011-01-06 06:10:57 +0800397
Logan Chien311c26f2011-07-11 14:30:34 +0800398
Jeff Brown937a0bc2011-01-26 23:20:14 -0800399 // Remove the file if it already exists before writing the new file.
400 // The old file may still be mapped elsewhere in memory and we do not want
401 // to modify its contents. (The same script may be running concurrently in
402 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700403 ::unlink(objPath.c_str());
Logan Chien311c26f2011-07-11 14:30:34 +0800404#if !USE_OLD_JIT && USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700405 ::unlink(infoPath.c_str());
406#endif
Jeff Brown937a0bc2011-01-26 23:20:14 -0800407
Logan Chien03a2e302011-07-13 21:46:32 +0800408 FileHandle objFile;
409 FileHandle infoFile;
410
411 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
412 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700413
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700414#if USE_OLD_JIT
Logan04329712011-01-06 06:10:57 +0800415 CacheWriter writer;
Logan Chien311c26f2011-07-11 14:30:34 +0800416#elif USE_MCJIT
417 MCCacheWriter writer;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700418#endif
Logana27a83f2011-01-07 10:25:48 +0800419
Joseph Wen2ca6e572011-06-24 14:12:23 -0700420#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800421 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700422 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700423 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800424#endif
Logana2e15af2011-01-07 11:46:08 +0800425
Logan474cbd22011-01-31 01:47:44 +0800426 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800427 if (mSourceList[i]) {
428 mSourceList[i]->introDependency(writer);
429 }
Logana2e15af2011-01-07 11:46:08 +0800430 }
431
Logana27a83f2011-01-07 10:25:48 +0800432 // libRS is threadable dirty hack
433 // TODO: This should be removed in the future
434 uint32_t libRS_threadable = 0;
435 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800436 libRS_threadable =
437 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
438 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800439 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700440
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700441 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700442 objFile.truncate();
443 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800444
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700445 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000446 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700447 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800448 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700449
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700450 infoFile.truncate();
451 infoFile.close();
452
453 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000454 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700455 infoPath.c_str(), strerror(errno));
456 }
Logan89eb47f2011-01-07 10:45:16 +0800457 }
458 }
Logan04329712011-01-06 06:10:57 +0800459 }
Logan35849002011-01-15 07:30:43 +0800460#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800461
462 return 0;
Logancf3e5212010-12-29 01:44:55 +0800463}
464
465
466char const *Script::getCompilerErrorMessage() {
467 if (mStatus != ScriptStatus::Compiled) {
468 mErrorCode = BCC_INVALID_OPERATION;
469 return NULL;
470 }
471
472 return mCompiled->getCompilerErrorMessage();
473}
474
475
476void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800477 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700478 case ScriptStatus::Compiled: {
479 return mCompiled->lookup(name);
480 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700481
Logan35849002011-01-15 07:30:43 +0800482#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700483 case ScriptStatus::Cached: {
484 return mCached->lookup(name);
485 }
Logan35849002011-01-15 07:30:43 +0800486#endif
Logan89eb47f2011-01-07 10:45:16 +0800487
Shih-wei Liaod50be322011-07-01 22:53:31 -0700488 default: {
489 mErrorCode = BCC_INVALID_OPERATION;
490 return NULL;
491 }
Logancf3e5212010-12-29 01:44:55 +0800492 }
Logancf3e5212010-12-29 01:44:55 +0800493}
494
495
Loganbe79ada2011-01-13 01:33:45 +0800496size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800497 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700498 case ScriptStatus::Compiled: {
499 return mCompiled->getExportVarCount();
500 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700501
Logan35849002011-01-15 07:30:43 +0800502#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700503 case ScriptStatus::Cached: {
504 return mCached->getExportVarCount();
505 }
Logan35849002011-01-15 07:30:43 +0800506#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700507
Shih-wei Liaod50be322011-07-01 22:53:31 -0700508 default: {
509 return 0;
510 }
Loganbe79ada2011-01-13 01:33:45 +0800511 }
512}
513
514
515size_t Script::getExportFuncCount() const {
516 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700517 case ScriptStatus::Compiled: {
518 return mCompiled->getExportFuncCount();
519 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700520
Logan35849002011-01-15 07:30:43 +0800521#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700522 case ScriptStatus::Cached: {
523 return mCached->getExportFuncCount();
524 }
Logan35849002011-01-15 07:30:43 +0800525#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700526
Shih-wei Liaod50be322011-07-01 22:53:31 -0700527 default: {
528 return 0;
529 }
Loganbe79ada2011-01-13 01:33:45 +0800530 }
531}
532
533
534size_t Script::getPragmaCount() const {
535 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700536 case ScriptStatus::Compiled: {
537 return mCompiled->getPragmaCount();
538 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700539
Logan35849002011-01-15 07:30:43 +0800540#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700541 case ScriptStatus::Cached: {
542 return mCached->getPragmaCount();
543 }
Logan35849002011-01-15 07:30:43 +0800544#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700545
Shih-wei Liaod50be322011-07-01 22:53:31 -0700546 default: {
547 return 0;
548 }
Loganbe79ada2011-01-13 01:33:45 +0800549 }
550}
551
552
553size_t Script::getFuncCount() const {
554 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700555 case ScriptStatus::Compiled: {
556 return mCompiled->getFuncCount();
557 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700558
Logan35849002011-01-15 07:30:43 +0800559#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700560 case ScriptStatus::Cached: {
561 return mCached->getFuncCount();
562 }
Logan35849002011-01-15 07:30:43 +0800563#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700564
Shih-wei Liaod50be322011-07-01 22:53:31 -0700565 default: {
566 return 0;
567 }
Loganbe79ada2011-01-13 01:33:45 +0800568 }
569}
570
571
Stephen Hines071288a2011-01-27 14:38:26 -0800572size_t Script::getObjectSlotCount() const {
573 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700574 case ScriptStatus::Compiled: {
575 return mCompiled->getObjectSlotCount();
576 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700577
Stephen Hines071288a2011-01-27 14:38:26 -0800578#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700579 case ScriptStatus::Cached: {
580 return mCached->getObjectSlotCount();
581 }
Stephen Hines071288a2011-01-27 14:38:26 -0800582#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700583
Shih-wei Liaod50be322011-07-01 22:53:31 -0700584 default: {
585 return 0;
586 }
Stephen Hines071288a2011-01-27 14:38:26 -0800587 }
588}
589
590
Loganbe79ada2011-01-13 01:33:45 +0800591void Script::getExportVarList(size_t varListSize, void **varList) {
592 switch (mStatus) {
593#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700594 case ScriptStatus::STATUS: \
595 m##STATUS->getExportVarList(varListSize, varList); \
596 break;
Logancf3e5212010-12-29 01:44:55 +0800597
Logan35849002011-01-15 07:30:43 +0800598#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700599 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800600#endif
601
Shih-wei Liaod50be322011-07-01 22:53:31 -0700602 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800603#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800604
Shih-wei Liaod50be322011-07-01 22:53:31 -0700605 default: {
606 mErrorCode = BCC_INVALID_OPERATION;
607 }
Logan89eb47f2011-01-07 10:45:16 +0800608 }
Logancf3e5212010-12-29 01:44:55 +0800609}
610
Joseph Wenf36637f2011-07-06 18:27:12 -0700611void Script::getExportVarNameList(std::vector<std::string> &varList) {
612 switch (mStatus) {
613 case ScriptStatus::Compiled: {
614 return mCompiled->getExportVarNameList(varList);
615 }
616
617 default: {
618 mErrorCode = BCC_INVALID_OPERATION;
619 }
620 }
621}
622
Logancf3e5212010-12-29 01:44:55 +0800623
Loganbe79ada2011-01-13 01:33:45 +0800624void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800625 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800626#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700627 case ScriptStatus::STATUS: \
628 m##STATUS->getExportFuncList(funcListSize, funcList); \
629 break;
Logancf3e5212010-12-29 01:44:55 +0800630
Logan35849002011-01-15 07:30:43 +0800631#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700632 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800633#endif
634
Shih-wei Liaod50be322011-07-01 22:53:31 -0700635 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800636#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800637
Shih-wei Liaod50be322011-07-01 22:53:31 -0700638 default: {
639 mErrorCode = BCC_INVALID_OPERATION;
640 }
Logan89eb47f2011-01-07 10:45:16 +0800641 }
Logancf3e5212010-12-29 01:44:55 +0800642}
643
Joseph Wenf36637f2011-07-06 18:27:12 -0700644void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
645 switch (mStatus) {
646 case ScriptStatus::Compiled: {
647 return mCompiled->getExportFuncNameList(funcList);
648 }
649
650 default: {
651 mErrorCode = BCC_INVALID_OPERATION;
652 }
653 }
654}
655
Logancf3e5212010-12-29 01:44:55 +0800656
Loganbe79ada2011-01-13 01:33:45 +0800657void Script::getPragmaList(size_t pragmaListSize,
658 char const **keyList,
659 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800660 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800661#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700662 case ScriptStatus::STATUS: \
663 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
664 break;
Logancf3e5212010-12-29 01:44:55 +0800665
Logan35849002011-01-15 07:30:43 +0800666#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700667 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800668#endif
669
Shih-wei Liaod50be322011-07-01 22:53:31 -0700670 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800671#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800672
Shih-wei Liaod50be322011-07-01 22:53:31 -0700673 default: {
674 mErrorCode = BCC_INVALID_OPERATION;
675 }
Logan89eb47f2011-01-07 10:45:16 +0800676 }
Logancf3e5212010-12-29 01:44:55 +0800677}
678
679
Loganf340bf72011-01-14 17:51:40 +0800680void Script::getFuncInfoList(size_t funcInfoListSize,
681 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800682 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800683#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700684 case ScriptStatus::STATUS: \
685 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
686 break;
Logancf3e5212010-12-29 01:44:55 +0800687
Logan35849002011-01-15 07:30:43 +0800688#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700689 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800690#endif
691
Shih-wei Liaod50be322011-07-01 22:53:31 -0700692 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800693#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800694
Shih-wei Liaod50be322011-07-01 22:53:31 -0700695 default: {
696 mErrorCode = BCC_INVALID_OPERATION;
697 }
Logan89eb47f2011-01-07 10:45:16 +0800698 }
Logancf3e5212010-12-29 01:44:55 +0800699}
700
Stephen Hines071288a2011-01-27 14:38:26 -0800701
702void Script::getObjectSlotList(size_t objectSlotListSize,
703 uint32_t *objectSlotList) {
704 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700705#define DELEGATE(STATUS) \
706 case ScriptStatus::STATUS: \
707 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
708 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800709
710#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700711 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800712#endif
713
Shih-wei Liaod50be322011-07-01 22:53:31 -0700714 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800715#undef DELEGATE
716
Shih-wei Liaod50be322011-07-01 22:53:31 -0700717 default: {
718 mErrorCode = BCC_INVALID_OPERATION;
719 }
Stephen Hines071288a2011-01-27 14:38:26 -0800720 }
721}
722
723
Logan Chiend2a5f302011-07-19 20:32:25 +0800724#if USE_OLD_JIT
Logana27a83f2011-01-07 10:25:48 +0800725char *Script::getContext() {
726 switch (mStatus) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700727
Logan35849002011-01-15 07:30:43 +0800728#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700729 case ScriptStatus::Cached: {
730 return mCached->getContext();
731 }
Logan35849002011-01-15 07:30:43 +0800732#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700733
Shih-wei Liaod50be322011-07-01 22:53:31 -0700734 case ScriptStatus::Compiled: {
735 return mCompiled->getContext();
736 }
Logana27a83f2011-01-07 10:25:48 +0800737
Shih-wei Liaod50be322011-07-01 22:53:31 -0700738 default: {
739 mErrorCode = BCC_INVALID_OPERATION;
740 return NULL;
741 }
Logan02286cb2011-01-07 00:30:47 +0800742 }
Logan02286cb2011-01-07 00:30:47 +0800743}
Logan Chiend2a5f302011-07-19 20:32:25 +0800744#endif
Logan02286cb2011-01-07 00:30:47 +0800745
Logancf3e5212010-12-29 01:44:55 +0800746
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800747int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800748 mpExtSymbolLookupFn = pFn;
749 mpExtSymbolLookupFnContext = pContext;
750
Logan7d2219f2011-01-06 06:19:25 +0800751 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800752 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000753 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800754 return 1;
Logancf3e5212010-12-29 01:44:55 +0800755 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800756 return 0;
Logancf3e5212010-12-29 01:44:55 +0800757}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700758
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700759#if USE_MCJIT
760size_t Script::getELFSize() const {
761 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700762 case ScriptStatus::Compiled: {
763 return mCompiled->getELFSize();
764 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700765
Shih-wei Liaod50be322011-07-01 22:53:31 -0700766 default: {
767 return 0;
768 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700769 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700770}
771
772const char *Script::getELF() const {
773 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700774 case ScriptStatus::Compiled: {
775 return mCompiled->getELF();
776 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700777
Shih-wei Liaod50be322011-07-01 22:53:31 -0700778 default: {
779 return NULL;
780 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700781 }
782}
783#endif
Logancf3e5212010-12-29 01:44:55 +0800784
785} // namespace bcc