MIPS: Bugfix: array constructors that expect a type feedback cell that points to an AllocationSite were being passed the undefined object in some cases. Clearly separate the cases where we have an AllocationSite and where we don't in the general ArrayConstructorStub.
Port r16693 (0852d4ab) BUG= R=gergely@homejinni.com Review URL: https://codereview.chromium.org/23451057 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16698 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
617f7546a7
commit
2cec3754da
@ -6968,7 +6968,14 @@ void ProfileEntryHookStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
|
||||
template<class T>
|
||||
static void CreateArrayDispatch(MacroAssembler* masm) {
|
||||
static void CreateArrayDispatch(MacroAssembler* masm,
|
||||
AllocationSiteOverrideMode mode) {
|
||||
if (mode == DISABLE_ALLOCATION_SITES) {
|
||||
T stub(GetInitialFastElementsKind(),
|
||||
CONTEXT_CHECK_REQUIRED,
|
||||
mode);
|
||||
__ TailCallStub(&stub);
|
||||
} else if (mode == DONT_OVERRIDE) {
|
||||
int last_index = GetSequenceIndexFromFastElementsKind(
|
||||
TERMINAL_FAST_ELEMENTS_KIND);
|
||||
for (int i = 0; i <= last_index; ++i) {
|
||||
@ -6982,15 +6989,21 @@ static void CreateArrayDispatch(MacroAssembler* masm) {
|
||||
|
||||
// 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
|
||||
Label normal_sequence;
|
||||
if (mode == DONT_OVERRIDE) {
|
||||
ASSERT(FAST_SMI_ELEMENTS == 0);
|
||||
ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
|
||||
ASSERT(FAST_ELEMENTS == 2);
|
||||
@ -6999,23 +7012,40 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
|
||||
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));
|
||||
}
|
||||
|
||||
// look at the first argument
|
||||
__ lw(t1, MemOperand(sp, 0));
|
||||
__ Branch(&normal_sequence, eq, t1, Operand(zero_reg));
|
||||
|
||||
if (mode == DISABLE_ALLOCATION_SITES) {
|
||||
ElementsKind initial = GetInitialFastElementsKind();
|
||||
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) {
|
||||
// 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));
|
||||
|
||||
if (FLAG_debug_code) {
|
||||
__ lw(t1, FieldMemOperand(t1, 0));
|
||||
__ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
|
||||
__ Branch(&normal_sequence, ne, t1, Operand(at));
|
||||
__ Assert(eq, kExpectedAllocationSiteInCell, t1, Operand(at));
|
||||
__ lw(t1, FieldMemOperand(a2, Cell::kValueOffset));
|
||||
}
|
||||
|
||||
// Save the resulting elements kind in type info
|
||||
__ SmiTag(a3);
|
||||
@ -7037,18 +7067,26 @@ static void CreateArrayDispatchOneArgument(MacroAssembler* masm) {
|
||||
|
||||
// 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);
|
||||
GenerateDispatchToArrayStub(masm, DONT_OVERRIDE);
|
||||
|
||||
__ bind(&no_info);
|
||||
__ li(a3, Operand(GetInitialFastElementsKind()));
|
||||
__ bind(&switch_ready);
|
||||
|
||||
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();
|
||||
}
|
||||
GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user