Refactor the use of Method by the oat compiler.
Change-Id: Ib0ee18ed06846f82567f746edc7a5049dc6215df
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 5be48ab..49c84c1 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -193,8 +193,15 @@
int numInsts;
int numBlocks;
GrowableList blockList;
- const Compiler* compiler;
- const Method* method;
+ const Compiler* compiler; // Compiler driving this compiler
+ art::ClassLinker* class_linker; // Linker to resolve fields and methods
+ const art::DexFile* dex_file; // DexFile containing the method being compiled
+ art::DexCache* dex_cache; // DexFile's corresponding cache
+ const art::ClassLoader* class_loader; // compiling method's class loader
+ uint32_t method_idx; // compiling method's index into method_ids of DexFile
+ const art::DexFile::CodeItem* code_item; // compiling method's DexFile code_item
+ uint32_t access_flags; // compiling method's access flags
+ const char* shorty; // compiling method's shorty
LIR* firstLIRInsn;
LIR* lastLIRInsn;
LIR* literalList; // Constants
@@ -276,7 +283,7 @@
*/
int numIns;
int numOuts;
- int numRegs; // Unlike struct Method, does not include ins
+ int numRegs; // Unlike numDalvikRegisters, does not include ins
int numCoreSpills;
int numFPSpills;
int numPadding; // # of 4-byte padding cells
diff --git a/src/compiler/Dataflow.cc b/src/compiler/Dataflow.cc
index 0eff7ea..8b92c86 100644
--- a/src/compiler/Dataflow.cc
+++ b/src/compiler/Dataflow.cc
@@ -2110,11 +2110,10 @@
* blocks.
*/
bb->dataFlowInfo->dalvikToSSAMap =
- (int *)oatNew(sizeof(int) * cUnit->method->NumRegisters(),
- false);
+ (int *)oatNew(sizeof(int) * cUnit->numDalvikRegisters, false);
memcpy(bb->dataFlowInfo->dalvikToSSAMap, cUnit->dalvikToSSAMap,
- sizeof(int) * cUnit->method->NumRegisters());
+ sizeof(int) * cUnit->numDalvikRegisters);
return true;
}
@@ -2202,7 +2201,7 @@
void oatInitializeSSAConversion(CompilationUnit* cUnit)
{
int i;
- int numDalvikReg = cUnit->method->NumRegisters();
+ int numDalvikReg = cUnit->numDalvikRegisters;
cUnit->ssaToDalvikMap = (GrowableList *)oatNew(sizeof(GrowableList),
false);
@@ -2383,10 +2382,9 @@
if ((bb->blockType == kEntryBlock) | bb->catchEntry) {
oatClearAllBits(cUnit->tempSSARegisterV);
- if (!cUnit->method->IsStatic()) {
+ if ((cUnit->access_flags & art::kAccStatic) == 0) {
// If non-static method, mark "this" as non-null
- int thisReg = cUnit->method->NumRegisters() -
- cUnit->method->NumIns();
+ int thisReg = cUnit->numDalvikRegisters - cUnit->numIns;
oatSetBit(cUnit->tempSSARegisterV, thisReg);
}
} else {
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 9a2cc31..57d4616 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -215,7 +215,7 @@
void oatDumpCFG(CompilationUnit* cUnit, const char* dirPrefix)
{
FILE* file;
- std::string name = art::PrettyMethod(cUnit->method);
+ std::string name = art::PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
char startOffset[80];
sprintf(startOffset, "_%x", cUnit->entryBlock->fallThrough->startOffset);
char* fileName = (char *) oatNew(
@@ -416,12 +416,7 @@
/* Identify code range in try blocks and set up the empty catch blocks */
STATIC void processTryCatchBlocks(CompilationUnit* cUnit)
{
- const Method* method = cUnit->method;
- art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
- const art::DexFile& dex_file = class_linker->FindDexFile(
- method->GetDeclaringClass()->GetDexCache());
- const art::DexFile::CodeItem* code_item =
- dex_file.GetCodeItem(method->GetCodeItemOffset());
+ const art::DexFile::CodeItem* code_item = cUnit->code_item;
int triesSize = code_item->tries_size_;
int offset;
@@ -615,13 +610,7 @@
ArenaBitVector* tryBlockAddr, const u2* codePtr,
const u2* codeEnd)
{
-
- const Method* method = cUnit->method;
- art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
- const art::DexFile& dex_file = class_linker->FindDexFile(
- method->GetDeclaringClass()->GetDexCache());
- const art::DexFile::CodeItem* code_item =
- dex_file.GetCodeItem(method->GetCodeItemOffset());
+ const art::DexFile::CodeItem* code_item = cUnit->code_item;
/* In try block */
if (oatIsBitSet(tryBlockAddr, curOffset)) {
@@ -691,28 +680,16 @@
/*
* Compile a method.
*/
-CompiledMethod* oatCompileMethod(const Compiler& compiler, bool is_direct,
- uint32_t method_idx, const art::ClassLoader* class_loader,
- const art::DexFile& dex_file, art::InstructionSet insnSet)
+CompiledMethod* oatCompileMethod(const Compiler& compiler, const art::DexFile::CodeItem* code_item,
+ uint32_t access_flags, uint32_t method_idx,
+ const art::ClassLoader* class_loader,
+ const art::DexFile& dex_file, art::InstructionSet insnSet)
{
- art::ClassLinker* linker = art::Runtime::Current()->GetClassLinker();
- art::DexCache* dex_cache = linker->FindDexCache(dex_file);
- art::Method* method = linker->ResolveMethod(dex_file, method_idx, dex_cache,
- class_loader, is_direct);
- if (method == NULL) {
- CHECK(Thread::Current()->IsExceptionPending());
- Thread::Current()->ClearException();
- LOG(INFO) << "Couldn't resolve " << PrettyMethod(method_idx, dex_file, true)
- << " for compilation";
- return NULL;
- }
if (compiler.IsVerbose()) {
- LOG(INFO) << "Compiling " << PrettyMethod(method) << "...";
+ LOG(INFO) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
}
oatArenaReset();
- const art::DexFile::CodeItem* code_item =
- dex_file.GetCodeItem(method->GetCodeItemOffset());
const u2* codePtr = code_item->insns_;
const u2* codeEnd = code_item->insns_ + code_item->insns_size_in_code_units_;
int numBlocks = 0;
@@ -720,16 +697,28 @@
oatInit(compiler);
+ art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
UniquePtr<CompilationUnit> cUnit(new CompilationUnit);
memset(cUnit.get(), 0, sizeof(*cUnit));
cUnit->compiler = &compiler;
- cUnit->method = method;
+ cUnit->class_linker = class_linker;
+ cUnit->dex_file = &dex_file;
+ cUnit->dex_cache = class_linker->FindDexCache(dex_file);
+ cUnit->method_idx = method_idx;
+ cUnit->code_item = code_item;
+ cUnit->access_flags = access_flags;
+ cUnit->shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));
cUnit->instructionSet = (OatInstructionSetType)insnSet;
cUnit->insns = code_item->insns_;
cUnit->insnsSize = code_item->insns_size_in_code_units_;
+ cUnit->numIns = code_item->ins_size_;
+ cUnit->numRegs = code_item->registers_size_ - cUnit->numIns;
+ cUnit->numOuts = code_item->outs_size_;
+ /* Adjust this value accordingly once inlining is performed */
+ cUnit->numDalvikRegisters = code_item->registers_size_;
bool useMatch = compilerMethodMatch.length() != 0;
bool match = useMatch && (compilerFlipMatch ^
- (PrettyMethod(method).find(compilerMethodMatch) != std::string::npos));
+ (PrettyMethod(method_idx, dex_file).find(compilerMethodMatch) != std::string::npos));
if (!useMatch || match) {
cUnit->disableOpt = compilerOptimizerDisableFlags;
cUnit->enableDebug = compilerDebugFlags;
@@ -860,10 +849,6 @@
oatDumpCompilationUnit(cUnit.get());
}
- /* Adjust this value accordingly once inlining is performed */
- cUnit->numDalvikRegisters = cUnit->method->NumRegisters();
-
-
/* Verify if all blocks are connected as claimed */
oatDataFlowAnalysisDispatcher(cUnit.get(), verifyPredInfo, kAllNodes, false /* isIterative */);
@@ -922,7 +907,7 @@
vmapTable);
if (compiler.IsVerbose()) {
- LOG(INFO) << "Compiled " << PrettyMethod(method)
+ LOG(INFO) << "Compiled " << PrettyMethod(method_idx, dex_file)
<< " (" << (cUnit->codeBuffer.size() * sizeof(cUnit->codeBuffer[0])) << " bytes)";
}
diff --git a/src/compiler/Ralloc.cc b/src/compiler/Ralloc.cc
index 184db9f..9a50c83 100644
--- a/src/compiler/Ralloc.cc
+++ b/src/compiler/Ralloc.cc
@@ -232,7 +232,7 @@
*/
if ((definedFP && definedCore) &&
((cUnit->disableOpt & (1 << kPromoteRegs)) == 0)) {
- LOG(WARNING) << art::PrettyMethod(cUnit->method)
+ LOG(WARNING) << art::PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
<< " op at block " << bb->id
<< " has both fp and core uses for same def.";
cUnit->disableOpt |= (1 << kPromoteRegs);
@@ -289,23 +289,24 @@
cUnit->regLocation = loc;
/* Allocation the promotion map */
- cUnit->promotionMap = (PromotionMap*)oatNew( cUnit->method->NumRegisters()
- * sizeof(cUnit->promotionMap[0]), true);
+ int numRegs = cUnit->numDalvikRegisters;
+ cUnit->promotionMap =
+ (PromotionMap*)oatNew(numRegs * sizeof(cUnit->promotionMap[0]), true);
/* Add types of incoming arguments based on signature */
- int numRegs = cUnit->method->NumRegisters();
- int numIns = cUnit->method->NumIns();
+ int numIns = cUnit->numIns;
if (numIns > 0) {
int sReg = numRegs - numIns;
- if (!cUnit->method->IsStatic()) {
- // Skip past "this"
+ if ((cUnit->access_flags & art::kAccStatic) == 0) {
+ // For non-static, skip past "this"
cUnit->regLocation[sReg].defined = true;
cUnit->regLocation[sReg].core = true;
sReg++;
}
- const String* shorty = cUnit->method->GetShorty();
- for (int i = 1; i < shorty->GetLength(); i++) {
- switch(shorty->CharAt(i)) {
+ const char* shorty = cUnit->shorty;
+ int shorty_len = strlen(shorty);
+ for (int i = 1; i < shorty_len; i++) {
+ switch(shorty[i]) {
case 'D':
cUnit->regLocation[sReg].wide = true;
cUnit->regLocation[sReg+1].highWord = true;
@@ -369,9 +370,6 @@
}
/* Figure out the frame size */
- cUnit->numIns = cUnit->method->NumIns();
- cUnit->numRegs = cUnit->method->NumRegisters() - cUnit->numIns;
- cUnit->numOuts = cUnit->method->NumOuts();
cUnit->numPadding = (STACK_ALIGN_WORDS -
(cUnit->numCoreSpills + cUnit->numFPSpills + cUnit->numRegs +
cUnit->numOuts + 2)) & (STACK_ALIGN_WORDS-1);
diff --git a/src/compiler/SSATransformation.cc b/src/compiler/SSATransformation.cc
index d35a8c7..235521d 100644
--- a/src/compiler/SSATransformation.cc
+++ b/src/compiler/SSATransformation.cc
@@ -107,10 +107,10 @@
* Also set the incoming parameters as defs in the entry block.
* Only need to handle the parameters for the outer method.
*/
- int inReg = cUnit->method->NumRegisters() - cUnit->method->NumIns();
- for (; inReg < cUnit->method->NumRegisters(); inReg++) {
- oatSetBit(cUnit->defBlockMatrix[inReg],
- cUnit->entryBlock->id);
+ int numRegs = cUnit->numDalvikRegisters;
+ int inReg = numRegs - cUnit->numIns;
+ for (; inReg < numRegs; inReg++) {
+ oatSetBit(cUnit->defBlockMatrix[inReg], cUnit->entryBlock->id);
}
}
@@ -562,7 +562,7 @@
/* Process this block */
oatDoSSAConversion(cUnit, block);
- int mapSize = sizeof(int) * cUnit->method->NumRegisters();
+ int mapSize = sizeof(int) * cUnit->numDalvikRegisters;
/* Save SSA map snapshot */
int* savedSSAMap = (int*)oatNew(mapSize, false);
diff --git a/src/compiler/Utility.cc b/src/compiler/Utility.cc
index e3c20ec..d292494 100644
--- a/src/compiler/Utility.cc
+++ b/src/compiler/Utility.cc
@@ -163,7 +163,7 @@
"Catch Block"
};
- LOG(INFO) << "Compiling " << art::PrettyMethod(cUnit->method);
+ LOG(INFO) << "Compiling " << art::PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
LOG(INFO) << cUnit->insns << " insns";
LOG(INFO) << cUnit->numBlocks << " blocks in total";
GrowableListIterator iterator;
@@ -530,10 +530,6 @@
const char* oatGetShortyFromTargetIdx(CompilationUnit *cUnit, int targetIdx)
{
- art::DexCache* dex_cache =
- cUnit->method->GetDeclaringClass()->GetDexCache();
- art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
- const art::DexFile& dex_file = class_linker->FindDexFile(dex_cache);
- const art::DexFile::MethodId& methodId = dex_file.GetMethodId(targetIdx);
- return dex_file.GetShorty(methodId.proto_idx_);
+ const art::DexFile::MethodId& methodId = cUnit->dex_file->GetMethodId(targetIdx);
+ return cUnit->dex_file->GetShorty(methodId.proto_idx_);
}
diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc
index 2a20efa..b702682 100644
--- a/src/compiler/codegen/arm/ArchUtility.cc
+++ b/src/compiler/codegen/arm/ArchUtility.cc
@@ -309,7 +309,7 @@
switch(lir->opcode) {
case kArmPseudoMethodEntry:
LOG(INFO) << "-------- method entry " <<
- art::PrettyMethod(cUnit->method);
+ art::PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
break;
case kArmPseudoMethodExit:
LOG(INFO) << "-------- Method_Exit";
@@ -380,8 +380,7 @@
void oatDumpPromotionMap(CompilationUnit *cUnit)
{
- const Method *method = cUnit->method;
- for (int i = 0; i < method->NumRegisters(); i++) {
+ for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
PromotionMap vRegMap = cUnit->promotionMap[i];
char buf[100];
if (vRegMap.fpLocation == kLocPhysReg) {
@@ -400,8 +399,7 @@
void oatDumpFullPromotionMap(CompilationUnit *cUnit)
{
- const Method *method = cUnit->method;
- for (int i = 0; i < method->NumRegisters(); i++) {
+ for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
PromotionMap vRegMap = cUnit->promotionMap[i];
LOG(INFO) << i << " -> " << "CL:" << (int)vRegMap.coreLocation <<
", CR:" << (int)vRegMap.coreReg << ", FL:" <<
@@ -413,9 +411,9 @@
/* Dump instructions and constant pool contents */
void oatCodegenDump(CompilationUnit* cUnit)
{
- const Method *method = cUnit->method;
LOG(INFO) << "/*";
- LOG(INFO) << "Dumping LIR insns for " << art::PrettyMethod(cUnit->method);
+ LOG(INFO) << "Dumping LIR insns for "
+ << art::PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
LIR* lirInsn;
ArmLIR* armLIR;
int insnsSize = cUnit->insnsSize;
@@ -449,10 +447,12 @@
armLIR->generic.offset, armLIR->generic.offset, armLIR->operands[0]);
}
- std::string signature = method->GetSignature()->ToModifiedUtf8();
- std::string name = method->GetName()->ToModifiedUtf8();
- std::string descriptor = method->GetDeclaringClass()->GetDescriptor()->
- ToModifiedUtf8();
+ const art::DexFile::MethodId& method_id =
+ cUnit->dex_file->GetMethodId(cUnit->method_idx);
+ std::string signature = cUnit->dex_file->GetMethodSignature(method_id);
+ std::string name = cUnit->dex_file->GetMethodName(method_id);
+ std::string descriptor =
+ cUnit->dex_file->GetMethodDeclaringClassDescriptor(method_id);
// Dump mapping table
if (cUnit->mappingTable.size() > 0) {
diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc
index 81c721d..5d2c4e6 100644
--- a/src/compiler/codegen/arm/ArmRallocUtil.cc
+++ b/src/compiler/codegen/arm/ArmRallocUtil.cc
@@ -111,7 +111,7 @@
*/
extern void oatDoPromotion(CompilationUnit* cUnit)
{
- int numRegs = cUnit->method->NumRegisters();
+ int numRegs = cUnit->numDalvikRegisters;
/*
* TUNING: is leaf? Can't just use "hasInvoke" to determine as some
diff --git a/src/compiler/codegen/arm/CodegenCommon.cc b/src/compiler/codegen/arm/CodegenCommon.cc
index 4a2768c..9b71b14 100644
--- a/src/compiler/codegen/arm/CodegenCommon.cc
+++ b/src/compiler/codegen/arm/CodegenCommon.cc
@@ -283,7 +283,7 @@
DCHECK(isPseudoOpcode(opcode) ||
(EncodingMap[opcode].flags & IS_TERTIARY_OP))
<< (int)opcode << " "
- << PrettyMethod(cUnit->method) << " "
+ << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
<< cUnit->currentDalvikOffset;
insn->opcode = opcode;
insn->operands[0] = dest;
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index a32446a..7a719f7 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -47,12 +47,15 @@
{
oatFlushAllRegs(cUnit); /* Everything to home location */
uint32_t type_idx = mir->dalvikInsn.vC;
- 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, pAllocArrayFromCode), rLR);
} else {
UNIMPLEMENTED(WARNING) << "Need to check access of '"
- << PrettyMethod(cUnit->method)
+ << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
<< "' to unresolved type " << type_idx;
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pAllocArrayFromCode), rLR);
@@ -79,9 +82,13 @@
oatFlushAllRegs(cUnit); /* Everything to home location */
loadWordDisp(cUnit, rSELF,
OFFSETOF_MEMBER(Thread, pCheckAndAllocArrayFromCode), rLR);
- if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method, typeId)) {
- UNIMPLEMENTED(WARNING) << "Need to check access of '" << PrettyMethod(cUnit->method)
- << "' to unresolved type " << typeId;
+ if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
+ cUnit->dex_cache,
+ *cUnit->dex_file,
+ typeId)) {
+ UNIMPLEMENTED(WARNING) << "Need to check access of '"
+ << PrettyMethod(cUnit->method_idx, *cUnit->dex_file)
+ << "' to unresolved type " << typeId;
}
loadCurrMethodDirect(cUnit, r1); // arg1 <- Method*
loadConstant(cUnit, r0, typeId); // arg0 <- type_id
@@ -158,11 +165,14 @@
}
}
-Field* FindFieldWithResolvedStaticStorage(const Method* method,
+Field* FindFieldWithResolvedStaticStorage(CompilationUnit* cUnit,
const uint32_t fieldIdx,
uint32_t& resolvedTypeIdx) {
- art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
- Field* field = class_linker->ResolveField(fieldIdx, method, true);
+ Field* field = cUnit->class_linker->ResolveField(*cUnit->dex_file,
+ fieldIdx,
+ cUnit->dex_cache,
+ cUnit->class_loader,
+ true);
if (field == NULL) {
Thread* thread = Thread::Current();
if (thread->IsExceptionPending()) { // clear any exception left by resolve field
@@ -170,11 +180,9 @@
}
return NULL;
}
- const art::DexFile& dex_file = class_linker->
- FindDexFile(method->GetDeclaringClass()->GetDexCache());
- const art::DexFile::FieldId& field_id = dex_file.GetFieldId(fieldIdx);
+ const art::DexFile::FieldId& field_id = cUnit->dex_file->GetFieldId(fieldIdx);
int type_idx = field_id.class_idx_;
- Class* klass = method->GetDexCacheResolvedTypes()->Get(type_idx);
+ Class* klass = cUnit->dex_cache->GetResolvedTypes()->Get(type_idx);
// Check if storage class is the same as class referred to by type idx.
// They may not be if the FieldId refers a subclass, but storage is in super
if (field->GetDeclaringClass() == klass) {
@@ -185,14 +193,18 @@
// we may not if the dex file never references the super class,
// but usually it will.
std::string descriptor = field->GetDeclaringClass()->GetDescriptor()->ToModifiedUtf8();
- for (size_t type_idx = 0; type_idx < dex_file.NumTypeIds(); type_idx++) {
- const art::DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx);
- if (descriptor == dex_file.GetTypeDescriptor(type_id)) {
- resolvedTypeIdx = type_idx;
- return field;
- }
+ const art::DexFile::StringId* string_id =
+ cUnit->dex_file->FindStringId(descriptor);
+ if (string_id == NULL) {
+ return NULL; // descriptor not found, resort to slow path
}
- return NULL; // resort to slow path
+ const art::DexFile::TypeId* type_id =
+ cUnit->dex_file->FindTypeId(cUnit->dex_file->GetIndexForStringId(*string_id));
+ if (type_id == NULL) {
+ return NULL; // type id not found, resort to slow path
+ }
+ resolvedTypeIdx = cUnit->dex_file->GetIndexForTypeId(*type_id);
+ return field;
}
STATIC void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
@@ -201,7 +213,7 @@
(mir->dalvikInsn.opcode == OP_SPUT_OBJECT_VOLATILE));
int fieldIdx = mir->dalvikInsn.vB;
uint32_t typeIdx;
- Field* field = FindFieldWithResolvedStaticStorage(cUnit->method, fieldIdx, typeIdx);
+ Field* field = FindFieldWithResolvedStaticStorage(cUnit, fieldIdx, typeIdx);
oatFlushAllRegs(cUnit);
if (SLOW_FIELD_PATH || field == NULL) {
// Slow path
@@ -261,7 +273,7 @@
{
int fieldIdx = mir->dalvikInsn.vB;
uint32_t typeIdx;
- Field* field = FindFieldWithResolvedStaticStorage(cUnit->method, fieldIdx, typeIdx);
+ Field* field = FindFieldWithResolvedStaticStorage(cUnit, fieldIdx, typeIdx);
oatFlushAllRegs(cUnit);
#if ANDROID_SMP != 0
bool isVolatile = (field == NULL) || field->IsVolatile();
@@ -312,7 +324,7 @@
{
int fieldIdx = mir->dalvikInsn.vB;
uint32_t typeIdx;
- Field* field = FindFieldWithResolvedStaticStorage(cUnit->method, fieldIdx, typeIdx);
+ Field* field = FindFieldWithResolvedStaticStorage(cUnit, fieldIdx, typeIdx);
#if ANDROID_SMP != 0
bool isVolatile = (field == NULL) || field->IsVolatile();
#else
@@ -364,7 +376,7 @@
{
int fieldIdx = mir->dalvikInsn.vB;
uint32_t typeIdx;
- Field* field = FindFieldWithResolvedStaticStorage(cUnit->method, fieldIdx, typeIdx);
+ Field* field = FindFieldWithResolvedStaticStorage(cUnit, fieldIdx, typeIdx);
bool isObject = ((mir->dalvikInsn.opcode == OP_SGET_OBJECT) ||
(mir->dalvikInsn.opcode == OP_SGET_OBJECT_VOLATILE));
oatFlushAllRegs(cUnit);
@@ -466,8 +478,11 @@
* This is the fast path in which the target virtual method is
* fully resolved at compile time.
*/
- art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
- Method* baseMethod = class_linker->ResolveMethod(dInsn->vB, cUnit->method, false);
+ Method* baseMethod = cUnit->class_linker->ResolveMethod(*cUnit->dex_file,
+ dInsn->vB,
+ cUnit->dex_cache,
+ cUnit->class_loader,
+ false);
CHECK(baseMethod != NULL);
uint32_t target_idx = baseMethod->GetMethodIndex();
switch(state) {
@@ -631,9 +646,16 @@
* within the size of the super's vtable has been done at compile-time.
*/
art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
- Method* baseMethod = class_linker->ResolveMethod(dInsn->vB, cUnit->method, false);
+ Method* baseMethod = class_linker->ResolveMethod(*cUnit->dex_file,
+ dInsn->vB,
+ cUnit->dex_cache,
+ cUnit->class_loader,
+ false);
CHECK(baseMethod != NULL);
- Class* superClass = cUnit->method->GetDeclaringClass()->GetSuperClass();
+ Class* declaring_class = cUnit->dex_cache->GetResolvedTypes()
+ ->Get(cUnit->dex_file->GetMethodId(cUnit->method_idx).class_idx_);
+ Class* superClass = (declaring_class != NULL)
+ ? declaring_class->GetSuperClass() : NULL;
CHECK(superClass != NULL);
int32_t target_idx = baseMethod->GetMethodIndex();
CHECK(superClass->GetVTable()->GetLength() > target_idx);
@@ -872,7 +894,7 @@
* Dalvik vRegs and the ins.
*/
int highestArg = oatGetSrc(cUnit, mir, numArgs-1).sRegLow;
- int boundaryReg = cUnit->method->NumRegisters() - cUnit->method->NumIns();
+ int boundaryReg = cUnit->numDalvikRegisters - cUnit->numIns;
if ((firstArg < boundaryReg) && (highestArg >= boundaryReg)) {
LOG(FATAL) << "Argument list spanned locals & args";
}
@@ -971,7 +993,7 @@
// Is this the special "Ljava/lang/Object;.<init>:()V" case?
if (mir->dalvikInsn.opcode == OP_INVOKE_DIRECT) {
int idx = mir->dalvikInsn.vB;
- Method* target = cUnit->method->GetDexCacheResolvedMethods()->Get(idx);
+ Method* target = cUnit->dex_cache->GetResolvedMethods()->Get(idx);
if (target) {
if (PrettyMethod(target) == "java.lang.Object.<init>()V") {
RegLocation rlArg = oatGetSrc(cUnit, mir, 0);
@@ -1043,7 +1065,11 @@
int callState = 0;
ArmLIR* rollback;
art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
- Method* baseMethod = class_linker->ResolveMethod(dInsn->vB, cUnit->method, false);
+ Method* baseMethod = class_linker->ResolveMethod(*cUnit->dex_file,
+ dInsn->vB,
+ cUnit->dex_cache,
+ cUnit->class_loader,
+ false);
NextCallInsn nextCallInsn;
bool fastPath = true;
oatFlushAllRegs(cUnit); /* Everything to home location */
@@ -1057,7 +1083,10 @@
}
fastPath = false;
} else {
- Class* superClass = cUnit->method->GetDeclaringClass()->GetSuperClass();
+ Class* declaring_class = cUnit->dex_cache->GetResolvedTypes()
+ ->Get(cUnit->dex_file->GetMethodId(cUnit->method_idx).class_idx_);
+ Class* superClass = (declaring_class != NULL)
+ ? declaring_class->GetSuperClass() : NULL;
if (superClass == NULL) {
fastPath = false;
} else {
@@ -1100,7 +1129,11 @@
int callState = 0;
ArmLIR* rollback;
art::ClassLinker* class_linker = art::Runtime::Current()->GetClassLinker();
- Method* method = class_linker->ResolveMethod(dInsn->vB, cUnit->method, false);
+ Method* method = class_linker->ResolveMethod(*cUnit->dex_file,
+ dInsn->vB,
+ cUnit->dex_cache,
+ cUnit->class_loader,
+ false);
NextCallInsn nextCallInsn;
oatFlushAllRegs(cUnit); /* Everything to home location */
@@ -1825,12 +1858,11 @@
*/
STATIC void flushIns(CompilationUnit* cUnit)
{
- if (cUnit->method->NumIns() == 0)
+ if (cUnit->numIns == 0)
return;
int firstArgReg = r1;
int lastArgReg = r3;
- int startVReg = cUnit->method->NumRegisters() -
- cUnit->method->NumIns();
+ int startVReg = cUnit->numDalvikRegisters - cUnit->numIns;
/*
* Arguments passed in registers should be flushed
* to their backing locations in the frame for now.
@@ -1842,7 +1874,7 @@
* cases, copy argument to both. This will be uncommon
* enough that it isn't worth attempting to optimize.
*/
- for (int i = 0; i < cUnit->method->NumIns(); i++) {
+ for (int i = 0; i < cUnit->numIns; i++) {
PromotionMap vMap = cUnit->promotionMap[startVReg + i];
if (i <= (lastArgReg - firstArgReg)) {
// If arriving in register
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);