Ensure coherency of call kinds for LocationSummary.

The coherency is enforced with checks added in the `InvokeRuntime`
helper, that we now also use on x86 and x86_64.

Change-Id: I8cb92b042f25dc3c5fd390e9c61a45b477d081f4
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc
index fdef06b..5ffab33 100644
--- a/compiler/optimizing/code_generator_x86.cc
+++ b/compiler/optimizing/code_generator_x86.cc
@@ -45,17 +45,23 @@
 static constexpr int kFakeReturnRegister = Register(8);
 
 #define __ down_cast<X86Assembler*>(codegen->GetAssembler())->
+#define QUICK_ENTRY_POINT(x) Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, x))
 
 class NullCheckSlowPathX86 : public SlowPathCodeX86 {
  public:
   explicit NullCheckSlowPathX86(HNullCheck* instruction) : instruction_(instruction) {}
 
   void EmitNativeCode(CodeGenerator* codegen) OVERRIDE {
+    CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen);
     __ Bind(GetEntryLabel());
-    __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pThrowNullPointer)));
-    RecordPcInfo(codegen, instruction_, instruction_->GetDexPc());
+    x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowNullPointer),
+                               instruction_,
+                               instruction_->GetDexPc(),
+                               this);
   }
 
+  bool IsFatal() const OVERRIDE { return true; }
+
   const char* GetDescription() const OVERRIDE { return "NullCheckSlowPathX86"; }
 
  private:
@@ -68,11 +74,16 @@
   explicit DivZeroCheckSlowPathX86(HDivZeroCheck* instruction) : instruction_(instruction) {}
 
   void EmitNativeCode(CodeGenerator* codegen) OVERRIDE {
+    CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen);
     __ Bind(GetEntryLabel());
-    __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pThrowDivZero)));
-    RecordPcInfo(codegen, instruction_, instruction_->GetDexPc());
+    x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowDivZero),
+                               instruction_,
+                               instruction_->GetDexPc(),
+                               this);
   }
 
+  bool IsFatal() const OVERRIDE { return true; }
+
   const char* GetDescription() const OVERRIDE { return "DivZeroCheckSlowPathX86"; }
 
  private:
@@ -124,10 +135,14 @@
         length_location_,
         Location::RegisterLocation(calling_convention.GetRegisterAt(1)),
         Primitive::kPrimInt);
-    __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pThrowArrayBounds)));
-    RecordPcInfo(codegen, instruction_, instruction_->GetDexPc());
+    x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pThrowArrayBounds),
+                               instruction_,
+                               instruction_->GetDexPc(),
+                               this);
   }
 
+  bool IsFatal() const OVERRIDE { return true; }
+
   const char* GetDescription() const OVERRIDE { return "BoundsCheckSlowPathX86"; }
 
  private:
@@ -147,8 +162,10 @@
     CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen);
     __ Bind(GetEntryLabel());
     SaveLiveRegisters(codegen, instruction_->GetLocations());
-    __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pTestSuspend)));
-    RecordPcInfo(codegen, instruction_, instruction_->GetDexPc());
+    x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pTestSuspend),
+                               instruction_,
+                               instruction_->GetDexPc(),
+                               this);
     RestoreLiveRegisters(codegen, instruction_->GetLocations());
     if (successor_ == nullptr) {
       __ jmp(GetReturnLabel());
@@ -190,8 +207,10 @@
 
     InvokeRuntimeCallingConvention calling_convention;
     __ movl(calling_convention.GetRegisterAt(0), Immediate(instruction_->GetStringIndex()));
-    __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pResolveString)));
-    RecordPcInfo(codegen, instruction_, instruction_->GetDexPc());
+    x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pResolveString),
+                               instruction_,
+                               instruction_->GetDexPc(),
+                               this);
     x86_codegen->Move32(locations->Out(), Location::RegisterLocation(EAX));
     RestoreLiveRegisters(codegen, locations);
 
@@ -224,10 +243,9 @@
 
     InvokeRuntimeCallingConvention calling_convention;
     __ movl(calling_convention.GetRegisterAt(0), Immediate(cls_->GetTypeIndex()));
-    __ fs()->call(Address::Absolute(do_clinit_
-        ? QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pInitializeStaticStorage)
-        : QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pInitializeType)));
-    RecordPcInfo(codegen, at_, dex_pc_);
+    x86_codegen->InvokeRuntime(do_clinit_ ? QUICK_ENTRY_POINT(pInitializeStaticStorage)
+                                          : QUICK_ENTRY_POINT(pInitializeType),
+                               at_, dex_pc_, this);
 
     // Move the class to the desired location.
     Location out = locations->Out();
@@ -291,11 +309,16 @@
         Primitive::kPrimNot);
 
     if (instruction_->IsInstanceOf()) {
-      __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize,
-                                                              pInstanceofNonTrivial)));
+      x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pInstanceofNonTrivial),
+                                 instruction_,
+                                 instruction_->GetDexPc(),
+                                 this);
     } else {
       DCHECK(instruction_->IsCheckCast());
-      __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pCheckCast)));
+      x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pCheckCast),
+                                 instruction_,
+                                 instruction_->GetDexPc(),
+                                 this);
     }
 
     RecordPcInfo(codegen, instruction_, dex_pc_);
@@ -324,9 +347,13 @@
     : instruction_(instruction) {}
 
   void EmitNativeCode(CodeGenerator* codegen) OVERRIDE {
+    CodeGeneratorX86* x86_codegen = down_cast<CodeGeneratorX86*>(codegen);
     __ Bind(GetEntryLabel());
     SaveLiveRegisters(codegen, instruction_->GetLocations());
-    __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pDeoptimize)));
+    x86_codegen->InvokeRuntime(QUICK_ENTRY_POINT(pDeoptimize),
+                               instruction_,
+                               instruction_->GetDexPc(),
+                               this);
     // No need to restore live registers.
     DCHECK(instruction_->IsDeoptimize());
     HDeoptimize* deoptimize = instruction_->AsDeoptimize();
@@ -398,6 +425,27 @@
   return GetFloatingPointSpillSlotSize();
 }
 
+void CodeGeneratorX86::InvokeRuntime(Address entry_point,
+                                     HInstruction* instruction,
+                                     uint32_t dex_pc,
+                                     SlowPathCode* slow_path) {
+  // Ensure that the call kind indication given to the register allocator is
+  // coherent with the runtime call generated.
+  if (slow_path == nullptr) {
+    DCHECK(instruction->GetLocations()->WillCall());
+  } else {
+    DCHECK(instruction->GetLocations()->OnlyCallsOnSlowPath() || slow_path->IsFatal());
+  }
+
+  __ fs()->call(entry_point);
+  RecordPcInfo(instruction, dex_pc, slow_path);
+  DCHECK(instruction->IsSuspendCheck()
+         || instruction->IsBoundsCheck()
+         || instruction->IsNullCheck()
+         || instruction->IsDivZeroCheck()
+         || !IsLeafMethod());
+}
+
 CodeGeneratorX86::CodeGeneratorX86(HGraph* graph,
                    const X86InstructionSetFeatures& isa_features,
                    const CompilerOptions& compiler_options)
@@ -2015,14 +2063,18 @@
 
         case Primitive::kPrimFloat:
           // Processing a Dex `float-to-long' instruction.
-          __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pF2l)));
-          codegen_->RecordPcInfo(conversion, conversion->GetDexPc());
+          codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pF2l),
+                                  conversion,
+                                  conversion->GetDexPc(),
+                                  nullptr);
           break;
 
         case Primitive::kPrimDouble:
           // Processing a Dex `double-to-long' instruction.
-          __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pD2l)));
-          codegen_->RecordPcInfo(conversion, conversion->GetDexPc());
+          codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pD2l),
+                                  conversion,
+                                  conversion->GetDexPc(),
+                                  nullptr);
           break;
 
         default:
@@ -2779,9 +2831,15 @@
       DCHECK_EQ(EDX, out.AsRegisterPairHigh<Register>());
 
       if (is_div) {
-        __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pLdiv)));
+        codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLdiv),
+                                instruction,
+                                instruction->GetDexPc(),
+                                nullptr);
       } else {
-        __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pLmod)));
+        codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pLmod),
+                                instruction,
+                                instruction->GetDexPc(),
+                                nullptr);
       }
       uint32_t dex_pc = is_div
           ? instruction->AsDiv()->GetDexPc()
@@ -3233,9 +3291,11 @@
   __ movl(calling_convention.GetRegisterAt(0), Immediate(instruction->GetTypeIndex()));
   // Note: if heap poisoning is enabled, the entry point takes cares
   // of poisoning the reference.
-  __ fs()->call(Address::Absolute(GetThreadOffset<kX86WordSize>(instruction->GetEntrypoint())));
-
-  codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+  codegen_->InvokeRuntime(
+      Address::Absolute(GetThreadOffset<kX86WordSize>(instruction->GetEntrypoint())),
+      instruction,
+      instruction->GetDexPc(),
+      nullptr);
   DCHECK(!codegen_->IsLeafMethod());
 }
 
@@ -3255,9 +3315,11 @@
 
   // Note: if heap poisoning is enabled, the entry point takes cares
   // of poisoning the reference.
-  __ fs()->call(Address::Absolute(GetThreadOffset<kX86WordSize>(instruction->GetEntrypoint())));
-
-  codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+  codegen_->InvokeRuntime(
+      Address::Absolute(GetThreadOffset<kX86WordSize>(instruction->GetEntrypoint())),
+      instruction,
+      instruction->GetDexPc(),
+      nullptr);
   DCHECK(!codegen_->IsLeafMethod());
 }
 
@@ -4160,8 +4222,10 @@
         DCHECK(!codegen_->IsLeafMethod());
         // Note: if heap poisoning is enabled, pAputObject takes cares
         // of poisoning the reference.
-        __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pAputObject)));
-        codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+        codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pAputObject),
+                                instruction,
+                                instruction->GetDexPc(),
+                                nullptr);
       }
       break;
     }
@@ -4723,8 +4787,10 @@
 }
 
 void InstructionCodeGeneratorX86::VisitThrow(HThrow* instruction) {
-  __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pDeliverException)));
-  codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+  codegen_->InvokeRuntime(QUICK_ENTRY_POINT(pDeliverException),
+                          instruction,
+                          instruction->GetDexPc(),
+                          nullptr);
 }
 
 void LocationsBuilderX86::VisitInstanceOf(HInstanceOf* instruction) {
@@ -4835,10 +4901,11 @@
 }
 
 void InstructionCodeGeneratorX86::VisitMonitorOperation(HMonitorOperation* instruction) {
-  __ fs()->call(Address::Absolute(instruction->IsEnter()
-        ? QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pLockObject)
-        : QUICK_ENTRYPOINT_OFFSET(kX86WordSize, pUnlockObject)));
-  codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
+  codegen_->InvokeRuntime(instruction->IsEnter() ? QUICK_ENTRY_POINT(pLockObject)
+                                                 : QUICK_ENTRY_POINT(pUnlockObject),
+                          instruction,
+                          instruction->GetDexPc(),
+                          nullptr);
 }
 
 void LocationsBuilderX86::VisitAnd(HAnd* instruction) { HandleBitwiseOperation(instruction); }