Commit a4414c95 authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

X87: [Interpreter] Add ForInPrepare runtime function which returns a ObjectTriple.

  port 84f8a506 (r33334)

  original commit message:
  Adds a ForInPrepare Runtime function which returns a triple of
  cache_type, cache_array and cache_length.

  This requires adding support to CEntryStub to call runtime functions
  which return a ObjectTriple - a struct containing three Object*
  pointers. Also did some cleanup of the x64 CEntryStub to avoid
  replicated code.

  Replaces the interpreter's use of the ad-hock InterpreterForInPrepare
  Runtime function with ForInPrepare in preparation for fixing deopt in
  BytecodeGraphBuilder for ForIn (which will be done in a followup CL).

  MIPS port contributed by Balazs Kilvady <balazs.kilvady@imgtec.com>.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#33352}
parent 30bcfba3
...@@ -2015,16 +2015,22 @@ void CEntryStub::Generate(MacroAssembler* masm) { ...@@ -2015,16 +2015,22 @@ void CEntryStub::Generate(MacroAssembler* masm) {
ProfileEntryHookStub::MaybeCallEntryHook(masm); ProfileEntryHookStub::MaybeCallEntryHook(masm);
// Reserve space on the stack for the three arguments passed to the call. If
// result size is greater than can be returned in registers, also reserve
// space for the hidden argument for the result location, and space for the
// result itself.
int arg_stack_space = result_size() < 3 ? 3 : 4 + result_size();
// Enter the exit frame that transitions from JavaScript to C++. // Enter the exit frame that transitions from JavaScript to C++.
if (argv_in_register()) { if (argv_in_register()) {
DCHECK(!save_doubles()); DCHECK(!save_doubles());
__ EnterApiExitFrame(3); __ EnterApiExitFrame(arg_stack_space);
// Move argc and argv into the correct registers. // Move argc and argv into the correct registers.
__ mov(esi, ecx); __ mov(esi, ecx);
__ mov(edi, eax); __ mov(edi, eax);
} else { } else {
__ EnterExitFrame(save_doubles()); __ EnterExitFrame(arg_stack_space, save_doubles());
} }
// ebx: pointer to C function (C callee-saved) // ebx: pointer to C function (C callee-saved)
...@@ -2039,14 +2045,36 @@ void CEntryStub::Generate(MacroAssembler* masm) { ...@@ -2039,14 +2045,36 @@ void CEntryStub::Generate(MacroAssembler* masm) {
if (FLAG_debug_code) { if (FLAG_debug_code) {
__ CheckStackAlignment(); __ CheckStackAlignment();
} }
// Call C function. // Call C function.
if (result_size() <= 2) {
__ mov(Operand(esp, 0 * kPointerSize), edi); // argc. __ mov(Operand(esp, 0 * kPointerSize), edi); // argc.
__ mov(Operand(esp, 1 * kPointerSize), esi); // argv. __ mov(Operand(esp, 1 * kPointerSize), esi); // argv.
__ mov(Operand(esp, 2 * kPointerSize), __ mov(Operand(esp, 2 * kPointerSize),
Immediate(ExternalReference::isolate_address(isolate()))); Immediate(ExternalReference::isolate_address(isolate())));
} else {
DCHECK_EQ(3, result_size());
// Pass a pointer to the result location as the first argument.
__ lea(eax, Operand(esp, 4 * kPointerSize));
__ mov(Operand(esp, 0 * kPointerSize), eax);
__ mov(Operand(esp, 1 * kPointerSize), edi); // argc.
__ mov(Operand(esp, 2 * kPointerSize), esi); // argv.
__ mov(Operand(esp, 3 * kPointerSize),
Immediate(ExternalReference::isolate_address(isolate())));
}
__ call(ebx); __ call(ebx);
// Result is in eax or edx:eax - do not destroy these registers!
if (result_size() > 2) {
DCHECK_EQ(3, result_size());
#ifndef _WIN32
// Restore the "hidden" argument on the stack which was popped by caller.
__ sub(esp, Immediate(kPointerSize));
#endif
// Read result values stored on stack. Result is stored above the arguments.
__ mov(kReturnRegister0, Operand(esp, 4 * kPointerSize));
__ mov(kReturnRegister1, Operand(esp, 5 * kPointerSize));
__ mov(kReturnRegister2, Operand(esp, 6 * kPointerSize));
}
// Result is in eax, edx:eax or edi:edx:eax - do not destroy these registers!
// Check result for exception sentinel. // Check result for exception sentinel.
Label exception_returned; Label exception_returned;
......
...@@ -936,7 +936,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) { ...@@ -936,7 +936,7 @@ void MacroAssembler::EnterExitFrameEpilogue(int argc, bool save_doubles) {
} }
void MacroAssembler::EnterExitFrame(bool save_doubles) { void MacroAssembler::EnterExitFrame(int argc, bool save_doubles) {
EnterExitFramePrologue(); EnterExitFramePrologue();
// Set up argc and argv in callee-saved registers. // Set up argc and argv in callee-saved registers.
...@@ -945,7 +945,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles) { ...@@ -945,7 +945,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles) {
lea(esi, Operand(ebp, eax, times_4, offset)); lea(esi, Operand(ebp, eax, times_4, offset));
// Reserve space for argc, argv and isolate. // Reserve space for argc, argv and isolate.
EnterExitFrameEpilogue(3, save_doubles); EnterExitFrameEpilogue(argc, save_doubles);
} }
......
...@@ -16,6 +16,7 @@ namespace internal { ...@@ -16,6 +16,7 @@ namespace internal {
// Give alias names to registers for calling conventions. // Give alias names to registers for calling conventions.
const Register kReturnRegister0 = {Register::kCode_eax}; const Register kReturnRegister0 = {Register::kCode_eax};
const Register kReturnRegister1 = {Register::kCode_edx}; const Register kReturnRegister1 = {Register::kCode_edx};
const Register kReturnRegister2 = {Register::kCode_edi};
const Register kJSFunctionRegister = {Register::kCode_edi}; const Register kJSFunctionRegister = {Register::kCode_edi};
const Register kContextRegister = {Register::kCode_esi}; const Register kContextRegister = {Register::kCode_esi};
const Register kInterpreterAccumulatorRegister = {Register::kCode_eax}; const Register kInterpreterAccumulatorRegister = {Register::kCode_eax};
...@@ -225,7 +226,7 @@ class MacroAssembler: public Assembler { ...@@ -225,7 +226,7 @@ class MacroAssembler: public Assembler {
// arguments in register eax and sets up the number of arguments in // arguments in register eax and sets up the number of arguments in
// register edi and the pointer to the first argument in register // register edi and the pointer to the first argument in register
// esi. // esi.
void EnterExitFrame(bool save_doubles); void EnterExitFrame(int argc, bool save_doubles);
void EnterApiExitFrame(int argc); void EnterApiExitFrame(int argc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment