| Index: src/mips/code-stubs-mips.cc
|
| diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
|
| index 61e05f8fc8da57c3b18fd7a2a105ca3fc87b0e97..66c72f8d1ac08d80d1aa3461c13bf687b214cb16 100644
|
| --- a/src/mips/code-stubs-mips.cc
|
| +++ b/src/mips/code-stubs-mips.cc
|
| @@ -328,6 +328,29 @@ void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
|
| }
|
|
|
|
|
| +void BinaryOpICStub::InitializeInterfaceDescriptor(
|
| + Isolate* isolate,
|
| + CodeStubInterfaceDescriptor* descriptor) {
|
| + static Register registers[] = { a1, a0 };
|
| + descriptor->register_param_count_ = 2;
|
| + descriptor->register_params_ = registers;
|
| + descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
|
| + descriptor->SetMissHandler(
|
| + ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
|
| +}
|
| +
|
| +
|
| +void BinaryOpWithAllocationSiteStub::InitializeInterfaceDescriptor(
|
| + Isolate* isolate,
|
| + CodeStubInterfaceDescriptor* descriptor) {
|
| + static Register registers[] = { a2, a1, a0 };
|
| + descriptor->register_param_count_ = 3;
|
| + descriptor->register_params_ = registers;
|
| + descriptor->deoptimization_handler_ =
|
| + FUNCTION_ADDR(BinaryOpIC_MissWithAllocationSite);
|
| +}
|
| +
|
| +
|
| void NewStringAddStub::InitializeInterfaceDescriptor(
|
| Isolate* isolate,
|
| CodeStubInterfaceDescriptor* descriptor) {
|
| @@ -1286,18 +1309,6 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
|
| }
|
|
|
|
|
| -void BinaryOpICStub::InitializeInterfaceDescriptor(
|
| - Isolate* isolate,
|
| - CodeStubInterfaceDescriptor* descriptor) {
|
| - static Register registers[] = { a1, a0 };
|
| - descriptor->register_param_count_ = 2;
|
| - descriptor->register_params_ = registers;
|
| - descriptor->deoptimization_handler_ = FUNCTION_ADDR(BinaryOpIC_Miss);
|
| - descriptor->SetMissHandler(
|
| - ExternalReference(IC_Utility(IC::kBinaryOpIC_Miss), isolate));
|
| -}
|
| -
|
| -
|
| void MathPowStub::Generate(MacroAssembler* masm) {
|
| const Register base = a1;
|
| const Register exponent = a2;
|
| @@ -1414,13 +1425,13 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
| {
|
| AllowExternalCallThatCantCauseGC scope(masm);
|
| __ PrepareCallCFunction(0, 2, scratch2);
|
| - __ SetCallCDoubleArguments(double_base, double_exponent);
|
| + __ MovToFloatParameters(double_base, double_exponent);
|
| __ CallCFunction(
|
| ExternalReference::power_double_double_function(masm->isolate()),
|
| 0, 2);
|
| }
|
| __ pop(ra);
|
| - __ GetCFunctionDoubleResult(double_result);
|
| + __ MovFromFloatResult(double_result);
|
| __ jmp(&done);
|
|
|
| __ bind(&int_exponent_convert);
|
| @@ -1498,13 +1509,13 @@ void MathPowStub::Generate(MacroAssembler* masm) {
|
| {
|
| AllowExternalCallThatCantCauseGC scope(masm);
|
| __ PrepareCallCFunction(0, 2, scratch);
|
| - __ SetCallCDoubleArguments(double_base, double_exponent);
|
| + __ MovToFloatParameters(double_base, double_exponent);
|
| __ CallCFunction(
|
| ExternalReference::power_double_double_function(masm->isolate()),
|
| 0, 2);
|
| }
|
| __ pop(ra);
|
| - __ GetCFunctionDoubleResult(double_result);
|
| + __ MovFromFloatResult(double_result);
|
|
|
| __ bind(&done);
|
| __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2);
|
| @@ -1528,6 +1539,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
|
| BinaryOpICStub::GenerateAheadOfTime(isolate);
|
| StoreRegistersStateStub::GenerateAheadOfTime(isolate);
|
| RestoreRegistersStateStub::GenerateAheadOfTime(isolate);
|
| + BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
|
| }
|
|
|
|
|
| @@ -3316,32 +3328,48 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
| // a2 : cache cell for call target
|
| Label slow, non_function;
|
|
|
| + // Check that the function is really a JavaScript function.
|
| + // a1: pushed function (to be verified)
|
| + __ JumpIfSmi(a1, &non_function);
|
| +
|
| // The receiver might implicitly be the global object. This is
|
| // indicated by passing the hole as the receiver to the call
|
| // function stub.
|
| - if (ReceiverMightBeImplicit()) {
|
| - Label call;
|
| - // Get the receiver from the stack.
|
| - // function, receiver [, arguments]
|
| - __ lw(t0, MemOperand(sp, argc_ * kPointerSize));
|
| - // Call as function is indicated with the hole.
|
| - __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
|
| - __ Branch(&call, ne, t0, Operand(at));
|
| + if (ReceiverMightBeImplicit() || ReceiverIsImplicit()) {
|
| + Label try_call, call, patch_current_context;
|
| + if (ReceiverMightBeImplicit()) {
|
| + // Get the receiver from the stack.
|
| + // function, receiver [, arguments]
|
| + __ lw(t0, MemOperand(sp, argc_ * kPointerSize));
|
| + // Call as function is indicated with the hole.
|
| + __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
|
| + __ Branch(&try_call, ne, t0, Operand(at));
|
| + }
|
| // Patch the receiver on the stack with the global receiver object.
|
| - __ lw(a3,
|
| - MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
| - __ lw(a3, FieldMemOperand(a3, GlobalObject::kGlobalReceiverOffset));
|
| + // Goto slow case if we do not have a function.
|
| + __ GetObjectType(a1, a3, a3);
|
| + __ Branch(&patch_current_context, ne, a3, Operand(JS_FUNCTION_TYPE));
|
| + CallStubCompiler::FetchGlobalProxy(masm, a3, a1);
|
| __ sw(a3, MemOperand(sp, argc_ * kPointerSize));
|
| + __ Branch(&call);
|
| +
|
| + __ bind(&patch_current_context);
|
| + __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
|
| + __ sw(t0, MemOperand(sp, argc_ * kPointerSize));
|
| + __ Branch(&slow);
|
| +
|
| + __ bind(&try_call);
|
| + // Get the map of the function object.
|
| + __ GetObjectType(a1, a3, a3);
|
| + __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE));
|
| +
|
| __ bind(&call);
|
| + } else {
|
| + // Get the map of the function object.
|
| + __ GetObjectType(a1, a3, a3);
|
| + __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE));
|
| }
|
|
|
| - // Check that the function is really a JavaScript function.
|
| - // a1: pushed function (to be verified)
|
| - __ JumpIfSmi(a1, &non_function);
|
| - // Get the map of the function object.
|
| - __ GetObjectType(a1, a3, a3);
|
| - __ Branch(&slow, ne, a3, Operand(JS_FUNCTION_TYPE));
|
| -
|
| if (RecordCallTarget()) {
|
| GenerateRecordCallTarget(masm);
|
| }
|
| @@ -3384,7 +3412,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
| __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32));
|
| __ li(a2, Operand(0, RelocInfo::NONE32));
|
| __ GetBuiltinEntry(a3, Builtins::CALL_FUNCTION_PROXY);
|
| - __ SetCallKind(t1, CALL_AS_METHOD);
|
| + __ SetCallKind(t1, CALL_AS_FUNCTION);
|
| {
|
| Handle<Code> adaptor =
|
| masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
|
| @@ -4306,6 +4334,35 @@ void StringCompareStub::Generate(MacroAssembler* masm) {
|
| }
|
|
|
|
|
| +void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) {
|
| + // ----------- S t a t e -------------
|
| + // -- a1 : left
|
| + // -- a0 : right
|
| + // -- ra : return address
|
| + // -----------------------------------
|
| + Isolate* isolate = masm->isolate();
|
| +
|
| + // Load a2 with the allocation site. We stick an undefined dummy value here
|
| + // and replace it with the real allocation site later when we instantiate this
|
| + // stub in BinaryOpICWithAllocationSiteStub::GetCodeCopyFromTemplate().
|
| + __ li(a2, handle(isolate->heap()->undefined_value()));
|
| +
|
| + // Make sure that we actually patched the allocation site.
|
| + if (FLAG_debug_code) {
|
| + __ And(at, a2, Operand(kSmiTagMask));
|
| + __ Assert(ne, kExpectedAllocationSite, at, Operand(zero_reg));
|
| + __ lw(t0, FieldMemOperand(a2, HeapObject::kMapOffset));
|
| + __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
|
| + __ Assert(eq, kExpectedAllocationSite, t0, Operand(at));
|
| + }
|
| +
|
| + // Tail call into the stub that handles binary operations with allocation
|
| + // sites.
|
| + BinaryOpWithAllocationSiteStub stub(state_);
|
| + __ TailCallStub(&stub);
|
| +}
|
| +
|
| +
|
| void StringAddStub::Generate(MacroAssembler* masm) {
|
| Label call_runtime, call_builtin;
|
| Builtins::JavaScript builtin_id = Builtins::ADD;
|
| @@ -5675,20 +5732,15 @@ template<class T>
|
| static void CreateArrayDispatch(MacroAssembler* masm,
|
| AllocationSiteOverrideMode mode) {
|
| if (mode == DISABLE_ALLOCATION_SITES) {
|
| - T stub(GetInitialFastElementsKind(),
|
| - CONTEXT_CHECK_REQUIRED,
|
| - mode);
|
| + T stub(GetInitialFastElementsKind(), mode);
|
| __ TailCallStub(&stub);
|
| } else if (mode == DONT_OVERRIDE) {
|
| int last_index = GetSequenceIndexFromFastElementsKind(
|
| TERMINAL_FAST_ELEMENTS_KIND);
|
| for (int i = 0; i <= last_index; ++i) {
|
| - Label next;
|
| ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
|
| - __ Branch(&next, ne, a3, Operand(kind));
|
| T stub(kind);
|
| - __ TailCallStub(&stub);
|
| - __ bind(&next);
|
| + __ TailCallStub(&stub, eq, a3, Operand(kind));
|
| }
|
|
|
| // If we reached this point there is a problem.
|
| @@ -5729,13 +5781,11 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
|
| ElementsKind holey_initial = GetHoleyElementsKind(initial);
|
|
|
| ArraySingleArgumentConstructorStub stub_holey(holey_initial,
|
| - CONTEXT_CHECK_REQUIRED,
|
| DISABLE_ALLOCATION_SITES);
|
| __ TailCallStub(&stub_holey);
|
|
|
| __ bind(&normal_sequence);
|
| ArraySingleArgumentConstructorStub stub(initial,
|
| - CONTEXT_CHECK_REQUIRED,
|
| DISABLE_ALLOCATION_SITES);
|
| __ TailCallStub(&stub);
|
| } else if (mode == DONT_OVERRIDE) {
|
| @@ -5764,12 +5814,9 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
|
| int last_index = GetSequenceIndexFromFastElementsKind(
|
| TERMINAL_FAST_ELEMENTS_KIND);
|
| for (int i = 0; i <= last_index; ++i) {
|
| - Label next;
|
| ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
|
| - __ Branch(&next, ne, a3, Operand(kind));
|
| ArraySingleArgumentConstructorStub stub(kind);
|
| - __ TailCallStub(&stub);
|
| - __ bind(&next);
|
| + __ TailCallStub(&stub, eq, a3, Operand(kind));
|
| }
|
|
|
| // If we reached this point there is a problem.
|
| @@ -5782,19 +5829,14 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm,
|
|
|
| template<class T>
|
| static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) {
|
| - ElementsKind initial_kind = GetInitialFastElementsKind();
|
| - ElementsKind initial_holey_kind = GetHoleyElementsKind(initial_kind);
|
| -
|
| int to_index = GetSequenceIndexFromFastElementsKind(
|
| TERMINAL_FAST_ELEMENTS_KIND);
|
| for (int i = 0; i <= to_index; ++i) {
|
| ElementsKind kind = GetFastElementsKindFromSequenceIndex(i);
|
| T stub(kind);
|
| stub.GetCode(isolate);
|
| - if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE ||
|
| - (!FLAG_track_allocation_sites &&
|
| - (kind == initial_kind || kind == initial_holey_kind))) {
|
| - T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES);
|
| + if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) {
|
| + T stub1(kind, DISABLE_ALLOCATION_SITES);
|
| stub1.GetCode(isolate);
|
| }
|
| }
|
| @@ -5911,34 +5953,25 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
|
|
| void InternalArrayConstructorStub::GenerateCase(
|
| MacroAssembler* masm, ElementsKind kind) {
|
| - Label not_zero_case, not_one_case;
|
| - Label normal_sequence;
|
|
|
| - __ Branch(¬_zero_case, ne, a0, Operand(zero_reg));
|
| InternalArrayNoArgumentConstructorStub stub0(kind);
|
| - __ TailCallStub(&stub0);
|
| + __ TailCallStub(&stub0, lo, a0, Operand(1));
|
|
|
| - __ bind(¬_zero_case);
|
| - __ Branch(¬_one_case, gt, a0, Operand(1));
|
| + InternalArrayNArgumentsConstructorStub stubN(kind);
|
| + __ TailCallStub(&stubN, hi, a0, Operand(1));
|
|
|
| if (IsFastPackedElementsKind(kind)) {
|
| // We might need to create a holey array
|
| // look at the first argument.
|
| __ lw(at, MemOperand(sp, 0));
|
| - __ Branch(&normal_sequence, eq, at, Operand(zero_reg));
|
|
|
| InternalArraySingleArgumentConstructorStub
|
| stub1_holey(GetHoleyElementsKind(kind));
|
| - __ TailCallStub(&stub1_holey);
|
| + __ TailCallStub(&stub1_holey, ne, at, Operand(zero_reg));
|
| }
|
|
|
| - __ bind(&normal_sequence);
|
| InternalArraySingleArgumentConstructorStub stub1(kind);
|
| __ TailCallStub(&stub1);
|
| -
|
| - __ bind(¬_one_case);
|
| - InternalArrayNArgumentsConstructorStub stubN(kind);
|
| - __ TailCallStub(&stubN);
|
| }
|
|
|
|
|
|
|