diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 727dee5d00..d290342fe3 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -61,6 +61,16 @@ void FastCloneShallowObjectStub::InitializeInterfaceDescriptor( } +void CreateAllocationSiteStub::InitializeInterfaceDescriptor( + Isolate* isolate, + CodeStubInterfaceDescriptor* descriptor) { + static Register registers[] = { a2 }; + descriptor->register_param_count_ = 1; + descriptor->register_params_ = registers; + descriptor->deoptimization_handler_ = NULL; +} + + void KeyedLoadFastElementStub::InitializeInterfaceDescriptor( Isolate* isolate, CodeStubInterfaceDescriptor* descriptor) { @@ -3079,6 +3089,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { StubFailureTrampolineStub::GenerateAheadOfTime(isolate); RecordWriteStub::GenerateFixedRegStubsAheadOfTime(isolate); ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); + CreateAllocationSiteStub::GenerateAheadOfTime(isolate); } @@ -4778,20 +4789,17 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) { // A monomorphic cache hit or an already megamorphic state: invoke the // function without changing the state. __ Branch(&done, eq, a3, Operand(a1)); - __ LoadRoot(at, Heap::kUndefinedValueRootIndex); - __ Branch(&done, eq, a3, Operand(at)); - // Special handling of the Array() function, which caches not only the - // monomorphic Array function but the initial ElementsKind with special - // sentinels - __ JumpIfNotSmi(a3, &miss); - if (FLAG_debug_code) { - Handle terminal_kind_sentinel = - TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), - LAST_FAST_ELEMENTS_KIND); - __ Assert(le, "Array function sentinel is not an ElementsKind", - a3, Operand(terminal_kind_sentinel)); - } + // If we came here, we need to see if we are the array function. + // If we didn't have a matching function, and we didn't find the megamorph + // sentinel, then we have in the cell either some other function or an + // AllocationSite. Do a map check on the object in a3. + Handle allocation_site_map( + masm->isolate()->heap()->allocation_site_map(), + masm->isolate()); + __ lw(t1, FieldMemOperand(a3, 0)); + __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); + __ Branch(&miss, ne, t1, Operand(at)); // Make sure the function is the Array() function __ LoadArrayFunction(a3); @@ -4818,14 +4826,22 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) { __ LoadArrayFunction(a3); __ Branch(¬_array_function, ne, a1, Operand(a3)); - // The target function is the Array constructor, install a sentinel value in - // the constructor's type info cell that will track the initial ElementsKind - // that should be used for the array when its constructed. - Handle initial_kind_sentinel = - TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), - GetInitialFastElementsKind()); - __ li(a3, Operand(initial_kind_sentinel)); - __ sw(a3, FieldMemOperand(a2, Cell::kValueOffset)); + // The target function is the Array constructor. + // Create an AllocationSite if we don't already have it, store it in the cell. + { + FrameScope scope(masm, StackFrame::INTERNAL); + const RegList kSavedRegs = + 1 << 4 | // a0 + 1 << 5 | // a1 + 1 << 6; // a2 + + __ MultiPush(kSavedRegs); + + CreateAllocationSiteStub create_stub; + __ CallStub(&create_stub); + + __ MultiPop(kSavedRegs); + } __ Branch(&done); __ bind(¬_array_function); @@ -7349,10 +7365,6 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm) { ASSERT(FAST_DOUBLE_ELEMENTS == 4); ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); - Handle undefined_sentinel( - masm->isolate()->heap()->undefined_value(), - masm->isolate()); - // is the low bit set? If so, we are holey and that is good. Label normal_sequence; __ And(at, a3, Operand(1)); @@ -7363,17 +7375,19 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm) { __ Branch(&normal_sequence, eq, t1, Operand(zero_reg)); // We are going to create a holey array, but our kind is non-holey. - // Fix kind and retry + // Fix kind and retry (only if we have an allocation site in the cell). __ Addu(a3, a3, Operand(1)); - __ Branch(&normal_sequence, eq, a2, Operand(undefined_sentinel)); - - // The type cell may have gone megamorphic, don't overwrite if so. - __ lw(t1, FieldMemOperand(a2, kPointerSize)); - __ JumpIfNotSmi(t1, &normal_sequence); + __ LoadRoot(at, Heap::kUndefinedValueRootIndex); + __ Branch(&normal_sequence, eq, a2, Operand(at)); + __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); + __ lw(t1, FieldMemOperand(t1, 0)); + __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); + __ Branch(&normal_sequence, ne, t1, Operand(at)); // Save the resulting elements kind in type info __ SmiTag(a3); - __ sw(a3, FieldMemOperand(a2, kPointerSize)); + __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); + __ sw(a3, FieldMemOperand(t1, AllocationSite::kPayloadOffset)); __ SmiUntag(a3); __ bind(&normal_sequence); @@ -7401,7 +7415,7 @@ static void ArrayConstructorStubAheadOfTimeHelper(Isolate* isolate) { ElementsKind kind = GetFastElementsKindFromSequenceIndex(i); T stub(kind); stub.GetCode(isolate)->set_is_pregenerated(true); - if (AllocationSiteInfo::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { + if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { T stub1(kind, CONTEXT_CHECK_REQUIRED, DISABLE_ALLOCATION_SITES); stub1.GetCode(isolate)->set_is_pregenerated(true); } @@ -7442,10 +7456,6 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { // -- sp[0] : return address // -- sp[4] : last argument // ----------------------------------- - Handle undefined_sentinel( - masm->isolate()->heap()->undefined_value(), - masm->isolate()); - if (FLAG_debug_code) { // The array construct code is only set for the global and natives // builtin Array functions which always have maps. @@ -7460,10 +7470,11 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { __ Assert(eq, "Unexpected initial map for Array function", t0, Operand(MAP_TYPE)); - // We should either have undefined in a2 or a valid cell + // We should either have undefined in a2 or a valid cell. Label okay_here; Handle cell_map = masm->isolate()->factory()->cell_map(); - __ Branch(&okay_here, eq, a2, Operand(undefined_sentinel)); + __ LoadRoot(at, Heap::kUndefinedValueRootIndex); + __ Branch(&okay_here, eq, a2, Operand(at)); __ lw(a3, FieldMemOperand(a2, 0)); __ Assert(eq, "Expected property cell in register a2", a3, Operand(cell_map)); @@ -7472,9 +7483,24 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { Label no_info, switch_ready; // Get the elements kind and case on that. - __ Branch(&no_info, eq, a2, Operand(undefined_sentinel)); + __ LoadRoot(at, Heap::kUndefinedValueRootIndex); + __ Branch(&no_info, eq, a2, Operand(at)); __ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); - __ JumpIfNotSmi(a3, &no_info); + + // The type cell may have undefined in its value. + __ LoadRoot(at, Heap::kUndefinedValueRootIndex); + __ Branch(&no_info, eq, a3, Operand(at)); + + // We should have an allocation site object + if (FLAG_debug_code) { + __ push(a3); + __ sw(a3, FieldMemOperand(a3, 0)); + __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); + __ Assert(eq, "Expected AllocationSite object in register a3", + a3, Operand(at)); + } + + __ lw(a3, FieldMemOperand(a3, AllocationSite::kPayloadOffset)); __ SmiUntag(a3); __ jmp(&switch_ready); __ bind(&no_info); diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc index 896e03007b..f659285947 100644 --- a/src/mips/ic-mips.cc +++ b/src/mips/ic-mips.cc @@ -1261,8 +1261,8 @@ static void KeyedStoreGenerateGenericHelper( t0, slow); ASSERT(receiver_map.is(a3)); // Transition code expects map in a3 - AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS, - FAST_DOUBLE_ELEMENTS); + AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, + FAST_DOUBLE_ELEMENTS); ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow); __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); __ jmp(&fast_double_without_map_check); @@ -1275,7 +1275,7 @@ static void KeyedStoreGenerateGenericHelper( t0, slow); ASSERT(receiver_map.is(a3)); // Transition code expects map in a3 - mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS); + mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS); ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode, slow); __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); @@ -1291,7 +1291,7 @@ static void KeyedStoreGenerateGenericHelper( t0, slow); ASSERT(receiver_map.is(a3)); // Transition code expects map in a3 - mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); + mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, slow); __ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset)); __ jmp(&finish_object_store); @@ -1495,8 +1495,8 @@ void KeyedStoreIC::GenerateTransitionElementsSmiToDouble(MacroAssembler* masm) { // Must return the modified receiver in v0. if (!FLAG_trace_elements_transitions) { Label fail; - AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_SMI_ELEMENTS, - FAST_DOUBLE_ELEMENTS); + AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, + FAST_DOUBLE_ELEMENTS); ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, &fail); __ Ret(USE_DELAY_SLOT); __ mov(v0, a2); @@ -1518,8 +1518,8 @@ void KeyedStoreIC::GenerateTransitionElementsDoubleToObject( // Must return the modified receiver in v0. if (!FLAG_trace_elements_transitions) { Label fail; - AllocationSiteMode mode = AllocationSiteInfo::GetMode(FAST_DOUBLE_ELEMENTS, - FAST_ELEMENTS); + AllocationSiteMode mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, + FAST_ELEMENTS); ElementsTransitionGenerator::GenerateDoubleToObject(masm, mode, &fail); __ Ret(USE_DELAY_SLOT); __ mov(v0, a2); diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 5dad77ec9c..a096709cb8 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -4064,7 +4064,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) { __ li(a2, Operand(instr->hydrogen()->property_cell())); ElementsKind kind = instr->hydrogen()->elements_kind(); AllocationSiteOverrideMode override_mode = - (AllocationSiteInfo::GetMode(kind) == TRACK_ALLOCATION_SITE) + (AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE) ? DISABLE_ALLOCATION_SITES : DONT_OVERRIDE; ContextCheckMode context_mode = CONTEXT_CHECK_NOT_REQUIRED; diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index 52211904d9..945fc52cc7 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -1744,11 +1744,11 @@ Handle CallStubCompiler::CompileArrayCodeCall( GenerateLoadFunctionFromCell(cell, function, &miss); } - Handle kind(Smi::FromInt(GetInitialFastElementsKind()), isolate()); - Handle kind_feedback_cell = - isolate()->factory()->NewCell(kind); + Handle site = isolate()->factory()->NewAllocationSite(); + site->set_payload(Smi::FromInt(GetInitialFastElementsKind())); + Handle site_feedback_cell = isolate()->factory()->NewCell(site); __ li(a0, Operand(argc)); - __ li(a2, Operand(kind_feedback_cell)); + __ li(a2, Operand(site_feedback_cell)); __ li(a1, Operand(function)); ArrayConstructorStub stub(isolate());