Array constructor expects AllocationSite or undefined as feedback.
Redefine Array constructor to expect an AllocationSite in the feedback register or undefined. This will make code simpler as we support pretenuring feedback for all constructed objects. R=hpayer@chromium.org Review URL: https://codereview.chromium.org/203173003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20064 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
42de2044a9
commit
5e4febb06e
@ -149,9 +149,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
|
||||
}
|
||||
|
||||
// Run the native code for the Array function called as a normal function.
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
|
||||
__ Mov(x2, Operand(megamorphic_sentinel));
|
||||
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
|
||||
ArrayConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
@ -728,9 +726,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
|
||||
__ Mov(x0, argc);
|
||||
if (is_construct) {
|
||||
// No type feedback cell is available.
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
|
||||
__ Mov(x2, Operand(megamorphic_sentinel));
|
||||
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
|
||||
|
||||
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
|
||||
__ CallStub(&stub);
|
||||
|
@ -3302,6 +3302,10 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
GenerateRecordCallTarget(masm, x0, function, cache_cell, slot, x4, x5);
|
||||
// Type information was updated. Because we may call Array, which
|
||||
// expects either undefined or an AllocationSite in ebx we need
|
||||
// to set ebx to undefined.
|
||||
__ LoadRoot(cache_cell, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3406,7 +3410,18 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
&slow);
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
Label feedback_register_initialized;
|
||||
GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5);
|
||||
|
||||
// Put the AllocationSite from the feedback vector into x2, or undefined.
|
||||
__ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2));
|
||||
__ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize));
|
||||
__ Ldr(x5, FieldMemOperand(x2, AllocationSite::kMapOffset));
|
||||
__ JumpIfRoot(x5, Heap::kAllocationSiteMapRootIndex,
|
||||
&feedback_register_initialized);
|
||||
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
|
||||
__ bind(&feedback_register_initialized);
|
||||
__ AssertUndefinedOrAllocationSite(x2, x5);
|
||||
}
|
||||
|
||||
// Jump to the function-specific construct stub.
|
||||
@ -5408,17 +5423,12 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- x0 : argc (only if argument_count_ == ANY)
|
||||
// -- x1 : constructor
|
||||
// -- x2 : feedback vector (fixed array or the megamorphic symbol)
|
||||
// -- x3 : slot index (if x2 is fixed array)
|
||||
// -- x2 : AllocationSite or undefined
|
||||
// -- sp[0] : return address
|
||||
// -- sp[4] : last argument
|
||||
// -----------------------------------
|
||||
Register constructor = x1;
|
||||
Register feedback_vector = x2;
|
||||
Register slot_index = x3;
|
||||
|
||||
ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
|
||||
masm->isolate()->heap()->megamorphic_symbol());
|
||||
Register allocation_site = x2;
|
||||
|
||||
if (FLAG_debug_code) {
|
||||
// The array construct code is only set for the global and natives
|
||||
@ -5435,37 +5445,15 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ Abort(kUnexpectedInitialMapForArrayFunction);
|
||||
__ Bind(&map_ok);
|
||||
|
||||
// In feedback_vector, we expect either the megamorphic symbol or a valid
|
||||
// fixed array.
|
||||
Label okay_here;
|
||||
Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
|
||||
__ JumpIfRoot(feedback_vector, Heap::kMegamorphicSymbolRootIndex,
|
||||
&okay_here);
|
||||
__ Ldr(x10, FieldMemOperand(feedback_vector, FixedArray::kMapOffset));
|
||||
__ Cmp(x10, Operand(fixed_array_map));
|
||||
__ Assert(eq, kExpectedFixedArrayInFeedbackVector);
|
||||
|
||||
// slot_index should be a smi if we don't have undefined in feedback_vector.
|
||||
__ AssertSmi(slot_index);
|
||||
|
||||
__ Bind(&okay_here);
|
||||
// We should either have undefined in the allocation_site register or a
|
||||
// valid AllocationSite.
|
||||
__ AssertUndefinedOrAllocationSite(allocation_site, x10);
|
||||
}
|
||||
|
||||
Register allocation_site = x2; // Overwrites feedback_vector.
|
||||
Register kind = x3;
|
||||
Label no_info;
|
||||
// Get the elements kind and case on that.
|
||||
__ JumpIfRoot(feedback_vector, Heap::kMegamorphicSymbolRootIndex, &no_info);
|
||||
__ Add(feedback_vector, feedback_vector,
|
||||
Operand::UntagSmiAndScale(slot_index, kPointerSizeLog2));
|
||||
__ Ldr(allocation_site, FieldMemOperand(feedback_vector,
|
||||
FixedArray::kHeaderSize));
|
||||
|
||||
// If the feedback vector is the megamorphic symbol, or contains anything
|
||||
// other than an AllocationSite, call an array constructor that doesn't
|
||||
// use AllocationSites.
|
||||
__ Ldr(x10, FieldMemOperand(allocation_site, AllocationSite::kMapOffset));
|
||||
__ JumpIfNotRoot(x10, Heap::kAllocationSiteMapRootIndex, &no_info);
|
||||
__ JumpIfRoot(allocation_site, Heap::kUndefinedValueRootIndex, &no_info);
|
||||
|
||||
__ Ldrsw(kind,
|
||||
UntagSmiFieldMemOperand(allocation_site,
|
||||
|
@ -441,9 +441,7 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
|
||||
|
||||
__ Mov(x0, instr->arity());
|
||||
// No cell in x2 for construct type feedback in optimized code.
|
||||
Handle<Object> megamorphic_symbol =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(isolate());
|
||||
__ Mov(x2, Operand(megamorphic_symbol));
|
||||
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
|
||||
|
||||
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
|
||||
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
||||
@ -458,7 +456,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
ASSERT(ToRegister(instr->constructor()).is(x1));
|
||||
|
||||
__ Mov(x0, Operand(instr->arity()));
|
||||
__ Mov(x2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
|
||||
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
|
||||
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
|
@ -155,9 +155,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
|
||||
|
||||
// Run the native code for the Array function called as a normal function.
|
||||
// tail call a stub
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
|
||||
__ mov(r2, Operand(megamorphic_sentinel));
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
ArrayConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
@ -737,9 +735,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
|
||||
__ mov(r0, Operand(r3));
|
||||
if (is_construct) {
|
||||
// No type feedback cell is available
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
|
||||
__ mov(r2, Operand(megamorphic_sentinel));
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
|
||||
__ CallStub(&stub);
|
||||
} else {
|
||||
|
@ -3032,6 +3032,10 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
GenerateRecordCallTarget(masm);
|
||||
// Type information was updated. Because we may call Array, which
|
||||
// expects either undefined or an AllocationSite in ebx we need
|
||||
// to set ebx to undefined.
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3134,7 +3138,18 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
__ b(ne, &slow);
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
Label feedback_register_initialized;
|
||||
GenerateRecordCallTarget(masm);
|
||||
|
||||
// Put the AllocationSite from the feedback vector into r2, or undefined.
|
||||
__ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
|
||||
__ ldr(r2, FieldMemOperand(r5, FixedArray::kHeaderSize));
|
||||
__ ldr(r5, FieldMemOperand(r2, AllocationSite::kMapOffset));
|
||||
__ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
|
||||
__ b(eq, &feedback_register_initialized);
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
__ bind(&feedback_register_initialized);
|
||||
__ AssertUndefinedOrAllocationSite(r2, r5);
|
||||
}
|
||||
|
||||
// Jump to the function-specific construct stub.
|
||||
@ -5209,15 +5224,11 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r0 : argc (only if argument_count_ == ANY)
|
||||
// -- r1 : constructor
|
||||
// -- r2 : feedback vector (fixed array or megamorphic symbol)
|
||||
// -- r3 : slot index (if r2 is fixed array)
|
||||
// -- r2 : AllocationSite or undefined
|
||||
// -- sp[0] : return address
|
||||
// -- sp[4] : last argument
|
||||
// -----------------------------------
|
||||
|
||||
ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
|
||||
masm->isolate()->heap()->megamorphic_symbol());
|
||||
|
||||
if (FLAG_debug_code) {
|
||||
// The array construct code is only set for the global and natives
|
||||
// builtin Array functions which always have maps.
|
||||
@ -5230,34 +5241,14 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ CompareObjectType(r4, r4, r5, MAP_TYPE);
|
||||
__ Assert(eq, kUnexpectedInitialMapForArrayFunction);
|
||||
|
||||
// We should either have the megamorphic symbol in ebx or a valid
|
||||
// fixed array.
|
||||
Label okay_here;
|
||||
Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
|
||||
__ CompareRoot(r2, Heap::kMegamorphicSymbolRootIndex);
|
||||
__ b(eq, &okay_here);
|
||||
__ ldr(r4, FieldMemOperand(r2, 0));
|
||||
__ cmp(r4, Operand(fixed_array_map));
|
||||
__ Assert(eq, kExpectedFixedArrayInRegisterR2);
|
||||
|
||||
// r3 should be a smi if we don't have undefined in r2
|
||||
__ AssertSmi(r3);
|
||||
|
||||
__ bind(&okay_here);
|
||||
// We should either have undefined in r2 or a valid AllocationSite
|
||||
__ AssertUndefinedOrAllocationSite(r2, r4);
|
||||
}
|
||||
|
||||
Label no_info;
|
||||
// Get the elements kind and case on that.
|
||||
__ CompareRoot(r2, Heap::kMegamorphicSymbolRootIndex);
|
||||
__ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
__ b(eq, &no_info);
|
||||
__ add(r2, r2, Operand::PointerOffsetFromSmiKey(r3));
|
||||
__ ldr(r2, FieldMemOperand(r2, FixedArray::kHeaderSize));
|
||||
|
||||
// If the feedback vector is undefined, or contains anything other than an
|
||||
// AllocationSite, call an array constructor that doesn't use AllocationSites.
|
||||
__ ldr(r4, FieldMemOperand(r2, 0));
|
||||
__ CompareRoot(r4, Heap::kAllocationSiteMapRootIndex);
|
||||
__ b(ne, &no_info);
|
||||
|
||||
__ ldr(r3, FieldMemOperand(r2, AllocationSite::kTransitionInfoOffset));
|
||||
__ SmiUntag(r3);
|
||||
|
@ -3911,9 +3911,7 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
|
||||
|
||||
__ mov(r0, Operand(instr->arity()));
|
||||
// No cell in r2 for construct type feedback in optimized code
|
||||
Handle<Object> megamorphic_symbol =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(isolate());
|
||||
__ mov(r2, Operand(megamorphic_symbol));
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
|
||||
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
||||
}
|
||||
@ -3925,7 +3923,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
ASSERT(ToRegister(instr->result()).is(r0));
|
||||
|
||||
__ mov(r0, Operand(instr->arity()));
|
||||
__ mov(r2, Operand(TypeFeedbackInfo::MegamorphicSentinel(isolate())));
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
|
||||
|
@ -473,9 +473,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
|
||||
// Invoke the code.
|
||||
if (is_construct) {
|
||||
// No type feedback cell is available
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
|
||||
__ mov(ebx, Immediate(megamorphic_sentinel));
|
||||
__ mov(ebx, masm->isolate()->factory()->undefined_value());
|
||||
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
|
||||
__ CallStub(&stub);
|
||||
} else {
|
||||
@ -1057,9 +1055,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
|
||||
|
||||
// Run the native code for the Array function called as a normal function.
|
||||
// tail call a stub
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
|
||||
__ mov(ebx, Immediate(megamorphic_sentinel));
|
||||
__ mov(ebx, masm->isolate()->factory()->undefined_value());
|
||||
ArrayConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -2374,6 +2374,10 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
GenerateRecordCallTarget(masm);
|
||||
// Type information was updated. Because we may call Array, which
|
||||
// expects either undefined or an AllocationSite in ebx we need
|
||||
// to set ebx to undefined.
|
||||
__ mov(ebx, Immediate(isolate->factory()->undefined_value()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2477,7 +2481,19 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
__ j(not_equal, &slow);
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
Label feedback_register_initialized;
|
||||
GenerateRecordCallTarget(masm);
|
||||
|
||||
// Put the AllocationSite from the feedback vector into ebx, or undefined.
|
||||
__ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
|
||||
FixedArray::kHeaderSize));
|
||||
Handle<Map> allocation_site_map =
|
||||
masm->isolate()->factory()->allocation_site_map();
|
||||
__ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map));
|
||||
__ j(equal, &feedback_register_initialized);
|
||||
__ mov(ebx, masm->isolate()->factory()->undefined_value());
|
||||
__ bind(&feedback_register_initialized);
|
||||
__ AssertUndefinedOrAllocationSite(ebx);
|
||||
}
|
||||
|
||||
// Jump to the function-specific construct stub.
|
||||
@ -5082,15 +5098,11 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
|
||||
void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- eax : argc (only if argument_count_ == ANY)
|
||||
// -- ebx : feedback vector (fixed array or megamorphic symbol)
|
||||
// -- edx : slot index (if ebx is fixed array)
|
||||
// -- ebx : AllocationSite or undefined
|
||||
// -- edi : constructor
|
||||
// -- esp[0] : return address
|
||||
// -- esp[4] : last argument
|
||||
// -----------------------------------
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(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.
|
||||
@ -5103,32 +5115,15 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ CmpObjectType(ecx, MAP_TYPE, ecx);
|
||||
__ Assert(equal, kUnexpectedInitialMapForArrayFunction);
|
||||
|
||||
// We should either have the megamorphic symbol in ebx or a valid
|
||||
// fixed array.
|
||||
Label okay_here;
|
||||
Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
|
||||
__ cmp(ebx, Immediate(megamorphic_sentinel));
|
||||
__ j(equal, &okay_here);
|
||||
__ cmp(FieldOperand(ebx, 0), Immediate(fixed_array_map));
|
||||
__ Assert(equal, kExpectedFixedArrayInRegisterEbx);
|
||||
|
||||
// edx should be a smi if we don't have the megamorphic symbol in ebx.
|
||||
__ AssertSmi(edx);
|
||||
|
||||
__ bind(&okay_here);
|
||||
// We should either have undefined in ebx or a valid AllocationSite
|
||||
__ AssertUndefinedOrAllocationSite(ebx);
|
||||
}
|
||||
|
||||
Label no_info;
|
||||
// If the feedback vector is the megamorphic sentinel, or contains anything
|
||||
// other than an AllocationSite, call an array constructor that doesn't use
|
||||
// AllocationSites.
|
||||
__ cmp(ebx, Immediate(megamorphic_sentinel));
|
||||
// If the feedback vector is the undefined value call an array constructor
|
||||
// that doesn't use AllocationSites.
|
||||
__ cmp(ebx, masm->isolate()->factory()->undefined_value());
|
||||
__ j(equal, &no_info);
|
||||
__ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size,
|
||||
FixedArray::kHeaderSize));
|
||||
__ cmp(FieldOperand(ebx, 0), Immediate(
|
||||
masm->isolate()->factory()->allocation_site_map()));
|
||||
__ j(not_equal, &no_info);
|
||||
|
||||
// Only look at the lower 16 bits of the transition info.
|
||||
__ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset));
|
||||
|
@ -4210,9 +4210,7 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
|
||||
ASSERT(ToRegister(instr->result()).is(eax));
|
||||
|
||||
// No cell in ebx for construct type feedback in optimized code
|
||||
Handle<Object> megamorphic_symbol =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(isolate());
|
||||
__ mov(ebx, Immediate(megamorphic_symbol));
|
||||
__ mov(ebx, isolate()->factory()->undefined_value());
|
||||
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
|
||||
__ Set(eax, Immediate(instr->arity()));
|
||||
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
||||
@ -4225,7 +4223,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
ASSERT(ToRegister(instr->result()).is(eax));
|
||||
|
||||
__ Set(eax, Immediate(instr->arity()));
|
||||
__ mov(ebx, TypeFeedbackInfo::MegamorphicSentinel(isolate()));
|
||||
__ mov(ebx, isolate()->factory()->undefined_value());
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
|
||||
|
@ -14897,8 +14897,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConstructor) {
|
||||
|
||||
Handle<AllocationSite> site;
|
||||
if (!type_info.is_null() &&
|
||||
!type_info.is_identical_to(
|
||||
TypeFeedbackInfo::MegamorphicSentinel(isolate))) {
|
||||
*type_info != isolate->heap()->undefined_value()) {
|
||||
site = Handle<AllocationSite>::cast(type_info);
|
||||
ASSERT(!site->SitePointsToLiteral());
|
||||
}
|
||||
|
@ -533,9 +533,7 @@ static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
|
||||
// Invoke the code.
|
||||
if (is_construct) {
|
||||
// No type feedback cell is available
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
|
||||
__ Move(rbx, megamorphic_sentinel);
|
||||
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
|
||||
// Expects rdi to hold function pointer.
|
||||
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
|
||||
__ CallStub(&stub);
|
||||
@ -1128,9 +1126,7 @@ void Builtins::Generate_ArrayCode(MacroAssembler* masm) {
|
||||
|
||||
// Run the native code for the Array function called as a normal function.
|
||||
// tail call a stub
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(masm->isolate());
|
||||
__ Move(rbx, megamorphic_sentinel);
|
||||
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
|
||||
ArrayConstructorStub stub(masm->isolate());
|
||||
__ TailCallStub(&stub);
|
||||
}
|
||||
|
@ -2211,6 +2211,10 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
GenerateRecordCallTarget(masm);
|
||||
// Type information was updated. Because we may call Array, which
|
||||
// expects either undefined or an AllocationSite in rbx we need
|
||||
// to set rbx to undefined.
|
||||
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2319,7 +2323,17 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
|
||||
__ j(not_equal, &slow);
|
||||
|
||||
if (RecordCallTarget()) {
|
||||
Label feedback_register_initialized;
|
||||
GenerateRecordCallTarget(masm);
|
||||
// Put the AllocationSite from the feedback vector into rbx, or undefined.
|
||||
__ SmiToInteger32(rdx, rdx);
|
||||
__ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size,
|
||||
FixedArray::kHeaderSize));
|
||||
__ CompareRoot(FieldOperand(rbx, 0), Heap::kAllocationSiteMapRootIndex);
|
||||
__ j(equal, &feedback_register_initialized);
|
||||
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
|
||||
__ bind(&feedback_register_initialized);
|
||||
__ AssertUndefinedOrAllocationSite(rbx);
|
||||
}
|
||||
|
||||
// Jump to the function-specific construct stub.
|
||||
@ -4924,15 +4938,11 @@ void ArrayConstructorStub::GenerateDispatchToArrayStub(
|
||||
void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- rax : argc
|
||||
// -- rbx : feedback vector (fixed array or megamorphic symbol)
|
||||
// -- rdx : slot index (if ebx is fixed array)
|
||||
// -- rbx : AllocationSite or undefined
|
||||
// -- rdi : constructor
|
||||
// -- rsp[0] : return address
|
||||
// -- rsp[8] : last argument
|
||||
// -----------------------------------
|
||||
Handle<Object> megamorphic_sentinel =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(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.
|
||||
@ -4946,34 +4956,16 @@ void ArrayConstructorStub::Generate(MacroAssembler* masm) {
|
||||
__ CmpObjectType(rcx, MAP_TYPE, rcx);
|
||||
__ Check(equal, kUnexpectedInitialMapForArrayFunction);
|
||||
|
||||
// We should either have the megamorphic symbol in rbx or a valid
|
||||
// fixed array.
|
||||
Label okay_here;
|
||||
Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map();
|
||||
__ Cmp(rbx, megamorphic_sentinel);
|
||||
__ j(equal, &okay_here);
|
||||
__ Cmp(FieldOperand(rbx, 0), fixed_array_map);
|
||||
__ Assert(equal, kExpectedFixedArrayInRegisterRbx);
|
||||
|
||||
// rdx should be a smi if we don't have the megamorphic symbol in rbx.
|
||||
__ AssertSmi(rdx);
|
||||
|
||||
__ bind(&okay_here);
|
||||
// We should either have undefined in rbx or a valid AllocationSite
|
||||
__ AssertUndefinedOrAllocationSite(rbx);
|
||||
}
|
||||
|
||||
Label no_info;
|
||||
// If the feedback slot is the megamorphic sentinel, or contains anything
|
||||
// other than an AllocationSite, call an array constructor that doesn't use
|
||||
// AllocationSites.
|
||||
__ Cmp(rbx, megamorphic_sentinel);
|
||||
__ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
|
||||
__ j(equal, &no_info);
|
||||
__ SmiToInteger32(rdx, rdx);
|
||||
__ movp(rbx, FieldOperand(rbx, rdx, times_pointer_size,
|
||||
FixedArray::kHeaderSize));
|
||||
__ Integer32ToSmi(rdx, rdx);
|
||||
__ Cmp(FieldOperand(rbx, 0),
|
||||
masm->isolate()->factory()->allocation_site_map());
|
||||
__ j(not_equal, &no_info);
|
||||
|
||||
// Only look at the lower 16 bits of the transition info.
|
||||
__ movp(rdx, FieldOperand(rbx, AllocationSite::kTransitionInfoOffset));
|
||||
|
@ -3827,9 +3827,7 @@ void LCodeGen::DoCallNew(LCallNew* instr) {
|
||||
|
||||
__ Set(rax, instr->arity());
|
||||
// No cell in ebx for construct type feedback in optimized code
|
||||
Handle<Object> megamorphic_symbol =
|
||||
TypeFeedbackInfo::MegamorphicSentinel(isolate());
|
||||
__ Move(rbx, megamorphic_symbol);
|
||||
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
|
||||
CallConstructStub stub(NO_CALL_FUNCTION_FLAGS);
|
||||
CallCode(stub.GetCode(isolate()), RelocInfo::CONSTRUCT_CALL, instr);
|
||||
}
|
||||
@ -3841,7 +3839,7 @@ void LCodeGen::DoCallNewArray(LCallNewArray* instr) {
|
||||
ASSERT(ToRegister(instr->result()).is(rax));
|
||||
|
||||
__ Set(rax, instr->arity());
|
||||
__ Move(rbx, TypeFeedbackInfo::MegamorphicSentinel(isolate()));
|
||||
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
|
||||
ElementsKind kind = instr->hydrogen()->elements_kind();
|
||||
AllocationSiteOverrideMode override_mode =
|
||||
(AllocationSite::GetMode(kind) == TRACK_ALLOCATION_SITE)
|
||||
|
Loading…
Reference in New Issue
Block a user