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
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()) {
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;
key_(key),
pos_(pos),
is_monomorphic_(false),
+ is_uninitialized_(false),
is_array_length_(false),
is_string_length_(false),
is_string_access_(false),
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;
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();
}
+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;
SetInfo(ast_id, map);
}
}
- } else if (target->ic_state() == MEGAMORPHIC) {
+ } else {
SetInfo(ast_id, target);
}
break;
Isolate* isolate);
bool LoadIsMonomorphicNormal(Property* expr);
+ bool LoadIsUninitialized(Property* expr);
bool LoadIsMegamorphicWithTypeInfo(Property* expr);
bool StoreIsMonomorphicNormal(Expression* expr);
bool StoreIsMegamorphicWithTypeInfo(Expression* expr);
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);
// 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]));
}