Save/restore local table state on down calls.

Also add unit test.

Change-Id: Ia1dc54eaac20c4bbb1ca3d9ac2933d6ab0241261
diff --git a/src/calling_convention_x86.cc b/src/calling_convention_x86.cc
index 9598647..ad7921d 100644
--- a/src/calling_convention_x86.cc
+++ b/src/calling_convention_x86.cc
@@ -18,6 +18,10 @@
   return X86ManagedRegister::FromCpuRegister(ECX);
 }
 
+ManagedRegister X86JniCallingConvention::ReturnScratchRegister() const {
+  return ManagedRegister::NoRegister();  // No free regs, so assembler uses push/pop
+}
+
 static ManagedRegister ReturnRegisterForMethod(Method* method) {
   if (method->IsReturnAFloatOrDouble()) {
     return X86ManagedRegister::FromX87Register(ST0);
@@ -68,13 +72,12 @@
 std::vector<ManagedRegister> X86JniCallingConvention::callee_save_regs_;
 
 size_t X86JniCallingConvention::FrameSize() {
-  // Return address and Method*
-  size_t frame_data_size = 2 * kPointerSize;
+  // Return address, Method* and local reference segment state
+  size_t frame_data_size = 3 * kPointerSize;
   // References plus 2 words for SIRT header
   size_t sirt_size = (ReferenceCount() + 2) * kPointerSize;
   // Plus return value spill area size
-  return RoundUp(frame_data_size + sirt_size + SizeOfReturnValue(),
-                 kStackAlignment);
+  return RoundUp(frame_data_size + sirt_size + SizeOfReturnValue(), kStackAlignment);
 }
 
 size_t X86JniCallingConvention::OutArgSize() {