From: rossberg@chromium.org Date: Mon, 2 Dec 2013 13:49:32 +0000 (+0000) Subject: Move more logic from AST to oracle, pt 3 X-Git-Tag: upstream/4.7.83~11465 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bf3d84e3c86b9309655336e90e467b3c2c6dbf63;p=platform%2Fupstream%2Fv8.git Move more logic from AST to oracle, pt 3 Also eliminates remaining dependencies of type-info on AST. R=jkummerow@chromium.org BUG= Review URL: https://codereview.chromium.org/95033003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18194 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ast.cc b/src/ast.cc index 85482fabf..aeb767ef0 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -580,35 +580,6 @@ void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { } -void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle, - Zone* zone) { - Property* prop = target()->AsProperty(); - ASSERT(prop != NULL); - TypeFeedbackId id = AssignmentFeedbackId(); - is_uninitialized_ = oracle->StoreIsUninitialized(id); - if (is_uninitialized_) return; - - is_pre_monomorphic_ = oracle->StoreIsPreMonomorphic(id); - is_monomorphic_ = oracle->StoreIsMonomorphicNormal(id); - ASSERT(!is_pre_monomorphic_ || !is_monomorphic_); - receiver_types_.Clear(); - if (prop->key()->IsPropertyName()) { - Literal* lit_key = prop->key()->AsLiteral(); - ASSERT(lit_key != NULL && lit_key->value()->IsString()); - Handle name = Handle::cast(lit_key->value()); - oracle->StoreReceiverTypes(this, name, &receiver_types_); - } else if (is_monomorphic_) { - // Record receiver type for monomorphic keyed stores. - receiver_types_.Add(oracle->StoreMonomorphicReceiverType(id), zone); - store_mode_ = oracle->GetStoreMode(id); - } else if (oracle->StoreIsKeyedPolymorphic(id)) { - receiver_types_.Reserve(kMaxKeyedPolymorphism, zone); - oracle->CollectKeyedReceiverTypes(id, &receiver_types_); - store_mode_ = oracle->GetStoreMode(id); - } -} - - bool Call::ComputeTarget(Handle type, Handle name) { // If there is an interceptor, we can't compute the target for a direct call. if (type->has_named_interceptor()) return false; @@ -711,20 +682,21 @@ Handle Call::GetPrototypeForPrimitiveCheck( void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle, CallKind call_kind) { - is_monomorphic_ = oracle->CallIsMonomorphic(this); + is_monomorphic_ = oracle->CallIsMonomorphic(CallFeedbackId()); Property* property = expression()->AsProperty(); if (property == NULL) { // Function call. Specialize for monomorphic calls. - if (is_monomorphic_) target_ = oracle->GetCallTarget(this); + if (is_monomorphic_) target_ = oracle->GetCallTarget(CallFeedbackId()); } else if (property->key()->IsPropertyName()) { // Method call. Specialize for the receiver types seen at runtime. Literal* key = property->key()->AsLiteral(); ASSERT(key != NULL && key->value()->IsString()); Handle name = Handle::cast(key->value()); - check_type_ = oracle->GetCallCheckType(this); + check_type_ = oracle->GetCallCheckType(CallFeedbackId()); receiver_types_.Clear(); if (check_type_ == RECEIVER_MAP_CHECK) { - oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_); + oracle->CallReceiverTypes(CallFeedbackId(), + name, arguments()->length(), call_kind, &receiver_types_); is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0; } else { holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate()); @@ -745,17 +717,19 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle, } } else { if (is_monomorphic_) { - keyed_array_call_is_holey_ = oracle->KeyedArrayCallIsHoley(this); + keyed_array_call_is_holey_ = + oracle->KeyedArrayCallIsHoley(CallFeedbackId()); } } } void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) { - allocation_info_cell_ = oracle->GetCallNewAllocationInfoCell(this); - is_monomorphic_ = oracle->CallNewIsMonomorphic(this); + allocation_info_cell_ = + oracle->GetCallNewAllocationInfoCell(CallNewFeedbackId()); + is_monomorphic_ = oracle->CallNewIsMonomorphic(CallNewFeedbackId()); if (is_monomorphic_) { - target_ = oracle->GetCallNewTarget(this); + target_ = oracle->GetCallNewTarget(CallNewFeedbackId()); Object* value = allocation_info_cell_->value(); ASSERT(!value->IsTheHole()); if (value->IsAllocationSite()) { @@ -767,9 +741,9 @@ void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) { void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { - receiver_type_ = oracle->ObjectLiteralStoreIsMonomorphic(this) - ? oracle->GetObjectLiteralStoreMap(this) - : Handle::null(); + TypeFeedbackId id = key()->LiteralFeedbackId(); + receiver_type_ = oracle->ObjectLiteralStoreIsMonomorphic(id) + ? oracle->GetObjectLiteralStoreMap(id) : Handle::null(); } diff --git a/src/ast.h b/src/ast.h index 3febc16f2..0bbb90452 100644 --- a/src/ast.h +++ b/src/ast.h @@ -2142,7 +2142,6 @@ class Assignment V8_FINAL : public Expression { // Type feedback information. TypeFeedbackId AssignmentFeedbackId() { return reuse(id()); } - void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone); virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; } bool IsUninitialized() { return is_uninitialized_; } bool IsPreMonomorphic() { return is_pre_monomorphic_; } @@ -2155,6 +2154,10 @@ class Assignment V8_FINAL : public Expression { virtual KeyedAccessStoreMode GetStoreMode() V8_OVERRIDE { return store_mode_; } + 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_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; } protected: Assignment(Isolate* isolate, diff --git a/src/type-info.cc b/src/type-info.cc index 3cb56556c..6e3a4f6b7 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -197,30 +197,29 @@ bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) { } -bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { - Handle value = GetInfo(expr->CallFeedbackId()); +bool TypeFeedbackOracle::CallIsMonomorphic(TypeFeedbackId id) { + Handle value = GetInfo(id); return value->IsMap() || value->IsAllocationSite() || value->IsJSFunction() || value->IsSmi() || (value->IsCode() && Handle::cast(value)->ic_state() == MONOMORPHIC); } -bool TypeFeedbackOracle::KeyedArrayCallIsHoley(Call* expr) { - Handle value = GetInfo(expr->CallFeedbackId()); +bool TypeFeedbackOracle::KeyedArrayCallIsHoley(TypeFeedbackId id) { + Handle value = GetInfo(id); Handle code = Handle::cast(value); return KeyedArrayCallStub::IsHoley(code); } -bool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew* expr) { - Handle info = GetInfo(expr->CallNewFeedbackId()); +bool TypeFeedbackOracle::CallNewIsMonomorphic(TypeFeedbackId id) { + Handle info = GetInfo(id); return info->IsAllocationSite() || info->IsJSFunction(); } -bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic( - ObjectLiteral::Property* prop) { - Handle map_or_code = GetInfo(prop->key()->LiteralFeedbackId()); +bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic(TypeFeedbackId id) { + Handle map_or_code = GetInfo(id); return map_or_code->IsMap(); } @@ -285,22 +284,21 @@ void TypeFeedbackOracle::LoadReceiverTypes(TypeFeedbackId id, } -void TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr, +void TypeFeedbackOracle::StoreReceiverTypes(TypeFeedbackId id, Handle name, SmallMapList* types) { Code::Flags flags = Code::ComputeFlags( Code::HANDLER, MONOMORPHIC, kNoExtraICState, Code::NORMAL, Code::STORE_IC); - CollectReceiverTypes(expr->AssignmentFeedbackId(), name, flags, types); + CollectReceiverTypes(id, name, flags, types); } -void TypeFeedbackOracle::CallReceiverTypes(Call* expr, +void TypeFeedbackOracle::CallReceiverTypes(TypeFeedbackId id, Handle name, + int arity, CallKind call_kind, SmallMapList* types) { - int arity = expr->arguments()->length(); - // Note: Currently we do not take string extra ic data into account // here. ContextualMode contextual_mode = call_kind == CALL_AS_FUNCTION @@ -311,12 +309,12 @@ void TypeFeedbackOracle::CallReceiverTypes(Call* expr, Code::Flags flags = Code::ComputeMonomorphicFlags( Code::CALL_IC, extra_ic_state, OWN_MAP, Code::NORMAL, arity); - CollectReceiverTypes(expr->CallFeedbackId(), name, flags, types); + CollectReceiverTypes(id, name, flags, types); } -CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { - Handle value = GetInfo(expr->CallFeedbackId()); +CheckType TypeFeedbackOracle::GetCallCheckType(TypeFeedbackId id) { + Handle value = GetInfo(id); if (!value->IsSmi()) return RECEIVER_MAP_CHECK; CheckType check = static_cast(Smi::cast(*value)->value()); ASSERT(check != RECEIVER_MAP_CHECK); @@ -324,8 +322,8 @@ CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { } -Handle TypeFeedbackOracle::GetCallTarget(Call* expr) { - Handle info = GetInfo(expr->CallFeedbackId()); +Handle TypeFeedbackOracle::GetCallTarget(TypeFeedbackId id) { + Handle info = GetInfo(id); if (info->IsAllocationSite()) { return Handle(isolate_->global_context()->array_function()); } else { @@ -334,8 +332,8 @@ Handle TypeFeedbackOracle::GetCallTarget(Call* expr) { } -Handle TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) { - Handle info = GetInfo(expr->CallNewFeedbackId()); +Handle TypeFeedbackOracle::GetCallNewTarget(TypeFeedbackId id) { + Handle info = GetInfo(id); if (info->IsAllocationSite()) { return Handle(isolate_->global_context()->array_function()); } else { @@ -344,15 +342,15 @@ Handle TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) { } -Handle TypeFeedbackOracle::GetCallNewAllocationInfoCell(CallNew* expr) { - return GetInfoCell(expr->CallNewFeedbackId()); +Handle TypeFeedbackOracle::GetCallNewAllocationInfoCell( + TypeFeedbackId id) { + return GetInfoCell(id); } -Handle TypeFeedbackOracle::GetObjectLiteralStoreMap( - ObjectLiteral::Property* prop) { - ASSERT(ObjectLiteralStoreIsMonomorphic(prop)); - return Handle::cast(GetInfo(prop->key()->LiteralFeedbackId())); +Handle TypeFeedbackOracle::GetObjectLiteralStoreMap(TypeFeedbackId id) { + ASSERT(ObjectLiteralStoreIsMonomorphic(id)); + return Handle::cast(GetInfo(id)); } @@ -482,6 +480,28 @@ void TypeFeedbackOracle::KeyedPropertyReceiverTypes( } +void TypeFeedbackOracle::AssignmentReceiverTypes( + TypeFeedbackId id, Handle name, SmallMapList* receiver_types) { + receiver_types->Clear(); + StoreReceiverTypes(id, name, receiver_types); +} + + +void TypeFeedbackOracle::KeyedAssignmentReceiverTypes( + TypeFeedbackId id, SmallMapList* receiver_types, + KeyedAccessStoreMode* store_mode) { + receiver_types->Clear(); + if (StoreIsMonomorphicNormal(id)) { + // Record receiver type for monomorphic keyed stores. + receiver_types->Add(StoreMonomorphicReceiverType(id), zone()); + } else if (StoreIsKeyedPolymorphic(id)) { + receiver_types->Reserve(kMaxKeyedPolymorphism, zone()); + CollectKeyedReceiverTypes(id, receiver_types); + } + *store_mode = GetStoreMode(id); +} + + void TypeFeedbackOracle::CountReceiverTypes( TypeFeedbackId id, SmallMapList* receiver_types) { receiver_types->Clear(); diff --git a/src/type-info.h b/src/type-info.h index 05c76f2ee..a0d321584 100644 --- a/src/type-info.h +++ b/src/type-info.h @@ -218,20 +218,9 @@ enum StringStubFeedback { // Forward declarations. -// TODO(rossberg): these should all go away eventually. -class Assignment; -class Call; -class CallNew; -class CaseClause; class CompilationInfo; -class CountOperation; -class Expression; -class ForInStatement; class ICStub; -class Property; class SmallMapList; -class ObjectLiteral; -class ObjectLiteralProperty; class TypeFeedbackOracle: public ZoneObject { @@ -245,14 +234,14 @@ class TypeFeedbackOracle: public ZoneObject { 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); - bool StoreIsKeyedPolymorphic(TypeFeedbackId ast_id); - bool CallIsMonomorphic(Call* expr); - bool KeyedArrayCallIsHoley(Call* expr); - bool CallNewIsMonomorphic(CallNew* expr); - bool ObjectLiteralStoreIsMonomorphic(ObjectLiteralProperty* prop); + bool StoreIsUninitialized(TypeFeedbackId id); + bool StoreIsMonomorphicNormal(TypeFeedbackId id); + bool StoreIsPreMonomorphic(TypeFeedbackId id); + bool StoreIsKeyedPolymorphic(TypeFeedbackId id); + bool CallIsMonomorphic(TypeFeedbackId aid); + bool KeyedArrayCallIsHoley(TypeFeedbackId id); + bool CallNewIsMonomorphic(TypeFeedbackId id); + bool ObjectLiteralStoreIsMonomorphic(TypeFeedbackId id); // TODO(1571) We can't use ForInStatement::ForInType as the return value due // to various cycles in our headers. @@ -263,21 +252,22 @@ class TypeFeedbackOracle: public ZoneObject { Handle LoadMonomorphicReceiverType(TypeFeedbackId id); Handle StoreMonomorphicReceiverType(TypeFeedbackId id); - KeyedAccessStoreMode GetStoreMode(TypeFeedbackId ast_id); + KeyedAccessStoreMode GetStoreMode(TypeFeedbackId id); void LoadReceiverTypes(TypeFeedbackId id, Handle name, SmallMapList* types); - void StoreReceiverTypes(Assignment* expr, + void StoreReceiverTypes(TypeFeedbackId id, Handle name, SmallMapList* types); - void CallReceiverTypes(Call* expr, + void CallReceiverTypes(TypeFeedbackId id, Handle name, + int arity, CallKind call_kind, SmallMapList* types); - void CollectKeyedReceiverTypes(TypeFeedbackId ast_id, + void CollectKeyedReceiverTypes(TypeFeedbackId id, SmallMapList* types); - void CollectPolymorphicStoreReceiverTypes(TypeFeedbackId ast_id, + void CollectPolymorphicStoreReceiverTypes(TypeFeedbackId id, SmallMapList* types); void PropertyReceiverTypes(TypeFeedbackId id, @@ -287,6 +277,12 @@ class TypeFeedbackOracle: public ZoneObject { void KeyedPropertyReceiverTypes(TypeFeedbackId id, SmallMapList* receiver_types, bool* is_string); + void AssignmentReceiverTypes(TypeFeedbackId id, + Handle name, + SmallMapList* receiver_types); + void KeyedAssignmentReceiverTypes(TypeFeedbackId id, + SmallMapList* receiver_types, + KeyedAccessStoreMode* store_mode); void CountReceiverTypes(TypeFeedbackId id, SmallMapList* receiver_types); @@ -296,12 +292,12 @@ class TypeFeedbackOracle: public ZoneObject { void CollectPolymorphicMaps(Handle code, SmallMapList* types); - CheckType GetCallCheckType(Call* expr); - Handle GetCallTarget(Call* expr); - Handle GetCallNewTarget(CallNew* expr); - Handle GetCallNewAllocationInfoCell(CallNew* expr); + CheckType GetCallCheckType(TypeFeedbackId id); + Handle GetCallTarget(TypeFeedbackId id); + Handle GetCallNewTarget(TypeFeedbackId id); + Handle GetCallNewAllocationInfoCell(TypeFeedbackId id); - Handle GetObjectLiteralStoreMap(ObjectLiteralProperty* prop); + Handle GetObjectLiteralStoreMap(TypeFeedbackId id); bool LoadIsBuiltin(TypeFeedbackId id, Builtins::Name builtin_id); bool LoadIsStub(TypeFeedbackId id, ICStub* stub); @@ -332,12 +328,12 @@ class TypeFeedbackOracle: public ZoneObject { Isolate* isolate() const { return isolate_; } private: - void CollectReceiverTypes(TypeFeedbackId ast_id, + void CollectReceiverTypes(TypeFeedbackId id, Handle name, Code::Flags flags, SmallMapList* types); - void SetInfo(TypeFeedbackId ast_id, Object* target); + void SetInfo(TypeFeedbackId id, Object* target); void BuildDictionary(Handle code); void GetRelocInfos(Handle code, ZoneList* infos); @@ -350,10 +346,10 @@ class TypeFeedbackOracle: public ZoneObject { // Returns an element from the backing store. Returns undefined if // there is no information. - Handle GetInfo(TypeFeedbackId ast_id); + Handle GetInfo(TypeFeedbackId id); // Return the cell that contains type feedback. - Handle GetInfoCell(TypeFeedbackId ast_id); + Handle GetInfoCell(TypeFeedbackId id); private: Handle native_context_; diff --git a/src/typing.cc b/src/typing.cc index d9420adb8..8487c05eb 100644 --- a/src/typing.cc +++ b/src/typing.cc @@ -387,31 +387,35 @@ void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { void AstTyper::VisitAssignment(Assignment* expr) { - // TODO(rossberg): Can we clean this up? - if (expr->is_compound()) { - // Collect type feedback. - Expression* target = expr->target(); - Property* prop = target->AsProperty(); - if (prop != NULL) { - RECURSE(Visit(expr->target())); - expr->RecordTypeFeedback(oracle(), zone()); - } - - RECURSE(Visit(expr->binary_operation())); - - NarrowType(expr, expr->binary_operation()->bounds()); - } else { - // Collect type feedback. - if (expr->target()->IsProperty()) { - expr->RecordTypeFeedback(oracle(), zone()); + // Collect type feedback. + Property* prop = expr->target()->AsProperty(); + if (prop != NULL) { + TypeFeedbackId id = expr->AssignmentFeedbackId(); + expr->set_is_uninitialized(oracle()->StoreIsUninitialized(id)); + if (!expr->IsUninitialized()) { + expr->set_is_pre_monomorphic(oracle()->StoreIsPreMonomorphic(id)); + expr->set_is_monomorphic(oracle()->StoreIsMonomorphicNormal(id)); + ASSERT(!expr->IsPreMonomorphic() || !expr->IsMonomorphic()); + if (prop->key()->IsPropertyName()) { + Literal* lit_key = prop->key()->AsLiteral(); + ASSERT(lit_key != NULL && lit_key->value()->IsString()); + Handle name = Handle::cast(lit_key->value()); + oracle()->AssignmentReceiverTypes(id, name, expr->GetReceiverTypes()); + } else { + KeyedAccessStoreMode store_mode; + oracle()->KeyedAssignmentReceiverTypes( + id, expr->GetReceiverTypes(), &store_mode); + expr->set_store_mode(store_mode); + } } - - RECURSE(Visit(expr->target())); - RECURSE(Visit(expr->value())); - - NarrowType(expr, expr->value()->bounds()); } + Expression* rhs = + expr->is_compound() ? expr->binary_operation() : expr->value(); + RECURSE(Visit(expr->target())); + RECURSE(Visit(rhs)); + NarrowType(expr, rhs->bounds()); + VariableProxy* proxy = expr->target()->AsVariableProxy(); if (proxy != NULL && proxy->var()->IsStackAllocated()) { store_.Seq(variable_index(proxy->var()), Effect(expr->bounds()));