X87: [interpreter]: Changes to interpreter builtins for accumulator and register...
authorchunyang.dai <chunyang.dai@intel.com>
Fri, 21 Aug 2015 10:14:51 +0000 (03:14 -0700)
committerCommit bot <commit-bot@chromium.org>
Fri, 21 Aug 2015 10:15:03 +0000 (10:15 +0000)
port 00df60d1c6943a10fb5ca84fce2c017dcd2001f5 (r30219).

original commit message:

    Makes the following modifications to the interpreter builtins and
    InterpreterAssembler:
     - Adds an accumulator register and initializes it to undefined()
     - Adds a register file pointer register and use it instead of FramePointer to
       access registers
     - Modifies builtin to support functions with 0 regiters in the register file
     - Modifies builtin to Call rather than TailCall to first bytecode handler.

BUG=

Review URL: https://codereview.chromium.org/1304593002

Cr-Commit-Position: refs/heads/master@{#30289}

src/x87/builtins-x87.cc
src/x87/macro-assembler-x87.h

index 7bc1813..a4f6704 100644 (file)
@@ -634,20 +634,23 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
 
   // Get the bytecode array from the function object and load the pointer to the
   // first entry into edi (InterpreterBytecodeRegister).
-  __ mov(edi, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
-  __ mov(edi, FieldOperand(edi, SharedFunctionInfo::kFunctionDataOffset));
+  __ mov(eax, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
+  __ mov(kInterpreterBytecodeArrayRegister,
+         FieldOperand(eax, SharedFunctionInfo::kFunctionDataOffset));
 
   if (FLAG_debug_code) {
     // Check function data field is actually a BytecodeArray object.
-    __ AssertNotSmi(edi);
-    __ CmpObjectType(edi, BYTECODE_ARRAY_TYPE, eax);
+    __ AssertNotSmi(kInterpreterBytecodeArrayRegister);
+    __ CmpObjectType(kInterpreterBytecodeArrayRegister, BYTECODE_ARRAY_TYPE,
+                     eax);
     __ Assert(equal, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry);
   }
 
   // Allocate the local and temporary register file on the stack.
   {
     // Load frame size from the BytecodeArray object.
-    __ mov(ebx, FieldOperand(edi, BytecodeArray::kFrameSizeOffset));
+    __ mov(ebx, FieldOperand(kInterpreterBytecodeArrayRegister,
+                             BytecodeArray::kFrameSizeOffset));
 
     // Do a stack check to ensure we don't go over the limit.
     Label ok;
@@ -656,21 +659,22 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
     ExternalReference stack_limit =
         ExternalReference::address_of_real_stack_limit(masm->isolate());
     __ cmp(ecx, Operand::StaticVariable(stack_limit));
-    __ j(above_equal, &ok, Label::kNear);
+    __ j(above_equal, &ok);
     __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION);
     __ bind(&ok);
 
     // If ok, push undefined as the initial value for all register file entries.
-    // Note: there should always be at least one stack slot for the return
-    // register in the register file.
     Label loop_header;
+    Label loop_check;
     __ mov(eax, Immediate(masm->isolate()->factory()->undefined_value()));
+    __ jmp(&loop_check);
     __ bind(&loop_header);
     // TODO(rmcilroy): Consider doing more than one push per loop iteration.
     __ push(eax);
     // Continue loop if not done.
+    __ bind(&loop_check);
     __ sub(ebx, Immediate(kPointerSize));
-    __ j(not_equal, &loop_header, Label::kNear);
+    __ j(greater_equal, &loop_header);
   }
 
   // TODO(rmcilroy): List of things not currently dealt with here but done in
@@ -700,25 +704,39 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
     ExternalReference stack_limit =
         ExternalReference::address_of_stack_limit(masm->isolate());
     __ cmp(esp, Operand::StaticVariable(stack_limit));
-    __ j(above_equal, &ok, Label::kNear);
+    __ j(above_equal, &ok);
     __ CallRuntime(Runtime::kStackGuard, 0);
     __ bind(&ok);
   }
 
-  // Load bytecode offset and dispatch table into registers.
-  __ mov(ecx, Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
+  // Load accumulator, register file, bytecode offset, dispatch table into
+  // registers.
+  __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex);
+  __ mov(kInterpreterRegisterFileRegister, ebp);
+  __ sub(
+      kInterpreterRegisterFileRegister,
+      Immediate(kPointerSize + StandardFrameConstants::kFixedFrameSizeFromFp));
+  __ mov(kInterpreterBytecodeOffsetRegister,
+         Immediate(BytecodeArray::kHeaderSize - kHeapObjectTag));
   // Since the dispatch table root might be set after builtins are generated,
   // load directly from the roots table.
-  __ LoadRoot(ebx, Heap::kInterpreterTableRootIndex);
-  __ add(ebx, Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
+  __ LoadRoot(kInterpreterDispatchTableRegister,
+              Heap::kInterpreterTableRootIndex);
+  __ add(kInterpreterDispatchTableRegister,
+         Immediate(FixedArray::kHeaderSize - kHeapObjectTag));
+
+  // TODO(rmcilroy) Push our context as a stack located parameter of the
+  // bytecode handler.
 
   // Dispatch to the first bytecode handler for the function.
-  __ movzx_b(eax, Operand(edi, ecx, times_1, 0));
-  __ mov(eax, Operand(ebx, eax, times_pointer_size, 0));
+  __ movzx_b(esi, Operand(kInterpreterBytecodeArrayRegister,
+                          kInterpreterBytecodeOffsetRegister, times_1, 0));
+  __ mov(esi, Operand(kInterpreterDispatchTableRegister, esi,
+                      times_pointer_size, 0));
   // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
   // and header removal.
-  __ add(eax, Immediate(Code::kHeaderSize - kHeapObjectTag));
-  __ jmp(eax);
+  __ add(esi, Immediate(Code::kHeaderSize - kHeapObjectTag));
+  __ call(esi);
 }
 
 
@@ -729,9 +747,8 @@ void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
   //  - Support profiler (specifically decrementing profiling_counter
   //    appropriately and calling out to HandleInterrupts if necessary).
 
-  // Load return value into r0.
-  __ mov(eax, Operand(ebp, -kPointerSize -
-                               StandardFrameConstants::kFixedFrameSizeFromFp));
+  // The return value is in accumulator, which is already in rax.
+
   // Leave the frame (also dropping the register file).
   __ leave();
   // Return droping receiver + arguments.
index 4b52564..9a2c903 100644 (file)
@@ -18,6 +18,8 @@ const Register kReturnRegister0 = {kRegister_eax_Code};
 const Register kReturnRegister1 = {kRegister_edx_Code};
 const Register kJSFunctionRegister = {kRegister_edi_Code};
 const Register kContextRegister = {kRegister_esi_Code};
+const Register kInterpreterAccumulatorRegister = {kRegister_eax_Code};
+const Register kInterpreterRegisterFileRegister = {kRegister_edx_Code};
 const Register kInterpreterBytecodeOffsetRegister = {kRegister_ecx_Code};
 const Register kInterpreterBytecodeArrayRegister = {kRegister_edi_Code};
 const Register kInterpreterDispatchTableRegister = {kRegister_ebx_Code};