Merge "Fixing some bugs and inefficiencies"
diff --git a/Android.mk b/Android.mk
index e3948c8..213cc45 100644
--- a/Android.mk
+++ b/Android.mk
@@ -22,10 +22,6 @@
# Whole Static Library to Be Linked In
#=====================================================================
-ifeq ($(libbcc_USE_OLD_JIT),1)
-libbcc_WHOLE_STATIC_LIBRARIES += libbccCodeGen
-endif
-
ifeq ($(libbcc_USE_DISASSEMBLER),1)
libbcc_WHOLE_STATIC_LIBRARIES += libbccDisassembler
endif
@@ -80,9 +76,7 @@
LOCAL_WHOLE_STATIC_LIBRARIES += libbccCompilerRT
endif
-ifeq ($(libbcc_USE_MCJIT),1)
- LOCAL_STATIC_LIBRARIES += librsloader
-endif
+LOCAL_STATIC_LIBRARIES += librsloader
ifeq ($(libbcc_USE_DISASSEMBLER),1)
ifeq ($(TARGET_ARCH),arm)
@@ -192,9 +186,7 @@
LOCAL_WHOLE_STATIC_LIBRARIES += $(libbcc_WHOLE_STATIC_LIBRARIES)
-ifeq ($(libbcc_USE_MCJIT),1)
- LOCAL_STATIC_LIBRARIES += librsloader
-endif
+LOCAL_STATIC_LIBRARIES += librsloader
ifeq ($(libbcc_USE_DISASSEMBLER),1)
LOCAL_STATIC_LIBRARIES += \
diff --git a/Config.h b/Config.h
index ebe0044..b1ea833 100644
--- a/Config.h
+++ b/Config.h
@@ -4,62 +4,22 @@
#include "ConfigFromMk.h"
//---------------------------------------------------------------------------
-// Configuration for JIT & MC Assembler
-//---------------------------------------------------------------------------
-#if !USE_OLD_JIT && !USE_MCJIT
-#error "You should choose at least one code generation method."
-#endif
-
-//---------------------------------------------------------------------------
// Configuration for Disassembler
//---------------------------------------------------------------------------
-#if !USE_OLD_JIT
-#undef DEBUG_OLD_JIT_DISASSEMBLER
-#define DEBUG_OLD_JIT_DISASSEMBLER 0
-#endif
-
-#if !USE_MCJIT
-#undef DEBUG_MCJIT_DISASSEMBLER
-#define DEBUG_MCJIT_DISASSEMBLER 0
-#endif
-
-#if DEBUG_OLD_JIT_DISASSEMBLER || DEBUG_MCJIT_DISASSEMBLER
+#if DEBUG_MC_DISASSEMBLER
#define USE_DISASSEMBLER 1
#else
#define USE_DISASSEMBLER 0
#endif
#if defined(__HOST__)
-#define DEBUG_OLD_JIT_DISASSEMBLER_FILE "/tmp/oldjit-dis.s"
-#define DEBUG_MCJIT_DISASSEMBLER_FILE "/tmp/mcjit-dis.s"
+#define DEBUG_MC_DISASSEMBLER_FILE "/tmp/mc-dis.s"
#else
-#define DEBUG_OLD_JIT_DISASSEMBLER_FILE "/data/local/tmp/oldjit-dis.s"
-#define DEBUG_MCJIT_DISASSEMBLER_FILE "/data/local/tmp/mcjit-dis.s"
+#define DEBUG_MC_DISASSEMBLER_FILE "/data/local/tmp/mc-dis.s"
#endif // defined(__HOST__)
//---------------------------------------------------------------------------
-// Configuration for ContextManager
-//---------------------------------------------------------------------------
-
-#if USE_OLD_JIT
-
-// Note: Most of the code should NOT use these constants. Use the public
-// static member of ContextManager instead, which is type-safe. For example,
-// if you need BCC_CONTEXT_FIXED_ADDR_, then you should write:
-// ContextManager::ContextFixedAddr
-
-#define BCC_CONTEXT_FIXED_ADDR_ reinterpret_cast<char *>(0x7e000000)
-
-#define BCC_CONTEXT_SLOT_COUNT_ 8
-
-#define BCC_CONTEXT_CODE_SIZE_ (128 * 1024)
-
-#define BCC_CONTEXT_DATA_SIZE_ (128 * 1024)
-
-#endif // USE_OLD_JIT
-
-//---------------------------------------------------------------------------
// Configuration for CodeGen and CompilerRT
//---------------------------------------------------------------------------
diff --git a/README.html b/README.html
index 0b8b447..447312a 100644
--- a/README.html
+++ b/README.html
@@ -419,24 +419,24 @@
table, and bcc context. Every section should be aligned to a word size.
Here is the brief description of each sections:</p>
<ul class="simple">
-<li><strong>Header</strong> (OBCC_Header) - The header of a cache file. It contains the
+<li><strong>Header</strong> (MCO_Header) - The header of a cache file. It contains the
magic word, version, machine integer type information (the endianness,
the size of off_t, size_t, and ptr_t), and the size
and offset of other sections. The header section is guaranteed
to be at the beginning of the cache file.</li>
-<li><strong>String Pool</strong> (OBCC_StringPool) - A collection of serialized variable
+<li><strong>String Pool</strong> (MCO_StringPool) - A collection of serialized variable
length strings. The strp_index in the other part of the cache file
represents the index of such string in this string pool.</li>
-<li><strong>Dependencies Table</strong> (OBCC_DependencyTable) - The dependencies table.
+<li><strong>Dependencies Table</strong> (MCO_DependencyTable) - The dependencies table.
This table stores the resource name (or file path), the resource
type (rather in APK or on the file system), and the SHA1 checksum.</li>
-<li><strong>Relocation Table</strong> (OBCC_RelocationTable) - <em>not enabled</em></li>
-<li><strong>Exported Variable List</strong> (OBCC_ExportVarList) -
+<li><strong>Relocation Table</strong> (MCO_RelocationTable) - <em>not enabled</em></li>
+<li><strong>Exported Variable List</strong> (MCO_ExportVarList) -
The list of the addresses of exported variables.</li>
-<li><strong>Exported Function List</strong> (OBCC_ExportFuncList) -
+<li><strong>Exported Function List</strong> (MCO_ExportFuncList) -
The list of the addresses of exported functions.</li>
-<li><strong>Pragma List</strong> (OBCC_PragmaList) - The list of pragma key-value pair.</li>
-<li><strong>Function Information Table</strong> (OBCC_FuncTable) - This is a table of
+<li><strong>Pragma List</strong> (MCO_PragmaList) - The list of pragma key-value pair.</li>
+<li><strong>Function Information Table</strong> (MCO_FuncTable) - This is a table of
function information, such as function name, function entry address,
and function binary size. Besides, the table should be ordered by
function name.</li>
diff --git a/README.rst b/README.rst
index cf40138..97070c0 100644
--- a/README.rst
+++ b/README.rst
@@ -138,31 +138,31 @@
table, and bcc context. Every section should be aligned to a word size.
Here is the brief description of each sections:
-* **Header** (OBCC_Header) - The header of a cache file. It contains the
+* **Header** (MCO_Header) - The header of a cache file. It contains the
magic word, version, machine integer type information (the endianness,
the size of off_t, size_t, and ptr_t), and the size
and offset of other sections. The header section is guaranteed
to be at the beginning of the cache file.
-* **String Pool** (OBCC_StringPool) - A collection of serialized variable
+* **String Pool** (MCO_StringPool) - A collection of serialized variable
length strings. The strp_index in the other part of the cache file
represents the index of such string in this string pool.
-* **Dependencies Table** (OBCC_DependencyTable) - The dependencies table.
+* **Dependencies Table** (MCO_DependencyTable) - The dependencies table.
This table stores the resource name (or file path), the resource
type (rather in APK or on the file system), and the SHA1 checksum.
-* **Relocation Table** (OBCC_RelocationTable) - *not enabled*
+* **Relocation Table** (MCO_RelocationTable) - *not enabled*
-* **Exported Variable List** (OBCC_ExportVarList) -
+* **Exported Variable List** (MCO_ExportVarList) -
The list of the addresses of exported variables.
-* **Exported Function List** (OBCC_ExportFuncList) -
+* **Exported Function List** (MCO_ExportFuncList) -
The list of the addresses of exported functions.
-* **Pragma List** (OBCC_PragmaList) - The list of pragma key-value pair.
+* **Pragma List** (MCO_PragmaList) - The list of pragma key-value pair.
-* **Function Information Table** (OBCC_FuncTable) - This is a table of
+* **Function Information Table** (MCO_FuncTable) - This is a table of
function information, such as function name, function entry address,
and function binary size. Besides, the table should be ordered by
function name.
diff --git a/include/bcc/bcc_cache.h b/include/bcc/bcc_cache.h
deleted file mode 100644
index 6809cce..0000000
--- a/include/bcc/bcc_cache.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright 2010-2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BCC_CACHE_H
-#define BCC_CACHE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-/* BCC Cache File Magic Word */
-#define OBCC_MAGIC "\0bcc"
-
-/* BCC Cache File Version, encoded in 4 bytes of ASCII */
-#define OBCC_VERSION "001\0"
-
-/* BCC Cache Header Structure */
-struct OBCC_Header {
- /* magic and version */
- uint8_t magic[4];
- uint8_t version[4];
-
- /* machine-dependent integer type size */
- uint8_t endianness;
- uint8_t sizeof_off_t;
- uint8_t sizeof_size_t;
- uint8_t sizeof_ptr_t;
-
- /* string pool section */
- off_t str_pool_offset;
- size_t str_pool_size;
-
- /* dependancy table */
- off_t depend_tab_offset;
- size_t depend_tab_size;
-
- /* relocation table section */
- off_t reloc_tab_offset;
- size_t reloc_tab_size;
-
- /* export variable list section */
- off_t export_var_list_offset;
- size_t export_var_list_size;
-
- /* export function list section */
- off_t export_func_list_offset;
- size_t export_func_list_size;
-
- /* pragma list section */
- off_t pragma_list_offset;
- size_t pragma_list_size;
-
- /* function table */
- off_t func_table_offset;
- size_t func_table_size;
-
- /* function table */
- off_t object_slot_list_offset;
- size_t object_slot_list_size;
-
- /* context section */
- char *context_cached_addr;
- uint32_t context_parity_checksum;
-
- /* dirty hack for libRS */
- /* TODO: This should be removed in the future */
- uint32_t libRS_threadable;
-
- /* export foreach list section */
- off_t export_foreach_list_offset;
- size_t export_foreach_list_size;
-};
-
-struct OBCC_String {
- size_t length; /* String length, without ending '\0' */
- off_t offset; /* Note: Offset related to string_pool_offset. */
-};
-
-struct OBCC_StringPool {
- size_t count;
- struct OBCC_String list[];
-};
-
-enum OBCC_ResourceType {
- BCC_APK_RESOURCE = 0,
- BCC_FILE_RESOURCE = 1,
-};
-
-struct OBCC_Dependency {
- size_t res_name_strp_index;
- uint32_t res_type; /* BCC_APK_RESOURCE or BCC_FILE_RESOURCE */
- unsigned char sha1[20];
-};
-
-struct OBCC_DependencyTable {
- size_t count;
- struct OBCC_Dependency table[];
-};
-
-struct OBCC_RelocationTable {
-/* TODO: Implement relocation table. */
-};
-
-struct OBCC_ExportVarList {
- size_t count;
- void *cached_addr_list[];
-};
-
-struct OBCC_ExportFuncList {
- size_t count;
- void *cached_addr_list[];
-};
-
-struct OBCC_ExportForEachList {
- size_t count;
- void *cached_addr_list[];
-};
-
-struct OBCC_Pragma {
- size_t key_strp_index;
- size_t value_strp_index;
-};
-
-struct OBCC_PragmaList {
- size_t count;
- struct OBCC_Pragma list[];
-};
-
-struct OBCC_ObjectSlotList {
- size_t count;
- uint32_t object_slot_list[];
-};
-
-struct OBCC_FuncInfo {
- size_t name_strp_index;
- void *cached_addr;
- size_t size;
-};
-
-struct OBCC_FuncTable {
- size_t count;
- struct OBCC_FuncInfo table[];
-};
-
-struct OBCC_String_Ptr {
- size_t count;
- size_t strp_indexs[];
-};
-
-
-#endif /* BCC_CACHE_H */
diff --git a/include/bcc/bcc_mccache.h b/include/bcc/bcc_mccache.h
index 292165d..a214831 100644
--- a/include/bcc/bcc_mccache.h
+++ b/include/bcc/bcc_mccache.h
@@ -20,8 +20,6 @@
#include <stdint.h>
#include <sys/types.h>
-#include "bcc_cache.h"
-
/* BCC Cache File Magic Word */
#define MCO_MAGIC "\0bcc"
@@ -81,5 +79,77 @@
size_t export_foreach_name_list_size;
};
+struct MCO_String {
+ size_t length; /* String length, without ending '\0' */
+ off_t offset; /* Note: Offset related to string_pool_offset. */
+};
+
+struct MCO_StringPool {
+ size_t count;
+ struct MCO_String list[];
+};
+
+enum MCO_ResourceType {
+ BCC_APK_RESOURCE = 0,
+ BCC_FILE_RESOURCE = 1,
+};
+
+struct MCO_Dependency {
+ size_t res_name_strp_index;
+ uint32_t res_type; /* BCC_APK_RESOURCE or BCC_FILE_RESOURCE */
+ unsigned char sha1[20];
+};
+
+struct MCO_DependencyTable {
+ size_t count;
+ struct MCO_Dependency table[];
+};
+
+struct MCO_ExportVarList {
+ size_t count;
+ void *cached_addr_list[];
+};
+
+struct MCO_ExportFuncList {
+ size_t count;
+ void *cached_addr_list[];
+};
+
+struct MCO_ExportForEachList {
+ size_t count;
+ void *cached_addr_list[];
+};
+
+struct MCO_Pragma {
+ size_t key_strp_index;
+ size_t value_strp_index;
+};
+
+struct MCO_PragmaList {
+ size_t count;
+ struct MCO_Pragma list[];
+};
+
+struct MCO_ObjectSlotList {
+ size_t count;
+ uint32_t object_slot_list[];
+};
+
+struct MCO_FuncInfo {
+ size_t name_strp_index;
+ void *cached_addr;
+ size_t size;
+};
+
+struct MCO_FuncTable {
+ size_t count;
+ struct MCO_FuncInfo table[];
+};
+
+struct MCO_String_Ptr {
+ size_t count;
+ size_t strp_indexs[];
+};
+
#endif /* BCC_MCCACHE_H */
diff --git a/lib/CodeGen/Android.mk b/lib/CodeGen/Android.mk
deleted file mode 100644
index 0eacfa1..0000000
--- a/lib/CodeGen/Android.mk
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-#
-
-LOCAL_PATH := $(call my-dir)
-include $(LOCAL_PATH)/../../libbcc-config.mk
-
-ifeq ($(libbcc_USE_OLD_JIT),1)
-
-#=====================================================================
-# Common: libbccCodeGen
-#=====================================================================
-
-libbcc_codegen_SRC_FILES := \
- CodeEmitter.cpp \
- CodeMemoryManager.cpp
-
-
-#=====================================================================
-# Device Static Library: libbccCodeGen
-#=====================================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libbccCodeGen
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-LOCAL_CFLAGS += $(libbcc_CFLAGS)
-LOCAL_C_INCLUDES += $(libbcc_C_INCLUDES)
-LOCAL_SRC_FILES := $(libbcc_codegen_SRC_FILES)
-
-include $(LIBBCC_ROOT_PATH)/libbcc-gen-config-from-mk.mk
-include $(LIBBCC_ROOT_PATH)/libbcc-build-rules.mk
-include $(LLVM_ROOT_PATH)/llvm-device-build.mk
-include $(BUILD_STATIC_LIBRARY)
-
-
-#=====================================================================
-# Host Static Library: libbccCodeGen
-#=====================================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := libbccCodeGen
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_CLASS := STATIC_LIBRARIES
-LOCAL_IS_HOST_MODULE := true
-
-LOCAL_CFLAGS += $(libbcc_CFLAGS)
-LOCAL_CFLAGS += -D__HOST__
-LOCAL_C_INCLUDES += $(libbcc_C_INCLUDES)
-
-LOCAL_SRC_FILES := $(libbcc_codegen_SRC_FILES)
-
-include $(LIBBCC_ROOT_PATH)/libbcc-gen-config-from-mk.mk
-include $(LIBBCC_ROOT_PATH)/libbcc-build-rules.mk
-include $(LLVM_ROOT_PATH)/llvm-host-build.mk
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-endif # $(libbcc_USE_OLD_JIT)
diff --git a/lib/CodeGen/CodeEmitter.cpp b/lib/CodeGen/CodeEmitter.cpp
deleted file mode 100644
index c3f37e1..0000000
--- a/lib/CodeGen/CodeEmitter.cpp
+++ /dev/null
@@ -1,1442 +0,0 @@
-//===-- CodeEmitter.cpp - CodeEmitter Class -------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See external/llvm/LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CodeEmitter class.
-//
-//===----------------------------------------------------------------------===//
-
-#define LOG_TAG "bcc"
-#include <cutils/log.h>
-
-#include "CodeEmitter.h"
-
-#include "Config.h"
-
-#if DEBUG_OLD_JIT_DISASSEMBLER
-#include "Disassembler/Disassembler.h"
-#endif
-
-#include "CodeMemoryManager.h"
-#include "ExecutionEngine/Runtime.h"
-#include "ExecutionEngine/ScriptCompiled.h"
-
-#include <bcc/bcc.h>
-#include <bcc/bcc_cache.h>
-#include "ExecutionEngine/bcc_internal.h"
-
-#include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-
-#include "llvm/CodeGen/MachineBasicBlock.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/MachineRelocation.h"
-#include "llvm/CodeGen/MachineJumpTableInfo.h"
-#include "llvm/CodeGen/JITCodeEmitter.h"
-
-#include "llvm/ExecutionEngine/GenericValue.h"
-
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include "llvm/Support/Host.h"
-
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Support/TargetRegistry.h"
-#include "llvm/Target/TargetJITInfo.h"
-
-#include "llvm/Constant.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalAlias.h"
-#include "llvm/GlobalValue.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/Instruction.h"
-#include "llvm/Type.h"
-
-#include <algorithm>
-#include <vector>
-#include <set>
-#include <string>
-
-#include <stddef.h>
-
-
-namespace bcc {
-
-// Will take the ownership of @MemMgr
-CodeEmitter::CodeEmitter(ScriptCompiled *result, CodeMemoryManager *pMemMgr)
- : mpResult(result),
- mpMemMgr(pMemMgr),
- mpTarget(NULL),
- mpTJI(NULL),
- mpTD(NULL),
- mpCurEmitFunction(NULL),
- mpConstantPool(NULL),
- mpJumpTable(NULL),
- mpMMI(NULL),
- mpSymbolLookupFn(NULL),
- mpSymbolLookupContext(NULL) {
-}
-
-
-CodeEmitter::~CodeEmitter() {
-}
-
-
-// Once you finish the compilation on a translation unit, you can call this
-// function to recycle the memory (which is used at compilation time and not
-// needed for runtime).
-//
-// NOTE: You should not call this funtion until the code-gen passes for a
-// given module is done. Otherwise, the results is undefined and may
-// cause the system crash!
-void CodeEmitter::releaseUnnecessary() {
- mMBBLocations.clear();
- mLabelLocations.clear();
- mGlobalAddressMap.clear();
- mFunctionToLazyStubMap.clear();
- GlobalToIndirectSymMap.clear();
- ExternalFnToStubMap.clear();
- PendingFunctions.clear();
-}
-
-
-void CodeEmitter::reset() {
- releaseUnnecessary();
-
- mpResult = NULL;
-
- mpSymbolLookupFn = NULL;
- mpSymbolLookupContext = NULL;
-
- mpTJI = NULL;
- mpTD = NULL;
-
- mpMemMgr->reset();
-}
-
-
-void *CodeEmitter::UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
- if (Addr == NULL) {
- // Removing mapping
- GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
- void *OldVal;
-
- if (I == mGlobalAddressMap.end()) {
- OldVal = NULL;
- } else {
- OldVal = I->second;
- mGlobalAddressMap.erase(I);
- }
-
- return OldVal;
- }
-
- void *&CurVal = mGlobalAddressMap[GV];
- void *OldVal = CurVal;
-
- CurVal = Addr;
-
- return OldVal;
-}
-
-
-unsigned int CodeEmitter::GetConstantPoolSizeInBytes(
- llvm::MachineConstantPool *MCP) {
- const std::vector<llvm::MachineConstantPoolEntry> &Constants =
- MCP->getConstants();
-
- if (Constants.empty())
- return 0;
-
- unsigned int Size = 0;
- for (int i = 0, e = Constants.size(); i != e; i++) {
- llvm::MachineConstantPoolEntry CPE = Constants[i];
- unsigned int AlignMask = CPE.getAlignment() - 1;
- Size = (Size + AlignMask) & ~AlignMask;
- llvm::Type *Ty = CPE.getType();
- Size += mpTD->getTypeAllocSize(Ty);
- }
-
- return Size;
-}
-
-// This function converts a Constant* into a GenericValue. The interesting
-// part is if C is a ConstantExpr.
-void CodeEmitter::GetConstantValue(const llvm::Constant *C,
- llvm::GenericValue &Result) {
- if (C->getValueID() == llvm::Value::UndefValueVal)
- return;
- else if (C->getValueID() == llvm::Value::ConstantExprVal) {
- const llvm::ConstantExpr *CE = (llvm::ConstantExpr*) C;
- const llvm::Constant *Op0 = CE->getOperand(0);
-
- switch (CE->getOpcode()) {
- case llvm::Instruction::GetElementPtr: {
- // Compute the index
- llvm::SmallVector<llvm::Value*, 8> Indices(CE->op_begin() + 1,
- CE->op_end());
- uint64_t Offset = mpTD->getIndexedOffset(Op0->getType(), Indices);
-
- GetConstantValue(Op0, Result);
- Result.PointerVal =
- static_cast<uint8_t*>(Result.PointerVal) + Offset;
-
- return;
- }
- case llvm::Instruction::Trunc: {
- uint32_t BitWidth =
- llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
-
- GetConstantValue(Op0, Result);
- Result.IntVal = Result.IntVal.trunc(BitWidth);
-
- return;
- }
- case llvm::Instruction::ZExt: {
- uint32_t BitWidth =
- llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
-
- GetConstantValue(Op0, Result);
- Result.IntVal = Result.IntVal.zext(BitWidth);
-
- return;
- }
- case llvm::Instruction::SExt: {
- uint32_t BitWidth =
- llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
-
- GetConstantValue(Op0, Result);
- Result.IntVal = Result.IntVal.sext(BitWidth);
-
- return;
- }
- case llvm::Instruction::FPTrunc: {
- // TODO(all): fixme: long double
- GetConstantValue(Op0, Result);
- Result.FloatVal = static_cast<float>(Result.DoubleVal);
- return;
- }
- case llvm::Instruction::FPExt: {
- // TODO(all): fixme: long double
- GetConstantValue(Op0, Result);
- Result.DoubleVal = static_cast<double>(Result.FloatVal);
- return;
- }
- case llvm::Instruction::UIToFP: {
- GetConstantValue(Op0, Result);
- if (CE->getType()->isFloatTy())
- Result.FloatVal =
- static_cast<float>(Result.IntVal.roundToDouble());
- else if (CE->getType()->isDoubleTy())
- Result.DoubleVal = Result.IntVal.roundToDouble();
- else if (CE->getType()->isX86_FP80Ty()) {
- const uint64_t zero[] = { 0, 0 };
- llvm::APFloat apf(llvm::APInt(80, 2, zero));
- apf.convertFromAPInt(Result.IntVal,
- false,
- llvm::APFloat::rmNearestTiesToEven);
- Result.IntVal = apf.bitcastToAPInt();
- }
- return;
- }
- case llvm::Instruction::SIToFP: {
- GetConstantValue(Op0, Result);
- if (CE->getType()->isFloatTy())
- Result.FloatVal =
- static_cast<float>(Result.IntVal.signedRoundToDouble());
- else if (CE->getType()->isDoubleTy())
- Result.DoubleVal = Result.IntVal.signedRoundToDouble();
- else if (CE->getType()->isX86_FP80Ty()) {
- const uint64_t zero[] = { 0, 0 };
- llvm::APFloat apf = llvm::APFloat(llvm::APInt(80, 2, zero));
- apf.convertFromAPInt(Result.IntVal,
- true,
- llvm::APFloat::rmNearestTiesToEven);
- Result.IntVal = apf.bitcastToAPInt();
- }
- return;
- }
- // double->APInt conversion handles sign
- case llvm::Instruction::FPToUI:
- case llvm::Instruction::FPToSI: {
- uint32_t BitWidth =
- llvm::cast<llvm::IntegerType>(CE->getType())->getBitWidth();
-
- GetConstantValue(Op0, Result);
- if (Op0->getType()->isFloatTy())
- Result.IntVal =
- llvm::APIntOps::RoundFloatToAPInt(Result.FloatVal, BitWidth);
- else if (Op0->getType()->isDoubleTy())
- Result.IntVal =
- llvm::APIntOps::RoundDoubleToAPInt(Result.DoubleVal,
- BitWidth);
- else if (Op0->getType()->isX86_FP80Ty()) {
- llvm::APFloat apf = llvm::APFloat(Result.IntVal);
- uint64_t V;
- bool Ignored;
- apf.convertToInteger(&V,
- BitWidth,
- CE->getOpcode() == llvm::Instruction::FPToSI,
- llvm::APFloat::rmTowardZero,
- &Ignored);
- Result.IntVal = V; // endian?
- }
- return;
- }
- case llvm::Instruction::PtrToInt: {
- uint32_t PtrWidth = mpTD->getPointerSizeInBits();
-
- GetConstantValue(Op0, Result);
- Result.IntVal = llvm::APInt(PtrWidth, uintptr_t
- (Result.PointerVal));
-
- return;
- }
- case llvm::Instruction::IntToPtr: {
- uint32_t PtrWidth = mpTD->getPointerSizeInBits();
-
- GetConstantValue(Op0, Result);
- if (PtrWidth != Result.IntVal.getBitWidth())
- Result.IntVal = Result.IntVal.zextOrTrunc(PtrWidth);
- bccAssert(Result.IntVal.getBitWidth() <= 64 && "Bad pointer width");
-
- Result.PointerVal =
- llvm::PointerTy(
- static_cast<uintptr_t>(Result.IntVal.getZExtValue()));
-
- return;
- }
- case llvm::Instruction::BitCast: {
- GetConstantValue(Op0, Result);
- const llvm::Type *DestTy = CE->getType();
-
- switch (Op0->getType()->getTypeID()) {
- case llvm::Type::IntegerTyID: {
- bccAssert(DestTy->isFloatingPointTy() && "invalid bitcast");
- if (DestTy->isFloatTy())
- Result.FloatVal = Result.IntVal.bitsToFloat();
- else if (DestTy->isDoubleTy())
- Result.DoubleVal = Result.IntVal.bitsToDouble();
- break;
- }
- case llvm::Type::FloatTyID: {
- bccAssert(DestTy->isIntegerTy(32) && "Invalid bitcast");
- Result.IntVal.floatToBits(Result.FloatVal);
- break;
- }
- case llvm::Type::DoubleTyID: {
- bccAssert(DestTy->isIntegerTy(64) && "Invalid bitcast");
- Result.IntVal.doubleToBits(Result.DoubleVal);
- break;
- }
- case llvm::Type::PointerTyID: {
- bccAssert(DestTy->isPointerTy() && "Invalid bitcast");
- break; // getConstantValue(Op0) above already converted it
- }
- default: {
- llvm_unreachable("Invalid bitcast operand");
- }
- }
- return;
- }
- case llvm::Instruction::Add:
- case llvm::Instruction::FAdd:
- case llvm::Instruction::Sub:
- case llvm::Instruction::FSub:
- case llvm::Instruction::Mul:
- case llvm::Instruction::FMul:
- case llvm::Instruction::UDiv:
- case llvm::Instruction::SDiv:
- case llvm::Instruction::URem:
- case llvm::Instruction::SRem:
- case llvm::Instruction::And:
- case llvm::Instruction::Or:
- case llvm::Instruction::Xor: {
- llvm::GenericValue LHS, RHS;
- GetConstantValue(Op0, LHS);
- GetConstantValue(CE->getOperand(1), RHS);
-
- switch (Op0->getType()->getTypeID()) {
- case llvm::Type::IntegerTyID: {
- switch (CE->getOpcode()) {
- case llvm::Instruction::Add: {
- Result.IntVal = LHS.IntVal + RHS.IntVal;
- break;
- }
- case llvm::Instruction::Sub: {
- Result.IntVal = LHS.IntVal - RHS.IntVal;
- break;
- }
- case llvm::Instruction::Mul: {
- Result.IntVal = LHS.IntVal * RHS.IntVal;
- break;
- }
- case llvm::Instruction::UDiv: {
- Result.IntVal = LHS.IntVal.udiv(RHS.IntVal);
- break;
- }
- case llvm::Instruction::SDiv: {
- Result.IntVal = LHS.IntVal.sdiv(RHS.IntVal);
- break;
- }
- case llvm::Instruction::URem: {
- Result.IntVal = LHS.IntVal.urem(RHS.IntVal);
- break;
- }
- case llvm::Instruction::SRem: {
- Result.IntVal = LHS.IntVal.srem(RHS.IntVal);
- break;
- }
- case llvm::Instruction::And: {
- Result.IntVal = LHS.IntVal & RHS.IntVal;
- break;
- }
- case llvm::Instruction::Or: {
- Result.IntVal = LHS.IntVal | RHS.IntVal;
- break;
- }
- case llvm::Instruction::Xor: {
- Result.IntVal = LHS.IntVal ^ RHS.IntVal;
- break;
- }
- default: {
- llvm_unreachable("Invalid integer opcode");
- }
- }
- break;
- }
- case llvm::Type::FloatTyID: {
- switch (CE->getOpcode()) {
- case llvm::Instruction::FAdd: {
- Result.FloatVal = LHS.FloatVal + RHS.FloatVal;
- break;
- }
- case llvm::Instruction::FSub: {
- Result.FloatVal = LHS.FloatVal - RHS.FloatVal;
- break;
- }
- case llvm::Instruction::FMul: {
- Result.FloatVal = LHS.FloatVal * RHS.FloatVal;
- break;
- }
- case llvm::Instruction::FDiv: {
- Result.FloatVal = LHS.FloatVal / RHS.FloatVal;
- break;
- }
- case llvm::Instruction::FRem: {
- Result.FloatVal = ::fmodf(LHS.FloatVal, RHS.FloatVal);
- break;
- }
- default: {
- llvm_unreachable("Invalid float opcode");
- }
- }
- break;
- }
- case llvm::Type::DoubleTyID: {
- switch (CE->getOpcode()) {
- case llvm::Instruction::FAdd: {
- Result.DoubleVal = LHS.DoubleVal + RHS.DoubleVal;
- break;
- }
- case llvm::Instruction::FSub: {
- Result.DoubleVal = LHS.DoubleVal - RHS.DoubleVal;
- break;
- }
- case llvm::Instruction::FMul: {
- Result.DoubleVal = LHS.DoubleVal * RHS.DoubleVal;
- break;
- }
- case llvm::Instruction::FDiv: {
- Result.DoubleVal = LHS.DoubleVal / RHS.DoubleVal;
- break;
- }
- case llvm::Instruction::FRem: {
- Result.DoubleVal = ::fmod(LHS.DoubleVal, RHS.DoubleVal);
- break;
- }
- default: {
- llvm_unreachable("Invalid double opcode");
- }
- }
- break;
- }
- case llvm::Type::X86_FP80TyID:
- case llvm::Type::PPC_FP128TyID:
- case llvm::Type::FP128TyID: {
- llvm::APFloat apfLHS = llvm::APFloat(LHS.IntVal);
- switch (CE->getOpcode()) {
- case llvm::Instruction::FAdd: {
- apfLHS.add(llvm::APFloat(RHS.IntVal),
- llvm::APFloat::rmNearestTiesToEven);
- break;
- }
- case llvm::Instruction::FSub: {
- apfLHS.subtract(llvm::APFloat(RHS.IntVal),
- llvm::APFloat::rmNearestTiesToEven);
- break;
- }
- case llvm::Instruction::FMul: {
- apfLHS.multiply(llvm::APFloat(RHS.IntVal),
- llvm::APFloat::rmNearestTiesToEven);
- break;
- }
- case llvm::Instruction::FDiv: {
- apfLHS.divide(llvm::APFloat(RHS.IntVal),
- llvm::APFloat::rmNearestTiesToEven);
- break;
- }
- case llvm::Instruction::FRem: {
- apfLHS.mod(llvm::APFloat(RHS.IntVal),
- llvm::APFloat::rmNearestTiesToEven);
- break;
- }
- default: {
- llvm_unreachable("Invalid long double opcode");
- }
- }
- Result.IntVal = apfLHS.bitcastToAPInt();
- break;
- }
- default: {
- llvm_unreachable("Bad add type!");
- }
- } // End switch (Op0->getType()->getTypeID())
- return;
- }
- default: {
- break;
- }
- } // End switch (CE->getOpcode())
-
- std::string msg;
- llvm::raw_string_ostream Msg(msg);
- Msg << "ConstantExpr not handled: " << *CE;
- llvm::report_fatal_error(Msg.str());
- } // C->getValueID() == llvm::Value::ConstantExprVal
-
- switch (C->getType()->getTypeID()) {
- case llvm::Type::FloatTyID: {
- Result.FloatVal =
- llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToFloat();
- break;
- }
- case llvm::Type::DoubleTyID: {
- Result.DoubleVal =
- llvm::cast<llvm::ConstantFP>(C)->getValueAPF().convertToDouble();
- break;
- }
- case llvm::Type::X86_FP80TyID:
- case llvm::Type::FP128TyID:
- case llvm::Type::PPC_FP128TyID: {
- Result.IntVal =
- llvm::cast<llvm::ConstantFP>(C)->getValueAPF().bitcastToAPInt();
- break;
- }
- case llvm::Type::IntegerTyID: {
- Result.IntVal =
- llvm::cast<llvm::ConstantInt>(C)->getValue();
- break;
- }
- case llvm::Type::PointerTyID: {
- switch (C->getValueID()) {
- case llvm::Value::ConstantPointerNullVal: {
- Result.PointerVal = NULL;
- break;
- }
- case llvm::Value::FunctionVal: {
- const llvm::Function *F = static_cast<const llvm::Function*>(C);
- Result.PointerVal =
- GetPointerToFunctionOrStub(const_cast<llvm::Function*>(F));
- break;
- }
- case llvm::Value::GlobalVariableVal: {
- const llvm::GlobalVariable *GV =
- static_cast<const llvm::GlobalVariable*>(C);
- Result.PointerVal =
- GetOrEmitGlobalVariable(const_cast<llvm::GlobalVariable*>(GV));
- break;
- }
- case llvm::Value::BlockAddressVal: {
- bccAssert(false && "JIT does not support address-of-label yet!");
- }
- default: {
- llvm_unreachable("Unknown constant pointer type!");
- }
- }
- break;
- }
- default: {
- std::string msg;
- llvm::raw_string_ostream Msg(msg);
- Msg << "ERROR: Constant unimplemented for type: " << *C->getType();
- llvm::report_fatal_error(Msg.str());
- break;
- }
- }
- return;
-}
-
-
-// Stores the data in @Val of type @Ty at address @Addr.
-void CodeEmitter::StoreValueToMemory(const llvm::GenericValue &Val,
- void *Addr,
- llvm::Type *Ty) {
- const unsigned int StoreBytes = mpTD->getTypeStoreSize(Ty);
-
- switch (Ty->getTypeID()) {
- case llvm::Type::IntegerTyID: {
- const llvm::APInt &IntVal = Val.IntVal;
- bccAssert(((IntVal.getBitWidth() + 7) / 8 >= StoreBytes) &&
- "Integer too small!");
-
- const uint8_t *Src =
- reinterpret_cast<const uint8_t*>(IntVal.getRawData());
-
- if (llvm::sys::isLittleEndianHost()) {
- // Little-endian host - the source is ordered from LSB to MSB.
- // Order the destination from LSB to MSB: Do a straight copy.
- memcpy(Addr, Src, StoreBytes);
- } else {
- // Big-endian host - the source is an array of 64 bit words
- // ordered from LSW to MSW.
- //
- // Each word is ordered from MSB to LSB.
- //
- // Order the destination from MSB to LSB:
- // Reverse the word order, but not the bytes in a word.
- unsigned int i = StoreBytes;
- while (i > sizeof(uint64_t)) {
- i -= sizeof(uint64_t);
- ::memcpy(reinterpret_cast<uint8_t*>(Addr) + i,
- Src,
- sizeof(uint64_t));
- Src += sizeof(uint64_t);
- }
- ::memcpy(Addr, Src + sizeof(uint64_t) - i, i);
- }
- break;
- }
- case llvm::Type::FloatTyID: {
- *reinterpret_cast<float*>(Addr) = Val.FloatVal;
- break;
- }
- case llvm::Type::DoubleTyID: {
- *reinterpret_cast<double*>(Addr) = Val.DoubleVal;
- break;
- }
- case llvm::Type::X86_FP80TyID: {
- memcpy(Addr, Val.IntVal.getRawData(), 10);
- break;
- }
- case llvm::Type::PointerTyID: {
- // Ensure 64 bit target pointers are fully initialized on 32 bit
- // hosts.
- if (StoreBytes != sizeof(llvm::PointerTy))
- memset(Addr, 0, StoreBytes);
- *((llvm::PointerTy*) Addr) = Val.PointerVal;
- break;
- }
- default: {
- break;
- }
- }
-
- if (llvm::sys::isLittleEndianHost() != mpTD->isLittleEndian())
- std::reverse(reinterpret_cast<uint8_t*>(Addr),
- reinterpret_cast<uint8_t*>(Addr) + StoreBytes);
-
- return;
-}
-
-
-// Recursive function to apply a @Constant value into the specified memory
-// location @Addr.
-void CodeEmitter::InitializeConstantToMemory(const llvm::Constant *C, void *Addr) {
- switch (C->getValueID()) {
- case llvm::Value::UndefValueVal: {
- // Nothing to do
- break;
- }
- case llvm::Value::ConstantVectorVal: {
- // dynamic cast may hurt performance
- const llvm::ConstantVector *CP = (llvm::ConstantVector*) C;
-
- unsigned int ElementSize = mpTD->getTypeAllocSize
- (CP->getType()->getElementType());
-
- for (int i = 0, e = CP->getNumOperands(); i != e;i++)
- InitializeConstantToMemory(
- CP->getOperand(i),
- reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
- break;
- }
- case llvm::Value::ConstantAggregateZeroVal: {
- memset(Addr, 0, (size_t) mpTD->getTypeAllocSize(C->getType()));
- break;
- }
- case llvm::Value::ConstantArrayVal: {
- const llvm::ConstantArray *CPA = (llvm::ConstantArray*) C;
- unsigned int ElementSize = mpTD->getTypeAllocSize
- (CPA->getType()->getElementType());
-
- for (int i = 0, e = CPA->getNumOperands(); i != e; i++)
- InitializeConstantToMemory(
- CPA->getOperand(i),
- reinterpret_cast<uint8_t*>(Addr) + i * ElementSize);
- break;
- }
- case llvm::Value::ConstantStructVal: {
- const llvm::ConstantStruct *CPS =
- static_cast<const llvm::ConstantStruct*>(C);
- const llvm::StructLayout *SL = mpTD->getStructLayout
- (llvm::cast<llvm::StructType>(CPS->getType()));
-
- for (int i = 0, e = CPS->getNumOperands(); i != e; i++)
- InitializeConstantToMemory(
- CPS->getOperand(i),
- reinterpret_cast<uint8_t*>(Addr) + SL->getElementOffset(i));
- break;
- }
- default: {
- if (C->getType()->isFirstClassType()) {
- llvm::GenericValue Val;
- GetConstantValue(C, Val);
- StoreValueToMemory(Val, Addr, C->getType());
- } else {
- llvm_unreachable("Unknown constant type to initialize memory "
- "with!");
- }
- break;
- }
- }
- return;
-}
-
-
-void CodeEmitter::emitConstantPool(llvm::MachineConstantPool *MCP) {
- if (mpTJI->hasCustomConstantPool())
- return;
-
- // Constant pool address resolution is handled by the target itself in ARM
- // (TargetJITInfo::hasCustomConstantPool() returns true).
-#if !defined(PROVIDE_ARM_CODEGEN)
- const std::vector<llvm::MachineConstantPoolEntry> &Constants =
- MCP->getConstants();
-
- if (Constants.empty())
- return;
-
- unsigned Size = GetConstantPoolSizeInBytes(MCP);
- unsigned Align = MCP->getConstantPoolAlignment();
-
- mpConstantPoolBase = allocateSpace(Size, Align);
- mpConstantPool = MCP;
-
- if (mpConstantPoolBase == NULL)
- return; // out of memory
-
- unsigned Offset = 0;
- for (int i = 0, e = Constants.size(); i != e; i++) {
- llvm::MachineConstantPoolEntry CPE = Constants[i];
- unsigned AlignMask = CPE.getAlignment() - 1;
- Offset = (Offset + AlignMask) & ~AlignMask;
-
- uintptr_t CAddr = (uintptr_t) mpConstantPoolBase + Offset;
- mConstPoolAddresses.push_back(CAddr);
-
- if (CPE.isMachineConstantPoolEntry())
- llvm::report_fatal_error
- ("Initialize memory with machine specific constant pool"
- " entry has not been implemented!");
-
- InitializeConstantToMemory(CPE.Val.ConstVal, (void*) CAddr);
-
- llvm::Type *Ty = CPE.Val.ConstVal->getType();
- Offset += mpTD->getTypeAllocSize(Ty);
- }
-#endif
- return;
-}
-
-
-void CodeEmitter::initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
- if (mpTJI->hasCustomJumpTables())
- return;
-
- const std::vector<llvm::MachineJumpTableEntry> &JT =
- MJTI->getJumpTables();
- if (JT.empty())
- return;
-
- unsigned NumEntries = 0;
- for (int i = 0, e = JT.size(); i != e; i++)
- NumEntries += JT[i].MBBs.size();
-
- unsigned EntrySize = MJTI->getEntrySize(*mpTD);
-
- mpJumpTable = MJTI;
- mpJumpTableBase = allocateSpace(NumEntries * EntrySize,
- MJTI->getEntryAlignment(*mpTD));
-
- return;
-}
-
-
-void CodeEmitter::emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI) {
- if (mpTJI->hasCustomJumpTables())
- return;
-
- const std::vector<llvm::MachineJumpTableEntry> &JT =
- MJTI->getJumpTables();
- if (JT.empty() || mpJumpTableBase == 0)
- return;
-
- bccAssert(mpTargetMachine->getRelocationModel() == llvm::Reloc::Static &&
- (MJTI->getEntrySize(*mpTD) == sizeof(mpTD /* a pointer type */)) &&
- "Cross JIT'ing?");
-
- // For each jump table, map each target in the jump table to the
- // address of an emitted MachineBasicBlock.
- intptr_t *SlotPtr = reinterpret_cast<intptr_t*>(mpJumpTableBase);
- for (int i = 0, ie = JT.size(); i != ie; i++) {
- const std::vector<llvm::MachineBasicBlock*> &MBBs = JT[i].MBBs;
- // Store the address of the basic block for this jump table slot in the
- // memory we allocated for the jump table in 'initJumpTableInfo'
- for (int j = 0, je = MBBs.size(); j != je; j++)
- *SlotPtr++ = getMachineBasicBlockAddress(MBBs[j]);
- }
-}
-
-
-void *CodeEmitter::GetPointerToGlobal(llvm::GlobalValue *V,
- void *Reference,
- bool MayNeedFarStub) {
- switch (V->getValueID()) {
- case llvm::Value::FunctionVal: {
- llvm::Function *F = (llvm::Function*) V;
-
- // If we have code, go ahead and return that.
- if (void *ResultPtr = GetPointerToGlobalIfAvailable(F))
- return ResultPtr;
-
- if (void *FnStub = GetLazyFunctionStubIfAvailable(F))
- // Return the function stub if it's already created.
- // We do this first so that:
- // we're returning the same address for the function as any
- // previous call.
- //
- // TODO(llvm.org): Yes, this is wrong. The lazy stub isn't
- // guaranteed to be close enough to call.
- return FnStub;
-
- // If we know the target can handle arbitrary-distance calls, try to
- // return a direct pointer.
- if (!MayNeedFarStub) {
- //
- // x86_64 architecture may encounter the bug:
- // http://llvm.org/bugs/show_bug.cgi?id=5201
- // which generate instruction "call" instead of "callq".
- //
- // And once the real address of stub is greater than 64-bit
- // long, the replacement will truncate to 32-bit resulting a
- // serious problem.
-#if !defined(__x86_64__)
- // If this is an external function pointer, we can force the JIT
- // to 'compile' it, which really just adds it to the map.
- if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
- return GetPointerToFunction(F, /* AbortOnFailure = */false);
- // Changing to false because wanting to allow later calls to
- // mpTJI->relocate() without aborting. For caching purpose
- }
-#endif
- }
-
- // Otherwise, we may need a to emit a stub, and, conservatively, we
- // always do so.
- return GetLazyFunctionStub(F);
- break;
- }
- case llvm::Value::GlobalVariableVal: {
- return GetOrEmitGlobalVariable((llvm::GlobalVariable*) V);
- break;
- }
- case llvm::Value::GlobalAliasVal: {
- llvm::GlobalAlias *GA = (llvm::GlobalAlias*) V;
- const llvm::GlobalValue *GV = GA->resolveAliasedGlobal(false);
-
- switch (GV->getValueID()) {
- case llvm::Value::FunctionVal: {
- // TODO(all): is there's any possibility that the function is not
- // code-gen'd?
- return GetPointerToFunction(
- static_cast<const llvm::Function*>(GV),
- /* AbortOnFailure = */false);
- // Changing to false because wanting to allow later calls to
- // mpTJI->relocate() without aborting. For caching purpose
- break;
- }
- case llvm::Value::GlobalVariableVal: {
- if (void *P = mGlobalAddressMap[GV])
- return P;
-
- llvm::GlobalVariable *GVar = (llvm::GlobalVariable*) GV;
- EmitGlobalVariable(GVar);
-
- return mGlobalAddressMap[GV];
- break;
- }
- case llvm::Value::GlobalAliasVal: {
- bccAssert(false && "Alias should be resolved ultimately!");
- }
- }
- break;
- }
- default: {
- break;
- }
- }
- llvm_unreachable("Unknown type of global value!");
-}
-
-
-// If the specified function has been code-gen'd, return a pointer to the
-// function. If not, compile it, or use a stub to implement lazy compilation
-// if available.
-void *CodeEmitter::GetPointerToFunctionOrStub(llvm::Function *F) {
- // If we have already code generated the function, just return the
- // address.
- if (void *Addr = GetPointerToGlobalIfAvailable(F))
- return Addr;
-
- // Get a stub if the target supports it.
- return GetLazyFunctionStub(F);
-}
-
-
-void *CodeEmitter::GetLazyFunctionStub(llvm::Function *F) {
- // If we already have a lazy stub for this function, recycle it.
- void *&Stub = mFunctionToLazyStubMap[F];
- if (Stub)
- return Stub;
-
- // In any cases, we should NOT resolve function at runtime (though we are
- // able to). We resolve this right now.
- void *Actual = NULL;
- if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
- Actual = GetPointerToFunction(F, /* AbortOnFailure = */false);
- // Changing to false because wanting to allow later calls to
- // mpTJI->relocate() without aborting. For caching purpose
- }
-
- // Codegen a new stub, calling the actual address of the external
- // function, if it was resolved.
- llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
- startGVStub(F, SL.Size, SL.Alignment);
- Stub = mpTJI->emitFunctionStub(F, Actual, *this);
- finishGVStub();
-
- // We really want the address of the stub in the GlobalAddressMap for the
- // JIT, not the address of the external function.
- UpdateGlobalMapping(F, Stub);
-
- if (!Actual) {
- PendingFunctions.insert(F);
- } else {
-#if DEBUG_OLD_JIT_DISASSEMBLER
- Disassemble(DEBUG_OLD_JIT_DISASSEMBLER_FILE,
- mpTarget, mpTargetMachine, F->getName(),
- (unsigned char const *)Stub, SL.Size);
-#endif
- }
-
- return Stub;
-}
-
-
-void *CodeEmitter::GetPointerToFunction(const llvm::Function *F,
- bool AbortOnFailure) {
- void *Addr = GetPointerToGlobalIfAvailable(F);
- if (Addr)
- return Addr;
-
- bccAssert((F->isDeclaration() || F->hasAvailableExternallyLinkage()) &&
- "Internal error: only external defined function routes here!");
-
- // Handle the failure resolution by ourselves.
- Addr = GetPointerToNamedSymbol(F->getName().str().c_str(),
- /* AbortOnFailure = */ false);
-
- // If we resolved the symbol to a null address (eg. a weak external)
- // return a null pointer let the application handle it.
- if (Addr == NULL) {
- if (AbortOnFailure)
- llvm::report_fatal_error("Could not resolve external function "
- "address: " + F->getName());
- else
- return NULL;
- }
-
- AddGlobalMapping(F, Addr);
-
- return Addr;
-}
-
-
-void *CodeEmitter::GetPointerToNamedSymbol(const std::string &Name,
- bool AbortOnFailure) {
- if (void *Addr = FindRuntimeFunction(Name.c_str()))
- return Addr;
-
- if (mpSymbolLookupFn)
- if (void *Addr = mpSymbolLookupFn(mpSymbolLookupContext, Name.c_str()))
- return Addr;
-
- if (AbortOnFailure)
- llvm::report_fatal_error("Program used external symbol '" + Name +
- "' which could not be resolved!");
-
- return NULL;
-}
-
-
-// Return the address of the specified global variable, possibly emitting it
-// to memory if needed. This is used by the Emitter.
-void *CodeEmitter::GetOrEmitGlobalVariable(llvm::GlobalVariable *GV) {
- void *Ptr = GetPointerToGlobalIfAvailable(GV);
- if (Ptr)
- return Ptr;
-
- if (GV->isDeclaration() || GV->hasAvailableExternallyLinkage()) {
- // If the global is external, just remember the address.
- Ptr = GetPointerToNamedSymbol(GV->getName().str(), true);
- AddGlobalMapping(GV, Ptr);
- } else {
- // If the global hasn't been emitted to memory yet, allocate space and
- // emit it into memory.
- Ptr = GetMemoryForGV(GV);
- AddGlobalMapping(GV, Ptr);
- EmitGlobalVariable(GV);
- }
-
- return Ptr;
-}
-
-
-// This method abstracts memory allocation of global variable so that the
-// JIT can allocate thread local variables depending on the target.
-void *CodeEmitter::GetMemoryForGV(llvm::GlobalVariable *GV) {
- void *Ptr;
-
- llvm::Type *GlobalType = GV->getType()->getElementType();
- size_t S = mpTD->getTypeAllocSize(GlobalType);
- size_t A = mpTD->getPreferredAlignment(GV);
-
- if (GV->isThreadLocal()) {
- // We can support TLS by
- //
- // Ptr = TJI.allocateThreadLocalMemory(S);
- //
- // But I tend not to.
- // (should we disable this in the front-end (i.e., slang)?).
- llvm::report_fatal_error
- ("Compilation of Thread Local Storage (TLS) is disabled!");
-
- } else if (mpTJI->allocateSeparateGVMemory()) {
- if (A <= 8) {
- Ptr = malloc(S);
- } else {
- // Allocate (S + A) bytes of memory, then use an aligned pointer
- // within that space.
- Ptr = malloc(S + A);
- unsigned int MisAligned = ((intptr_t) Ptr & (A - 1));
- Ptr = reinterpret_cast<uint8_t*>(Ptr) +
- (MisAligned ? (A - MisAligned) : 0);
- }
- } else {
- Ptr = allocateGlobal(S, A);
- }
-
- return Ptr;
-}
-
-
-void CodeEmitter::EmitGlobalVariable(llvm::GlobalVariable *GV) {
- void *GA = GetPointerToGlobalIfAvailable(GV);
-
- if (GV->isThreadLocal())
- llvm::report_fatal_error
- ("We don't support Thread Local Storage (TLS)!");
-
- if (GA == NULL) {
- // If it's not already specified, allocate memory for the global.
- GA = GetMemoryForGV(GV);
- AddGlobalMapping(GV, GA);
- }
-
- InitializeConstantToMemory(GV->getInitializer(), GA);
-
- // You can do some statistics on global variable here.
- return;
-}
-
-
-void *CodeEmitter::GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference) {
- // Make sure GV is emitted first, and create a stub containing the fully
- // resolved address.
- void *GVAddress = GetPointerToGlobal(V, Reference, false);
-
- // If we already have a stub for this global variable, recycle it.
- void *&IndirectSym = GlobalToIndirectSymMap[V];
- // Otherwise, codegen a new indirect symbol.
- if (!IndirectSym)
- IndirectSym = mpTJI->emitGlobalValueIndirectSym(V, GVAddress, *this);
-
- return IndirectSym;
-}
-
-
-// Return a stub for the function at the specified address.
-void *CodeEmitter::GetExternalFunctionStub(void *FnAddr) {
- void *&Stub = ExternalFnToStubMap[FnAddr];
- if (Stub)
- return Stub;
-
- llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
- startGVStub(0, SL.Size, SL.Alignment);
- Stub = mpTJI->emitFunctionStub(0, FnAddr, *this);
- finishGVStub();
-
- return Stub;
-}
-
-
-void CodeEmitter::setTargetMachine(llvm::TargetMachine &TM) {
- mpTargetMachine = &TM;
-
- // Set Target
- mpTarget = &TM.getTarget();
- // Set TargetJITInfo
- mpTJI = TM.getJITInfo();
- // set TargetData
- mpTD = TM.getTargetData();
-
- bccAssert(!mpTJI->needsGOT() && "We don't support GOT needed target!");
-
- return;
-}
-
-
-// This callback is invoked when the specified function is about to be code
-// generated. This initializes the BufferBegin/End/Ptr fields.
-void CodeEmitter::startFunction(llvm::MachineFunction &F) {
- uintptr_t ActualSize = 0;
-
- mpMemMgr->setMemoryWritable();
-
- // BufferBegin, BufferEnd and CurBufferPtr are all inherited from class
- // MachineCodeEmitter, which is the super class of the class
- // JITCodeEmitter.
- //
- // BufferBegin/BufferEnd - Pointers to the start and end of the memory
- // allocated for this code buffer.
- //
- // CurBufferPtr - Pointer to the next byte of memory to fill when emitting
- // code. This is guranteed to be in the range
- // [BufferBegin, BufferEnd]. If this pointer is at
- // BufferEnd, it will never move due to code emission, and
- // all code emission requests will be ignored (this is the
- // buffer overflow condition).
- BufferBegin = CurBufferPtr =
- mpMemMgr->startFunctionBody(F.getFunction(), ActualSize);
- BufferEnd = BufferBegin + ActualSize;
-
- if (mpCurEmitFunction == NULL) {
- mpCurEmitFunction = new FuncInfo(); // TODO(all): Allocation check!
- mpCurEmitFunction->name = NULL;
- mpCurEmitFunction->addr = NULL;
- mpCurEmitFunction->size = 0;
- }
-
- // Ensure the constant pool/jump table info is at least 4-byte aligned.
- emitAlignment(16);
-
- emitConstantPool(F.getConstantPool());
- if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
- initJumpTableInfo(MJTI);
-
- // About to start emitting the machine code for the function.
- emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
-
- UpdateGlobalMapping(F.getFunction(), CurBufferPtr);
-
- mpCurEmitFunction->addr = CurBufferPtr;
-
- mMBBLocations.clear();
-}
-
-
-// This callback is invoked when the specified function has finished code
-// generation. If a buffer overflow has occurred, this method returns true
-// (the callee is required to try again).
-bool CodeEmitter::finishFunction(llvm::MachineFunction &F) {
- if (CurBufferPtr == BufferEnd) {
- // No enough memory
- mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
- return false;
- }
-
- if (llvm::MachineJumpTableInfo *MJTI = F.getJumpTableInfo())
- emitJumpTableInfo(MJTI);
-
- if (!mRelocations.empty()) {
- //ptrdiff_t BufferOffset = BufferBegin - mpMemMgr->getCodeMemBase();
-
- // Resolve the relocations to concrete pointers.
- for (int i = 0, e = mRelocations.size(); i != e; i++) {
- llvm::MachineRelocation &MR = mRelocations[i];
- void *ResultPtr = NULL;
-
- if (!MR.letTargetResolve()) {
- if (MR.isExternalSymbol()) {
- ResultPtr = GetPointerToNamedSymbol(MR.getExternalSymbol(), true);
-
- if (MR.mayNeedFarStub()) {
- ResultPtr = GetExternalFunctionStub(ResultPtr);
- }
-
- } else if (MR.isGlobalValue()) {
- ResultPtr = GetPointerToGlobal(MR.getGlobalValue(),
- BufferBegin
- + MR.getMachineCodeOffset(),
- MR.mayNeedFarStub());
- } else if (MR.isIndirectSymbol()) {
- ResultPtr =
- GetPointerToGVIndirectSym(
- MR.getGlobalValue(),
- BufferBegin + MR.getMachineCodeOffset());
- } else if (MR.isBasicBlock()) {
- ResultPtr =
- (void*) getMachineBasicBlockAddress(MR.getBasicBlock());
- } else if (MR.isConstantPoolIndex()) {
- ResultPtr =
- (void*) getConstantPoolEntryAddress(MR.getConstantPoolIndex());
- } else {
- bccAssert(MR.isJumpTableIndex() && "Unknown type of relocation");
- ResultPtr =
- (void*) getJumpTableEntryAddress(MR.getJumpTableIndex());
- }
-
- if (!MR.isExternalSymbol() || MR.mayNeedFarStub()) {
- // TODO(logan): Cache external symbol relocation entry.
- // Currently, we are not caching them. But since Android
- // system is using prelink, it is not a problem.
-#if 0
- // Cache the relocation result address
- mCachingRelocations.push_back(
- oBCCRelocEntry(MR.getRelocationType(),
- MR.getMachineCodeOffset() + BufferOffset,
- ResultPtr));
-#endif
- }
-
- MR.setResultPointer(ResultPtr);
- }
- }
-
- mpTJI->relocate(BufferBegin, &mRelocations[0], mRelocations.size(),
- mpMemMgr->getGOTBase());
- }
-
- mpMemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
- // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
- // global variables that were referenced in the relocations.
- if (CurBufferPtr == BufferEnd)
- return false;
-
- // Now that we've succeeded in emitting the function.
- mpCurEmitFunction->size = CurBufferPtr - BufferBegin;
-
-#if DEBUG_OLD_JIT_DISASSEMBLER
- // FnStart is the start of the text, not the start of the constant pool
- // and other per-function data.
- uint8_t *FnStart =
- reinterpret_cast<uint8_t*>(
- GetPointerToGlobalIfAvailable(F.getFunction()));
-
- // FnEnd is the end of the function's machine code.
- uint8_t *FnEnd = CurBufferPtr;
-#endif
-
- BufferBegin = CurBufferPtr = 0;
-
- if (F.getFunction()->hasName()) {
- std::string const &name = F.getFunction()->getNameStr();
- mpResult->mEmittedFunctions[name] = mpCurEmitFunction;
- mpCurEmitFunction = NULL;
- }
-
- mRelocations.clear();
- mConstPoolAddresses.clear();
-
- if (mpMMI)
- mpMMI->EndFunction();
-
- updateFunctionStub(F.getFunction());
-
- // Mark code region readable and executable if it's not so already.
- mpMemMgr->setMemoryExecutable();
-
-#if DEBUG_OLD_JIT_DISASSEMBLER
- Disassemble(DEBUG_OLD_JIT_DISASSEMBLER_FILE,
- mpTarget, mpTargetMachine, F.getFunction()->getName(),
- (unsigned char const *)FnStart, FnEnd - FnStart);
-#endif
-
- return false;
-}
-
-
-void CodeEmitter::startGVStub(const llvm::GlobalValue *GV, unsigned StubSize,
- unsigned Alignment) {
- mpSavedBufferBegin = BufferBegin;
- mpSavedBufferEnd = BufferEnd;
- mpSavedCurBufferPtr = CurBufferPtr;
-
- BufferBegin = CurBufferPtr = mpMemMgr->allocateStub(GV, StubSize,
- Alignment);
- BufferEnd = BufferBegin + StubSize + 1;
-
- return;
-}
-
-
-void CodeEmitter::startGVStub(void *Buffer, unsigned StubSize) {
- mpSavedBufferBegin = BufferBegin;
- mpSavedBufferEnd = BufferEnd;
- mpSavedCurBufferPtr = CurBufferPtr;
-
- BufferBegin = CurBufferPtr = reinterpret_cast<uint8_t *>(Buffer);
- BufferEnd = BufferBegin + StubSize + 1;
-
- return;
-}
-
-
-void CodeEmitter::finishGVStub() {
- bccAssert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space.");
-
- // restore
- BufferBegin = mpSavedBufferBegin;
- BufferEnd = mpSavedBufferEnd;
- CurBufferPtr = mpSavedCurBufferPtr;
-}
-
-
-// Allocates and fills storage for an indirect GlobalValue, and returns the
-// address.
-void *CodeEmitter::allocIndirectGV(const llvm::GlobalValue *GV,
- const uint8_t *Buffer, size_t Size,
- unsigned Alignment) {
- uint8_t *IndGV = mpMemMgr->allocateStub(GV, Size, Alignment);
- memcpy(IndGV, Buffer, Size);
- return IndGV;
-}
-
-
-// Allocate memory for a global. Unlike allocateSpace, this method does not
-// allocate memory in the current output buffer, because a global may live
-// longer than the current function.
-void *CodeEmitter::allocateGlobal(uintptr_t Size, unsigned Alignment) {
- // Delegate this call through the memory manager.
- return mpMemMgr->allocateGlobal(Size, Alignment);
-}
-
-
-// This should be called by the target when a new basic block is about to be
-// emitted. This way the MCE knows where the start of the block is, and can
-// implement getMachineBasicBlockAddress.
-void CodeEmitter::StartMachineBasicBlock(llvm::MachineBasicBlock *MBB) {
- if (mMBBLocations.size() <= (unsigned) MBB->getNumber())
- mMBBLocations.resize((MBB->getNumber() + 1) * 2);
- mMBBLocations[MBB->getNumber()] = getCurrentPCValue();
- return;
-}
-
-
-// Return the address of the jump table with index @Index in the function
-// that last called initJumpTableInfo.
-uintptr_t CodeEmitter::getJumpTableEntryAddress(unsigned Index) const {
- const std::vector<llvm::MachineJumpTableEntry> &JT =
- mpJumpTable->getJumpTables();
-
- bccAssert((Index < JT.size()) && "Invalid jump table index!");
-
- unsigned int Offset = 0;
- unsigned int EntrySize = mpJumpTable->getEntrySize(*mpTD);
-
- for (unsigned i = 0; i < Index; i++)
- Offset += JT[i].MBBs.size();
- Offset *= EntrySize;
-
- return (uintptr_t)(reinterpret_cast<uint8_t*>(mpJumpTableBase) + Offset);
-}
-
-
-// Return the address of the specified MachineBasicBlock, only usable after
-// the label for the MBB has been emitted.
-uintptr_t CodeEmitter::getMachineBasicBlockAddress(
- llvm::MachineBasicBlock *MBB) const {
- bccAssert(mMBBLocations.size() > (unsigned) MBB->getNumber() &&
- mMBBLocations[MBB->getNumber()] &&
- "MBB not emitted!");
- return mMBBLocations[MBB->getNumber()];
-}
-
-
-void CodeEmitter::updateFunctionStub(const llvm::Function *F) {
- // Get the empty stub we generated earlier.
- void *Stub;
- std::set<const llvm::Function*>::iterator I = PendingFunctions.find(F);
- if (I != PendingFunctions.end())
- Stub = mFunctionToLazyStubMap[F];
- else
- return;
-
- void *Addr = GetPointerToGlobalIfAvailable(F);
-
- bccAssert(Addr != Stub &&
- "Function must have non-stub address to be updated.");
-
- // Tell the target jit info to rewrite the stub at the specified address,
- // rather than creating a new one.
- llvm::TargetJITInfo::StubLayout SL = mpTJI->getStubLayout();
- startGVStub(Stub, SL.Size);
- mpTJI->emitFunctionStub(F, Addr, *this);
- finishGVStub();
-
-#if DEBUG_OLD_JIT_DISASSEMBLER
- Disassemble(DEBUG_OLD_JIT_DISASSEMBLER_FILE,
- mpTarget, mpTargetMachine, F->getName(),
- (unsigned char const *)Stub, SL.Size);
-#endif
-
- PendingFunctions.erase(I);
-}
-
-
-} // namespace bcc
diff --git a/lib/CodeGen/CodeEmitter.h b/lib/CodeGen/CodeEmitter.h
deleted file mode 100644
index fc6dab1..0000000
--- a/lib/CodeGen/CodeEmitter.h
+++ /dev/null
@@ -1,339 +0,0 @@
-//===-- CodeEmitter.h - CodeEmitter Class -----------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See external/llvm/LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CodeEmitter class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef BCC_CODEEMITTER_H
-#define BCC_CODEEMITTER_H
-
-#include <bcc/bcc.h>
-#include <bcc/bcc_assert.h>
-#include <bcc/bcc_cache.h>
-#include "ExecutionEngine/bcc_internal.h"
-
-#include "Config.h"
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/CodeGen/MachineConstantPool.h"
-#include "llvm/CodeGen/MachineRelocation.h"
-#include "llvm/CodeGen/JITCodeEmitter.h"
-#include "llvm/Support/ValueHandle.h"
-
-#include <map>
-#include <vector>
-#include <set>
-
-#include <stdint.h>
-
-namespace llvm {
- class Constant;
- class GenericValue;
- class GlobalVariable;
- class GlobalValue;
- class Function;
- class MachineBasicBlock;
- class MachineFunction;
- class MachineJumpTableInfo;
- class MachineModuleInfo;
- class MCSymbol;
- class Target;
- class TargetData;
- class TargetJITInfo;
- class TargetMachine;
- class Type;
-}
-
-namespace bcc {
- class CodeMemoryManager;
- class ScriptCompiled;
-
- class CodeEmitter : public llvm::JITCodeEmitter {
- private:
- typedef llvm::DenseMap<const llvm::GlobalValue *, void *>
- GlobalAddressMapTy;
-
- typedef llvm::DenseMap<const llvm::Function *, void*>
- FunctionToLazyStubMapTy;
-
- typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void *>
- GlobalToIndirectSymMapTy;
-
- public:
- typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
-
-
- private:
- ScriptCompiled *mpResult;
-
- CodeMemoryManager *mpMemMgr;
-
- llvm::TargetMachine *mpTargetMachine;
-
- // The JITInfo for the target we are compiling to
- const llvm::Target *mpTarget;
-
- llvm::TargetJITInfo *mpTJI;
-
- const llvm::TargetData *mpTD;
-
-
- FuncInfo *mpCurEmitFunction;
-
- GlobalAddressMapTy mGlobalAddressMap;
-
- // This vector is a mapping from MBB ID's to their address. It is filled in
- // by the StartMachineBasicBlock callback and queried by the
- // getMachineBasicBlockAddress callback.
- std::vector<uintptr_t> mMBBLocations;
-
- // The constant pool for the current function.
- llvm::MachineConstantPool *mpConstantPool;
-
- // A pointer to the first entry in the constant pool.
- void *mpConstantPoolBase;
-
- // Addresses of individual constant pool entries.
- llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
-
- // The jump tables for the current function.
- llvm::MachineJumpTableInfo *mpJumpTable;
-
- // A pointer to the first entry in the jump table.
- void *mpJumpTableBase;
-
- // When outputting a function stub in the context of some other function, we
- // save BufferBegin/BufferEnd/CurBufferPtr here.
- uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
-
- // These are the relocations that the function needs, as emitted.
- std::vector<llvm::MachineRelocation> mRelocations;
-
-#if 0
- std::vector<oBCCRelocEntry> mCachingRelocations;
-#endif
-
- // This vector is a mapping from Label ID's to their address.
- llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
-
- // Machine module info for exception informations
- llvm::MachineModuleInfo *mpMMI;
-
-
- FunctionToLazyStubMapTy mFunctionToLazyStubMap;
-
- std::set<const llvm::Function*> PendingFunctions;
-
- GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
-
- std::map<void*, void*> ExternalFnToStubMap;
-
- public:
- // Resolver to undefined symbol in CodeEmitter
- BCCSymbolLookupFn mpSymbolLookupFn;
- void *mpSymbolLookupContext;
-
- // Will take the ownership of @MemMgr
- explicit CodeEmitter(ScriptCompiled *result, CodeMemoryManager *pMemMgr);
-
- virtual ~CodeEmitter();
-
- global_addresses_const_iterator global_address_begin() const {
- return mGlobalAddressMap.begin();
- }
-
- global_addresses_const_iterator global_address_end() const {
- return mGlobalAddressMap.end();
- }
-
-#if 0
- std::vector<oBCCRelocEntry> const &getCachingRelocations() const {
- return mCachingRelocations;
- }
-#endif
-
- void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
- mpSymbolLookupFn = pFn;
- mpSymbolLookupContext = pContext;
- }
-
- void setTargetMachine(llvm::TargetMachine &TM);
-
- // This callback is invoked when the specified function is about to be code
- // generated. This initializes the BufferBegin/End/Ptr fields.
- virtual void startFunction(llvm::MachineFunction &F);
-
- // This callback is invoked when the specified function has finished code
- // generation. If a buffer overflow has occurred, this method returns true
- // (the callee is required to try again).
- virtual bool finishFunction(llvm::MachineFunction &F);
-
- // Allocates and fills storage for an indirect GlobalValue, and returns the
- // address.
- virtual void *allocIndirectGV(const llvm::GlobalValue *GV,
- const uint8_t *Buffer, size_t Size,
- unsigned Alignment);
-
- // Emits a label
- virtual void emitLabel(llvm::MCSymbol *Label) {
- mLabelLocations[Label] = getCurrentPCValue();
- }
-
- // Allocate memory for a global. Unlike allocateSpace, this method does not
- // allocate memory in the current output buffer, because a global may live
- // longer than the current function.
- virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment);
-
- // This should be called by the target when a new basic block is about to be
- // emitted. This way the MCE knows where the start of the block is, and can
- // implement getMachineBasicBlockAddress.
- virtual void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB);
-
- // Whenever a relocatable address is needed, it should be noted with this
- // interface.
- virtual void addRelocation(const llvm::MachineRelocation &MR) {
- mRelocations.push_back(MR);
- }
-
- // Return the address of the @Index entry in the constant pool that was
- // last emitted with the emitConstantPool method.
- virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
- bccAssert(Index < mpConstantPool->getConstants().size() &&
- "Invalid constant pool index!");
- return mConstPoolAddresses[Index];
- }
-
- // Return the address of the jump table with index @Index in the function
- // that last called initJumpTableInfo.
- virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const;
-
- // Return the address of the specified MachineBasicBlock, only usable after
- // the label for the MBB has been emitted.
- virtual uintptr_t getMachineBasicBlockAddress(
- llvm::MachineBasicBlock *MBB) const;
-
- // Return the address of the specified LabelID, only usable after the
- // LabelID has been emitted.
- virtual uintptr_t getLabelAddress(llvm::MCSymbol *Label) const {
- bccAssert(mLabelLocations.count(Label) && "Label not emitted!");
- return mLabelLocations.find(Label)->second;
- }
-
- // Specifies the MachineModuleInfo object. This is used for exception
- // handling purposes.
- virtual void setModuleInfo(llvm::MachineModuleInfo *Info) {
- mpMMI = Info;
- }
-
- void releaseUnnecessary();
-
- void reset();
-
- private:
- void startGVStub(const llvm::GlobalValue *GV, unsigned StubSize,
- unsigned Alignment);
-
- void startGVStub(void *Buffer, unsigned StubSize);
-
- void finishGVStub();
-
- // Replace an existing mapping for GV with a new address. This updates both
- // maps as required. If Addr is null, the entry for the global is removed
- // from the mappings.
- void *UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr);
-
- // Tell the execution engine that the specified global is at the specified
- // location. This is used internally as functions are JIT'd and as global
- // variables are laid out in memory.
- void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
- void *&CurVal = mGlobalAddressMap[GV];
- assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
- CurVal = Addr;
- }
-
- // This returns the address of the specified global value if it is has
- // already been codegen'd, otherwise it returns null.
- void *GetPointerToGlobalIfAvailable(const llvm::GlobalValue *GV) {
- GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
- return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
- }
-
- unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool *MCP);
-
- // This function converts a Constant* into a GenericValue. The interesting
- // part is if C is a ConstantExpr.
- void GetConstantValue(const llvm::Constant *C, llvm::GenericValue &Result);
-
- // Stores the data in @Val of type @Ty at address @Addr.
- void StoreValueToMemory(const llvm::GenericValue &Val, void *Addr,
- llvm::Type *Ty);
-
- // Recursive function to apply a @Constant value into the specified memory
- // location @Addr.
- void InitializeConstantToMemory(const llvm::Constant *C, void *Addr);
-
- void emitConstantPool(llvm::MachineConstantPool *MCP);
-
- void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI);
-
- void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI);
-
- void *GetPointerToGlobal(llvm::GlobalValue *V,
- void *Reference,
- bool MayNeedFarStub);
-
- // If the specified function has been code-gen'd, return a pointer to the
- // function. If not, compile it, or use a stub to implement lazy compilation
- // if available.
- void *GetPointerToFunctionOrStub(llvm::Function *F);
-
- void *GetLazyFunctionStubIfAvailable(llvm::Function *F) {
- return mFunctionToLazyStubMap.lookup(F);
- }
-
- void *GetLazyFunctionStub(llvm::Function *F);
-
- void updateFunctionStub(const llvm::Function *F);
-
- void *GetPointerToFunction(const llvm::Function *F, bool AbortOnFailure);
-
- void *GetPointerToNamedSymbol(const std::string &Name,
- bool AbortOnFailure);
-
- // Return the address of the specified global variable, possibly emitting it
- // to memory if needed. This is used by the Emitter.
- void *GetOrEmitGlobalVariable(llvm::GlobalVariable *GV);
-
- // This method abstracts memory allocation of global variable so that the
- // JIT can allocate thread local variables depending on the target.
- void *GetMemoryForGV(llvm::GlobalVariable *GV);
-
- void EmitGlobalVariable(llvm::GlobalVariable *GV);
-
- void *GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference);
-
- // This is the equivalent of FunctionToLazyStubMap for external functions.
- //
- // TODO(llvm.org): Of course, external functions don't need a lazy stub.
- // It's actually here to make it more likely that far calls
- // succeed, but no single stub can guarantee that. I'll
- // remove this in a subsequent checkin when I actually fix
- // far calls.
-
- // Return a stub for the function at the specified address.
- void *GetExternalFunctionStub(void *FnAddr);
-
- };
-
-} // namespace bcc
-
-#endif // BCC_CODEEMITTER_H
diff --git a/lib/CodeGen/CodeMemoryManager.cpp b/lib/CodeGen/CodeMemoryManager.cpp
deleted file mode 100644
index 5f015cc..0000000
--- a/lib/CodeGen/CodeMemoryManager.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-//===-- CodeMemoryManager.cpp - CodeMemoryManager Class -------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See external/llvm/LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CodeMemoryManager class.
-//
-//===----------------------------------------------------------------------===//
-
-#define LOG_TAG "bcc"
-#include <bcc/bcc_assert.h>
-
-#include <cutils/log.h>
-
-#include "CodeMemoryManager.h"
-#include "ExecutionEngine/OldJIT/ContextManager.h"
-
-#include "llvm/Support/ErrorHandling.h"
-
-#include <sys/mman.h>
-
-#include <stddef.h>
-
-#include <map>
-#include <string>
-#include <utility>
-
-
-namespace bcc {
-
-
-const unsigned int MaxCodeSize = ContextManager::ContextCodeSize;
-const unsigned int MaxGOTSize = 1 * 1024;
-const unsigned int MaxGlobalVarSize = ContextManager::ContextDataSize;
-
-
-CodeMemoryManager::CodeMemoryManager()
- : mpCodeMem(NULL), mpGVMem(NULL), mpGOTBase(NULL) {
-
- reset();
- std::string ErrMsg;
-
- mpCodeMem = ContextManager::get().allocateContext();
-
- if (!mpCodeMem) {
- ALOGE("Unable to allocate mpCodeMem\n");
- llvm::report_fatal_error("Failed to allocate memory for emitting "
- "codes\n" + ErrMsg);
- }
-
- // Set global variable pool
- mpGVMem = mpCodeMem + MaxCodeSize;
-
- return;
-}
-
-
-CodeMemoryManager::~CodeMemoryManager() {
- mpCodeMem = 0;
- mpGVMem = 0;
-}
-
-
-uint8_t *CodeMemoryManager::allocateSGMemory(uintptr_t Size,
- unsigned Alignment) {
-
- intptr_t FreeMemSize = getFreeCodeMemSize();
- if ((FreeMemSize < 0) || (static_cast<uintptr_t>(FreeMemSize) < Size))
- // The code size excesses our limit
- return NULL;
-
- if (Alignment == 0)
- Alignment = 1;
-
- uint8_t *result = getCodeMemBase() + mCurSGMemIdx - Size;
- result = (uint8_t*) (((intptr_t) result) & ~(intptr_t) (Alignment - 1));
-
- mCurSGMemIdx = result - getCodeMemBase();
-
- return result;
-}
-
-
-// setMemoryWritable - When code generation is in progress, the code pages
-// may need permissions changed.
-void CodeMemoryManager::setMemoryWritable() {
- mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_WRITE | PROT_EXEC);
-}
-
-
-// When code generation is done and we're ready to start execution, the
-// code pages may need permissions changed.
-void CodeMemoryManager::setMemoryExecutable() {
- mprotect(mpCodeMem, MaxCodeSize, PROT_READ | PROT_EXEC);
-}
-
-
-// Setting this flag to true makes the memory manager garbage values over
-// freed memory. This is useful for testing and debugging, and is to be
-// turned on by default in debug mode.
-void CodeMemoryManager::setPoisonMemory(bool poison) {
- // no effect
-}
-
-
-// Global Offset Table Management
-
-// If the current table requires a Global Offset Table, this method is
-// invoked to allocate it. This method is required to set HasGOT to true.
-void CodeMemoryManager::AllocateGOT() {
- bccAssert(mpGOTBase != NULL && "Cannot allocate the GOT multiple times");
- mpGOTBase = allocateSGMemory(MaxGOTSize);
- HasGOT = true;
-}
-
-
-// Main Allocation Functions
-
-// When we start JITing a function, the JIT calls this method to allocate a
-// block of free RWX memory, which returns a pointer to it. If the JIT wants
-// to request a block of memory of at least a certain size, it passes that
-// value as ActualSize, and this method returns a block with at least that
-// much space. If the JIT doesn't know ahead of time how much space it will
-// need to emit the function, it passes 0 for the ActualSize. In either
-// case, this method is required to pass back the size of the allocated
-// block through ActualSize. The JIT will be careful to not write more than
-// the returned ActualSize bytes of memory.
-uint8_t *CodeMemoryManager::startFunctionBody(const llvm::Function *F,
- uintptr_t &ActualSize) {
- intptr_t FreeMemSize = getFreeCodeMemSize();
- if ((FreeMemSize < 0) ||
- (static_cast<uintptr_t>(FreeMemSize) < ActualSize))
- // The code size excesses our limit
- return NULL;
-
- ActualSize = getFreeCodeMemSize();
- return (getCodeMemBase() + mCurFuncMemIdx);
-}
-
-// This method is called when the JIT is done codegen'ing the specified
-// function. At this point we know the size of the JIT compiled function.
-// This passes in FunctionStart (which was returned by the startFunctionBody
-// method) and FunctionEnd which is a pointer to the actual end of the
-// function. This method should mark the space allocated and remember where
-// it is in case the client wants to deallocate it.
-void CodeMemoryManager::endFunctionBody(const llvm::Function *F,
- uint8_t *FunctionStart,
- uint8_t *FunctionEnd) {
- bccAssert(FunctionEnd > FunctionStart);
- bccAssert(FunctionStart == (getCodeMemBase() + mCurFuncMemIdx) &&
- "Mismatched function start/end!");
-
- // Advance the pointer
- intptr_t FunctionCodeSize = FunctionEnd - FunctionStart;
- bccAssert(FunctionCodeSize <= getFreeCodeMemSize() &&
- "Code size excess the limitation!");
- mCurFuncMemIdx += FunctionCodeSize;
-
- // Record there's a function in our memory start from @FunctionStart
- bccAssert(mFunctionMap.find(F) == mFunctionMap.end() &&
- "Function already emitted!");
- mFunctionMap.insert(
- std::make_pair<const llvm::Function*, std::pair<void*, void*> >(
- F, std::make_pair(FunctionStart, FunctionEnd)));
-
- return;
-}
-
-// Allocate a (function code) memory block of the given size. This method
-// cannot be called between calls to startFunctionBody and endFunctionBody.
-uint8_t *CodeMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) {
- if (getFreeCodeMemSize() < Size) {
- // The code size excesses our limit
- return NULL;
- }
-
- if (Alignment == 0)
- Alignment = 1;
-
- uint8_t *result = getCodeMemBase() + mCurFuncMemIdx;
- result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
- ~(intptr_t) (Alignment - 1));
-
- mCurFuncMemIdx = (result + Size) - getCodeMemBase();
-
- return result;
-}
-
-// Allocate memory for a global variable.
-uint8_t *CodeMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) {
- if (getFreeGVMemSize() < Size) {
- // The code size excesses our limit
- ALOGE("No Global Memory");
- return NULL;
- }
-
- if (Alignment == 0)
- Alignment = 1;
-
- uint8_t *result = getGVMemBase() + mCurGVMemIdx;
- result = (uint8_t*) (((intptr_t) result + Alignment - 1) &
- ~(intptr_t) (Alignment - 1));
-
- mCurGVMemIdx = (result + Size) - getGVMemBase();
-
- return result;
-}
-
-// Free the specified function body. The argument must be the return value
-// from a call to startFunctionBody() that hasn't been deallocated yet. This
-// is never called when the JIT is currently emitting a function.
-void CodeMemoryManager::deallocateFunctionBody(void *Body) {
- // linear search
- uint8_t *FunctionStart = NULL, *FunctionEnd = NULL;
- for (FunctionMapTy::iterator I = mFunctionMap.begin(),
- E = mFunctionMap.end(); I != E; I++) {
- if (I->second.first == Body) {
- FunctionStart = reinterpret_cast<uint8_t*>(I->second.first);
- FunctionEnd = reinterpret_cast<uint8_t*>(I->second.second);
- break;
- }
- }
-
- bccAssert((FunctionStart == NULL) && "Memory is never allocated!");
-
- // free the memory
- intptr_t SizeNeedMove = (getCodeMemBase() + mCurFuncMemIdx) - FunctionEnd;
-
- bccAssert(SizeNeedMove >= 0 &&
- "Internal error: CodeMemoryManager::mCurFuncMemIdx may not"
- " be correctly calculated!");
-
- if (SizeNeedMove > 0) {
- // there's data behind deallocating function
- memmove(FunctionStart, FunctionEnd, SizeNeedMove);
- }
-
- mCurFuncMemIdx -= (FunctionEnd - FunctionStart);
-}
-
-// Below are the methods we create
-void CodeMemoryManager::reset() {
- mpGOTBase = NULL;
- HasGOT = false;
-
- mCurFuncMemIdx = 0;
- mCurSGMemIdx = MaxCodeSize - 1;
- mCurGVMemIdx = 0;
-
- mFunctionMap.clear();
-}
-
-} // namespace bcc
diff --git a/lib/CodeGen/CodeMemoryManager.h b/lib/CodeGen/CodeMemoryManager.h
deleted file mode 100644
index ed003ec..0000000
--- a/lib/CodeGen/CodeMemoryManager.h
+++ /dev/null
@@ -1,246 +0,0 @@
-//===-- CodeMemoryManager.h - CodeMemoryManager Class -----------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See external/llvm/LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the CodeMemoryManager class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef BCC_CODEMEMORYMANAGER_H
-#define BCC_CODEMEMORYMANAGER_H
-
-#include "ExecutionEngine/Compiler.h"
-
-#include "llvm/ExecutionEngine/JITMemoryManager.h"
-
-#include <bcc/bcc_assert.h>
-
-#include <map>
-#include <utility>
-
-#include <stddef.h>
-#include <stdint.h>
-
-
-namespace llvm {
- // Forward Declaration
- class Function;
- class GlobalValue;
-};
-
-
-namespace bcc {
-
- //////////////////////////////////////////////////////////////////////////////
- // Memory manager for the code reside in memory
- //
- // The memory for our code emitter is very simple and is conforming to the
- // design decisions of Android RenderScript's Exection Environment:
- // The code, data, and symbol sizes are limited (currently 100KB.)
- //
- // It's very different from typical compiler, which has no limitation
- // on the code size. How does code emitter know the size of the code
- // it is about to emit? It does not know beforehand. We want to solve
- // this without complicating the code emitter too much.
- //
- // We solve this by pre-allocating a certain amount of memory,
- // and then start the code emission. Once the buffer overflows, the emitter
- // simply discards all the subsequent emission but still has a counter
- // on how many bytes have been emitted.
- //
- // So once the whole emission is done, if there's a buffer overflow,
- // it re-allocates the buffer with enough size (based on the
- // counter from previous emission) and re-emit again.
-
- extern const unsigned int MaxCodeSize;
- extern const unsigned int MaxGOTSize;
- extern const unsigned int MaxGlobalVarSize;
-
-
- class CodeMemoryManager : public llvm::JITMemoryManager {
- private:
- typedef std::map<const llvm::Function*,
- std::pair<void * /* start address */,
- void * /* end address */> > FunctionMapTy;
-
-
- private:
- //
- // Our memory layout is as follows:
- //
- // The direction of arrows (-> and <-) shows memory's growth direction
- // when more space is needed.
- //
- // @mpCodeMem:
- // +--------------------------------------------------------------+
- // | Function Memory ... -> <- ... Stub/GOT |
- // +--------------------------------------------------------------+
- // |<------------------ Total: @MaxCodeSize KiB ----------------->|
- //
- // Where size of GOT is @MaxGOTSize KiB.
- //
- // @mpGVMem:
- // +--------------------------------------------------------------+
- // | Global variable ... -> |
- // +--------------------------------------------------------------+
- // |<--------------- Total: @MaxGlobalVarSize KiB --------------->|
- //
- //
- // @mCurFuncMemIdx: The current index (starting from 0) of the last byte
- // of function code's memory usage
- // @mCurSGMemIdx: The current index (starting from tail) of the last byte
- // of stub/GOT's memory usage
- // @mCurGVMemIdx: The current index (starting from tail) of the last byte
- // of global variable's memory usage
- //
- uintptr_t mCurFuncMemIdx;
- uintptr_t mCurSGMemIdx;
- uintptr_t mCurGVMemIdx;
- char *mpCodeMem;
- char *mpGVMem;
-
- // GOT Base
- uint8_t *mpGOTBase;
-
- FunctionMapTy mFunctionMap;
-
-
- public:
- CodeMemoryManager();
-
- virtual ~CodeMemoryManager();
-
- uint8_t *getCodeMemBase() const {
- return reinterpret_cast<uint8_t*>(mpCodeMem);
- }
-
- // setMemoryWritable - When code generation is in progress, the code pages
- // may need permissions changed.
- virtual void setMemoryWritable();
-
- // When code generation is done and we're ready to start execution, the
- // code pages may need permissions changed.
- virtual void setMemoryExecutable();
-
- // Setting this flag to true makes the memory manager garbage values over
- // freed memory. This is useful for testing and debugging, and is to be
- // turned on by default in debug mode.
- virtual void setPoisonMemory(bool poison);
-
-
- // Global Offset Table Management
-
- // If the current table requires a Global Offset Table, this method is
- // invoked to allocate it. This method is required to set HasGOT to true.
- virtual void AllocateGOT();
-
- // If this is managing a Global Offset Table, this method should return a
- // pointer to its base.
- virtual uint8_t *getGOTBase() const {
- return mpGOTBase;
- }
-
- // Main Allocation Functions
-
- // When we start JITing a function, the JIT calls this method to allocate a
- // block of free RWX memory, which returns a pointer to it. If the JIT wants
- // to request a block of memory of at least a certain size, it passes that
- // value as ActualSize, and this method returns a block with at least that
- // much space. If the JIT doesn't know ahead of time how much space it will
- // need to emit the function, it passes 0 for the ActualSize. In either
- // case, this method is required to pass back the size of the allocated
- // block through ActualSize. The JIT will be careful to not write more than
- // the returned ActualSize bytes of memory.
- virtual uint8_t *startFunctionBody(const llvm::Function *F,
- uintptr_t &ActualSize);
-
- // This method is called by the JIT to allocate space for a function stub
- // (used to handle limited branch displacements) while it is JIT compiling a
- // function. For example, if foo calls bar, and if bar either needs to be
- // lazily compiled or is a native function that exists too far away from the
- // call site to work, this method will be used to make a thunk for it. The
- // stub should be "close" to the current function body, but should not be
- // included in the 'actualsize' returned by startFunctionBody.
- virtual uint8_t *allocateStub(const llvm::GlobalValue *F,
- unsigned StubSize,
- unsigned Alignment) {
- return allocateSGMemory(StubSize, Alignment);
- }
-
- // This method is called when the JIT is done codegen'ing the specified
- // function. At this point we know the size of the JIT compiled function.
- // This passes in FunctionStart (which was returned by the startFunctionBody
- // method) and FunctionEnd which is a pointer to the actual end of the
- // function. This method should mark the space allocated and remember where
- // it is in case the client wants to deallocate it.
- virtual void endFunctionBody(const llvm::Function *F,
- uint8_t *FunctionStart,
- uint8_t *FunctionEnd);
-
- // Allocate a (function code) memory block of the given size. This method
- // cannot be called between calls to startFunctionBody and endFunctionBody.
- virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
-
- // Allocate memory for a global variable.
- virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
-
- // Free the specified function body. The argument must be the return value
- // from a call to startFunctionBody() that hasn't been deallocated yet. This
- // is never called when the JIT is currently emitting a function.
- virtual void deallocateFunctionBody(void *Body);
-
- // When we finished JITing the function, if exception handling is set, we
- // emit the exception table.
- virtual uint8_t *startExceptionTable(const llvm::Function *F,
- uintptr_t &ActualSize) {
- bccAssert(false &&
- "Exception is not allowed in our language specification");
- return NULL;
- }
-
- // This method is called when the JIT is done emitting the exception table.
- virtual void endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
- uint8_t *TableEnd, uint8_t *FrameRegister) {
- bccAssert(false &&
- "Exception is not allowed in our language specification");
- }
-
- // Free the specified exception table's memory. The argument must be the
- // return value from a call to startExceptionTable() that hasn't been
- // deallocated yet. This is never called when the JIT is currently emitting
- // an exception table.
- virtual void deallocateExceptionTable(void *ET) {
- bccAssert(false &&
- "Exception is not allowed in our language specification");
- }
-
- // Below are the methods we create
- void reset();
-
-
- private:
- intptr_t getFreeCodeMemSize() const {
- return mCurSGMemIdx - mCurFuncMemIdx;
- }
-
- uint8_t *allocateSGMemory(uintptr_t Size,
- unsigned Alignment = 1 /* no alignment */);
-
- uintptr_t getFreeGVMemSize() const {
- return MaxGlobalVarSize - mCurGVMemIdx;
- }
-
- uint8_t *getGVMemBase() const {
- return reinterpret_cast<uint8_t*>(mpGVMem);
- }
-
- };
-
-} // namespace bcc
-
-#endif // BCC_CODEMEMORYMANAGER_H
diff --git a/lib/ExecutionEngine/Android.mk b/lib/ExecutionEngine/Android.mk
index 2e2a4fa..c015bcc 100644
--- a/lib/ExecutionEngine/Android.mk
+++ b/lib/ExecutionEngine/Android.mk
@@ -27,34 +27,15 @@
FileHandle.cpp \
GDBJIT.cpp \
GDBJITRegistrar.cpp \
+ MCCacheWriter.cpp \
+ MCCacheReader.cpp \
Runtime.c \
RuntimeStub.c \
Script.cpp \
- ScriptCompiled.cpp \
- SourceInfo.cpp
-
-ifeq ($(libbcc_USE_OLD_JIT),1)
-libbcc_executionengine_SRC_FILES += \
- OldJIT/ContextManager.cpp
-endif
-
-ifeq ($(libbcc_USE_CACHE),1)
-ifeq ($(libbcc_USE_OLD_JIT),1)
-libbcc_executionengine_SRC_FILES += \
- OldJIT/CacheReader.cpp \
- OldJIT/CacheWriter.cpp
-endif
-
-ifeq ($(libbcc_USE_MCJIT),1)
-libbcc_executionengine_SRC_FILES += \
- MCCacheWriter.cpp \
- MCCacheReader.cpp
-endif
-
-libbcc_executionengine_SRC_FILES += \
ScriptCached.cpp \
- Sha1Helper.cpp
-endif
+ ScriptCompiled.cpp \
+ Sha1Helper.cpp \
+ SourceInfo.cpp
#=====================================================================
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index e7bdd52..8a55e38 100644
--- a/lib/ExecutionEngine/Compiler.cpp
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -19,10 +19,6 @@
#include "Config.h"
#include <bcinfo/MetadataExtractor.h>
-#if USE_OLD_JIT
-#include "OldJIT/ContextManager.h"
-#endif
-
#if USE_DISASSEMBLER
#include "Disassembler/Disassembler.h"
#endif
@@ -34,9 +30,7 @@
#include "Sha1Helper.h"
#include "CompilerOption.h"
-#if USE_MCJIT
#include "librsloader.h"
-#endif
#include "Transforms/BCCTransforms.h"
@@ -210,12 +204,10 @@
// Register the scheduler
llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
-#if USE_CACHE
// Read in SHA1 checksum of libbcc and libRS.
readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
calcFileSHA1(sha1LibRS, pathLibRS);
-#endif
GlobalInitialized = true;
}
@@ -229,27 +221,9 @@
}
-#if USE_OLD_JIT
-CodeMemoryManager *Compiler::createCodeMemoryManager() {
- mCodeMemMgr.reset(new CodeMemoryManager());
- return mCodeMemMgr.get();
-}
-#endif
-
-
-#if USE_OLD_JIT
-CodeEmitter *Compiler::createCodeEmitter() {
- mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
- return mCodeEmitter.get();
-}
-#endif
-
-
Compiler::Compiler(ScriptCompiled *result)
: mpResult(result),
-#if USE_MCJIT
mRSExecutable(NULL),
-#endif
mpSymbolLookupFn(NULL),
mpSymbolLookupContext(NULL),
mModule(NULL),
@@ -413,14 +387,6 @@
}
// Perform code generation
-#if USE_OLD_JIT
- if (runCodeGen(new llvm::TargetData(*TD), TM,
- ExportVarMetadata, ExportFuncMetadata) != 0) {
- goto on_bcc_compile_error;
- }
-#endif
-
-#if USE_MCJIT
if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
goto on_bcc_compile_error;
}
@@ -468,7 +434,7 @@
}
}
-#if DEBUG_MCJIT_DISASSEMBLER
+#if DEBUG_MC_DISASSEMBLER
{
// Get MC codegen emitted function name list
size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
@@ -480,13 +446,12 @@
void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
if (func) {
size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
- Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
+ Disassemble(DEBUG_MC_DISASSEMBLER_FILE,
Target, TM, func_list[i], (unsigned char const *)func, size);
}
}
}
#endif
-#endif
on_bcc_compile_error:
// ALOGE("on_bcc_compiler_error");
@@ -507,133 +472,6 @@
}
-#if USE_OLD_JIT
-int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
- llvm::NamedMDNode const *ExportVarMetadata,
- llvm::NamedMDNode const *ExportFuncMetadata) {
- // Create memory manager for creation of code emitter later.
- if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
- setError("Failed to startup memory management for further compilation");
- return 1;
- }
-
- mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
-
- // Create code emitter
- if (!mCodeEmitter.get()) {
- if (!createCodeEmitter()) {
- setError("Failed to create machine code emitter for compilation");
- return 1;
- }
- } else {
- // Reuse the code emitter
- mCodeEmitter->reset();
- }
-
- mCodeEmitter->setTargetMachine(*TM);
- mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
- mpSymbolLookupContext);
-
- // Create code-gen pass to run the code emitter
- llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
- new llvm::FunctionPassManager(mModule));
-
- // Add TargetData to code generation pass manager
- CodeGenPasses->add(TD);
-
- // Add code emit passes
- if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
- *mCodeEmitter,
- CodeGenOptLevel)) {
- setError("The machine code emission is not supported on '" + Triple + "'");
- return 1;
- }
-
- // Run the code emitter on every non-declaration function in the module
- CodeGenPasses->doInitialization();
- for (llvm::Module::iterator
- I = mModule->begin(), E = mModule->end(); I != E; I++) {
- if (!I->isDeclaration()) {
- CodeGenPasses->run(*I);
- }
- }
-
- CodeGenPasses->doFinalization();
-
- // Copy the global address mapping from code emitter and remapping
- if (ExportVarMetadata) {
- ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
-
- for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
- if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
- llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
- if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportVarName =
- static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
-
- CodeEmitter::global_addresses_const_iterator I, E;
- for (I = mCodeEmitter->global_address_begin(),
- E = mCodeEmitter->global_address_end();
- I != E; I++) {
- if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
- continue;
- if (ExportVarName == I->first->getName()) {
- varList.push_back(I->second);
-#if DEBUG_BCC_REFLECT
- ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
-#endif
- break;
- }
- }
- if (I != mCodeEmitter->global_address_end())
- continue; // found
-
-#if DEBUG_BCC_REFLECT
- ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
- ExportVarName.str().c_str(), (void *)0);
-#endif
- }
- }
- // if reaching here, we know the global variable record in metadata is
- // not found. So we make an empty slot
- varList.push_back(NULL);
- }
-
- bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
- "Number of slots doesn't match the number of export variables!");
- }
-
- if (ExportFuncMetadata) {
- ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
-
- for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
- llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
- if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
- llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
- if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
- llvm::StringRef ExportFuncName =
- static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
- funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
-#if DEBUG_BCC_REFLECT
- ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
- funcList.back());
-#endif
- }
- }
- }
- }
-
- // Tell code emitter now can release the memory using during the JIT since
- // we have done the code emission
- mCodeEmitter->releaseUnnecessary();
-
- return 0;
-}
-#endif // USE_OLD_JIT
-
-
-#if USE_MCJIT
int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
// Decorate mEmittedELFExecutable with formatted ostream
llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
@@ -658,7 +496,6 @@
OutSVOS.flush();
return 0;
}
-#endif // USE_MCJIT
int Compiler::runInternalPasses(std::vector<std::string>& Names,
std::vector<uint32_t>& Signatures) {
@@ -804,14 +641,11 @@
}
-#if USE_MCJIT
void *Compiler::getSymbolAddress(char const *name) {
return rsloaderGetSymbolAddress(mRSExecutable, name);
}
-#endif
-#if USE_MCJIT
void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
Compiler *self = reinterpret_cast<Compiler *>(context);
@@ -828,13 +662,10 @@
ALOGE("Unable to resolve symbol: %s\n", name);
return NULL;
}
-#endif
Compiler::~Compiler() {
-#if USE_MCJIT
rsloaderDisposeExec(mRSExecutable);
-#endif
// llvm::llvm_shutdown();
}
diff --git a/lib/ExecutionEngine/Compiler.h b/lib/ExecutionEngine/Compiler.h
index eebe550..863cda6 100644
--- a/lib/ExecutionEngine/Compiler.h
+++ b/lib/ExecutionEngine/Compiler.h
@@ -19,12 +19,9 @@
#include <bcc/bcc.h>
-#include "CodeGen/CodeEmitter.h"
-#include "CodeGen/CodeMemoryManager.h"
+#include <Config.h>
-#if USE_MCJIT
#include "librsloader.h"
-#endif
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringRef.h"
@@ -85,21 +82,11 @@
std::string mError;
-#if USE_OLD_JIT
- // The memory manager for code emitter
- llvm::OwningPtr<CodeMemoryManager> mCodeMemMgr;
-
- // The CodeEmitter
- llvm::OwningPtr<CodeEmitter> mCodeEmitter;
-#endif
-
-#if USE_MCJIT
- // Compilation buffer for MCJIT
+ // Compilation buffer for MC
llvm::SmallVector<char, 1024> mEmittedELFExecutable;
// Loaded and relocated executable
RSExecRef mRSExecutable;
-#endif
BCCSymbolLookupFn mpSymbolLookupFn;
void *mpSymbolLookupContext;
@@ -126,19 +113,11 @@
mpSymbolLookupContext = pContext;
}
-#if USE_OLD_JIT
- CodeMemoryManager *createCodeMemoryManager();
-
- CodeEmitter *createCodeEmitter();
-#endif
-
-#if USE_MCJIT
void *getSymbolAddress(char const *name);
const llvm::SmallVector<char, 1024> &getELF() const {
return mEmittedELFExecutable;
}
-#endif
int readModule(llvm::Module *module) {
mModule = module;
@@ -167,9 +146,8 @@
int runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM);
-#if USE_MCJIT
static void *resolveSymbolAdapter(void *context, char const *name);
-#endif
+
int runInternalPasses(std::vector<std::string>& Names,
std::vector<uint32_t>& Signatures);
diff --git a/lib/ExecutionEngine/MCCacheReader.cpp b/lib/ExecutionEngine/MCCacheReader.cpp
index 5beff88..6005536 100644
--- a/lib/ExecutionEngine/MCCacheReader.cpp
+++ b/lib/ExecutionEngine/MCCacheReader.cpp
@@ -39,8 +39,6 @@
using namespace std;
-
-#if USE_MCJIT
namespace bcc {
MCCacheReader::~MCCacheReader() {
@@ -148,15 +146,15 @@
bool MCCacheReader::checkHeader() {
- if (memcmp(mpHeader->magic, OBCC_MAGIC, 4) != 0) {
+ if (memcmp(mpHeader->magic, MCO_MAGIC, 4) != 0) {
ALOGE("Bad magic word\n");
return false;
}
- if (memcmp(mpHeader->version, OBCC_VERSION, 4) != 0) {
+ if (memcmp(mpHeader->version, MCO_VERSION, 4) != 0) {
mpHeader->version[4 - 1] = '\0'; // ensure c-style string terminated
ALOGI("Cache file format version mismatch: now %s cached %s\n",
- OBCC_VERSION, mpHeader->version);
+ MCO_VERSION, mpHeader->version);
return false;
}
return true;
@@ -242,7 +240,7 @@
bool MCCacheReader::readStringPool() {
- CACHE_READER_READ_SECTION(OBCC_StringPool,
+ CACHE_READER_READ_SECTION(MCO_StringPool,
mpResult->mpStringPoolRaw, str_pool);
char *str_base = reinterpret_cast<char *>(str_pool_raw);
@@ -258,7 +256,7 @@
bool MCCacheReader::checkStringPool() {
- OBCC_StringPool *poolR = mpResult->mpStringPoolRaw;
+ MCO_StringPool *poolR = mpResult->mpStringPoolRaw;
vector<char const *> &pool = mpResult->mStringPool;
// Ensure that every c-style string is ended with '\0'
@@ -274,7 +272,7 @@
bool MCCacheReader::readDependencyTable() {
- CACHE_READER_READ_SECTION(OBCC_DependencyTable, mpCachedDependTable,
+ CACHE_READER_READ_SECTION(MCO_DependencyTable, mpCachedDependTable,
depend_tab);
return true;
}
@@ -297,7 +295,7 @@
uint32_t depType = dep->second.first;
unsigned char const *depSHA1 = dep->second.second;
- OBCC_Dependency *depCached =&mpCachedDependTable->table[i];
+ MCO_Dependency *depCached =&mpCachedDependTable->table[i];
char const *depCachedName = strPool[depCached->res_name_strp_index];
uint32_t depCachedType = depCached->res_type;
unsigned char const *depCachedSHA1 = depCached->sha1;
@@ -337,10 +335,10 @@
}
bool MCCacheReader::readVarNameList() {
- CACHE_READER_READ_SECTION(OBCC_String_Ptr, mpVarNameList, export_var_name_list);
+ CACHE_READER_READ_SECTION(MCO_String_Ptr, mpVarNameList, export_var_name_list);
vector<char const *> const &strPool = mpResult->mStringPool;
- mpResult->mpExportVars = (OBCC_ExportVarList*)
+ mpResult->mpExportVars = (MCO_ExportVarList*)
malloc(sizeof(size_t) +
sizeof(void*) * export_var_name_list_raw->count);
if (!mpResult->mpExportVars) {
@@ -352,7 +350,7 @@
for (size_t i = 0; i < export_var_name_list_raw->count; ++i) {
mpResult->mpExportVars->cached_addr_list[i] =
rsloaderGetSymbolAddress(mpResult->mRSExecutable, strPool[export_var_name_list_raw->strp_indexs[i]]);
-#if DEBUG_MCJIT_REFLECT
+#if DEBUG_MC_REFLECT
ALOGD("Get symbol address: %s -> %p",
strPool[export_var_name_list_raw->strp_indexs[i]], mpResult->mpExportVars->cached_addr_list[i]);
#endif
@@ -361,10 +359,10 @@
}
bool MCCacheReader::readFuncNameList() {
- CACHE_READER_READ_SECTION(OBCC_String_Ptr, mpFuncNameList, export_func_name_list);
+ CACHE_READER_READ_SECTION(MCO_String_Ptr, mpFuncNameList, export_func_name_list);
vector<char const *> const &strPool = mpResult->mStringPool;
- mpResult->mpExportFuncs = (OBCC_ExportFuncList*)
+ mpResult->mpExportFuncs = (MCO_ExportFuncList*)
malloc(sizeof(size_t) +
sizeof(void*) * export_func_name_list_raw->count);
if (!mpResult->mpExportFuncs) {
@@ -376,7 +374,7 @@
for (size_t i = 0; i < export_func_name_list_raw->count; ++i) {
mpResult->mpExportFuncs->cached_addr_list[i] =
rsloaderGetSymbolAddress(mpResult->mRSExecutable, strPool[export_func_name_list_raw->strp_indexs[i]]);
-#if DEBUG_MCJIT_REFLECT
+#if DEBUG_MC_REFLECT
ALOGD("Get function address: %s -> %p",
strPool[export_func_name_list_raw->strp_indexs[i]], mpResult->mpExportFuncs->cached_addr_list[i]);
#endif
@@ -385,10 +383,10 @@
}
bool MCCacheReader::readForEachNameList() {
- CACHE_READER_READ_SECTION(OBCC_String_Ptr, mpForEachNameList, export_foreach_name_list);
+ CACHE_READER_READ_SECTION(MCO_String_Ptr, mpForEachNameList, export_foreach_name_list);
vector<char const *> const &strPool = mpResult->mStringPool;
- mpResult->mpExportForEach = (OBCC_ExportForEachList*)
+ mpResult->mpExportForEach = (MCO_ExportForEachList*)
malloc(sizeof(size_t) +
sizeof(void*) * export_foreach_name_list_raw->count);
if (!mpResult->mpExportForEach) {
@@ -400,7 +398,7 @@
for (size_t i = 0; i < export_foreach_name_list_raw->count; ++i) {
mpResult->mpExportForEach->cached_addr_list[i] =
rsloaderGetSymbolAddress(mpResult->mRSExecutable, strPool[export_foreach_name_list_raw->strp_indexs[i]]);
-#if DEBUG_MCJIT_REFLECT
+#if DEBUG_MC_REFLECT
ALOGE("Get foreach function address: %s -> %p",
strPool[export_foreach_name_list_raw->strp_indexs[i]], mpResult->mpExportForEach->cached_addr_list[i]);
#endif
@@ -409,13 +407,13 @@
}
bool MCCacheReader::readPragmaList() {
- CACHE_READER_READ_SECTION(OBCC_PragmaList, mpPragmaList, pragma_list);
+ CACHE_READER_READ_SECTION(MCO_PragmaList, mpPragmaList, pragma_list);
vector<char const *> const &strPool = mpResult->mStringPool;
ScriptCached::PragmaList &pragmas = mpResult->mPragmas;
for (size_t i = 0; i < pragma_list_raw->count; ++i) {
- OBCC_Pragma *pragma = &pragma_list_raw->list[i];
+ MCO_Pragma *pragma = &pragma_list_raw->list[i];
pragmas.push_back(make_pair(strPool[pragma->key_strp_index],
strPool[pragma->value_strp_index]));
}
@@ -425,7 +423,7 @@
bool MCCacheReader::readObjectSlotList() {
- CACHE_READER_READ_SECTION(OBCC_ObjectSlotList,
+ CACHE_READER_READ_SECTION(MCO_ObjectSlotList,
mpResult->mpObjectSlotList, object_slot_list);
return true;
}
@@ -484,4 +482,3 @@
}
} // namespace bcc
-#endif
diff --git a/lib/ExecutionEngine/MCCacheReader.h b/lib/ExecutionEngine/MCCacheReader.h
index 1e59111..df4aca3 100644
--- a/lib/ExecutionEngine/MCCacheReader.h
+++ b/lib/ExecutionEngine/MCCacheReader.h
@@ -40,13 +40,13 @@
off_t mInfoFileSize;
MCO_Header *mpHeader;
- OBCC_DependencyTable *mpCachedDependTable;
- OBCC_PragmaList *mpPragmaList;
- OBCC_FuncTable *mpFuncTable;
+ MCO_DependencyTable *mpCachedDependTable;
+ MCO_PragmaList *mpPragmaList;
+ MCO_FuncTable *mpFuncTable;
- OBCC_String_Ptr *mpVarNameList;
- OBCC_String_Ptr *mpFuncNameList;
- OBCC_String_Ptr *mpForEachNameList;
+ MCO_String_Ptr *mpVarNameList;
+ MCO_String_Ptr *mpFuncNameList;
+ MCO_String_Ptr *mpForEachNameList;
llvm::OwningPtr<ScriptCached> mpResult;
@@ -68,7 +68,7 @@
~MCCacheReader();
- void addDependency(OBCC_ResourceType resType,
+ void addDependency(MCO_ResourceType resType,
std::string const &resName,
unsigned char const *sha1) {
mDependencies.insert(std::make_pair(resName,
diff --git a/lib/ExecutionEngine/MCCacheWriter.cpp b/lib/ExecutionEngine/MCCacheWriter.cpp
index cca724e..b0bf117 100644
--- a/lib/ExecutionEngine/MCCacheWriter.cpp
+++ b/lib/ExecutionEngine/MCCacheWriter.cpp
@@ -31,7 +31,6 @@
using namespace std;
-#if USE_MCJIT
namespace bcc {
MCCacheWriter::~MCCacheWriter() {
@@ -88,8 +87,8 @@
memset(header, '\0', sizeof(MCO_Header));
// Magic word and version
- memcpy(header->magic, OBCC_MAGIC, 4);
- memcpy(header->version, OBCC_VERSION, 4);
+ memcpy(header->magic, MCO_MAGIC, 4);
+ memcpy(header->version, MCO_VERSION, 4);
// Machine Integer Type
uint32_t number = 0x00000001;
@@ -107,10 +106,10 @@
bool MCCacheWriter::prepareDependencyTable() {
- size_t tableSize = sizeof(OBCC_DependencyTable) +
- sizeof(OBCC_Dependency) * mDependencies.size();
+ size_t tableSize = sizeof(MCO_DependencyTable) +
+ sizeof(MCO_Dependency) * mDependencies.size();
- OBCC_DependencyTable *tab = (OBCC_DependencyTable *)malloc(tableSize);
+ MCO_DependencyTable *tab = (MCO_DependencyTable *)malloc(tableSize);
if (!tab) {
ALOGE("Unable to allocate for dependency table section.\n");
@@ -125,7 +124,7 @@
size_t i = 0;
for (map<string, pair<uint32_t, unsigned char const *> >::iterator
I = mDependencies.begin(), E = mDependencies.end(); I != E; ++I, ++i) {
- OBCC_Dependency *dep = &tab->table[i];
+ MCO_Dependency *dep = &tab->table[i];
dep->res_name_strp_index = addString(I->first.c_str(), I->first.size());
dep->res_type = I->second.first;
@@ -138,10 +137,10 @@
bool MCCacheWriter::preparePragmaList() {
size_t pragmaCount = mpOwner->getPragmaCount();
- size_t listSize = sizeof(OBCC_PragmaList) +
- sizeof(OBCC_Pragma) * pragmaCount;
+ size_t listSize = sizeof(MCO_PragmaList) +
+ sizeof(MCO_Pragma) * pragmaCount;
- OBCC_PragmaList *list = (OBCC_PragmaList *)malloc(listSize);
+ MCO_PragmaList *list = (MCO_PragmaList *)malloc(listSize);
if (!list) {
ALOGE("Unable to allocate for pragma list\n");
@@ -164,7 +163,7 @@
size_t keyLen = strlen(key);
size_t valueLen = strlen(value);
- OBCC_Pragma *pragma = &list->list[i];
+ MCO_Pragma *pragma = &list->list[i];
pragma->key_strp_index = addString(key, keyLen);
pragma->value_strp_index = addString(value, valueLen);
}
@@ -174,8 +173,8 @@
bool MCCacheWriter::prepareStringPool() {
// Calculate string pool size
- size_t size = sizeof(OBCC_StringPool) +
- sizeof(OBCC_String) * mStringPool.size();
+ size_t size = sizeof(MCO_StringPool) +
+ sizeof(MCO_String) * mStringPool.size();
off_t strOffset = size;
@@ -184,7 +183,7 @@
}
// Create string pool
- OBCC_StringPool *pool = (OBCC_StringPool *)malloc(size);
+ MCO_StringPool *pool = (MCO_StringPool *)malloc(size);
if (!pool) {
ALOGE("Unable to allocate string pool.\n");
@@ -199,7 +198,7 @@
char *strPtr = reinterpret_cast<char *>(pool) + strOffset;
for (size_t i = 0; i < mStringPool.size(); ++i) {
- OBCC_String *str = &pool->list[i];
+ MCO_String *str = &pool->list[i];
str->length = mStringPool[i].second;
str->offset = strOffset;
@@ -217,9 +216,9 @@
bool MCCacheWriter::prepareExportVarNameList() {
size_t varCount = mpOwner->getExportVarCount();
- size_t listSize = sizeof(OBCC_String_Ptr) + sizeof(size_t) * varCount;
+ size_t listSize = sizeof(MCO_String_Ptr) + sizeof(size_t) * varCount;
- OBCC_String_Ptr *list = (OBCC_String_Ptr*)malloc(listSize);
+ MCO_String_Ptr *list = (MCO_String_Ptr*)malloc(listSize);
if (!list) {
ALOGE("Unable to allocate for export variable name list\n");
@@ -241,9 +240,9 @@
bool MCCacheWriter::prepareExportFuncNameList() {
size_t funcCount = mpOwner->getExportFuncCount();
- size_t listSize = sizeof(OBCC_String_Ptr) + sizeof(size_t) * funcCount;
+ size_t listSize = sizeof(MCO_String_Ptr) + sizeof(size_t) * funcCount;
- OBCC_String_Ptr *list = (OBCC_String_Ptr*)malloc(listSize);
+ MCO_String_Ptr *list = (MCO_String_Ptr*)malloc(listSize);
if (!list) {
ALOGE("Unable to allocate for export function name list\n");
@@ -265,9 +264,9 @@
bool MCCacheWriter::prepareExportForEachNameList() {
size_t forEachCount = mpOwner->getExportForEachCount();
- size_t listSize = sizeof(OBCC_String_Ptr) + sizeof(size_t) * forEachCount;
+ size_t listSize = sizeof(MCO_String_Ptr) + sizeof(size_t) * forEachCount;
- OBCC_String_Ptr *list = (OBCC_String_Ptr*)malloc(listSize);
+ MCO_String_Ptr *list = (MCO_String_Ptr*)malloc(listSize);
if (!list) {
ALOGE("Unable to allocate for export forEach name list\n");
@@ -290,10 +289,10 @@
bool MCCacheWriter::prepareObjectSlotList() {
size_t objectSlotCount = mpOwner->getObjectSlotCount();
- size_t listSize = sizeof(OBCC_ObjectSlotList) +
+ size_t listSize = sizeof(MCO_ObjectSlotList) +
sizeof(uint32_t) * objectSlotCount;
- OBCC_ObjectSlotList *list = (OBCC_ObjectSlotList *)malloc(listSize);
+ MCO_ObjectSlotList *list = (MCO_ObjectSlotList *)malloc(listSize);
if (!list) {
ALOGE("Unable to allocate for object slot list\n");
@@ -387,4 +386,3 @@
}
} // namespace bcc
-#endif
diff --git a/lib/ExecutionEngine/MCCacheWriter.h b/lib/ExecutionEngine/MCCacheWriter.h
index 58f6ef5..b2bcb12 100644
--- a/lib/ExecutionEngine/MCCacheWriter.h
+++ b/lib/ExecutionEngine/MCCacheWriter.h
@@ -41,14 +41,14 @@
std::pair<uint32_t, unsigned char const *> > mDependencies;
MCO_Header *mpHeaderSection;
- OBCC_StringPool *mpStringPoolSection;
- OBCC_DependencyTable *mpDependencyTableSection;
- OBCC_PragmaList *mpPragmaListSection;
- OBCC_ObjectSlotList *mpObjectSlotSection;
+ MCO_StringPool *mpStringPoolSection;
+ MCO_DependencyTable *mpDependencyTableSection;
+ MCO_PragmaList *mpPragmaListSection;
+ MCO_ObjectSlotList *mpObjectSlotSection;
- OBCC_String_Ptr *mpExportVarNameListSection;
- OBCC_String_Ptr *mpExportFuncNameListSection;
- OBCC_String_Ptr *mpExportForEachNameListSection;
+ MCO_String_Ptr *mpExportVarNameListSection;
+ MCO_String_Ptr *mpExportFuncNameListSection;
+ MCO_String_Ptr *mpExportForEachNameListSection;
std::vector<std::string> varNameList;
std::vector<std::string> funcNameList;
@@ -66,7 +66,7 @@
bool writeCacheFile(FileHandle *objFile, FileHandle *infoFile,
Script *S, uint32_t libRS_threadable);
- void addDependency(OBCC_ResourceType resType,
+ void addDependency(MCO_ResourceType resType,
std::string const &resName,
unsigned char const *sha1) {
mDependencies.insert(std::make_pair(resName,
diff --git a/lib/ExecutionEngine/OldJIT/CacheReader.cpp b/lib/ExecutionEngine/OldJIT/CacheReader.cpp
deleted file mode 100644
index 8eceb5f..0000000
--- a/lib/ExecutionEngine/OldJIT/CacheReader.cpp
+++ /dev/null
@@ -1,453 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "CacheReader.h"
-
-#include "ContextManager.h"
-#include "DebugHelper.h"
-#include "FileHandle.h"
-#include "ScriptCached.h"
-
-#include <bcc/bcc_cache.h>
-
-#include <llvm/ADT/OwningPtr.h>
-
-#include <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <utility>
-#include <vector>
-
-#include <new>
-
-#include <stdlib.h>
-#include <string.h>
-
-using namespace std;
-
-
-namespace bcc {
-
-CacheReader::~CacheReader() {
- if (mpHeader) { free(mpHeader); }
- if (mpCachedDependTable) { free(mpCachedDependTable); }
- if (mpPragmaList) { free(mpPragmaList); }
- if (mpFuncTable) { free(mpFuncTable); }
-}
-
-ScriptCached *CacheReader::readCacheFile(FileHandle *objFile,
- FileHandle *infoFile,
- Script *S) {
- // Check file handle
- if (!objFile || objFile->getFD() < 0 ||
- !infoFile || infoFile->getFD() < 0) {
- return NULL;
- }
-
- mObjFile = objFile;
- mInfoFile = infoFile;
-
- // Allocate ScriptCached object
- mpResult.reset(new (nothrow) ScriptCached(S));
-
- if (!mpResult) {
- ALOGE("Unable to allocate ScriptCached object.\n");
- return NULL;
- }
-
- bool result = checkFileSize()
- && readHeader()
- && checkHeader()
- && checkMachineIntType()
- && checkSectionOffsetAndSize()
- && readStringPool()
- && checkStringPool()
- && readDependencyTable()
- && checkDependency()
- && readExportVarList()
- && readExportFuncList()
- && readPragmaList()
- && readFuncTable()
- && readObjectSlotList()
- && readContext()
- && checkContext()
- //&& readRelocationTable()
- //&& relocate()
- ;
-
- return result ? mpResult.take() : NULL;
-}
-
-
-bool CacheReader::checkFileSize() {
- struct stat stfile;
-
- if (fstat(mInfoFile->getFD(), &stfile) < 0) {
- ALOGE("Unable to stat metadata information file.\n");
- return false;
- }
-
- mInfoFileSize = stfile.st_size;
-
- if (mInfoFileSize < (off_t)sizeof(OBCC_Header)) {
- ALOGE("Metadata information file is too small to be correct.\n");
- return false;
- }
-
- if (fstat(mObjFile->getFD(), &stfile) < 0) {
- ALOGE("Unable to stat executable file.\n");
- return false;
- }
-
- if (stfile.st_size < (off_t)ContextManager::ContextSize) {
- ALOGE("Executable file is too small to be correct.\n");
- return false;
- }
-
- return true;
-}
-
-
-bool CacheReader::readHeader() {
- if (mInfoFile->seek(0, SEEK_SET) != 0) {
- ALOGE("Unable to seek to 0. (reason: %s)\n", strerror(errno));
- return false;
- }
-
- mpHeader = (OBCC_Header *)malloc(sizeof(OBCC_Header));
- if (!mpHeader) {
- ALOGE("Unable to allocate for cache header.\n");
- return false;
- }
-
- if (mInfoFile->read((char *)mpHeader, sizeof(OBCC_Header)) !=
- (ssize_t)sizeof(OBCC_Header)) {
- ALOGE("Unable to read cache header.\n");
- return false;
- }
-
- // Dirty hack for libRS.
- // TODO(all): This should be removed in the future.
- if (mpHeader->libRS_threadable) {
- mpResult->mLibRSThreadable = true;
- }
-
- return true;
-}
-
-
-bool CacheReader::checkHeader() {
- if (memcmp(mpHeader->magic, OBCC_MAGIC, 4) != 0) {
- ALOGE("Bad magic word\n");
- return false;
- }
-
- if (memcmp(mpHeader->version, OBCC_VERSION, 4) != 0) {
- mpHeader->version[4 - 1] = '\0'; // ensure c-style string terminated
- ALOGI("Cache file format version mismatch: now %s cached %s\n",
- OBCC_VERSION, mpHeader->version);
- return false;
- }
- return true;
-}
-
-
-bool CacheReader::checkMachineIntType() {
- uint32_t number = 0x00000001;
-
- bool isLittleEndian = (*reinterpret_cast<char *>(&number) == 1);
- if ((isLittleEndian && mpHeader->endianness != 'e') ||
- (!isLittleEndian && mpHeader->endianness != 'E')) {
- ALOGE("Machine endianness mismatch.\n");
- return false;
- }
-
- if ((unsigned int)mpHeader->sizeof_off_t != sizeof(off_t) ||
- (unsigned int)mpHeader->sizeof_size_t != sizeof(size_t) ||
- (unsigned int)mpHeader->sizeof_ptr_t != sizeof(void *)) {
- ALOGE("Machine integer size mismatch.\n");
- return false;
- }
-
- return true;
-}
-
-
-bool CacheReader::checkSectionOffsetAndSize() {
-#define CHECK_SECTION_OFFSET(NAME) \
- do { \
- off_t offset = mpHeader-> NAME##_offset; \
- off_t size = (off_t)mpHeader-> NAME##_size; \
- \
- if (mInfoFileSize < offset || mInfoFileSize < offset + size) { \
- ALOGE(#NAME " section overflow.\n"); \
- return false; \
- } \
- \
- if (offset % sizeof(int) != 0) { \
- ALOGE(#NAME " offset must aligned to %d.\n", (int)sizeof(int)); \
- return false; \
- } \
- \
- if (size < static_cast<off_t>(sizeof(size_t))) { \
- ALOGE(#NAME " size is too small to be correct.\n"); \
- return false; \
- } \
- } while (0)
-
- CHECK_SECTION_OFFSET(str_pool);
- CHECK_SECTION_OFFSET(depend_tab);
- //CHECK_SECTION_OFFSET(reloc_tab);
- CHECK_SECTION_OFFSET(export_var_list);
- CHECK_SECTION_OFFSET(export_func_list);
- CHECK_SECTION_OFFSET(pragma_list);
-
-#undef CHECK_SECTION_OFFSET
-
- // TODO(logan): Move this to some where else.
- long pagesize = sysconf(_SC_PAGESIZE);
- if ((uintptr_t)mpHeader->context_cached_addr % pagesize != 0) {
- ALOGE("cached address is not aligned to pagesize.\n");
- return false;
- }
-
- return true;
-}
-
-
-#define CACHE_READER_READ_SECTION(TYPE, AUTO_MANAGED_HOLDER, NAME) \
- TYPE *NAME##_raw = (TYPE *)malloc(mpHeader->NAME##_size); \
- \
- if (!NAME##_raw) { \
- ALOGE("Unable to allocate for " #NAME "\n"); \
- return false; \
- } \
- \
- /* We have to ensure that some one will deallocate NAME##_raw */ \
- AUTO_MANAGED_HOLDER = NAME##_raw; \
- \
- if (mInfoFile->seek(mpHeader->NAME##_offset, SEEK_SET) == -1) { \
- ALOGE("Unable to seek to " #NAME " section\n"); \
- return false; \
- } \
- \
- if (mInfoFile->read(reinterpret_cast<char *>(NAME##_raw), \
- mpHeader->NAME##_size) != (ssize_t)mpHeader->NAME##_size) \
- { \
- ALOGE("Unable to read " #NAME ".\n"); \
- return false; \
- }
-
-
-bool CacheReader::readStringPool() {
- CACHE_READER_READ_SECTION(OBCC_StringPool,
- mpResult->mpStringPoolRaw, str_pool);
-
- char *str_base = reinterpret_cast<char *>(str_pool_raw);
-
- vector<char const *> &pool = mpResult->mStringPool;
- for (size_t i = 0; i < str_pool_raw->count; ++i) {
- char *str = str_base + str_pool_raw->list[i].offset;
- pool.push_back(str);
- }
-
- return true;
-}
-
-
-bool CacheReader::checkStringPool() {
- OBCC_StringPool *poolR = mpResult->mpStringPoolRaw;
- vector<char const *> &pool = mpResult->mStringPool;
-
- // Ensure that every c-style string is ended with '\0'
- for (size_t i = 0; i < poolR->count; ++i) {
- if (pool[i][poolR->list[i].length] != '\0') {
- ALOGE("The %lu-th string does not end with '\\0'.\n", (unsigned long)i);
- return false;
- }
- }
-
- return true;
-}
-
-
-bool CacheReader::readDependencyTable() {
- CACHE_READER_READ_SECTION(OBCC_DependencyTable, mpCachedDependTable,
- depend_tab);
- return true;
-}
-
-
-bool CacheReader::checkDependency() {
- if (mDependencies.size() != mpCachedDependTable->count) {
- ALOGE("Dependencies count mismatch. (%lu vs %lu)\n",
- (unsigned long)mDependencies.size(),
- (unsigned long)mpCachedDependTable->count);
- return false;
- }
-
- vector<char const *> &strPool = mpResult->mStringPool;
- map<string, pair<uint32_t, unsigned char const *> >::iterator dep;
-
- dep = mDependencies.begin();
- for (size_t i = 0; i < mpCachedDependTable->count; ++i, ++dep) {
- string const &depName = dep->first;
- uint32_t depType = dep->second.first;
- unsigned char const *depSHA1 = dep->second.second;
-
- OBCC_Dependency *depCached =&mpCachedDependTable->table[i];
- char const *depCachedName = strPool[depCached->res_name_strp_index];
- uint32_t depCachedType = depCached->res_type;
- unsigned char const *depCachedSHA1 = depCached->sha1;
-
- if (depName != depCachedName) {
- ALOGE("Cache dependency name mismatch:\n");
- ALOGE(" given: %s\n", depName.c_str());
- ALOGE(" cached: %s\n", depCachedName);
-
- return false;
- }
-
- if (memcmp(depSHA1, depCachedSHA1, 20) != 0) {
- ALOGE("Cache dependency %s sha1 mismatch:\n", depCachedName);
-
-#define PRINT_SHA1(PREFIX, X, POSTFIX) \
- ALOGE(PREFIX "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" \
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" POSTFIX, \
- X[0], X[1], X[2], X[3], X[4], X[5], X[6], X[7], X[8], X[9], \
- X[10],X[11],X[12],X[13],X[14],X[15],X[16],X[17],X[18],X[19]);
-
- PRINT_SHA1(" given: ", depSHA1, "\n");
- PRINT_SHA1(" cached: ", depCachedSHA1, "\n");
-
-#undef PRINT_SHA1
-
- return false;
- }
-
- if (depType != depCachedType) {
- ALOGE("Cache dependency %s resource type mismatch.\n", depCachedName);
- return false;
- }
- }
-
- return true;
-}
-
-bool CacheReader::readExportVarList() {
- CACHE_READER_READ_SECTION(OBCC_ExportVarList,
- mpResult->mpExportVars, export_var_list);
- return true;
-}
-
-
-bool CacheReader::readExportFuncList() {
- CACHE_READER_READ_SECTION(OBCC_ExportFuncList,
- mpResult->mpExportFuncs, export_func_list);
- return true;
-}
-
-
-bool CacheReader::readPragmaList() {
- CACHE_READER_READ_SECTION(OBCC_PragmaList, mpPragmaList, pragma_list);
-
- vector<char const *> const &strPool = mpResult->mStringPool;
- ScriptCached::PragmaList &pragmas = mpResult->mPragmas;
-
- for (size_t i = 0; i < pragma_list_raw->count; ++i) {
- OBCC_Pragma *pragma = &pragma_list_raw->list[i];
- pragmas.push_back(make_pair(strPool[pragma->key_strp_index],
- strPool[pragma->value_strp_index]));
- }
-
- return true;
-}
-
-
-bool CacheReader::readObjectSlotList() {
- CACHE_READER_READ_SECTION(OBCC_ObjectSlotList,
- mpResult->mpObjectSlotList, object_slot_list);
- return true;
-}
-
-
-bool CacheReader::readFuncTable() {
- CACHE_READER_READ_SECTION(OBCC_FuncTable, mpFuncTable, func_table);
-
- vector<char const *> &strPool = mpResult->mStringPool;
- ScriptCached::FuncTable &table = mpResult->mFunctions;
- for (size_t i = 0; i < func_table_raw->count; ++i) {
- OBCC_FuncInfo *func = &func_table_raw->table[i];
- table.insert(make_pair(strPool[func->name_strp_index],
- make_pair(func->cached_addr, func->size)));
- }
-
- return true;
-}
-
-#undef CACHE_READER_READ_SECTION
-
-
-bool CacheReader::readContext() {
- mpResult->mContext =
- ContextManager::get().allocateContext(mpHeader->context_cached_addr,
- mObjFile->getFD(), 0);
-
- if (!mpResult->mContext) {
- // Unable to allocate at cached address. Give up.
- mIsContextSlotNotAvail = true;
- return false;
-
- // TODO(logan): If relocation is fixed, we should try to allocate the
- // code in different location, and relocate the context.
- }
-
- return true;
-}
-
-
-bool CacheReader::checkContext() {
- uint32_t sum = mpHeader->context_parity_checksum;
- uint32_t *ptr = reinterpret_cast<uint32_t *>(mpResult->mContext);
-
- for (size_t i = 0; i < ContextManager::ContextSize / sizeof(uint32_t); ++i) {
- sum ^= *ptr++;
- }
-
- if (sum != 0) {
- ALOGE("Checksum check failed\n");
- return false;
- }
-
- ALOGI("Passed checksum even parity verification.\n");
- return true;
-}
-
-
-bool CacheReader::readRelocationTable() {
- // TODO(logan): Not finished.
- return true;
-}
-
-
-bool CacheReader::relocate() {
- // TODO(logan): Not finished.
- return true;
-}
-
-
-} // namespace bcc
diff --git a/lib/ExecutionEngine/OldJIT/CacheReader.h b/lib/ExecutionEngine/OldJIT/CacheReader.h
deleted file mode 100644
index a208ed6..0000000
--- a/lib/ExecutionEngine/OldJIT/CacheReader.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BCC_CACHEREADER_H
-#define BCC_CACHEREADER_H
-
-#include "ScriptCached.h"
-
-#include <llvm/ADT/OwningPtr.h>
-
-#include <map>
-#include <string>
-#include <utility>
-
-#include <stddef.h>
-#include <stdint.h>
-
-struct OBCC_Header;
-
-namespace bcc {
- class FileHandle;
- class Script;
-
- class CacheReader {
- private:
- FileHandle *mObjFile;
- FileHandle *mInfoFile;
- off_t mInfoFileSize;
-
- OBCC_Header *mpHeader;
- OBCC_DependencyTable *mpCachedDependTable;
- OBCC_PragmaList *mpPragmaList;
- OBCC_FuncTable *mpFuncTable;
-
- llvm::OwningPtr<ScriptCached> mpResult;
-
- std::map<std::string,
- std::pair<uint32_t, unsigned char const *> > mDependencies;
-
- bool mIsContextSlotNotAvail;
-
- public:
- CacheReader()
- : mObjFile(NULL), mInfoFile(NULL), mInfoFileSize(0), mpHeader(NULL),
- mpCachedDependTable(NULL), mpPragmaList(NULL), mpFuncTable(NULL),
- mIsContextSlotNotAvail(false) {
- }
-
- ~CacheReader();
-
- void addDependency(OBCC_ResourceType resType,
- std::string const &resName,
- unsigned char const *sha1) {
- mDependencies.insert(std::make_pair(resName,
- std::make_pair((uint32_t)resType, sha1)));
- }
-
- ScriptCached *readCacheFile(FileHandle *objFile,
- FileHandle *infoFile,
- Script *s);
-
- bool isContextSlotNotAvail() const {
- return mIsContextSlotNotAvail;
- }
-
- private:
- bool readHeader();
- bool readStringPool();
- bool readDependencyTable();
- bool readExportVarList();
- bool readExportFuncList();
- bool readPragmaList();
- bool readFuncTable();
- bool readObjectSlotList();
- bool readContext();
- bool readRelocationTable();
-
- bool checkFileSize();
- bool checkHeader();
- bool checkMachineIntType();
- bool checkSectionOffsetAndSize();
- bool checkStringPool();
- bool checkDependency();
- bool checkContext();
-
- bool relocate();
- };
-
-} // namespace bcc
-
-#endif // BCC_CACHEREADER_H
diff --git a/lib/ExecutionEngine/OldJIT/CacheWriter.cpp b/lib/ExecutionEngine/OldJIT/CacheWriter.cpp
deleted file mode 100644
index 36bf281..0000000
--- a/lib/ExecutionEngine/OldJIT/CacheWriter.cpp
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "CacheWriter.h"
-
-#include "ContextManager.h"
-#include "DebugHelper.h"
-#include "FileHandle.h"
-#include "Script.h"
-
-#include <map>
-#include <string>
-#include <vector>
-#include <utility>
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-using namespace std;
-
-namespace bcc {
-
-CacheWriter::~CacheWriter() {
-#define CHECK_AND_FREE(VAR) if (VAR) { free(VAR); }
-
- CHECK_AND_FREE(mpHeaderSection);
- CHECK_AND_FREE(mpStringPoolSection);
- CHECK_AND_FREE(mpDependencyTableSection);
- //CHECK_AND_FREE(mpRelocationTableSection);
- CHECK_AND_FREE(mpExportVarListSection);
- CHECK_AND_FREE(mpExportFuncListSection);
- CHECK_AND_FREE(mpPragmaListSection);
- CHECK_AND_FREE(mpFuncTableSection);
- CHECK_AND_FREE(mpObjectSlotSection);
-
-#undef CHECK_AND_FREE
-}
-
-bool CacheWriter::writeCacheFile(FileHandle *objFile,
- FileHandle *infoFile,
- Script *S,
- uint32_t libRS_threadable) {
- if (!objFile || objFile->getFD() < 0 ||
- !infoFile || infoFile->getFD() < 0) {
- return false;
- }
-
- mObjFile = objFile;
- mInfoFile = infoFile;
- mpOwner = S;
-
- bool result = prepareHeader(libRS_threadable)
- && prepareDependencyTable()
- && prepareFuncTable()
- && preparePragmaList()
- //&& prepareRelocationTable()
- && prepareStringPool()
- && prepareExportVarList()
- && prepareExportFuncList()
- && prepareObjectSlotList()
- && calcSectionOffset()
- && calcContextChecksum()
- && writeAll()
- ;
-
- return result;
-}
-
-
-bool CacheWriter::prepareHeader(uint32_t libRS_threadable) {
- OBCC_Header *header = (OBCC_Header *)malloc(sizeof(OBCC_Header));
-
- if (!header) {
- ALOGE("Unable to allocate for header.\n");
- return false;
- }
-
- mpHeaderSection = header;
-
- // Initialize
- memset(header, '\0', sizeof(OBCC_Header));
-
- // Magic word and version
- memcpy(header->magic, OBCC_MAGIC, 4);
- memcpy(header->version, OBCC_VERSION, 4);
-
- // Machine Integer Type
- uint32_t number = 0x00000001;
- header->endianness = (*reinterpret_cast<char *>(&number) == 1) ? 'e' : 'E';
- header->sizeof_off_t = sizeof(off_t);
- header->sizeof_size_t = sizeof(size_t);
- header->sizeof_ptr_t = sizeof(void *);
-
- // Context
- header->context_cached_addr = mpOwner->getContext();
-
- // libRS is threadable dirty hack
- // TODO: This should be removed in the future
- header->libRS_threadable = libRS_threadable;
-
- return true;
-}
-
-
-bool CacheWriter::prepareDependencyTable() {
- size_t tableSize = sizeof(OBCC_DependencyTable) +
- sizeof(OBCC_Dependency) * mDependencies.size();
-
- OBCC_DependencyTable *tab = (OBCC_DependencyTable *)malloc(tableSize);
-
- if (!tab) {
- ALOGE("Unable to allocate for dependency table section.\n");
- return false;
- }
-
- mpDependencyTableSection = tab;
- mpHeaderSection->depend_tab_size = tableSize;
-
- tab->count = mDependencies.size();
-
- size_t i = 0;
- for (map<string, pair<uint32_t, unsigned char const *> >::iterator
- I = mDependencies.begin(), E = mDependencies.end(); I != E; ++I, ++i) {
- OBCC_Dependency *dep = &tab->table[i];
-
- dep->res_name_strp_index = addString(I->first.c_str(), I->first.size());
- dep->res_type = I->second.first;
- memcpy(dep->sha1, I->second.second, 20);
- }
-
- return true;
-}
-
-
-bool CacheWriter::prepareFuncTable() {
- size_t funcCount = mpOwner->getFuncCount();
-
- size_t tableSize = sizeof(OBCC_FuncTable) +
- sizeof(OBCC_FuncInfo) * funcCount;
-
- OBCC_FuncTable *tab = (OBCC_FuncTable *)malloc(tableSize);
-
- if (!tab) {
- ALOGE("Unable to allocate for function table section.\n");
- return false;
- }
-
- mpFuncTableSection = tab;
- mpHeaderSection->func_table_size = tableSize;
-
- tab->count = static_cast<size_t>(funcCount);
-
- // Get the function informations
- vector<FuncInfo> funcInfoList(funcCount);
- mpOwner->getFuncInfoList(funcCount, &*funcInfoList.begin());
-
- for (size_t i = 0; i < funcCount; ++i) {
- FuncInfo *info = &funcInfoList[i];
- OBCC_FuncInfo *outputInfo = &tab->table[i];
-
- outputInfo->name_strp_index = addString(info->name, strlen(info->name));
- outputInfo->cached_addr = info->addr;
- outputInfo->size = info->size;
- }
-
- return true;
-}
-
-
-bool CacheWriter::preparePragmaList() {
- size_t pragmaCount = mpOwner->getPragmaCount();
-
- size_t listSize = sizeof(OBCC_PragmaList) +
- sizeof(OBCC_Pragma) * pragmaCount;
-
- OBCC_PragmaList *list = (OBCC_PragmaList *)malloc(listSize);
-
- if (!list) {
- ALOGE("Unable to allocate for pragma list\n");
- return false;
- }
-
- mpPragmaListSection = list;
- mpHeaderSection->pragma_list_size = listSize;
-
- list->count = pragmaCount;
-
- vector<char const *> keyList(pragmaCount);
- vector<char const *> valueList(pragmaCount);
- mpOwner->getPragmaList(pragmaCount, &*keyList.begin(), &*valueList.begin());
-
- for (size_t i = 0; i < pragmaCount; ++i) {
- char const *key = keyList[i];
- char const *value = valueList[i];
-
- size_t keyLen = strlen(key);
- size_t valueLen = strlen(value);
-
- OBCC_Pragma *pragma = &list->list[i];
- pragma->key_strp_index = addString(key, keyLen);
- pragma->value_strp_index = addString(value, valueLen);
- }
-
- return true;
-}
-
-
-bool CacheWriter::prepareRelocationTable() {
- // TODO(logan): Implement relocation table cache write.
- return false;
-}
-
-
-bool CacheWriter::prepareStringPool() {
- // Calculate string pool size
- size_t size = sizeof(OBCC_StringPool) +
- sizeof(OBCC_String) * mStringPool.size();
-
- off_t strOffset = size;
-
- for (size_t i = 0; i < mStringPool.size(); ++i) {
- size += mStringPool[i].second + 1;
- }
-
- // Create string pool
- OBCC_StringPool *pool = (OBCC_StringPool *)malloc(size);
-
- if (!pool) {
- ALOGE("Unable to allocate string pool.\n");
- return false;
- }
-
- mpStringPoolSection = pool;
- mpHeaderSection->str_pool_size = size;
-
- pool->count = mStringPool.size();
-
- char *strPtr = reinterpret_cast<char *>(pool) + strOffset;
-
- for (size_t i = 0; i < mStringPool.size(); ++i) {
- OBCC_String *str = &pool->list[i];
-
- str->length = mStringPool[i].second;
- str->offset = strOffset;
- memcpy(strPtr, mStringPool[i].first, str->length);
-
- strPtr += str->length;
- *strPtr++ = '\0';
-
- strOffset += str->length + 1;
- }
-
- return true;
-}
-
-
-bool CacheWriter::prepareExportVarList() {
- size_t varCount = mpOwner->getExportVarCount();
- size_t listSize = sizeof(OBCC_ExportVarList) + sizeof(void *) * varCount;
-
- OBCC_ExportVarList *list = (OBCC_ExportVarList *)malloc(listSize);
-
- if (!list) {
- ALOGE("Unable to allocate for export variable list\n");
- return false;
- }
-
- mpExportVarListSection = list;
- mpHeaderSection->export_var_list_size = listSize;
-
- list->count = static_cast<size_t>(varCount);
-
- mpOwner->getExportVarList(varCount, list->cached_addr_list);
- return true;
-}
-
-
-bool CacheWriter::prepareExportFuncList() {
- size_t funcCount = mpOwner->getExportFuncCount();
- size_t listSize = sizeof(OBCC_ExportFuncList) + sizeof(void *) * funcCount;
-
- OBCC_ExportFuncList *list = (OBCC_ExportFuncList *)malloc(listSize);
-
- if (!list) {
- ALOGE("Unable to allocate for export function list\n");
- return false;
- }
-
- mpExportFuncListSection = list;
- mpHeaderSection->export_func_list_size = listSize;
-
- list->count = static_cast<size_t>(funcCount);
-
- mpOwner->getExportFuncList(funcCount, list->cached_addr_list);
- return true;
-}
-
-
-bool CacheWriter::prepareObjectSlotList() {
- size_t objectSlotCount = mpOwner->getObjectSlotCount();
-
- size_t listSize = sizeof(OBCC_ObjectSlotList) +
- sizeof(uint32_t) * objectSlotCount;
-
- OBCC_ObjectSlotList *list = (OBCC_ObjectSlotList *)malloc(listSize);
-
- if (!list) {
- ALOGE("Unable to allocate for object slot list\n");
- return false;
- }
-
- mpObjectSlotSection = list;
- mpHeaderSection->object_slot_list_size = listSize;
-
- list->count = objectSlotCount;
-
- mpOwner->getObjectSlotList(objectSlotCount, list->object_slot_list);
- return true;
-}
-
-
-bool CacheWriter::calcSectionOffset() {
- size_t offset = sizeof(OBCC_Header);
-
-#define OFFSET_INCREASE(NAME) \
- do { \
- /* Align to a word */ \
- size_t rem = offset % sizeof(int); \
- if (rem > 0) { \
- offset += sizeof(int) - rem; \
- } \
- \
- /* Save the offset and increase it */ \
- mpHeaderSection->NAME##_offset = offset; \
- offset += mpHeaderSection->NAME##_size; \
- } while (0)
-
- OFFSET_INCREASE(str_pool);
- OFFSET_INCREASE(depend_tab);
- //OFFSET_INCREASE(reloc_tab);
- OFFSET_INCREASE(export_var_list);
- OFFSET_INCREASE(export_func_list);
- OFFSET_INCREASE(pragma_list);
- OFFSET_INCREASE(func_table);
- OFFSET_INCREASE(object_slot_list);
-
-#undef OFFSET_INCREASE
- return true;
-}
-
-
-bool CacheWriter::calcContextChecksum() {
- uint32_t sum = 0;
- uint32_t *ptr = reinterpret_cast<uint32_t *>(mpOwner->getContext());
-
- for (size_t i = 0; i < ContextManager::ContextSize / sizeof(uint32_t); ++i) {
- sum ^= *ptr++;
- }
-
- mpHeaderSection->context_parity_checksum = sum;
- return true;
-}
-
-
-bool CacheWriter::writeAll() {
-#define WRITE_SECTION(NAME, OFFSET, SIZE, SECTION) \
- do { \
- if (mInfoFile->seek(OFFSET, SEEK_SET) == -1) { \
- ALOGE("Unable to seek to " #NAME " section for writing.\n"); \
- return false; \
- } \
- \
- if (mInfoFile->write(reinterpret_cast<char *>(SECTION), (SIZE)) != \
- static_cast<ssize_t>(SIZE)) { \
- ALOGE("Unable to write " #NAME " section to cache file.\n"); \
- return false; \
- } \
- } while (0)
-
-#define WRITE_SECTION_SIMPLE(NAME, SECTION) \
- WRITE_SECTION(NAME, \
- mpHeaderSection->NAME##_offset, \
- mpHeaderSection->NAME##_size, \
- SECTION)
-
- WRITE_SECTION(header, 0, sizeof(OBCC_Header), mpHeaderSection);
-
- WRITE_SECTION_SIMPLE(str_pool, mpStringPoolSection);
- WRITE_SECTION_SIMPLE(depend_tab, mpDependencyTableSection);
- //WRITE_SECTION_SIMPLE(reloc_tab, mpRelocationTableSection);
- WRITE_SECTION_SIMPLE(export_var_list, mpExportVarListSection);
- WRITE_SECTION_SIMPLE(export_func_list, mpExportFuncListSection);
- WRITE_SECTION_SIMPLE(pragma_list, mpPragmaListSection);
- WRITE_SECTION_SIMPLE(func_table, mpFuncTableSection);
- WRITE_SECTION_SIMPLE(object_slot_list, mpObjectSlotSection);
-
-#undef WRITE_SECTION_SIMPLE
-#undef WRITE_SECTION
-
-
- // Write Context to Executable File
- char const *context = (char const *)mpOwner->getContext();
- size_t context_size = ContextManager::ContextSize;
- if (mObjFile->write(context, context_size) != (ssize_t)context_size) {
- ALOGE("Unable to write context image to executable file\n");
- return false;
- }
-
- return true;
-}
-
-
-} // namespace bcc
diff --git a/lib/ExecutionEngine/OldJIT/CacheWriter.h b/lib/ExecutionEngine/OldJIT/CacheWriter.h
deleted file mode 100644
index d492d4a..0000000
--- a/lib/ExecutionEngine/OldJIT/CacheWriter.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BCC_CACHEWRITER_H
-#define BCC_CACHEWRITER_H
-
-#include <bcc/bcc_cache.h>
-
-#include "FileHandle.h"
-
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-namespace bcc {
- class Script;
-
- class CacheWriter {
- private:
- Script *mpOwner;
-
- FileHandle *mObjFile;
- FileHandle *mInfoFile;
-
- std::vector<std::pair<char const *, size_t> > mStringPool;
-
- std::map<std::string,
- std::pair<uint32_t, unsigned char const *> > mDependencies;
-
- OBCC_Header *mpHeaderSection;
- OBCC_StringPool *mpStringPoolSection;
- OBCC_DependencyTable *mpDependencyTableSection;
- //OBCC_RelocationTable *mpRelocationTableSection;
- OBCC_ExportVarList *mpExportVarListSection;
- OBCC_ExportFuncList *mpExportFuncListSection;
- OBCC_PragmaList *mpPragmaListSection;
- OBCC_FuncTable *mpFuncTableSection;
- OBCC_ObjectSlotList *mpObjectSlotSection;
-
- public:
- CacheWriter()
- : mpHeaderSection(NULL), mpStringPoolSection(NULL),
- mpDependencyTableSection(NULL), mpExportVarListSection(NULL),
- mpExportFuncListSection(NULL), mpPragmaListSection(NULL),
- mpFuncTableSection(NULL), mpObjectSlotSection(NULL) {
- }
-
- ~CacheWriter();
-
- bool writeCacheFile(FileHandle *objFile,
- FileHandle *infoFile,
- Script *S,
- uint32_t libRS_threadable);
-
- void addDependency(OBCC_ResourceType resType,
- std::string const &resName,
- unsigned char const *sha1) {
- mDependencies.insert(std::make_pair(resName,
- std::make_pair((uint32_t)resType, sha1)));
- }
-
- private:
- bool prepareHeader(uint32_t libRS_threadable);
- bool prepareStringPool();
- bool prepareDependencyTable();
- bool prepareRelocationTable();
- bool prepareExportVarList();
- bool prepareExportFuncList();
- bool preparePragmaList();
- bool prepareFuncTable();
- bool prepareObjectSlotList();
-
- bool writeAll();
-
- bool calcSectionOffset();
- bool calcContextChecksum();
-
- size_t addString(char const *str, size_t size) {
- mStringPool.push_back(std::make_pair(str, size));
- return mStringPool.size() - 1;
- }
-
- };
-
-} // namespace bcc
-
-#endif // BCC_CACHEWRITER_H
diff --git a/lib/ExecutionEngine/OldJIT/ContextManager.cpp b/lib/ExecutionEngine/OldJIT/ContextManager.cpp
deleted file mode 100644
index 5dca382..0000000
--- a/lib/ExecutionEngine/OldJIT/ContextManager.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * copyright 2010, the android open source project
- *
- * licensed under the apache license, version 2.0 (the "license");
- * you may not use this file except in compliance with the license.
- * you may obtain a copy of the license at
- *
- * http://www.apache.org/licenses/license-2.0
- *
- * unless required by applicable law or agreed to in writing, software
- * distributed under the license is distributed on an "as is" basis,
- * without warranties or conditions of any kind, either express or implied.
- * see the license for the specific language governing permissions and
- * limitations under the license.
- */
-
-#include "ContextManager.h"
-
-#include "DebugHelper.h"
-
-#include <llvm/Support/Mutex.h>
-#include <llvm/Support/MutexGuard.h>
-
-#include <errno.h>
-#include <sys/mman.h>
-#include <utils/threads.h>
-
-#include <stddef.h>
-#include <string.h>
-
-
-namespace bcc {
-
-// Starting address for context slots
-char * const ContextManager::ContextFixedAddr = BCC_CONTEXT_FIXED_ADDR_;
-
-// ContextManager singleton object
-ContextManager ContextManager::TheContextManager;
-
-
-ContextManager::ContextManager() {
- // Initialize context slot occupation table to false
- for (size_t i = 0; i < ContextSlotCount; ++i) {
- mContextSlotOccupied[i] = false;
- }
-}
-
-char *ContextManager::allocateContext() {
- {
- // Acquire mContextSlotOccupiedLock
- llvm::MutexGuard Locked(mContextSlotOccupiedLock);
-
- // Try to allocate context on the managed context slot.
- for (size_t i = 0; i < ContextSlotCount; ++i) {
- if (mContextSlotOccupied[i]) {
- continue;
- }
-
- void *addr = ContextFixedAddr + ContextSize * i;
- void *result = mmap(addr, ContextSize,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANON, -1, 0);
-
- if (result == addr) {
- ALOGI("Allocate bcc context. addr=%p\n", result);
- mContextSlotOccupied[i] = true;
- return static_cast<char *>(result);
- }
-
- if (result && result != MAP_FAILED) {
- ALOGE("Unable to allocate. suggested=%p, result=%p\n", addr, result);
- munmap(result, ContextSize);
- }
-
- ALOGE("Unable to allocate. addr=%p. Retry ...\n", addr);
- }
- // Release mContextSlotOccupiedLock
- }
-
- // No slot available, allocate at arbitary address.
- void *result = mmap(0, ContextSize, PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE | MAP_ANON, -1, 0);
-
- if (!result || result == MAP_FAILED) {
- ALOGE("Unable to mmap. (reason: %s)\n", strerror(errno));
- return NULL;
- }
-
- ALOGI("Allocate bcc context. addr=%p\n", result);
- return static_cast<char *>(result);
-}
-
-
-char *ContextManager::allocateContext(char *addr,
- int imageFd, off_t imageOffset) {
- // This function should only allocate context when address is an context
- // slot address. And the image offset is aligned to the pagesize.
-
- if (imageFd < 0) {
- ALOGE("Invalid file descriptor for bcc context image\n");
- return NULL;
- }
-
- unsigned long pagesize = (unsigned long)sysconf(_SC_PAGESIZE);
-
- if (imageOffset % pagesize > 0) {
- ALOGE("BCC context image offset is not aligned to page size\n");
- return NULL;
- }
-
- ssize_t slot = getSlotIndexFromAddress(addr);
- if (slot < 0) {
- ALOGE("Suggested address is not a bcc context slot address\n");
- return NULL;
- }
-
- llvm::MutexGuard Locked(mContextSlotOccupiedLock);
- if (mContextSlotOccupied[slot]) {
- ALOGW("Suggested bcc context slot has been occupied.\n");
- return NULL;
- }
-
- // ALOGI("addr=%x, imageFd=%d, imageOffset=%x", addr, imageFd, imageOffset);
- void *result = mmap(addr, ContextSize,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_PRIVATE, imageFd, imageOffset);
-
- if (!result || result == MAP_FAILED) {
- ALOGE("Unable to allocate. addr=%p\n", addr);
- return NULL;
- }
-
- if (result != addr) {
- ALOGE("Unable to allocate at suggested=%p, result=%p\n", addr, result);
- munmap(result, ContextSize);
- return NULL;
- }
-
- ALOGI("Allocate bcc context. addr=%p\n", addr);
- mContextSlotOccupied[slot] = true;
- return static_cast<char *>(result);
-}
-
-
-void ContextManager::deallocateContext(char *addr) {
- if (!addr) {
- return;
- }
-
- llvm::MutexGuard Locked(mContextSlotOccupiedLock);
-
- ALOGI("Deallocate bcc context. addr=%p\n", addr);
-
- // Unmap
- if (munmap(addr, ContextSize) < 0) {
- ALOGE("Unable to unmap. addr=%p (reason: %s)\n", addr, strerror(errno));
- return;
- }
-
- // If the address is one of the context slot, then mark such slot
- // freely available as well.
- ssize_t slot = getSlotIndexFromAddress(addr);
- if (slot >= 0) {
- // Give the context slot back.
- mContextSlotOccupied[slot] = false;
- }
-}
-
-
-bool ContextManager::isManagingContext(char *addr) const {
- ssize_t slot = getSlotIndexFromAddress(addr);
-
- if (slot < 0) {
- return false;
- }
-
- llvm::MutexGuard Locked(mContextSlotOccupiedLock);
- return mContextSlotOccupied[slot];
-}
-
-
-ssize_t ContextManager::getSlotIndexFromAddress(char *addr) {
- if (addr >= ContextFixedAddr) {
- size_t offset = (size_t)(addr - ContextFixedAddr);
- if (offset % ContextSize == 0) {
- size_t slot = offset / ContextSize;
- if (slot < ContextSlotCount) {
- return slot;
- }
- }
- }
- return -1;
-}
-
-
-
-} // namespace bcc
diff --git a/lib/ExecutionEngine/OldJIT/ContextManager.h b/lib/ExecutionEngine/OldJIT/ContextManager.h
deleted file mode 100644
index f23c4a1..0000000
--- a/lib/ExecutionEngine/OldJIT/ContextManager.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * copyright 2010, the android open source project
- *
- * licensed under the apache license, version 2.0 (the "license");
- * you may not use this file except in compliance with the license.
- * you may obtain a copy of the license at
- *
- * http://www.apache.org/licenses/license-2.0
- *
- * unless required by applicable law or agreed to in writing, software
- * distributed under the license is distributed on an "as is" basis,
- * without warranties or conditions of any kind, either express or implied.
- * see the license for the specific language governing permissions and
- * limitations under the license.
- */
-
-#ifndef BCC_CONTEXTMANAGER_H
-#define BCC_CONTEXTMANAGER_H
-
-#include <Config.h>
-
-#include <llvm/Support/Mutex.h>
-
-#include <unistd.h>
-#include <stddef.h>
-
-
-namespace bcc {
-
- class ContextManager {
- public:
- // Starting address of context slot address space
- static char * const ContextFixedAddr;
-
- // Number of the context slots
- static size_t const ContextSlotCount = BCC_CONTEXT_SLOT_COUNT_;
-
- // Context size
- static size_t const ContextCodeSize = BCC_CONTEXT_CODE_SIZE_;
- static size_t const ContextDataSize = BCC_CONTEXT_DATA_SIZE_;
- static size_t const ContextSize = ContextCodeSize + ContextDataSize;
-
- private:
- // Context manager singleton
- static ContextManager TheContextManager;
-
- private:
- // Mutex lock for context slot occupation table
- mutable llvm::sys::Mutex mContextSlotOccupiedLock;
-
- // Context slot occupation table
- bool mContextSlotOccupied[ContextSlotCount];
-
- ContextManager();
-
- public:
- static ContextManager &get() {
- return TheContextManager;
- }
-
- char *allocateContext();
- char *allocateContext(char *addr, int imageFd, off_t imageOffset);
- void deallocateContext(char *addr);
-
- bool isManagingContext(char *addr) const;
-
- private:
- static ssize_t getSlotIndexFromAddress(char *addr);
-
- };
-
-} // namespace bcc
-
-#endif // BCC_CONTEXTMANAGER_H
diff --git a/lib/ExecutionEngine/Script.cpp b/lib/ExecutionEngine/Script.cpp
index 4b0b406..445d075 100644
--- a/lib/ExecutionEngine/Script.cpp
+++ b/lib/ExecutionEngine/Script.cpp
@@ -18,19 +18,10 @@
#include "Config.h"
-#if USE_OLD_JIT
-#include "OldJIT/CacheReader.h"
-#include "OldJIT/CacheWriter.h"
-#endif
-
#include "MCCacheReader.h"
#include "MCCacheWriter.h"
#include "CompilerOption.h"
-#if USE_OLD_JIT
-#include "OldJIT/ContextManager.h"
-#endif
-
#include "DebugHelper.h"
#include "FileHandle.h"
#include "GDBJITRegistrar.h"
@@ -66,11 +57,9 @@
delete mCompiled;
break;
-#if USE_CACHE
case ScriptStatus::Cached:
delete mCached;
break;
-#endif
default:
break;
@@ -230,10 +219,7 @@
return 1;
}
- int status = -1;
-#if USE_CACHE
- status = internalLoadCache(cacheDir, cacheName, /* checkOnly */ false);
-#endif
+ int status = internalLoadCache(cacheDir, cacheName, /* checkOnly */ false);
if (status != 0) {
CompilerOption option;
@@ -259,7 +245,6 @@
return status;
}
-#if USE_CACHE
int Script::internalLoadCache(char const *cacheDir, char const *cacheName,
bool checkOnly) {
if ((cacheDir == NULL) || (cacheName == NULL)) {
@@ -294,9 +279,6 @@
return 1;
}
-#if USE_OLD_JIT
- CacheReader reader;
-#elif USE_MCJIT
MCCacheReader reader;
// Register symbol lookup function
@@ -304,7 +286,6 @@
reader.registerSymbolCallback(mpExtSymbolLookupFn,
mpExtSymbolLookupFnContext);
}
-#endif
// Dependencies
reader.addDependency(BCC_FILE_RESOURCE, pathLibBCC_SHA1, sha1LibBCC_SHA1);
@@ -338,7 +319,6 @@
return 0;
}
-#endif
int Script::internalCompile(const CompilerOption &option) {
// Create the ScriptCompiled object
@@ -406,19 +386,13 @@
(getCompilerErrorMessage() == NULL))
return 1;
-#if USE_CACHE
// Note: If we re-compile the script because the cached context slot not
// available, then we don't have to write the cache.
// Note: If the address of the context is not in the context slot, then
// we don't have to cache it.
- if (
-#if USE_OLD_JIT
- !mIsContextSlotNotAvail &&
- ContextManager::get().isManagingContext(getContext()) &&
-#endif
- isCacheable()) {
+ if (isCacheable()) {
std::string objPath = getCachedObjectPath();
std::string infoPath = getCacheInfoPath();
@@ -428,9 +402,7 @@
// to modify its contents. (The same script may be running concurrently in
// the same process or a different process!)
::unlink(objPath.c_str());
-#if !USE_OLD_JIT && USE_MCJIT
::unlink(infoPath.c_str());
-#endif
FileHandle objFile;
FileHandle infoFile;
@@ -438,11 +410,7 @@
if (objFile.open(objPath.c_str(), OpenMode::Write) >= 0 &&
infoFile.open(infoPath.c_str(), OpenMode::Write) >= 0) {
-#if USE_OLD_JIT
- CacheWriter writer;
-#elif USE_MCJIT
MCCacheWriter writer;
-#endif
#ifdef TARGET_BUILD
// Dependencies
@@ -484,7 +452,6 @@
}
}
}
-#endif // USE_CACHE
return 0;
}
@@ -506,11 +473,9 @@
return mCompiled->lookup(name);
}
-#if USE_CACHE
case ScriptStatus::Cached: {
return mCached->lookup(name);
}
-#endif
default: {
mErrorCode = BCC_INVALID_OPERATION;
@@ -526,11 +491,9 @@
return mCompiled->getExportVarCount();
}
-#if USE_CACHE
case ScriptStatus::Cached: {
return mCached->getExportVarCount();
}
-#endif
default: {
return 0;
@@ -545,11 +508,9 @@
return mCompiled->getExportFuncCount();
}
-#if USE_CACHE
case ScriptStatus::Cached: {
return mCached->getExportFuncCount();
}
-#endif
default: {
return 0;
@@ -564,11 +525,9 @@
return mCompiled->getExportForEachCount();
}
-#if USE_CACHE
case ScriptStatus::Cached: {
return mCached->getExportForEachCount();
}
-#endif
default: {
return 0;
@@ -583,11 +542,9 @@
return mCompiled->getPragmaCount();
}
-#if USE_CACHE
case ScriptStatus::Cached: {
return mCached->getPragmaCount();
}
-#endif
default: {
return 0;
@@ -602,11 +559,9 @@
return mCompiled->getFuncCount();
}
-#if USE_CACHE
case ScriptStatus::Cached: {
return mCached->getFuncCount();
}
-#endif
default: {
return 0;
@@ -621,11 +576,9 @@
return mCompiled->getObjectSlotCount();
}
-#if USE_CACHE
case ScriptStatus::Cached: {
return mCached->getObjectSlotCount();
}
-#endif
default: {
return 0;
@@ -641,9 +594,7 @@
m##STATUS->getExportVarList(varListSize, varList); \
break;
-#if USE_CACHE
DELEGATE(Cached);
-#endif
DELEGATE(Compiled);
#undef DELEGATE
@@ -674,9 +625,7 @@
m##STATUS->getExportFuncList(funcListSize, funcList); \
break;
-#if USE_CACHE
DELEGATE(Cached);
-#endif
DELEGATE(Compiled);
#undef DELEGATE
@@ -706,9 +655,7 @@
m##STATUS->getExportForEachList(funcListSize, funcList); \
break;
-#if USE_CACHE
DELEGATE(Cached);
-#endif
DELEGATE(Compiled);
#undef DELEGATE
@@ -740,9 +687,7 @@
m##STATUS->getPragmaList(pragmaListSize, keyList, valueList); \
break;
-#if USE_CACHE
DELEGATE(Cached);
-#endif
DELEGATE(Compiled);
#undef DELEGATE
@@ -762,9 +707,7 @@
m##STATUS->getFuncInfoList(funcInfoListSize, funcInfoList); \
break;
-#if USE_CACHE
DELEGATE(Cached);
-#endif
DELEGATE(Compiled);
#undef DELEGATE
@@ -784,9 +727,7 @@
m##STATUS->getObjectSlotList(objectSlotListSize, objectSlotList); \
break;
-#if USE_CACHE
DELEGATE(Cached);
-#endif
DELEGATE(Compiled);
#undef DELEGATE
@@ -798,29 +739,6 @@
}
-#if USE_OLD_JIT
-char *Script::getContext() {
- switch (mStatus) {
-
-#if USE_CACHE
- case ScriptStatus::Cached: {
- return mCached->getContext();
- }
-#endif
-
- case ScriptStatus::Compiled: {
- return mCompiled->getContext();
- }
-
- default: {
- mErrorCode = BCC_INVALID_OPERATION;
- return NULL;
- }
- }
-}
-#endif
-
-
int Script::registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
mpExtSymbolLookupFn = pFn;
mpExtSymbolLookupFnContext = pContext;
@@ -834,7 +752,6 @@
}
bool Script::isCacheable() const {
-#if USE_CACHE
if (getBooleanProp("debug.bcc.nocache")) {
// Android system environment property: Disables the cache mechanism by
// setting "debug.bcc.nocache". So we will not load the cache file any
@@ -849,22 +766,18 @@
}
return true;
-#else
- return false;
-#endif
}
-#if USE_MCJIT
size_t Script::getELFSize() const {
switch (mStatus) {
case ScriptStatus::Compiled: {
return mCompiled->getELFSize();
}
-#if USE_CACHE
+
case ScriptStatus::Cached: {
return mCached->getELFSize();
}
-#endif
+
default: {
return 0;
}
@@ -876,16 +789,15 @@
case ScriptStatus::Compiled: {
return mCompiled->getELF();
}
-#if USE_CACHE
+
case ScriptStatus::Cached: {
return mCached->getELF();
}
-#endif
+
default: {
return NULL;
}
}
}
-#endif
} // namespace bcc
diff --git a/lib/ExecutionEngine/Script.h b/lib/ExecutionEngine/Script.h
index b05fc07..16a453c 100644
--- a/lib/ExecutionEngine/Script.h
+++ b/lib/ExecutionEngine/Script.h
@@ -44,9 +44,7 @@
enum StatusType {
Unknown,
Compiled,
-#if USE_CACHE
- Cached,
-#endif
+ Cached
};
}
@@ -71,31 +69,19 @@
union {
ScriptCompiled *mCompiled;
-#if USE_CACHE
ScriptCached *mCached;
-#endif
};
-#if USE_CACHE
std::string mCacheDir;
std::string mCacheName;
inline std::string getCachedObjectPath() const {
-#if USE_OLD_JIT
- return std::string(mCacheDir + mCacheName + ".jit-image");
-#elif USE_MCJIT
return std::string(mCacheDir + mCacheName + ".o");
-#endif
}
inline std::string getCacheInfoPath() const {
-#if USE_OLD_JIT
- return getCachedObjectPath().append(".oBCC");
-#elif USE_MCJIT
return getCachedObjectPath().append(".info");
-#endif
}
-#endif
bool mIsContextSlotNotAvail;
@@ -217,10 +203,6 @@
int registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext);
-#if USE_OLD_JIT
- char *getContext();
-#endif
-
bool isCacheable() const;
void setError(int error) {
@@ -236,14 +218,13 @@
}
private:
-#if USE_CACHE
//
// It returns 0 if there's a cache hit.
//
// Side effect: it will set mCacheDir, mCacheName.
int internalLoadCache(char const *cacheDir, char const *cacheName,
bool checkOnly);
-#endif
+
int internalCompile(const CompilerOption&);
};
diff --git a/lib/ExecutionEngine/ScriptCached.cpp b/lib/ExecutionEngine/ScriptCached.cpp
index 30fc3fd..bbfac2b 100644
--- a/lib/ExecutionEngine/ScriptCached.cpp
+++ b/lib/ExecutionEngine/ScriptCached.cpp
@@ -18,12 +18,6 @@
#include "ScriptCached.h"
-#include <bcc/bcc_cache.h>
-
-#if USE_OLD_JIT
-#include "OldJIT/ContextManager.h"
-#endif
-
#include "DebugHelper.h"
#include <stdlib.h>
@@ -31,13 +25,6 @@
namespace bcc {
ScriptCached::~ScriptCached() {
- // Deallocate the bcc script context
-#if USE_OLD_JIT
- if (mContext) {
- ContextManager::get().deallocateContext(mContext);
- }
-#endif
-
// Deallocate string pool, exported var list, exported func list
if (mpStringPoolRaw) { free(mpStringPoolRaw); }
if (mpExportVars) { free(mpExportVars); }
@@ -127,11 +114,7 @@
void *ScriptCached::lookup(const char *name) {
-#if USE_MCJIT
return rsloaderGetSymbolAddress(mRSExecutable, name);
-#endif
- FuncTable::const_iterator I = mFunctions.find(name);
- return (I == mFunctions.end()) ? NULL : I->second.first;
}
void ScriptCached::getFuncInfoList(size_t funcInfoListSize,
diff --git a/lib/ExecutionEngine/ScriptCached.h b/lib/ExecutionEngine/ScriptCached.h
index f18cb88..e24a714 100644
--- a/lib/ExecutionEngine/ScriptCached.h
+++ b/lib/ExecutionEngine/ScriptCached.h
@@ -20,13 +20,10 @@
#include "Config.h"
#include <bcc/bcc.h>
-#include <bcc/bcc_cache.h>
#include <bcc/bcc_mccache.h>
#include "bcc_internal.h"
-#if USE_MCJIT
#include "librsloader.h"
-#endif
#include <llvm/ADT/SmallVector.h>
@@ -59,24 +56,18 @@
private:
Script *mpOwner;
- OBCC_ExportVarList *mpExportVars;
- OBCC_ExportFuncList *mpExportFuncs;
- OBCC_ExportForEachList *mpExportForEach;
+ MCO_ExportVarList *mpExportVars;
+ MCO_ExportFuncList *mpExportFuncs;
+ MCO_ExportForEachList *mpExportForEach;
PragmaList mPragmas;
- OBCC_ObjectSlotList *mpObjectSlotList;
+ MCO_ObjectSlotList *mpObjectSlotList;
FuncTable mFunctions;
-#if USE_OLD_JIT
- char *mContext;
-#endif
-
-#if USE_MCJIT
RSExecRef mRSExecutable;
llvm::SmallVector<char, 1024> mCachedELFExecutable;
-#endif
- OBCC_StringPool *mpStringPoolRaw;
+ MCO_StringPool *mpStringPoolRaw;
std::vector<char const *> mStringPool;
bool mLibRSThreadable;
@@ -88,9 +79,6 @@
mpExportFuncs(NULL),
mpExportForEach(NULL),
mpObjectSlotList(NULL),
-#if USE_OLD_JIT
- mContext(NULL),
-#endif
mpStringPoolRaw(NULL),
mLibRSThreadable(false) {
}
@@ -139,13 +127,6 @@
void getObjectSlotList(size_t objectSlotListSize,
uint32_t *objectSlotList);
-#if USE_OLD_JIT
- char *getContext() {
- return mContext;
- }
-#endif
-
-#if USE_MCJIT
const char *getELF() const {
return &*mCachedELFExecutable.begin();
}
@@ -153,7 +134,7 @@
size_t getELFSize() const {
return mCachedELFExecutable.size();
}
-#endif
+
// Dirty hack for libRS.
// TODO(all): This should be removed in the future.
bool isLibRSThreadable() const {
diff --git a/lib/ExecutionEngine/ScriptCompiled.cpp b/lib/ExecutionEngine/ScriptCompiled.cpp
index 47f2bb4..4f2bb1b 100644
--- a/lib/ExecutionEngine/ScriptCompiled.cpp
+++ b/lib/ExecutionEngine/ScriptCompiled.cpp
@@ -17,28 +17,11 @@
#include "ScriptCompiled.h"
#include "bcc_internal.h"
-#if USE_OLD_JIT
-#include "OldJIT/ContextManager.h"
-#endif
#include "DebugHelper.h"
namespace bcc {
ScriptCompiled::~ScriptCompiled() {
-#if USE_OLD_JIT
- // Deallocate the BCC context
- if (mContext) {
- ContextManager::get().deallocateContext(mContext);
- }
-
- // Delete the emitted function information
- for (FuncInfoMap::iterator I = mEmittedFunctions.begin(),
- E = mEmittedFunctions.end(); I != E; I++) {
- if (I->second != NULL) {
- delete I->second;
- }
- }
-#endif
}
void ScriptCompiled::getExportVarList(size_t varListSize, void **varList) {
@@ -126,16 +109,7 @@
void *ScriptCompiled::lookup(const char *name) {
-#if USE_OLD_JIT
- FuncInfoMap::const_iterator I = mEmittedFunctions.find(name);
- return (I == mEmittedFunctions.end()) ? NULL : I->second->addr;
-#endif
-
-#if USE_MCJIT
return mCompiler.getSymbolAddress(name);
-#endif
-
- return NULL;
}
diff --git a/lib/ExecutionEngine/ScriptCompiled.h b/lib/ExecutionEngine/ScriptCompiled.h
index 4498f1a..d945024 100644
--- a/lib/ExecutionEngine/ScriptCompiled.h
+++ b/lib/ExecutionEngine/ScriptCompiled.h
@@ -65,16 +65,9 @@
FuncInfoMap mEmittedFunctions;
-#if USE_OLD_JIT
- char *mContext; // Context of BCC script (code and data)
-#endif
-
public:
ScriptCompiled(Script *owner)
: mpOwner(owner), mCompiler(this)
-#if USE_OLD_JIT
- , mContext(NULL)
-#endif
{
}
@@ -149,13 +142,6 @@
return mpOwner->getUserDefinedExternalSymbols();
}
-#if USE_OLD_JIT
- char *getContext() {
- return mContext;
- }
-#endif
-
-#if USE_MCJIT
const char *getELF() const {
return &*mCompiler.getELF().begin();
}
@@ -163,7 +149,6 @@
size_t getELFSize() const {
return mCompiler.getELF().size();
}
-#endif
void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
mCompiler.registerSymbolCallback(pFn, pContext);
diff --git a/lib/ExecutionEngine/SourceInfo.cpp b/lib/ExecutionEngine/SourceInfo.cpp
index 25c53e8..c069462 100644
--- a/lib/ExecutionEngine/SourceInfo.cpp
+++ b/lib/ExecutionEngine/SourceInfo.cpp
@@ -16,23 +16,14 @@
#include "SourceInfo.h"
-#if USE_CACHE
-#if USE_OLD_JIT
-#include "OldJIT/CacheReader.h"
-#include "OldJIT/CacheWriter.h"
-#endif
-#if USE_MCJIT
#include "MCCacheWriter.h"
#include "MCCacheReader.h"
-#endif
-#endif
#include "DebugHelper.h"
#include "ScriptCompiled.h"
#include "Sha1Helper.h"
#include <bcc/bcc.h>
-#include <bcc/bcc_cache.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/Module.h>
@@ -64,7 +55,6 @@
result->buffer.bitcodeSize = bitcodeSize;
result->flags = flags;
-#if USE_CACHE
if (!resName && !(flags & BCC_SKIP_DEP_SHA1)) {
result->flags |= BCC_SKIP_DEP_SHA1;
@@ -78,7 +68,6 @@
} else {
calcSHA1(result->sha1, bitcode, bitcodeSize);
}
-#endif
return result;
}
@@ -96,13 +85,11 @@
result->file.path = path;
result->flags = flags;
-#if USE_CACHE
memset(result->sha1, '\0', 20);
if (!(result->flags & BCC_SKIP_DEP_SHA1)) {
calcFileSHA1(result->sha1, path);
}
-#endif
return result;
}
@@ -120,7 +107,6 @@
result->module = module;
result->flags = flags;
-#if USE_CACHE
if (! (flags & BCC_SKIP_DEP_SHA1)) {
result->flags |= BCC_SKIP_DEP_SHA1;
@@ -130,7 +116,6 @@
}
memset(result->sha1, '\0', 20);
-#endif
return result;
}
@@ -196,7 +181,6 @@
}
}
-#if USE_CACHE
template <typename T> void SourceInfo::introDependency(T &checker) {
if (flags & BCC_SKIP_DEP_SHA1) {
return;
@@ -216,16 +200,8 @@
}
}
-#if USE_OLD_JIT
-template void SourceInfo::introDependency<CacheReader>(CacheReader &);
-template void SourceInfo::introDependency<CacheWriter>(CacheWriter &);
-#endif
-
-#if USE_MCJIT
template void SourceInfo::introDependency<MCCacheWriter>(MCCacheWriter &);
template void SourceInfo::introDependency<MCCacheReader>(MCCacheReader &);
-#endif
-#endif // USE_CACHE
} // namespace bcc
diff --git a/lib/ExecutionEngine/SourceInfo.h b/lib/ExecutionEngine/SourceInfo.h
index 9026f1c..080d3b4 100644
--- a/lib/ExecutionEngine/SourceInfo.h
+++ b/lib/ExecutionEngine/SourceInfo.h
@@ -61,9 +61,7 @@
unsigned long flags;
-#if USE_CACHE
unsigned char sha1[20];
-#endif
private:
SourceInfo() : module(NULL), shared_context(false) { }
@@ -91,9 +89,7 @@
// Share with the given context if it's provided.
int prepareModule(llvm::LLVMContext *context = NULL);
-#if USE_CACHE
template <typename T> void introDependency(T &checker);
-#endif
~SourceInfo();
};
diff --git a/libbcc-config.mk b/libbcc-config.mk
index dc3ab33..37cc848 100644
--- a/libbcc-config.mk
+++ b/libbcc-config.mk
@@ -28,33 +28,19 @@
# Configurations
#=====================================================================
-libbcc_USE_OLD_JIT := 0
-libbcc_USE_MCJIT := 1
-
-libbcc_USE_CACHE := 1
-
-libbcc_DEBUG_OLD_JIT_DISASSEMBLER := 0
-libbcc_DEBUG_MCJIT_DISASSEMBLER := 0
+libbcc_DEBUG_MC_DISASSEMBLER := 0
libbcc_USE_LOGGER := 1
libbcc_USE_FUNC_LOGGER := 0
libbcc_DEBUG_BCC_REFLECT := 0
-libbcc_DEBUG_MCJIT_REFLECT := 0
+libbcc_DEBUG_MC_REFLECT := 0
#=====================================================================
# Automatic Configurations
#=====================================================================
-ifeq ($(libbcc_USE_OLD_JIT),0)
-libbcc_DEBUG_OLD_JIT_DISASSEMBLER := 0
-endif
-
-ifeq ($(libbcc_USE_MCJIT),0)
-libbcc_DEBUG_MCJIT_DISASSEMBLER := 0
-endif
-
-ifeq ($(libbcc_DEBUG_OLD_JIT_DISASSEMBLER)$(libbcc_DEBUG_MCJIT_DISASSEMBLER),00)
+ifeq ($(libbcc_DEBUG_MC_DISASSEMBLER),0)
libbcc_USE_DISASSEMBLER := 0
else
libbcc_USE_DISASSEMBLER := 1