Chromium Code Reviews| Index: src/ast.cc |
| diff --git a/src/ast.cc b/src/ast.cc |
| index 9d8624ca1b179b239314388eab61e9d4a8062f74..f3141382c3aa9e406e1ffb664e21e91b4f2a2945 100644 |
| --- a/src/ast.cc |
| +++ b/src/ast.cc |
| @@ -594,6 +594,19 @@ void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { |
| } |
| +int Call::ConsumeFeedbackSlots(Isolate* isolate, int current_slot) { |
| + CallType call_type = GetCallType(isolate); |
| + int slots = 0; |
| + if (call_type == LOOKUP_SLOT_CALL || call_type == OTHER_CALL) { |
| + // Call only uses a slot in some cases. |
| + slots++; |
| + first_feedback_slot_ = current_slot; |
| + } |
| + |
| + return current_slot + slots; |
| +} |
| + |
| + |
| Call::CallType Call::GetCallType(Isolate* isolate) const { |
| VariableProxy* proxy = expression()->AsVariableProxy(); |
| if (proxy != NULL) { |
| @@ -605,7 +618,6 @@ Call::CallType Call::GetCallType(Isolate* isolate) const { |
| return LOOKUP_SLOT_CALL; |
| } |
| } |
| - |
| Property* property = expression()->AsProperty(); |
| return property != NULL ? PROPERTY_CALL : OTHER_CALL; |
| } |
| @@ -712,43 +724,52 @@ Handle<JSObject> Call::GetPrototypeForPrimitiveCheck( |
| void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| - is_monomorphic_ = oracle->CallIsMonomorphic(CallFeedbackId()); |
| - Property* property = expression()->AsProperty(); |
| - if (property == NULL) { |
| - // Function call. Specialize for monomorphic calls. |
| - 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<String> name = Handle<String>::cast(key->value()); |
| - check_type_ = oracle->GetCallCheckType(CallFeedbackId()); |
| - receiver_types_.Clear(); |
| - if (check_type_ == RECEIVER_MAP_CHECK) { |
| - oracle->CallReceiverTypes(CallFeedbackId(), |
| - name, arguments()->length(), &receiver_types_); |
| - is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0; |
| - } else { |
| - holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate()); |
| - receiver_types_.Add(handle(holder_->map()), oracle->zone()); |
| - } |
| + if (CallFeedbackSlot() >= 0) { |
|
Benedikt Meurer
2014/01/24 11:29:54
!= kInvalidFeedbackSlot
mvstanton
2014/01/30 15:13:41
Done.
|
| + // We stored feedback in the type vector. |
| + is_monomorphic_ = oracle->CallIsMonomorphic(CallFeedbackSlot()); |
| + ASSERT(expression()->AsProperty() == NULL); |
| + if (is_monomorphic_) target_ = oracle->GetCallTarget(CallFeedbackSlot()); |
| + } else { |
| + // We stored feedback in an IC. |
| + is_monomorphic_ = oracle->CallIsMonomorphic(CallFeedbackId()); |
| + Property* property = expression()->AsProperty(); |
| + if (property != NULL) { |
| + 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<String> name = Handle<String>::cast(key->value()); |
| + check_type_ = oracle->GetCallCheckType(CallFeedbackId()); |
| + receiver_types_.Clear(); |
| + if (check_type_ == RECEIVER_MAP_CHECK) { |
| + oracle->CallReceiverTypes(CallFeedbackId(), |
| + name, arguments()->length(), |
| + &receiver_types_); |
| + is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0; |
| + } else { |
| + holder_ = GetPrototypeForPrimitiveCheck(check_type_, |
| + oracle->isolate()); |
| + receiver_types_.Add(handle(holder_->map()), oracle->zone()); |
| + } |
| #ifdef ENABLE_SLOW_ASSERTS |
| - if (FLAG_enable_slow_asserts) { |
| - int length = receiver_types_.length(); |
| - for (int i = 0; i < length; i++) { |
| - Handle<Map> map = receiver_types_.at(i); |
| - ASSERT(!map.is_null() && *map != NULL); |
| - } |
| - } |
| + if (FLAG_enable_slow_asserts) { |
| + int length = receiver_types_.length(); |
| + for (int i = 0; i < length; i++) { |
| + Handle<Map> map = receiver_types_.at(i); |
| + ASSERT(!map.is_null() && *map != NULL); |
| + } |
| + } |
| #endif |
| - if (is_monomorphic_) { |
| - Handle<Map> map = receiver_types_.first(); |
| - is_monomorphic_ = ComputeTarget(map, name); |
| - } |
| - } else { |
| - if (is_monomorphic_) { |
| - keyed_array_call_is_holey_ = |
| - oracle->KeyedArrayCallIsHoley(CallFeedbackId()); |
| + if (is_monomorphic_) { |
| + Handle<Map> map = receiver_types_.first(); |
| + is_monomorphic_ = ComputeTarget(map, name); |
| + } |
| + } else { |
| + if (is_monomorphic_) { |
| + keyed_array_call_is_holey_ = |
| + oracle->KeyedArrayCallIsHoley(CallFeedbackId()); |
| + } |
| + } |
| } |
| } |
| } |
| @@ -756,10 +777,10 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) { |
| allocation_site_ = |
| - oracle->GetCallNewAllocationSite(CallNewFeedbackId()); |
| - is_monomorphic_ = oracle->CallNewIsMonomorphic(CallNewFeedbackId()); |
| + oracle->GetCallNewAllocationSite(CallNewFeedbackSlot()); |
| + is_monomorphic_ = oracle->CallNewIsMonomorphic(CallNewFeedbackSlot()); |
| if (is_monomorphic_) { |
| - target_ = oracle->GetCallNewTarget(CallNewFeedbackId()); |
| + target_ = oracle->GetCallNewTarget(CallNewFeedbackSlot()); |
| if (!allocation_site_.is_null()) { |
| elements_kind_ = allocation_site_->GetElementsKind(); |
| } |
| @@ -1161,10 +1182,14 @@ CaseClause::CaseClause(Zone* zone, |
| #define REGULAR_NODE(NodeType) \ |
| void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ |
| increase_node_count(); \ |
| + increase_feedback_slots(NodeType::MinimumFeedbackSlots(), \ |
| + NodeType::MaximumFeedbackSlots()); \ |
| } |
| #define DONT_OPTIMIZE_NODE(NodeType) \ |
| void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ |
| increase_node_count(); \ |
| + increase_feedback_slots(NodeType::MinimumFeedbackSlots(), \ |
| + NodeType::MaximumFeedbackSlots()); \ |
| set_dont_optimize_reason(k##NodeType); \ |
| add_flag(kDontInline); \ |
| add_flag(kDontSelfOptimize); \ |
| @@ -1172,12 +1197,15 @@ CaseClause::CaseClause(Zone* zone, |
| #define DONT_SELFOPTIMIZE_NODE(NodeType) \ |
| void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ |
| increase_node_count(); \ |
| + increase_feedback_slots(NodeType::MinimumFeedbackSlots(), \ |
| + NodeType::MaximumFeedbackSlots()); \ |
| add_flag(kDontSelfOptimize); \ |
| } |
| #define DONT_CACHE_NODE(NodeType) \ |
| void AstConstructionVisitor::Visit##NodeType(NodeType* node) { \ |
| increase_node_count(); \ |
| - set_dont_optimize_reason(k##NodeType); \ |
| + increase_feedback_slots(NodeType::MinimumFeedbackSlots(), \ |
| + NodeType::MaximumFeedbackSlots()); \ |
| add_flag(kDontInline); \ |
| add_flag(kDontSelfOptimize); \ |
| add_flag(kDontCache); \ |
| @@ -1241,6 +1269,8 @@ DONT_CACHE_NODE(ModuleLiteral) |
| void AstConstructionVisitor::VisitCallRuntime(CallRuntime* node) { |
| increase_node_count(); |
| + increase_feedback_slots(CallRuntime::MinimumFeedbackSlots(), |
| + CallRuntime::MaximumFeedbackSlots()); |
| if (node->is_jsruntime()) { |
| // Don't try to inline JS runtime calls because we don't (currently) even |
| // optimize them. |