Transmit mapping table to runtime

Pass the <native offset,dalvik offset> mapping table to the
runtime.  Also update the MonitorEnter/Exit stubs to optionally
take the thread pointer.

Change-Id: Ie1345fbafc6c0477deed44297bba1c566e6301f6
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 643e795..4ce3177 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -176,11 +176,6 @@
     kRetryHalve
 } AssemblerStatus;
 
-typedef struct MappingTable {
-    int targetOffset;
-    int dalvikOffset;
-} MappingTable;
-
 typedef struct CompilationUnit {
     int numInsts;
     int numBlocks;
@@ -198,7 +193,8 @@
     int totalSize;                      // header + code size
     AssemblerStatus assemblerStatus;    // Success or fix and retry
     int assemblerRetries;
-    std::vector<short>codeBuffer;
+    std::vector<short> codeBuffer;
+    std::vector<uint32_t> mappingTable;
     bool printMe;
     bool printMeVerbose;
     bool hasClassLiterals;              // Contains class ptrs used as literals
@@ -279,8 +275,6 @@
      */
      int currentDalvikOffset;
      GrowableList switchTables;
-     int mappingTableSize;
-     MappingTable* mappingTable;
      GrowableList fillArrayData;
      const u2* insns;
      u4 insnsSize;
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 2abefe10..702611d 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -861,19 +861,25 @@
         }
     }
 
-    art::ByteArray* managed_code = art::ByteArray::Alloc(cUnit.codeBuffer.size() * 2);
+    art::ByteArray* managed_code =
+        art::ByteArray::Alloc(cUnit.codeBuffer.size() *
+        sizeof(cUnit.codeBuffer[0]));
     memcpy(managed_code->GetData(),
            reinterpret_cast<const int8_t*>(&cUnit.codeBuffer[0]),
            managed_code->GetLength());
-    method->SetCode(managed_code, art::kThumb2);
+    art::ByteArray* mapping_table =
+        art::ByteArray::Alloc(cUnit.mappingTable.size() *
+        sizeof(cUnit.mappingTable[0]));
+    memcpy(mapping_table->GetData(),
+           reinterpret_cast<const int8_t*>(&cUnit.mappingTable[0]),
+           mapping_table->GetLength());
+    method->SetCode(managed_code, art::kThumb2, mapping_table);
     method->SetFrameSizeInBytes(cUnit.frameSize);
     method->SetCoreSpillMask(cUnit.coreSpillMask);
     method->SetFpSpillMask(cUnit.fpSpillMask);
     LOG(INFO) << "Compiled " << PrettyMethod(method)
               << " code at " << reinterpret_cast<void*>(managed_code->GetData())
               << " (" << managed_code->GetLength() << " bytes)";
-    // TODO: Transmit mapping table to caller
-
 #if 0
     oatDumpCFG(&cUnit, "/sdcard/cfg/");
 #endif
diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc
index dc8bdec..e51774e 100644
--- a/src/compiler/codegen/arm/ArchUtility.cc
+++ b/src/compiler/codegen/arm/ArchUtility.cc
@@ -473,21 +473,17 @@
     LOG(INFO) << "    };\n\n";
 
     // Dump mapping table
-    if (cUnit->mappingTableSize > 0) {
-        MappingTable *table = cUnit->mappingTable;
-        if (!table) {
-            LOG(FATAL) << "Null table";
-        }
+    if (cUnit->mappingTable.size() > 0) {
         sprintf(buf,"\n    MappingTable %s%s_%s_mappingTable[%d] = {",
                 descriptor.c_str(), name.c_str(), signature.c_str(),
-                cUnit->mappingTableSize);
+                cUnit->mappingTable.size());
         for (unsigned int i = 0; i < strlen(buf); i++)
             if (buf[i] == ';') buf[i] = '_';
         LOG(INFO) << buf;
         strcpy(buf,"       ");
-        for (int i = 0; i < cUnit->mappingTableSize; i++) {
+        for (uint32_t i = 0; i < cUnit->mappingTable.size(); i+=2) {
             sprintf(buf+strlen(buf)," {0x%08x, 0x%04x},",
-                    table[i].targetOffset, table[i].dalvikOffset);
+                cUnit->mappingTable[i], cUnit->mappingTable[i+1]);
             LOG(INFO) << buf;
             strcpy(buf,"       ");
         }
diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc
index 54e0aaf..2004d46 100644
--- a/src/compiler/codegen/arm/Assemble.cc
+++ b/src/compiler/codegen/arm/Assemble.cc
@@ -1429,11 +1429,10 @@
     return offset;
 }
 
-static int createMappingTable(CompilationUnit* cUnit, MappingTable** pTable)
+static void createMappingTable(CompilationUnit* cUnit)
 {
     ArmLIR* armLIR;
     int currentDalvikOffset = -1;
-    int count = 0;
 
     for (armLIR = (ArmLIR *) cUnit->firstLIRInsn;
          armLIR;
@@ -1441,17 +1440,11 @@
         if ((armLIR->opcode >= 0) && !armLIR->flags.isNop &&
             (currentDalvikOffset != armLIR->generic.dalvikOffset)) {
             // Changed - need to emit a record
-            if (pTable) {
-                MappingTable *table = *pTable;
-                assert(table);
-                table[count].targetOffset = armLIR->generic.offset;
-                table[count].dalvikOffset = armLIR->generic.dalvikOffset;
-            }
-            count++;
+            cUnit->mappingTable.push_back(armLIR->generic.offset);
+            cUnit->mappingTable.push_back(armLIR->generic.dalvikOffset);
             currentDalvikOffset = armLIR->generic.dalvikOffset;
         }
     }
-    return count;
 }
 
 /* Determine the offset of each literal field */
@@ -1577,8 +1570,5 @@
     /*
      * Create the mapping table
      */
-    cUnit->mappingTableSize = createMappingTable(cUnit, NULL /* just count */);
-    cUnit->mappingTable = (MappingTable*)oatNew(
-        cUnit->mappingTableSize * sizeof(*cUnit->mappingTable), true);
-    createMappingTable(cUnit, &cUnit->mappingTable);
+    createMappingTable(cUnit);
 }
diff --git a/src/object.cc b/src/object.cc
index edc5bdd..d7b6024 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -453,10 +453,12 @@
           this->GetSignature()->Equals(that->GetSignature()));
 }
 
-void Method::SetCode(ByteArray* code_array,
-                     InstructionSet instruction_set) {
+void Method::SetCode(ByteArray* code_array, InstructionSet instruction_set,
+                     ByteArray* mapping_table) {
   CHECK(!HasCode() || IsNative());
   SetFieldPtr<ByteArray*>(OFFSET_OF_OBJECT_MEMBER(Method, code_array_), code_array, false);
+  SetFieldPtr<ByteArray*>(OFFSET_OF_OBJECT_MEMBER(Method, mapping_table_),
+       mapping_table, false);
   int8_t* code = code_array->GetData();
   uintptr_t address = reinterpret_cast<uintptr_t>(code);
   if (instruction_set == kThumb2) {
diff --git a/src/object.h b/src/object.h
index bbd8acf..c0e725c 100644
--- a/src/object.h
+++ b/src/object.h
@@ -216,11 +216,13 @@
     SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Object, monitor_), monitor, false);
   }
 
-  void MonitorEnter() {
+  void MonitorEnter(Thread* thread = NULL) {
+    // TODO: use thread to get lock id
     GetMonitor()->Enter();
   }
 
-  void MonitorExit() {
+  void MonitorExit(Thread* thread = NULL) {
+    // TODO: use thread to get lock id
     GetMonitor()->Exit();
   }
 
@@ -856,7 +858,8 @@
     return GetCode() != NULL;
   }
 
-  void SetCode(ByteArray* code_array, InstructionSet instruction_set);
+  void SetCode(ByteArray* code_array, InstructionSet instruction_set,
+               ByteArray* mapping_table = NULL);
 
   static MemberOffset GetCodeOffset() {
     return OFFSET_OF_OBJECT_MEMBER(Method, code_);
@@ -1057,6 +1060,9 @@
   // Storage for code_
   const ByteArray* code_array_;
 
+  // Storage for mapping_table_
+  const ByteArray* mapping_table_;
+
   // Compiled code associated with this method for callers from managed code.
   // May be compiled managed code or a bridge for invoking a native method.
   const void* code_;
diff --git a/src/thread.cc b/src/thread.cc
index d40451e..7d909c9 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -119,13 +119,12 @@
 static void UnlockObjectFromCode(Thread* thread, Object* obj) {
     // TODO: throw and unwind if lock not held
     // TODO: throw and unwind on NPE
-    obj->MonitorExit();
+    obj->MonitorExit(thread);
 }
 
 // TODO: placeholder
 static void LockObjectFromCode(Thread* thread, Object* obj) {
-    // Need thread for ownership?
-    obj->MonitorEnter();
+    obj->MonitorEnter(thread);
 }
 
 void Thread::InitFunctionPointers() {