Commit b974978e authored by rossberg@chromium.org's avatar rossberg@chromium.org

Move more logic from AST to oracle, pt 2

(More to follow)

R=jkummerow@chromium.org
BUG=

Review URL: https://codereview.chromium.org/95163002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18130 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 73725966
...@@ -580,37 +580,6 @@ void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { ...@@ -580,37 +580,6 @@ void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
} }
void Property::RecordTypeFeedback(TypeFeedbackOracle* oracle,
Zone* zone) {
// Record type feedback from the oracle in the AST.
is_uninitialized_ = oracle->LoadIsUninitialized(this);
if (is_uninitialized_) return;
is_pre_monomorphic_ = oracle->LoadIsPreMonomorphic(this);
is_monomorphic_ = oracle->LoadIsMonomorphicNormal(this);
ASSERT(!is_pre_monomorphic_ || !is_monomorphic_);
receiver_types_.Clear();
if (key()->IsPropertyName()) {
FunctionPrototypeStub proto_stub(Code::LOAD_IC);
if (oracle->LoadIsStub(this, &proto_stub)) {
is_function_prototype_ = true;
} else {
Literal* lit_key = key()->AsLiteral();
ASSERT(lit_key != NULL && lit_key->value()->IsString());
Handle<String> name = Handle<String>::cast(lit_key->value());
oracle->LoadReceiverTypes(this, name, &receiver_types_);
}
} else if (oracle->LoadIsBuiltin(this, Builtins::kKeyedLoadIC_String)) {
is_string_access_ = true;
} else if (is_monomorphic_) {
receiver_types_.Add(oracle->LoadMonomorphicReceiverType(this), zone);
} else if (oracle->LoadIsPolymorphic(this)) {
receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
oracle->CollectKeyedReceiverTypes(PropertyFeedbackId(), &receiver_types_);
}
}
void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle, void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle,
Zone* zone) { Zone* zone) {
Property* prop = target()->AsProperty(); Property* prop = target()->AsProperty();
......
...@@ -1691,7 +1691,6 @@ class Property V8_FINAL : public Expression { ...@@ -1691,7 +1691,6 @@ class Property V8_FINAL : public Expression {
bool IsFunctionPrototype() const { return is_function_prototype_; } bool IsFunctionPrototype() const { return is_function_prototype_; }
// Type feedback information. // Type feedback information.
void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone);
virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; } virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; }
virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE { virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE {
return &receiver_types_; return &receiver_types_;
...@@ -1704,6 +1703,12 @@ class Property V8_FINAL : public Expression { ...@@ -1704,6 +1703,12 @@ class Property V8_FINAL : public Expression {
bool HasNoTypeInformation() { bool HasNoTypeInformation() {
return is_uninitialized_ || is_pre_monomorphic_; return is_uninitialized_ || is_pre_monomorphic_;
} }
void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
void set_is_monomorphic(bool b) { is_monomorphic_ = b; }
void set_is_pre_monomorphic(bool b) { is_pre_monomorphic_ = b; }
void set_is_string_access(bool b) { is_string_access_ = b; }
void set_is_function_prototype(bool b) { is_function_prototype_ = b; }
TypeFeedbackId PropertyFeedbackId() { return reuse(id()); } TypeFeedbackId PropertyFeedbackId() { return reuse(id()); }
protected: protected:
......
...@@ -99,8 +99,8 @@ Handle<Cell> TypeFeedbackOracle::GetInfoCell( ...@@ -99,8 +99,8 @@ Handle<Cell> TypeFeedbackOracle::GetInfoCell(
} }
bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) { bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) {
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId()); Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsMap()) return false; if (map_or_code->IsMap()) return false;
if (map_or_code->IsCode()) { if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code); Handle<Code> code = Handle<Code>::cast(map_or_code);
...@@ -110,8 +110,8 @@ bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) { ...@@ -110,8 +110,8 @@ bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) {
} }
bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) { bool TypeFeedbackOracle::LoadIsMonomorphicNormal(TypeFeedbackId id) {
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId()); Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsMap()) return true; if (map_or_code->IsMap()) return true;
if (map_or_code->IsCode()) { if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code); Handle<Code> code = Handle<Code>::cast(map_or_code);
...@@ -128,8 +128,8 @@ bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) { ...@@ -128,8 +128,8 @@ bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
} }
bool TypeFeedbackOracle::LoadIsPreMonomorphic(Property* expr) { bool TypeFeedbackOracle::LoadIsPreMonomorphic(TypeFeedbackId id) {
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId()); Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsCode()) { if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code); Handle<Code> code = Handle<Code>::cast(map_or_code);
return code->is_inline_cache_stub() && code->ic_state() == PREMONOMORPHIC; return code->is_inline_cache_stub() && code->ic_state() == PREMONOMORPHIC;
...@@ -138,8 +138,8 @@ bool TypeFeedbackOracle::LoadIsPreMonomorphic(Property* expr) { ...@@ -138,8 +138,8 @@ bool TypeFeedbackOracle::LoadIsPreMonomorphic(Property* expr) {
} }
bool TypeFeedbackOracle::LoadIsPolymorphic(Property* expr) { bool TypeFeedbackOracle::LoadIsPolymorphic(TypeFeedbackId id) {
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId()); Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsCode()) { if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code); Handle<Code> code = Handle<Code>::cast(map_or_code);
return code->is_keyed_load_stub() && code->ic_state() == POLYMORPHIC; return code->is_keyed_load_stub() && code->ic_state() == POLYMORPHIC;
...@@ -233,9 +233,9 @@ byte TypeFeedbackOracle::ForInType(TypeFeedbackId id) { ...@@ -233,9 +233,9 @@ byte TypeFeedbackOracle::ForInType(TypeFeedbackId id) {
} }
Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) { Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(TypeFeedbackId id) {
ASSERT(LoadIsMonomorphicNormal(expr)); ASSERT(LoadIsMonomorphicNormal(id));
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId()); Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsCode()) { if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code); Handle<Code> code = Handle<Code>::cast(map_or_code);
Map* map = code->FindFirstMap()->CurrentMapForDeprecated(); Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
...@@ -275,13 +275,13 @@ KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode( ...@@ -275,13 +275,13 @@ KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
} }
void TypeFeedbackOracle::LoadReceiverTypes(Property* expr, void TypeFeedbackOracle::LoadReceiverTypes(TypeFeedbackId id,
Handle<String> name, Handle<String> name,
SmallMapList* types) { SmallMapList* types) {
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
Code::HANDLER, MONOMORPHIC, Code::kNoExtraICState, Code::HANDLER, MONOMORPHIC, Code::kNoExtraICState,
Code::NORMAL, Code::LOAD_IC); Code::NORMAL, Code::LOAD_IC);
CollectReceiverTypes(expr->PropertyFeedbackId(), name, flags, types); CollectReceiverTypes(id, name, flags, types);
} }
...@@ -353,14 +353,14 @@ Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap( ...@@ -353,14 +353,14 @@ Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(
} }
bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) { bool TypeFeedbackOracle::LoadIsBuiltin(
return *GetInfo(expr->PropertyFeedbackId()) == TypeFeedbackId id, Builtins::Name builtin) {
isolate_->builtins()->builtin(id); return *GetInfo(id) == isolate_->builtins()->builtin(builtin);
} }
bool TypeFeedbackOracle::LoadIsStub(Property* expr, ICStub* stub) { bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) {
Handle<Object> object = GetInfo(expr->PropertyFeedbackId()); Handle<Object> object = GetInfo(id);
if (!object->IsCode()) return false; if (!object->IsCode()) return false;
Handle<Code> code = Handle<Code>::cast(object); Handle<Code> code = Handle<Code>::cast(object);
if (!code->is_load_stub()) return false; if (!code->is_load_stub()) return false;
...@@ -456,6 +456,33 @@ Handle<Type> TypeFeedbackOracle::CountType(TypeFeedbackId id) { ...@@ -456,6 +456,33 @@ Handle<Type> TypeFeedbackOracle::CountType(TypeFeedbackId id) {
} }
void TypeFeedbackOracle::PropertyReceiverTypes(
TypeFeedbackId id, Handle<String> name,
SmallMapList* receiver_types, bool* is_prototype) {
receiver_types->Clear();
FunctionPrototypeStub proto_stub(Code::LOAD_IC);
*is_prototype = LoadIsStub(id, &proto_stub);
if (!*is_prototype) {
LoadReceiverTypes(id, name, receiver_types);
}
}
void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string) {
receiver_types->Clear();
*is_string = false;
if (LoadIsBuiltin(id, Builtins::kKeyedLoadIC_String)) {
*is_string = true;
} else if (LoadIsMonomorphicNormal(id)) {
receiver_types->Add(LoadMonomorphicReceiverType(id), zone());
} else if (LoadIsPolymorphic(id)) {
receiver_types->Reserve(kMaxKeyedPolymorphism, zone());
CollectKeyedReceiverTypes(id, receiver_types);
}
}
void TypeFeedbackOracle::CountReceiverTypes( void TypeFeedbackOracle::CountReceiverTypes(
TypeFeedbackId id, SmallMapList* receiver_types) { TypeFeedbackId id, SmallMapList* receiver_types) {
receiver_types->Clear(); receiver_types->Clear();
......
...@@ -241,10 +241,10 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -241,10 +241,10 @@ class TypeFeedbackOracle: public ZoneObject {
Isolate* isolate, Isolate* isolate,
Zone* zone); Zone* zone);
bool LoadIsMonomorphicNormal(Property* expr); bool LoadIsMonomorphicNormal(TypeFeedbackId id);
bool LoadIsUninitialized(Property* expr); bool LoadIsUninitialized(TypeFeedbackId id);
bool LoadIsPreMonomorphic(Property* expr); bool LoadIsPreMonomorphic(TypeFeedbackId id);
bool LoadIsPolymorphic(Property* expr); bool LoadIsPolymorphic(TypeFeedbackId id);
bool StoreIsUninitialized(TypeFeedbackId ast_id); bool StoreIsUninitialized(TypeFeedbackId ast_id);
bool StoreIsMonomorphicNormal(TypeFeedbackId ast_id); bool StoreIsMonomorphicNormal(TypeFeedbackId ast_id);
bool StoreIsPreMonomorphic(TypeFeedbackId ast_id); bool StoreIsPreMonomorphic(TypeFeedbackId ast_id);
...@@ -260,12 +260,12 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -260,12 +260,12 @@ class TypeFeedbackOracle: public ZoneObject {
// be possible. // be possible.
byte ForInType(TypeFeedbackId id); byte ForInType(TypeFeedbackId id);
Handle<Map> LoadMonomorphicReceiverType(Property* expr); Handle<Map> LoadMonomorphicReceiverType(TypeFeedbackId id);
Handle<Map> StoreMonomorphicReceiverType(TypeFeedbackId id); Handle<Map> StoreMonomorphicReceiverType(TypeFeedbackId id);
KeyedAccessStoreMode GetStoreMode(TypeFeedbackId ast_id); KeyedAccessStoreMode GetStoreMode(TypeFeedbackId ast_id);
void LoadReceiverTypes(Property* expr, void LoadReceiverTypes(TypeFeedbackId id,
Handle<String> name, Handle<String> name,
SmallMapList* types); SmallMapList* types);
void StoreReceiverTypes(Assignment* expr, void StoreReceiverTypes(Assignment* expr,
...@@ -280,6 +280,16 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -280,6 +280,16 @@ class TypeFeedbackOracle: public ZoneObject {
void CollectPolymorphicStoreReceiverTypes(TypeFeedbackId ast_id, void CollectPolymorphicStoreReceiverTypes(TypeFeedbackId ast_id,
SmallMapList* types); SmallMapList* types);
void PropertyReceiverTypes(TypeFeedbackId id,
Handle<String> name,
SmallMapList* receiver_types,
bool* is_prototype);
void KeyedPropertyReceiverTypes(TypeFeedbackId id,
SmallMapList* receiver_types,
bool* is_string);
void CountReceiverTypes(TypeFeedbackId id,
SmallMapList* receiver_types);
static bool CanRetainOtherContext(Map* map, Context* native_context); static bool CanRetainOtherContext(Map* map, Context* native_context);
static bool CanRetainOtherContext(JSFunction* function, static bool CanRetainOtherContext(JSFunction* function,
Context* native_context); Context* native_context);
...@@ -293,8 +303,8 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -293,8 +303,8 @@ class TypeFeedbackOracle: public ZoneObject {
Handle<Map> GetObjectLiteralStoreMap(ObjectLiteralProperty* prop); Handle<Map> GetObjectLiteralStoreMap(ObjectLiteralProperty* prop);
bool LoadIsBuiltin(Property* expr, Builtins::Name id); bool LoadIsBuiltin(TypeFeedbackId id, Builtins::Name builtin_id);
bool LoadIsStub(Property* expr, ICStub* stub); bool LoadIsStub(TypeFeedbackId id, ICStub* stub);
// TODO(1571) We can't use ToBooleanStub::Types as the return value because // TODO(1571) We can't use ToBooleanStub::Types as the return value because
// of various cycles in our headers. Death to tons of implementations in // of various cycles in our headers. Death to tons of implementations in
...@@ -315,7 +325,6 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -315,7 +325,6 @@ class TypeFeedbackOracle: public ZoneObject {
Handle<Type>* combined); Handle<Type>* combined);
Handle<Type> CountType(TypeFeedbackId id); Handle<Type> CountType(TypeFeedbackId id);
void CountReceiverTypes(TypeFeedbackId id, SmallMapList* receiver_types);
Handle<Type> ClauseType(TypeFeedbackId id); Handle<Type> ClauseType(TypeFeedbackId id);
......
...@@ -393,7 +393,7 @@ void AstTyper::VisitAssignment(Assignment* expr) { ...@@ -393,7 +393,7 @@ void AstTyper::VisitAssignment(Assignment* expr) {
Expression* target = expr->target(); Expression* target = expr->target();
Property* prop = target->AsProperty(); Property* prop = target->AsProperty();
if (prop != NULL) { if (prop != NULL) {
prop->RecordTypeFeedback(oracle(), zone()); RECURSE(Visit(expr->target()));
expr->RecordTypeFeedback(oracle(), zone()); expr->RecordTypeFeedback(oracle(), zone());
} }
...@@ -437,7 +437,27 @@ void AstTyper::VisitThrow(Throw* expr) { ...@@ -437,7 +437,27 @@ void AstTyper::VisitThrow(Throw* expr) {
void AstTyper::VisitProperty(Property* expr) { void AstTyper::VisitProperty(Property* expr) {
// Collect type feedback. // Collect type feedback.
expr->RecordTypeFeedback(oracle(), zone()); TypeFeedbackId id = expr->PropertyFeedbackId();
expr->set_is_uninitialized(oracle()->LoadIsUninitialized(id));
if (!expr->IsUninitialized()) {
expr->set_is_pre_monomorphic(oracle()->LoadIsPreMonomorphic(id));
expr->set_is_monomorphic(oracle()->LoadIsMonomorphicNormal(id));
ASSERT(!expr->IsPreMonomorphic() || !expr->IsMonomorphic());
if (expr->key()->IsPropertyName()) {
Literal* lit_key = expr->key()->AsLiteral();
ASSERT(lit_key != NULL && lit_key->value()->IsString());
Handle<String> name = Handle<String>::cast(lit_key->value());
bool is_prototype;
oracle()->PropertyReceiverTypes(
id, name, expr->GetReceiverTypes(), &is_prototype);
expr->set_is_function_prototype(is_prototype);
} else {
bool is_string;
oracle()->KeyedPropertyReceiverTypes(
id, expr->GetReceiverTypes(), &is_string);
expr->set_is_string_access(is_string);
}
}
RECURSE(Visit(expr->obj())); RECURSE(Visit(expr->obj()));
RECURSE(Visit(expr->key())); RECURSE(Visit(expr->key()));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment