1474cbd2fde362e63375f7a5099ca38b5c67835cfLogan/*
2474cbd2fde362e63375f7a5099ca38b5c67835cfLogan * Copyright 2010, The Android Open Source Project
3474cbd2fde362e63375f7a5099ca38b5c67835cfLogan *
4474cbd2fde362e63375f7a5099ca38b5c67835cfLogan * Licensed under the Apache License, Version 2.0 (the "License");
5474cbd2fde362e63375f7a5099ca38b5c67835cfLogan * you may not use this file except in compliance with the License.
6474cbd2fde362e63375f7a5099ca38b5c67835cfLogan * You may obtain a copy of the License at
7474cbd2fde362e63375f7a5099ca38b5c67835cfLogan *
8474cbd2fde362e63375f7a5099ca38b5c67835cfLogan *     http://www.apache.org/licenses/LICENSE-2.0
9474cbd2fde362e63375f7a5099ca38b5c67835cfLogan *
10474cbd2fde362e63375f7a5099ca38b5c67835cfLogan * Unless required by applicable law or agreed to in writing, software
11474cbd2fde362e63375f7a5099ca38b5c67835cfLogan * distributed under the License is distributed on an "AS IS" BASIS,
12474cbd2fde362e63375f7a5099ca38b5c67835cfLogan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13474cbd2fde362e63375f7a5099ca38b5c67835cfLogan * See the License for the specific language governing permissions and
14474cbd2fde362e63375f7a5099ca38b5c67835cfLogan * limitations under the License.
15474cbd2fde362e63375f7a5099ca38b5c67835cfLogan */
16474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
17474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include "SourceInfo.h"
18474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
19474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#if USE_CACHE
20d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#if USE_OLD_JIT
21d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#include "OldJIT/CacheReader.h"
22d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#include "OldJIT/CacheWriter.h"
23d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#endif
24d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#if USE_MCJIT
255e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include "MCCacheWriter.h"
265e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liao#include "MCCacheReader.h"
27474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#endif
28d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#endif
29474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
304dcd6798f3db374a056ea6acc6b425f544c5207cLogan#include "DebugHelper.h"
31474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include "ScriptCompiled.h"
32474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include "Sha1Helper.h"
33474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
34474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include <bcc/bcc.h>
35474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include <bcc/bcc_cache.h>
36474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
37474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include <llvm/ADT/OwningPtr.h>
38474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include <llvm/ADT/StringRef.h>
39474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include <llvm/Support/MemoryBuffer.h>
40c4ea07fae41dad1b38cb5d9ab802f78d99c8b00fLogan Chien#include <llvm/Support/system_error.h>
41474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
42474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include <stddef.h>
43474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#include <string.h>
44474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
45474cbd2fde362e63375f7a5099ca38b5c67835cfLogannamespace bcc {
46474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
47474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
48474cbd2fde362e63375f7a5099ca38b5c67835cfLoganSourceInfo *SourceInfo::createFromBuffer(char const *resName,
49474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                                         char const *bitcode,
50474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                                         size_t bitcodeSize,
51474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                                         unsigned long flags) {
52474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  SourceInfo *result = new SourceInfo();
53474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
54474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  if (!result) {
55474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    return NULL;
56474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
57474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
58474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->type = SourceKind::Buffer;
59474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->buffer.resName = resName;
60474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->buffer.bitcode = bitcode;
61474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->buffer.bitcodeSize = bitcodeSize;
62474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->flags = flags;
63474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
64474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#if USE_CACHE
65474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  if (!resName && !(flags & BCC_SKIP_DEP_SHA1)) {
66474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    result->flags |= BCC_SKIP_DEP_SHA1;
67474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
68474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    LOGW("It is required to give resName for sha1 dependency check.\n");
69474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    LOGW("Sha1sum dependency check will be skipped.\n");
70474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    LOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
71474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
72474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
73474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  if (result->flags & BCC_SKIP_DEP_SHA1) {
74474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    memset(result->sha1, '\0', 20);
75474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  } else {
76474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    calcSHA1(result->sha1, bitcode, bitcodeSize);
77474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
78474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#endif
79474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
80474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return result;
81474cbd2fde362e63375f7a5099ca38b5c67835cfLogan}
82474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
83474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
84474cbd2fde362e63375f7a5099ca38b5c67835cfLoganSourceInfo *SourceInfo::createFromFile(char const *path,
85474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                                       unsigned long flags) {
86474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  SourceInfo *result = new SourceInfo();
87474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
88474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  if (!result) {
89474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    return NULL;
90474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
91474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
92474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->type = SourceKind::File;
93474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->file.path = path;
94474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->flags = flags;
95474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
96474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#if USE_CACHE
97474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  memset(result->sha1, '\0', 20);
98474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
99474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  if (!(result->flags & BCC_SKIP_DEP_SHA1)) {
100474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    calcFileSHA1(result->sha1, path);
101474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
102474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#endif
103474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
104474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return result;
105474cbd2fde362e63375f7a5099ca38b5c67835cfLogan}
106474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
107474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
108474cbd2fde362e63375f7a5099ca38b5c67835cfLoganSourceInfo *SourceInfo::createFromModule(llvm::Module *module,
109474cbd2fde362e63375f7a5099ca38b5c67835cfLogan                                         unsigned long flags) {
110474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  SourceInfo *result = new SourceInfo();
111474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
112474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  if (!result) {
113474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    return NULL;
114474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
115474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
116474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->type = SourceKind::Module;
117474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->module.reset(module);
118474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  result->flags = flags;
119474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
120474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#if USE_CACHE
121474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  if (! (flags & BCC_SKIP_DEP_SHA1)) {
122474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    result->flags |= BCC_SKIP_DEP_SHA1;
123474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
124474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    LOGW("Unable to calculate sha1sum for llvm::Module.\n");
125474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    LOGW("Sha1sum dependency check will be skipped.\n");
126474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    LOGW("Set BCC_SKIP_DEP_SHA1 for flags to surpress this warning.\n");
127474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
128474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
129474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  memset(result->sha1, '\0', 20);
130474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#endif
131474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
132474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return result;
133474cbd2fde362e63375f7a5099ca38b5c67835cfLogan}
134474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
135474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
136474cbd2fde362e63375f7a5099ca38b5c67835cfLoganint SourceInfo::prepareModule(ScriptCompiled *SC) {
137474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  switch (type) {
138474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  case SourceKind::Buffer:
139474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    {
140474cbd2fde362e63375f7a5099ca38b5c67835cfLogan      llvm::OwningPtr<llvm::MemoryBuffer> MEM(
141474cbd2fde362e63375f7a5099ca38b5c67835cfLogan        llvm::MemoryBuffer::getMemBuffer(
142474cbd2fde362e63375f7a5099ca38b5c67835cfLogan          llvm::StringRef(buffer.bitcode, buffer.bitcodeSize)));
143474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
144474cbd2fde362e63375f7a5099ca38b5c67835cfLogan      if (!MEM.get()) {
145474cbd2fde362e63375f7a5099ca38b5c67835cfLogan        LOGE("Unable to MemoryBuffer::getMemBuffer(addr=%p, size=%lu)\n",
146474cbd2fde362e63375f7a5099ca38b5c67835cfLogan             buffer.bitcode, (unsigned long)buffer.bitcodeSize);
147474cbd2fde362e63375f7a5099ca38b5c67835cfLogan        return 1;
148474cbd2fde362e63375f7a5099ca38b5c67835cfLogan      }
149474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
150474cbd2fde362e63375f7a5099ca38b5c67835cfLogan      module.reset(SC->parseBitcodeFile(MEM.get()));
151474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    }
152474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    break;
153474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
154474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  case SourceKind::File:
155474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    {
156c4ea07fae41dad1b38cb5d9ab802f78d99c8b00fLogan Chien      llvm::OwningPtr<llvm::MemoryBuffer> MEM;
157474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
158c4ea07fae41dad1b38cb5d9ab802f78d99c8b00fLogan Chien      if (llvm::error_code ec = llvm::MemoryBuffer::getFile(file.path, MEM)) {
159474cbd2fde362e63375f7a5099ca38b5c67835cfLogan        LOGE("Unable to MemoryBuffer::getFile(path=%s)\n", file.path);
160474cbd2fde362e63375f7a5099ca38b5c67835cfLogan        return 1;
161474cbd2fde362e63375f7a5099ca38b5c67835cfLogan      }
162474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
163474cbd2fde362e63375f7a5099ca38b5c67835cfLogan      module.reset(SC->parseBitcodeFile(MEM.get()));
164474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    }
165474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    break;
166474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
167474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  default:
168474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    break;
169474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
170474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
171474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  return (module.get()) ? 0 : 1;
172474cbd2fde362e63375f7a5099ca38b5c67835cfLogan}
173474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
174474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
175474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#if USE_CACHE
176474cbd2fde362e63375f7a5099ca38b5c67835cfLogantemplate <typename T> void SourceInfo::introDependency(T &checker) {
177474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  if (flags & BCC_SKIP_DEP_SHA1) {
178474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    return;
179474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
180474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
181474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  switch (type) {
182474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  case SourceKind::Buffer:
183474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    checker.addDependency(BCC_APK_RESOURCE, buffer.resName, sha1);
184474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    break;
185474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
186474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  case SourceKind::File:
187474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    checker.addDependency(BCC_FILE_RESOURCE, file.path, sha1);
188474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    break;
189474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
190474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  default:
191474cbd2fde362e63375f7a5099ca38b5c67835cfLogan    break;
192474cbd2fde362e63375f7a5099ca38b5c67835cfLogan  }
193474cbd2fde362e63375f7a5099ca38b5c67835cfLogan}
194474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
195d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#if USE_OLD_JIT
196474cbd2fde362e63375f7a5099ca38b5c67835cfLogantemplate void SourceInfo::introDependency<CacheReader>(CacheReader &);
197474cbd2fde362e63375f7a5099ca38b5c67835cfLogantemplate void SourceInfo::introDependency<CacheWriter>(CacheWriter &);
198d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#endif
199d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien
200d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#if USE_MCJIT
2015e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaotemplate void SourceInfo::introDependency<MCCacheWriter>(MCCacheWriter &);
2025e3e0ce19d80c9a42b89ca95f22d98fbbe6ffb14Shih-wei Liaotemplate void SourceInfo::introDependency<MCCacheReader>(MCCacheReader &);
203d2a5f305f48c47b9e98a0d7ccdd0cf027bdcfe18Logan Chien#endif
204474cbd2fde362e63375f7a5099ca38b5c67835cfLogan#endif // USE_CACHE
205474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
206474cbd2fde362e63375f7a5099ca38b5c67835cfLogan
207474cbd2fde362e63375f7a5099ca38b5c67835cfLogan} // namespace bcc
208