// x1 : the function to call
// x2 : feedback vector
// x3 : slot in feedback vector (smi)
- Label check_array, initialize_array, initialize_non_array, megamorphic, done;
+ Label initialize, done, miss, megamorphic, not_array_function;
ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
masm->isolate()->heap()->undefined_value());
- Heap::RootListIndex kMegamorphicRootIndex = Heap::kUndefinedValueRootIndex;
ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()),
masm->isolate()->heap()->the_hole_value());
- Heap::RootListIndex kUninitializedRootIndex = Heap::kTheHoleValueRootIndex;
- ASSERT_EQ(*TypeFeedbackInfo::PremonomorphicSentinel(masm->isolate()),
- masm->isolate()->heap()->null_value());
- Heap::RootListIndex kPremonomorphicRootIndex = Heap::kNullValueRootIndex;
// Load the cache state.
__ Add(x4, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2));
// function without changing the state.
__ Cmp(x4, x1);
__ B(eq, &done);
- __ JumpIfRoot(x4, kMegamorphicRootIndex, &done);
- // Check if we're dealing with the Array function or not.
- __ LoadArrayFunction(x5);
- __ Cmp(x1, x5);
- __ B(eq, &check_array);
-
- // Non-array cache: Check the cache state.
- __ JumpIfRoot(x4, kPremonomorphicRootIndex, &initialize_non_array);
- __ JumpIfNotRoot(x4, kUninitializedRootIndex, &megamorphic);
+ // If we came here, we need to see if we are the array function.
+ // If we didn't have a matching function, and we didn't find the megamorph
+ // sentinel, then we have in the slot either some other function or an
+ // AllocationSite. Do a map check on the object in ecx.
+ __ Ldr(x5, FieldMemOperand(x4, AllocationSite::kMapOffset));
+ __ JumpIfNotRoot(x5, Heap::kAllocationSiteMapRootIndex, &miss);
- // Non-array cache: Uninitialized -> premonomorphic. The sentinel is an
- // immortal immovable object (null) so no write-barrier is needed.
- __ Add(x4, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2));
- __ LoadRoot(x10, kPremonomorphicRootIndex);
- __ Str(x10, FieldMemOperand(x4, FixedArray::kHeaderSize));
+ // Make sure the function is the Array() function
+ __ LoadArrayFunction(x4);
+ __ Cmp(x1, x4);
+ __ B(ne, &megamorphic);
__ B(&done);
- // Array cache: Check the cache state to see if we're in a monomorphic
- // state where the state object is an AllocationSite object.
- __ Bind(&check_array);
- __ Ldr(x5, FieldMemOperand(x4, AllocationSite::kMapOffset));
- __ JumpIfRoot(x5, Heap::kAllocationSiteMapRootIndex, &done);
-
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
- __ JumpIfRoot(x4, kUninitializedRootIndex, &initialize_array);
- __ JumpIfRoot(x4, kPremonomorphicRootIndex, &initialize_array);
+ __ Bind(&miss);
- // Both caches: Monomorphic -> megamorphic. The sentinel is an
- // immortal immovable object (undefined) so no write-barrier is needed.
+ // A monomorphic miss (i.e, here the cache is not uninitialized) goes
+ // megamorphic.
+ __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &initialize);
+ // MegamorphicSentinel is an immortal immovable object (undefined) so no
+ // write-barrier is needed.
__ Bind(&megamorphic);
__ Add(x4, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2));
- __ LoadRoot(x10, kMegamorphicRootIndex);
+ __ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
__ Str(x10, FieldMemOperand(x4, FixedArray::kHeaderSize));
__ B(&done);
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
- __ Bind(&initialize_array);
+ // An uninitialized cache is patched with the function or sentinel to
+ // indicate the ElementsKind if function is the Array constructor.
+ __ Bind(&initialize);
+ // Make sure the function is the Array() function
+ __ LoadArrayFunction(x4);
+ __ Cmp(x1, x4);
+ __ B(ne, ¬_array_function);
+
+ // The target function is the Array constructor,
+ // Create an AllocationSite if we don't already have it, store it in the slot.
{
FrameScope scope(masm, StackFrame::INTERNAL);
CreateAllocationSiteStub create_stub;
}
__ B(&done);
- // Non-array cache: Premonomorphic -> monomorphic.
- __ Bind(&initialize_non_array);
+ __ Bind(¬_array_function);
+ // An uninitialized cache is patched with the function.
+
__ Add(x4, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2));
// TODO(all): Does the value need to be left in x4? If not, FieldMemOperand
// could be used to avoid this add.
__ Pop(x1, x2, x4);
// TODO(all): Are x4, x2 and x1 outputs? This isn't clear.
+
__ Bind(&done);
}
// r1 : the function to call
// r2 : Feedback vector
// r3 : slot in feedback vector (Smi)
- Label check_array, initialize_array, initialize_non_array, megamorphic, done;
+ Label initialize, done, miss, megamorphic, not_array_function;
ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
masm->isolate()->heap()->undefined_value());
- Heap::RootListIndex kMegamorphicRootIndex = Heap::kUndefinedValueRootIndex;
ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()),
masm->isolate()->heap()->the_hole_value());
- Heap::RootListIndex kUninitializedRootIndex = Heap::kTheHoleValueRootIndex;
- ASSERT_EQ(*TypeFeedbackInfo::PremonomorphicSentinel(masm->isolate()),
- masm->isolate()->heap()->null_value());
- Heap::RootListIndex kPremonomorphicRootIndex = Heap::kNullValueRootIndex;
// Load the cache state into r4.
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
// function without changing the state.
__ cmp(r4, r1);
__ b(eq, &done);
- __ CompareRoot(r4, kMegamorphicRootIndex);
- __ b(eq, &done);
- // Check if we're dealing with the Array function or not.
- __ LoadArrayFunction(r5);
- __ cmp(r1, r5);
- __ b(eq, &check_array);
+ // If we came here, we need to see if we are the array function.
+ // If we didn't have a matching function, and we didn't find the megamorph
+ // sentinel, then we have in the slot either some other function or an
+ // AllocationSite. Do a map check on the object in ecx.
+ __ ldr(r5, FieldMemOperand(r4, 0));
+ __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
+ __ b(ne, &miss);
- // Non-array cache: Check the cache state.
- __ CompareRoot(r4, kPremonomorphicRootIndex);
- __ b(eq, &initialize_non_array);
- __ CompareRoot(r4, kUninitializedRootIndex);
+ // Make sure the function is the Array() function
+ __ LoadArrayFunction(r4);
+ __ cmp(r1, r4);
__ b(ne, &megamorphic);
-
- // Non-array cache: Uninitialized -> premonomorphic. The sentinel is an
- // immortal immovable object (null) so no write-barrier is needed.
- __ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
- __ LoadRoot(ip, kPremonomorphicRootIndex);
- __ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
__ jmp(&done);
- // Array cache: Check the cache state to see if we're in a monomorphic
- // state where the state object is an AllocationSite object.
- __ bind(&check_array);
- __ ldr(r5, FieldMemOperand(r4, 0));
- __ CompareRoot(r5, Heap::kAllocationSiteMapRootIndex);
- __ b(eq, &done);
-
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
- __ CompareRoot(r4, kUninitializedRootIndex);
- __ b(eq, &initialize_array);
- __ CompareRoot(r4, kPremonomorphicRootIndex);
- __ b(eq, &initialize_array);
+ __ bind(&miss);
- // Both caches: Monomorphic -> megamorphic. The sentinel is an
- // immortal immovable object (undefined) so no write-barrier is needed.
+ // A monomorphic miss (i.e, here the cache is not uninitialized) goes
+ // megamorphic.
+ __ CompareRoot(r4, Heap::kTheHoleValueRootIndex);
+ __ b(eq, &initialize);
+ // MegamorphicSentinel is an immortal immovable object (undefined) so no
+ // write-barrier is needed.
__ bind(&megamorphic);
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
- __ LoadRoot(ip, kMegamorphicRootIndex);
+ __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
__ str(ip, FieldMemOperand(r4, FixedArray::kHeaderSize));
__ jmp(&done);
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
- __ bind(&initialize_array);
+ // An uninitialized cache is patched with the function or sentinel to
+ // indicate the ElementsKind if function is the Array constructor.
+ __ bind(&initialize);
+ // Make sure the function is the Array() function
+ __ LoadArrayFunction(r4);
+ __ cmp(r1, r4);
+ __ b(ne, ¬_array_function);
+
+ // The target function is the Array constructor,
+ // Create an AllocationSite if we don't already have it, store it in the slot.
{
FrameScope scope(masm, StackFrame::INTERNAL);
}
__ b(&done);
- // Non-array cache: Premonomorphic -> monomorphic.
- __ bind(&initialize_non_array);
+ __ bind(¬_array_function);
+
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
__ add(r4, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
__ str(r1, MemOperand(r4, 0));
// edx : slot in feedback vector (Smi)
// edi : the function to call
Isolate* isolate = masm->isolate();
- Label check_array, initialize_array, initialize_non_array, megamorphic, done;
+ Label initialize, done, miss, megamorphic, not_array_function;
// Load the cache state into ecx.
__ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
__ cmp(ecx, Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
__ j(equal, &done, Label::kFar);
- // Load the global or builtins object from the current context and check
- // if we're dealing with the Array function or not.
+ // If we came here, we need to see if we are the array function.
+ // If we didn't have a matching function, and we didn't find the megamorph
+ // sentinel, then we have in the slot either some other function or an
+ // AllocationSite. Do a map check on the object in ecx.
+ Handle<Map> allocation_site_map =
+ masm->isolate()->factory()->allocation_site_map();
+ __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map));
+ __ j(not_equal, &miss);
+
+ // Load the global or builtins object from the current context
__ LoadGlobalContext(ecx);
+ // Make sure the function is the Array() function
__ cmp(edi, Operand(ecx,
Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
- __ j(equal, &check_array);
-
- // Non-array cache: Reload the cache state and check it.
- __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
- FixedArray::kHeaderSize));
- __ cmp(ecx, Immediate(TypeFeedbackInfo::PremonomorphicSentinel(isolate)));
- __ j(equal, &initialize_non_array);
- __ cmp(ecx, Immediate(TypeFeedbackInfo::UninitializedSentinel(isolate)));
__ j(not_equal, &megamorphic);
-
- // Non-array cache: Uninitialized -> premonomorphic. The sentinel is an
- // immortal immovable object (null) so no write-barrier is needed.
- __ mov(FieldOperand(ebx, edx, times_half_pointer_size,
- FixedArray::kHeaderSize),
- Immediate(TypeFeedbackInfo::PremonomorphicSentinel(isolate)));
__ jmp(&done, Label::kFar);
- // Array cache: Reload the cache state and check to see if we're in a
- // monomorphic state where the state object is an AllocationSite object.
- __ bind(&check_array);
- __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
- FixedArray::kHeaderSize));
- Handle<Map> allocation_site_map = isolate->factory()->allocation_site_map();
- __ cmp(FieldOperand(ecx, 0), Immediate(allocation_site_map));
- __ j(equal, &done, Label::kFar);
+ __ bind(&miss);
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
+ // A monomorphic miss (i.e, here the cache is not uninitialized) goes
+ // megamorphic.
__ cmp(ecx, Immediate(TypeFeedbackInfo::UninitializedSentinel(isolate)));
- __ j(equal, &initialize_array);
- __ cmp(ecx, Immediate(TypeFeedbackInfo::PremonomorphicSentinel(isolate)));
- __ j(equal, &initialize_array);
-
- // Both caches: Monomorphic -> megamorphic. The sentinel is an
- // immortal immovable object (undefined) so no write-barrier is needed.
+ __ j(equal, &initialize);
+ // MegamorphicSentinel is an immortal immovable object (undefined) so no
+ // write-barrier is needed.
__ bind(&megamorphic);
__ mov(FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize),
Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate)));
__ jmp(&done, Label::kFar);
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
- __ bind(&initialize_array);
+ // An uninitialized cache is patched with the function or sentinel to
+ // indicate the ElementsKind if function is the Array constructor.
+ __ bind(&initialize);
+ __ LoadGlobalContext(ecx);
+ // Make sure the function is the Array() function
+ __ cmp(edi, Operand(ecx,
+ Context::SlotOffset(Context::ARRAY_FUNCTION_INDEX)));
+ __ j(not_equal, ¬_array_function);
+
+ // The target function is the Array constructor,
+ // Create an AllocationSite if we don't already have it, store it in the slot.
{
FrameScope scope(masm, StackFrame::INTERNAL);
}
__ jmp(&done);
- // Non-array cache: Premonomorphic -> monomorphic.
- __ bind(&initialize_non_array);
+ __ bind(¬_array_function);
__ mov(FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize),
edi);
+ // We won't need edx or ebx anymore, just save edi
__ push(edi);
__ push(ebx);
__ push(edx);
// a1 : the function to call
// a2 : Feedback vector
// a3 : slot in feedback vector (Smi)
- Label check_array, initialize_array, initialize_non_array, megamorphic, done;
+ Label initialize, done, miss, megamorphic, not_array_function;
ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()),
masm->isolate()->heap()->undefined_value());
- Heap::RootListIndex kMegamorphicRootIndex = Heap::kUndefinedValueRootIndex;
ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()),
masm->isolate()->heap()->the_hole_value());
- Heap::RootListIndex kUninitializedRootIndex = Heap::kTheHoleValueRootIndex;
- ASSERT_EQ(*TypeFeedbackInfo::PremonomorphicSentinel(masm->isolate()),
- masm->isolate()->heap()->null_value());
- Heap::RootListIndex kPremonomorphicRootIndex = Heap::kNullValueRootIndex;
// Load the cache state into t0.
__ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
// A monomorphic cache hit or an already megamorphic state: invoke the
// function without changing the state.
__ Branch(&done, eq, t0, Operand(a1));
- __ LoadRoot(at, kMegamorphicRootIndex);
- __ Branch(&done, eq, t0, Operand(at));
-
- // Check if we're dealing with the Array function or not.
- __ LoadArrayFunction(t1);
- __ Branch(&check_array, eq, a1, Operand(t1));
-
- // Non-array cache: Check the cache state.
- __ LoadRoot(at, kPremonomorphicRootIndex);
- __ Branch(&initialize_non_array, eq, t0, Operand(at));
- __ LoadRoot(at, kUninitializedRootIndex);
- __ Branch(&megamorphic, ne, t0, Operand(at));
-
- // Non-array cache: Uninitialized -> premonomorphic. The sentinel is an
- // immortal immovable object (null) so no write-barrier is needed.
- __ sll(at, a3, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(t0, a2, at);
- __ LoadRoot(at, kPremonomorphicRootIndex);
- __ Branch(USE_DELAY_SLOT, &done);
- __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); // In delay slot.
-
- // Array cache: Check the cache state to see if we're in a monomorphic
- // state where the state object is an AllocationSite object.
- __ bind(&check_array);
+
+ // If we came here, we need to see if we are the array function.
+ // If we didn't have a matching function, and we didn't find the megamorph
+ // sentinel, then we have in the slot either some other function or an
+ // AllocationSite. Do a map check on the object in a3.
__ lw(t1, FieldMemOperand(t0, 0));
__ LoadRoot(at, Heap::kAllocationSiteMapRootIndex);
- __ Branch(&done, eq, t1, Operand(at));
+ __ Branch(&miss, ne, t1, Operand(at));
+
+ // Make sure the function is the Array() function
+ __ LoadArrayFunction(t0);
+ __ Branch(&megamorphic, ne, a1, Operand(t0));
+ __ jmp(&done);
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
- __ LoadRoot(at, kUninitializedRootIndex);
- __ Branch(&initialize_array, eq, t0, Operand(at));
- __ LoadRoot(at, kPremonomorphicRootIndex);
- __ Branch(&initialize_array, eq, t0, Operand(at));
+ __ bind(&miss);
- // Both caches: Monomorphic -> megamorphic. The sentinel is an
- // immortal immovable object (undefined) so no write-barrier is needed.
+ // A monomorphic miss (i.e, here the cache is not uninitialized) goes
+ // megamorphic.
+ __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
+ __ Branch(&initialize, eq, t0, Operand(at));
+ // MegamorphicSentinel is an immortal immovable object (undefined) so no
+ // write-barrier is needed.
__ bind(&megamorphic);
__ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
__ Addu(t0, a2, Operand(t0));
- __ LoadRoot(at, kMegamorphicRootIndex);
- __ Branch(USE_DELAY_SLOT, &done);
- __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); // In delay slot.
-
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
- __ bind(&initialize_array);
+ __ LoadRoot(at, Heap::kUndefinedValueRootIndex);
+ __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize));
+ __ jmp(&done);
+
+ // An uninitialized cache is patched with the function or sentinel to
+ // indicate the ElementsKind if function is the Array constructor.
+ __ bind(&initialize);
+ // Make sure the function is the Array() function
+ __ LoadArrayFunction(t0);
+ __ Branch(¬_array_function, ne, a1, Operand(t0));
+
+ // The target function is the Array constructor.
+ // Create an AllocationSite if we don't already have it, store it in the slot.
{
FrameScope scope(masm, StackFrame::INTERNAL);
const RegList kSavedRegs =
}
__ Branch(&done);
- // Non-array cache: Premonomorphic -> monomorphic.
- __ bind(&initialize_non_array);
+ __ bind(¬_array_function);
+
__ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize);
__ Addu(t0, a2, Operand(t0));
__ Addu(t0, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
}
-Handle<Object> TypeFeedbackInfo::PremonomorphicSentinel(Isolate* isolate) {
- return isolate->factory()->null_value();
-}
-
-
Handle<Object> TypeFeedbackInfo::MegamorphicSentinel(Isolate* isolate) {
return isolate->factory()->undefined_value();
}
// The object that indicates an uninitialized cache.
static inline Handle<Object> UninitializedSentinel(Isolate* isolate);
- // The object that indicates a cache in pre-monomorphic state.
- static inline Handle<Object> PremonomorphicSentinel(Isolate* isolate);
-
// The object that indicates a megamorphic state.
static inline Handle<Object> MegamorphicSentinel(Isolate* isolate);
Handle<AllocationSite> site;
if (!type_info.is_null() &&
- *type_info != isolate->heap()->null_value() &&
*type_info != isolate->heap()->undefined_value()) {
site = Handle<AllocationSite>::cast(type_info);
ASSERT(!site->SitePointsToLiteral());
// rdx : slot in feedback vector (Smi)
// rdi : the function to call
Isolate* isolate = masm->isolate();
- Label check_array, initialize_array, initialize_non_array, megamorphic, done;
+ Label initialize, done, miss, megamorphic, not_array_function,
+ done_no_smi_convert;
// Load the cache state into rcx.
__ SmiToInteger32(rdx, rdx);
__ Cmp(rcx, TypeFeedbackInfo::MegamorphicSentinel(isolate));
__ j(equal, &done);
- // Check if we're dealing with the Array function or not.
+ // If we came here, we need to see if we are the array function.
+ // If we didn't have a matching function, and we didn't find the megamorph
+ // sentinel, then we have in the slot either some other function or an
+ // AllocationSite. Do a map check on the object in rcx.
+ Handle<Map> allocation_site_map =
+ masm->isolate()->factory()->allocation_site_map();
+ __ Cmp(FieldOperand(rcx, 0), allocation_site_map);
+ __ j(not_equal, &miss);
+
+ // Make sure the function is the Array() function
__ LoadArrayFunction(rcx);
__ cmpq(rdi, rcx);
- __ j(equal, &check_array);
-
- // Non-array cache: Reload the cache state and check it.
- __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size,
- FixedArray::kHeaderSize));
- __ Cmp(rcx, TypeFeedbackInfo::PremonomorphicSentinel(isolate));
- __ j(equal, &initialize_non_array);
- __ Cmp(rcx, TypeFeedbackInfo::UninitializedSentinel(isolate));
__ j(not_equal, &megamorphic);
+ __ jmp(&done);
- // Non-array cache: Uninitialized -> premonomorphic. The sentinel is an
- // immortal immovable object (null) so no write-barrier is needed.
- __ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
- TypeFeedbackInfo::PremonomorphicSentinel(isolate));
- __ jmp(&done, Label::kFar);
-
- // Array cache: Reload the cache state and check to see if we're in a
- // monomorphic state where the state object is an AllocationSite object.
- __ bind(&check_array);
- __ movp(rcx, FieldOperand(rbx, rdx, times_pointer_size,
- FixedArray::kHeaderSize));
- Handle<Map> allocation_site_map = isolate->factory()->allocation_site_map();
- __ Cmp(FieldOperand(rcx, 0), allocation_site_map);
- __ j(equal, &done);
+ __ bind(&miss);
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
+ // A monomorphic miss (i.e, here the cache is not uninitialized) goes
+ // megamorphic.
__ Cmp(rcx, TypeFeedbackInfo::UninitializedSentinel(isolate));
- __ j(equal, &initialize_array);
- __ Cmp(rcx, TypeFeedbackInfo::PremonomorphicSentinel(isolate));
- __ j(equal, &initialize_array);
-
- // Both caches: Monomorphic -> megamorphic. The sentinel is an
- // immortal immovable object (undefined) so no write-barrier is needed.
+ __ j(equal, &initialize);
+ // MegamorphicSentinel is an immortal immovable object (undefined) so no
+ // write-barrier is needed.
__ bind(&megamorphic);
__ Move(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
TypeFeedbackInfo::MegamorphicSentinel(isolate));
__ jmp(&done);
- // Array cache: Uninitialized or premonomorphic -> monomorphic.
- __ bind(&initialize_array);
+ // An uninitialized cache is patched with the function or sentinel to
+ // indicate the ElementsKind if function is the Array constructor.
+ __ bind(&initialize);
+ // Make sure the function is the Array() function
+ __ LoadArrayFunction(rcx);
+ __ cmpq(rdi, rcx);
+ __ j(not_equal, ¬_array_function);
+
+ // The target function is the Array constructor,
+ // Create an AllocationSite if we don't already have it, store it in the slot.
{
FrameScope scope(masm, StackFrame::INTERNAL);
__ pop(rax);
__ SmiToInteger32(rax, rax);
}
- Label done_no_smi_convert;
__ jmp(&done_no_smi_convert);
- // Non-array cache: Premonomorphic -> monomorphic.
- __ bind(&initialize_non_array);
+ __ bind(¬_array_function);
__ movp(FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize),
rdi);
+
+ // We won't need rdx or rbx anymore, just save rdi
__ push(rdi);
__ push(rbx);
__ push(rdx);
// originating from two different native contexts.
CcTest::global()->Set(v8_str("fun1"), fun1);
CcTest::global()->Set(v8_str("fun2"), fun2);
- CompileRun("function f(a, b) { a(); b(); }"
- "f(fun1, fun2);" // Run twice to skip premonomorphic state.
- "f(fun1, fun2)");
+ CompileRun("function f(a, b) { a(); b(); } f(fun1, fun2);");
Handle<JSFunction> f =
v8::Utils::OpenHandle(