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) {
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++.
if (argv_in_register()) {
DCHECK(!save_doubles());
__ EnterApiExitFrame(3);
__ EnterApiExitFrame(arg_stack_space);
// Move argc and argv into the correct registers.
__ mov(esi, ecx);
__ mov(edi, eax);
} else {
__ EnterExitFrame(save_doubles());
__ EnterExitFrame(arg_stack_space, save_doubles());
}
// ebx: pointer to C function (C callee-saved)
......@@ -2039,14 +2045,36 @@ void CEntryStub::Generate(MacroAssembler* masm) {
if (FLAG_debug_code) {
__ CheckStackAlignment();
}
// Call C function.
__ mov(Operand(esp, 0 * kPointerSize), edi); // argc.
__ mov(Operand(esp, 1 * kPointerSize), esi); // argv.
__ mov(Operand(esp, 2 * kPointerSize),
Immediate(ExternalReference::isolate_address(isolate())));
if (result_size() <= 2) {
__ mov(Operand(esp, 0 * kPointerSize), edi); // argc.
__ mov(Operand(esp, 1 * kPointerSize), esi); // argv.
__ mov(Operand(esp, 2 * kPointerSize),
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);
// 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.
Label exception_returned;
......
......@@ -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();
// Set up argc and argv in callee-saved registers.
......@@ -945,7 +945,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles) {
lea(esi, Operand(ebp, eax, times_4, offset));
// Reserve space for argc, argv and isolate.
EnterExitFrameEpilogue(3, save_doubles);
EnterExitFrameEpilogue(argc, save_doubles);
}
......
......@@ -16,6 +16,7 @@ namespace internal {
// Give alias names to registers for calling conventions.
const Register kReturnRegister0 = {Register::kCode_eax};
const Register kReturnRegister1 = {Register::kCode_edx};
const Register kReturnRegister2 = {Register::kCode_edi};
const Register kJSFunctionRegister = {Register::kCode_edi};
const Register kContextRegister = {Register::kCode_esi};
const Register kInterpreterAccumulatorRegister = {Register::kCode_eax};
......@@ -225,7 +226,7 @@ class MacroAssembler: public Assembler {
// arguments in register eax and sets up the number of arguments in
// register edi and the pointer to the first argument in register
// esi.
void EnterExitFrame(bool save_doubles);
void EnterExitFrame(int argc, bool save_doubles);
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