From: fschneider@chromium.org Date: Mon, 19 Mar 2012 15:54:37 +0000 (+0000) Subject: Insert explicit deoptimization for named loads that have "uninitialized" type feedback. X-Git-Tag: upstream/4.7.83~17062 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e081a3bfba5033ef8c91c7f85b0cfc96a8bec0af;p=platform%2Fupstream%2Fv8.git 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 --- diff --git a/src/ast.cc b/src/ast.cc index 629e4722b..4b6ae680a 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -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()) { diff --git a/src/ast.h b/src/ast.h index 0ca3f0c09..b827302eb 100644 --- a/src/ast.h +++ b/src/ast.h @@ -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 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; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index c28730b17..358256cbf 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -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 name = expr->key()->AsLiteral()->handle(); HValue* context = environment()->LookupContext(); diff --git a/src/type-info.cc b/src/type-info.cc index 78fb47a16..159be6a5a 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -77,6 +77,17 @@ Handle TypeFeedbackOracle::GetInfo(unsigned ast_id) { } +bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) { + Handle map_or_code = GetInfo(expr->id()); + if (map_or_code->IsMap()) return false; + if (map_or_code->IsCode()) { + Handle code = Handle::cast(map_or_code); + return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; + } + return false; +} + + bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) { Handle map_or_code = GetInfo(expr->id()); if (map_or_code->IsMap()) return true; @@ -649,7 +660,7 @@ void TypeFeedbackOracle::ProcessRelocInfos(ZoneList* infos) { SetInfo(ast_id, map); } } - } else if (target->ic_state() == MEGAMORPHIC) { + } else { SetInfo(ast_id, target); } break; diff --git a/src/type-info.h b/src/type-info.h index 2e2ce10f9..d461331be 100644 --- a/src/type-info.h +++ b/src/type-info.h @@ -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); diff --git a/test/cctest/test-log-stack-tracer.cc b/test/cctest/test-log-stack-tracer.cc index f536e6b19..8b2348cd5 100644 --- a/test/cctest/test-log-stack-tracer.cc +++ b/test/cctest/test-log-stack-tracer.cc @@ -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])); }