Commit 3ccedd5d authored by mvstanton's avatar mvstanton Committed by Commit bot

CallConstruct also gets call count information if megamorphic.

BUG=

Review-Url: https://codereview.chromium.org/2333243004
Cr-Commit-Position: refs/heads/master@{#39398}
parent f85af183
......@@ -1646,7 +1646,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// r2 : feedback vector
// r3 : slot in feedback vector (Smi)
Label initialize, done, miss, megamorphic, not_array_function;
Label done_initialize_count, done_increment_count;
DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
masm->isolate()->heap()->megamorphic_symbol());
......@@ -1666,7 +1665,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
Register weak_value = r9;
__ ldr(weak_value, FieldMemOperand(r5, WeakCell::kValueOffset));
__ cmp(r1, weak_value);
__ b(eq, &done_increment_count);
__ b(eq, &done);
__ CompareRoot(r5, Heap::kmegamorphic_symbolRootIndex);
__ b(eq, &done);
__ ldr(feedback_map, FieldMemOperand(r5, HeapObject::kMapOffset));
......@@ -1689,7 +1688,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, r5);
__ cmp(r1, r5);
__ b(ne, &megamorphic);
__ jmp(&done_increment_count);
__ jmp(&done);
__ bind(&miss);
......@@ -1718,32 +1717,22 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// slot.
CreateAllocationSiteStub create_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &create_stub);
__ b(&done_initialize_count);
__ b(&done);
__ bind(&not_array_function);
CreateWeakCellStub weak_cell_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &weak_cell_stub);
__ bind(&done_initialize_count);
// Initialize the call counter.
__ Move(r5, Operand(Smi::FromInt(1)));
__ add(r4, r2, Operand::PointerOffsetFromSmiKey(r3));
__ str(r5, FieldMemOperand(r4, FixedArray::kHeaderSize + kPointerSize));
__ b(&done);
__ bind(&done_increment_count);
__ bind(&done);
// Increment the call count for monomorphic function calls.
// Increment the call count for all function calls.
__ add(r5, r2, Operand::PointerOffsetFromSmiKey(r3));
__ add(r5, r5, Operand(FixedArray::kHeaderSize + kPointerSize));
__ ldr(r4, FieldMemOperand(r5, 0));
__ add(r4, r4, Operand(Smi::FromInt(1)));
__ str(r4, FieldMemOperand(r5, 0));
__ bind(&done);
}
void CallConstructStub::Generate(MacroAssembler* masm) {
// r0 : number of arguments
// r1 : the function to call
......
......@@ -1845,7 +1845,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
// feedback_vector : the feedback vector
// index : slot in feedback vector (smi)
Label initialize, done, miss, megamorphic, not_array_function;
Label done_initialize_count, done_increment_count;
DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
masm->isolate()->heap()->megamorphic_symbol());
......@@ -1868,7 +1867,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
Label check_allocation_site;
__ Ldr(feedback_value, FieldMemOperand(feedback, WeakCell::kValueOffset));
__ Cmp(function, feedback_value);
__ B(eq, &done_increment_count);
__ B(eq, &done);
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ B(eq, &done);
__ Ldr(feedback_map, FieldMemOperand(feedback, HeapObject::kMapOffset));
......@@ -1890,7 +1889,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch1);
__ Cmp(function, scratch1);
__ B(ne, &megamorphic);
__ B(&done_increment_count);
__ B(&done);
__ Bind(&miss);
......@@ -1921,33 +1920,22 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
CreateAllocationSiteStub create_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &create_stub, argc, function,
feedback_vector, index, new_target);
__ B(&done_initialize_count);
__ B(&done);
__ Bind(&not_array_function);
CreateWeakCellStub weak_cell_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &weak_cell_stub, argc, function,
feedback_vector, index, new_target);
__ bind(&done_initialize_count);
// Initialize the call counter.
__ Mov(scratch1, Operand(Smi::FromInt(1)));
__ Adds(scratch2, feedback_vector,
Operand::UntagSmiAndScale(index, kPointerSizeLog2));
__ Str(scratch1,
FieldMemOperand(scratch2, FixedArray::kHeaderSize + kPointerSize));
__ b(&done);
__ bind(&done_increment_count);
__ Bind(&done);
// Increment the call count for monomorphic function calls.
// Increment the call count for all function calls.
__ Add(scratch1, feedback_vector,
Operand::UntagSmiAndScale(index, kPointerSizeLog2));
__ Add(scratch1, scratch1, Operand(FixedArray::kHeaderSize + kPointerSize));
__ Ldr(scratch2, FieldMemOperand(scratch1, 0));
__ Add(scratch2, scratch2, Operand(Smi::FromInt(1)));
__ Str(scratch2, FieldMemOperand(scratch1, 0));
__ Bind(&done);
}
......
......@@ -1921,10 +1921,9 @@ class CallNew final : public Expression {
// Type feedback information.
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) {
callnew_feedback_slot_ = spec->AddGeneralSlot();
// Construct calls have two slots, one right after the other.
// The second slot stores the call count for monomorphic calls.
spec->AddGeneralSlot();
// CallNew stores feedback in the exact same way as Call. We can
// piggyback on the type feedback infrastructure for calls.
callnew_feedback_slot_ = spec->AddCallICSlot();
}
FeedbackVectorSlot CallNewFeedbackSlot() {
......
......@@ -386,8 +386,8 @@ Reduction JSCallReducer::ReduceJSCallConstruct(Node* node) {
// Check if we have an allocation site.
Handle<AllocationSite> site;
if (p.feedback().IsValid()) {
Handle<Object> feedback(
p.feedback().vector()->Get(p.feedback().slot()), isolate());
CallICNexus nexus(p.feedback().vector(), p.feedback().slot());
Handle<Object> feedback(nexus.GetFeedback(), isolate());
if (feedback->IsAllocationSite()) {
site = Handle<AllocationSite>::cast(feedback);
}
......@@ -412,10 +412,9 @@ Reduction JSCallReducer::ReduceJSCallConstruct(Node* node) {
// Not much we can do if deoptimization support is disabled.
if (!(flags() & kDeoptimizationEnabled)) return NoChange();
// TODO(mvstanton): Use ConstructICNexus here, once available.
Handle<Object> feedback;
if (!p.feedback().IsValid()) return NoChange();
feedback = handle(p.feedback().vector()->Get(p.feedback().slot()), isolate());
CallICNexus nexus(p.feedback().vector(), p.feedback().slot());
Handle<Object> feedback(nexus.GetFeedback(), isolate());
if (feedback->IsAllocationSite()) {
// The feedback is an AllocationSite, which means we have called the
// Array function and collected transition (and pretenuring) feedback
......
......@@ -132,12 +132,8 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode());
CallConstructParameters p = CallConstructParametersOf(node->op());
if (p.feedback().IsValid()) {
int const extra_index =
p.feedback().vector()->GetIndex(p.feedback().slot()) + 1;
Object* feedback_extra = p.feedback().vector()->get(extra_index);
if (feedback_extra->IsSmi()) {
candidate.calls = Smi::cast(feedback_extra)->value();
}
CallICNexus nexus(p.feedback().vector(), p.feedback().slot());
candidate.calls = nexus.ExtractCallCount();
}
}
......
......@@ -1301,7 +1301,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// edi : the function to call
Isolate* isolate = masm->isolate();
Label initialize, done, miss, megamorphic, not_array_function;
Label done_increment_count, done_initialize_count;
// Load the cache state into ecx.
__ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
......@@ -1314,7 +1313,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// type-feedback-vector.h).
Label check_allocation_site;
__ cmp(edi, FieldOperand(ecx, WeakCell::kValueOffset));
__ j(equal, &done_increment_count, Label::kFar);
__ j(equal, &done, Label::kFar);
__ CompareRoot(ecx, Heap::kmegamorphic_symbolRootIndex);
__ j(equal, &done, Label::kFar);
__ CompareRoot(FieldOperand(ecx, HeapObject::kMapOffset),
......@@ -1337,7 +1336,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
__ cmp(edi, ecx);
__ j(not_equal, &megamorphic);
__ jmp(&done_increment_count, Label::kFar);
__ jmp(&done, Label::kFar);
__ bind(&miss);
......@@ -1366,26 +1365,17 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// slot.
CreateAllocationSiteStub create_stub(isolate);
CallStubInRecordCallTarget(masm, &create_stub);
__ jmp(&done_initialize_count);
__ jmp(&done);
__ bind(&not_array_function);
CreateWeakCellStub weak_cell_stub(isolate);
CallStubInRecordCallTarget(masm, &weak_cell_stub);
__ bind(&done_initialize_count);
// Initialize the call counter.
__ mov(FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize + kPointerSize),
Immediate(Smi::FromInt(1)));
__ jmp(&done);
__ bind(&done_increment_count);
// Increment the call count for monomorphic function calls.
__ bind(&done);
// Increment the call count for all function calls.
__ add(FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize + kPointerSize),
Immediate(Smi::FromInt(1)));
__ bind(&done);
}
......
......@@ -500,6 +500,7 @@ void InterpreterAssembler::CallEpilogue() {
Node* InterpreterAssembler::IncrementCallCount(Node* type_feedback_vector,
Node* slot_id) {
Comment("increment call count");
Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1));
Node* call_count =
LoadFixedArrayElement(type_feedback_vector, call_count_slot);
......@@ -756,24 +757,20 @@ Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context,
// are uninitialized, monomorphic (indicated by a JSFunction), and
// megamorphic.
// TODO(mythria/v8:5210): Check if it is better to mark extra_checks as a
// deferred block so that call_construct_function will be scheduled just
// after increment_count and in the fast path we can reduce one branch in
// the
// fast path.
Label increment_count(this), extra_checks(this),
call_construct_function(this);
// deferred block so that call_construct_function will be scheduled.
Label extra_checks(this), call_construct_function(this);
Node* feedback_element =
LoadFixedArrayElement(type_feedback_vector, slot_id);
Node* feedback_value = LoadWeakCellValue(feedback_element);
Node* is_monomorphic = WordEqual(constructor, feedback_value);
BranchIf(is_monomorphic, &increment_count, &extra_checks);
BranchIf(is_monomorphic, &call_construct_function, &extra_checks);
Bind(&extra_checks);
{
Label mark_megamorphic(this), initialize(this),
check_allocation_site(this), check_initialized(this),
set_alloc_feedback_and_inc_count(this);
set_alloc_feedback_and_call(this);
{
// Check if it is a megamorphic target
Comment("check if megamorphic");
......@@ -806,14 +803,14 @@ Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context,
LoadFixedArrayElement(LoadNativeContext(context),
Int32Constant(Context::ARRAY_FUNCTION_INDEX));
Node* is_array_function = WordEqual(context_slot, constructor);
BranchIf(is_array_function, &set_alloc_feedback_and_inc_count,
BranchIf(is_array_function, &set_alloc_feedback_and_call,
&mark_megamorphic);
}
Bind(&set_alloc_feedback_and_inc_count);
Bind(&set_alloc_feedback_and_call);
{
allocation_feedback.Bind(feedback_element);
Goto(&increment_count);
Goto(&call_construct_function);
}
Bind(&check_initialized);
......@@ -827,8 +824,7 @@ Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context,
Bind(&initialize);
{
Label initialize_count(this), create_weak_cell(this),
create_allocation_site(this);
Label create_weak_cell(this), create_allocation_site(this);
Comment("initialize the feedback element");
// Check that it is the Array() function.
Node* context_slot =
......@@ -847,22 +843,13 @@ Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context,
Node* feedback_element =
LoadFixedArrayElement(type_feedback_vector, slot_id);
allocation_feedback.Bind(feedback_element);
Goto(&initialize_count);
Goto(&call_construct_function);
}
Bind(&create_weak_cell);
{
CreateWeakCellInFeedbackVector(type_feedback_vector, SmiTag(slot_id),
constructor);
Goto(&initialize_count);
}
Bind(&initialize_count);
{
Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1));
// Count is Smi, so we don't need a write barrier.
StoreFixedArrayElement(type_feedback_vector, call_count_slot,
SmiTag(Int32Constant(1)), SKIP_WRITE_BARRIER);
Goto(&call_construct_function);
}
}
......@@ -882,23 +869,10 @@ Node* InterpreterAssembler::CallConstruct(Node* constructor, Node* context,
}
}
Bind(&increment_count);
{
// Increment the call count.
Comment("increment call count");
Node* call_count_slot = IntPtrAdd(slot_id, IntPtrConstant(1));
Node* call_count =
LoadFixedArrayElement(type_feedback_vector, call_count_slot);
Node* new_count = SmiAdd(call_count, SmiTag(Int32Constant(1)));
// Count is Smi, so we don't need a write barrier.
StoreFixedArrayElement(type_feedback_vector, call_count_slot, new_count,
SKIP_WRITE_BARRIER);
Goto(&call_construct_function);
}
Bind(&call_construct_function);
{
Comment("call using callConstructFunction");
IncrementCallCount(type_feedback_vector, slot_id);
Callable callable_function = CodeFactory::InterpreterPushArgsAndConstruct(
isolate(), CallableType::kJSFunction);
return_value.Bind(CallStub(callable_function.descriptor(),
......
......@@ -1782,7 +1782,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// a2 : feedback vector
// a3 : slot in feedback vector (Smi)
Label initialize, done, miss, megamorphic, not_array_function;
Label done_initialize_count, done_increment_count;
DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
masm->isolate()->heap()->megamorphic_symbol());
......@@ -1801,7 +1800,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
Register feedback_map = t1;
Register weak_value = t4;
__ lw(weak_value, FieldMemOperand(t2, WeakCell::kValueOffset));
__ Branch(&done_increment_count, eq, a1, Operand(weak_value));
__ Branch(&done, eq, a1, Operand(weak_value));
__ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
__ Branch(&done, eq, t2, Operand(at));
__ lw(feedback_map, FieldMemOperand(t2, HeapObject::kMapOffset));
......@@ -1823,7 +1822,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// Make sure the function is the Array() function
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, t2);
__ Branch(&megamorphic, ne, a1, Operand(t2));
__ jmp(&done_increment_count);
__ jmp(&done);
__ bind(&miss);
......@@ -1850,28 +1849,19 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// slot.
CreateAllocationSiteStub create_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &create_stub);
__ Branch(&done_initialize_count);
__ Branch(&done);
__ bind(&not_array_function);
CreateWeakCellStub weak_cell_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &weak_cell_stub);
__ bind(&done_initialize_count);
// Initialize the call counter.
__ Lsa(at, a2, a3, kPointerSizeLog2 - kSmiTagSize);
__ li(t0, Operand(Smi::FromInt(1)));
__ Branch(USE_DELAY_SLOT, &done);
__ sw(t0, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize));
__ bind(&done_increment_count);
__ bind(&done);
// Increment the call count for monomorphic function calls.
// Increment the call count for all function calls.
__ Lsa(at, a2, a3, kPointerSizeLog2 - kSmiTagSize);
__ lw(t0, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize));
__ Addu(t0, t0, Operand(Smi::FromInt(1)));
__ sw(t0, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize));
__ bind(&done);
}
......
......@@ -1783,7 +1783,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// a2 : feedback vector
// a3 : slot in feedback vector (Smi)
Label initialize, done, miss, megamorphic, not_array_function;
Label done_initialize_count, done_increment_count;
DCHECK_EQ(*TypeFeedbackVector::MegamorphicSentinel(masm->isolate()),
masm->isolate()->heap()->megamorphic_symbol());
......@@ -1803,7 +1802,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
Register feedback_map = a6;
Register weak_value = t0;
__ ld(weak_value, FieldMemOperand(a5, WeakCell::kValueOffset));
__ Branch(&done_increment_count, eq, a1, Operand(weak_value));
__ Branch(&done, eq, a1, Operand(weak_value));
__ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
__ Branch(&done, eq, a5, Operand(at));
__ ld(feedback_map, FieldMemOperand(a5, HeapObject::kMapOffset));
......@@ -1825,7 +1824,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// Make sure the function is the Array() function
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, a5);
__ Branch(&megamorphic, ne, a1, Operand(a5));
__ jmp(&done_increment_count);
__ jmp(&done);
__ bind(&miss);
......@@ -1853,32 +1852,21 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// slot.
CreateAllocationSiteStub create_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &create_stub);
__ Branch(&done_initialize_count);
__ Branch(&done);
__ bind(&not_array_function);
CreateWeakCellStub weak_cell_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &weak_cell_stub);
__ bind(&done_initialize_count);
// Initialize the call counter.
__ SmiScale(a4, a3, kPointerSizeLog2);
__ Daddu(a4, a2, Operand(a4));
__ li(a5, Operand(Smi::FromInt(1)));
__ Branch(USE_DELAY_SLOT, &done);
__ sd(a5, FieldMemOperand(a4, FixedArray::kHeaderSize + kPointerSize));
__ bind(&done_increment_count);
__ bind(&done);
// Increment the call count for monomorphic function calls.
// Increment the call count for all function calls.
__ SmiScale(a4, a3, kPointerSizeLog2);
__ Daddu(a5, a2, Operand(a4));
__ ld(a4, FieldMemOperand(a5, FixedArray::kHeaderSize + kPointerSize));
__ Daddu(a4, a4, Operand(Smi::FromInt(1)));
__ sd(a4, FieldMemOperand(a5, FixedArray::kHeaderSize + kPointerSize));
__ bind(&done);
}
......
......@@ -1175,6 +1175,7 @@ static void CallStubInRecordCallTarget(MacroAssembler* masm, CodeStub* stub) {
__ Pop(rdx);
__ Pop(rdi);
__ Pop(rax);
__ SmiToInteger32(rdx, rdx);
__ SmiToInteger32(rax, rax);
}
......@@ -1189,7 +1190,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// rdi : the function to call
Isolate* isolate = masm->isolate();
Label initialize, done, miss, megamorphic, not_array_function;
Label done_initialize_count, done_increment_count;
// Load the cache state into r11.
__ SmiToInteger32(rdx, rdx);
......@@ -1203,7 +1203,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// type-feedback-vector.h).
Label check_allocation_site;
__ cmpp(rdi, FieldOperand(r11, WeakCell::kValueOffset));
__ j(equal, &done_increment_count, Label::kFar);
__ j(equal, &done, Label::kFar);
__ CompareRoot(r11, Heap::kmegamorphic_symbolRootIndex);
__ j(equal, &done, Label::kFar);
__ CompareRoot(FieldOperand(r11, HeapObject::kMapOffset),
......@@ -1227,7 +1227,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, r11);
__ cmpp(rdi, r11);
__ j(not_equal, &megamorphic);
__ jmp(&done_increment_count);
__ jmp(&done);
__ bind(&miss);
......@@ -1253,29 +1253,17 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
CreateAllocationSiteStub create_stub(isolate);
CallStubInRecordCallTarget(masm, &create_stub);
__ jmp(&done_initialize_count);
__ jmp(&done);
__ bind(&not_array_function);
CreateWeakCellStub weak_cell_stub(isolate);
CallStubInRecordCallTarget(masm, &weak_cell_stub);
__ bind(&done_initialize_count);
// Initialize the call counter.
__ SmiToInteger32(rdx, rdx);
__ Move(FieldOperand(rbx, rdx, times_pointer_size,
FixedArray::kHeaderSize + kPointerSize),
Smi::FromInt(1));
__ jmp(&done);
__ bind(&done_increment_count);
// Increment the call count for monomorphic function calls.
__ bind(&done);
// Increment the call count for all function calls.
__ SmiAddConstant(FieldOperand(rbx, rdx, times_pointer_size,
FixedArray::kHeaderSize + kPointerSize),
Smi::FromInt(1));
__ bind(&done);
__ Integer32ToSmi(rdx, rdx);
}
......@@ -1294,7 +1282,6 @@ void CallConstructStub::Generate(MacroAssembler* masm) {
GenerateRecordCallTarget(masm);
__ SmiToInteger32(rdx, rdx);
Label feedback_register_initialized;
// Put the AllocationSite from the feedback vector into rbx, or undefined.
__ movp(rbx,
......
......@@ -290,13 +290,21 @@ TEST(VectorConstructCounts) {
Handle<JSFunction> f = GetFunction("f");
Handle<TypeFeedbackVector> feedback_vector =
Handle<TypeFeedbackVector>(f->feedback_vector(), isolate);
FeedbackVectorSlot slot(0);
CallICNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
CHECK(feedback_vector->Get(slot)->IsWeakCell());
CompileRun("f(Foo); f(Foo);");
FeedbackVectorSlot cslot(1);
CHECK(feedback_vector->Get(cslot)->IsSmi());
CHECK_EQ(3, Smi::cast(feedback_vector->Get(cslot))->value());
CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
CHECK_EQ(3, nexus.ExtractCallCount());
// Send the IC megamorphic, but we should still have incrementing counts.
CompileRun("f(function() {});");
CHECK_EQ(GENERIC, nexus.StateFromFeedback());
CHECK_EQ(4, nexus.ExtractCallCount());
}
TEST(VectorLoadICStates) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment