OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 5971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5982 if (!IsLoad() && IsProperty() && IsReadOnly()) { | 5982 if (!IsLoad() && IsProperty() && IsReadOnly()) { |
5983 return false; | 5983 return false; |
5984 } | 5984 } |
5985 | 5985 |
5986 if (IsData()) { | 5986 if (IsData()) { |
5987 // Construct the object field access. | 5987 // Construct the object field access. |
5988 int index = GetLocalFieldIndexFromMap(map); | 5988 int index = GetLocalFieldIndexFromMap(map); |
5989 access_ = HObjectAccess::ForField(map, index, representation(), name_); | 5989 access_ = HObjectAccess::ForField(map, index, representation(), name_); |
5990 | 5990 |
5991 // Load field map for heap objects. | 5991 // Load field map for heap objects. |
5992 LoadFieldMaps(map); | 5992 return LoadFieldMaps(map); |
5993 } else if (IsAccessorConstant()) { | 5993 } else if (IsAccessorConstant()) { |
5994 Handle<Object> accessors = GetAccessorsFromMap(map); | 5994 Handle<Object> accessors = GetAccessorsFromMap(map); |
5995 if (!accessors->IsAccessorPair()) return false; | 5995 if (!accessors->IsAccessorPair()) return false; |
5996 Object* raw_accessor = | 5996 Object* raw_accessor = |
5997 IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter() | 5997 IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter() |
5998 : Handle<AccessorPair>::cast(accessors)->setter(); | 5998 : Handle<AccessorPair>::cast(accessors)->setter(); |
5999 if (!raw_accessor->IsJSFunction()) return false; | 5999 if (!raw_accessor->IsJSFunction()) return false; |
6000 Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor)); | 6000 Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor)); |
6001 if (accessor->shared()->IsApiFunction()) { | 6001 if (accessor->shared()->IsApiFunction()) { |
6002 CallOptimization call_optimization(accessor); | 6002 CallOptimization call_optimization(accessor); |
6003 if (call_optimization.is_simple_api_call()) { | 6003 if (call_optimization.is_simple_api_call()) { |
6004 CallOptimization::HolderLookup holder_lookup; | 6004 CallOptimization::HolderLookup holder_lookup; |
6005 api_holder_ = | 6005 api_holder_ = |
6006 call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup); | 6006 call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup); |
6007 } | 6007 } |
6008 } | 6008 } |
6009 accessor_ = accessor; | 6009 accessor_ = accessor; |
6010 } else if (IsDataConstant()) { | 6010 } else if (IsDataConstant()) { |
6011 constant_ = GetConstantFromMap(map); | 6011 constant_ = GetConstantFromMap(map); |
6012 } | 6012 } |
6013 | 6013 |
6014 return true; | 6014 return true; |
6015 } | 6015 } |
6016 | 6016 |
6017 | 6017 |
6018 void HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( | 6018 bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( |
6019 Handle<Map> map) { | 6019 Handle<Map> map) { |
6020 // Clear any previously collected field maps/type. | 6020 // Clear any previously collected field maps/type. |
6021 field_maps_.Clear(); | 6021 field_maps_.Clear(); |
6022 field_type_ = HType::Tagged(); | 6022 field_type_ = HType::Tagged(); |
6023 | 6023 |
6024 // Figure out the field type from the accessor map. | 6024 // Figure out the field type from the accessor map. |
6025 Handle<HeapType> field_type = GetFieldTypeFromMap(map); | 6025 Handle<HeapType> field_type = GetFieldTypeFromMap(map); |
6026 | 6026 |
6027 // Collect the (stable) maps from the field type. | 6027 // Collect the (stable) maps from the field type. |
6028 int num_field_maps = field_type->NumClasses(); | 6028 int num_field_maps = field_type->NumClasses(); |
6029 if (num_field_maps == 0) return; | 6029 if (num_field_maps > 0) { |
6030 DCHECK(access_.representation().IsHeapObject()); | 6030 DCHECK(access_.representation().IsHeapObject()); |
6031 field_maps_.Reserve(num_field_maps, zone()); | 6031 field_maps_.Reserve(num_field_maps, zone()); |
6032 HeapType::Iterator<Map> it = field_type->Classes(); | 6032 HeapType::Iterator<Map> it = field_type->Classes(); |
6033 while (!it.Done()) { | 6033 while (!it.Done()) { |
6034 Handle<Map> field_map = it.Current(); | 6034 Handle<Map> field_map = it.Current(); |
6035 if (!field_map->is_stable()) { | 6035 if (!field_map->is_stable()) { |
6036 field_maps_.Clear(); | 6036 field_maps_.Clear(); |
6037 return; | 6037 break; |
| 6038 } |
| 6039 field_maps_.Add(field_map, zone()); |
| 6040 it.Advance(); |
6038 } | 6041 } |
6039 field_maps_.Add(field_map, zone()); | |
6040 it.Advance(); | |
6041 } | 6042 } |
| 6043 |
| 6044 if (field_maps_.is_empty()) { |
| 6045 // Store is not safe if the field map was cleared. |
| 6046 return IsLoad() || !field_type->Is(HeapType::None()); |
| 6047 } |
| 6048 |
6042 field_maps_.Sort(); | 6049 field_maps_.Sort(); |
6043 DCHECK_EQ(num_field_maps, field_maps_.length()); | 6050 DCHECK_EQ(num_field_maps, field_maps_.length()); |
6044 | 6051 |
6045 // Determine field HType from field HeapType. | 6052 // Determine field HType from field HeapType. |
6046 field_type_ = HType::FromType<HeapType>(field_type); | 6053 field_type_ = HType::FromType<HeapType>(field_type); |
6047 DCHECK(field_type_.IsHeapObject()); | 6054 DCHECK(field_type_.IsHeapObject()); |
6048 | 6055 |
6049 // Add dependency on the map that introduced the field. | 6056 // Add dependency on the map that introduced the field. |
6050 Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map), | 6057 Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map), |
6051 DependentCode::kFieldTypeGroup, top_info()); | 6058 DependentCode::kFieldTypeGroup, top_info()); |
| 6059 return true; |
6052 } | 6060 } |
6053 | 6061 |
6054 | 6062 |
6055 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { | 6063 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { |
6056 Handle<Map> map = this->map(); | 6064 Handle<Map> map = this->map(); |
6057 | 6065 |
6058 while (map->prototype()->IsJSObject()) { | 6066 while (map->prototype()->IsJSObject()) { |
6059 holder_ = handle(JSObject::cast(map->prototype())); | 6067 holder_ = handle(JSObject::cast(map->prototype())); |
6060 if (holder_->map()->is_deprecated()) { | 6068 if (holder_->map()->is_deprecated()) { |
6061 JSObject::TryMigrateInstance(holder_); | 6069 JSObject::TryMigrateInstance(holder_); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6099 int descriptor = transition()->LastAdded(); | 6107 int descriptor = transition()->LastAdded(); |
6100 int index = | 6108 int index = |
6101 transition()->instance_descriptors()->GetFieldIndex(descriptor) - | 6109 transition()->instance_descriptors()->GetFieldIndex(descriptor) - |
6102 map_->inobject_properties(); | 6110 map_->inobject_properties(); |
6103 PropertyDetails details = | 6111 PropertyDetails details = |
6104 transition()->instance_descriptors()->GetDetails(descriptor); | 6112 transition()->instance_descriptors()->GetDetails(descriptor); |
6105 Representation representation = details.representation(); | 6113 Representation representation = details.representation(); |
6106 access_ = HObjectAccess::ForField(map_, index, representation, name_); | 6114 access_ = HObjectAccess::ForField(map_, index, representation, name_); |
6107 | 6115 |
6108 // Load field map for heap objects. | 6116 // Load field map for heap objects. |
6109 LoadFieldMaps(transition()); | 6117 return LoadFieldMaps(transition()); |
6110 return true; | |
6111 } | 6118 } |
6112 return false; | 6119 return false; |
6113 } | 6120 } |
6114 | 6121 |
6115 | 6122 |
6116 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( | 6123 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( |
6117 SmallMapList* maps) { | 6124 SmallMapList* maps) { |
6118 DCHECK(map_.is_identical_to(maps->first())); | 6125 DCHECK(map_.is_identical_to(maps->first())); |
6119 if (!CanAccessMonomorphic()) return false; | 6126 if (!CanAccessMonomorphic()) return false; |
6120 STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); | 6127 STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); |
(...skipping 7282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13403 if (ShouldProduceTraceOutput()) { | 13410 if (ShouldProduceTraceOutput()) { |
13404 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13411 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
13405 } | 13412 } |
13406 | 13413 |
13407 #ifdef DEBUG | 13414 #ifdef DEBUG |
13408 graph_->Verify(false); // No full verify. | 13415 graph_->Verify(false); // No full verify. |
13409 #endif | 13416 #endif |
13410 } | 13417 } |
13411 | 13418 |
13412 } } // namespace v8::internal | 13419 } } // namespace v8::internal |
OLD | NEW |