Index: src/arm64/builtins-arm64.cc |
diff --git a/src/arm64/builtins-arm64.cc b/src/arm64/builtins-arm64.cc |
index 39bc8d052d277c47196c1ca3af3d5ac7f2104e99..b99431e0de6fad6930566c113f0c9287fdec2485 100644 |
--- a/src/arm64/builtins-arm64.cc |
+++ b/src/arm64/builtins-arm64.cc |
@@ -893,6 +893,141 @@ void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) { |
} |
+// 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 |
+// count expected by the function. |
+// |
+// The live registers are: |
+// - x1: the JS function object being called. |
+// - cp: our context. |
+// - fp: our caller's frame pointer. |
+// - jssp: stack pointer. |
+// - lr: return address. |
+// |
+// The function builds a JS frame. Please see JavaScriptFrameConstants in |
+// frames-arm64.h for its layout. |
+// TODO(rmcilroy): We will need to include the current bytecode pointer in the |
+// frame. |
+void Builtins::Generate_InterpreterEntryTrampoline(MacroAssembler* masm) { |
+ // Open a frame scope to indicate that there is a frame on the stack. The |
+ // MANUAL indicates that the scope shouldn't actually generate code to set up |
+ // the frame (that is done below). |
+ FrameScope frame_scope(masm, StackFrame::MANUAL); |
+ __ Push(lr, fp, cp, x1); |
+ __ Add(fp, jssp, StandardFrameConstants::kFixedFrameSizeFromFp); |
+ |
+ // Get the bytecode array from the function object and load the pointer to the |
+ // first entry into kInterpreterBytecodeRegister. |
+ __ Ldr(x0, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
+ __ Ldr(kInterpreterBytecodeArrayRegister, |
+ FieldMemOperand(x0, SharedFunctionInfo::kFunctionDataOffset)); |
+ |
+ if (FLAG_debug_code) { |
+ // Check function data field is actually a BytecodeArray object. |
+ __ AssertNotSmi(kInterpreterBytecodeArrayRegister, |
+ kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
+ __ CompareObjectType(kInterpreterBytecodeArrayRegister, x0, x0, |
+ BYTECODE_ARRAY_TYPE); |
+ __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry); |
+ } |
+ |
+ // Allocate the local and temporary register file on the stack. |
+ { |
+ // Load frame size from the BytecodeArray object. |
+ __ Ldr(w11, FieldMemOperand(kInterpreterBytecodeArrayRegister, |
+ BytecodeArray::kFrameSizeOffset)); |
+ |
+ // Do a stack check to ensure we don't go over the limit. |
+ Label ok; |
+ DCHECK(jssp.Is(__ StackPointer())); |
+ __ Sub(x10, jssp, Operand(x11)); |
+ __ CompareRoot(x10, Heap::kRealStackLimitRootIndex); |
+ __ B(hs, &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; |
+ __ LoadRoot(x10, Heap::kUndefinedValueRootIndex); |
+ // TODO(rmcilroy): Ensure we always have an even number of registers to |
+ // allow stack to be 16 bit aligned (and remove need for jssp). |
+ __ Lsr(x11, x11, kPointerSizeLog2); |
+ __ PushMultipleTimes(x10, x11); |
+ __ Bind(&loop_header); |
+ } |
+ |
+ // TODO(rmcilroy): List of things not currently dealt with here but done in |
+ // fullcodegen's prologue: |
+ // - Support profiler (specifically profiling_counter). |
+ // - Call ProfileEntryHookStub when isolate has a function_entry_hook. |
+ // - Allow simulator stop operations if FLAG_stop_at is set. |
+ // - Deal with sloppy mode functions which need to replace the |
+ // receiver with the global proxy when called as functions (without an |
+ // explicit receiver object). |
+ // - Code aging of the BytecodeArray object. |
+ // - Supporting FLAG_trace. |
+ // |
+ // The following items are also not done here, and will probably be done using |
+ // explicit bytecodes instead: |
+ // - Allocating a new local context if applicable. |
+ // - Setting up a local binding to the this function, which is used in |
+ // derived constructors with super calls. |
+ // - Setting new.target if required. |
+ // - Dealing with REST parameters (only if |
+ // https://codereview.chromium.org/1235153006 doesn't land by then). |
+ // - Dealing with argument objects. |
+ |
+ // Perform stack guard check. |
+ { |
+ Label ok; |
+ __ CompareRoot(jssp, Heap::kStackLimitRootIndex); |
+ __ B(hs, &ok); |
+ __ CallRuntime(Runtime::kStackGuard, 0); |
+ __ Bind(&ok); |
+ } |
+ |
+ // Load bytecode offset and dispatch table into registers. |
+ __ Mov(kInterpreterBytecodeOffsetRegister, |
+ Operand(BytecodeArray::kHeaderSize - kHeapObjectTag)); |
+ __ LoadRoot(kInterpreterDispatchTableRegister, |
+ Heap::kInterpreterTableRootIndex); |
+ __ Add(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister, |
+ Operand(FixedArray::kHeaderSize - kHeapObjectTag)); |
+ |
+ // Dispatch to the first bytecode handler for the function. |
+ __ Ldrb(x0, MemOperand(kInterpreterBytecodeArrayRegister, |
+ kInterpreterBytecodeOffsetRegister)); |
+ __ Mov(x0, Operand(x0, LSL, kPointerSizeLog2)); |
+ __ Ldr(ip0, MemOperand(kInterpreterDispatchTableRegister, x0)); |
+ // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging |
+ // and header removal. |
+ __ Add(ip0, ip0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
+ __ Jump(ip0); |
+} |
+ |
+ |
+void Builtins::Generate_InterpreterExitTrampoline(MacroAssembler* masm) { |
+ // TODO(rmcilroy): List of things not currently dealt with here but done in |
+ // fullcodegen's EmitReturnSequence. |
+ // - Supporting FLAG_trace for Runtime::TraceExit. |
+ // - Support profiler (specifically decrementing profiling_counter |
+ // appropriately and calling out to HandleInterrupts if necessary). |
+ |
+ // Load return value into x0. |
+ __ ldr(x0, MemOperand(fp, -kPointerSize - |
+ StandardFrameConstants::kFixedFrameSizeFromFp)); |
+ // Leave the frame (also dropping the register file). |
+ __ LeaveFrame(StackFrame::JAVA_SCRIPT); |
+ // Drop receiver + arguments. |
+ // TODO(rmcilroy): Get number of arguments from BytecodeArray. |
+ __ Drop(1, kXRegSize); |
+ __ Ret(); |
+} |
+ |
+ |
void Builtins::Generate_CompileLazy(MacroAssembler* masm) { |
CallRuntimePassFunction(masm, Runtime::kCompileLazy); |
GenerateTailCallToReturnedCode(masm); |