blob: bfa914bdcebd157e381fb6b27234f76deba92efb [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
Zonr Changdf3fee42012-01-10 15:58:36 +080079 for (size_t i = 0; i < 2; ++i)
Logan474cbd22011-01-31 01:47:44 +080080 delete mSourceList[i];
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
Shih-wei Liao8afed382012-01-10 15:57:24 +0800182int Script::prepareObject(char const *cacheDir,
183 char const *cacheName,
184 llvm::Reloc::Model RelocModel,
185 unsigned long flags) {
Zonr Chang4ea08862012-01-17 17:26:49 +0800186 mObjectType = ScriptObject::Relocatable;
Joseph Wen34c600a2011-07-25 17:59:17 -0700187#if USE_CACHE
188 if (cacheDir && cacheName) {
189 // Set Cache Directory and File Name
190 mCacheDir = cacheDir;
191 mCacheName = cacheName;
192
193 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
194 mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
195 }
196
197 // Check Cache File
198 if (internalLoadCache(true) == 0) {
199 return 0;
200 }
201 }
202#endif
Zonr Chang2fcbd022012-01-06 21:04:31 +0800203
204 CompilerOption option;
Shih-wei Liao8afed382012-01-10 15:57:24 +0800205 option.RelocModelOpt = RelocModel;
Zonr Chang2fcbd022012-01-06 21:04:31 +0800206 option.LoadAfterCompile = false;
207 int status = internalCompile(option);
Joseph Wen34c600a2011-07-25 17:59:17 -0700208 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000209 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Joseph Wen34c600a2011-07-25 17:59:17 -0700210 }
211 return status;
212}
213
Logancf3e5212010-12-29 01:44:55 +0800214
Logan Chien311c26f2011-07-11 14:30:34 +0800215int Script::prepareExecutable(char const *cacheDir,
216 char const *cacheName,
217 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800218 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800219 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000220 ALOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800221 return 1;
222 }
223
Zonr Chang4ea08862012-01-17 17:26:49 +0800224 mObjectType = ScriptObject::Executable;
Logan35849002011-01-15 07:30:43 +0800225#if USE_CACHE
Logan Chien311c26f2011-07-11 14:30:34 +0800226 if (cacheDir && cacheName) {
227 // Set Cache Directory and File Name
228 mCacheDir = cacheDir;
229 mCacheName = cacheName;
230
231 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
232 mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
233 }
234
235 // Load Cache File
Joseph Wen34c600a2011-07-25 17:59:17 -0700236 if (internalLoadCache(false) == 0) {
Logan Chien311c26f2011-07-11 14:30:34 +0800237 return 0;
238 }
Logan033f46e2011-01-06 05:51:24 +0800239 }
Logan35849002011-01-15 07:30:43 +0800240#endif
Loganecf4cbd2011-01-06 05:34:11 +0800241
Zonr Chang2fcbd022012-01-06 21:04:31 +0800242 CompilerOption option;
243 int status = internalCompile(option);
Stephen Hines27b35102011-05-11 17:58:48 -0700244 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000245 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Stephen Hines27b35102011-05-11 17:58:48 -0700246 }
247 return status;
Logan033f46e2011-01-06 05:51:24 +0800248}
249
250
Logan35849002011-01-15 07:30:43 +0800251#if USE_CACHE
Joseph Wen34c600a2011-07-25 17:59:17 -0700252int Script::internalLoadCache(bool checkOnly) {
Joseph Wen76919072011-07-07 23:06:15 -0700253 if (getBooleanProp("debug.bcc.nocache")) {
Logan033f46e2011-01-06 05:51:24 +0800254 // Android system environment property disable the cache mechanism by
255 // setting "debug.bcc.nocache". So we will not load the cache file any
256 // way.
257 return 1;
258 }
259
Logan Chien311c26f2011-07-11 14:30:34 +0800260 if (mCacheDir.empty() || mCacheName.empty()) {
Loganf340bf72011-01-14 17:51:40 +0800261 // The application developer has not specify the cachePath, so
Logan04329712011-01-06 06:10:57 +0800262 // we don't know where to open the cache file.
263 return 1;
Logan033f46e2011-01-06 05:51:24 +0800264 }
Logan04329712011-01-06 06:10:57 +0800265
Zonr Chang4ea08862012-01-17 17:26:49 +0800266 std::string objPath = getCachedObjectPath();
267 std::string infoPath = getCacheInfoPath();
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700268
Logan Chien311c26f2011-07-11 14:30:34 +0800269 FileHandle objFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700270 if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800271 // Unable to open the executable file in read mode.
Logan04329712011-01-06 06:10:57 +0800272 return 1;
273 }
274
Logan Chien311c26f2011-07-11 14:30:34 +0800275 FileHandle infoFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700276 if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800277 // Unable to open the metadata information file in read mode.
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700278 return 1;
279 }
280
Logan Chien311c26f2011-07-11 14:30:34 +0800281#if USE_OLD_JIT
282 CacheReader reader;
283#elif USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700284 MCCacheReader reader;
285
286 // Register symbol lookup function
287 if (mpExtSymbolLookupFn) {
288 reader.registerSymbolCallback(mpExtSymbolLookupFn,
289 mpExtSymbolLookupFnContext);
290 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700291#endif
Logan04329712011-01-06 06:10:57 +0800292
Logan9a5f8682011-01-07 06:09:57 +0800293 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700294 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700295 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logan9a5f8682011-01-07 06:09:57 +0800296
Logan474cbd22011-01-31 01:47:44 +0800297 for (size_t i = 0; i < 2; ++i) {
298 if (mSourceList[i]) {
299 mSourceList[i]->introDependency(reader);
300 }
Logan9a5f8682011-01-07 06:09:57 +0800301 }
302
Joseph Wen34c600a2011-07-25 17:59:17 -0700303 if (checkOnly)
Joseph Wen49281042011-07-26 10:04:09 -0700304 return !reader.checkCacheFile(&objFile, &infoFile, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700305
Logan9a5f8682011-01-07 06:09:57 +0800306 // Read cache file
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700307 ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700308
Logan04329712011-01-06 06:10:57 +0800309 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800310 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800311 return 1;
312 }
313
314 mCached = cached;
315 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800316
Loganf3c83ce2011-01-07 06:36:33 +0800317 // Dirty hack for libRS.
318 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800319 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800320 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
321 }
322
Loganf7f0ac52011-01-07 03:53:43 +0800323 return 0;
Logan033f46e2011-01-06 05:51:24 +0800324}
Logan35849002011-01-15 07:30:43 +0800325#endif
Logan033f46e2011-01-06 05:51:24 +0800326
Zonr Chang2fcbd022012-01-06 21:04:31 +0800327int Script::internalCompile(CompilerOption &option) {
Logan033f46e2011-01-06 05:51:24 +0800328 // Create the ScriptCompiled object
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800329 mCompiled = new (std::nothrow) ScriptCompiled(this);
Loganecf4cbd2011-01-06 05:34:11 +0800330
331 if (!mCompiled) {
332 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000333 ALOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
Loganecf4cbd2011-01-06 05:34:11 +0800334 return 1;
335 }
336
337 mStatus = ScriptStatus::Compiled;
338
Logan033f46e2011-01-06 05:51:24 +0800339 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800340 if (mpExtSymbolLookupFn) {
341 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
342 mpExtSymbolLookupFnContext);
343 }
344
Zonr Changdf3fee42012-01-10 15:58:36 +0800345 if (!mSourceList[0]) {
346 ALOGE("Source bitcode is not set.\n");
Logan474cbd22011-01-31 01:47:44 +0800347 return 1;
348 }
349
Zonr Changdf3fee42012-01-10 15:58:36 +0800350 // Parse Bitcode File (if necessary)
351 if (mSourceList[0]->prepareModule() != 0)
352 return 1;
353
354 // Set the main source module
355 if (mCompiled->readModule(mSourceList[0]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000356 ALOGE("Unable to read source module\n");
Logan474cbd22011-01-31 01:47:44 +0800357 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800358 }
359
Logan3133c412011-01-06 06:15:40 +0800360 // Link the source module with the library module
Zonr Changdf3fee42012-01-10 15:58:36 +0800361 if (mSourceList[1] &&
362 mSourceList[1]->prepareModule(mSourceList[0]->getContext())) {
363 if (mCompiled->linkModule(mSourceList[1]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000364 ALOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800365 return 1;
366 }
367 }
Loganecf4cbd2011-01-06 05:34:11 +0800368
Logan3133c412011-01-06 06:15:40 +0800369 // Compile and JIT the code
Zonr Chang2fcbd022012-01-06 21:04:31 +0800370 if (mCompiled->compile(option) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000371 ALOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800372 return 1;
373 }
374
Logan35849002011-01-15 07:30:43 +0800375#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800376 // Note: If we re-compile the script because the cached context slot not
377 // available, then we don't have to write the cache.
378
379 // Note: If the address of the context is not in the context slot, then
380 // we don't have to cache it.
381
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
Zonr Chang4ea08862012-01-17 17:26:49 +0800390 std::string objPath = getCachedObjectPath();
391 std::string infoPath = getCacheInfoPath();
Logan Chien311c26f2011-07-11 14:30:34 +0800392
Jeff Brown937a0bc2011-01-26 23:20:14 -0800393 // Remove the file if it already exists before writing the new file.
394 // The old file may still be mapped elsewhere in memory and we do not want
395 // to modify its contents. (The same script may be running concurrently in
396 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700397 ::unlink(objPath.c_str());
Logan Chien311c26f2011-07-11 14:30:34 +0800398#if !USE_OLD_JIT && USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700399 ::unlink(infoPath.c_str());
400#endif
Jeff Brown937a0bc2011-01-26 23:20:14 -0800401
Logan Chien03a2e302011-07-13 21:46:32 +0800402 FileHandle objFile;
403 FileHandle infoFile;
404
405 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
406 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700407
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700408#if USE_OLD_JIT
Logan04329712011-01-06 06:10:57 +0800409 CacheWriter writer;
Logan Chien311c26f2011-07-11 14:30:34 +0800410#elif USE_MCJIT
411 MCCacheWriter writer;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700412#endif
Logana27a83f2011-01-07 10:25:48 +0800413
Joseph Wen2ca6e572011-06-24 14:12:23 -0700414#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800415 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700416 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700417 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800418#endif
Logana2e15af2011-01-07 11:46:08 +0800419
Logan474cbd22011-01-31 01:47:44 +0800420 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800421 if (mSourceList[i]) {
422 mSourceList[i]->introDependency(writer);
423 }
Logana2e15af2011-01-07 11:46:08 +0800424 }
425
Logana27a83f2011-01-07 10:25:48 +0800426 // libRS is threadable dirty hack
427 // TODO: This should be removed in the future
428 uint32_t libRS_threadable = 0;
429 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800430 libRS_threadable =
431 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
432 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800433 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700434
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700435 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700436 objFile.truncate();
437 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800438
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700439 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000440 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700441 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800442 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700443
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700444 infoFile.truncate();
445 infoFile.close();
446
447 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000448 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700449 infoPath.c_str(), strerror(errno));
450 }
Logan89eb47f2011-01-07 10:45:16 +0800451 }
452 }
Logan04329712011-01-06 06:10:57 +0800453 }
Logan35849002011-01-15 07:30:43 +0800454#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800455
456 return 0;
Logancf3e5212010-12-29 01:44:55 +0800457}
458
459
460char const *Script::getCompilerErrorMessage() {
461 if (mStatus != ScriptStatus::Compiled) {
462 mErrorCode = BCC_INVALID_OPERATION;
463 return NULL;
464 }
465
466 return mCompiled->getCompilerErrorMessage();
467}
468
469
470void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800471 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700472 case ScriptStatus::Compiled: {
473 return mCompiled->lookup(name);
474 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700475
Logan35849002011-01-15 07:30:43 +0800476#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700477 case ScriptStatus::Cached: {
478 return mCached->lookup(name);
479 }
Logan35849002011-01-15 07:30:43 +0800480#endif
Logan89eb47f2011-01-07 10:45:16 +0800481
Shih-wei Liaod50be322011-07-01 22:53:31 -0700482 default: {
483 mErrorCode = BCC_INVALID_OPERATION;
484 return NULL;
485 }
Logancf3e5212010-12-29 01:44:55 +0800486 }
Logancf3e5212010-12-29 01:44:55 +0800487}
488
489
Loganbe79ada2011-01-13 01:33:45 +0800490size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800491 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700492 case ScriptStatus::Compiled: {
493 return mCompiled->getExportVarCount();
494 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700495
Logan35849002011-01-15 07:30:43 +0800496#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700497 case ScriptStatus::Cached: {
498 return mCached->getExportVarCount();
499 }
Logan35849002011-01-15 07:30:43 +0800500#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700501
Shih-wei Liaod50be322011-07-01 22:53:31 -0700502 default: {
503 return 0;
504 }
Loganbe79ada2011-01-13 01:33:45 +0800505 }
506}
507
508
509size_t Script::getExportFuncCount() const {
510 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700511 case ScriptStatus::Compiled: {
512 return mCompiled->getExportFuncCount();
513 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700514
Logan35849002011-01-15 07:30:43 +0800515#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700516 case ScriptStatus::Cached: {
517 return mCached->getExportFuncCount();
518 }
Logan35849002011-01-15 07:30:43 +0800519#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700520
Shih-wei Liaod50be322011-07-01 22:53:31 -0700521 default: {
522 return 0;
523 }
Loganbe79ada2011-01-13 01:33:45 +0800524 }
525}
526
527
528size_t Script::getPragmaCount() const {
529 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700530 case ScriptStatus::Compiled: {
531 return mCompiled->getPragmaCount();
532 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700533
Logan35849002011-01-15 07:30:43 +0800534#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700535 case ScriptStatus::Cached: {
536 return mCached->getPragmaCount();
537 }
Logan35849002011-01-15 07:30:43 +0800538#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700539
Shih-wei Liaod50be322011-07-01 22:53:31 -0700540 default: {
541 return 0;
542 }
Loganbe79ada2011-01-13 01:33:45 +0800543 }
544}
545
546
547size_t Script::getFuncCount() const {
548 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700549 case ScriptStatus::Compiled: {
550 return mCompiled->getFuncCount();
551 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700552
Logan35849002011-01-15 07:30:43 +0800553#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700554 case ScriptStatus::Cached: {
555 return mCached->getFuncCount();
556 }
Logan35849002011-01-15 07:30:43 +0800557#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700558
Shih-wei Liaod50be322011-07-01 22:53:31 -0700559 default: {
560 return 0;
561 }
Loganbe79ada2011-01-13 01:33:45 +0800562 }
563}
564
565
Stephen Hines071288a2011-01-27 14:38:26 -0800566size_t Script::getObjectSlotCount() const {
567 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700568 case ScriptStatus::Compiled: {
569 return mCompiled->getObjectSlotCount();
570 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700571
Stephen Hines071288a2011-01-27 14:38:26 -0800572#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700573 case ScriptStatus::Cached: {
574 return mCached->getObjectSlotCount();
575 }
Stephen Hines071288a2011-01-27 14:38:26 -0800576#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700577
Shih-wei Liaod50be322011-07-01 22:53:31 -0700578 default: {
579 return 0;
580 }
Stephen Hines071288a2011-01-27 14:38:26 -0800581 }
582}
583
584
Loganbe79ada2011-01-13 01:33:45 +0800585void Script::getExportVarList(size_t varListSize, void **varList) {
586 switch (mStatus) {
587#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700588 case ScriptStatus::STATUS: \
589 m##STATUS->getExportVarList(varListSize, varList); \
590 break;
Logancf3e5212010-12-29 01:44:55 +0800591
Logan35849002011-01-15 07:30:43 +0800592#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700593 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800594#endif
595
Shih-wei Liaod50be322011-07-01 22:53:31 -0700596 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800597#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800598
Shih-wei Liaod50be322011-07-01 22:53:31 -0700599 default: {
600 mErrorCode = BCC_INVALID_OPERATION;
601 }
Logan89eb47f2011-01-07 10:45:16 +0800602 }
Logancf3e5212010-12-29 01:44:55 +0800603}
604
Joseph Wenf36637f2011-07-06 18:27:12 -0700605void Script::getExportVarNameList(std::vector<std::string> &varList) {
606 switch (mStatus) {
607 case ScriptStatus::Compiled: {
608 return mCompiled->getExportVarNameList(varList);
609 }
610
611 default: {
612 mErrorCode = BCC_INVALID_OPERATION;
613 }
614 }
615}
616
Logancf3e5212010-12-29 01:44:55 +0800617
Loganbe79ada2011-01-13 01:33:45 +0800618void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800619 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800620#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700621 case ScriptStatus::STATUS: \
622 m##STATUS->getExportFuncList(funcListSize, funcList); \
623 break;
Logancf3e5212010-12-29 01:44:55 +0800624
Logan35849002011-01-15 07:30:43 +0800625#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700626 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800627#endif
628
Shih-wei Liaod50be322011-07-01 22:53:31 -0700629 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800630#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800631
Shih-wei Liaod50be322011-07-01 22:53:31 -0700632 default: {
633 mErrorCode = BCC_INVALID_OPERATION;
634 }
Logan89eb47f2011-01-07 10:45:16 +0800635 }
Logancf3e5212010-12-29 01:44:55 +0800636}
637
Joseph Wenf36637f2011-07-06 18:27:12 -0700638void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
639 switch (mStatus) {
640 case ScriptStatus::Compiled: {
641 return mCompiled->getExportFuncNameList(funcList);
642 }
643
644 default: {
645 mErrorCode = BCC_INVALID_OPERATION;
646 }
647 }
648}
649
Logancf3e5212010-12-29 01:44:55 +0800650
Loganbe79ada2011-01-13 01:33:45 +0800651void Script::getPragmaList(size_t pragmaListSize,
652 char const **keyList,
653 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800654 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800655#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700656 case ScriptStatus::STATUS: \
657 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
658 break;
Logancf3e5212010-12-29 01:44:55 +0800659
Logan35849002011-01-15 07:30:43 +0800660#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700661 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800662#endif
663
Shih-wei Liaod50be322011-07-01 22:53:31 -0700664 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800665#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800666
Shih-wei Liaod50be322011-07-01 22:53:31 -0700667 default: {
668 mErrorCode = BCC_INVALID_OPERATION;
669 }
Logan89eb47f2011-01-07 10:45:16 +0800670 }
Logancf3e5212010-12-29 01:44:55 +0800671}
672
673
Loganf340bf72011-01-14 17:51:40 +0800674void Script::getFuncInfoList(size_t funcInfoListSize,
675 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800676 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800677#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700678 case ScriptStatus::STATUS: \
679 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
680 break;
Logancf3e5212010-12-29 01:44:55 +0800681
Logan35849002011-01-15 07:30:43 +0800682#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700683 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800684#endif
685
Shih-wei Liaod50be322011-07-01 22:53:31 -0700686 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800687#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800688
Shih-wei Liaod50be322011-07-01 22:53:31 -0700689 default: {
690 mErrorCode = BCC_INVALID_OPERATION;
691 }
Logan89eb47f2011-01-07 10:45:16 +0800692 }
Logancf3e5212010-12-29 01:44:55 +0800693}
694
Stephen Hines071288a2011-01-27 14:38:26 -0800695
696void Script::getObjectSlotList(size_t objectSlotListSize,
697 uint32_t *objectSlotList) {
698 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700699#define DELEGATE(STATUS) \
700 case ScriptStatus::STATUS: \
701 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
702 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800703
704#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700705 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800706#endif
707
Shih-wei Liaod50be322011-07-01 22:53:31 -0700708 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800709#undef DELEGATE
710
Shih-wei Liaod50be322011-07-01 22:53:31 -0700711 default: {
712 mErrorCode = BCC_INVALID_OPERATION;
713 }
Stephen Hines071288a2011-01-27 14:38:26 -0800714 }
715}
716
717
Logan Chiend2a5f302011-07-19 20:32:25 +0800718#if USE_OLD_JIT
Logana27a83f2011-01-07 10:25:48 +0800719char *Script::getContext() {
720 switch (mStatus) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700721
Logan35849002011-01-15 07:30:43 +0800722#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700723 case ScriptStatus::Cached: {
724 return mCached->getContext();
725 }
Logan35849002011-01-15 07:30:43 +0800726#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700727
Shih-wei Liaod50be322011-07-01 22:53:31 -0700728 case ScriptStatus::Compiled: {
729 return mCompiled->getContext();
730 }
Logana27a83f2011-01-07 10:25:48 +0800731
Shih-wei Liaod50be322011-07-01 22:53:31 -0700732 default: {
733 mErrorCode = BCC_INVALID_OPERATION;
734 return NULL;
735 }
Logan02286cb2011-01-07 00:30:47 +0800736 }
Logan02286cb2011-01-07 00:30:47 +0800737}
Logan Chiend2a5f302011-07-19 20:32:25 +0800738#endif
Logan02286cb2011-01-07 00:30:47 +0800739
Logancf3e5212010-12-29 01:44:55 +0800740
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800741int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800742 mpExtSymbolLookupFn = pFn;
743 mpExtSymbolLookupFnContext = pContext;
744
Logan7d2219f2011-01-06 06:19:25 +0800745 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800746 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000747 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800748 return 1;
Logancf3e5212010-12-29 01:44:55 +0800749 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800750 return 0;
Logancf3e5212010-12-29 01:44:55 +0800751}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700752
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700753#if USE_MCJIT
754size_t Script::getELFSize() const {
755 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700756 case ScriptStatus::Compiled: {
757 return mCompiled->getELFSize();
758 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700759
Shih-wei Liaod50be322011-07-01 22:53:31 -0700760 default: {
761 return 0;
762 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700763 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700764}
765
766const char *Script::getELF() const {
767 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700768 case ScriptStatus::Compiled: {
769 return mCompiled->getELF();
770 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700771
Shih-wei Liaod50be322011-07-01 22:53:31 -0700772 default: {
773 return NULL;
774 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700775 }
776}
777#endif
Logancf3e5212010-12-29 01:44:55 +0800778
779} // namespace bcc