diff options
Diffstat (limited to 'deps/v8/src/mips/builtins-mips.cc')
-rw-r--r-- | deps/v8/src/mips/builtins-mips.cc | 229 |
1 files changed, 170 insertions, 59 deletions
diff --git a/deps/v8/src/mips/builtins-mips.cc b/deps/v8/src/mips/builtins-mips.cc index 42a0bbe58b..9bdc1e1bd8 100644 --- a/deps/v8/src/mips/builtins-mips.cc +++ b/deps/v8/src/mips/builtins-mips.cc @@ -941,7 +941,9 @@ static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { // Push function as parameter to the runtime call. __ Push(a1, a1); // Whether to compile in a background thread. - __ Push(masm->isolate()->factory()->ToBoolean(concurrent)); + __ LoadRoot( + at, concurrent ? Heap::kTrueValueRootIndex : Heap::kFalseValueRootIndex); + __ push(at); __ CallRuntime(Runtime::kCompileOptimized, 2); // Restore receiver. @@ -1349,49 +1351,100 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { } -void Builtins::Generate_FunctionApply(MacroAssembler* masm) { - const int kIndexOffset = - StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); - const int kLimitOffset = - StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); - const int kArgsOffset = 2 * kPointerSize; - const int kRecvOffset = 3 * kPointerSize; - const int kFunctionOffset = 4 * kPointerSize; +static void Generate_CheckStackOverflow(MacroAssembler* masm, + const int calleeOffset) { + // Check the stack for overflow. We are not trying to catch + // interruptions (e.g. debug break and preemption) here, so the "real stack + // limit" is checked. + Label okay; + __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); + // Make a2 the space we have left. The stack might already be overflowed + // here which will cause a2 to become negative. + __ Subu(a2, sp, a2); + // Check if the arguments will overflow the stack. + __ sll(t3, v0, kPointerSizeLog2 - kSmiTagSize); + // Signed comparison. + __ Branch(&okay, gt, a2, Operand(t3)); + + // Out of stack space. + __ lw(a1, MemOperand(fp, calleeOffset)); + __ Push(a1, v0); + __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); + + __ bind(&okay); +} + + +static void Generate_PushAppliedArguments(MacroAssembler* masm, + const int argumentsOffset, + const int indexOffset, + const int limitOffset) { + Label entry, loop; + __ lw(a0, MemOperand(fp, indexOffset)); + __ Branch(&entry); + + // Load the current argument from the arguments array and push it to the + // stack. + // a0: current argument index + __ bind(&loop); + __ lw(a1, MemOperand(fp, argumentsOffset)); + __ Push(a1, a0); + + // Call the runtime to access the property in the arguments array. + __ CallRuntime(Runtime::kGetProperty, 2); + __ push(v0); + + // Use inline caching to access the arguments. + __ lw(a0, MemOperand(fp, indexOffset)); + __ Addu(a0, a0, Operand(1 << kSmiTagSize)); + __ sw(a0, MemOperand(fp, indexOffset)); + + // Test if the copy loop has finished copying all the elements from the + // arguments object. + __ bind(&entry); + __ lw(a1, MemOperand(fp, limitOffset)); + __ Branch(&loop, ne, a0, Operand(a1)); + + // On exit, the pushed arguments count is in a0, untagged + __ SmiUntag(a0); +} + + +// Used by FunctionApply and ReflectApply +static void Generate_ApplyHelper(MacroAssembler* masm, bool targetIsArgument) { + const int kFormalParameters = targetIsArgument ? 3 : 2; + const int kStackSize = kFormalParameters + 1; { FrameScope frame_scope(masm, StackFrame::INTERNAL); + const int kArgumentsOffset = kFPOnStackSize + kPCOnStackSize; + const int kReceiverOffset = kArgumentsOffset + kPointerSize; + const int kFunctionOffset = kReceiverOffset + kPointerSize; + __ lw(a0, MemOperand(fp, kFunctionOffset)); // Get the function. __ push(a0); - __ lw(a0, MemOperand(fp, kArgsOffset)); // Get the args array. + __ lw(a0, MemOperand(fp, kArgumentsOffset)); // Get the args array. __ push(a0); // Returns (in v0) number of arguments to copy to stack as Smi. - __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); - - // Check the stack for overflow. We are not trying to catch - // interruptions (e.g. debug break and preemption) here, so the "real stack - // limit" is checked. - Label okay; - __ LoadRoot(a2, Heap::kRealStackLimitRootIndex); - // Make a2 the space we have left. The stack might already be overflowed - // here which will cause a2 to become negative. - __ subu(a2, sp, a2); - // Check if the arguments will overflow the stack. - __ sll(t3, v0, kPointerSizeLog2 - kSmiTagSize); - __ Branch(&okay, gt, a2, Operand(t3)); // Signed comparison. - - // Out of stack space. - __ lw(a1, MemOperand(fp, kFunctionOffset)); - __ Push(a1, v0); - __ InvokeBuiltin(Builtins::STACK_OVERFLOW, CALL_FUNCTION); - // End of stack check. + if (targetIsArgument) { + __ InvokeBuiltin(Builtins::REFLECT_APPLY_PREPARE, CALL_FUNCTION); + } else { + __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); + } + + // Returns the result in v0. + Generate_CheckStackOverflow(masm, kFunctionOffset); // Push current limit and index. - __ bind(&okay); + const int kIndexOffset = + StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); + const int kLimitOffset = + StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); __ mov(a1, zero_reg); __ Push(v0, a1); // Limit and initial index. // Get the receiver. - __ lw(a0, MemOperand(fp, kRecvOffset)); + __ lw(a0, MemOperand(fp, kReceiverOffset)); // Check that the function is a JS function (otherwise it must be a proxy). Label push_receiver; @@ -1447,36 +1500,12 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { __ push(a0); // Copy all arguments from the array to the stack. - Label entry, loop; - __ lw(a0, MemOperand(fp, kIndexOffset)); - __ Branch(&entry); - - // Load the current argument from the arguments array and push it to the - // stack. - // a0: current argument index - __ bind(&loop); - __ lw(a1, MemOperand(fp, kArgsOffset)); - __ Push(a1, a0); - - // Call the runtime to access the property in the arguments array. - __ CallRuntime(Runtime::kGetProperty, 2); - __ push(v0); - - // Use inline caching to access the arguments. - __ lw(a0, MemOperand(fp, kIndexOffset)); - __ Addu(a0, a0, Operand(1 << kSmiTagSize)); - __ sw(a0, MemOperand(fp, kIndexOffset)); - - // Test if the copy loop has finished copying all the elements from the - // arguments object. - __ bind(&entry); - __ lw(a1, MemOperand(fp, kLimitOffset)); - __ Branch(&loop, ne, a0, Operand(a1)); + Generate_PushAppliedArguments( + masm, kArgumentsOffset, kIndexOffset, kLimitOffset); // Call the function. Label call_proxy; ParameterCount actual(a0); - __ sra(a0, a0, kSmiTagSize); __ lw(a1, MemOperand(fp, kFunctionOffset)); __ GetObjectType(a1, a2, a2); __ Branch(&call_proxy, ne, a2, Operand(JS_FUNCTION_TYPE)); @@ -1485,7 +1514,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { frame_scope.GenerateLeaveFrame(); __ Ret(USE_DELAY_SLOT); - __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. + __ Addu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot. // Call the function proxy. __ bind(&call_proxy); @@ -1499,7 +1528,89 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { } __ Ret(USE_DELAY_SLOT); - __ Addu(sp, sp, Operand(3 * kPointerSize)); // In delay slot. + __ Addu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot. +} + + +static void Generate_ConstructHelper(MacroAssembler* masm) { + const int kFormalParameters = 3; + const int kStackSize = kFormalParameters + 1; + + { + FrameScope frame_scope(masm, StackFrame::INTERNAL); + const int kNewTargetOffset = kFPOnStackSize + kPCOnStackSize; + const int kArgumentsOffset = kNewTargetOffset + kPointerSize; + const int kFunctionOffset = kArgumentsOffset + kPointerSize; + + // If newTarget is not supplied, set it to constructor + Label validate_arguments; + __ lw(a0, MemOperand(fp, kNewTargetOffset)); + __ LoadRoot(at, Heap::kUndefinedValueRootIndex); + __ Branch(&validate_arguments, ne, a0, Operand(at)); + __ lw(a0, MemOperand(fp, kFunctionOffset)); + __ sw(a0, MemOperand(fp, kNewTargetOffset)); + + // Validate arguments + __ bind(&validate_arguments); + __ lw(a0, MemOperand(fp, kFunctionOffset)); // get the function + __ push(a0); + __ lw(a0, MemOperand(fp, kArgumentsOffset)); // get the args array + __ push(a0); + __ lw(a0, MemOperand(fp, kNewTargetOffset)); // get the new.target + __ push(a0); + // Returns argument count in v0. + __ InvokeBuiltin(Builtins::REFLECT_CONSTRUCT_PREPARE, CALL_FUNCTION); + + // Returns result in v0. + Generate_CheckStackOverflow(masm, kFunctionOffset); + + // Push current limit and index. + const int kIndexOffset = + StandardFrameConstants::kExpressionsOffset - (2 * kPointerSize); + const int kLimitOffset = + StandardFrameConstants::kExpressionsOffset - (1 * kPointerSize); + __ push(v0); // limit + __ mov(a1, zero_reg); // initial index + __ push(a1); + // Push newTarget and callee functions + __ lw(a0, MemOperand(fp, kNewTargetOffset)); + __ push(a0); + __ lw(a0, MemOperand(fp, kFunctionOffset)); + __ push(a0); + + // Copy all arguments from the array to the stack. + Generate_PushAppliedArguments( + masm, kArgumentsOffset, kIndexOffset, kLimitOffset); + + // Use undefined feedback vector + __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); + __ lw(a1, MemOperand(fp, kFunctionOffset)); + + // Call the function. + CallConstructStub stub(masm->isolate(), SUPER_CONSTRUCTOR_CALL); + __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); + + __ Drop(1); + + // Leave internal frame. + } + __ jr(ra); + __ Addu(sp, sp, Operand(kStackSize * kPointerSize)); // In delay slot. +} + + +void Builtins::Generate_FunctionApply(MacroAssembler* masm) { + Generate_ApplyHelper(masm, false); +} + + +void Builtins::Generate_ReflectApply(MacroAssembler* masm) { + Generate_ApplyHelper(masm, true); +} + + +void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { + Generate_ConstructHelper(masm); } |