am f8bbb844: Add code size to oat files
* commit 'f8bbb8448c733e9e3ad43aad69774c37888329b1':
Add code size to oat files
diff --git a/build/Android.libart-compiler-llvm.mk b/build/Android.libart-compiler-llvm.mk
index 1b584d6..bb7b458 100644
--- a/build/Android.libart-compiler-llvm.mk
+++ b/build/Android.libart-compiler-llvm.mk
@@ -83,11 +83,11 @@
libLLVMARMCodeGen \
libLLVMARMDesc
-# libart_compiler_llvm_mips_STATIC_LIBRARIES := \
-# libLLVMMipsInfo \
-# libLLVMMipsCodeGen \
-# libLLVMMipsDesc \
-# libLLVMMipsAsmPrinter \
+ libart_compiler_llvm_mips_STATIC_LIBRARIES := \
+ libLLVMMipsInfo \
+ libLLVMMipsCodeGen \
+ libLLVMMipsDesc \
+ libLLVMMipsAsmPrinter \
libart_compiler_llvm_x86_STATIC_LIBRARIES := \
libLLVMX86Info \
diff --git a/build/Android.libart.mk b/build/Android.libart.mk
index aa00a31..5bc8f46 100644
--- a/build/Android.libart.mk
+++ b/build/Android.libart.mk
@@ -88,11 +88,11 @@
libLLVMARMCodeGen \
libLLVMARMDesc
-# libart_mips_STATIC_LIBRARIES := \
-# libLLVMMipsInfo \
-# libLLVMMipsCodeGen \
-# libLLVMMipsDesc \
-# libLLVMMipsAsmPrinter \
+ libart_mips_STATIC_LIBRARIES := \
+ libLLVMMipsInfo \
+ libLLVMMipsCodeGen \
+ libLLVMMipsDesc \
+ libLLVMMipsAsmPrinter \
libart_x86_STATIC_LIBRARIES := \
libLLVMX86Info \
diff --git a/src/asm_support.h b/src/asm_support.h
index 6ba23bc..bcad9ad 100644
--- a/src/asm_support.h
+++ b/src/asm_support.h
@@ -30,7 +30,7 @@
#elif defined(__i386__)
// Offset of field Thread::self_ verified in InitCpu
-#define THREAD_SELF_OFFSET 108
+#define THREAD_SELF_OFFSET 112
#endif
#endif // ART_SRC_ASM_SUPPORT_H_
diff --git a/src/compiler_llvm/art_module.ll b/src/compiler_llvm/art_module.ll
index 39fbec7..78d388b 100644
--- a/src/compiler_llvm/art_module.ll
+++ b/src/compiler_llvm/art_module.ll
@@ -21,14 +21,14 @@
%JavaObject = type opaque
-%ArtFrame = type { %ArtFrame* ; Previous frame (sirt)
- , %JavaObject* ; Method object pointer
- , i32 ; Line number for stack backtrace
- , i32 ; Size of SIRT
- ; [0 x %JavaObject*] ; Stack indirect reference table
- }
+%ShadowFrame = type { %ShadowFrame* ; Previous frame
+ , %JavaObject* ; Method object pointer
+ , i32 ; Line number for stack backtrace
+ , i32 ; Number of references
+ ; [0 x %JavaObject*] ; References
+ }
-declare void @__art_type_list(%JavaObject*, %ArtFrame*)
+declare void @__art_type_list(%JavaObject*, %ShadowFrame*)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -43,7 +43,7 @@
declare void @art_test_suspend_from_code()
-declare void @art_push_shadow_frame_from_code(%ArtFrame*)
+declare void @art_push_shadow_frame_from_code(%ShadowFrame*)
declare void @art_pop_shadow_frame_from_code()
diff --git a/src/compiler_llvm/generated/art_module.cc b/src/compiler_llvm/generated/art_module.cc
index dedc392..fe708ae 100644
--- a/src/compiler_llvm/generated/art_module.cc
+++ b/src/compiler_llvm/generated/art_module.cc
@@ -39,19 +39,19 @@
PointerType* PointerTy_1 = PointerType::get(StructTy_JavaObject, 0);
FuncTy_0_args.push_back(PointerTy_1);
-StructType *StructTy_ArtFrame = mod->getTypeByName("ArtFrame");
-if (!StructTy_ArtFrame) {
-StructTy_ArtFrame = StructType::create(mod->getContext(), "ArtFrame");
+StructType *StructTy_ShadowFrame = mod->getTypeByName("ShadowFrame");
+if (!StructTy_ShadowFrame) {
+StructTy_ShadowFrame = StructType::create(mod->getContext(), "ShadowFrame");
}
-std::vector<Type*>StructTy_ArtFrame_fields;
-PointerType* PointerTy_2 = PointerType::get(StructTy_ArtFrame, 0);
+std::vector<Type*>StructTy_ShadowFrame_fields;
+PointerType* PointerTy_2 = PointerType::get(StructTy_ShadowFrame, 0);
-StructTy_ArtFrame_fields.push_back(PointerTy_2);
-StructTy_ArtFrame_fields.push_back(PointerTy_1);
-StructTy_ArtFrame_fields.push_back(IntegerType::get(mod->getContext(), 32));
-StructTy_ArtFrame_fields.push_back(IntegerType::get(mod->getContext(), 32));
-if (StructTy_ArtFrame->isOpaque()) {
-StructTy_ArtFrame->setBody(StructTy_ArtFrame_fields, /*isPacked=*/false);
+StructTy_ShadowFrame_fields.push_back(PointerTy_2);
+StructTy_ShadowFrame_fields.push_back(PointerTy_1);
+StructTy_ShadowFrame_fields.push_back(IntegerType::get(mod->getContext(), 32));
+StructTy_ShadowFrame_fields.push_back(IntegerType::get(mod->getContext(), 32));
+if (StructTy_ShadowFrame->isOpaque()) {
+StructTy_ShadowFrame->setBody(StructTy_ShadowFrame_fields, /*isPacked=*/false);
}
@@ -142,26 +142,26 @@
/*isVarArg=*/false);
std::vector<Type*>FuncTy_14_args;
-FuncTy_14_args.push_back(PointerTy_1);
FuncTy_14_args.push_back(IntegerType::get(mod->getContext(), 32));
+FuncTy_14_args.push_back(PointerTy_1);
+FuncTy_14_args.push_back(PointerTy_1);
FunctionType* FuncTy_14 = FunctionType::get(
/*Result=*/PointerTy_1,
/*Params=*/FuncTy_14_args,
/*isVarArg=*/false);
std::vector<Type*>FuncTy_15_args;
-FuncTy_15_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_15_args.push_back(PointerTy_1);
FuncTy_15_args.push_back(IntegerType::get(mod->getContext(), 32));
FunctionType* FuncTy_15 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
+ /*Result=*/PointerTy_1,
/*Params=*/FuncTy_15_args,
/*isVarArg=*/false);
std::vector<Type*>FuncTy_16_args;
FuncTy_16_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_16_args.push_back(PointerTy_1);
-FuncTy_16_args.push_back(IntegerType::get(mod->getContext(), 64));
+FuncTy_16_args.push_back(IntegerType::get(mod->getContext(), 32));
FunctionType* FuncTy_16 = FunctionType::get(
/*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_16_args,
@@ -170,7 +170,7 @@
std::vector<Type*>FuncTy_17_args;
FuncTy_17_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_17_args.push_back(PointerTy_1);
-FuncTy_17_args.push_back(PointerTy_1);
+FuncTy_17_args.push_back(IntegerType::get(mod->getContext(), 64));
FunctionType* FuncTy_17 = FunctionType::get(
/*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_17_args,
@@ -179,6 +179,7 @@
std::vector<Type*>FuncTy_18_args;
FuncTy_18_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_18_args.push_back(PointerTy_1);
+FuncTy_18_args.push_back(PointerTy_1);
FunctionType* FuncTy_18 = FunctionType::get(
/*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_18_args,
@@ -188,17 +189,15 @@
FuncTy_19_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_19_args.push_back(PointerTy_1);
FunctionType* FuncTy_19 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 64),
+ /*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_19_args,
/*isVarArg=*/false);
std::vector<Type*>FuncTy_20_args;
FuncTy_20_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_20_args.push_back(PointerTy_1);
-FuncTy_20_args.push_back(PointerTy_1);
-FuncTy_20_args.push_back(IntegerType::get(mod->getContext(), 32));
FunctionType* FuncTy_20 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 32),
+ /*Result=*/IntegerType::get(mod->getContext(), 64),
/*Params=*/FuncTy_20_args,
/*isVarArg=*/false);
@@ -206,7 +205,7 @@
FuncTy_21_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_21_args.push_back(PointerTy_1);
FuncTy_21_args.push_back(PointerTy_1);
-FuncTy_21_args.push_back(IntegerType::get(mod->getContext(), 64));
+FuncTy_21_args.push_back(IntegerType::get(mod->getContext(), 32));
FunctionType* FuncTy_21 = FunctionType::get(
/*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_21_args,
@@ -216,7 +215,7 @@
FuncTy_22_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_22_args.push_back(PointerTy_1);
FuncTy_22_args.push_back(PointerTy_1);
-FuncTy_22_args.push_back(PointerTy_1);
+FuncTy_22_args.push_back(IntegerType::get(mod->getContext(), 64));
FunctionType* FuncTy_22 = FunctionType::get(
/*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_22_args,
@@ -226,8 +225,9 @@
FuncTy_23_args.push_back(IntegerType::get(mod->getContext(), 32));
FuncTy_23_args.push_back(PointerTy_1);
FuncTy_23_args.push_back(PointerTy_1);
+FuncTy_23_args.push_back(PointerTy_1);
FunctionType* FuncTy_23 = FunctionType::get(
- /*Result=*/IntegerType::get(mod->getContext(), 64),
+ /*Result=*/IntegerType::get(mod->getContext(), 32),
/*Params=*/FuncTy_23_args,
/*isVarArg=*/false);
@@ -236,7 +236,7 @@
FuncTy_24_args.push_back(PointerTy_1);
FuncTy_24_args.push_back(PointerTy_1);
FunctionType* FuncTy_24 = FunctionType::get(
- /*Result=*/PointerTy_1,
+ /*Result=*/IntegerType::get(mod->getContext(), 64),
/*Params=*/FuncTy_24_args,
/*isVarArg=*/false);
@@ -526,7 +526,7 @@
Function* func_art_find_interface_method_from_code = mod->getFunction("art_find_interface_method_from_code");
if (!func_art_find_interface_method_from_code) {
func_art_find_interface_method_from_code = Function::Create(
- /*Type=*/FuncTy_24,
+ /*Type=*/FuncTy_14,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_find_interface_method_from_code", mod); // (external, no body)
func_art_find_interface_method_from_code->setCallingConv(CallingConv::C);
@@ -537,7 +537,7 @@
Function* func_art_find_virtual_method_from_code = mod->getFunction("art_find_virtual_method_from_code");
if (!func_art_find_virtual_method_from_code) {
func_art_find_virtual_method_from_code = Function::Create(
- /*Type=*/FuncTy_24,
+ /*Type=*/FuncTy_14,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_find_virtual_method_from_code", mod); // (external, no body)
func_art_find_virtual_method_from_code->setCallingConv(CallingConv::C);
@@ -548,7 +548,7 @@
Function* func_art_find_super_method_from_code = mod->getFunction("art_find_super_method_from_code");
if (!func_art_find_super_method_from_code) {
func_art_find_super_method_from_code = Function::Create(
- /*Type=*/FuncTy_24,
+ /*Type=*/FuncTy_14,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_find_super_method_from_code", mod); // (external, no body)
func_art_find_super_method_from_code->setCallingConv(CallingConv::C);
@@ -592,7 +592,7 @@
Function* func_art_resolve_string_from_code = mod->getFunction("art_resolve_string_from_code");
if (!func_art_resolve_string_from_code) {
func_art_resolve_string_from_code = Function::Create(
- /*Type=*/FuncTy_14,
+ /*Type=*/FuncTy_15,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_resolve_string_from_code", mod); // (external, no body)
func_art_resolve_string_from_code->setCallingConv(CallingConv::C);
@@ -603,7 +603,7 @@
Function* func_art_set32_static_from_code = mod->getFunction("art_set32_static_from_code");
if (!func_art_set32_static_from_code) {
func_art_set32_static_from_code = Function::Create(
- /*Type=*/FuncTy_15,
+ /*Type=*/FuncTy_16,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_set32_static_from_code", mod); // (external, no body)
func_art_set32_static_from_code->setCallingConv(CallingConv::C);
@@ -614,7 +614,7 @@
Function* func_art_set64_static_from_code = mod->getFunction("art_set64_static_from_code");
if (!func_art_set64_static_from_code) {
func_art_set64_static_from_code = Function::Create(
- /*Type=*/FuncTy_16,
+ /*Type=*/FuncTy_17,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_set64_static_from_code", mod); // (external, no body)
func_art_set64_static_from_code->setCallingConv(CallingConv::C);
@@ -625,7 +625,7 @@
Function* func_art_set_obj_static_from_code = mod->getFunction("art_set_obj_static_from_code");
if (!func_art_set_obj_static_from_code) {
func_art_set_obj_static_from_code = Function::Create(
- /*Type=*/FuncTy_17,
+ /*Type=*/FuncTy_18,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_set_obj_static_from_code", mod); // (external, no body)
func_art_set_obj_static_from_code->setCallingConv(CallingConv::C);
@@ -636,7 +636,7 @@
Function* func_art_get32_static_from_code = mod->getFunction("art_get32_static_from_code");
if (!func_art_get32_static_from_code) {
func_art_get32_static_from_code = Function::Create(
- /*Type=*/FuncTy_18,
+ /*Type=*/FuncTy_19,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_get32_static_from_code", mod); // (external, no body)
func_art_get32_static_from_code->setCallingConv(CallingConv::C);
@@ -647,7 +647,7 @@
Function* func_art_get64_static_from_code = mod->getFunction("art_get64_static_from_code");
if (!func_art_get64_static_from_code) {
func_art_get64_static_from_code = Function::Create(
- /*Type=*/FuncTy_19,
+ /*Type=*/FuncTy_20,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_get64_static_from_code", mod); // (external, no body)
func_art_get64_static_from_code->setCallingConv(CallingConv::C);
@@ -669,7 +669,7 @@
Function* func_art_set32_instance_from_code = mod->getFunction("art_set32_instance_from_code");
if (!func_art_set32_instance_from_code) {
func_art_set32_instance_from_code = Function::Create(
- /*Type=*/FuncTy_20,
+ /*Type=*/FuncTy_21,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_set32_instance_from_code", mod); // (external, no body)
func_art_set32_instance_from_code->setCallingConv(CallingConv::C);
@@ -680,7 +680,7 @@
Function* func_art_set64_instance_from_code = mod->getFunction("art_set64_instance_from_code");
if (!func_art_set64_instance_from_code) {
func_art_set64_instance_from_code = Function::Create(
- /*Type=*/FuncTy_21,
+ /*Type=*/FuncTy_22,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_set64_instance_from_code", mod); // (external, no body)
func_art_set64_instance_from_code->setCallingConv(CallingConv::C);
@@ -691,7 +691,7 @@
Function* func_art_set_obj_instance_from_code = mod->getFunction("art_set_obj_instance_from_code");
if (!func_art_set_obj_instance_from_code) {
func_art_set_obj_instance_from_code = Function::Create(
- /*Type=*/FuncTy_22,
+ /*Type=*/FuncTy_23,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_set_obj_instance_from_code", mod); // (external, no body)
func_art_set_obj_instance_from_code->setCallingConv(CallingConv::C);
@@ -702,7 +702,7 @@
Function* func_art_get32_instance_from_code = mod->getFunction("art_get32_instance_from_code");
if (!func_art_get32_instance_from_code) {
func_art_get32_instance_from_code = Function::Create(
- /*Type=*/FuncTy_17,
+ /*Type=*/FuncTy_18,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_get32_instance_from_code", mod); // (external, no body)
func_art_get32_instance_from_code->setCallingConv(CallingConv::C);
@@ -713,7 +713,7 @@
Function* func_art_get64_instance_from_code = mod->getFunction("art_get64_instance_from_code");
if (!func_art_get64_instance_from_code) {
func_art_get64_instance_from_code = Function::Create(
- /*Type=*/FuncTy_23,
+ /*Type=*/FuncTy_24,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_get64_instance_from_code", mod); // (external, no body)
func_art_get64_instance_from_code->setCallingConv(CallingConv::C);
@@ -724,7 +724,7 @@
Function* func_art_get_obj_instance_from_code = mod->getFunction("art_get_obj_instance_from_code");
if (!func_art_get_obj_instance_from_code) {
func_art_get_obj_instance_from_code = Function::Create(
- /*Type=*/FuncTy_24,
+ /*Type=*/FuncTy_14,
/*Linkage=*/GlobalValue::ExternalLinkage,
/*Name=*/"art_get_obj_instance_from_code", mod); // (external, no body)
func_art_get_obj_instance_from_code->setCallingConv(CallingConv::C);
diff --git a/src/compiler_llvm/ir_builder.cc b/src/compiler_llvm/ir_builder.cc
index 60f31f2..d38960a 100644
--- a/src/compiler_llvm/ir_builder.cc
+++ b/src/compiler_llvm/ir_builder.cc
@@ -33,7 +33,7 @@
// Get java object type from module
llvm::Type* jobject_struct_type = module.getTypeByName("JavaObject");
- CHECK_NE(jobject_struct_type, static_cast<llvm::Type*>(NULL));
+ CHECK(jobject_struct_type != NULL);
jobject_type_ = jobject_struct_type->getPointerTo();
// Create JEnv* type
@@ -41,8 +41,8 @@
jenv_type_ = jenv_struct_type->getPointerTo();
// Get Art shadow frame struct type from module
- art_frame_type_ = module.getTypeByName("ArtFrame");
- CHECK_NE(art_frame_type_, static_cast<llvm::StructType*>(NULL));
+ art_frame_type_ = module.getTypeByName("ShadowFrame");
+ CHECK(art_frame_type_ != NULL);
// Load the runtime support function declaration from module
InitRuntimeSupportFuncDecl();
@@ -185,7 +185,7 @@
llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t sirt_size) {
- std::string name(StringPrintf("ArtFrame%u", sirt_size));
+ std::string name(StringPrintf("ShadowFrame%u", sirt_size));
// Try to find the existing struct type definition
if (llvm::Type* type = module_->getTypeByName(name)) {
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 18e157e..03f4458 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -26,6 +26,7 @@
#include "object.h"
#include "object_utils.h"
#include "runtime_support_func.h"
+#include "shadow_frame.h"
#include "stl_util.h"
#include "stringprintf.h"
#include "utils_llvm.h"
@@ -199,26 +200,25 @@
irb_.CreateStore(zero_initializer, shadow_frame_);
- // Variables for GetElementPtr
- llvm::Constant* zero = irb_.getInt32(0);
-
- llvm::Value* gep_index[] = {
- zero, // No displacement for shadow frame pointer
- zero, // Get the %ArtFrame data structure
- NULL,
- };
-
// Store the method pointer
- gep_index[2] = irb_.getInt32(1);
- llvm::Value* method_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
+ llvm::Value* method_field_addr =
+ irb_.CreatePtrDisp(shadow_frame_,
+ irb_.getPtrEquivInt(ShadowFrame::MethodOffset()),
+ irb_.getJObjectTy()->getPointerTo());
+
llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
irb_.CreateStore(method_object_addr, method_field_addr);
// Store the number of the pointer slots
- gep_index[2] = irb_.getInt32(3);
- llvm::Value* size_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
- llvm::ConstantInt* sirt_size_value = irb_.getInt32(sirt_size);
- irb_.CreateStore(sirt_size_value, size_field_addr);
+ llvm::ConstantInt* num_of_refs_offset =
+ irb_.getPtrEquivInt(ShadowFrame::NumberOfReferencesOffset());
+
+ llvm::Value* num_of_refs_field_addr =
+ irb_.CreatePtrDisp(shadow_frame_, num_of_refs_offset,
+ irb_.getJIntTy()->getPointerTo());
+
+ llvm::ConstantInt* num_of_refs_value = irb_.getJInt(sirt_size);
+ irb_.CreateStore(num_of_refs_value, num_of_refs_field_addr);
// Push the shadow frame
llvm::Value* shadow_frame_upcast =
@@ -3881,15 +3881,11 @@
void MethodCompiler::EmitUpdateLineNum(int32_t line_num) {
- llvm::Constant* zero = irb_.getInt32(0);
+ llvm::Value* line_num_field_addr =
+ irb_.CreatePtrDisp(shadow_frame_,
+ irb_.getPtrEquivInt(ShadowFrame::LineNumOffset()),
+ irb_.getJIntTy()->getPointerTo());
- llvm::Value* gep_index[] = {
- zero, // No displacement for shadow frame pointer
- zero, // Get the %ArtFrame data structure
- irb_.getInt32(2),
- };
-
- llvm::Value* line_num_field_addr = irb_.CreateGEP(shadow_frame_, gep_index);
llvm::ConstantInt* line_num_value = irb_.getInt32(line_num);
irb_.CreateStore(line_num_value, line_num_field_addr);
}
diff --git a/src/compiler_llvm/runtime_support_llvm.cc b/src/compiler_llvm/runtime_support_llvm.cc
index 013a530..f09d6c1 100644
--- a/src/compiler_llvm/runtime_support_llvm.cc
+++ b/src/compiler_llvm/runtime_support_llvm.cc
@@ -6,6 +6,7 @@
#include "object_utils.h"
#include "runtime_support_common.h"
#include "runtime_support_llvm.h"
+#include "shadow_frame.h"
#include "thread.h"
#include "thread_list.h"
@@ -49,14 +50,12 @@
void art_push_shadow_frame_from_code(void* new_shadow_frame) {
Thread* thread = Thread::Current();
- thread->PushSirt(
- static_cast<StackIndirectReferenceTable*>(new_shadow_frame)
- );
+ thread->PushShadowFrame(static_cast<ShadowFrame*>(new_shadow_frame));
}
void art_pop_shadow_frame_from_code() {
Thread* thread = Thread::Current();
- thread->PopSirt();
+ thread->PopShadowFrame();
}
diff --git a/src/dex_instruction_list.h b/src/dex_instruction_list.h
index 8a5b5ad..ed26795 100644
--- a/src/dex_instruction_list.h
+++ b/src/dex_instruction_list.h
@@ -53,7 +53,7 @@
V(0x23, NEW_ARRAY, "new-array", k22c, true, kTypeRef, kContinue | kThrow, kVerifyRegA | kVerifyRegB | kVerifyRegCNewArray) \
V(0x24, FILLED_NEW_ARRAY, "filled-new-array", k35c, false, kTypeRef, kContinue | kThrow, kVerifyRegBType | kVerifyVarArg) \
V(0x25, FILLED_NEW_ARRAY_RANGE, "filled-new-array/range", k3rc, false, kTypeRef, kContinue | kThrow, kVerifyRegBType | kVerifyVarArgRange) \
- V(0x26, FILL_ARRAY_DATA, "fill-array-data", k31t, false, kNone, kContinue, kVerifyRegA | kVerifyArrayData) \
+ V(0x26, FILL_ARRAY_DATA, "fill-array-data", k31t, false, kNone, kContinue | kThrow, kVerifyRegA | kVerifyArrayData) \
V(0x27, THROW, "throw", k11x, false, kNone, kThrow, kVerifyRegA) \
V(0x28, GOTO, "goto", k10t, false, kNone, kBranch, kVerifyBranchTarget) \
V(0x29, GOTO_16, "goto/16", k20t, false, kNone, kBranch, kVerifyBranchTarget) \
diff --git a/src/mem_map.cc b/src/mem_map.cc
index 92c6a59..885389d 100644
--- a/src/mem_map.cc
+++ b/src/mem_map.cc
@@ -29,7 +29,9 @@
namespace art {
-size_t ParseHex(const std::string& string) {
+#if !defined(NDEBUG)
+
+static size_t ParseHex(const std::string& string) {
CHECK_EQ(8U, string.size());
const char* str = string.c_str();
char* end;
@@ -39,17 +41,65 @@
return value;
}
+static void CheckMapRegion(uint32_t base, uint32_t limit, uint32_t start, uint32_t end, const std::string& maps) {
+ CHECK(!(base >= start && base < end) // start of new within old
+ && !(limit > start && limit < end) // end of new within old
+ && !(base <= start && limit > end)) // start/end of new includes all of old
+ << StringPrintf("Requested region %08x-%08x overlaps with existing map %08x-%08x\n",
+ base, limit, start, end)
+ << maps;
+}
+
void CheckMapRequest(byte* addr, size_t length) {
-#if !defined(NDEBUG)
-#if defined(__APPLE__)
- UNIMPLEMENTED(WARNING);
-#else
if (addr == NULL) {
return;
}
- size_t base = reinterpret_cast<size_t>(addr);
- size_t limit = base + length;
+ uint32_t base = reinterpret_cast<size_t>(addr);
+ uint32_t limit = base + length;
+#if defined(__APPLE__)
+ // Mac OS vmmap(1) output currently looks something like this:
+
+ // Virtual Memory Map of process 51036 (dex2oatd)
+ // Output report format: 2.2 -- 32-bit process
+ //
+ // ==== regions for process 51036 (non-writable and writable regions are interleaved)
+ // __PAGEZERO 00000000-00001000 [ 4K 0K 0K] ---/--- SM=NUL out/host/darwin-x86/bin/dex2oatd
+ // __TEXT 00001000-00015000 [ 80K 80K 0K] r-x/rwx SM=COW out/host/darwin-x86/bin/dex2oatd
+ // __DATA 00015000-00016000 [ 4K 4K 4K] rw-/rwx SM=PRV out/host/darwin-x86/bin/dex2oatd
+ // __LINKEDIT 00016000-00044000 [ 184K 184K 0K] r--/rwx SM=COW out/host/darwin-x86/bin/dex2oatd
+ // __TEXT 00044000-00046000 [ 8K 8K 4K] r-x/rwx SM=COW out/host/darwin-x86/obj/lib/libnativehelper.dylib
+ // __DATA 00046000-00047000 [ 4K 4K 4K] rw-/rwx SM=ZER out/host/darwin-x86/obj/lib/libnativehelper.dylib
+ // __LINKEDIT 00047000-0004a000 [ 12K 12K 0K] r--/rwx SM=COW out/host/darwin-x86/obj/lib/libnativehelper.dylib
+ // ...
+
+ std::string command(StringPrintf("vmmap -v -interleaved %d", getpid()));
+ FILE* fp = popen(command.c_str(), "r");
+ if (fp == NULL) {
+ PLOG(FATAL) << "popen failed";
+ }
+ std::vector<char> chars(512);
+ std::string maps;
+ while (fgets(&chars[0], chars.size(), fp) != NULL) {
+ std::string line(&chars[0]);
+ maps += line;
+ if (line.size() < 40 || line[31] != '-') {
+ continue;
+ }
+
+ std::string start_str(line.substr(22, 8));
+ std::string end_str(line.substr(31, 8));
+ uint32_t start = ParseHex(start_str);
+ uint32_t end = ParseHex(end_str);
+ CheckMapRegion(base, limit, start, end, maps);
+ }
+ if (ferror(fp)) {
+ PLOG(FATAL) << "fgets failed";
+ }
+ if (pclose(fp) == -1) {
+ PLOG(FATAL) << "pclose failed";
+ }
+#else // Linux
std::string maps;
bool read = ReadFileToString("/proc/self/maps", &maps);
if (!read) {
@@ -93,20 +143,18 @@
std::string end_str(maps.substr(i+1+8, 8));
uint32_t start = ParseHex(start_str);
uint32_t end = ParseHex(end_str);
- CHECK(!(base >= start && base < end) // start of new within old
- && !(limit > start && limit < end) // end of new within old
- && !(base <= start && limit > end)) // start/end of new includes all of old
- << StringPrintf("Requested region %08x-%08x overlaps with existing map %08x-%08x\n",
- base, limit, start, end)
- << maps;
+ CheckMapRegion(base, limit, start, end, maps);
i += 8+1+8;
i = maps.find('\n', i);
CHECK(i != std::string::npos) << "Failed to find newline from pos " << i << "\n" << maps;
}
#endif
-#endif
}
+#else
+static void CheckMapRequest(byte* addr, size_t length) { }
+#endif
+
MemMap* MemMap::MapAnonymous(const char* name, byte* addr, size_t length, int prot) {
CHECK_NE(0U, length);
CHECK_NE(0, prot);
diff --git a/src/oat_test.cc b/src/oat_test.cc
index 0ca581a..dff360c 100644
--- a/src/oat_test.cc
+++ b/src/oat_test.cc
@@ -21,7 +21,38 @@
namespace art {
-class OatTest : public CommonTest {};
+class OatTest : public CommonTest {
+ protected:
+ void CheckMethod(Method* method,
+ const OatFile::OatMethod& oat_method,
+ const DexFile* dex_file) {
+ const CompiledMethod* compiled_method =
+ compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file,
+ method->GetDexMethodIndex()));
+
+ if (compiled_method == NULL) {
+ EXPECT_TRUE(oat_method.GetCode() == NULL) << PrettyMethod(method) << " "
+ << oat_method.GetCode();
+ EXPECT_EQ(oat_method.GetFrameSizeInBytes(), static_cast<uint32_t>(kStackAlignment));
+ EXPECT_EQ(oat_method.GetCoreSpillMask(), 0U);
+ EXPECT_EQ(oat_method.GetFpSpillMask(), 0U);
+ } else {
+ const void* oat_code = oat_method.GetCode();
+ EXPECT_TRUE(oat_code != NULL) << PrettyMethod(method);
+ uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(oat_code), 2);
+ oat_code = reinterpret_cast<const void*>(oat_code_aligned);
+
+ const std::vector<uint8_t>& code = compiled_method->GetCode();
+ size_t code_size = code.size() * sizeof(code[0]);
+ EXPECT_EQ(0, memcmp(oat_code, &code[0], code_size))
+ << PrettyMethod(method) << " " << code_size;
+ CHECK_EQ(0, memcmp(oat_code, &code[0], code_size));
+ EXPECT_EQ(oat_method.GetFrameSizeInBytes(), compiled_method->GetFrameSizeInBytes());
+ EXPECT_EQ(oat_method.GetCoreSpillMask(), compiled_method->GetCoreSpillMask());
+ EXPECT_EQ(oat_method.GetFpSpillMask(), compiled_method->GetFpSpillMask());
+ }
+ }
+};
TEST_F(OatTest, WriteRead) {
const bool compile = false; // DISABLED_ due to the time to compile libcore
@@ -64,59 +95,12 @@
size_t method_index = 0;
for (size_t i = 0; i < klass->NumDirectMethods(); i++, method_index++) {
- Method* method = klass->GetDirectMethod(i);
- const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index);
- const CompiledMethod* compiled_method =
- compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file,
- method->GetDexMethodIndex()));
-
- if (compiled_method == NULL) {
- EXPECT_TRUE(oat_method.GetCode() == NULL) << PrettyMethod(method) << " " << oat_method.GetCode();
- EXPECT_EQ(oat_method.GetFrameSizeInBytes(), static_cast<uint32_t>(kStackAlignment));
- EXPECT_EQ(oat_method.GetCoreSpillMask(), 0U);
- EXPECT_EQ(oat_method.GetFpSpillMask(), 0U);
- } else {
- const void* oat_code = oat_method.GetCode();
- uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(oat_code), 2);
- oat_code = reinterpret_cast<const void*>(oat_code_aligned);
-
- const std::vector<uint8_t>& code = compiled_method->GetCode();
- size_t code_size = code.size() * sizeof(code[0]);
- EXPECT_EQ(0, memcmp(oat_code, &code[0], code_size))
- << PrettyMethod(method) << " " << code_size;
- CHECK_EQ(0, memcmp(oat_code, &code[0], code_size));
- EXPECT_EQ(oat_method.GetFrameSizeInBytes(), compiled_method->GetFrameSizeInBytes());
- EXPECT_EQ(oat_method.GetCoreSpillMask(), compiled_method->GetCoreSpillMask());
- EXPECT_EQ(oat_method.GetFpSpillMask(), compiled_method->GetFpSpillMask());
- }
+ CheckMethod(klass->GetDirectMethod(i),
+ oat_class->GetOatMethod(method_index), dex_file);
}
for (size_t i = 0; i < num_virtual_methods; i++, method_index++) {
- Method* method = klass->GetVirtualMethod(i);
- const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index);
- const CompiledMethod* compiled_method =
- compiler_->GetCompiledMethod(Compiler::MethodReference(dex_file,
- method->GetDexMethodIndex()));
-
- if (compiled_method == NULL) {
- EXPECT_TRUE(oat_method.GetCode() == NULL) << PrettyMethod(method) << " " << oat_method.GetCode();
- EXPECT_EQ(oat_method.GetFrameSizeInBytes(), static_cast<uint32_t>(kStackAlignment));
- EXPECT_EQ(oat_method.GetCoreSpillMask(), 0U);
- EXPECT_EQ(oat_method.GetFpSpillMask(), 0U);
- } else {
- const void* oat_code = oat_method.GetCode();
- EXPECT_TRUE(oat_code != NULL) << PrettyMethod(method);
- uintptr_t oat_code_aligned = RoundDown(reinterpret_cast<uintptr_t>(oat_code), 2);
- oat_code = reinterpret_cast<const void*>(oat_code_aligned);
-
- const std::vector<uint8_t>& code = compiled_method->GetCode();
- size_t code_size = code.size() * sizeof(code[0]);
- EXPECT_EQ(0, memcmp(oat_code, &code[0], code_size))
- << PrettyMethod(method) << " " << code_size;
- CHECK_EQ(0, memcmp(oat_code, &code[0], code_size));
- EXPECT_EQ(oat_method.GetFrameSizeInBytes(), compiled_method->GetFrameSizeInBytes());
- EXPECT_EQ(oat_method.GetCoreSpillMask(), compiled_method->GetCoreSpillMask());
- EXPECT_EQ(oat_method.GetFpSpillMask(), compiled_method->GetFpSpillMask());
- }
+ CheckMethod(klass->GetVirtualMethod(i),
+ oat_class->GetOatMethod(method_index), dex_file);
}
}
}
diff --git a/src/shadow_frame.h b/src/shadow_frame.h
new file mode 100644
index 0000000..3bdee8e
--- /dev/null
+++ b/src/shadow_frame.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 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 ART_SRC_SHADOW_FRAME_H_
+#define ART_SRC_SHADOW_FRAME_H_
+
+#include "logging.h"
+#include "macros.h"
+
+namespace art {
+
+class Object;
+
+class ShadowFrame {
+ public:
+ // Number of references contained within this shadow frame
+ uint32_t NumberOfReferences() const {
+ return number_of_references_;
+ }
+
+ // Link to previous shadow frame or NULL
+ ShadowFrame* GetLink() const {
+ return link_;
+ }
+
+ void SetLink(ShadowFrame* frame) {
+ DCHECK_NE(this, frame);
+ link_ = frame;
+ }
+
+ Object* GetReference(size_t i) const {
+ DCHECK_LT(i, number_of_references_);
+ return references_[i];
+ }
+
+ void SetReference(size_t i, Object* object) {
+ DCHECK_LT(i, number_of_references_);
+ references_[i] = object;
+ }
+
+ // Offset of link within shadow frame
+ static size_t LinkOffset() {
+ return OFFSETOF_MEMBER(ShadowFrame, link_);
+ }
+
+ // Offset of method within shadow frame
+ static size_t MethodOffset() {
+ return OFFSETOF_MEMBER(ShadowFrame, method_);
+ }
+
+ // Offset of line number within shadow frame
+ static size_t LineNumOffset() {
+ return OFFSETOF_MEMBER(ShadowFrame, line_num_);
+ }
+
+ // Offset of length within shadow frame
+ static size_t NumberOfReferencesOffset() {
+ return OFFSETOF_MEMBER(ShadowFrame, number_of_references_);
+ }
+
+ // Offset of references within shadow frame
+ static size_t ReferencesOffset() {
+ return OFFSETOF_MEMBER(ShadowFrame, references_);
+ }
+
+ private:
+ // ShadowFrame should be allocated by the generated code directly.
+ // We should not create new shadow stack in the runtime support function.
+ ~ShadowFrame() {}
+
+ uint32_t number_of_references_;
+ ShadowFrame* link_;
+ Object* method_;
+ uint32_t line_num_;
+ Object* references_[];
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ShadowFrame);
+};
+
+} // namespace art
+
+#endif // ART_SRC_SHADOW_FRAME_H_
diff --git a/src/stack_indirect_reference_table.h b/src/stack_indirect_reference_table.h
index 5c6bc0a..5f37294 100644
--- a/src/stack_indirect_reference_table.h
+++ b/src/stack_indirect_reference_table.h
@@ -90,10 +90,6 @@
size_t number_of_references_;
StackIndirectReferenceTable* link_;
-#if defined(ART_USE_LLVM_COMPILER)
- Object* method_;
- uint32_t line_num_;
-#endif
// number_of_references_ are available if this is allocated and filled in by jni_compiler.
Object* references_[1];
diff --git a/src/thread.cc b/src/thread.cc
index 629cb0f..4417b7f 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -43,6 +43,7 @@
#include "runtime_support.h"
#include "ScopedLocalRef.h"
#include "scoped_jni_thread_state.h"
+#include "shadow_frame.h"
#include "space.h"
#include "stack.h"
#include "stack_indirect_reference_table.h"
@@ -868,6 +869,7 @@
stack_end_(NULL),
native_to_managed_record_(NULL),
top_sirt_(NULL),
+ top_shadow_frame_(NULL),
jni_env_(NULL),
state_(Thread::kNative),
self_(NULL),
@@ -1003,6 +1005,18 @@
}
}
+void Thread::ShadowFrameVisitRoots(Heap::RootVisitor* visitor, void* arg) {
+ for (ShadowFrame* cur = top_shadow_frame_; cur; cur = cur->GetLink()) {
+ size_t num_refs = cur->NumberOfReferences();
+ for (size_t j = 0; j < num_refs; j++) {
+ Object* object = cur->GetReference(j);
+ if (object != NULL) {
+ visitor(object, arg);
+ }
+ }
+ }
+}
+
Object* Thread::DecodeJObject(jobject obj) {
DCHECK(CanAccessDirectReferences());
if (obj == NULL) {
@@ -1181,6 +1195,18 @@
return pc;
}
+void Thread::PushShadowFrame(ShadowFrame* frame) {
+ frame->SetLink(top_shadow_frame_);
+ top_shadow_frame_ = frame;
+}
+
+ShadowFrame* Thread::PopShadowFrame() {
+ CHECK(top_shadow_frame_ != NULL);
+ ShadowFrame* frame = top_shadow_frame_;
+ top_shadow_frame_ = frame->GetLink();
+ return frame;
+}
+
void Thread::PushSirt(StackIndirectReferenceTable* sirt) {
sirt->SetLink(top_sirt_);
top_sirt_ = sirt;
@@ -1665,6 +1691,7 @@
jni_env_->monitors.VisitRoots(visitor, arg);
SirtVisitRoots(visitor, arg);
+ ShadowFrameVisitRoots(visitor, arg);
// Cheat and steal the long jump context. Assume that we are not doing a GC during exception
// delivery.
diff --git a/src/thread.h b/src/thread.h
index 51385f9..bbf7730 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -50,6 +50,7 @@
class Monitor;
class Object;
class Runtime;
+class ShadowFrame;
class StackIndirectReferenceTable;
class StackTraceElement;
class StaticStorageBase;
@@ -266,6 +267,8 @@
void SirtVisitRoots(Heap::RootVisitor* visitor, void* arg);
+ void ShadowFrameVisitRoots(Heap::RootVisitor* visitor, void* arg);
+
// Convert a jobject into a Object*
Object* DecodeJObject(jobject obj);
@@ -393,6 +396,9 @@
return ThreadOffset(OFFSETOF_MEMBER(Thread, top_of_managed_stack_pc_));
}
+ void PushShadowFrame(ShadowFrame* frame);
+ ShadowFrame* PopShadowFrame();
+
void PushSirt(StackIndirectReferenceTable* sirt);
StackIndirectReferenceTable* PopSirt();
@@ -524,6 +530,10 @@
// Top of linked list of stack indirect reference tables or NULL for none
StackIndirectReferenceTable* top_sirt_;
+ // Top of linked list of shadow stack or NULL for none
+ // Some backend may require shadow frame to ease the GC work.
+ ShadowFrame* top_shadow_frame_;
+
// Every thread may have an associated JNI environment
JNIEnvExt* jni_env_;