Collect call counts for constructor calls, too.

The TurboFan inliner makes use of these counts.

BUG=

Review-Url: https://codereview.chromium.org/1969783002
Cr-Commit-Position: refs/heads/master@{#36472}
This commit is contained in:
mvstanton 2016-05-24 04:53:13 -07:00 committed by Commit bot
parent daae44f69b
commit a6ddbef064
10 changed files with 170 additions and 26 deletions

View File

@ -1786,6 +1786,7 @@ 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());
@ -1805,7 +1806,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
Register weak_value = r9;
__ ldr(weak_value, FieldMemOperand(r5, WeakCell::kValueOffset));
__ cmp(r1, weak_value);
__ b(eq, &done);
__ b(eq, &done_increment_count);
__ CompareRoot(r5, Heap::kmegamorphic_symbolRootIndex);
__ b(eq, &done);
__ ldr(feedback_map, FieldMemOperand(r5, HeapObject::kMapOffset));
@ -1828,7 +1829,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, r5);
__ cmp(r1, r5);
__ b(ne, &megamorphic);
__ jmp(&done);
__ jmp(&done_increment_count);
__ bind(&miss);
@ -1857,11 +1858,28 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// slot.
CreateAllocationSiteStub create_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &create_stub);
__ b(&done);
__ b(&done_initialize_count);
__ 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);
// Increment the call count for monomorphic 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);
}

View File

@ -2010,6 +2010,7 @@ 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());
@ -2032,7 +2033,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);
__ B(eq, &done_increment_count);
__ CompareRoot(feedback, Heap::kmegamorphic_symbolRootIndex);
__ B(eq, &done);
__ Ldr(feedback_map, FieldMemOperand(feedback, HeapObject::kMapOffset));
@ -2054,7 +2055,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, Register argc,
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, scratch1);
__ Cmp(function, scratch1);
__ B(ne, &megamorphic);
__ B(&done);
__ B(&done_increment_count);
__ Bind(&miss);
@ -2085,12 +2086,32 @@ 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);
__ B(&done_initialize_count);
__ 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);
// Increment the call count for monomorphic 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);
}

View File

@ -2004,6 +2004,9 @@ class CallNew final : public Expression {
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
FeedbackVectorSlotCache* cache) override {
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();
}
FeedbackVectorSlot CallNewFeedbackSlot() {

View File

@ -1457,6 +1457,7 @@ 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,
@ -1469,7 +1470,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// type-feedback-vector.h).
Label check_allocation_site;
__ cmp(edi, FieldOperand(ecx, WeakCell::kValueOffset));
__ j(equal, &done, Label::kFar);
__ j(equal, &done_increment_count, Label::kFar);
__ CompareRoot(ecx, Heap::kmegamorphic_symbolRootIndex);
__ j(equal, &done, Label::kFar);
__ CompareRoot(FieldOperand(ecx, HeapObject::kMapOffset),
@ -1492,7 +1493,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, ecx);
__ cmp(edi, ecx);
__ j(not_equal, &megamorphic);
__ jmp(&done, Label::kFar);
__ jmp(&done_increment_count, Label::kFar);
__ bind(&miss);
@ -1521,11 +1522,25 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// slot.
CreateAllocationSiteStub create_stub(isolate);
CallStubInRecordCallTarget(masm, &create_stub);
__ jmp(&done);
__ jmp(&done_initialize_count);
__ 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.
__ add(FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize + kPointerSize),
Immediate(Smi::FromInt(1)));
__ bind(&done);
}

View File

@ -1908,6 +1908,7 @@ 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());
@ -1926,7 +1927,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
Register feedback_map = t1;
Register weak_value = t4;
__ lw(weak_value, FieldMemOperand(t2, WeakCell::kValueOffset));
__ Branch(&done, eq, a1, Operand(weak_value));
__ Branch(&done_increment_count, eq, a1, Operand(weak_value));
__ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
__ Branch(&done, eq, t2, Operand(at));
__ lw(feedback_map, FieldMemOperand(t2, HeapObject::kMapOffset));
@ -1948,7 +1949,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);
__ jmp(&done_increment_count);
__ bind(&miss);
@ -1975,11 +1976,27 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// slot.
CreateAllocationSiteStub create_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &create_stub);
__ Branch(&done);
__ Branch(&done_initialize_count);
__ 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)));
__ sw(t0, FieldMemOperand(at, FixedArray::kHeaderSize + kPointerSize));
__ b(&done);
__ bind(&done_increment_count);
// Increment the call count for monomorphic 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);
}

View File

@ -1911,6 +1911,7 @@ 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());
@ -1930,7 +1931,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
Register feedback_map = a6;
Register weak_value = t0;
__ ld(weak_value, FieldMemOperand(a5, WeakCell::kValueOffset));
__ Branch(&done, eq, a1, Operand(weak_value));
__ Branch(&done_increment_count, eq, a1, Operand(weak_value));
__ LoadRoot(at, Heap::kmegamorphic_symbolRootIndex);
__ Branch(&done, eq, a5, Operand(at));
__ ld(feedback_map, FieldMemOperand(a5, HeapObject::kMapOffset));
@ -1952,7 +1953,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);
__ jmp(&done_increment_count);
__ bind(&miss);
@ -1980,12 +1981,31 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// slot.
CreateAllocationSiteStub create_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &create_stub);
__ Branch(&done);
__ Branch(&done_initialize_count);
__ bind(&not_array_function);
CreateWeakCellStub weak_cell_stub(masm->isolate());
CallStubInRecordCallTarget(masm, &weak_cell_stub);
__ bind(&done_initialize_count);
// Initialize the call counter.
__ dsrl(a4, a3, 32 - kPointerSizeLog2);
__ Daddu(a4, a2, Operand(a4));
__ li(a5, Operand(Smi::FromInt(1)));
__ sd(a5, FieldMemOperand(a4, FixedArray::kHeaderSize + kPointerSize));
__ bind(&done);
__ bind(&done_increment_count);
// Increment the call count for monomorphic function calls.
__ dsrl(a4, a3, 32 - 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);
}

View File

@ -1331,8 +1331,8 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// rdx : slot in feedback vector (Smi)
// rdi : the function to call
Isolate* isolate = masm->isolate();
Label initialize, done, miss, megamorphic, not_array_function,
done_no_smi_convert;
Label initialize, done, miss, megamorphic, not_array_function;
Label done_initialize_count, done_increment_count;
// Load the cache state into r11.
__ SmiToInteger32(rdx, rdx);
@ -1346,7 +1346,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// type-feedback-vector.h).
Label check_allocation_site;
__ cmpp(rdi, FieldOperand(r11, WeakCell::kValueOffset));
__ j(equal, &done, Label::kFar);
__ j(equal, &done_increment_count, Label::kFar);
__ CompareRoot(r11, Heap::kmegamorphic_symbolRootIndex);
__ j(equal, &done, Label::kFar);
__ CompareRoot(FieldOperand(r11, HeapObject::kMapOffset),
@ -1370,7 +1370,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
__ LoadNativeContextSlot(Context::ARRAY_FUNCTION_INDEX, r11);
__ cmpp(rdi, r11);
__ j(not_equal, &megamorphic);
__ jmp(&done);
__ jmp(&done_increment_count);
__ bind(&miss);
@ -1396,17 +1396,29 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
CreateAllocationSiteStub create_stub(isolate);
CallStubInRecordCallTarget(masm, &create_stub);
__ jmp(&done_no_smi_convert);
__ jmp(&done_initialize_count);
__ bind(&not_array_function);
CreateWeakCellStub weak_cell_stub(isolate);
CallStubInRecordCallTarget(masm, &weak_cell_stub);
__ jmp(&done_no_smi_convert);
__ 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.
__ SmiAddConstant(FieldOperand(rbx, rdx, times_pointer_size,
FixedArray::kHeaderSize + kPointerSize),
Smi::FromInt(1));
__ bind(&done);
__ Integer32ToSmi(rdx, rdx);
__ bind(&done_no_smi_convert);
}

View File

@ -150,6 +150,7 @@
# TODO(mythria,4780): Related to type feedback support for calls.
'test-feedback-vector/VectorCallICStates': [PASS, NO_IGNITION],
'test-feedback-vector/VectorCallCounts': [PASS, NO_IGNITION],
'test-compiler/FeedbackVectorPreservedAcrossRecompiles': [PASS, NO_IGNITION],
'test-heap/WeakFunctionInConstructor': [PASS, NO_IGNITION],
'test-heap/IncrementalMarkingClearsMonomorphicConstructor': [PASS, NO_IGNITION],
@ -553,6 +554,7 @@
# TODO(mythria,4780): Related to type feedback support for calls.
'test-feedback-vector/VectorCallICStates': [FAIL],
'test-feedback-vector/VectorCallCounts': [FAIL],
'test-compiler/FeedbackVectorPreservedAcrossRecompiles': [FAIL],
'test-heap/WeakFunctionInConstructor': [FAIL],
'test-heap/IncrementalMarkingClearsMonomorphicConstructor': [FAIL],

View File

@ -19,7 +19,7 @@ parameter count: 1
bytecode array length: 11
bytecodes: [
/* 45 E> */ B(StackCheck),
/* 50 S> */ B(LdaGlobal), U8(0), U8(2),
/* 50 S> */ B(LdaGlobal), U8(0), U8(3),
B(Star), R(0),
/* 57 E> */ B(New), R(0), R(0), U8(0),
/* 68 S> */ B(Return),
@ -41,7 +41,7 @@ parameter count: 1
bytecode array length: 17
bytecodes: [
/* 58 E> */ B(StackCheck),
/* 63 S> */ B(LdaGlobal), U8(0), U8(2),
/* 63 S> */ B(LdaGlobal), U8(0), U8(3),
B(Star), R(0),
B(LdaSmi), U8(3),
B(Star), R(1),
@ -71,7 +71,7 @@ parameter count: 1
bytecode array length: 25
bytecodes: [
/* 100 E> */ B(StackCheck),
/* 105 S> */ B(LdaGlobal), U8(0), U8(2),
/* 105 S> */ B(LdaGlobal), U8(0), U8(3),
B(Star), R(0),
B(LdaSmi), U8(3),
B(Star), R(1),

View File

@ -233,6 +233,42 @@ TEST(VectorCallICStates) {
CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
}
TEST(VectorCallCounts) {
if (i::FLAG_always_opt) return;
CcTest::InitializeVM();
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
Isolate* isolate = CcTest::i_isolate();
// Make sure function f has a call that uses a type feedback slot.
CompileRun(
"function foo() { return 17; }"
"function f(a) { a(); } f(foo);");
Handle<JSFunction> f = GetFunction("f");
// There should be one IC.
Handle<TypeFeedbackVector> feedback_vector =
Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate);
FeedbackVectorSlot slot(0);
CallICNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
CompileRun("f(foo); f(foo);");
CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
CHECK_EQ(3, nexus.ExtractCallCount());
CompileRun(
"function Foo() {}"
"function f(a) { new a(); } f(Foo);");
f = GetFunction("f");
// There should be one IC.
feedback_vector =
Handle<TypeFeedbackVector>(f->shared()->feedback_vector(), isolate);
FeedbackVectorSlot cslot(1);
CompileRun("f(Foo); f(Foo);");
CHECK(feedback_vector->Get(cslot)->IsSmi());
CHECK_EQ(3, Smi::cast(feedback_vector->Get(cslot))->value());
}
TEST(VectorLoadICStates) {
if (i::FLAG_always_opt) return;