| Index: src/mips64/builtins-mips64.cc
|
| diff --git a/src/mips64/builtins-mips64.cc b/src/mips64/builtins-mips64.cc
|
| index 04b854ee9e966086da9c3d92e95d55826f6ebd92..1426f15858b896dcac70c392f612b97ffeb431ca 100644
|
| --- a/src/mips64/builtins-mips64.cc
|
| +++ b/src/mips64/builtins-mips64.cc
|
| @@ -858,6 +858,144 @@ 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:
|
| +// o a1: the JS function object being called.
|
| +// o cp: our context
|
| +// o fp: the caller's frame pointer
|
| +// o sp: stack pointer
|
| +// o ra: return address
|
| +//
|
| +// The function builds a JS frame. Please see JavaScriptFrameConstants in
|
| +// frames-mips.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(ra, fp, cp, a1);
|
| + __ Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
|
| +
|
| + // Get the bytecode array from the function object and load the pointer to the
|
| + // first entry into kInterpreterBytecodeRegister.
|
| + __ ld(a0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
|
| + __ ld(kInterpreterBytecodeArrayRegister,
|
| + FieldMemOperand(a0, SharedFunctionInfo::kFunctionDataOffset));
|
| +
|
| + if (FLAG_debug_code) {
|
| + // Check function data field is actually a BytecodeArray object.
|
| + __ SmiTst(kInterpreterBytecodeArrayRegister, a4);
|
| + __ Assert(ne, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, a4,
|
| + Operand(zero_reg));
|
| + __ GetObjectType(kInterpreterBytecodeArrayRegister, a4, a4);
|
| + __ Assert(eq, kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry, a4,
|
| + Operand(BYTECODE_ARRAY_TYPE));
|
| + }
|
| +
|
| + // Allocate the local and temporary register file on the stack.
|
| + {
|
| + // Load frame size from the BytecodeArray object.
|
| + __ ld(a4, FieldMemOperand(kInterpreterBytecodeArrayRegister,
|
| + BytecodeArray::kFrameSizeOffset));
|
| +
|
| + // Do a stack check to ensure we don't go over the limit.
|
| + Label ok;
|
| + __ Dsubu(a5, sp, Operand(a4));
|
| + __ LoadRoot(a2, Heap::kRealStackLimitRootIndex);
|
| + __ Branch(&ok, hs, a5, Operand(a2));
|
| + __ 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(a5, Heap::kUndefinedValueRootIndex);
|
| + __ bind(&loop_header);
|
| + // TODO(rmcilroy): Consider doing more than one push per loop iteration.
|
| + __ push(a5);
|
| + // Continue loop if not done.
|
| + __ Dsubu(a4, a4, Operand(kPointerSize));
|
| + __ Branch(&loop_header, ge, a4, Operand(zero_reg));
|
| + }
|
| +
|
| + // 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;
|
| + __ LoadRoot(at, Heap::kStackLimitRootIndex);
|
| + __ Branch(&ok, hs, sp, Operand(at));
|
| + __ CallRuntime(Runtime::kStackGuard, 0);
|
| + __ bind(&ok);
|
| + }
|
| +
|
| + // Load bytecode offset and dispatch table into registers.
|
| + __ li(kInterpreterBytecodeOffsetRegister,
|
| + Operand(BytecodeArray::kHeaderSize - kHeapObjectTag));
|
| + __ LoadRoot(kInterpreterDispatchTableRegister,
|
| + Heap::kInterpreterTableRootIndex);
|
| + __ Daddu(kInterpreterDispatchTableRegister, kInterpreterDispatchTableRegister,
|
| + Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
| +
|
| + // Dispatch to the first bytecode handler for the function.
|
| + __ Daddu(a0, kInterpreterBytecodeArrayRegister,
|
| + kInterpreterBytecodeOffsetRegister);
|
| + __ lbu(a0, MemOperand(a0));
|
| + __ dsll(at, a0, kPointerSizeLog2);
|
| + __ Daddu(at, kInterpreterDispatchTableRegister, at);
|
| + __ ld(at, MemOperand(at));
|
| + // TODO(rmcilroy): Make dispatch table point to code entrys to avoid untagging
|
| + // and header removal.
|
| + __ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
|
| + __ Jump(at);
|
| +}
|
| +
|
| +
|
| +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 v0.
|
| + __ ld(v0, MemOperand(fp, -kPointerSize -
|
| + StandardFrameConstants::kFixedFrameSizeFromFp));
|
| + // Leave the frame (also dropping the register file).
|
| + __ LeaveFrame(StackFrame::JAVA_SCRIPT);
|
| + // Drop receiver + arguments.
|
| + __ Drop(1); // TODO(rmcilroy): Get number of arguments from BytecodeArray.
|
| + __ Jump(ra);
|
| +}
|
| +
|
| +
|
| void Builtins::Generate_CompileLazy(MacroAssembler* masm) {
|
| CallRuntimePassFunction(masm, Runtime::kCompileLazy);
|
| GenerateTailCallToReturnedCode(masm);
|
|
|