Milestone: close Quick side channel communication

This CL elminates side-channel communication between the Quick
Compiler's Dex->MIR->LLVM-IR and LLVM-IR->LIR lowering stages by clearing
key data structures between the two stages.

The purpose if to flush out any hidden information transfer, and thus
ensure that the GreenlandIR representation of the program is sufficient.

Note that as of this change, we've lost all register promotion info
so the Quick compiler will generate non-promoted code.  A near-future
CL will restore that info from the MethodInfo intrinsic.

Change-Id: I797845f1fc029bc03aac3ec20f8cd81f917817ca
diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h
index 2f95be2..4d749ce 100644
--- a/src/compiler/Compiler.h
+++ b/src/compiler/Compiler.h
@@ -127,6 +127,9 @@
   kDebugShowMemoryUsage,
   kDebugShowNops,
   kDebugCountOpcodes,
+#if defined(ART_USE_QUICK_COMPILER)
+  kDebugDumpBitcodeFile,
+#endif
 };
 
 enum OatMethodAttributes {
@@ -193,6 +196,7 @@
 void oatProcessSwitchTables(CompilationUnit* cUnit);
 bool oatIsFpReg(int reg);
 uint32_t oatFpRegMask(void);
+void oatReplaceSpecialChars(std::string& str);
 
 }  // namespace art
 
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index b1c7427..ba99715 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -504,6 +504,7 @@
 
   /* SSA name for Method* */
   int methodSReg;
+  RegLocation methodLoc;            // Describes location of method*
 
   /*
    * Set to the Dalvik PC of the switch instruction if it has more than
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index d5e6b12..3d6e983 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -52,6 +52,9 @@
   //(1 << kDebugShowMemoryUsage) |
   //(1 << kDebugShowNops) |
   //(1 << kDebugCountOpcodes) |
+#if defined(ART_USE_QUICK_COMPILER)
+  //(1 << kDebugDumpBitcodeFile) |
+#endif
   0;
 
 inline bool contentIsInsn(const u2* codePtr) {
@@ -243,37 +246,26 @@
   return bb;
 }
 
+/* Turn method name into a legal Linux file name */
+void oatReplaceSpecialChars(std::string& str)
+{
+  static const struct { const char before; const char after; } match[] =
+      {{'/','-'}, {';','#'}, {' ','#'}, {'$','+'},
+       {'(','@'}, {')','@'}, {'<','='}, {'>','='}};
+  for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
+    std::replace(str.begin(), str.end(), match[i].before, match[i].after);
+  }
+}
+
 /* Dump the CFG into a DOT graph */
 void oatDumpCFG(CompilationUnit* cUnit, const char* dirPrefix)
 {
   FILE* file;
-  std::string name(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
-  char startOffset[80];
-  sprintf(startOffset, "_%x", cUnit->entryBlock->fallThrough->startOffset);
-  char* fileName = (char*) oatNew(cUnit, strlen(dirPrefix) +
-                                  name.length() + strlen(".dot") + 1,
-                                  true, kAllocDebugInfo);
-  sprintf(fileName, "%s%s%s.dot", dirPrefix, name.c_str(), startOffset);
-
-  /*
-   * Convert the special characters into a filesystem- and shell-friendly
-   * format.
-   */
-  int i;
-  for (i = strlen(dirPrefix); fileName[i]; i++) {
-    if (fileName[i] == '/') {
-      fileName[i] = '_';
-    } else if (fileName[i] == ';') {
-      fileName[i] = '#';
-    } else if (fileName[i] == '$') {
-      fileName[i] = '+';
-    } else if (fileName[i] == '(' || fileName[i] == ')') {
-      fileName[i] = '@';
-    } else if (fileName[i] == '<' || fileName[i] == '>') {
-      fileName[i] = '=';
-    }
-  }
-  file = fopen(fileName, "w");
+  std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
+  oatReplaceSpecialChars(fname);
+  fname = StringPrintf("%s%s%x.dot", dirPrefix, fname.c_str(),
+                      cUnit->entryBlock->fallThrough->startOffset);
+  file = fopen(fname.c_str(), "w");
   if (file == NULL) {
     return;
   }
@@ -788,6 +780,7 @@
 #if defined(ART_USE_QUICK_COMPILER)
   if (cUnit->genBitcode) {
     cUnit->printMe = true;
+    cUnit->enableDebug |= (1 << kDebugDumpBitcodeFile);
   }
 #endif
   if (cUnit->instructionSet == kX86) {
diff --git a/src/compiler/Ralloc.cc b/src/compiler/Ralloc.cc
index 29766e0..0062f53 100644
--- a/src/compiler/Ralloc.cc
+++ b/src/compiler/Ralloc.cc
@@ -339,6 +339,17 @@
                                      INVALID_REG, INVALID_REG, INVALID_SREG,
                                      INVALID_SREG};
 
+int oatComputeFrameSize(CompilationUnit* cUnit) {
+  /* Figure out the frame size */
+  static const uint32_t kAlignMask = kStackAlignment - 1;
+  uint32_t size = (cUnit->numCoreSpills + cUnit->numFPSpills +
+                   1 /* filler word */ + cUnit->numRegs + cUnit->numOuts +
+                   cUnit->numCompilerTemps + 1 /* curMethod* */)
+                   * sizeof(uint32_t);
+  /* Align and set */
+  return (size + kAlignMask) & ~(kAlignMask);
+}
+
 /*
  * Simple register allocation.  Some Dalvik virtual registers may
  * be promoted to physical registers.  Most of the work for temp
@@ -459,19 +470,16 @@
 
   oatDoPromotion(cUnit);
 
+  /* Get easily-accessable post-promotion copy of RegLocation for Method* */
+  cUnit->methodLoc = cUnit->regLocation[cUnit->methodSReg];
+
   if (cUnit->printMe && !(cUnit->disableOpt & (1 << kPromoteRegs))) {
     LOG(INFO) << "After Promotion";
     oatDumpRegLocTable(cUnit->regLocation, cUnit->numSSARegs);
   }
 
-  /* Figure out the frame size */
-  static const uint32_t kAlignMask = kStackAlignment - 1;
-  uint32_t size = (cUnit->numCoreSpills + cUnit->numFPSpills +
-                   1 /* filler word */ + cUnit->numRegs + cUnit->numOuts +
-                   cUnit->numCompilerTemps + 1 /* curMethod* */)
-                   * sizeof(uint32_t);
-  /* Align and set */
-  cUnit->frameSize = (size + kAlignMask) & ~(kAlignMask);
+  /* Set the frame size */
+  cUnit->frameSize = oatComputeFrameSize(cUnit);
 }
 
 }  // namespace art
diff --git a/src/compiler/SSATransformation.cc b/src/compiler/SSATransformation.cc
index 6eb0415..7d6a733 100644
--- a/src/compiler/SSATransformation.cc
+++ b/src/compiler/SSATransformation.cc
@@ -206,7 +206,6 @@
   if (mismatch) {
     LOG(INFO) << "Mismatch for "
               << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
-    oatDumpCFG(cUnit, "/tmp/");
     LOG(INFO) << "New dfs";
     for (unsigned int i = 0; i < cUnit->dfsOrder.numUsed; i++) {
       LOG(INFO) << i << " - " << cUnit->dfsOrder.elemList[i];
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/CodegenFactory.cc
index 71b557c..9d380c7 100644
--- a/src/compiler/codegen/CodegenFactory.cc
+++ b/src/compiler/codegen/CodegenFactory.cc
@@ -292,17 +292,17 @@
 /* Utilities to load the current Method* */
 void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
 {
-  loadValueDirectFixed(cUnit, cUnit->regLocation[cUnit->methodSReg], rTgt);
+  loadValueDirectFixed(cUnit, cUnit->methodLoc, rTgt);
 }
 
 RegLocation loadCurrMethod(CompilationUnit *cUnit)
 {
-  return loadValue(cUnit, cUnit->regLocation[cUnit->methodSReg], kCoreReg);
+  return loadValue(cUnit, cUnit->methodLoc, kCoreReg);
 }
 
 bool methodStarInReg(CompilationUnit* cUnit)
 {
-   return (cUnit->regLocation[cUnit->methodSReg].location == kLocPhysReg);
+   return (cUnit->methodLoc.location == kLocPhysReg);
 }
 
 
diff --git a/src/compiler/codegen/GenInvoke.cc b/src/compiler/codegen/GenInvoke.cc
index bcc9067..7c2cf1c 100644
--- a/src/compiler/codegen/GenInvoke.cc
+++ b/src/compiler/codegen/GenInvoke.cc
@@ -33,16 +33,18 @@
  * If there are any ins passed in registers that have not been promoted
  * to a callee-save register, flush them to the frame.  Perform intial
  * assignment of promoted arguments.
+ *
+ * argLocs is an array of location records describing the incoming arguments
+ * with one location record per word of argument.
  */
-void flushIns(CompilationUnit* cUnit)
+void flushIns(CompilationUnit* cUnit, RegLocation* argLocs, RegLocation rlMethod)
 {
   /*
    * Dummy up a RegLocation for the incoming Method*
    * It will attempt to keep rARG0 live (or copy it to home location
    * if promoted).
    */
-  RegLocation rlSrc = cUnit->regLocation[cUnit->methodSReg];
-  RegLocation rlMethod = cUnit->regLocation[cUnit->methodSReg];
+  RegLocation rlSrc = rlMethod;
   rlSrc.location = kLocPhysReg;
   rlSrc.lowReg = rARG0;
   rlSrc.home = false;
@@ -75,7 +77,7 @@
     if (i < numArgRegs) {
       // If arriving in register
       bool needFlush = true;
-      RegLocation* tLoc = &cUnit->regLocation[startVReg + i];
+      RegLocation* tLoc = &argLocs[i];
       if ((vMap->coreLocation == kLocPhysReg) && !tLoc->fp) {
         opRegCopy(cUnit, vMap->coreReg, argRegs[i]);
         needFlush = false;
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/MethodBitcode.cc
index f13a473..66823c2 100644
--- a/src/compiler/codegen/MethodBitcode.cc
+++ b/src/compiler/codegen/MethodBitcode.cc
@@ -27,6 +27,7 @@
 #include <llvm/Type.h>
 #include <llvm/Instructions.h>
 #include <llvm/Support/Casting.h>
+#include <llvm/Support/InstIterator.h>
 
 const char* labelFormat = "L0x%x_%d";
 
@@ -75,6 +76,50 @@
   return res;
 }
 
+/* Create an in-memory RegLocation from an llvm Value. */
+void createLocFromValue(CompilationUnit* cUnit, llvm::Value* val)
+{
+  // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
+  std::string s(val->getName().str());
+  const char* valName = s.c_str();
+  if (cUnit->printMe) {
+    LOG(INFO) << "Processing llvm Value " << valName;
+  }
+  SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
+  DCHECK(it == cUnit->locMap.end()) << " - already defined: " << valName;
+  int baseSReg = INVALID_SREG;
+  int subscript = -1;
+  sscanf(valName, "v%d_%d", &baseSReg, &subscript);
+  if ((baseSReg == INVALID_SREG) && (!strcmp(valName, "method"))) {
+    baseSReg = SSA_METHOD_BASEREG;
+    subscript = 0;
+  }
+  if (cUnit->printMe) {
+    LOG(INFO) << "Base: " << baseSReg << ", Sub: " << subscript;
+  }
+  DCHECK_NE(baseSReg, INVALID_SREG);
+  DCHECK_NE(subscript, -1);
+  // TODO: redo during C++'ification
+  RegLocation loc =  {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
+                      INVALID_REG, INVALID_SREG, INVALID_SREG};
+  llvm::Type* ty = val->getType();
+  loc.wide = ((ty == cUnit->irb->getInt64Ty()) ||
+              (ty == cUnit->irb->getDoubleTy()));
+  loc.defined = true;
+  if ((ty == cUnit->irb->getFloatTy()) ||
+      (ty == cUnit->irb->getDoubleTy())) {
+    loc.fp = true;
+  } else if (ty == cUnit->irb->GetJObjectTy()) {
+    loc.ref = true;
+  } else {
+    loc.core = true;
+  }
+  loc.home = false;  // Will change during promotion
+  loc.sRegLow = baseSReg;
+  loc.origSReg = cUnit->locMap.size();
+  cUnit->locMap.Put(val, loc);
+}
+
 void initIR(CompilationUnit* cUnit)
 {
   cUnit->context = new llvm::LLVMContext();
@@ -1372,19 +1417,25 @@
 
   llvm::verifyFunction(*cUnit->func, llvm::PrintMessageAction);
 
-  // Write bitcode to file
-  std::string errmsg;
+  if (cUnit->enableDebug & (1 << kDebugDumpBitcodeFile)) {
+    // Write bitcode to file
+    std::string errmsg;
+    std::string fname(PrettyMethod(cUnit->method_idx, *cUnit->dex_file));
+    oatReplaceSpecialChars(fname);
+    // TODO: make configurable
+    fname = StringPrintf("/tmp/%s.bc", fname.c_str());
 
-  llvm::OwningPtr<llvm::tool_output_file> out_file(
-      new llvm::tool_output_file("/tmp/foo.bc", errmsg,
-                                 llvm::raw_fd_ostream::F_Binary));
+    llvm::OwningPtr<llvm::tool_output_file> out_file(
+        new llvm::tool_output_file(fname.c_str(), errmsg,
+                                   llvm::raw_fd_ostream::F_Binary));
 
-  if (!errmsg.empty()) {
-    LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
+    if (!errmsg.empty()) {
+      LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
+    }
+
+    llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
+    out_file->keep();
   }
-
-  llvm::WriteBitcodeToFile(cUnit->module, out_file->os());
-  out_file->keep();
 }
 
 RegLocation getLoc(CompilationUnit* cUnit, llvm::Value* val) {
@@ -1575,11 +1626,6 @@
   UNIMPLEMENTED(FATAL);
 }
 
-void setMethodInfo(CompilationUnit* cUnit, llvm::CallInst* callInst)
-{
-  UNIMPLEMENTED(WARNING) << "Net setMethodInfo";
-}
-
 void cvtCopy(CompilationUnit* cUnit, llvm::CallInst* callInst)
 {
   DCHECK(callInst->getNumArgOperands() == 1);
@@ -1670,6 +1716,14 @@
   genInvoke(cUnit, info);
 }
 
+/* Look up the RegLocation associated with a Value.  Must already be defined */
+RegLocation valToLoc(CompilationUnit* cUnit, llvm::Value* val)
+{
+  SafeMap<llvm::Value*, RegLocation>::iterator it = cUnit->locMap.find(val);
+  DCHECK(it != cUnit->locMap.end()) << "Missing definition";
+  return it->second;
+}
+
 bool methodBitcodeBlockCodeGen(CompilationUnit* cUnit, llvm::BasicBlock* bb)
 {
   bool isEntry = (bb == &cUnit->func->getEntryBlock());
@@ -1697,7 +1751,19 @@
 
   if (isEntry) {
     cUnit->currentDalvikOffset = 0;
-    genEntrySequence(cUnit);
+    RegLocation* argLocs = (RegLocation*)
+        oatNew(cUnit, sizeof(RegLocation) * cUnit->numIns, true, kAllocMisc);
+    llvm::Function::arg_iterator it(cUnit->func->arg_begin());
+    llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
+    for (unsigned i = 0; it != it_end; ++it) {
+      llvm::Value* val = it;
+      argLocs[i++] = valToLoc(cUnit, val);
+      llvm::Type* ty = val->getType();
+      if ((ty == cUnit->irb->getInt64Ty()) || (ty == cUnit->irb->getDoubleTy())) {
+        argLocs[i++].sRegLow = INVALID_SREG;
+      }
+    }
+    genEntrySequence(cUnit, argLocs, cUnit->methodLoc);
   }
 
   // Visit all of the instructions in the block
@@ -1779,7 +1845,7 @@
               cvtConst(cUnit, callInst);
               break;
             case greenland::IntrinsicHelper::MethodInfo:
-              setMethodInfo(cUnit, callInst);
+              // Already dealt with - just ignore it here.
               break;
             case greenland::IntrinsicHelper::CheckSuspend:
               genSuspendTest(cUnit, 0 /* optFlags already applied */);
@@ -1891,17 +1957,62 @@
  */
 void oatMethodBitcode2LIR(CompilationUnit* cUnit)
 {
-  int numBasicBlocks = cUnit->func->getBasicBlockList().size();
+  llvm::Function* func = cUnit->func;
+  int numBasicBlocks = func->getBasicBlockList().size();
   // Allocate a list for LIR basic block labels
   cUnit->blockLabelList =
     (void*)oatNew(cUnit, sizeof(LIR) * numBasicBlocks, true, kAllocLIR);
   LIR* labelList = (LIR*)cUnit->blockLabelList;
   int nextLabel = 0;
-  for (llvm::Function::iterator i = cUnit->func->begin(),
-       e = cUnit->func->end(); i != e; ++i) {
+  for (llvm::Function::iterator i = func->begin(),
+       e = func->end(); i != e; ++i) {
     cUnit->blockToLabelMap.Put(static_cast<llvm::BasicBlock*>(i),
                                &labelList[nextLabel++]);
   }
+
+  /*
+   * Keep honest - clear regLocations, Value => RegLocation,
+   * promotion map and VmapTables.
+   */
+  cUnit->locMap.clear();  // Start fresh
+  cUnit->regLocation = NULL;
+  for (int i = 0; i < cUnit->numDalvikRegisters + cUnit->numCompilerTemps + 1;
+       i++) {
+    cUnit->promotionMap[i].coreLocation = kLocDalvikFrame;
+    cUnit->promotionMap[i].fpLocation = kLocDalvikFrame;
+  }
+  cUnit->coreSpillMask = 0;
+  cUnit->numCoreSpills = 0;
+  cUnit->fpSpillMask = 0;
+  cUnit->numFPSpills = 0;
+  cUnit->coreVmapTable.clear();
+  cUnit->fpVmapTable.clear();
+  oatAdjustSpillMask(cUnit);
+  cUnit->frameSize = oatComputeFrameSize(cUnit);
+
+  /*
+   * At this point, we've lost all knowledge of register promotion.
+   * Rebuild that info from the MethodInfo intrinsic (if it
+   * exists - not required for correctness).
+   */
+  // TODO: find and recover MethodInfo.
+
+  // Create RegLocations for arguments
+  llvm::Function::arg_iterator it(cUnit->func->arg_begin());
+  llvm::Function::arg_iterator it_end(cUnit->func->arg_end());
+  for (; it != it_end; ++it) {
+    llvm::Value* val = it;
+    createLocFromValue(cUnit, val);
+  }
+  // Create RegLocations for all non-argument defintions
+  for (llvm::inst_iterator i = llvm::inst_begin(func),
+       e = llvm::inst_end(func); i != e; ++i) {
+    llvm::Value* val = &*i;
+    if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
+      createLocFromValue(cUnit, val);
+    }
+  }
+
   // Walk the blocks, generating code.
   for (llvm::Function::iterator i = cUnit->func->begin(),
        e = cUnit->func->end(); i != e; ++i) {
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index aab323b..7898ddb 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -904,7 +904,9 @@
   LIR* headLIR = NULL;
 
   if (bb->blockType == kEntryBlock) {
-    genEntrySequence(cUnit);
+    int startVReg = cUnit->numDalvikRegisters - cUnit->numIns;
+    genEntrySequence(cUnit, &cUnit->regLocation[startVReg],
+                     cUnit->regLocation[cUnit->methodSReg]);
   } else if (bb->blockType == kExitBlock) {
     genExitSequence(cUnit);
   }
diff --git a/src/compiler/codegen/Ralloc.h b/src/compiler/codegen/Ralloc.h
index 8c3887a..ec47e22 100644
--- a/src/compiler/codegen/Ralloc.h
+++ b/src/compiler/codegen/Ralloc.h
@@ -229,6 +229,7 @@
 extern void oatAdjustSpillMask(CompilationUnit* cUnit);
 void oatMarkPreservedSingle(CompilationUnit* cUnit, int vReg, int reg);
 void oatRegCopy(CompilationUnit* cUnit, int rDest, int rSrc);
+int oatComputeFrameSize(CompilationUnit* cUnit);
 
 }  // namespace art
 
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc
index e2f2cd6..074fd26 100644
--- a/src/compiler/codegen/RallocUtil.cc
+++ b/src/compiler/codegen/RallocUtil.cc
@@ -29,17 +29,6 @@
 
 namespace art {
 
-#define SREG(c, s) ((c)->regLocation[(s)].sRegLow)
-/*
- * Get the "real" sreg number associated with an sReg slot.  In general,
- * sReg values passed through codegen are the SSA names created by
- * dataflow analysis and refer to slot numbers in the cUnit->regLocation
- * array.  However, renaming is accomplished by simply replacing RegLocation
- * entries in the cUnit->reglocation[] array.  Therefore, when location
- * records for operands are first created, we need to ask the locRecord
- * identified by the dataflow pass what it's new name is.
- */
-
 /*
  * Free all allocated temps in the temp pools.  Note that this does
  * not affect the "liveness" of a temp register, which will stay
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index c0d91a4..ba49277 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -56,7 +56,8 @@
   return rLR;
 }
 
-void genEntrySequence(CompilationUnit* cUnit)
+void genEntrySequence(CompilationUnit* cUnit, RegLocation* argLocs,
+                      RegLocation rlMethod)
 {
   int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
   /*
@@ -101,7 +102,7 @@
     opRegImm(cUnit, kOpSub, rSP, cUnit->frameSize - (spillCount * 4));
   }
 
-  flushIns(cUnit);
+  flushIns(cUnit, argLocs, rlMethod);
 
   if (cUnit->genDebugger) {
     // Refresh update debugger callout
diff --git a/src/compiler/codegen/mips/ArchFactory.cc b/src/compiler/codegen/mips/ArchFactory.cc
index bf4c8a6..4a61efb 100644
--- a/src/compiler/codegen/mips/ArchFactory.cc
+++ b/src/compiler/codegen/mips/ArchFactory.cc
@@ -144,7 +144,8 @@
   opRegImm(cUnit, kOpAdd, rSP, cUnit->frameSize);
 }
 
-void genEntrySequence(CompilationUnit* cUnit)
+void genEntrySequence(CompilationUnit* cUnit, RegLocation* argLocs,
+                      RegLocation rlMethod)
 {
   int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
   /*
@@ -183,7 +184,7 @@
     opRegImm(cUnit, kOpSub, rSP, cUnit->frameSize - (spillCount * 4));
   }
 
-  flushIns(cUnit);
+  flushIns(cUnit, argLocs, rlMethod);
 
   if (cUnit->genDebugger) {
     // Refresh update debugger callout
diff --git a/src/compiler/codegen/x86/ArchFactory.cc b/src/compiler/codegen/x86/ArchFactory.cc
index b3cebdc..1620044 100644
--- a/src/compiler/codegen/x86/ArchFactory.cc
+++ b/src/compiler/codegen/x86/ArchFactory.cc
@@ -163,7 +163,8 @@
   newLIR2(cUnit, opcode, rDest, threadOffset);
 }
 
-void genEntrySequence(CompilationUnit* cUnit)
+void genEntrySequence(CompilationUnit* cUnit, RegLocation* argLocs,
+                      RegLocation rlMethod)
 {
   /*
    * On entry, rARG0, rARG1, rARG2 are live.  Let the register
@@ -199,7 +200,7 @@
     oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
   }
 
-  flushIns(cUnit);
+  flushIns(cUnit, argLocs, rlMethod);
 
   if (cUnit->genDebugger) {
     // Refresh update debugger callout