[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}
This commit is contained in:
parent
3902043324
commit
5ef1bddf80
@ -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++;
|
||||
}
|
||||
} else 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++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FeedbackVectorSlotKind::GENERAL:
|
||||
break;
|
||||
case FeedbackVectorSlotKind::INVALID:
|
||||
case FeedbackVectorSlotKind::KINDS_NUMBER:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user