OSDN Git Service

Add tables to map between callee saves and vregs
authorbuzbee <buzbee@google.com>
Fri, 23 Sep 2011 19:46:19 +0000 (12:46 -0700)
committerbuzbee <buzbee@google.com>
Fri, 23 Sep 2011 20:53:25 +0000 (13:53 -0700)
Also added function to return sp-relative offset for Dalvik
virtual registers using Method*

[Note: must be matched with corresponding libcore change to
reflect new field in Method]

Change-Id: Id739908c6232ce60763d8199bc05111e960da46e

src/class_linker_test.cc
src/compiler.h
src/compiler/CompilerIR.h
src/compiler/Frontend.cc
src/compiler/codegen/RallocUtil.cc
src/compiler/codegen/arm/ArchUtility.cc
src/compiler/codegen/arm/ArmRallocUtil.cc
src/object.cc
src/object.h

index a920007..c3b063c 100644 (file)
@@ -449,6 +449,7 @@ struct MethodOffsets : public CheckOffsets {
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, register_map_header_),                  "shadow$_register_map_header_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, shorty_),                               "shadow$_shorty_"));
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, signature_),                            "shadow$_signature_"));
+    offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, vmap_table_),                           "shadow$_vmap_table_"));
 
     // alphabetical 32-bit
     offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_generic_types_are_initialized_),   "genericTypesAreInitialized"));
index 26b33b8..50447db 100644 (file)
@@ -45,6 +45,7 @@ class Compiler {
   void CompileDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
   void CompileClass(Class* klass);
   void CompileMethod(Method* klass);
+  int oatVRegOffsetFromMethod(Method* method, int reg);
 
   // After compiling, walk all the DexCaches and set the code and
   // method pointers of CodeAndDirectMethods entries in the DexCaches.
index 0965c14..5a38c47 100644 (file)
@@ -198,6 +198,8 @@ typedef struct CompilationUnit {
     int assemblerRetries;
     std::vector<short> codeBuffer;
     std::vector<uint32_t> mappingTable;
+    std::vector<uint32_t> coreVmapTable;
+    std::vector<short> fpVmapTable;
     bool printMe;
     bool printMeVerbose;
     bool dumpCFG;
index 6a01e36..9659903 100644 (file)
@@ -889,7 +889,21 @@ bool oatCompileMethod(const Compiler& compiler, Method* method, art::Instruction
     memcpy(mapping_table->GetData(),
            reinterpret_cast<const int32_t*>(&cUnit.mappingTable[0]),
            mapping_table->GetLength() * sizeof(cUnit.mappingTable[0]));
-    method->SetCode(managed_code, art::kThumb2, mapping_table);
+    // Add a marker to take place of lr
+    cUnit.coreVmapTable.push_back(-1);
+    // Combine vmap tables - core regs, then fp regs
+    for (uint32_t i = 0; i < cUnit.fpVmapTable.size(); i++) {
+        cUnit.coreVmapTable.push_back(cUnit.fpVmapTable[i]);
+    }
+    DCHECK(cUnit.coreVmapTable.size() == (uint32_t)
+        (__builtin_popcount(cUnit.coreSpillMask) +
+         __builtin_popcount(cUnit.fpSpillMask)));
+    art::ShortArray* vmap_table =
+        art::ShortArray::Alloc(cUnit.coreVmapTable.size());
+    memcpy(vmap_table->GetData(),
+           reinterpret_cast<const int16_t*>(&cUnit.coreVmapTable[0]),
+           vmap_table->GetLength() * sizeof(cUnit.coreVmapTable[0]));
+    method->SetCode(managed_code, art::kThumb2, mapping_table, vmap_table);
     method->SetFrameSizeInBytes(cUnit.frameSize);
     method->SetReturnPcOffsetInBytes(cUnit.frameSize - sizeof(intptr_t));
     method->SetCoreSpillMask(cUnit.coreSpillMask);
index 8b84500..8b9ae13 100644 (file)
@@ -220,6 +220,7 @@ extern int oatAllocPreservedCoreReg(CompilationUnit* cUnit, int sReg)
             res = coreRegs[i].reg;
             coreRegs[i].inUse = true;
             cUnit->coreSpillMask |= (1 << res);
+            cUnit->coreVmapTable.push_back(sReg);
             cUnit->numSpills++;
             cUnit->regLocation[sReg].location = kLocPhysReg;
             cUnit->regLocation[sReg].lowReg = res;
@@ -245,6 +246,7 @@ static int allocPreservedSingle(CompilationUnit* cUnit, int sReg, bool even)
             res = FPRegs[i].reg;
             FPRegs[i].inUse = true;
             cUnit->fpSpillMask |= (1 << (res & FP_REG_MASK));
+            cUnit->fpVmapTable.push_back(sReg);
             cUnit->numSpills++;
             cUnit->numFPSpills++;
             cUnit->regLocation[sReg].fpLocation = kLocPhysReg;
index 45e1b19..350f38c 100644 (file)
@@ -450,13 +450,15 @@ void oatCodegenDump(CompilationUnit* cUnit)
 
     }
 
-    int linebreak = 0;
     std::string signature = method->GetSignature()->ToModifiedUtf8();
     std::string name = method->GetName()->ToModifiedUtf8();
     std::string descriptor = method->GetDeclaringClass()->GetDescriptor()->
         ToModifiedUtf8();
 
     char buf[256];
+#if 0
+    int linebreak = 0;
+    //TODO: delete when we're sure it's no longer necessary
     LOG(INFO) << "*/";
     sprintf(buf,"\n    u1 %s%s_%s_code[] = {", descriptor.c_str(),
             name.c_str(), signature.c_str());
@@ -477,6 +479,7 @@ void oatCodegenDump(CompilationUnit* cUnit)
         LOG(INFO) << buf;
     }
     LOG(INFO) << "    };\n\n";
+#endif
 
     // Dump mapping table
     if (cUnit->mappingTable.size() > 0) {
@@ -495,4 +498,6 @@ void oatCodegenDump(CompilationUnit* cUnit)
         }
         LOG(INFO) <<"    };\n\n";
     }
+
+    // Dump vmap table
 }
index 030131f..0908c6d 100644 (file)
@@ -260,6 +260,21 @@ extern int oatVRegOffset(CompilationUnit* cUnit, int reg)
             cUnit->insOffset + ((reg - cUnit->numRegs) << 2);
 }
 
+/* Return sp-relative offset in bytes using Method* */
+extern int oatVRegOffsetFromMethod(Method* method, int reg)
+{
+    int numIns = method->NumIns();
+    int numRegs = method->NumRegisters() - numIns;
+    int numOuts = method->NumOuts();
+    int numSpills = __builtin_popcount(method->GetCoreSpillMask()) +
+                    __builtin_popcount(method->GetFpSpillMask());
+    int numPadding = (STACK_ALIGN_WORDS -
+        (numSpills + numRegs + numOuts + 2)) & (STACK_ALIGN_WORDS-1);
+    int regsOffset = (numOuts + numPadding + 1) * 4;
+    int insOffset = method->GetFrameSizeInBytes() + 4;
+    return (reg < numRegs) ? regsOffset + (reg << 2) :
+           insOffset + ((reg - numRegs) << 2);
+}
 
 /* Clobber all regs that might be used by an external C call */
 extern void oatClobberCallRegs(CompilationUnit *cUnit)
index 1af840f..12cd68d 100644 (file)
@@ -593,11 +593,13 @@ uint32_t Method::FindCatchBlock(Class* exception_type, uint32_t dex_pc) const {
 }
 
 void Method::SetCode(ByteArray* code_array, InstructionSet instruction_set,
-                     IntArray* mapping_table) {
+                     IntArray* mapping_table, ShortArray* vmap_table) {
   CHECK(GetCode() == NULL || IsNative());
   SetFieldPtr<ByteArray*>(OFFSET_OF_OBJECT_MEMBER(Method, code_array_), code_array, false);
   SetFieldPtr<IntArray*>(OFFSET_OF_OBJECT_MEMBER(Method, mapping_table_),
        mapping_table, false);
+  SetFieldPtr<ShortArray*>(OFFSET_OF_OBJECT_MEMBER(Method, vmap_table_),
+       vmap_table, false);
   int8_t* code = code_array->GetData();
   uintptr_t address = reinterpret_cast<uintptr_t>(code);
   if (instruction_set == kThumb2) {
index 51b9213..ffc8caf 100644 (file)
@@ -816,7 +816,7 @@ class MANAGED Method : public AccessibleObject {
   }
 
   void SetCode(ByteArray* code_array, InstructionSet instruction_set,
-               IntArray* mapping_table = NULL);
+               IntArray* mapping_table = NULL, ShortArray* vmap_table = NULL);
 
   static MemberOffset GetCodeOffset() {
     return OFFSET_OF_OBJECT_MEMBER(Method, code_);
@@ -830,6 +830,11 @@ class MANAGED Method : public AccessibleObject {
         OFFSET_OF_OBJECT_MEMBER(Method, mapping_table_), false);
   }
 
+  ShortArray* GetVMapTable() const {
+    return GetFieldObject<ShortArray*>(
+        OFFSET_OF_OBJECT_MEMBER(Method, vmap_table_), false);
+  }
+
   size_t GetFrameSizeInBytes() const {
     DCHECK(sizeof(size_t) == sizeof(uint32_t));
     size_t result = GetField32(
@@ -1017,6 +1022,9 @@ class MANAGED Method : public AccessibleObject {
   //   (IDLjava/lang/Thread;)Ljava/lang/Object;
   String* signature_;
 
+  // Storage for Dalvik virtual register mapping_table_
+  ShortArray* vmap_table_;
+
   uint32_t java_generic_types_are_initialized_;
 
   // Access flags; low 16 bits are defined by spec.