}
-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();
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_;
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:
}
-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);
}
-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);
}
-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;
}
-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;
}
-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();
}
-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);
}
}
-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;
}
+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();
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);
// 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,
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);
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
Handle<Type>* combined);
Handle<Type> CountType(TypeFeedbackId id);
- void CountReceiverTypes(TypeFeedbackId id, SmallMapList* receiver_types);
Handle<Type> ClauseType(TypeFeedbackId id);
Expression* target = expr->target();
Property* prop = target->AsProperty();
if (prop != NULL) {
- prop->RecordTypeFeedback(oracle(), zone());
+ RECURSE(Visit(expr->target()));
expr->RecordTypeFeedback(oracle(), zone());
}
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()));