Insert explicit deoptimization for named loads that have "uninitialized" type feedback.

We already do this for binary-ops, unary-ops and comparisons. Typefeedback for named loads can now also
be in "uninitialized" state which means that the corresponding load IC was never executed.
Review URL: https://chromiumcodereview.appspot.com/9722041

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11087 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
fschneider@chromium.org 2012-03-19 15:54:37 +00:00
parent 56c75c387a
commit e081a3bfba
6 changed files with 27 additions and 2 deletions

View File

@ -399,6 +399,9 @@ bool FunctionDeclaration::IsInlineable() const {
void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
// Record type feedback from the oracle in the AST.
is_uninitialized_ = oracle->LoadIsUninitialized(this);
if (is_uninitialized_) return;
is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
receiver_types_.Clear();
if (key()->IsPropertyName()) {

View File

@ -1527,6 +1527,7 @@ class Property: public Expression {
virtual bool IsMonomorphic() { return is_monomorphic_; }
virtual SmallMapList* GetReceiverTypes() { return &receiver_types_; }
bool IsArrayLength() { return is_array_length_; }
bool IsUninitialized() { return is_uninitialized_; }
protected:
template<class> friend class AstNodeFactory;
@ -1540,6 +1541,7 @@ class Property: public Expression {
key_(key),
pos_(pos),
is_monomorphic_(false),
is_uninitialized_(false),
is_array_length_(false),
is_string_length_(false),
is_string_access_(false),
@ -1552,6 +1554,7 @@ class Property: public Expression {
SmallMapList receiver_types_;
bool is_monomorphic_ : 1;
bool is_uninitialized_ : 1;
bool is_array_length_ : 1;
bool is_string_length_ : 1;
bool is_string_access_ : 1;

View File

@ -4523,6 +4523,10 @@ HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
HInstruction* HGraphBuilder::BuildLoadNamedGeneric(HValue* obj,
Property* expr) {
if (expr->IsUninitialized()) {
AddInstruction(new(zone()) HSoftDeoptimize);
current_block()->MarkAsDeoptimizing();
}
ASSERT(expr->key()->IsPropertyName());
Handle<Object> name = expr->key()->AsLiteral()->handle();
HValue* context = environment()->LookupContext();

View File

@ -77,6 +77,17 @@ Handle<Object> TypeFeedbackOracle::GetInfo(unsigned ast_id) {
}
bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) {
Handle<Object> map_or_code = GetInfo(expr->id());
if (map_or_code->IsMap()) return false;
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED;
}
return false;
}
bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
Handle<Object> map_or_code = GetInfo(expr->id());
if (map_or_code->IsMap()) return true;
@ -649,7 +660,7 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList<RelocInfo>* infos) {
SetInfo(ast_id, map);
}
}
} else if (target->ic_state() == MEGAMORPHIC) {
} else {
SetInfo(ast_id, target);
}
break;

View File

@ -239,6 +239,7 @@ class TypeFeedbackOracle BASE_EMBEDDED {
Isolate* isolate);
bool LoadIsMonomorphicNormal(Property* expr);
bool LoadIsUninitialized(Property* expr);
bool LoadIsMegamorphicWithTypeInfo(Property* expr);
bool StoreIsMonomorphicNormal(Expression* expr);
bool StoreIsMegamorphicWithTypeInfo(Expression* expr);

View File

@ -277,7 +277,9 @@ static void CreateTraceCallerFunction(const char* func_name,
TEST(CFromJSStackTrace) {
// BUG(1303) Inlining of JSFuncDoTrace() in JSTrace below breaks this test.
i::FLAG_use_inlining = false;
// This test does not work with --always-opt because we don't replace the code
// in the JSFunction at deoptimization in that case.
i::FLAG_always_opt = false;
TickSample sample;
InitTraceEnv(&sample);
@ -307,6 +309,7 @@ TEST(CFromJSStackTrace) {
// Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
int base = 0;
CHECK_GT(sample.frames_count, base + 1);
CHECK(IsAddressWithinFuncCode("JSFuncDoTrace", sample.stack[base + 0]));
CHECK(IsAddressWithinFuncCode("JSTrace", sample.stack[base + 1]));
}