blob: aae0692e27ae90050cafe68a8a2bb7ee8aee89df [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
79 for (size_t i = 0; i < 2; ++i) {
80 delete mSourceList[i];
81 }
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
Joseph Wen34c600a2011-07-25 17:59:17 -0700183int Script::prepareSharedObject(char const *cacheDir,
184 char const *cacheName,
185 unsigned long flags) {
186#if USE_CACHE
187 if (cacheDir && cacheName) {
188 // Set Cache Directory and File Name
189 mCacheDir = cacheDir;
190 mCacheName = cacheName;
191
192 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
193 mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
194 }
195
196 // Check Cache File
197 if (internalLoadCache(true) == 0) {
198 return 0;
199 }
200 }
201#endif
Zonr Chang2fcbd022012-01-06 21:04:31 +0800202
203 CompilerOption option;
204 option.LoadAfterCompile = false;
205 int status = internalCompile(option);
Joseph Wen34c600a2011-07-25 17:59:17 -0700206 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000207 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Joseph Wen34c600a2011-07-25 17:59:17 -0700208 }
209 return status;
210}
211
Logancf3e5212010-12-29 01:44:55 +0800212
Logan Chien311c26f2011-07-11 14:30:34 +0800213int Script::prepareExecutable(char const *cacheDir,
214 char const *cacheName,
215 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800216 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800217 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000218 ALOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800219 return 1;
220 }
221
Logan35849002011-01-15 07:30:43 +0800222#if USE_CACHE
Logan Chien311c26f2011-07-11 14:30:34 +0800223 if (cacheDir && cacheName) {
224 // Set Cache Directory and File Name
225 mCacheDir = cacheDir;
226 mCacheName = cacheName;
227
228 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
229 mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
230 }
231
232 // Load Cache File
Joseph Wen34c600a2011-07-25 17:59:17 -0700233 if (internalLoadCache(false) == 0) {
Logan Chien311c26f2011-07-11 14:30:34 +0800234 return 0;
235 }
Logan033f46e2011-01-06 05:51:24 +0800236 }
Logan35849002011-01-15 07:30:43 +0800237#endif
Loganecf4cbd2011-01-06 05:34:11 +0800238
Zonr Chang2fcbd022012-01-06 21:04:31 +0800239 CompilerOption option;
240 int status = internalCompile(option);
Stephen Hines27b35102011-05-11 17:58:48 -0700241 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000242 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Stephen Hines27b35102011-05-11 17:58:48 -0700243 }
244 return status;
Logan033f46e2011-01-06 05:51:24 +0800245}
246
247
Logan35849002011-01-15 07:30:43 +0800248#if USE_CACHE
Joseph Wen34c600a2011-07-25 17:59:17 -0700249int Script::internalLoadCache(bool checkOnly) {
Joseph Wen76919072011-07-07 23:06:15 -0700250 if (getBooleanProp("debug.bcc.nocache")) {
Logan033f46e2011-01-06 05:51:24 +0800251 // Android system environment property disable the cache mechanism by
252 // setting "debug.bcc.nocache". So we will not load the cache file any
253 // way.
254 return 1;
255 }
256
Logan Chien311c26f2011-07-11 14:30:34 +0800257 if (mCacheDir.empty() || mCacheName.empty()) {
Loganf340bf72011-01-14 17:51:40 +0800258 // The application developer has not specify the cachePath, so
Logan04329712011-01-06 06:10:57 +0800259 // we don't know where to open the cache file.
260 return 1;
Logan033f46e2011-01-06 05:51:24 +0800261 }
Logan04329712011-01-06 06:10:57 +0800262
Logan Chien311c26f2011-07-11 14:30:34 +0800263#if USE_OLD_JIT
Logan Chien03a2e302011-07-13 21:46:32 +0800264 std::string objPath(mCacheDir + mCacheName + ".jit-image");
265 std::string infoPath(mCacheDir + mCacheName + ".oBCC"); // TODO: .info instead
Logan Chien311c26f2011-07-11 14:30:34 +0800266#elif USE_MCJIT
267 std::string objPath(mCacheDir + mCacheName + ".o");
268 std::string infoPath(mCacheDir + mCacheName + ".info");
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700269#endif
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700270
Logan Chien311c26f2011-07-11 14:30:34 +0800271 FileHandle objFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700272 if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800273 // Unable to open the executable file in read mode.
Logan04329712011-01-06 06:10:57 +0800274 return 1;
275 }
276
Logan Chien311c26f2011-07-11 14:30:34 +0800277 FileHandle infoFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700278 if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800279 // Unable to open the metadata information file in read mode.
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700280 return 1;
281 }
282
Logan Chien311c26f2011-07-11 14:30:34 +0800283#if USE_OLD_JIT
284 CacheReader reader;
285#elif USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700286 MCCacheReader reader;
287
288 // Register symbol lookup function
289 if (mpExtSymbolLookupFn) {
290 reader.registerSymbolCallback(mpExtSymbolLookupFn,
291 mpExtSymbolLookupFnContext);
292 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700293#endif
Logan04329712011-01-06 06:10:57 +0800294
Logan9a5f8682011-01-07 06:09:57 +0800295 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700296 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700297 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logan9a5f8682011-01-07 06:09:57 +0800298
Logan474cbd22011-01-31 01:47:44 +0800299 for (size_t i = 0; i < 2; ++i) {
300 if (mSourceList[i]) {
301 mSourceList[i]->introDependency(reader);
302 }
Logan9a5f8682011-01-07 06:09:57 +0800303 }
304
Joseph Wen34c600a2011-07-25 17:59:17 -0700305 if (checkOnly)
Joseph Wen49281042011-07-26 10:04:09 -0700306 return !reader.checkCacheFile(&objFile, &infoFile, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700307
Logan9a5f8682011-01-07 06:09:57 +0800308 // Read cache file
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700309 ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700310
Logan04329712011-01-06 06:10:57 +0800311 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800312 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800313 return 1;
314 }
315
316 mCached = cached;
317 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800318
Loganf3c83ce2011-01-07 06:36:33 +0800319 // Dirty hack for libRS.
320 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800321 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800322 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
323 }
324
Loganf7f0ac52011-01-07 03:53:43 +0800325 return 0;
Logan033f46e2011-01-06 05:51:24 +0800326}
Logan35849002011-01-15 07:30:43 +0800327#endif
Logan033f46e2011-01-06 05:51:24 +0800328
Zonr Chang2fcbd022012-01-06 21:04:31 +0800329int Script::internalCompile(CompilerOption &option) {
Logan033f46e2011-01-06 05:51:24 +0800330 // Create the ScriptCompiled object
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800331 mCompiled = new (std::nothrow) ScriptCompiled(this);
Loganecf4cbd2011-01-06 05:34:11 +0800332
333 if (!mCompiled) {
334 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000335 ALOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
Loganecf4cbd2011-01-06 05:34:11 +0800336 return 1;
337 }
338
339 mStatus = ScriptStatus::Compiled;
340
Logan033f46e2011-01-06 05:51:24 +0800341 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800342 if (mpExtSymbolLookupFn) {
343 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
344 mpExtSymbolLookupFnContext);
345 }
346
Logan474cbd22011-01-31 01:47:44 +0800347 // Parse Bitcode File (if necessary)
348 for (size_t i = 0; i < 2; ++i) {
349 if (mSourceList[i] && mSourceList[i]->prepareModule(mCompiled) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000350 ALOGE("Unable to parse bitcode for source[%lu]\n", (unsigned long)i);
Logan033f46e2011-01-06 05:51:24 +0800351 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800352 }
Logan474cbd22011-01-31 01:47:44 +0800353 }
354
355 // Set the main source module
356 if (!mSourceList[0] || !mSourceList[0]->getModule()) {
Steve Block10c14122012-01-08 10:15:06 +0000357 ALOGE("Source bitcode is not setted.\n");
Logan474cbd22011-01-31 01:47:44 +0800358 return 1;
359 }
360
361 if (mCompiled->readModule(mSourceList[0]->takeModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000362 ALOGE("Unable to read source module\n");
Logan474cbd22011-01-31 01:47:44 +0800363 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800364 }
365
Logan3133c412011-01-06 06:15:40 +0800366 // Link the source module with the library module
Logan474cbd22011-01-31 01:47:44 +0800367 if (mSourceList[1]) {
368 if (mCompiled->linkModule(mSourceList[1]->takeModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000369 ALOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800370 return 1;
371 }
372 }
Loganecf4cbd2011-01-06 05:34:11 +0800373
Logan3133c412011-01-06 06:15:40 +0800374 // Compile and JIT the code
Zonr Chang2fcbd022012-01-06 21:04:31 +0800375 if (mCompiled->compile(option) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000376 ALOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800377 return 1;
378 }
379
Logan35849002011-01-15 07:30:43 +0800380#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800381 // Note: If we re-compile the script because the cached context slot not
382 // available, then we don't have to write the cache.
383
384 // Note: If the address of the context is not in the context slot, then
385 // we don't have to cache it.
386
Logan Chien311c26f2011-07-11 14:30:34 +0800387 if (!mCacheDir.empty() &&
388 !mCacheName.empty() &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700389#if USE_OLD_JIT
Logan1dc63142011-02-25 17:14:51 +0800390 !mIsContextSlotNotAvail &&
391 ContextManager::get().isManagingContext(getContext()) &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700392#endif
Logan42598052011-01-26 22:41:13 +0800393 !getBooleanProp("debug.bcc.nocache")) {
394
Logan Chien311c26f2011-07-11 14:30:34 +0800395#if USE_OLD_JIT
Logan Chien03a2e302011-07-13 21:46:32 +0800396 std::string objPath(mCacheDir + mCacheName + ".jit-image");
397 std::string infoPath(mCacheDir + mCacheName + ".oBCC");
Logan Chien311c26f2011-07-11 14:30:34 +0800398#elif USE_MCJIT
Logan Chien311c26f2011-07-11 14:30:34 +0800399 std::string objPath(mCacheDir + mCacheName + ".o");
400 std::string infoPath(mCacheDir + mCacheName + ".info");
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700401#endif
Logan04329712011-01-06 06:10:57 +0800402
Logan Chien311c26f2011-07-11 14:30:34 +0800403
Jeff Brown937a0bc2011-01-26 23:20:14 -0800404 // Remove the file if it already exists before writing the new file.
405 // The old file may still be mapped elsewhere in memory and we do not want
406 // to modify its contents. (The same script may be running concurrently in
407 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700408 ::unlink(objPath.c_str());
Logan Chien311c26f2011-07-11 14:30:34 +0800409#if !USE_OLD_JIT && USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700410 ::unlink(infoPath.c_str());
411#endif
Jeff Brown937a0bc2011-01-26 23:20:14 -0800412
Logan Chien03a2e302011-07-13 21:46:32 +0800413 FileHandle objFile;
414 FileHandle infoFile;
415
416 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
417 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700418
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700419#if USE_OLD_JIT
Logan04329712011-01-06 06:10:57 +0800420 CacheWriter writer;
Logan Chien311c26f2011-07-11 14:30:34 +0800421#elif USE_MCJIT
422 MCCacheWriter writer;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700423#endif
Logana27a83f2011-01-07 10:25:48 +0800424
Joseph Wen2ca6e572011-06-24 14:12:23 -0700425#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800426 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700427 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700428 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800429#endif
Logana2e15af2011-01-07 11:46:08 +0800430
Logan474cbd22011-01-31 01:47:44 +0800431 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800432 if (mSourceList[i]) {
433 mSourceList[i]->introDependency(writer);
434 }
Logana2e15af2011-01-07 11:46:08 +0800435 }
436
Logana27a83f2011-01-07 10:25:48 +0800437 // libRS is threadable dirty hack
438 // TODO: This should be removed in the future
439 uint32_t libRS_threadable = 0;
440 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800441 libRS_threadable =
442 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
443 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800444 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700445
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700446 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700447 objFile.truncate();
448 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800449
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700450 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000451 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700452 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800453 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700454
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700455 infoFile.truncate();
456 infoFile.close();
457
458 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000459 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700460 infoPath.c_str(), strerror(errno));
461 }
Logan89eb47f2011-01-07 10:45:16 +0800462 }
463 }
Logan04329712011-01-06 06:10:57 +0800464 }
Logan35849002011-01-15 07:30:43 +0800465#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800466
467 return 0;
Logancf3e5212010-12-29 01:44:55 +0800468}
469
470
471char const *Script::getCompilerErrorMessage() {
472 if (mStatus != ScriptStatus::Compiled) {
473 mErrorCode = BCC_INVALID_OPERATION;
474 return NULL;
475 }
476
477 return mCompiled->getCompilerErrorMessage();
478}
479
480
481void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800482 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700483 case ScriptStatus::Compiled: {
484 return mCompiled->lookup(name);
485 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700486
Logan35849002011-01-15 07:30:43 +0800487#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700488 case ScriptStatus::Cached: {
489 return mCached->lookup(name);
490 }
Logan35849002011-01-15 07:30:43 +0800491#endif
Logan89eb47f2011-01-07 10:45:16 +0800492
Shih-wei Liaod50be322011-07-01 22:53:31 -0700493 default: {
494 mErrorCode = BCC_INVALID_OPERATION;
495 return NULL;
496 }
Logancf3e5212010-12-29 01:44:55 +0800497 }
Logancf3e5212010-12-29 01:44:55 +0800498}
499
500
Loganbe79ada2011-01-13 01:33:45 +0800501size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800502 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700503 case ScriptStatus::Compiled: {
504 return mCompiled->getExportVarCount();
505 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700506
Logan35849002011-01-15 07:30:43 +0800507#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700508 case ScriptStatus::Cached: {
509 return mCached->getExportVarCount();
510 }
Logan35849002011-01-15 07:30:43 +0800511#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700512
Shih-wei Liaod50be322011-07-01 22:53:31 -0700513 default: {
514 return 0;
515 }
Loganbe79ada2011-01-13 01:33:45 +0800516 }
517}
518
519
520size_t Script::getExportFuncCount() const {
521 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700522 case ScriptStatus::Compiled: {
523 return mCompiled->getExportFuncCount();
524 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700525
Logan35849002011-01-15 07:30:43 +0800526#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700527 case ScriptStatus::Cached: {
528 return mCached->getExportFuncCount();
529 }
Logan35849002011-01-15 07:30:43 +0800530#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700531
Shih-wei Liaod50be322011-07-01 22:53:31 -0700532 default: {
533 return 0;
534 }
Loganbe79ada2011-01-13 01:33:45 +0800535 }
536}
537
538
539size_t Script::getPragmaCount() const {
540 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700541 case ScriptStatus::Compiled: {
542 return mCompiled->getPragmaCount();
543 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700544
Logan35849002011-01-15 07:30:43 +0800545#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700546 case ScriptStatus::Cached: {
547 return mCached->getPragmaCount();
548 }
Logan35849002011-01-15 07:30:43 +0800549#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700550
Shih-wei Liaod50be322011-07-01 22:53:31 -0700551 default: {
552 return 0;
553 }
Loganbe79ada2011-01-13 01:33:45 +0800554 }
555}
556
557
558size_t Script::getFuncCount() const {
559 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700560 case ScriptStatus::Compiled: {
561 return mCompiled->getFuncCount();
562 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700563
Logan35849002011-01-15 07:30:43 +0800564#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700565 case ScriptStatus::Cached: {
566 return mCached->getFuncCount();
567 }
Logan35849002011-01-15 07:30:43 +0800568#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700569
Shih-wei Liaod50be322011-07-01 22:53:31 -0700570 default: {
571 return 0;
572 }
Loganbe79ada2011-01-13 01:33:45 +0800573 }
574}
575
576
Stephen Hines071288a2011-01-27 14:38:26 -0800577size_t Script::getObjectSlotCount() const {
578 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700579 case ScriptStatus::Compiled: {
580 return mCompiled->getObjectSlotCount();
581 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700582
Stephen Hines071288a2011-01-27 14:38:26 -0800583#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700584 case ScriptStatus::Cached: {
585 return mCached->getObjectSlotCount();
586 }
Stephen Hines071288a2011-01-27 14:38:26 -0800587#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700588
Shih-wei Liaod50be322011-07-01 22:53:31 -0700589 default: {
590 return 0;
591 }
Stephen Hines071288a2011-01-27 14:38:26 -0800592 }
593}
594
595
Loganbe79ada2011-01-13 01:33:45 +0800596void Script::getExportVarList(size_t varListSize, void **varList) {
597 switch (mStatus) {
598#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700599 case ScriptStatus::STATUS: \
600 m##STATUS->getExportVarList(varListSize, varList); \
601 break;
Logancf3e5212010-12-29 01:44:55 +0800602
Logan35849002011-01-15 07:30:43 +0800603#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700604 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800605#endif
606
Shih-wei Liaod50be322011-07-01 22:53:31 -0700607 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800608#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800609
Shih-wei Liaod50be322011-07-01 22:53:31 -0700610 default: {
611 mErrorCode = BCC_INVALID_OPERATION;
612 }
Logan89eb47f2011-01-07 10:45:16 +0800613 }
Logancf3e5212010-12-29 01:44:55 +0800614}
615
Joseph Wenf36637f2011-07-06 18:27:12 -0700616void Script::getExportVarNameList(std::vector<std::string> &varList) {
617 switch (mStatus) {
618 case ScriptStatus::Compiled: {
619 return mCompiled->getExportVarNameList(varList);
620 }
621
622 default: {
623 mErrorCode = BCC_INVALID_OPERATION;
624 }
625 }
626}
627
Logancf3e5212010-12-29 01:44:55 +0800628
Loganbe79ada2011-01-13 01:33:45 +0800629void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800630 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800631#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700632 case ScriptStatus::STATUS: \
633 m##STATUS->getExportFuncList(funcListSize, funcList); \
634 break;
Logancf3e5212010-12-29 01:44:55 +0800635
Logan35849002011-01-15 07:30:43 +0800636#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700637 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800638#endif
639
Shih-wei Liaod50be322011-07-01 22:53:31 -0700640 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800641#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800642
Shih-wei Liaod50be322011-07-01 22:53:31 -0700643 default: {
644 mErrorCode = BCC_INVALID_OPERATION;
645 }
Logan89eb47f2011-01-07 10:45:16 +0800646 }
Logancf3e5212010-12-29 01:44:55 +0800647}
648
Joseph Wenf36637f2011-07-06 18:27:12 -0700649void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
650 switch (mStatus) {
651 case ScriptStatus::Compiled: {
652 return mCompiled->getExportFuncNameList(funcList);
653 }
654
655 default: {
656 mErrorCode = BCC_INVALID_OPERATION;
657 }
658 }
659}
660
Logancf3e5212010-12-29 01:44:55 +0800661
Loganbe79ada2011-01-13 01:33:45 +0800662void Script::getPragmaList(size_t pragmaListSize,
663 char const **keyList,
664 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800665 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800666#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700667 case ScriptStatus::STATUS: \
668 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
669 break;
Logancf3e5212010-12-29 01:44:55 +0800670
Logan35849002011-01-15 07:30:43 +0800671#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700672 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800673#endif
674
Shih-wei Liaod50be322011-07-01 22:53:31 -0700675 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800676#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800677
Shih-wei Liaod50be322011-07-01 22:53:31 -0700678 default: {
679 mErrorCode = BCC_INVALID_OPERATION;
680 }
Logan89eb47f2011-01-07 10:45:16 +0800681 }
Logancf3e5212010-12-29 01:44:55 +0800682}
683
684
Loganf340bf72011-01-14 17:51:40 +0800685void Script::getFuncInfoList(size_t funcInfoListSize,
686 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800687 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800688#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700689 case ScriptStatus::STATUS: \
690 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
691 break;
Logancf3e5212010-12-29 01:44:55 +0800692
Logan35849002011-01-15 07:30:43 +0800693#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700694 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800695#endif
696
Shih-wei Liaod50be322011-07-01 22:53:31 -0700697 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800698#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800699
Shih-wei Liaod50be322011-07-01 22:53:31 -0700700 default: {
701 mErrorCode = BCC_INVALID_OPERATION;
702 }
Logan89eb47f2011-01-07 10:45:16 +0800703 }
Logancf3e5212010-12-29 01:44:55 +0800704}
705
Stephen Hines071288a2011-01-27 14:38:26 -0800706
707void Script::getObjectSlotList(size_t objectSlotListSize,
708 uint32_t *objectSlotList) {
709 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700710#define DELEGATE(STATUS) \
711 case ScriptStatus::STATUS: \
712 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
713 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800714
715#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700716 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800717#endif
718
Shih-wei Liaod50be322011-07-01 22:53:31 -0700719 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800720#undef DELEGATE
721
Shih-wei Liaod50be322011-07-01 22:53:31 -0700722 default: {
723 mErrorCode = BCC_INVALID_OPERATION;
724 }
Stephen Hines071288a2011-01-27 14:38:26 -0800725 }
726}
727
728
Logan Chiend2a5f302011-07-19 20:32:25 +0800729#if USE_OLD_JIT
Logana27a83f2011-01-07 10:25:48 +0800730char *Script::getContext() {
731 switch (mStatus) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700732
Logan35849002011-01-15 07:30:43 +0800733#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700734 case ScriptStatus::Cached: {
735 return mCached->getContext();
736 }
Logan35849002011-01-15 07:30:43 +0800737#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700738
Shih-wei Liaod50be322011-07-01 22:53:31 -0700739 case ScriptStatus::Compiled: {
740 return mCompiled->getContext();
741 }
Logana27a83f2011-01-07 10:25:48 +0800742
Shih-wei Liaod50be322011-07-01 22:53:31 -0700743 default: {
744 mErrorCode = BCC_INVALID_OPERATION;
745 return NULL;
746 }
Logan02286cb2011-01-07 00:30:47 +0800747 }
Logan02286cb2011-01-07 00:30:47 +0800748}
Logan Chiend2a5f302011-07-19 20:32:25 +0800749#endif
Logan02286cb2011-01-07 00:30:47 +0800750
Logancf3e5212010-12-29 01:44:55 +0800751
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800752int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800753 mpExtSymbolLookupFn = pFn;
754 mpExtSymbolLookupFnContext = pContext;
755
Logan7d2219f2011-01-06 06:19:25 +0800756 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800757 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000758 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800759 return 1;
Logancf3e5212010-12-29 01:44:55 +0800760 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800761 return 0;
Logancf3e5212010-12-29 01:44:55 +0800762}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700763
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