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) {
}
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,
Zone* zone) {
Property* prop = target()->AsProperty();
......
......@@ -1691,7 +1691,6 @@ class Property V8_FINAL : public Expression {
bool IsFunctionPrototype() const { return is_function_prototype_; }
// Type feedback information.
void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone);
virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; }
virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE {
return &receiver_types_;
......@@ -1704,6 +1703,12 @@ class Property V8_FINAL : public Expression {
bool HasNoTypeInformation() {
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()); }
protected:
......
......@@ -99,8 +99,8 @@ Handle<Cell> TypeFeedbackOracle::GetInfoCell(
}
bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) {
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) {
Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsMap()) return false;
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
......@@ -110,8 +110,8 @@ bool TypeFeedbackOracle::LoadIsUninitialized(Property* expr) {
}
bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
bool TypeFeedbackOracle::LoadIsMonomorphicNormal(TypeFeedbackId id) {
Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsMap()) return true;
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
......@@ -128,8 +128,8 @@ bool TypeFeedbackOracle::LoadIsMonomorphicNormal(Property* expr) {
}
bool TypeFeedbackOracle::LoadIsPreMonomorphic(Property* expr) {
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
bool TypeFeedbackOracle::LoadIsPreMonomorphic(TypeFeedbackId id) {
Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
return code->is_inline_cache_stub() && code->ic_state() == PREMONOMORPHIC;
......@@ -138,8 +138,8 @@ bool TypeFeedbackOracle::LoadIsPreMonomorphic(Property* expr) {
}
bool TypeFeedbackOracle::LoadIsPolymorphic(Property* expr) {
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
bool TypeFeedbackOracle::LoadIsPolymorphic(TypeFeedbackId id) {
Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
return code->is_keyed_load_stub() && code->ic_state() == POLYMORPHIC;
......@@ -233,9 +233,9 @@ byte TypeFeedbackOracle::ForInType(TypeFeedbackId id) {
}
Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(Property* expr) {
ASSERT(LoadIsMonomorphicNormal(expr));
Handle<Object> map_or_code = GetInfo(expr->PropertyFeedbackId());
Handle<Map> TypeFeedbackOracle::LoadMonomorphicReceiverType(TypeFeedbackId id) {
ASSERT(LoadIsMonomorphicNormal(id));
Handle<Object> map_or_code = GetInfo(id);
if (map_or_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(map_or_code);
Map* map = code->FindFirstMap()->CurrentMapForDeprecated();
......@@ -275,13 +275,13 @@ KeyedAccessStoreMode TypeFeedbackOracle::GetStoreMode(
}
void TypeFeedbackOracle::LoadReceiverTypes(Property* expr,
void TypeFeedbackOracle::LoadReceiverTypes(TypeFeedbackId id,
Handle<String> name,
SmallMapList* types) {
Code::Flags flags = Code::ComputeFlags(
Code::HANDLER, MONOMORPHIC, Code::kNoExtraICState,
Code::NORMAL, Code::LOAD_IC);
CollectReceiverTypes(expr->PropertyFeedbackId(), name, flags, types);
CollectReceiverTypes(id, name, flags, types);
}
......@@ -353,14 +353,14 @@ Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(
}
bool TypeFeedbackOracle::LoadIsBuiltin(Property* expr, Builtins::Name id) {
return *GetInfo(expr->PropertyFeedbackId()) ==
isolate_->builtins()->builtin(id);
bool TypeFeedbackOracle::LoadIsBuiltin(
TypeFeedbackId id, Builtins::Name builtin) {
return *GetInfo(id) == isolate_->builtins()->builtin(builtin);
}
bool TypeFeedbackOracle::LoadIsStub(Property* expr, ICStub* stub) {
Handle<Object> object = GetInfo(expr->PropertyFeedbackId());
bool TypeFeedbackOracle::LoadIsStub(TypeFeedbackId id, ICStub* stub) {
Handle<Object> object = GetInfo(id);
if (!object->IsCode()) return false;
Handle<Code> code = Handle<Code>::cast(object);
if (!code->is_load_stub()) return false;
......@@ -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(
TypeFeedbackId id, SmallMapList* receiver_types) {
receiver_types->Clear();
......
......@@ -241,10 +241,10 @@ class TypeFeedbackOracle: public ZoneObject {
Isolate* isolate,
Zone* zone);
bool LoadIsMonomorphicNormal(Property* expr);
bool LoadIsUninitialized(Property* expr);
bool LoadIsPreMonomorphic(Property* expr);
bool LoadIsPolymorphic(Property* expr);
bool LoadIsMonomorphicNormal(TypeFeedbackId id);
bool LoadIsUninitialized(TypeFeedbackId id);
bool LoadIsPreMonomorphic(TypeFeedbackId id);
bool LoadIsPolymorphic(TypeFeedbackId id);
bool StoreIsUninitialized(TypeFeedbackId ast_id);
bool StoreIsMonomorphicNormal(TypeFeedbackId ast_id);
bool StoreIsPreMonomorphic(TypeFeedbackId ast_id);
......@@ -260,12 +260,12 @@ class TypeFeedbackOracle: public ZoneObject {
// be possible.
byte ForInType(TypeFeedbackId id);
Handle<Map> LoadMonomorphicReceiverType(Property* expr);
Handle<Map> LoadMonomorphicReceiverType(TypeFeedbackId id);
Handle<Map> StoreMonomorphicReceiverType(TypeFeedbackId id);
KeyedAccessStoreMode GetStoreMode(TypeFeedbackId ast_id);
void LoadReceiverTypes(Property* expr,
void LoadReceiverTypes(TypeFeedbackId id,
Handle<String> name,
SmallMapList* types);
void StoreReceiverTypes(Assignment* expr,
......@@ -280,6 +280,16 @@ class TypeFeedbackOracle: public ZoneObject {
void CollectPolymorphicStoreReceiverTypes(TypeFeedbackId ast_id,
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(JSFunction* function,
Context* native_context);
......@@ -293,8 +303,8 @@ class TypeFeedbackOracle: public ZoneObject {
Handle<Map> GetObjectLiteralStoreMap(ObjectLiteralProperty* prop);
bool LoadIsBuiltin(Property* expr, Builtins::Name id);
bool LoadIsStub(Property* expr, ICStub* stub);
bool LoadIsBuiltin(TypeFeedbackId id, Builtins::Name builtin_id);
bool LoadIsStub(TypeFeedbackId id, ICStub* stub);
// 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
......@@ -315,7 +325,6 @@ class TypeFeedbackOracle: public ZoneObject {
Handle<Type>* combined);
Handle<Type> CountType(TypeFeedbackId id);
void CountReceiverTypes(TypeFeedbackId id, SmallMapList* receiver_types);
Handle<Type> ClauseType(TypeFeedbackId id);
......
......@@ -393,7 +393,7 @@ void AstTyper::VisitAssignment(Assignment* expr) {
Expression* target = expr->target();
Property* prop = target->AsProperty();
if (prop != NULL) {
prop->RecordTypeFeedback(oracle(), zone());
RECURSE(Visit(expr->target()));
expr->RecordTypeFeedback(oracle(), zone());
}
......@@ -437,7 +437,27 @@ void AstTyper::VisitThrow(Throw* expr) {
void AstTyper::VisitProperty(Property* expr) {
// 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->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