}
// 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);
}
__ 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);
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);
}
}
&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.
// ----------- 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
__ 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,
__ 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);
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 =
// 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);
}
__ 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 {
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);
}
}
__ 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.
// ----------- 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.
__ 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);
__ 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);
}
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)
// 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 {
// 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);
}
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()));
}
}
__ 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.
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.
__ 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));
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);
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)
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());
}
// 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);
// 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);
}
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);
}
}
__ 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.
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.
__ 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));
__ 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);
}
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)