Commit 5ef1bddf authored by bmeurer's avatar bmeurer Committed by Commit bot

[compiler] Sanitize IC counts for vector based ICs.

All vector ICs use the TypeFeedbackVector::ComputeCounts method now,
while the remaining patching ICs still use the traditional way of
counting on the TypeFeedbackInfo hanging off the fullcodegen code
object. This fixes the problem that counts were sometimes off.

Drive-by-fix: Move FullCodeGenerator::CallIC to fullcodegen.cc.

R=yangguo@chromium.org

Review-Url: https://codereview.chromium.org/2472653002
Cr-Commit-Position: refs/heads/master@{#40690}
parent 39020433
......@@ -2226,17 +2226,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
context()->Plug(r0);
}
void FullCodeGenerator::CallIC(Handle<Code> code,
TypeFeedbackId ast_id) {
ic_total_count_++;
// All calls must have a predictable size in full-codegen code to ensure that
// the debugger can patch them correctly.
__ Call(code, RelocInfo::CODE_TARGET, ast_id, al,
NEVER_INLINE_TARGET_ADDRESS);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
......
......@@ -2120,16 +2120,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
context()->Plug(x0);
}
void FullCodeGenerator::CallIC(Handle<Code> code,
TypeFeedbackId ast_id) {
ic_total_count_++;
// All calls must have a predictable size in full-codegen code to ensure that
// the debugger can patch them correctly.
__ Call(code, RelocInfo::CODE_TARGET, ast_id);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
ASM_LOCATION("FullCodeGenerator::EmitCallWithLoadIC");
......
......@@ -223,20 +223,25 @@ void FullCodeGenerator::PrepareForBailout(Expression* node,
PrepareForBailoutForId(node->id(), state);
}
void FullCodeGenerator::CallLoadIC(FeedbackVectorSlot slot, Handle<Object> name,
TypeFeedbackId id) {
void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) {
ic_total_count_++;
__ Call(code, RelocInfo::CODE_TARGET, ast_id);
}
void FullCodeGenerator::CallLoadIC(FeedbackVectorSlot slot,
Handle<Object> name) {
DCHECK(name->IsName());
__ Move(LoadDescriptor::NameRegister(), name);
EmitLoadSlot(LoadDescriptor::SlotRegister(), slot);
Handle<Code> ic = CodeFactory::LoadIC(isolate()).code();
CallIC(ic, id);
Handle<Code> code = CodeFactory::LoadIC(isolate()).code();
__ Call(code, RelocInfo::CODE_TARGET);
if (FLAG_tf_load_ic_stub) RestoreContext();
}
void FullCodeGenerator::CallStoreIC(FeedbackVectorSlot slot,
Handle<Object> name, TypeFeedbackId id) {
Handle<Object> name) {
DCHECK(name->IsName());
__ Move(StoreDescriptor::NameRegister(), name);
......@@ -249,8 +254,8 @@ void FullCodeGenerator::CallStoreIC(FeedbackVectorSlot slot,
EmitLoadSlot(StoreDescriptor::SlotRegister(), slot);
}
Handle<Code> ic = CodeFactory::StoreIC(isolate(), language_mode()).code();
CallIC(ic, id);
Handle<Code> code = CodeFactory::StoreIC(isolate(), language_mode()).code();
__ Call(code, RelocInfo::CODE_TARGET);
RestoreContext();
}
......@@ -264,9 +269,9 @@ void FullCodeGenerator::CallKeyedStoreIC(FeedbackVectorSlot slot) {
EmitLoadSlot(StoreDescriptor::SlotRegister(), slot);
}
Handle<Code> ic =
Handle<Code> code =
CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
CallIC(ic);
__ Call(code, RelocInfo::CODE_TARGET);
RestoreContext();
}
......@@ -503,8 +508,8 @@ void FullCodeGenerator::EmitGlobalVariableLoad(VariableProxy* proxy,
#endif
EmitLoadSlot(LoadGlobalDescriptor::SlotRegister(),
proxy->VariableFeedbackSlot());
Handle<Code> ic = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code();
CallIC(ic);
Handle<Code> code = CodeFactory::LoadGlobalIC(isolate(), typeof_mode).code();
__ Call(code, RelocInfo::CODE_TARGET);
}
void FullCodeGenerator::VisitSloppyBlockFunctionStatement(
......@@ -1122,8 +1127,8 @@ void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
EmitLoadSlot(LoadDescriptor::SlotRegister(), prop->PropertyFeedbackSlot());
Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate()).code();
CallIC(ic);
Handle<Code> code = CodeFactory::KeyedLoadIC(isolate()).code();
__ Call(code, RelocInfo::CODE_TARGET);
RestoreContext();
}
......
......@@ -616,10 +616,8 @@ class FullCodeGenerator final : public AstVisitor<FullCodeGenerator> {
void CallIC(Handle<Code> code,
TypeFeedbackId id = TypeFeedbackId::None());
void CallLoadIC(FeedbackVectorSlot slot, Handle<Object> name,
TypeFeedbackId id = TypeFeedbackId::None());
void CallStoreIC(FeedbackVectorSlot slot, Handle<Object> name,
TypeFeedbackId id = TypeFeedbackId::None());
void CallLoadIC(FeedbackVectorSlot slot, Handle<Object> name);
void CallStoreIC(FeedbackVectorSlot slot, Handle<Object> name);
void CallKeyedStoreIC(FeedbackVectorSlot slot);
void SetFunctionPosition(FunctionLiteral* fun);
......
......@@ -2136,14 +2136,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
context()->Plug(eax);
}
void FullCodeGenerator::CallIC(Handle<Code> code,
TypeFeedbackId ast_id) {
ic_total_count_++;
__ call(code, RelocInfo::CODE_TARGET, ast_id);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
......
......@@ -2242,14 +2242,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
context()->Plug(v0);
}
void FullCodeGenerator::CallIC(Handle<Code> code,
TypeFeedbackId id) {
ic_total_count_++;
__ Call(code, RelocInfo::CODE_TARGET, id);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
......
......@@ -2241,14 +2241,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
context()->Plug(v0);
}
void FullCodeGenerator::CallIC(Handle<Code> code,
TypeFeedbackId id) {
ic_total_count_++;
__ Call(code, RelocInfo::CODE_TARGET, id);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
......
......@@ -2238,13 +2238,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
context()->Plug(r3);
}
void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) {
ic_total_count_++;
__ Call(code, RelocInfo::CODE_TARGET, ast_id);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
......
......@@ -2190,11 +2190,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
context()->Plug(r2);
}
void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) {
ic_total_count_++;
__ Call(code, RelocInfo::CODE_TARGET, ast_id);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
......
......@@ -2123,14 +2123,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
context()->Plug(rax);
}
void FullCodeGenerator::CallIC(Handle<Code> code,
TypeFeedbackId ast_id) {
ic_total_count_++;
__ call(code, RelocInfo::CODE_TARGET, ast_id);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
......
......@@ -2128,14 +2128,6 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
context()->Plug(eax);
}
void FullCodeGenerator::CallIC(Handle<Code> code,
TypeFeedbackId ast_id) {
ic_total_count_++;
__ call(code, RelocInfo::CODE_TARGET, ast_id);
}
// Code common for calls using the IC.
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
......
......@@ -794,7 +794,10 @@ class MacroAssembler: public Assembler {
void Drop(int element_count);
void Call(Label* target) { call(target); }
void Call(Handle<Code> target, RelocInfo::Mode rmode) { call(target, rmode); }
void Call(Handle<Code> target, RelocInfo::Mode rmode,
TypeFeedbackId id = TypeFeedbackId::None()) {
call(target, rmode, id);
}
void Jump(Handle<Code> target, RelocInfo::Mode rmode) { jmp(target, rmode); }
void Push(Register src) { push(src); }
void Push(const Operand& src) { push(src); }
......
......@@ -118,10 +118,7 @@ static void GetICCounts(JSFunction* function, int* ic_with_type_info_count,
function->shared()->code()->is_interpreter_trampoline_builtin();
vector->ComputeCounts(&with, &gen, &type_vector_ic_count, is_interpreted);
if (is_interpreted) {
DCHECK_EQ(*ic_total_count, 0);
*ic_total_count = type_vector_ic_count;
}
*ic_total_count += type_vector_ic_count;
*ic_with_type_info_count += with;
*ic_generic_count += gen;
......
......@@ -159,8 +159,6 @@ CompareOperationHint CompareOperationHintFromFeedback(int type_feedback) {
void TypeFeedbackVector::ComputeCounts(int* with_type_info, int* generic,
int* vector_ic_count,
bool code_is_interpreted) {
Object* uninitialized_sentinel =
TypeFeedbackVector::RawUninitializedSentinel(GetIsolate());
Object* megamorphic_sentinel =
*TypeFeedbackVector::MegamorphicSentinel(GetIsolate());
int with = 0;
......@@ -171,47 +169,58 @@ void TypeFeedbackVector::ComputeCounts(int* with_type_info, int* generic,
FeedbackVectorSlot slot = iter.Next();
FeedbackVectorSlotKind kind = iter.kind();
Object* obj = Get(slot);
if (kind == FeedbackVectorSlotKind::GENERAL) {
continue;
}
total++;
if (obj != uninitialized_sentinel) {
if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC ||
kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC) {
// If we are not running interpreted code, we need to ignore
// the special ic slots for binaryop/compare used by the
// interpreter.
// TODO(mvstanton): Remove code_is_interpreted when full code
// is retired from service.
if (!code_is_interpreted) continue;
DCHECK(obj->IsSmi());
int op_feedback = static_cast<int>(Smi::cast(obj)->value());
if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC) {
CompareOperationHint hint =
CompareOperationHintFromFeedback(op_feedback);
if (hint == CompareOperationHint::kAny) {
gen++;
} else if (hint != CompareOperationHint::kNone) {
with++;
}
} else {
DCHECK(kind == FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC);
BinaryOperationHint hint =
BinaryOperationHintFromFeedback(op_feedback);
if (hint == BinaryOperationHint::kAny) {
gen++;
} else if (hint != BinaryOperationHint::kNone) {
with++;
Object* const obj = Get(slot);
switch (kind) {
case FeedbackVectorSlotKind::CALL_IC:
case FeedbackVectorSlotKind::LOAD_IC:
case FeedbackVectorSlotKind::LOAD_GLOBAL_IC:
case FeedbackVectorSlotKind::KEYED_LOAD_IC:
case FeedbackVectorSlotKind::STORE_IC:
case FeedbackVectorSlotKind::KEYED_STORE_IC: {
if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) {
with++;
} else if (obj == megamorphic_sentinel) {
gen++;
}
total++;
break;
}
case FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC:
case FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC: {
// If we are not running interpreted code, we need to ignore the special
// IC slots for binaryop/compare used by the interpreter.
// TODO(mvstanton): Remove code_is_interpreted when full code is retired
// from service.
if (code_is_interpreted) {
int const feedback = Smi::cast(obj)->value();
if (kind == FeedbackVectorSlotKind::INTERPRETER_COMPARE_IC) {
CompareOperationHint hint =
CompareOperationHintFromFeedback(feedback);
if (hint == CompareOperationHint::kAny) {
gen++;
} else if (hint != CompareOperationHint::kNone) {
with++;
}
} else {
DCHECK_EQ(FeedbackVectorSlotKind::INTERPRETER_BINARYOP_IC, kind);
BinaryOperationHint hint =
BinaryOperationHintFromFeedback(feedback);
if (hint == BinaryOperationHint::kAny) {
gen++;
} else if (hint != BinaryOperationHint::kNone) {
with++;
}
}
total++;
}
} else if (obj->IsWeakCell() || obj->IsFixedArray() || obj->IsString()) {
with++;
} else if (obj == megamorphic_sentinel) {
gen++;
break;
}
case FeedbackVectorSlotKind::GENERAL:
break;
case FeedbackVectorSlotKind::INVALID:
case FeedbackVectorSlotKind::KINDS_NUMBER:
UNREACHABLE();
break;
}
}
......
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