Extract method-related information from CompilationUnit.
Extract method-related information, such as class_loader,
class_linker, dex_file, dex_cache, code_item, method_idx,
and access_flags from art::CompilationUnit, so that we
can use them in 2 different code generators.
Change-Id: I20631cc73b6f01e9646a983156f3fcb066d732db
diff --git a/src/compiler.cc b/src/compiler.cc
index a51e5da..9a49cdd 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -24,10 +24,10 @@
#include "assembler.h"
#include "class_linker.h"
#include "class_loader.h"
-#include "compiler/CompilerIR.h"
#include "dex_cache.h"
#include "jni_compiler.h"
#include "jni_internal.h"
+#include "oat_compilation_unit.h"
#include "oat_file.h"
#include "object_utils.h"
#include "runtime.h"
@@ -438,32 +438,36 @@
return result;
}
-static Class* ComputeReferrerClass(CompilationUnit* cUnit) {
- const DexFile::MethodId& referrer_method_id = cUnit->dex_file->GetMethodId(cUnit->method_idx);
- return cUnit->class_linker->ResolveType(*cUnit->dex_file, referrer_method_id.class_idx_,
- cUnit->dex_cache, cUnit->class_loader);
+static Class* ComputeReferrerClass(OatCompilationUnit* mUnit) {
+ const DexFile::MethodId& referrer_method_id =
+ mUnit->dex_file_->GetMethodId(mUnit->method_idx_);
+
+ return mUnit->class_linker_->ResolveType(
+ *mUnit->dex_file_, referrer_method_id.class_idx_,
+ mUnit->dex_cache_, mUnit->class_loader_);
}
-static Field* ComputeReferrerField(CompilationUnit* cUnit, uint32_t field_idx) {
- return cUnit->class_linker->ResolveField(*cUnit->dex_file, field_idx, cUnit->dex_cache,
- cUnit->class_loader, false);
-
+static Field* ComputeReferrerField(OatCompilationUnit* mUnit, uint32_t field_idx) {
+ return mUnit->class_linker_->ResolveField(
+ *mUnit->dex_file_, field_idx, mUnit->dex_cache_,
+ mUnit->class_loader_, false);
}
-static Method* ComputeReferrerMethod(CompilationUnit* cUnit, uint32_t method_idx) {
- return cUnit->class_linker->ResolveMethod(*cUnit->dex_file, method_idx, cUnit->dex_cache,
- cUnit->class_loader, true);
+static Method* ComputeReferrerMethod(OatCompilationUnit* mUnit, uint32_t method_idx) {
+ return mUnit->class_linker_->ResolveMethod(
+ *mUnit->dex_file_, method_idx, mUnit->dex_cache_,
+ mUnit->class_loader_, true);
}
-bool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, CompilationUnit* cUnit,
+bool Compiler::ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
int& field_offset, bool& is_volatile, bool is_put) {
// Conservative defaults
field_offset = -1;
is_volatile = true;
// Try to resolve field
- Field* resolved_field = ComputeReferrerField(cUnit, field_idx);
+ Field* resolved_field = ComputeReferrerField(mUnit, field_idx);
if (resolved_field != NULL) {
- Class* referrer_class = ComputeReferrerClass(cUnit);
+ Class* referrer_class = ComputeReferrerClass(mUnit);
// Try to resolve referring class then access check, failure to pass the
Class* fields_class = resolved_field->GetDeclaringClass();
bool is_write_to_final_from_wrong_class = is_put && resolved_field->IsFinal() &&
@@ -486,7 +490,7 @@
return false; // Incomplete knowledge needs slow path.
}
-bool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, CompilationUnit* cUnit,
+bool Compiler::ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
int& field_offset, int& ssb_index,
bool& is_referrers_class, bool& is_volatile, bool is_put) {
// Conservative defaults
@@ -495,10 +499,10 @@
is_referrers_class = false;
is_volatile = true;
// Try to resolve field
- Field* resolved_field = ComputeReferrerField(cUnit, field_idx);
+ Field* resolved_field = ComputeReferrerField(mUnit, field_idx);
if (resolved_field != NULL) {
DCHECK(resolved_field->IsStatic());
- Class* referrer_class = ComputeReferrerClass(cUnit);
+ Class* referrer_class = ComputeReferrerClass(mUnit);
if (referrer_class != NULL) {
Class* fields_class = resolved_field->GetDeclaringClass();
if (fields_class == referrer_class) {
@@ -516,7 +520,7 @@
// in its static storage base (which may fail if it doesn't have a slot for it)
// TODO: for images we can elide the static storage base null check
// if we know there's a non-null entry in the image
- if (fields_class->GetDexCache() == cUnit->dex_cache) {
+ if (fields_class->GetDexCache() == mUnit->dex_cache_) {
// common case where the dex cache of both the referrer and the field are the same,
// no need to search the dex file
ssb_index = fields_class->GetDexTypeIndex();
@@ -528,13 +532,13 @@
// Search dex file for localized ssb index
std::string descriptor(FieldHelper(resolved_field).GetDeclaringClassDescriptor());
const DexFile::StringId* string_id =
- cUnit->dex_file->FindStringId(descriptor);
+ mUnit->dex_file_->FindStringId(descriptor);
if (string_id != NULL) {
const DexFile::TypeId* type_id =
- cUnit->dex_file->FindTypeId(cUnit->dex_file->GetIndexForStringId(*string_id));
+ mUnit->dex_file_->FindTypeId(mUnit->dex_file_->GetIndexForStringId(*string_id));
if(type_id != NULL) {
// medium path, needs check of static storage base being initialized
- ssb_index = cUnit->dex_file->GetIndexForTypeId(*type_id);
+ ssb_index = mUnit->dex_file_->GetIndexForTypeId(*type_id);
field_offset = resolved_field->GetOffset().Int32Value();
is_volatile = resolved_field->IsVolatile();
stats_->ResolvedStaticField();
@@ -554,12 +558,12 @@
return false; // Incomplete knowledge needs slow path.
}
-bool Compiler::ComputeInvokeInfo(uint32_t method_idx, CompilationUnit* cUnit, InvokeType type,
+bool Compiler::ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType type,
int& vtable_idx) {
vtable_idx = -1;
- Method* resolved_method = ComputeReferrerMethod(cUnit, method_idx);
+ Method* resolved_method = ComputeReferrerMethod(mUnit, method_idx);
if (resolved_method != NULL) {
- Class* referrer_class = ComputeReferrerClass(cUnit);
+ Class* referrer_class = ComputeReferrerClass(mUnit);
if (referrer_class != NULL) {
Class* methods_class = resolved_method->GetDeclaringClass();
if (!referrer_class->CanAccess(methods_class) ||
@@ -568,11 +572,11 @@
// The referring class can't access the resolved method, this may occur as a result of a
// protected method being made public by implementing an interface that re-declares the
// method public. Resort to the dex file to determine the correct class for the access check
- const DexFile& dex_file = cUnit->class_linker->FindDexFile(referrer_class->GetDexCache());
+ const DexFile& dex_file = mUnit->class_linker_->FindDexFile(referrer_class->GetDexCache());
methods_class =
- cUnit->class_linker->ResolveType(dex_file,
- dex_file.GetMethodId(method_idx).class_idx_,
- referrer_class);
+ mUnit->class_linker_->ResolveType(dex_file,
+ dex_file.GetMethodId(method_idx).class_idx_,
+ referrer_class);
}
if (referrer_class->CanAccess(methods_class) &&
@@ -957,15 +961,23 @@
const DexFile& dex_file) {
CompiledMethod* compiled_method = NULL;
uint64_t start_ns = NanoTime();
+
+#if defined(ART_USE_LLVM_COMPILER)
+ ClassLinker *class_linker = Runtime::Current()->GetClassLinker();
+ DexCache *dex_cache = class_linker->FindDexCache(dex_file);
+
+ UniquePtr<OatCompilationUnit> oat_compilation_unit(
+ new OatCompilationUnit(class_loader, class_linker, dex_file, *dex_cache, code_item,
+ method_idx, access_flags));
+#endif
+
if ((access_flags & kAccNative) != 0) {
compiled_method = jni_compiler_.Compile(access_flags, method_idx, class_loader, dex_file);
CHECK(compiled_method != NULL);
} else if ((access_flags & kAccAbstract) != 0) {
} else {
#if defined(ART_USE_LLVM_COMPILER)
- compiled_method =
- compiler_llvm_->CompileDexMethod(code_item, access_flags, method_idx,
- class_loader, dex_file);
+ compiled_method = compiler_llvm_->CompileDexMethod(oat_compilation_unit.get());
#else
compiled_method = oatCompileMethod(*this, code_item, access_flags, method_idx, class_loader,
dex_file, kThumb2);
diff --git a/src/compiler.h b/src/compiler.h
index 92329f0..27de42f 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -39,8 +39,8 @@
class AOTCompilationStats;
class Context;
+class OatCompilationUnit;
class TimingLogger;
-typedef struct CompilationUnit CompilationUnit;
class Compiler {
@@ -110,17 +110,17 @@
const DexFile& dex_file, uint32_t type_idx);
// Can we fast path instance field access? Computes field's offset and volatility
- bool ComputeInstanceFieldInfo(uint32_t field_idx, CompilationUnit* cUnit,
+ bool ComputeInstanceFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
int& field_offset, bool& is_volatile, bool is_put);
// Can we fastpath static field access? Computes field's offset, volatility and whether the
// field is within the referrer (which can avoid checking class initialization)
- bool ComputeStaticFieldInfo(uint32_t field_idx, CompilationUnit* cUnit,
+ bool ComputeStaticFieldInfo(uint32_t field_idx, OatCompilationUnit* mUnit,
int& field_offset, int& ssb_index,
bool& is_referrers_class, bool& is_volatile, bool is_put);
// Can we fastpath a interface, super class or virtual method call? Computes method's vtable index
- bool ComputeInvokeInfo(uint32_t method_idx, CompilationUnit* cUnit, InvokeType type,
+ bool ComputeInvokeInfo(uint32_t method_idx, OatCompilationUnit* mUnit, InvokeType type,
int& vtable_idx);
#if defined(ART_USE_LLVM_COMPILER)
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 72b3d6e..ce8cfda 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -53,11 +53,15 @@
// Explicit register usage
oatLockCallTemps(cUnit);
+ OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
+ *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
+ cUnit->method_idx, cUnit->access_flags);
+
uint32_t dexMethodIdx = dInsn->vB;
int vtableIdx;
bool skipThis;
bool fastPath =
- cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, cUnit, type,
+ cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
vtableIdx)
&& !SLOW_INVOKE_PATH;
if (type == kInterface) {
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index bdadf6e..c3de5ff 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -22,6 +22,8 @@
*
*/
+#include "oat_compilation_unit.h"
+
#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
@@ -303,8 +305,13 @@
bool isVolatile;
bool isReferrersClass;
uint32_t fieldIdx = mir->dalvikInsn.vB;
+
+ OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
+ *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
+ cUnit->method_idx, cUnit->access_flags);
+
bool fastPath =
- cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, cUnit,
+ cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, &mUnit,
fieldOffset, ssbIndex,
isReferrersClass, isVolatile, true);
if (fastPath && !SLOW_FIELD_PATH) {
@@ -397,8 +404,13 @@
bool isVolatile;
bool isReferrersClass;
uint32_t fieldIdx = mir->dalvikInsn.vB;
+
+ OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
+ *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
+ cUnit->method_idx, cUnit->access_flags);
+
bool fastPath =
- cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, cUnit,
+ cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, &mUnit,
fieldOffset, ssbIndex,
isReferrersClass, isVolatile, false);
if (fastPath && !SLOW_FIELD_PATH) {
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 5a9750a..e20e19b 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -22,6 +22,8 @@
*
*/
+#include "oat_compilation_unit.h"
+
namespace art {
/*
@@ -382,8 +384,13 @@
int fieldOffset;
bool isVolatile;
uint32_t fieldIdx = mir->dalvikInsn.vC;
+
+ OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
+ *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
+ cUnit->method_idx, cUnit->access_flags);
+
bool fastPath =
- cUnit->compiler->ComputeInstanceFieldInfo(fieldIdx, cUnit,
+ cUnit->compiler->ComputeInstanceFieldInfo(fieldIdx, &mUnit,
fieldOffset, isVolatile, false);
if (fastPath && !SLOW_FIELD_PATH) {
RegLocation rlResult;
@@ -437,8 +444,13 @@
int fieldOffset;
bool isVolatile;
uint32_t fieldIdx = mir->dalvikInsn.vC;
+
+ OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
+ *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
+ cUnit->method_idx, cUnit->access_flags);
+
bool fastPath =
- cUnit->compiler->ComputeInstanceFieldInfo(fieldIdx, cUnit,
+ cUnit->compiler->ComputeInstanceFieldInfo(fieldIdx, &mUnit,
fieldOffset, isVolatile, true);
if (fastPath && !SLOW_FIELD_PATH) {
RegisterClass regClass = oatRegClassBySize(size);
diff --git a/src/compiler_llvm/compiler_llvm.cc b/src/compiler_llvm/compiler_llvm.cc
index 038e826..6099841 100644
--- a/src/compiler_llvm/compiler_llvm.cc
+++ b/src/compiler_llvm/compiler_llvm.cc
@@ -19,6 +19,7 @@
#include "compiler.h"
#include "ir_builder.h"
#include "method_compiler.h"
+#include "oat_compilation_unit.h"
#include "upcall_compiler.h"
#include <llvm/ADT/OwningPtr.h>
@@ -81,22 +82,11 @@
}
-CompiledMethod*
-CompilerLLVM::CompileDexMethod(DexFile::CodeItem const* code_item,
- uint32_t access_flags,
- uint32_t method_idx,
- ClassLoader const* class_loader,
- DexFile const& dex_file) {
-
+CompiledMethod* CompilerLLVM::CompileDexMethod(OatCompilationUnit* oat_compilation_unit) {
MutexLock GUARD(compiler_lock_);
- ClassLinker *class_linker = Runtime::Current()->GetClassLinker();
- DexCache *dex_cache = class_linker->FindDexCache(dex_file);
-
UniquePtr<MethodCompiler> method_compiler(
- new MethodCompiler(insn_set_, compiler_, class_linker, class_loader,
- &dex_file, dex_cache, code_item, method_idx,
- access_flags));
+ new MethodCompiler(insn_set_, compiler_, oat_compilation_unit));
return method_compiler->Compile();
}
diff --git a/src/compiler_llvm/compiler_llvm.h b/src/compiler_llvm/compiler_llvm.h
index f39f686..13dc063 100644
--- a/src/compiler_llvm/compiler_llvm.h
+++ b/src/compiler_llvm/compiler_llvm.h
@@ -30,6 +30,7 @@
class CompiledInvokeStub;
class CompiledMethod;
class Compiler;
+ class OatCompilationUnit;
}
@@ -78,11 +79,7 @@
return irb_.get();
}
- CompiledMethod* CompileDexMethod(DexFile::CodeItem const* code_item,
- uint32_t access_flags,
- uint32_t method_idx,
- ClassLoader const* class_loader,
- DexFile const& dex_file);
+ CompiledMethod* CompileDexMethod(OatCompilationUnit* oat_compilation_unit);
CompiledInvokeStub* CreateInvokeStub(bool is_static, char const *shorty);
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index eed4630..714b6e5 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -21,6 +21,7 @@
#include "inferred_reg_category_map.h"
#include "ir_builder.h"
#include "logging.h"
+#include "oat_compilation_unit.h"
#include "object.h"
#include "object_utils.h"
#include "runtime_support_func.h"
@@ -44,26 +45,26 @@
MethodCompiler::MethodCompiler(InstructionSet insn_set,
Compiler* compiler,
- ClassLinker* class_linker,
- ClassLoader const* class_loader,
- DexFile const* dex_file,
- DexCache* dex_cache,
- DexFile::CodeItem const* code_item,
- uint32_t method_idx,
- uint32_t access_flags)
-: insn_set_(insn_set),
- compiler_(compiler), compiler_llvm_(compiler->GetCompilerLLVM()),
- class_linker_(class_linker), class_loader_(class_loader),
- dex_file_(dex_file), dex_cache_(dex_cache), code_item_(code_item),
- method_(dex_cache->GetResolvedMethod(method_idx)),
- method_helper_(method_), method_idx_(method_idx),
- access_flags_(access_flags), module_(compiler_llvm_->GetModule()),
+ OatCompilationUnit* oat_compilation_unit)
+: insn_set_(insn_set), compiler_(compiler),
+ compiler_llvm_(compiler->GetCompilerLLVM()),
+ class_linker_(oat_compilation_unit->class_linker_),
+ class_loader_(oat_compilation_unit->class_loader_),
+ dex_file_(oat_compilation_unit->dex_file_),
+ dex_cache_(oat_compilation_unit->dex_cache_),
+ code_item_(oat_compilation_unit->code_item_),
+ oat_compilation_unit_(oat_compilation_unit),
+ method_(dex_cache_->GetResolvedMethod(oat_compilation_unit->method_idx_)),
+ method_helper_(method_),
+ method_idx_(oat_compilation_unit->method_idx_),
+ access_flags_(oat_compilation_unit->access_flags_),
+ module_(compiler_llvm_->GetModule()),
context_(compiler_llvm_->GetLLVMContext()),
irb_(*compiler_llvm_->GetIRBuilder()), func_(NULL), retval_reg_(NULL),
basic_block_reg_alloca_(NULL), basic_block_shadow_frame_alloca_(NULL),
basic_block_reg_zero_init_(NULL), basic_block_reg_arg_init_(NULL),
- basic_blocks_(code_item->insns_size_in_code_units_),
- basic_block_landing_pads_(code_item->tries_size_, NULL),
+ basic_blocks_(code_item_->insns_size_in_code_units_),
+ basic_block_landing_pads_(code_item_->tries_size_, NULL),
basic_block_unwind_(NULL), basic_block_unreachable_(NULL),
shadow_frame_(NULL) {
}
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index dd10bc8..de60fa3 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -38,6 +38,7 @@
class Compiler;
class DexCache;
class Field;
+ class OatCompilationUnit;
}
@@ -71,6 +72,7 @@
DexCache* dex_cache_;
DexFile::CodeItem const* code_item_;
+ OatCompilationUnit* oat_compilation_unit_;
Method* method_;
MethodHelper method_helper_;
@@ -101,13 +103,7 @@
public:
MethodCompiler(InstructionSet insn_set,
Compiler* compiler,
- ClassLinker* class_linker,
- ClassLoader const* class_loader,
- DexFile const* dex_file,
- DexCache* dex_cache,
- DexFile::CodeItem const* code_item,
- uint32_t method_idx,
- uint32_t access_flags);
+ OatCompilationUnit* oat_compilation_unit);
~MethodCompiler();
diff --git a/src/oat_compilation_unit.h b/src/oat_compilation_unit.h
new file mode 100644
index 0000000..9d1463e
--- /dev/null
+++ b/src/oat_compilation_unit.h
@@ -0,0 +1,54 @@
+/*
+ * 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_METHOD_UNIT_H_
+#define ART_SRC_METHOD_UNIT_H_
+
+#include <stdint.h>
+
+namespace art {
+
+class ClassLoader;
+class ClassLinker;
+class DexFile;
+class DexCache;
+
+class OatCompilationUnit {
+ public:
+ OatCompilationUnit(ClassLoader const* class_loader, ClassLinker* class_linker,
+ DexFile const& dex_file, DexCache& dex_cache,
+ DexFile::CodeItem const* code_item,
+ uint32_t method_idx, uint32_t access_flags)
+ : class_loader_(class_loader), class_linker_(class_linker),
+ dex_file_(&dex_file), dex_cache_(&dex_cache), code_item_(code_item),
+ method_idx_(method_idx), access_flags_(access_flags) {
+ }
+
+ public:
+ ClassLoader const* class_loader_;
+ ClassLinker* class_linker_;
+
+ DexFile const* dex_file_;
+ DexCache* dex_cache_;
+
+ DexFile::CodeItem const* code_item_;
+ uint32_t method_idx_;
+ uint32_t access_flags_;
+};
+
+} // namespace art
+
+#endif // ART_SRC_METHOD_UNIT_H_