blob: 128aa48ca43b72bf7d7ea7cf0040ba2154c8095f [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) {
Joseph Wen76919072011-07-07 23:06:15 -0700254 if (getBooleanProp("debug.bcc.nocache")) {
Logan033f46e2011-01-06 05:51:24 +0800255 // Android system environment property disable the cache mechanism by
256 // setting "debug.bcc.nocache". So we will not load the cache file any
257 // way.
258 return 1;
259 }
260
Logan Chien311c26f2011-07-11 14:30:34 +0800261 if (mCacheDir.empty() || mCacheName.empty()) {
Loganf340bf72011-01-14 17:51:40 +0800262 // The application developer has not specify the cachePath, so
Logan04329712011-01-06 06:10:57 +0800263 // we don't know where to open the cache file.
264 return 1;
Logan033f46e2011-01-06 05:51:24 +0800265 }
Logan04329712011-01-06 06:10:57 +0800266
Zonr Chang4ea08862012-01-17 17:26:49 +0800267 std::string objPath = getCachedObjectPath();
268 std::string infoPath = getCacheInfoPath();
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700269
Logan Chien311c26f2011-07-11 14:30:34 +0800270 FileHandle objFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700271 if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800272 // Unable to open the executable file in read mode.
Logan04329712011-01-06 06:10:57 +0800273 return 1;
274 }
275
Logan Chien311c26f2011-07-11 14:30:34 +0800276 FileHandle infoFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700277 if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800278 // Unable to open the metadata information file in read mode.
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700279 return 1;
280 }
281
Logan Chien311c26f2011-07-11 14:30:34 +0800282#if USE_OLD_JIT
283 CacheReader reader;
284#elif USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700285 MCCacheReader reader;
286
287 // Register symbol lookup function
288 if (mpExtSymbolLookupFn) {
289 reader.registerSymbolCallback(mpExtSymbolLookupFn,
290 mpExtSymbolLookupFnContext);
291 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700292#endif
Logan04329712011-01-06 06:10:57 +0800293
Logan9a5f8682011-01-07 06:09:57 +0800294 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700295 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700296 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logan9a5f8682011-01-07 06:09:57 +0800297
Logan474cbd22011-01-31 01:47:44 +0800298 for (size_t i = 0; i < 2; ++i) {
299 if (mSourceList[i]) {
300 mSourceList[i]->introDependency(reader);
301 }
Logan9a5f8682011-01-07 06:09:57 +0800302 }
303
Joseph Wen34c600a2011-07-25 17:59:17 -0700304 if (checkOnly)
Joseph Wen49281042011-07-26 10:04:09 -0700305 return !reader.checkCacheFile(&objFile, &infoFile, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700306
Logan9a5f8682011-01-07 06:09:57 +0800307 // Read cache file
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700308 ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700309
Logan04329712011-01-06 06:10:57 +0800310 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800311 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800312 return 1;
313 }
314
315 mCached = cached;
316 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800317
Loganf3c83ce2011-01-07 06:36:33 +0800318 // Dirty hack for libRS.
319 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800320 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800321 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
322 }
323
Loganf7f0ac52011-01-07 03:53:43 +0800324 return 0;
Logan033f46e2011-01-06 05:51:24 +0800325}
Logan35849002011-01-15 07:30:43 +0800326#endif
Logan033f46e2011-01-06 05:51:24 +0800327
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800328int Script::internalCompile(const CompilerOption &option) {
Logan033f46e2011-01-06 05:51:24 +0800329 // Create the ScriptCompiled object
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800330 mCompiled = new (std::nothrow) ScriptCompiled(this);
Loganecf4cbd2011-01-06 05:34:11 +0800331
332 if (!mCompiled) {
333 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000334 ALOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
Loganecf4cbd2011-01-06 05:34:11 +0800335 return 1;
336 }
337
338 mStatus = ScriptStatus::Compiled;
339
Logan033f46e2011-01-06 05:51:24 +0800340 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800341 if (mpExtSymbolLookupFn) {
342 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
343 mpExtSymbolLookupFnContext);
344 }
345
Zonr Changdf3fee42012-01-10 15:58:36 +0800346 if (!mSourceList[0]) {
347 ALOGE("Source bitcode is not set.\n");
Logan474cbd22011-01-31 01:47:44 +0800348 return 1;
349 }
350
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800351 // Parse Source bitcode file (if necessary)
352 if (mSourceList[0]->prepareModule() != 0) {
353 ALOGE("Unable to setup source module\n");
Zonr Changdf3fee42012-01-10 15:58:36 +0800354 return 1;
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800355 }
356
357 // Parse Library bitcode file (if necessary)
358 if (mSourceList[1]) {
359 if (mSourceList[1]->prepareModule(mSourceList[0]->getContext()) != 0) {
360 ALOGE("Unable to setup library module\n");
361 return 1;
362 }
363 }
Zonr Changdf3fee42012-01-10 15:58:36 +0800364
365 // Set the main source module
366 if (mCompiled->readModule(mSourceList[0]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000367 ALOGE("Unable to read source module\n");
Logan474cbd22011-01-31 01:47:44 +0800368 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800369 }
370
Logan3133c412011-01-06 06:15:40 +0800371 // Link the source module with the library module
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800372 if (mSourceList[1]) {
Zonr Changdf3fee42012-01-10 15:58:36 +0800373 if (mCompiled->linkModule(mSourceList[1]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000374 ALOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800375 return 1;
376 }
377 }
Loganecf4cbd2011-01-06 05:34:11 +0800378
Logan3133c412011-01-06 06:15:40 +0800379 // Compile and JIT the code
Zonr Chang2fcbd022012-01-06 21:04:31 +0800380 if (mCompiled->compile(option) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000381 ALOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800382 return 1;
383 }
384
Logan35849002011-01-15 07:30:43 +0800385#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800386 // Note: If we re-compile the script because the cached context slot not
387 // available, then we don't have to write the cache.
388
389 // Note: If the address of the context is not in the context slot, then
390 // we don't have to cache it.
391
Logan Chien311c26f2011-07-11 14:30:34 +0800392 if (!mCacheDir.empty() &&
393 !mCacheName.empty() &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700394#if USE_OLD_JIT
Logan1dc63142011-02-25 17:14:51 +0800395 !mIsContextSlotNotAvail &&
396 ContextManager::get().isManagingContext(getContext()) &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700397#endif
Logan42598052011-01-26 22:41:13 +0800398 !getBooleanProp("debug.bcc.nocache")) {
399
Zonr Chang4ea08862012-01-17 17:26:49 +0800400 std::string objPath = getCachedObjectPath();
401 std::string infoPath = getCacheInfoPath();
Logan Chien311c26f2011-07-11 14:30:34 +0800402
Jeff Brown937a0bc2011-01-26 23:20:14 -0800403 // Remove the file if it already exists before writing the new file.
404 // The old file may still be mapped elsewhere in memory and we do not want
405 // to modify its contents. (The same script may be running concurrently in
406 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700407 ::unlink(objPath.c_str());
Logan Chien311c26f2011-07-11 14:30:34 +0800408#if !USE_OLD_JIT && USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700409 ::unlink(infoPath.c_str());
410#endif
Jeff Brown937a0bc2011-01-26 23:20:14 -0800411
Logan Chien03a2e302011-07-13 21:46:32 +0800412 FileHandle objFile;
413 FileHandle infoFile;
414
415 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
416 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700417
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700418#if USE_OLD_JIT
Logan04329712011-01-06 06:10:57 +0800419 CacheWriter writer;
Logan Chien311c26f2011-07-11 14:30:34 +0800420#elif USE_MCJIT
421 MCCacheWriter writer;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700422#endif
Logana27a83f2011-01-07 10:25:48 +0800423
Joseph Wen2ca6e572011-06-24 14:12:23 -0700424#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800425 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700426 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700427 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800428#endif
Logana2e15af2011-01-07 11:46:08 +0800429
Logan474cbd22011-01-31 01:47:44 +0800430 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800431 if (mSourceList[i]) {
432 mSourceList[i]->introDependency(writer);
433 }
Logana2e15af2011-01-07 11:46:08 +0800434 }
435
Logana27a83f2011-01-07 10:25:48 +0800436 // libRS is threadable dirty hack
437 // TODO: This should be removed in the future
438 uint32_t libRS_threadable = 0;
439 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800440 libRS_threadable =
441 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
442 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800443 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700444
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700445 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700446 objFile.truncate();
447 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800448
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700449 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000450 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700451 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800452 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700453
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700454 infoFile.truncate();
455 infoFile.close();
456
457 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000458 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700459 infoPath.c_str(), strerror(errno));
460 }
Logan89eb47f2011-01-07 10:45:16 +0800461 }
462 }
Logan04329712011-01-06 06:10:57 +0800463 }
Logan35849002011-01-15 07:30:43 +0800464#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800465
466 return 0;
Logancf3e5212010-12-29 01:44:55 +0800467}
468
469
470char const *Script::getCompilerErrorMessage() {
471 if (mStatus != ScriptStatus::Compiled) {
472 mErrorCode = BCC_INVALID_OPERATION;
473 return NULL;
474 }
475
476 return mCompiled->getCompilerErrorMessage();
477}
478
479
480void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800481 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700482 case ScriptStatus::Compiled: {
483 return mCompiled->lookup(name);
484 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700485
Logan35849002011-01-15 07:30:43 +0800486#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700487 case ScriptStatus::Cached: {
488 return mCached->lookup(name);
489 }
Logan35849002011-01-15 07:30:43 +0800490#endif
Logan89eb47f2011-01-07 10:45:16 +0800491
Shih-wei Liaod50be322011-07-01 22:53:31 -0700492 default: {
493 mErrorCode = BCC_INVALID_OPERATION;
494 return NULL;
495 }
Logancf3e5212010-12-29 01:44:55 +0800496 }
Logancf3e5212010-12-29 01:44:55 +0800497}
498
499
Loganbe79ada2011-01-13 01:33:45 +0800500size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800501 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700502 case ScriptStatus::Compiled: {
503 return mCompiled->getExportVarCount();
504 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700505
Logan35849002011-01-15 07:30:43 +0800506#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700507 case ScriptStatus::Cached: {
508 return mCached->getExportVarCount();
509 }
Logan35849002011-01-15 07:30:43 +0800510#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700511
Shih-wei Liaod50be322011-07-01 22:53:31 -0700512 default: {
513 return 0;
514 }
Loganbe79ada2011-01-13 01:33:45 +0800515 }
516}
517
518
519size_t Script::getExportFuncCount() const {
520 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700521 case ScriptStatus::Compiled: {
522 return mCompiled->getExportFuncCount();
523 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700524
Logan35849002011-01-15 07:30:43 +0800525#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700526 case ScriptStatus::Cached: {
527 return mCached->getExportFuncCount();
528 }
Logan35849002011-01-15 07:30:43 +0800529#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700530
Shih-wei Liaod50be322011-07-01 22:53:31 -0700531 default: {
532 return 0;
533 }
Loganbe79ada2011-01-13 01:33:45 +0800534 }
535}
536
537
538size_t Script::getPragmaCount() const {
539 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700540 case ScriptStatus::Compiled: {
541 return mCompiled->getPragmaCount();
542 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700543
Logan35849002011-01-15 07:30:43 +0800544#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700545 case ScriptStatus::Cached: {
546 return mCached->getPragmaCount();
547 }
Logan35849002011-01-15 07:30:43 +0800548#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700549
Shih-wei Liaod50be322011-07-01 22:53:31 -0700550 default: {
551 return 0;
552 }
Loganbe79ada2011-01-13 01:33:45 +0800553 }
554}
555
556
557size_t Script::getFuncCount() const {
558 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700559 case ScriptStatus::Compiled: {
560 return mCompiled->getFuncCount();
561 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700562
Logan35849002011-01-15 07:30:43 +0800563#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700564 case ScriptStatus::Cached: {
565 return mCached->getFuncCount();
566 }
Logan35849002011-01-15 07:30:43 +0800567#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700568
Shih-wei Liaod50be322011-07-01 22:53:31 -0700569 default: {
570 return 0;
571 }
Loganbe79ada2011-01-13 01:33:45 +0800572 }
573}
574
575
Stephen Hines071288a2011-01-27 14:38:26 -0800576size_t Script::getObjectSlotCount() const {
577 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700578 case ScriptStatus::Compiled: {
579 return mCompiled->getObjectSlotCount();
580 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700581
Stephen Hines071288a2011-01-27 14:38:26 -0800582#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700583 case ScriptStatus::Cached: {
584 return mCached->getObjectSlotCount();
585 }
Stephen Hines071288a2011-01-27 14:38:26 -0800586#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700587
Shih-wei Liaod50be322011-07-01 22:53:31 -0700588 default: {
589 return 0;
590 }
Stephen Hines071288a2011-01-27 14:38:26 -0800591 }
592}
593
594
Loganbe79ada2011-01-13 01:33:45 +0800595void Script::getExportVarList(size_t varListSize, void **varList) {
596 switch (mStatus) {
597#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700598 case ScriptStatus::STATUS: \
599 m##STATUS->getExportVarList(varListSize, varList); \
600 break;
Logancf3e5212010-12-29 01:44:55 +0800601
Logan35849002011-01-15 07:30:43 +0800602#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700603 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800604#endif
605
Shih-wei Liaod50be322011-07-01 22:53:31 -0700606 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800607#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800608
Shih-wei Liaod50be322011-07-01 22:53:31 -0700609 default: {
610 mErrorCode = BCC_INVALID_OPERATION;
611 }
Logan89eb47f2011-01-07 10:45:16 +0800612 }
Logancf3e5212010-12-29 01:44:55 +0800613}
614
Joseph Wenf36637f2011-07-06 18:27:12 -0700615void Script::getExportVarNameList(std::vector<std::string> &varList) {
616 switch (mStatus) {
617 case ScriptStatus::Compiled: {
618 return mCompiled->getExportVarNameList(varList);
619 }
620
621 default: {
622 mErrorCode = BCC_INVALID_OPERATION;
623 }
624 }
625}
626
Logancf3e5212010-12-29 01:44:55 +0800627
Loganbe79ada2011-01-13 01:33:45 +0800628void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800629 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800630#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700631 case ScriptStatus::STATUS: \
632 m##STATUS->getExportFuncList(funcListSize, funcList); \
633 break;
Logancf3e5212010-12-29 01:44:55 +0800634
Logan35849002011-01-15 07:30:43 +0800635#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700636 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800637#endif
638
Shih-wei Liaod50be322011-07-01 22:53:31 -0700639 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800640#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800641
Shih-wei Liaod50be322011-07-01 22:53:31 -0700642 default: {
643 mErrorCode = BCC_INVALID_OPERATION;
644 }
Logan89eb47f2011-01-07 10:45:16 +0800645 }
Logancf3e5212010-12-29 01:44:55 +0800646}
647
Joseph Wenf36637f2011-07-06 18:27:12 -0700648void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
649 switch (mStatus) {
650 case ScriptStatus::Compiled: {
651 return mCompiled->getExportFuncNameList(funcList);
652 }
653
654 default: {
655 mErrorCode = BCC_INVALID_OPERATION;
656 }
657 }
658}
659
Logancf3e5212010-12-29 01:44:55 +0800660
Loganbe79ada2011-01-13 01:33:45 +0800661void Script::getPragmaList(size_t pragmaListSize,
662 char const **keyList,
663 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800664 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800665#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700666 case ScriptStatus::STATUS: \
667 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
668 break;
Logancf3e5212010-12-29 01:44:55 +0800669
Logan35849002011-01-15 07:30:43 +0800670#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700671 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800672#endif
673
Shih-wei Liaod50be322011-07-01 22:53:31 -0700674 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800675#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800676
Shih-wei Liaod50be322011-07-01 22:53:31 -0700677 default: {
678 mErrorCode = BCC_INVALID_OPERATION;
679 }
Logan89eb47f2011-01-07 10:45:16 +0800680 }
Logancf3e5212010-12-29 01:44:55 +0800681}
682
683
Loganf340bf72011-01-14 17:51:40 +0800684void Script::getFuncInfoList(size_t funcInfoListSize,
685 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800686 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800687#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700688 case ScriptStatus::STATUS: \
689 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
690 break;
Logancf3e5212010-12-29 01:44:55 +0800691
Logan35849002011-01-15 07:30:43 +0800692#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700693 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800694#endif
695
Shih-wei Liaod50be322011-07-01 22:53:31 -0700696 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800697#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800698
Shih-wei Liaod50be322011-07-01 22:53:31 -0700699 default: {
700 mErrorCode = BCC_INVALID_OPERATION;
701 }
Logan89eb47f2011-01-07 10:45:16 +0800702 }
Logancf3e5212010-12-29 01:44:55 +0800703}
704
Stephen Hines071288a2011-01-27 14:38:26 -0800705
706void Script::getObjectSlotList(size_t objectSlotListSize,
707 uint32_t *objectSlotList) {
708 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700709#define DELEGATE(STATUS) \
710 case ScriptStatus::STATUS: \
711 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
712 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800713
714#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700715 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800716#endif
717
Shih-wei Liaod50be322011-07-01 22:53:31 -0700718 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800719#undef DELEGATE
720
Shih-wei Liaod50be322011-07-01 22:53:31 -0700721 default: {
722 mErrorCode = BCC_INVALID_OPERATION;
723 }
Stephen Hines071288a2011-01-27 14:38:26 -0800724 }
725}
726
727
Logan Chiend2a5f302011-07-19 20:32:25 +0800728#if USE_OLD_JIT
Logana27a83f2011-01-07 10:25:48 +0800729char *Script::getContext() {
730 switch (mStatus) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700731
Logan35849002011-01-15 07:30:43 +0800732#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700733 case ScriptStatus::Cached: {
734 return mCached->getContext();
735 }
Logan35849002011-01-15 07:30:43 +0800736#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700737
Shih-wei Liaod50be322011-07-01 22:53:31 -0700738 case ScriptStatus::Compiled: {
739 return mCompiled->getContext();
740 }
Logana27a83f2011-01-07 10:25:48 +0800741
Shih-wei Liaod50be322011-07-01 22:53:31 -0700742 default: {
743 mErrorCode = BCC_INVALID_OPERATION;
744 return NULL;
745 }
Logan02286cb2011-01-07 00:30:47 +0800746 }
Logan02286cb2011-01-07 00:30:47 +0800747}
Logan Chiend2a5f302011-07-19 20:32:25 +0800748#endif
Logan02286cb2011-01-07 00:30:47 +0800749
Logancf3e5212010-12-29 01:44:55 +0800750
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800751int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800752 mpExtSymbolLookupFn = pFn;
753 mpExtSymbolLookupFnContext = pContext;
754
Logan7d2219f2011-01-06 06:19:25 +0800755 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800756 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000757 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800758 return 1;
Logancf3e5212010-12-29 01:44:55 +0800759 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800760 return 0;
Logancf3e5212010-12-29 01:44:55 +0800761}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700762
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700763#if USE_MCJIT
764size_t Script::getELFSize() const {
765 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700766 case ScriptStatus::Compiled: {
767 return mCompiled->getELFSize();
768 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700769
Shih-wei Liaod50be322011-07-01 22:53:31 -0700770 default: {
771 return 0;
772 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700773 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700774}
775
776const char *Script::getELF() const {
777 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700778 case ScriptStatus::Compiled: {
779 return mCompiled->getELF();
780 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700781
Shih-wei Liaod50be322011-07-01 22:53:31 -0700782 default: {
783 return NULL;
784 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700785 }
786}
787#endif
Logancf3e5212010-12-29 01:44:55 +0800788
789} // namespace bcc