Merge "Fix endianness of compiled code and stacks of stubs for MIPS." into dalvik-dev
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 434320d..593fce5 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -576,6 +576,7 @@
    */
   int liveSReg;
 #endif
+  std::set<uint32_t> catches;
   int* opcodeCount;    // Count Dalvik opcodes for tuning
 };
 
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 09bc054..d1259b7 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -700,6 +700,7 @@
                                          false /* creat */,
                                          NULL  /* immedPredBlockP */);
       catchBlock->catchEntry = true;
+      cUnit->catches.insert(catchBlock->startOffset);
       SuccessorBlockInfo *successorBlockInfo = (SuccessorBlockInfo *)
           oatNew(cUnit, sizeof(SuccessorBlockInfo), false, kAllocSuccessor);
       successorBlockInfo->block = catchBlock;
@@ -840,7 +841,9 @@
   }
 #if defined(ART_USE_QUICK_COMPILER)
   if (cUnit->genBitcode) {
-    //cUnit->enableDebug |= (1 << kDebugVerifyBitcode);
+#ifndef NDEBUG
+    cUnit->enableDebug |= (1 << kDebugVerifyBitcode);
+#endif
     //cUnit->printMe = true;
     //cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
   }
diff --git a/src/compiler/codegen/CodegenUtil.cc b/src/compiler/codegen/CodegenUtil.cc
index 22aacc2..ccc2a83 100644
--- a/src/compiler/codegen/CodegenUtil.cc
+++ b/src/compiler/codegen/CodegenUtil.cc
@@ -764,6 +764,40 @@
   return offset;
 }
 
+// Make sure we have a code address for every declared catch entry
+bool verifyCatchEntries(CompilationUnit* cUnit)
+{
+  bool success = true;
+  for (std::set<uint32_t>::const_iterator it = cUnit->catches.begin(); it != cUnit->catches.end(); ++it) {
+    uint32_t dexPc = *it;
+    bool found = false;
+    for (size_t i = 0; i < cUnit->dex2pcMappingTable.size(); i += 2) {
+      if (dexPc == cUnit->dex2pcMappingTable[i+1]) {
+        found = true;
+        break;
+      }
+    }
+    if (!found) {
+      LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dexPc;
+      success = false;
+    }
+  }
+  // Now, try in the other direction
+  for (size_t i = 0; i < cUnit->dex2pcMappingTable.size(); i += 2) {
+    uint32_t dexPc = cUnit->dex2pcMappingTable[i+1];
+    if (cUnit->catches.find(dexPc) == cUnit->catches.end()) {
+      LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << dexPc;
+      success = false;
+    }
+  }
+  if (!success) {
+    LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
+    LOG(INFO) << "Entries @ decode: " << cUnit->catches.size() << ", Entries in table: "
+              << cUnit->dex2pcMappingTable.size()/2;
+  }
+  return success;
+}
+
 void createMappingTables(CompilationUnit* cUnit)
 {
   for (LIR* tgtLIR = (LIR *) cUnit->firstLIRInsn; tgtLIR != NULL; tgtLIR = NEXT_LIR(tgtLIR)) {
@@ -776,6 +810,7 @@
       cUnit->dex2pcMappingTable.push_back(tgtLIR->dalvikOffset);
     }
   }
+  DCHECK(verifyCatchEntries(cUnit));
   cUnit->combinedMappingTable.push_back(cUnit->pc2dexMappingTable.size() +
                                         cUnit->dex2pcMappingTable.size());
   cUnit->combinedMappingTable.push_back(cUnit->pc2dexMappingTable.size());
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index cff4ee5..a9e134f 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -540,10 +540,16 @@
   if (index == -1) {
     return;
   }
+  llvm::Type* ty = newVal->getType();
   greenland::IntrinsicHelper::IntrinsicId id =
       greenland::IntrinsicHelper::SetShadowFrameEntry;
   llvm::Function* func = cUnit->intrinsic_helper->GetIntrinsicFunction(id);
   llvm::Value* tableSlot = cUnit->irb->getInt32(index);
+  // If newVal is a Null pointer, we'll see it here as a const int.  Replace
+  if (!ty->isPointerTy()) {
+    // TODO: assert newVal created w/ dex_lang_const_int(0) or dex_lang_const_float(0)
+    newVal = cUnit->irb->GetJNull();
+  }
   llvm::Value* args[] = { newVal, tableSlot };
   cUnit->irb->CreateCall(func, args);
 }
@@ -2112,9 +2118,14 @@
     std::string errmsg;
     std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
     oatReplaceSpecialChars(fname);
-    // TODO: make configurable
+    // TODO: make configurable change naming mechanism to avoid fname length issues.
     fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());
 
+    if (fname.size() > 240) {
+      LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
+      fname.resize(240);
+    }
+
     llvm::OwningPtr<llvm::tool_output_file> out_file(
         new llvm::tool_output_file(fname.c_str(), errmsg,
                                    llvm::raw_fd_ostream::F_Binary));
diff --git a/src/oatdump.cc b/src/oatdump.cc
index c35d233..ab7f277 100644
--- a/src/oatdump.cc
+++ b/src/oatdump.cc
@@ -421,6 +421,7 @@
       return;
     }
 
+    ++raw_table;
     uint32_t length = *raw_table;
     ++raw_table;
     uint32_t pc_to_dex_entries = *raw_table;