Index: src/mips/code-stubs-mips.cc |
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc |
index 68b0c5fa679c63f14429725434568e354739510b..0589bf01624997e680c44c851a5f68ec48e1efe0 100644 |
--- a/src/mips/code-stubs-mips.cc |
+++ b/src/mips/code-stubs-mips.cc |
@@ -6968,87 +6968,125 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) { |
template<class T> |
-static void CreateArrayDispatch(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)); |
- T stub(kind); |
+static void CreateArrayDispatch(MacroAssembler* masm, |
+ AllocationSiteOverrideMode mode) { |
+ if (mode == DISABLE_ALLOCATION_SITES) { |
+ T stub(GetInitialFastElementsKind(), |
+ CONTEXT_CHECK_REQUIRED, |
+ mode); |
__ TailCallStub(&stub); |
- __ bind(&next); |
- } |
+ } 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); |
+ } |
- // If we reached this point there is a problem. |
- __ Abort(kUnexpectedElementsKindInArrayConstructor); |
+ // If we reached this point there is a problem. |
+ __ Abort(kUnexpectedElementsKindInArrayConstructor); |
+ } else { |
+ UNREACHABLE(); |
+ } |
} |
-static void CreateArrayDispatchOneArgument(MacroAssembler* masm) { |
- // a2 - type info cell |
- // a3 - kind |
+static void CreateArrayDispatchOneArgument(MacroAssembler* masm, |
+ AllocationSiteOverrideMode mode) { |
+ // a2 - type info cell (if mode != DISABLE_ALLOCATION_SITES) |
+ // a3 - kind (if mode != DISABLE_ALLOCATION_SITES) |
// a0 - number of arguments |
// a1 - constructor? |
// sp[0] - last argument |
- ASSERT(FAST_SMI_ELEMENTS == 0); |
- ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
- ASSERT(FAST_ELEMENTS == 2); |
- ASSERT(FAST_HOLEY_ELEMENTS == 3); |
- ASSERT(FAST_DOUBLE_ELEMENTS == 4); |
- ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); |
- |
- // is the low bit set? If so, we are holey and that is good. |
Label normal_sequence; |
- __ And(at, a3, Operand(1)); |
- __ Branch(&normal_sequence, ne, at, Operand(zero_reg)); |
+ if (mode == DONT_OVERRIDE) { |
+ ASSERT(FAST_SMI_ELEMENTS == 0); |
+ ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); |
+ ASSERT(FAST_ELEMENTS == 2); |
+ ASSERT(FAST_HOLEY_ELEMENTS == 3); |
+ ASSERT(FAST_DOUBLE_ELEMENTS == 4); |
+ ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == 5); |
+ |
+ // is the low bit set? If so, we are holey and that is good. |
+ __ And(at, a3, Operand(1)); |
+ __ Branch(&normal_sequence, ne, at, Operand(zero_reg)); |
+ } |
// look at the first argument |
__ lw(t1, MemOperand(sp, 0)); |
__ 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 (only if we have an allocation site in the cell). |
- __ Addu(a3, a3, Operand(1)); |
- __ 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)); |
+ if (mode == DISABLE_ALLOCATION_SITES) { |
+ ElementsKind initial = GetInitialFastElementsKind(); |
+ ElementsKind holey_initial = GetHoleyElementsKind(initial); |
- // Save the resulting elements kind in type info |
- __ SmiTag(a3); |
- __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); |
- __ sw(a3, FieldMemOperand(t1, AllocationSite::kTransitionInfoOffset)); |
- __ SmiUntag(a3); |
+ ArraySingleArgumentConstructorStub stub_holey(holey_initial, |
+ CONTEXT_CHECK_REQUIRED, |
+ DISABLE_ALLOCATION_SITES); |
+ __ TailCallStub(&stub_holey); |
- __ bind(&normal_sequence); |
- 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); |
+ __ bind(&normal_sequence); |
+ ArraySingleArgumentConstructorStub stub(initial, |
+ CONTEXT_CHECK_REQUIRED, |
+ DISABLE_ALLOCATION_SITES); |
__ TailCallStub(&stub); |
- __ bind(&next); |
- } |
+ } else if (mode == DONT_OVERRIDE) { |
+ // We are going to create a holey array, but our kind is non-holey. |
+ // Fix kind and retry (only if we have an allocation site in the cell). |
+ __ Addu(a3, a3, Operand(1)); |
+ __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); |
+ |
+ if (FLAG_debug_code) { |
+ __ lw(t1, FieldMemOperand(t1, 0)); |
+ __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
+ __ Assert(eq, kExpectedAllocationSiteInCell, t1, Operand(at)); |
+ __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); |
+ } |
- // If we reached this point there is a problem. |
- __ Abort(kUnexpectedElementsKindInArrayConstructor); |
+ // Save the resulting elements kind in type info |
+ __ SmiTag(a3); |
+ __ lw(t1, FieldMemOperand(a2, Cell::kValueOffset)); |
+ __ sw(a3, FieldMemOperand(t1, AllocationSite::kTransitionInfoOffset)); |
+ __ SmiUntag(a3); |
+ |
+ __ bind(&normal_sequence); |
+ 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); |
+ } |
+ |
+ // If we reached this point there is a problem. |
+ __ Abort(kUnexpectedElementsKindInArrayConstructor); |
+ } else { |
+ UNREACHABLE(); |
+ } |
} |
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)->set_is_pregenerated(true); |
- if (AllocationSite::GetMode(kind) != DONT_TRACK_ALLOCATION_SITE) { |
+ 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); |
stub1.GetCode(isolate)->set_is_pregenerated(true); |
} |
@@ -7081,6 +7119,33 @@ void InternalArrayConstructorStubBase::GenerateStubsAheadOfTime( |
} |
+void ArrayConstructorStub::GenerateDispatchToArrayStub( |
+ MacroAssembler* masm, |
+ AllocationSiteOverrideMode mode) { |
+ if (argument_count_ == ANY) { |
+ Label not_zero_case, not_one_case; |
+ __ And(at, a0, a0); |
+ __ Branch(¬_zero_case, ne, at, Operand(zero_reg)); |
+ CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); |
+ |
+ __ bind(¬_zero_case); |
+ __ Branch(¬_one_case, gt, a0, Operand(1)); |
+ CreateArrayDispatchOneArgument(masm, mode); |
+ |
+ __ bind(¬_one_case); |
+ CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
+ } else if (argument_count_ == NONE) { |
+ CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm, mode); |
+ } else if (argument_count_ == ONE) { |
+ CreateArrayDispatchOneArgument(masm, mode); |
+ } else if (argument_count_ == MORE_THAN_ONE) { |
+ CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
+ } else { |
+ UNREACHABLE(); |
+ } |
+} |
+ |
+ |
void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
// ----------- S t a t e ------------- |
// -- a0 : argc (only if argument_count_ == ANY) |
@@ -7114,49 +7179,24 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
__ bind(&okay_here); |
} |
- Label no_info, switch_ready; |
+ Label no_info; |
// Get the elements kind and case on that. |
__ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
__ Branch(&no_info, eq, a2, Operand(at)); |
__ lw(a3, FieldMemOperand(a2, Cell::kValueOffset)); |
- // The type cell may have undefined in its value. |
- __ LoadRoot(at, Heap::kUndefinedValueRootIndex); |
- __ Branch(&no_info, eq, a3, Operand(at)); |
- |
- // The type cell has either an AllocationSite or a JSFunction. |
+ // If the type cell is undefined, or contains anything other than an |
+ // AllocationSite, call an array constructor that doesn't use AllocationSites. |
__ lw(t0, FieldMemOperand(a3, 0)); |
__ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
__ Branch(&no_info, ne, t0, Operand(at)); |
__ lw(a3, FieldMemOperand(a3, AllocationSite::kTransitionInfoOffset)); |
__ SmiUntag(a3); |
- __ jmp(&switch_ready); |
- __ bind(&no_info); |
- __ li(a3, Operand(GetInitialFastElementsKind())); |
- __ bind(&switch_ready); |
+ GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
- if (argument_count_ == ANY) { |
- Label not_zero_case, not_one_case; |
- __ And(at, a0, a0); |
- __ Branch(¬_zero_case, ne, at, Operand(zero_reg)); |
- CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm); |
- |
- __ bind(¬_zero_case); |
- __ Branch(¬_one_case, gt, a0, Operand(1)); |
- CreateArrayDispatchOneArgument(masm); |
- |
- __ bind(¬_one_case); |
- CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm); |
- } else if (argument_count_ == NONE) { |
- CreateArrayDispatch<ArrayNoArgumentConstructorStub>(masm); |
- } else if (argument_count_ == ONE) { |
- CreateArrayDispatchOneArgument(masm); |
- } else if (argument_count_ == MORE_THAN_ONE) { |
- CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm); |
- } else { |
- UNREACHABLE(); |
- } |
+ __ bind(&no_info); |
+ GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
} |