blob: 9e59495bbfe71278010b534762a079cf34cf02bf [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) {
Joseph Wen34c600a2011-07-25 17:59:17 -0700186#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;
Shih-wei Liao8afed382012-01-10 15:57:24 +0800204 option.RelocModelOpt = RelocModel;
Zonr Chang2fcbd022012-01-06 21:04:31 +0800205 option.LoadAfterCompile = false;
206 int status = internalCompile(option);
Joseph Wen34c600a2011-07-25 17:59:17 -0700207 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000208 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Joseph Wen34c600a2011-07-25 17:59:17 -0700209 }
210 return status;
211}
212
Logancf3e5212010-12-29 01:44:55 +0800213
Logan Chien311c26f2011-07-11 14:30:34 +0800214int Script::prepareExecutable(char const *cacheDir,
215 char const *cacheName,
216 unsigned long flags) {
Loganecf4cbd2011-01-06 05:34:11 +0800217 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800218 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000219 ALOGE("Invalid operation: %s\n", __func__);
Logancf3e5212010-12-29 01:44:55 +0800220 return 1;
221 }
222
Logan35849002011-01-15 07:30:43 +0800223#if USE_CACHE
Logan Chien311c26f2011-07-11 14:30:34 +0800224 if (cacheDir && cacheName) {
225 // Set Cache Directory and File Name
226 mCacheDir = cacheDir;
227 mCacheName = cacheName;
228
229 if (!mCacheDir.empty() && *mCacheDir.rbegin() != '/') {
230 mCacheDir.push_back('/'); // Ensure mCacheDir is end with '/'
231 }
232
233 // Load Cache File
Joseph Wen34c600a2011-07-25 17:59:17 -0700234 if (internalLoadCache(false) == 0) {
Logan Chien311c26f2011-07-11 14:30:34 +0800235 return 0;
236 }
Logan033f46e2011-01-06 05:51:24 +0800237 }
Logan35849002011-01-15 07:30:43 +0800238#endif
Loganecf4cbd2011-01-06 05:34:11 +0800239
Zonr Chang2fcbd022012-01-06 21:04:31 +0800240 CompilerOption option;
241 int status = internalCompile(option);
Stephen Hines27b35102011-05-11 17:58:48 -0700242 if (status != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000243 ALOGE("LLVM error message: %s\n", getCompilerErrorMessage());
Stephen Hines27b35102011-05-11 17:58:48 -0700244 }
245 return status;
Logan033f46e2011-01-06 05:51:24 +0800246}
247
248
Logan35849002011-01-15 07:30:43 +0800249#if USE_CACHE
Joseph Wen34c600a2011-07-25 17:59:17 -0700250int Script::internalLoadCache(bool checkOnly) {
Joseph Wen76919072011-07-07 23:06:15 -0700251 if (getBooleanProp("debug.bcc.nocache")) {
Logan033f46e2011-01-06 05:51:24 +0800252 // Android system environment property disable the cache mechanism by
253 // setting "debug.bcc.nocache". So we will not load the cache file any
254 // way.
255 return 1;
256 }
257
Logan Chien311c26f2011-07-11 14:30:34 +0800258 if (mCacheDir.empty() || mCacheName.empty()) {
Loganf340bf72011-01-14 17:51:40 +0800259 // The application developer has not specify the cachePath, so
Logan04329712011-01-06 06:10:57 +0800260 // we don't know where to open the cache file.
261 return 1;
Logan033f46e2011-01-06 05:51:24 +0800262 }
Logan04329712011-01-06 06:10:57 +0800263
Logan Chien311c26f2011-07-11 14:30:34 +0800264#if USE_OLD_JIT
Logan Chien03a2e302011-07-13 21:46:32 +0800265 std::string objPath(mCacheDir + mCacheName + ".jit-image");
266 std::string infoPath(mCacheDir + mCacheName + ".oBCC"); // TODO: .info instead
Logan Chien311c26f2011-07-11 14:30:34 +0800267#elif USE_MCJIT
268 std::string objPath(mCacheDir + mCacheName + ".o");
269 std::string infoPath(mCacheDir + mCacheName + ".info");
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700270#endif
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700271
Logan Chien311c26f2011-07-11 14:30:34 +0800272 FileHandle objFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700273 if (objFile.open(objPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800274 // Unable to open the executable file in read mode.
Logan04329712011-01-06 06:10:57 +0800275 return 1;
276 }
277
Logan Chien311c26f2011-07-11 14:30:34 +0800278 FileHandle infoFile;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700279 if (infoFile.open(infoPath.c_str(), OpenMode::Read) < 0) {
Logan Chien03a2e302011-07-13 21:46:32 +0800280 // Unable to open the metadata information file in read mode.
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700281 return 1;
282 }
283
Logan Chien311c26f2011-07-11 14:30:34 +0800284#if USE_OLD_JIT
285 CacheReader reader;
286#elif USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700287 MCCacheReader reader;
288
289 // Register symbol lookup function
290 if (mpExtSymbolLookupFn) {
291 reader.registerSymbolCallback(mpExtSymbolLookupFn,
292 mpExtSymbolLookupFnContext);
293 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700294#endif
Logan04329712011-01-06 06:10:57 +0800295
Logan9a5f8682011-01-07 06:09:57 +0800296 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700297 reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700298 reader.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logan9a5f8682011-01-07 06:09:57 +0800299
Logan474cbd22011-01-31 01:47:44 +0800300 for (size_t i = 0; i < 2; ++i) {
301 if (mSourceList[i]) {
302 mSourceList[i]->introDependency(reader);
303 }
Logan9a5f8682011-01-07 06:09:57 +0800304 }
305
Joseph Wen34c600a2011-07-25 17:59:17 -0700306 if (checkOnly)
Joseph Wen49281042011-07-26 10:04:09 -0700307 return !reader.checkCacheFile(&objFile, &infoFile, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700308
Logan9a5f8682011-01-07 06:09:57 +0800309 // Read cache file
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700310 ScriptCached *cached = reader.readCacheFile(&objFile, &infoFile, this);
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700311
Logan04329712011-01-06 06:10:57 +0800312 if (!cached) {
Logan42598052011-01-26 22:41:13 +0800313 mIsContextSlotNotAvail = reader.isContextSlotNotAvail();
Logan04329712011-01-06 06:10:57 +0800314 return 1;
315 }
316
317 mCached = cached;
318 mStatus = ScriptStatus::Cached;
Logan033f46e2011-01-06 05:51:24 +0800319
Loganf3c83ce2011-01-07 06:36:33 +0800320 // Dirty hack for libRS.
321 // TODO(all): This dirty hack should be removed in the future.
Shih-wei Liao8eb5fe92011-02-01 04:17:38 -0800322 if (!cached->isLibRSThreadable() && mpExtSymbolLookupFn) {
Loganf3c83ce2011-01-07 06:36:33 +0800323 mpExtSymbolLookupFn(mpExtSymbolLookupFnContext, "__clearThreadable");
324 }
325
Loganf7f0ac52011-01-07 03:53:43 +0800326 return 0;
Logan033f46e2011-01-06 05:51:24 +0800327}
Logan35849002011-01-15 07:30:43 +0800328#endif
Logan033f46e2011-01-06 05:51:24 +0800329
Zonr Chang2fcbd022012-01-06 21:04:31 +0800330int Script::internalCompile(CompilerOption &option) {
Logan033f46e2011-01-06 05:51:24 +0800331 // Create the ScriptCompiled object
Nowar Gu09b6c1c2011-05-24 23:49:07 +0800332 mCompiled = new (std::nothrow) ScriptCompiled(this);
Loganecf4cbd2011-01-06 05:34:11 +0800333
334 if (!mCompiled) {
335 mErrorCode = BCC_OUT_OF_MEMORY;
Steve Block10c14122012-01-08 10:15:06 +0000336 ALOGE("Out of memory: %s %d\n", __FILE__, __LINE__);
Loganecf4cbd2011-01-06 05:34:11 +0800337 return 1;
338 }
339
340 mStatus = ScriptStatus::Compiled;
341
Logan033f46e2011-01-06 05:51:24 +0800342 // Register symbol lookup function
Loganecf4cbd2011-01-06 05:34:11 +0800343 if (mpExtSymbolLookupFn) {
344 mCompiled->registerSymbolCallback(mpExtSymbolLookupFn,
345 mpExtSymbolLookupFnContext);
346 }
347
Zonr Changdf3fee42012-01-10 15:58:36 +0800348 if (!mSourceList[0]) {
349 ALOGE("Source bitcode is not set.\n");
Logan474cbd22011-01-31 01:47:44 +0800350 return 1;
351 }
352
Zonr Changdf3fee42012-01-10 15:58:36 +0800353 // Parse Bitcode File (if necessary)
354 if (mSourceList[0]->prepareModule() != 0)
355 return 1;
356
357 // Set the main source module
358 if (mCompiled->readModule(mSourceList[0]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000359 ALOGE("Unable to read source module\n");
Logan474cbd22011-01-31 01:47:44 +0800360 return 1;
Loganecf4cbd2011-01-06 05:34:11 +0800361 }
362
Logan3133c412011-01-06 06:15:40 +0800363 // Link the source module with the library module
Zonr Changdf3fee42012-01-10 15:58:36 +0800364 if (mSourceList[1] &&
365 mSourceList[1]->prepareModule(mSourceList[0]->getContext())) {
366 if (mCompiled->linkModule(mSourceList[1]->getModule()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000367 ALOGE("Unable to link library module\n");
Logan04329712011-01-06 06:10:57 +0800368 return 1;
369 }
370 }
Loganecf4cbd2011-01-06 05:34:11 +0800371
Logan3133c412011-01-06 06:15:40 +0800372 // Compile and JIT the code
Zonr Chang2fcbd022012-01-06 21:04:31 +0800373 if (mCompiled->compile(option) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000374 ALOGE("Unable to compile.\n");
Logan04329712011-01-06 06:10:57 +0800375 return 1;
376 }
377
Logan35849002011-01-15 07:30:43 +0800378#if USE_CACHE
Logan42598052011-01-26 22:41:13 +0800379 // Note: If we re-compile the script because the cached context slot not
380 // available, then we don't have to write the cache.
381
382 // Note: If the address of the context is not in the context slot, then
383 // we don't have to cache it.
384
Logan Chien311c26f2011-07-11 14:30:34 +0800385 if (!mCacheDir.empty() &&
386 !mCacheName.empty() &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700387#if USE_OLD_JIT
Logan1dc63142011-02-25 17:14:51 +0800388 !mIsContextSlotNotAvail &&
389 ContextManager::get().isManagingContext(getContext()) &&
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700390#endif
Logan42598052011-01-26 22:41:13 +0800391 !getBooleanProp("debug.bcc.nocache")) {
392
Logan Chien311c26f2011-07-11 14:30:34 +0800393#if USE_OLD_JIT
Logan Chien03a2e302011-07-13 21:46:32 +0800394 std::string objPath(mCacheDir + mCacheName + ".jit-image");
395 std::string infoPath(mCacheDir + mCacheName + ".oBCC");
Logan Chien311c26f2011-07-11 14:30:34 +0800396#elif USE_MCJIT
Logan Chien311c26f2011-07-11 14:30:34 +0800397 std::string objPath(mCacheDir + mCacheName + ".o");
398 std::string infoPath(mCacheDir + mCacheName + ".info");
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700399#endif
Logan04329712011-01-06 06:10:57 +0800400
Logan Chien311c26f2011-07-11 14:30:34 +0800401
Jeff Brown937a0bc2011-01-26 23:20:14 -0800402 // Remove the file if it already exists before writing the new file.
403 // The old file may still be mapped elsewhere in memory and we do not want
404 // to modify its contents. (The same script may be running concurrently in
405 // the same process or a different process!)
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700406 ::unlink(objPath.c_str());
Logan Chien311c26f2011-07-11 14:30:34 +0800407#if !USE_OLD_JIT && USE_MCJIT
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700408 ::unlink(infoPath.c_str());
409#endif
Jeff Brown937a0bc2011-01-26 23:20:14 -0800410
Logan Chien03a2e302011-07-13 21:46:32 +0800411 FileHandle objFile;
412 FileHandle infoFile;
413
414 if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
415 infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700416
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700417#if USE_OLD_JIT
Logan04329712011-01-06 06:10:57 +0800418 CacheWriter writer;
Logan Chien311c26f2011-07-11 14:30:34 +0800419#elif USE_MCJIT
420 MCCacheWriter writer;
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700421#endif
Logana27a83f2011-01-07 10:25:48 +0800422
Joseph Wen2ca6e572011-06-24 14:12:23 -0700423#ifdef TARGET_BUILD
Logana2e15af2011-01-07 11:46:08 +0800424 // Dependencies
Joseph Wen2ca6e572011-06-24 14:12:23 -0700425 writer.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700426 writer.addDependency(BCC_FILE_RESOURCE, pathLibRS, sha1LibRS);
Logane1323992011-01-12 04:47:13 +0800427#endif
Logana2e15af2011-01-07 11:46:08 +0800428
Logan474cbd22011-01-31 01:47:44 +0800429 for (size_t i = 0; i < 2; ++i) {
Logan825c3b22011-02-28 05:05:48 +0800430 if (mSourceList[i]) {
431 mSourceList[i]->introDependency(writer);
432 }
Logana2e15af2011-01-07 11:46:08 +0800433 }
434
Logana27a83f2011-01-07 10:25:48 +0800435 // libRS is threadable dirty hack
436 // TODO: This should be removed in the future
437 uint32_t libRS_threadable = 0;
438 if (mpExtSymbolLookupFn) {
Logan89eb47f2011-01-07 10:45:16 +0800439 libRS_threadable =
440 (uint32_t)mpExtSymbolLookupFn(mpExtSymbolLookupFnContext,
441 "__isThreadable");
Logana27a83f2011-01-07 10:25:48 +0800442 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700443
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700444 if (!writer.writeCacheFile(&objFile, &infoFile, this, libRS_threadable)) {
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700445 objFile.truncate();
446 objFile.close();
Logana27a83f2011-01-07 10:25:48 +0800447
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700448 if (unlink(objPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000449 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700450 objPath.c_str(), strerror(errno));
Logan89eb47f2011-01-07 10:45:16 +0800451 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700452
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700453 infoFile.truncate();
454 infoFile.close();
455
456 if (unlink(infoPath.c_str()) != 0) {
Steve Block10c14122012-01-08 10:15:06 +0000457 ALOGE("Unable to remove the invalid cache file: %s. (reason: %s)\n",
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700458 infoPath.c_str(), strerror(errno));
459 }
Logan89eb47f2011-01-07 10:45:16 +0800460 }
461 }
Logan04329712011-01-06 06:10:57 +0800462 }
Logan35849002011-01-15 07:30:43 +0800463#endif // USE_CACHE
Logan04329712011-01-06 06:10:57 +0800464
465 return 0;
Logancf3e5212010-12-29 01:44:55 +0800466}
467
468
469char const *Script::getCompilerErrorMessage() {
470 if (mStatus != ScriptStatus::Compiled) {
471 mErrorCode = BCC_INVALID_OPERATION;
472 return NULL;
473 }
474
475 return mCompiled->getCompilerErrorMessage();
476}
477
478
479void *Script::lookup(const char *name) {
Logan89eb47f2011-01-07 10:45:16 +0800480 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700481 case ScriptStatus::Compiled: {
482 return mCompiled->lookup(name);
483 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700484
Logan35849002011-01-15 07:30:43 +0800485#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700486 case ScriptStatus::Cached: {
487 return mCached->lookup(name);
488 }
Logan35849002011-01-15 07:30:43 +0800489#endif
Logan89eb47f2011-01-07 10:45:16 +0800490
Shih-wei Liaod50be322011-07-01 22:53:31 -0700491 default: {
492 mErrorCode = BCC_INVALID_OPERATION;
493 return NULL;
494 }
Logancf3e5212010-12-29 01:44:55 +0800495 }
Logancf3e5212010-12-29 01:44:55 +0800496}
497
498
Loganbe79ada2011-01-13 01:33:45 +0800499size_t Script::getExportVarCount() const {
Logan89eb47f2011-01-07 10:45:16 +0800500 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700501 case ScriptStatus::Compiled: {
502 return mCompiled->getExportVarCount();
503 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700504
Logan35849002011-01-15 07:30:43 +0800505#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700506 case ScriptStatus::Cached: {
507 return mCached->getExportVarCount();
508 }
Logan35849002011-01-15 07:30:43 +0800509#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700510
Shih-wei Liaod50be322011-07-01 22:53:31 -0700511 default: {
512 return 0;
513 }
Loganbe79ada2011-01-13 01:33:45 +0800514 }
515}
516
517
518size_t Script::getExportFuncCount() const {
519 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700520 case ScriptStatus::Compiled: {
521 return mCompiled->getExportFuncCount();
522 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700523
Logan35849002011-01-15 07:30:43 +0800524#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700525 case ScriptStatus::Cached: {
526 return mCached->getExportFuncCount();
527 }
Logan35849002011-01-15 07:30:43 +0800528#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700529
Shih-wei Liaod50be322011-07-01 22:53:31 -0700530 default: {
531 return 0;
532 }
Loganbe79ada2011-01-13 01:33:45 +0800533 }
534}
535
536
537size_t Script::getPragmaCount() const {
538 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700539 case ScriptStatus::Compiled: {
540 return mCompiled->getPragmaCount();
541 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700542
Logan35849002011-01-15 07:30:43 +0800543#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700544 case ScriptStatus::Cached: {
545 return mCached->getPragmaCount();
546 }
Logan35849002011-01-15 07:30:43 +0800547#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700548
Shih-wei Liaod50be322011-07-01 22:53:31 -0700549 default: {
550 return 0;
551 }
Loganbe79ada2011-01-13 01:33:45 +0800552 }
553}
554
555
556size_t Script::getFuncCount() const {
557 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700558 case ScriptStatus::Compiled: {
559 return mCompiled->getFuncCount();
560 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700561
Logan35849002011-01-15 07:30:43 +0800562#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700563 case ScriptStatus::Cached: {
564 return mCached->getFuncCount();
565 }
Logan35849002011-01-15 07:30:43 +0800566#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700567
Shih-wei Liaod50be322011-07-01 22:53:31 -0700568 default: {
569 return 0;
570 }
Loganbe79ada2011-01-13 01:33:45 +0800571 }
572}
573
574
Stephen Hines071288a2011-01-27 14:38:26 -0800575size_t Script::getObjectSlotCount() const {
576 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700577 case ScriptStatus::Compiled: {
578 return mCompiled->getObjectSlotCount();
579 }
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700580
Stephen Hines071288a2011-01-27 14:38:26 -0800581#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700582 case ScriptStatus::Cached: {
583 return mCached->getObjectSlotCount();
584 }
Stephen Hines071288a2011-01-27 14:38:26 -0800585#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700586
Shih-wei Liaod50be322011-07-01 22:53:31 -0700587 default: {
588 return 0;
589 }
Stephen Hines071288a2011-01-27 14:38:26 -0800590 }
591}
592
593
Loganbe79ada2011-01-13 01:33:45 +0800594void Script::getExportVarList(size_t varListSize, void **varList) {
595 switch (mStatus) {
596#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700597 case ScriptStatus::STATUS: \
598 m##STATUS->getExportVarList(varListSize, varList); \
599 break;
Logancf3e5212010-12-29 01:44:55 +0800600
Logan35849002011-01-15 07:30:43 +0800601#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700602 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800603#endif
604
Shih-wei Liaod50be322011-07-01 22:53:31 -0700605 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800606#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800607
Shih-wei Liaod50be322011-07-01 22:53:31 -0700608 default: {
609 mErrorCode = BCC_INVALID_OPERATION;
610 }
Logan89eb47f2011-01-07 10:45:16 +0800611 }
Logancf3e5212010-12-29 01:44:55 +0800612}
613
Joseph Wenf36637f2011-07-06 18:27:12 -0700614void Script::getExportVarNameList(std::vector<std::string> &varList) {
615 switch (mStatus) {
616 case ScriptStatus::Compiled: {
617 return mCompiled->getExportVarNameList(varList);
618 }
619
620 default: {
621 mErrorCode = BCC_INVALID_OPERATION;
622 }
623 }
624}
625
Logancf3e5212010-12-29 01:44:55 +0800626
Loganbe79ada2011-01-13 01:33:45 +0800627void Script::getExportFuncList(size_t funcListSize, void **funcList) {
Logan89eb47f2011-01-07 10:45:16 +0800628 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800629#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700630 case ScriptStatus::STATUS: \
631 m##STATUS->getExportFuncList(funcListSize, funcList); \
632 break;
Logancf3e5212010-12-29 01:44:55 +0800633
Logan35849002011-01-15 07:30:43 +0800634#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700635 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800636#endif
637
Shih-wei Liaod50be322011-07-01 22:53:31 -0700638 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800639#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800640
Shih-wei Liaod50be322011-07-01 22:53:31 -0700641 default: {
642 mErrorCode = BCC_INVALID_OPERATION;
643 }
Logan89eb47f2011-01-07 10:45:16 +0800644 }
Logancf3e5212010-12-29 01:44:55 +0800645}
646
Joseph Wenf36637f2011-07-06 18:27:12 -0700647void Script::getExportFuncNameList(std::vector<std::string> &funcList) {
648 switch (mStatus) {
649 case ScriptStatus::Compiled: {
650 return mCompiled->getExportFuncNameList(funcList);
651 }
652
653 default: {
654 mErrorCode = BCC_INVALID_OPERATION;
655 }
656 }
657}
658
Logancf3e5212010-12-29 01:44:55 +0800659
Loganbe79ada2011-01-13 01:33:45 +0800660void Script::getPragmaList(size_t pragmaListSize,
661 char const **keyList,
662 char const **valueList) {
Logan89eb47f2011-01-07 10:45:16 +0800663 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800664#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700665 case ScriptStatus::STATUS: \
666 m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
667 break;
Logancf3e5212010-12-29 01:44:55 +0800668
Logan35849002011-01-15 07:30:43 +0800669#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700670 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800671#endif
672
Shih-wei Liaod50be322011-07-01 22:53:31 -0700673 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800674#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800675
Shih-wei Liaod50be322011-07-01 22:53:31 -0700676 default: {
677 mErrorCode = BCC_INVALID_OPERATION;
678 }
Logan89eb47f2011-01-07 10:45:16 +0800679 }
Logancf3e5212010-12-29 01:44:55 +0800680}
681
682
Loganf340bf72011-01-14 17:51:40 +0800683void Script::getFuncInfoList(size_t funcInfoListSize,
684 FuncInfo *funcInfoList) {
Logan89eb47f2011-01-07 10:45:16 +0800685 switch (mStatus) {
Loganbe79ada2011-01-13 01:33:45 +0800686#define DELEGATE(STATUS) \
Shih-wei Liaod50be322011-07-01 22:53:31 -0700687 case ScriptStatus::STATUS: \
688 m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
689 break;
Logancf3e5212010-12-29 01:44:55 +0800690
Logan35849002011-01-15 07:30:43 +0800691#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700692 DELEGATE(Cached);
Logan35849002011-01-15 07:30:43 +0800693#endif
694
Shih-wei Liaod50be322011-07-01 22:53:31 -0700695 DELEGATE(Compiled);
Loganbe79ada2011-01-13 01:33:45 +0800696#undef DELEGATE
Logan89eb47f2011-01-07 10:45:16 +0800697
Shih-wei Liaod50be322011-07-01 22:53:31 -0700698 default: {
699 mErrorCode = BCC_INVALID_OPERATION;
700 }
Logan89eb47f2011-01-07 10:45:16 +0800701 }
Logancf3e5212010-12-29 01:44:55 +0800702}
703
Stephen Hines071288a2011-01-27 14:38:26 -0800704
705void Script::getObjectSlotList(size_t objectSlotListSize,
706 uint32_t *objectSlotList) {
707 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700708#define DELEGATE(STATUS) \
709 case ScriptStatus::STATUS: \
710 m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
711 break;
Stephen Hines071288a2011-01-27 14:38:26 -0800712
713#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700714 DELEGATE(Cached);
Stephen Hines071288a2011-01-27 14:38:26 -0800715#endif
716
Shih-wei Liaod50be322011-07-01 22:53:31 -0700717 DELEGATE(Compiled);
Stephen Hines071288a2011-01-27 14:38:26 -0800718#undef DELEGATE
719
Shih-wei Liaod50be322011-07-01 22:53:31 -0700720 default: {
721 mErrorCode = BCC_INVALID_OPERATION;
722 }
Stephen Hines071288a2011-01-27 14:38:26 -0800723 }
724}
725
726
Logan Chiend2a5f302011-07-19 20:32:25 +0800727#if USE_OLD_JIT
Logana27a83f2011-01-07 10:25:48 +0800728char *Script::getContext() {
729 switch (mStatus) {
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700730
Logan35849002011-01-15 07:30:43 +0800731#if USE_CACHE
Shih-wei Liaod50be322011-07-01 22:53:31 -0700732 case ScriptStatus::Cached: {
733 return mCached->getContext();
734 }
Logan35849002011-01-15 07:30:43 +0800735#endif
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700736
Shih-wei Liaod50be322011-07-01 22:53:31 -0700737 case ScriptStatus::Compiled: {
738 return mCompiled->getContext();
739 }
Logana27a83f2011-01-07 10:25:48 +0800740
Shih-wei Liaod50be322011-07-01 22:53:31 -0700741 default: {
742 mErrorCode = BCC_INVALID_OPERATION;
743 return NULL;
744 }
Logan02286cb2011-01-07 00:30:47 +0800745 }
Logan02286cb2011-01-07 00:30:47 +0800746}
Logan Chiend2a5f302011-07-19 20:32:25 +0800747#endif
Logan02286cb2011-01-07 00:30:47 +0800748
Logancf3e5212010-12-29 01:44:55 +0800749
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800750int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
Logancf3e5212010-12-29 01:44:55 +0800751 mpExtSymbolLookupFn = pFn;
752 mpExtSymbolLookupFnContext = pContext;
753
Logan7d2219f2011-01-06 06:19:25 +0800754 if (mStatus != ScriptStatus::Unknown) {
Logancf3e5212010-12-29 01:44:55 +0800755 mErrorCode = BCC_INVALID_OPERATION;
Steve Block10c14122012-01-08 10:15:06 +0000756 ALOGE("Invalid operation: %s\n", __func__);
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800757 return 1;
Logancf3e5212010-12-29 01:44:55 +0800758 }
Shih-wei Liaoce82d492011-01-20 12:34:03 -0800759 return 0;
Logancf3e5212010-12-29 01:44:55 +0800760}
Shih-wei Liaob65410d2011-06-19 11:11:48 -0700761
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700762#if USE_MCJIT
763size_t Script::getELFSize() const {
764 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700765 case ScriptStatus::Compiled: {
766 return mCompiled->getELFSize();
767 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700768
Shih-wei Liaod50be322011-07-01 22:53:31 -0700769 default: {
770 return 0;
771 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700772 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700773}
774
775const char *Script::getELF() const {
776 switch (mStatus) {
Shih-wei Liaod50be322011-07-01 22:53:31 -0700777 case ScriptStatus::Compiled: {
778 return mCompiled->getELF();
779 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700780
Shih-wei Liaod50be322011-07-01 22:53:31 -0700781 default: {
782 return NULL;
783 }
Shih-wei Liao5e3e0ce2011-06-17 13:59:46 -0700784 }
785}
786#endif
Logancf3e5212010-12-29 01:44:55 +0800787
788} // namespace bcc