Bugfix: The general array constructor stub did not handle the case
properly when it is called with a function pointer in the type cell, instead assuming that an AllocationSite object should be present. The case where this can happen is if the cell is uninitialized, then the first constructor call made is to the Array function of a different context. In that case, we'll store the function pointer in the cell, and then go ahead and call the array constructor stub too. The bug is fixed by checking for the AllocationSite object map. If not found, the constructor stub goes forward with a default ElementsKind, just as in several other cases. A test in allocation-site-info.js was beefed up to make sure the state chain described above is traversed. BUG= R=hpayer@chromium.org, hpayer@google.com Review URL: https://codereview.chromium.org/18277006 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15555 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
2c33325114
commit
c1e19bfc35
@ -7076,13 +7076,10 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ CompareRoot(r3, Heap::kUndefinedValueRootIndex);
|
||||
__ b(eq, &no_info);
|
||||
|
||||
// We should have an allocation site object
|
||||
if (FLAG_debug_code) {
|
||||
__ push(r3);
|
||||
__ ldr(r3, FieldMemOperand(r3, 0));
|
||||
__ CompareRoot(r3, Heap::kAllocationSiteMapRootIndex);
|
||||
__ Assert(eq, "Expected AllocationSite object in register edx");
|
||||
}
|
||||
// The type cell has either an AllocationSite or a JSFunction
|
||||
__ ldr(r4, FieldMemOperand(r3, 0));
|
||||
__ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex);
|
||||
__ b(ne, &no_info);
|
||||
|
||||
__ ldr(r3, FieldMemOperand(r3, AllocationSite::kPayloadOffset));
|
||||
__ SmiUntag(r3);
|
||||
|
@ -7628,13 +7628,10 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ cmp(edx, Immediate(undefined_sentinel));
|
||||
__ j(equal, &no_info);
|
||||
|
||||
// We should have an allocation site object
|
||||
if (FLAG_debug_code) {
|
||||
__ cmp(FieldOperand(edx, 0),
|
||||
Immediate(Handle<Map>(
|
||||
masm->isolate()->heap()->allocation_site_map())));
|
||||
__ Assert(equal, "Expected AllocationSite object in register edx");
|
||||
}
|
||||
// The type cell has either an AllocationSite or a JSFunction
|
||||
__ cmp(FieldOperand(edx, 0), Immediate(Handle<Map>(
|
||||
masm->isolate()->heap()->allocation_site_map())));
|
||||
__ j(not_equal, &no_info);
|
||||
|
||||
__ mov(edx, FieldOperand(edx, AllocationSite::kPayloadOffset));
|
||||
__ SmiUntag(edx);
|
||||
|
@ -6673,12 +6673,10 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ Cmp(rdx, undefined_sentinel);
|
||||
__ j(equal, &no_info);
|
||||
|
||||
// We should have an allocation site object
|
||||
if (FLAG_debug_code) {
|
||||
__ Cmp(FieldOperand(rdx, 0),
|
||||
Handle<Map>(masm->isolate()->heap()->allocation_site_map()));
|
||||
__ Assert(equal, "Expected AllocationSite object in register rdx");
|
||||
}
|
||||
// The type cell has either an AllocationSite or a JSFunction
|
||||
__ Cmp(FieldOperand(rdx, 0),
|
||||
Handle<Map>(masm->isolate()->heap()->allocation_site_map()));
|
||||
__ j(not_equal, &no_info);
|
||||
|
||||
__ movq(rdx, FieldOperand(rdx, AllocationSite::kPayloadOffset));
|
||||
__ SmiToInteger32(rdx, rdx);
|
||||
|
@ -297,9 +297,26 @@ if (support_smi_only_arrays) {
|
||||
assertTrue(new type(1,2,3) instanceof type);
|
||||
}
|
||||
|
||||
function instanceof_check2(type) {
|
||||
assertTrue(new type() instanceof type);
|
||||
assertTrue(new type(5) instanceof type);
|
||||
assertTrue(new type(1,2,3) instanceof type);
|
||||
}
|
||||
|
||||
var realmBArray = Realm.eval(realmB, "Array");
|
||||
instanceof_check(Array);
|
||||
instanceof_check(realmBArray);
|
||||
|
||||
// instanceof_check2 is here because the call site goes through a state.
|
||||
// Since instanceof_check(Array) was first called with the current context
|
||||
// Array function, it went from (uninit->Array) then (Array->megamorphic).
|
||||
// We'll get a different state traversal if we start with realmBArray.
|
||||
// It'll go (uninit->realmBArray) then (realmBArray->megamorphic). Recognize
|
||||
// that state "Array" implies an AllocationSite is present, and code is
|
||||
// configured to use it.
|
||||
instanceof_check2(realmBArray);
|
||||
instanceof_check2(Array);
|
||||
|
||||
%OptimizeFunctionOnNextCall(instanceof_check);
|
||||
|
||||
// No de-opt will occur because HCallNewArray wasn't selected, on account of
|
||||
|
Loading…
Reference in New Issue
Block a user