OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 5789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5800 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 5800 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
5801 } else { | 5801 } else { |
5802 set_current_block(NULL); | 5802 set_current_block(NULL); |
5803 } | 5803 } |
5804 } | 5804 } |
5805 | 5805 |
5806 | 5806 |
5807 static bool ComputeReceiverTypes(Expression* expr, | 5807 static bool ComputeReceiverTypes(Expression* expr, |
5808 HValue* receiver, | 5808 HValue* receiver, |
5809 SmallMapList** t, | 5809 SmallMapList** t, |
5810 PropertyAccessType access_type, | |
5810 Zone* zone) { | 5811 Zone* zone) { |
5811 SmallMapList* types = expr->GetReceiverTypes(); | 5812 SmallMapList* types = expr->GetReceiverTypes(); |
5812 *t = types; | 5813 *t = types; |
5813 bool monomorphic = expr->IsMonomorphic(); | 5814 bool monomorphic = expr->IsMonomorphic(); |
5814 if (types != NULL && receiver->HasMonomorphicJSObjectType()) { | 5815 Isolate* isolate = zone->isolate(); |
5815 Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); | 5816 if (types != NULL) { |
5816 types->FilterForPossibleTransitions(root_map); | 5817 if (receiver->HasMonomorphicJSObjectType()) { |
5818 Map* root_map = receiver->GetMonomorphicJSObjectMap()->FindRootMap(); | |
5819 types->FilterForPossibleTransitions(root_map); | |
5820 } else if (types->is_empty() && | |
5821 receiver->IsConstant() && | |
5822 HConstant::cast(receiver)->handle(isolate)->IsJSObject()) { | |
5823 Handle<Map> map(Handle<JSObject>::cast( | |
5824 HConstant::cast(receiver)->handle(isolate))->map()); | |
5825 | |
5826 if (access_type != STORE || !map->is_observed()) { | |
Toon Verwaest
2014/04/09 14:08:16
So this case will still trigger for observed maps,
p.antonov
2014/04/09 14:16:19
When it is a load - yes (since loads should not be
| |
5827 types->Add(map, zone); | |
5828 } | |
5829 } | |
5817 monomorphic = types->length() == 1; | 5830 monomorphic = types->length() == 1; |
5818 } | 5831 } |
5819 return monomorphic && CanInlinePropertyAccess( | 5832 return monomorphic && CanInlinePropertyAccess( |
5820 IC::MapToType<Type>(types->first(), zone)); | 5833 IC::MapToType<Type>(types->first(), zone)); |
5821 } | 5834 } |
5822 | 5835 |
5823 | 5836 |
5824 static bool AreStringTypes(SmallMapList* types) { | 5837 static bool AreStringTypes(SmallMapList* types) { |
5825 for (int i = 0; i < types->length(); i++) { | 5838 for (int i = 0; i < types->length(); i++) { |
5826 if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; | 5839 if (types->at(i)->instance_type() >= FIRST_NONSTRING_TYPE) return false; |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6513 HValue* obj, | 6526 HValue* obj, |
6514 HValue* key, | 6527 HValue* key, |
6515 HValue* val, | 6528 HValue* val, |
6516 Expression* expr, | 6529 Expression* expr, |
6517 PropertyAccessType access_type, | 6530 PropertyAccessType access_type, |
6518 bool* has_side_effects) { | 6531 bool* has_side_effects) { |
6519 ASSERT(!expr->IsPropertyName()); | 6532 ASSERT(!expr->IsPropertyName()); |
6520 HInstruction* instr = NULL; | 6533 HInstruction* instr = NULL; |
6521 | 6534 |
6522 SmallMapList* types; | 6535 SmallMapList* types; |
6523 bool monomorphic = ComputeReceiverTypes(expr, obj, &types, zone()); | 6536 bool monomorphic = ComputeReceiverTypes(expr, |
6537 obj, | |
6538 &types, | |
6539 access_type, | |
6540 zone()); | |
6524 | 6541 |
6525 bool force_generic = false; | 6542 bool force_generic = false; |
6526 if (access_type == STORE && | 6543 if (access_type == STORE && |
6527 (monomorphic || (types != NULL && !types->is_empty()))) { | 6544 (monomorphic || (types != NULL && !types->is_empty()))) { |
6528 // Stores can't be mono/polymorphic if their prototype chain has dictionary | 6545 // Stores can't be mono/polymorphic if their prototype chain has dictionary |
6529 // elements. However a receiver map that has dictionary elements itself | 6546 // elements. However a receiver map that has dictionary elements itself |
6530 // should be left to normal mono/poly behavior (the other maps may benefit | 6547 // should be left to normal mono/poly behavior (the other maps may benefit |
6531 // from highly optimized stores). | 6548 // from highly optimized stores). |
6532 for (int i = 0; i < types->length(); i++) { | 6549 for (int i = 0; i < types->length(); i++) { |
6533 Handle<Map> current_map = types->at(i); | 6550 Handle<Map> current_map = types->at(i); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6652 HInstruction* HOptimizedGraphBuilder::BuildNamedAccess( | 6669 HInstruction* HOptimizedGraphBuilder::BuildNamedAccess( |
6653 PropertyAccessType access, | 6670 PropertyAccessType access, |
6654 BailoutId ast_id, | 6671 BailoutId ast_id, |
6655 BailoutId return_id, | 6672 BailoutId return_id, |
6656 Expression* expr, | 6673 Expression* expr, |
6657 HValue* object, | 6674 HValue* object, |
6658 Handle<String> name, | 6675 Handle<String> name, |
6659 HValue* value, | 6676 HValue* value, |
6660 bool is_uninitialized) { | 6677 bool is_uninitialized) { |
6661 SmallMapList* types; | 6678 SmallMapList* types; |
6662 ComputeReceiverTypes(expr, object, &types, zone()); | 6679 ComputeReceiverTypes(expr, object, &types, access, zone()); |
6663 ASSERT(types != NULL); | 6680 ASSERT(types != NULL); |
6664 | 6681 |
6665 if (types->length() > 0) { | 6682 if (types->length() > 0) { |
6666 PropertyAccessInfo info(this, access, ToType(types->first()), name); | 6683 PropertyAccessInfo info(this, access, ToType(types->first()), name); |
6667 if (!info.CanAccessAsMonomorphic(types)) { | 6684 if (!info.CanAccessAsMonomorphic(types)) { |
6668 HandlePolymorphicNamedFieldAccess( | 6685 HandlePolymorphicNamedFieldAccess( |
6669 access, ast_id, return_id, object, value, types, name); | 6686 access, ast_id, return_id, object, value, types, name); |
6670 return NULL; | 6687 return NULL; |
6671 } | 6688 } |
6672 | 6689 |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7968 Expression* callee = expr->expression(); | 7985 Expression* callee = expr->expression(); |
7969 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 7986 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
7970 HInstruction* call = NULL; | 7987 HInstruction* call = NULL; |
7971 | 7988 |
7972 Property* prop = callee->AsProperty(); | 7989 Property* prop = callee->AsProperty(); |
7973 if (prop != NULL) { | 7990 if (prop != NULL) { |
7974 CHECK_ALIVE(VisitForValue(prop->obj())); | 7991 CHECK_ALIVE(VisitForValue(prop->obj())); |
7975 HValue* receiver = Top(); | 7992 HValue* receiver = Top(); |
7976 | 7993 |
7977 SmallMapList* types; | 7994 SmallMapList* types; |
7978 ComputeReceiverTypes(expr, receiver, &types, zone()); | 7995 ComputeReceiverTypes(expr, receiver, &types, LOAD, zone()); |
7979 | 7996 |
7980 if (prop->key()->IsPropertyName() && types->length() > 0) { | 7997 if (prop->key()->IsPropertyName() && types->length() > 0) { |
7981 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 7998 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
7982 PropertyAccessInfo info(this, LOAD, ToType(types->first()), name); | 7999 PropertyAccessInfo info(this, LOAD, ToType(types->first()), name); |
7983 if (!info.CanAccessAsMonomorphic(types)) { | 8000 if (!info.CanAccessAsMonomorphic(types)) { |
7984 HandlePolymorphicCallNamed(expr, receiver, types, name); | 8001 HandlePolymorphicCallNamed(expr, receiver, types, name); |
7985 return; | 8002 return; |
7986 } | 8003 } |
7987 } | 8004 } |
7988 | 8005 |
(...skipping 3513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11502 if (ShouldProduceTraceOutput()) { | 11519 if (ShouldProduceTraceOutput()) { |
11503 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11520 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11504 } | 11521 } |
11505 | 11522 |
11506 #ifdef DEBUG | 11523 #ifdef DEBUG |
11507 graph_->Verify(false); // No full verify. | 11524 graph_->Verify(false); // No full verify. |
11508 #endif | 11525 #endif |
11509 } | 11526 } |
11510 | 11527 |
11511 } } // namespace v8::internal | 11528 } } // namespace v8::internal |
OLD | NEW |