Revision: 16131
Author: [email protected]
Date: Fri Aug 9 05:50:42 2013
Log: Deoptimization is easier to diagnose when there is a text reason.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/22339018
http://code.google.com/p/v8/source/detail?r=16131
Modified:
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/code-stubs-hydrogen.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/hydrogen.h
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/mips/lithium-codegen-mips.cc
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Aug 9
01:24:29 2013
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Aug 9
05:50:42 2013
@@ -5694,6 +5694,8 @@
if (info()->IsStub() && type == Deoptimizer::EAGER) {
type = Deoptimizer::LAZY;
}
+
+ Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
DeoptimizeIf(al, instr->environment(), type);
}
=======================================
--- /branches/bleeding_edge/src/code-stubs-hydrogen.cc Tue Aug 6 06:34:51
2013
+++ /branches/bleeding_edge/src/code-stubs-hydrogen.cc Fri Aug 9 05:50:42
2013
@@ -92,7 +92,7 @@
}
~ArrayContextChecker() {
- checker_.ElseDeopt();
+ checker_.ElseDeopt("Array constructor called from different
context");
checker_.End();
}
private:
@@ -233,7 +233,7 @@
IfBuilder builder(this);
builder.IfNot<HCompareObjectEqAndBranch, HValue*>(undefined,
undefined);
builder.Then();
- builder.ElseDeopt();
+ builder.ElseDeopt("Forced deopt to runtime");
return undefined;
}
@@ -387,7 +387,7 @@
length));
}
- checker.ElseDeopt();
+ checker.ElseDeopt("Uninitialized boilerplate literals");
checker.End();
return environment()->Pop();
@@ -434,7 +434,7 @@
}
environment()->Push(object);
- checker.ElseDeopt();
+ checker.ElseDeopt("Uninitialized boilerplate in fast clone");
checker.End();
return environment()->Pop();
@@ -844,7 +844,7 @@
IfBuilder builder(this);
builder.If<HCompareObjectEqAndBranch>(cell_contents, value);
builder.Then();
- builder.ElseDeopt();
+ builder.ElseDeopt("Unexpected cell contents in constant global store");
builder.End();
} else {
// Load the payload of the global parameter cell. A hole indicates
that the
@@ -854,7 +854,7 @@
HValue* hole_value = Add<HConstant>(hole);
builder.If<HCompareObjectEqAndBranch>(cell_contents, hole_value);
builder.Then();
- builder.Deopt();
+ builder.Deopt("Unexpected cell contents in global store");
builder.Else();
Add<HStoreNamedField>(cell, access, value);
builder.End();
@@ -878,7 +878,8 @@
if (FLAG_trace_elements_transitions) {
// Tracing elements transitions is the job of the runtime.
- Add<HDeoptimize>(Deoptimizer::EAGER);
+ Add<HDeoptimize>("Deopt due to --trace-elements-transitions",
+ Deoptimizer::EAGER);
} else {
info()->MarkAsSavesCallerDoubles();
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri Aug 9 04:21:03
2013
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri Aug 9 05:50:42
2013
@@ -1248,19 +1248,23 @@
class HDeoptimize: public HTemplateInstruction<0> {
public:
- DECLARE_INSTRUCTION_FACTORY_P1(HDeoptimize, Deoptimizer::BailoutType);
+ DECLARE_INSTRUCTION_FACTORY_P2(HDeoptimize, const char*,
+ Deoptimizer::BailoutType);
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
+ const char* reason() const { return reason_; }
Deoptimizer::BailoutType type() { return type_; }
DECLARE_CONCRETE_INSTRUCTION(Deoptimize)
private:
- explicit HDeoptimize(Deoptimizer::BailoutType type) : type_(type) {}
+ explicit HDeoptimize(const char* reason, Deoptimizer::BailoutType type)
+ : reason_(reason), type_(type) {}
+ const char* reason_;
Deoptimizer::BailoutType type_;
};
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Fri Aug 9 04:21:03 2013
+++ /branches/bleeding_edge/src/hydrogen.cc Fri Aug 9 05:50:42 2013
@@ -824,14 +824,14 @@
}
-void HGraphBuilder::IfBuilder::Deopt() {
+void HGraphBuilder::IfBuilder::Deopt(const char* reason) {
ASSERT(did_then_);
if (did_else_) {
deopt_else_ = true;
} else {
deopt_then_ = true;
}
- builder_->Add<HDeoptimize>(Deoptimizer::EAGER);
+ builder_->Add<HDeoptimize>(reason, Deoptimizer::EAGER);
}
@@ -1034,9 +1034,9 @@
void HGraphBuilder::FinishExitWithHardDeoptimization(
- HBasicBlock* continuation) {
+ const char* reason, HBasicBlock* continuation) {
PadEnvironmentForContinuation(current_block(), continuation);
- Add<HDeoptimize>(Deoptimizer::EAGER);
+ Add<HDeoptimize>(reason, Deoptimizer::EAGER);
if (no_side_effects_scope_count_ > 0) {
current_block()->GotoNoSimulate(continuation);
} else {
@@ -1108,7 +1108,7 @@
IfBuilder key_checker(this);
key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT);
key_checker.Then();
- key_checker.ElseDeopt();
+ key_checker.ElseDeopt("Key out of capacity range");
key_checker.End();
HValue* new_capacity = BuildNewElementsCapacity(key);
@@ -1264,7 +1264,7 @@
negative_checker.Then();
HInstruction* result = AddExternalArrayElementAccess(
external_elements, key, val, bounds_check, elements_kind,
is_store);
- negative_checker.ElseDeopt();
+ negative_checker.ElseDeopt("Negative key encountered");
length_checker.End();
return result;
} else {
@@ -1751,7 +1751,7 @@
// emitted below is the actual monomorphic map.
BuildCheckMap(value, type->Classes().Current());
} else {
- if_nil.Deopt();
+ if_nil.Deopt("Too many undetectable types");
}
}
@@ -3347,7 +3347,7 @@
if (stmt->switch_type() == SwitchStatement::SMI_SWITCH) {
if (!clause->compare_type()->Is(Type::Smi())) {
- Add<HDeoptimize>(Deoptimizer::SOFT);
+ Add<HDeoptimize>("Non-smi switch type", Deoptimizer::SOFT);
}
HCompareNumericAndBranch* compare_ =
@@ -4736,7 +4736,7 @@
// know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC.
if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
- FinishExitWithHardDeoptimization(join);
+ FinishExitWithHardDeoptimization("All known maps handled", join);
} else {
HInstruction* instr = BuildStoreNamedGeneric(object, name,
store_value);
instr->set_position(position);
@@ -4784,7 +4784,10 @@
HValue* value = environment()->ExpressionStackAt(0);
HValue* object = environment()->ExpressionStackAt(1);
- if (expr->IsUninitialized()) Add<HDeoptimize>(Deoptimizer::SOFT);
+ if (expr->IsUninitialized()) {
+ Add<HDeoptimize>("Insufficient type feedback for property
assignment",
+ Deoptimizer::SOFT);
+ }
return BuildStoreNamed(expr, expr->id(), expr->position(),
expr->AssignmentId(), prop, object, value,
value);
} else {
@@ -4830,7 +4833,8 @@
}
builder.Then();
builder.Else();
- Add<HDeoptimize>(Deoptimizer::EAGER);
+ Add<HDeoptimize>("Constant global variable assignment",
+ Deoptimizer::EAGER);
builder.End();
}
HInstruction* instr =
@@ -5271,7 +5275,8 @@
Handle<String> name,
Property* expr) {
if (expr->IsUninitialized()) {
- Add<HDeoptimize>(Deoptimizer::SOFT);
+ Add<HDeoptimize>("Insufficient feedback for generic named load",
+ Deoptimizer::SOFT);
}
HValue* context = environment()->context();
return new(zone()) HLoadNamedGeneric(context, object, name);
@@ -5588,7 +5593,8 @@
// Deopt if none of the cases matched.
NoObservableSideEffectsScope scope(this);
- FinishExitWithHardDeoptimization(join);
+ FinishExitWithHardDeoptimization("Unknown type in polymorphic element
access",
+ join);
set_current_block(join);
return is_store ? NULL : Pop();
}
@@ -5624,12 +5630,14 @@
} else {
if (is_store) {
if (expr->IsAssignment() && expr->AsAssignment()->IsUninitialized())
{
- Add<HDeoptimize>(Deoptimizer::SOFT);
+ Add<HDeoptimize>("Insufficient feedback for keyed store",
+ Deoptimizer::SOFT);
}
instr = BuildStoreKeyedGeneric(obj, key, val);
} else {
if (expr->AsProperty()->IsUninitialized()) {
- Add<HDeoptimize>(Deoptimizer::SOFT);
+ Add<HDeoptimize>("Insufficient feedback for keyed load",
+ Deoptimizer::SOFT);
}
instr = BuildLoadKeyedGeneric(obj, key);
}
@@ -6076,7 +6084,7 @@
// that the environment stack matches the depth on deopt that it
otherwise
// would have had after a successful call.
Drop(argument_count - (ast_context()->IsEffect() ? 0 : 1));
- FinishExitWithHardDeoptimization(join);
+ FinishExitWithHardDeoptimization("Unknown map in polymorphic call",
join);
} else {
HValue* context = environment()->context();
HCallNamed* call = new(zone()) HCallNamed(context, name,
argument_count);
@@ -7636,12 +7644,14 @@
}
if (left_type->Is(Type::None())) {
- Add<HDeoptimize>(Deoptimizer::SOFT);
+ Add<HDeoptimize>("Insufficient type feedback for left side",
+ Deoptimizer::SOFT);
// TODO(rossberg): we should be able to get rid of non-continuous
defaults.
left_type = handle(Type::Any(), isolate());
}
if (right_type->Is(Type::None())) {
- Add<HDeoptimize>(Deoptimizer::SOFT);
+ Add<HDeoptimize>("Insufficient type feedback for right side",
+ Deoptimizer::SOFT);
right_type = handle(Type::Any(), isolate());
}
HInstruction* instr = NULL;
@@ -7991,7 +8001,8 @@
// Cases handled below depend on collected type feedback. They should
// soft deoptimize when there is no type feedback.
if (combined_type->Is(Type::None())) {
- Add<HDeoptimize>(Deoptimizer::SOFT);
+ Add<HDeoptimize>("insufficient type feedback for combined type",
+ Deoptimizer::SOFT);
combined_type = left_type = right_type = handle(Type::Any(),
isolate());
}
=======================================
--- /branches/bleeding_edge/src/hydrogen.h Tue Aug 6 06:34:51 2013
+++ /branches/bleeding_edge/src/hydrogen.h Fri Aug 9 05:50:42 2013
@@ -1270,7 +1270,8 @@
void PushAndAdd(HInstruction* instr);
- void FinishExitWithHardDeoptimization(HBasicBlock* continuation);
+ void FinishExitWithHardDeoptimization(const char* reason,
+ HBasicBlock* continuation);
void AddIncrementCounter(StatsCounter* counter,
HValue* context);
@@ -1374,10 +1375,10 @@
void Else();
void End();
- void Deopt();
- void ElseDeopt() {
+ void Deopt(const char* reason);
+ void ElseDeopt(const char* reason) {
Else();
- Deopt();
+ Deopt(reason);
}
void Return(HValue* value);
@@ -1582,13 +1583,13 @@
template<>
inline HInstruction* HGraphBuilder::AddUncasted<HDeoptimize>(
- Deoptimizer::BailoutType type) {
+ const char* reason, Deoptimizer::BailoutType type) {
if (type == Deoptimizer::SOFT) {
isolate()->counters()->soft_deopts_requested()->Increment();
if (FLAG_always_opt) return NULL;
}
if (current_block()->IsDeoptimizing()) return NULL;
- HDeoptimize* instr = New<HDeoptimize>(type);
+ HDeoptimize* instr = New<HDeoptimize>(reason, type);
AddInstruction(instr);
if (type == Deoptimizer::SOFT) {
isolate()->counters()->soft_deopts_inserted()->Increment();
@@ -1601,8 +1602,8 @@
template<>
inline HDeoptimize* HGraphBuilder::Add<HDeoptimize>(
- Deoptimizer::BailoutType type) {
- return static_cast<HDeoptimize*>(AddUncasted<HDeoptimize>(type));
+ const char* reason, Deoptimizer::BailoutType type) {
+ return static_cast<HDeoptimize*>(AddUncasted<HDeoptimize>(reason, type));
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Aug 9
01:24:29 2013
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri Aug 9
05:50:42 2013
@@ -6390,6 +6390,7 @@
if (info()->IsStub() && type == Deoptimizer::EAGER) {
type = Deoptimizer::LAZY;
}
+ Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
DeoptimizeIf(no_condition, instr->environment(), type);
}
=======================================
--- /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Fri Aug 9
01:24:29 2013
+++ /branches/bleeding_edge/src/mips/lithium-codegen-mips.cc Fri Aug 9
05:50:42 2013
@@ -5708,6 +5708,8 @@
if (info()->IsStub() && type == Deoptimizer::EAGER) {
type = Deoptimizer::LAZY;
}
+
+ Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
DeoptimizeIf(al, instr->environment(), type, zero_reg,
Operand(zero_reg));
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri Aug 9
01:24:29 2013
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri Aug 9
05:50:42 2013
@@ -5459,6 +5459,8 @@
if (info()->IsStub() && type == Deoptimizer::EAGER) {
type = Deoptimizer::LAZY;
}
+
+ Comment(";;; deoptimize: %s", instr->hydrogen()->reason());
DeoptimizeIf(no_condition, instr->environment(), type);
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.