| Index: src/arm64/builtins-arm64.cc
 | 
| diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc
 | 
| index 81f01188bd2e8e3ac194a67224450c4234f1c28d..dc293729ae4ce5ced4c262246444118acaefd761 100644
 | 
| --- a/src/arm64/builtins-arm64.cc
 | 
| +++ b/src/arm64/builtins-arm64.cc
 | 
| @@ -963,7 +963,6 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
 | 
|    Generate_JSEntryTrampolineHelper(masm, true);
 | 
|  }
 | 
|  
 | 
| -
 | 
|  // Generate code for entering a JS function with the interpreter.
 | 
|  // On entry to the function the receiver and arguments have been pushed on the
 | 
|  // stack left to right.  The actual argument count matches the formal parameter
 | 
| @@ -1062,9 +1061,20 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
 | 
|    __ Mov(x1, Operand(x1, LSL, kPointerSizeLog2));
 | 
|    __ Ldr(ip0, MemOperand(kInterpreterDispatchTableRegister, x1));
 | 
|    __ Call(ip0);
 | 
| +  masm->isolate()->heap()->SetInterpreterEntryReturnPCOffset(masm->pc_offset());
 | 
| +
 | 
| +  // The return value is in x0.
 | 
| +
 | 
| +  // Get the arguments + reciever count.
 | 
| +  __ ldr(x1, MemOperand(fp, InterpreterFrameConstants::kBytecodeArrayFromFp));
 | 
| +  __ Ldr(w1, FieldMemOperand(x1, BytecodeArray::kParameterSizeOffset));
 | 
| +
 | 
| +  // Leave the frame (also dropping the register file).
 | 
| +  __ LeaveFrame(StackFrame::JAVA_SCRIPT);
 | 
|  
 | 
| -  // Even though the first bytecode handler was called, we will never return.
 | 
| -  __ Abort(kUnexpectedReturnFromBytecodeHandler);
 | 
| +  // Drop receiver + arguments and return.
 | 
| +  __ Drop(x1, 1);
 | 
| +  __ Ret();
 | 
|  
 | 
|    // Load debug copy of the bytecode array.
 | 
|    __ Bind(&load_debug_bytecode_array);
 | 
| @@ -1085,22 +1095,87 @@ void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) {
 | 
|    __ Jump(x7);
 | 
|  }
 | 
|  
 | 
| +// static
 | 
| +void Builtins::Generate_InterpreterPushArgsAndCallImpl(
 | 
| +    MacroAssembler* masm, TailCallMode tail_call_mode) {
 | 
| +  // ----------- S t a t e -------------
 | 
| +  //  -- x0 : the number of arguments (not including the receiver)
 | 
| +  //  -- x2 : the address of the first argument to be pushed. Subsequent
 | 
| +  //          arguments should be consecutive above this, in the same order as
 | 
| +  //          they are to be pushed onto the stack.
 | 
| +  //  -- x1 : the target to call (can be any Object).
 | 
| +  // -----------------------------------
 | 
|  
 | 
| -void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) {
 | 
| -  // The return value is in accumulator, which is already in x0.
 | 
| +  // Find the address of the last argument.
 | 
| +  __ add(x3, x0, Operand(1));  // Add one for receiver.
 | 
| +  __ lsl(x3, x3, kPointerSizeLog2);
 | 
| +  __ sub(x4, x2, x3);
 | 
|  
 | 
| -  // Leave the frame (also dropping the register file).
 | 
| -  __ LeaveFrame(StackFrame::JAVA_SCRIPT);
 | 
| +  // Push the arguments.
 | 
| +  Label loop_header, loop_check;
 | 
| +  __ Mov(x5, jssp);
 | 
| +  __ Claim(x3, 1);
 | 
| +  __ B(&loop_check);
 | 
| +  __ Bind(&loop_header);
 | 
| +  // TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned.
 | 
| +  __ Ldr(x3, MemOperand(x2, -kPointerSize, PostIndex));
 | 
| +  __ Str(x3, MemOperand(x5, -kPointerSize, PreIndex));
 | 
| +  __ Bind(&loop_check);
 | 
| +  __ Cmp(x2, x4);
 | 
| +  __ B(gt, &loop_header);
 | 
|  
 | 
| -  // Drop receiver + arguments and return.
 | 
| -  __ Ldr(w1, FieldMemOperand(kInterpreterBytecodeArrayRegister,
 | 
| -                             BytecodeArray::kParameterSizeOffset));
 | 
| -  __ Drop(x1, 1);
 | 
| -  __ Ret();
 | 
| +  // Call the target.
 | 
| +  __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
 | 
| +                                            tail_call_mode),
 | 
| +          RelocInfo::CODE_TARGET);
 | 
|  }
 | 
|  
 | 
| +// static
 | 
| +void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
 | 
| +  // ----------- S t a t e -------------
 | 
| +  // -- x0 : argument count (not including receiver)
 | 
| +  // -- x3 : new target
 | 
| +  // -- x1 : constructor to call
 | 
| +  // -- x2 : address of the first argument
 | 
| +  // -----------------------------------
 | 
| +
 | 
| +  // Find the address of the last argument.
 | 
| +  __ add(x5, x0, Operand(1));  // Add one for receiver (to be constructed).
 | 
| +  __ lsl(x5, x5, kPointerSizeLog2);
 | 
| +
 | 
| +  // Set stack pointer and where to stop.
 | 
| +  __ Mov(x6, jssp);
 | 
| +  __ Claim(x5, 1);
 | 
| +  __ sub(x4, x6, x5);
 | 
| +
 | 
| +  // Push a slot for the receiver.
 | 
| +  __ Str(xzr, MemOperand(x6, -kPointerSize, PreIndex));
 | 
| +
 | 
| +  Label loop_header, loop_check;
 | 
| +  // Push the arguments.
 | 
| +  __ B(&loop_check);
 | 
| +  __ Bind(&loop_header);
 | 
| +  // TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned.
 | 
| +  __ Ldr(x5, MemOperand(x2, -kPointerSize, PostIndex));
 | 
| +  __ Str(x5, MemOperand(x6, -kPointerSize, PreIndex));
 | 
| +  __ Bind(&loop_check);
 | 
| +  __ Cmp(x6, x4);
 | 
| +  __ B(gt, &loop_header);
 | 
| +
 | 
| +  // Call the constructor with x0, x1, and x3 unmodified.
 | 
| +  __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
 | 
| +}
 | 
| +
 | 
| +void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
 | 
| +  // Set the return address to the correct point in the interpreter entry
 | 
| +  // trampoline.
 | 
| +  Smi* interpreter_entry_return_pc_offset(
 | 
| +      masm->isolate()->heap()->interpreter_entry_return_pc_offset());
 | 
| +  DCHECK_NE(interpreter_entry_return_pc_offset, Smi::FromInt(0));
 | 
| +  __ LoadObject(x1, masm->isolate()->builtins()->InterpreterEntryTrampoline());
 | 
| +  __ Add(lr, x1, Operand(interpreter_entry_return_pc_offset->value() +
 | 
| +                         Code::kHeaderSize - kHeapObjectTag));
 | 
|  
 | 
| -static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
 | 
|    // Initialize the dispatch table register.
 | 
|    __ Mov(kInterpreterDispatchTableRegister,
 | 
|           Operand(ExternalReference::interpreter_dispatch_table_address(
 | 
| @@ -1132,55 +1207,6 @@ static void Generate_EnterBytecodeDispatch(MacroAssembler* masm) {
 | 
|    __ Jump(ip0);
 | 
|  }
 | 
|  
 | 
| -
 | 
| -static void Generate_InterpreterNotifyDeoptimizedHelper(
 | 
| -    MacroAssembler* masm, Deoptimizer::BailoutType type) {
 | 
| -  // Enter an internal frame.
 | 
| -  {
 | 
| -    FrameScope scope(masm, StackFrame::INTERNAL);
 | 
| -
 | 
| -    // Pass the deoptimization type to the runtime system.
 | 
| -    __ Mov(x1, Operand(Smi::FromInt(static_cast<int>(type))));
 | 
| -    __ Push(x1);
 | 
| -    __ CallRuntime(Runtime::kNotifyDeoptimized);
 | 
| -    // Tear down internal frame.
 | 
| -  }
 | 
| -
 | 
| -  // Drop state (we don't use these for interpreter deopts) and and pop the
 | 
| -  // accumulator value into the accumulator register.
 | 
| -  __ Drop(1);
 | 
| -  __ Pop(kInterpreterAccumulatorRegister);
 | 
| -
 | 
| -  // Enter the bytecode dispatch.
 | 
| -  Generate_EnterBytecodeDispatch(masm);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void Builtins::Generate_InterpreterNotifyDeoptimized(MacroAssembler* masm) {
 | 
| -  Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::EAGER);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void Builtins::Generate_InterpreterNotifySoftDeoptimized(MacroAssembler* masm) {
 | 
| -  Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::SOFT);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -void Builtins::Generate_InterpreterNotifyLazyDeoptimized(MacroAssembler* masm) {
 | 
| -  Generate_InterpreterNotifyDeoptimizedHelper(masm, Deoptimizer::LAZY);
 | 
| -}
 | 
| -
 | 
| -void Builtins::Generate_InterpreterEnterBytecodeDispatch(MacroAssembler* masm) {
 | 
| -  // Set the address of the interpreter entry trampoline as a return address.
 | 
| -  // This simulates the initial call to bytecode handlers in interpreter entry
 | 
| -  // trampoline. The return will never actually be taken, but our stack walker
 | 
| -  // uses this address to determine whether a frame is interpreted.
 | 
| -  __ LoadObject(lr, masm->isolate()->builtins()->InterpreterEntryTrampoline());
 | 
| -
 | 
| -  Generate_EnterBytecodeDispatch(masm);
 | 
| -}
 | 
| -
 | 
| -
 | 
|  void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
 | 
|    // ----------- S t a t e -------------
 | 
|    //  -- x0 : argument count (preserved for callee)
 | 
| @@ -1469,15 +1495,19 @@ static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
 | 
|  
 | 
|    // Switch on the state.
 | 
|    Label with_tos_register, unknown_state;
 | 
| -  __ CompareAndBranch(
 | 
| -      state, FullCodeGenerator::NO_REGISTERS, ne, &with_tos_register);
 | 
| +  __ CompareAndBranch(state,
 | 
| +                      static_cast<int>(Deoptimizer::BailoutState::NO_REGISTERS),
 | 
| +                      ne, &with_tos_register);
 | 
|    __ Drop(1);  // Remove state.
 | 
|    __ Ret();
 | 
|  
 | 
|    __ Bind(&with_tos_register);
 | 
|    // Reload TOS register.
 | 
| +  DCHECK_EQ(kInterpreterAccumulatorRegister.code(), x0.code());
 | 
|    __ Peek(x0, kPointerSize);
 | 
| -  __ CompareAndBranch(state, FullCodeGenerator::TOS_REG, ne, &unknown_state);
 | 
| +  __ CompareAndBranch(state,
 | 
| +                      static_cast<int>(Deoptimizer::BailoutState::TOS_REGISTER),
 | 
| +                      ne, &unknown_state);
 | 
|    __ Drop(2);  // Remove state and TOS.
 | 
|    __ Ret();
 | 
|  
 | 
| @@ -2678,79 +2708,6 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
 | 
|            RelocInfo::CODE_TARGET);
 | 
|  }
 | 
|  
 | 
| -
 | 
| -// static
 | 
| -void Builtins::Generate_InterpreterPushArgsAndCallImpl(
 | 
| -    MacroAssembler* masm, TailCallMode tail_call_mode) {
 | 
| -  // ----------- S t a t e -------------
 | 
| -  //  -- x0 : the number of arguments (not including the receiver)
 | 
| -  //  -- x2 : the address of the first argument to be pushed. Subsequent
 | 
| -  //          arguments should be consecutive above this, in the same order as
 | 
| -  //          they are to be pushed onto the stack.
 | 
| -  //  -- x1 : the target to call (can be any Object).
 | 
| -  // -----------------------------------
 | 
| -
 | 
| -  // Find the address of the last argument.
 | 
| -  __ add(x3, x0, Operand(1));  // Add one for receiver.
 | 
| -  __ lsl(x3, x3, kPointerSizeLog2);
 | 
| -  __ sub(x4, x2, x3);
 | 
| -
 | 
| -  // Push the arguments.
 | 
| -  Label loop_header, loop_check;
 | 
| -  __ Mov(x5, jssp);
 | 
| -  __ Claim(x3, 1);
 | 
| -  __ B(&loop_check);
 | 
| -  __ Bind(&loop_header);
 | 
| -  // TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned.
 | 
| -  __ Ldr(x3, MemOperand(x2, -kPointerSize, PostIndex));
 | 
| -  __ Str(x3, MemOperand(x5, -kPointerSize, PreIndex));
 | 
| -  __ Bind(&loop_check);
 | 
| -  __ Cmp(x2, x4);
 | 
| -  __ B(gt, &loop_header);
 | 
| -
 | 
| -  // Call the target.
 | 
| -  __ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
 | 
| -                                            tail_call_mode),
 | 
| -          RelocInfo::CODE_TARGET);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// static
 | 
| -void Builtins::Generate_InterpreterPushArgsAndConstruct(MacroAssembler* masm) {
 | 
| -  // ----------- S t a t e -------------
 | 
| -  // -- x0 : argument count (not including receiver)
 | 
| -  // -- x3 : new target
 | 
| -  // -- x1 : constructor to call
 | 
| -  // -- x2 : address of the first argument
 | 
| -  // -----------------------------------
 | 
| -
 | 
| -  // Find the address of the last argument.
 | 
| -  __ add(x5, x0, Operand(1));  // Add one for receiver (to be constructed).
 | 
| -  __ lsl(x5, x5, kPointerSizeLog2);
 | 
| -
 | 
| -  // Set stack pointer and where to stop.
 | 
| -  __ Mov(x6, jssp);
 | 
| -  __ Claim(x5, 1);
 | 
| -  __ sub(x4, x6, x5);
 | 
| -
 | 
| -  // Push a slot for the receiver.
 | 
| -  __ Str(xzr, MemOperand(x6, -kPointerSize, PreIndex));
 | 
| -
 | 
| -  Label loop_header, loop_check;
 | 
| -  // Push the arguments.
 | 
| -  __ B(&loop_check);
 | 
| -  __ Bind(&loop_header);
 | 
| -  // TODO(rmcilroy): Push two at a time once we ensure we keep stack aligned.
 | 
| -  __ Ldr(x5, MemOperand(x2, -kPointerSize, PostIndex));
 | 
| -  __ Str(x5, MemOperand(x6, -kPointerSize, PreIndex));
 | 
| -  __ Bind(&loop_check);
 | 
| -  __ Cmp(x6, x4);
 | 
| -  __ B(gt, &loop_header);
 | 
| -
 | 
| -  // Call the constructor with x0, x1, and x3 unmodified.
 | 
| -  __ Jump(masm->isolate()->builtins()->Construct(), RelocInfo::CODE_TARGET);
 | 
| -}
 | 
| -
 | 
|  // static
 | 
|  void Builtins::Generate_AllocateInNewSpace(MacroAssembler* masm) {
 | 
|    ASM_LOCATION("Builtins::Generate_AllocateInNewSpace");
 | 
| 
 |