Refactor the use of Method by the oat compiler.
Change-Id: Ib0ee18ed06846f82567f746edc7a5049dc6215df
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 006be69..b02cde5 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -33,21 +33,13 @@
STATIC RegLocation getRetLoc(CompilationUnit* cUnit);
-std::string fieldNameFromIndex(const Method* method, uint32_t fieldIdx)
-{
- art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
- const art::DexFile& dex_file = class_linker->FindDexFile(
- method->GetDeclaringClass()->GetDexCache());
- const art::DexFile::FieldId& field_id = dex_file.GetFieldId(fieldIdx);
- std::string class_name = dex_file.StringByTypeIdx(field_id.class_idx_);
- std::string field_name = dex_file.StringDataByIdx(field_id.name_idx_);
- return class_name + "." + field_name;
-}
-
void warnIfUnresolved(CompilationUnit* cUnit, int fieldIdx, Field* field) {
if (field == NULL) {
- LOG(INFO) << "Field " << fieldNameFromIndex(cUnit->method, fieldIdx)
- << " unresolved at compile time";
+ const art::DexFile::FieldId& field_id = cUnit->dex_file->GetFieldId(fieldIdx);
+ std::string class_name = cUnit->dex_file->GetFieldDeclaringClassDescriptor(field_id);
+ std::string field_name = cUnit->dex_file->GetFieldName(field_id);
+ LOG(INFO) << "Field " << art::PrettyDescriptor(class_name) << "."
+ << field_name << " unresolved at compile time";
} else {
// We also use the slow path for wide volatile fields.
}
@@ -455,8 +447,7 @@
STATIC void genIGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
RegLocation rlDest, RegLocation rlObj)
{
- Field* fieldPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
- GetResolvedField(mir->dalvikInsn.vC);
+ Field* fieldPtr = cUnit->dex_cache->GetResolvedField(mir->dalvikInsn.vC);
RegLocation rlResult;
RegisterClass regClass = oatRegClassBySize(size);
if (SLOW_FIELD_PATH || fieldPtr == NULL) {
@@ -490,8 +481,7 @@
STATIC void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size,
RegLocation rlSrc, RegLocation rlObj, bool isObject)
{
- Field* fieldPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
- GetResolvedField(mir->dalvikInsn.vC);
+ Field* fieldPtr = cUnit->dex_cache->GetResolvedField(mir->dalvikInsn.vC);
RegisterClass regClass = oatRegClassBySize(size);
if (SLOW_FIELD_PATH || fieldPtr == NULL) {
getFieldOffset(cUnit, mir, fieldPtr);
@@ -530,8 +520,7 @@
RegLocation rlObj)
{
RegLocation rlResult;
- Field* fieldPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
- GetResolvedField(mir->dalvikInsn.vC);
+ Field* fieldPtr = cUnit->dex_cache->GetResolvedField(mir->dalvikInsn.vC);
#if ANDROID_SMP != 0
bool isVolatile = (fieldPtr == NULL) || fieldPtr->IsVolatile();
#else
@@ -568,8 +557,7 @@
STATIC void genIPutWide(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
RegLocation rlObj)
{
- Field* fieldPtr = cUnit->method->GetDeclaringClass()->GetDexCache()->
- GetResolvedField(mir->dalvikInsn.vC);
+ Field* fieldPtr = cUnit->dex_cache->GetResolvedField(mir->dalvikInsn.vC);
#if ANDROID_SMP != 0
bool isVolatile = (fieldPtr == NULL) || fieldPtr->IsVolatile();
#else
@@ -607,16 +595,28 @@
int mReg = loadCurrMethod(cUnit);
int resReg = oatAllocTemp(cUnit);
RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
- if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method, type_idx)) {
- // Check we have access to type_idx and if not throw IllegalAccessError
- UNIMPLEMENTED(FATAL);
+ if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
+ cUnit->dex_cache,
+ *cUnit->dex_file,
+ type_idx)) {
+ // Call out to helper which resolves type and verifies access.
+ // Resolved type returned in r0.
+ loadWordDisp(cUnit, rSELF,
+ OFFSETOF_MEMBER(Thread, pInitializeTypeAndVerifyAccessFromCode),
+ rLR);
+ genRegCopy(cUnit, r1, mReg);
+ loadConstant(cUnit, r0, type_idx);
+ callRuntimeHelper(cUnit, rLR);
+ RegLocation rlResult = oatGetReturn(cUnit);
+ storeValue(cUnit, rlDest, rlResult);
} else {
// We're don't need access checks, load type from dex cache
int32_t dex_cache_offset = Method::DexCacheResolvedTypesOffset().Int32Value();
loadWordDisp(cUnit, mReg, dex_cache_offset, resReg);
int32_t offset_of_type = Array::DataOffset().Int32Value() + (sizeof(Class*) * type_idx);
loadWordDisp(cUnit, resReg, offset_of_type, rlResult.lowReg);
- if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->method, type_idx) ||
+ if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache,
+ type_idx) ||
SLOW_TYPE_PATH) {
// Slow path, at runtime test if the type is null and if so initialize
oatFlushAllRegs(cUnit);
@@ -652,7 +652,7 @@
/* NOTE: Most strings should be available at compile time */
uint32_t string_idx = mir->dalvikInsn.vB;
int32_t offset_of_string = Array::DataOffset().Int32Value() + (sizeof(String*) * string_idx);
- if (!cUnit->compiler->CanAssumeStringIsPresentInDexCache(cUnit->method, string_idx) ||
+ if (!cUnit->compiler->CanAssumeStringIsPresentInDexCache(cUnit->dex_cache, string_idx) ||
SLOW_STRING_PATH) {
// slow path, resolve string if not in dex cache
oatFlushAllRegs(cUnit);
@@ -694,7 +694,10 @@
uint32_t type_idx = mir->dalvikInsn.vB;
// alloc will always check for resolution, do we also need to verify access because the
// verifier was unable to?
- if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method, type_idx)) {
+ if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
+ cUnit->dex_cache,
+ *cUnit->dex_file,
+ type_idx)) {
loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pAllocObjectFromCode), rLR);
} else {
loadWordDisp(cUnit, rSELF,
@@ -724,7 +727,10 @@
uint32_t type_idx = mir->dalvikInsn.vC;
loadCurrMethodDirect(cUnit, r1); // r1 <= current Method*
int classReg = r2; // r2 will hold the Class*
- if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method, type_idx)) {
+ if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
+ cUnit->dex_cache,
+ *cUnit->dex_file,
+ type_idx)) {
// Check we have access to type_idx and if not throw IllegalAccessError,
// returns Class* in r0
loadWordDisp(cUnit, rSELF,
@@ -740,7 +746,7 @@
loadWordDisp(cUnit, r1, Method::DexCacheResolvedTypesOffset().Int32Value(), classReg);
int32_t offset_of_type = Array::DataOffset().Int32Value() + (sizeof(Class*) * type_idx);
loadWordDisp(cUnit, classReg, offset_of_type, classReg);
- if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->method, type_idx)) {
+ if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache, type_idx)) {
// Need to test presence of type in dex cache at runtime
ArmLIR* hopBranch = genCmpImmBranch(cUnit, kArmCondNe, classReg, 0);
// Not resolved
@@ -787,7 +793,10 @@
uint32_t type_idx = mir->dalvikInsn.vB;
loadCurrMethodDirect(cUnit, r1); // r1 <= current Method*
int classReg = r2; // r2 will hold the Class*
- if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method, type_idx)) {
+ if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
+ cUnit->dex_cache,
+ *cUnit->dex_file,
+ type_idx)) {
// Check we have access to type_idx and if not throw IllegalAccessError,
// returns Class* in r0
loadWordDisp(cUnit, rSELF,
@@ -801,7 +810,7 @@
loadWordDisp(cUnit, r1, Method::DexCacheResolvedTypesOffset().Int32Value(), classReg);
int32_t offset_of_type = Array::DataOffset().Int32Value() + (sizeof(Class*) * type_idx);
loadWordDisp(cUnit, classReg, offset_of_type, classReg);
- if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->method, type_idx)) {
+ if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache, type_idx)) {
// Need to test presence of type in dex cache at runtime
ArmLIR* hopBranch = genCmpImmBranch(cUnit, kArmCondNe, classReg, 0);
// Not resolved
@@ -1793,7 +1802,7 @@
/* Check if we need to check for pending suspend request */
STATIC void genSuspendTest(CompilationUnit* cUnit, MIR* mir)
{
- if (NO_SUSPEND || mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK) {
+ if (NO_SUSPEND || (mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK)) {
return;
}
oatFlushAllRegs(cUnit);