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 5996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6007 if (!IsLoad() && IsProperty() && IsReadOnly()) { | 6007 if (!IsLoad() && IsProperty() && IsReadOnly()) { |
6008 return false; | 6008 return false; |
6009 } | 6009 } |
6010 | 6010 |
6011 if (IsData()) { | 6011 if (IsData()) { |
6012 // Construct the object field access. | 6012 // Construct the object field access. |
6013 int index = GetLocalFieldIndexFromMap(map); | 6013 int index = GetLocalFieldIndexFromMap(map); |
6014 access_ = HObjectAccess::ForField(map, index, representation(), name_); | 6014 access_ = HObjectAccess::ForField(map, index, representation(), name_); |
6015 | 6015 |
6016 // Load field map for heap objects. | 6016 // Load field map for heap objects. |
6017 LoadFieldMaps(map); | 6017 return LoadFieldMaps(map); |
6018 } else if (IsAccessorConstant()) { | 6018 } else if (IsAccessorConstant()) { |
6019 Handle<Object> accessors = GetAccessorsFromMap(map); | 6019 Handle<Object> accessors = GetAccessorsFromMap(map); |
6020 if (!accessors->IsAccessorPair()) return false; | 6020 if (!accessors->IsAccessorPair()) return false; |
6021 Object* raw_accessor = | 6021 Object* raw_accessor = |
6022 IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter() | 6022 IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter() |
6023 : Handle<AccessorPair>::cast(accessors)->setter(); | 6023 : Handle<AccessorPair>::cast(accessors)->setter(); |
6024 if (!raw_accessor->IsJSFunction()) return false; | 6024 if (!raw_accessor->IsJSFunction()) return false; |
6025 Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor)); | 6025 Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor)); |
6026 if (accessor->shared()->IsApiFunction()) { | 6026 if (accessor->shared()->IsApiFunction()) { |
6027 CallOptimization call_optimization(accessor); | 6027 CallOptimization call_optimization(accessor); |
6028 if (call_optimization.is_simple_api_call()) { | 6028 if (call_optimization.is_simple_api_call()) { |
6029 CallOptimization::HolderLookup holder_lookup; | 6029 CallOptimization::HolderLookup holder_lookup; |
6030 api_holder_ = | 6030 api_holder_ = |
6031 call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup); | 6031 call_optimization.LookupHolderOfExpectedType(map_, &holder_lookup); |
6032 } | 6032 } |
6033 } | 6033 } |
6034 accessor_ = accessor; | 6034 accessor_ = accessor; |
6035 } else if (IsDataConstant()) { | 6035 } else if (IsDataConstant()) { |
6036 constant_ = GetConstantFromMap(map); | 6036 constant_ = GetConstantFromMap(map); |
6037 } | 6037 } |
6038 | 6038 |
6039 return true; | 6039 return true; |
6040 } | 6040 } |
6041 | 6041 |
6042 | 6042 |
6043 void HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( | 6043 bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( |
6044 Handle<Map> map) { | 6044 Handle<Map> map) { |
6045 // Clear any previously collected field maps/type. | 6045 // Clear any previously collected field maps/type. |
6046 field_maps_.Clear(); | 6046 field_maps_.Clear(); |
6047 field_type_ = HType::Tagged(); | 6047 field_type_ = HType::Tagged(); |
6048 | 6048 |
6049 // Figure out the field type from the accessor map. | 6049 // Figure out the field type from the accessor map. |
6050 Handle<HeapType> field_type = GetFieldTypeFromMap(map); | 6050 Handle<HeapType> field_type = GetFieldTypeFromMap(map); |
6051 | 6051 |
6052 // Collect the (stable) maps from the field type. | 6052 // Collect the (stable) maps from the field type. |
6053 int num_field_maps = field_type->NumClasses(); | 6053 int num_field_maps = field_type->NumClasses(); |
6054 if (num_field_maps == 0) return; | 6054 if (num_field_maps > 0) { |
6055 DCHECK(access_.representation().IsHeapObject()); | 6055 DCHECK(access_.representation().IsHeapObject()); |
6056 field_maps_.Reserve(num_field_maps, zone()); | 6056 field_maps_.Reserve(num_field_maps, zone()); |
6057 HeapType::Iterator<Map> it = field_type->Classes(); | 6057 HeapType::Iterator<Map> it = field_type->Classes(); |
6058 while (!it.Done()) { | 6058 while (!it.Done()) { |
6059 Handle<Map> field_map = it.Current(); | 6059 Handle<Map> field_map = it.Current(); |
6060 if (!field_map->is_stable()) { | 6060 if (!field_map->is_stable()) { |
6061 field_maps_.Clear(); | 6061 field_maps_.Clear(); |
6062 return; | 6062 break; |
| 6063 } |
| 6064 field_maps_.Add(field_map, zone()); |
| 6065 it.Advance(); |
6063 } | 6066 } |
6064 field_maps_.Add(field_map, zone()); | |
6065 it.Advance(); | |
6066 } | 6067 } |
| 6068 |
| 6069 if (field_maps_.is_empty()) { |
| 6070 // Store is not safe if the field map was cleared. |
| 6071 return IsLoad() || !field_type->Is(HeapType::None()); |
| 6072 } |
| 6073 |
6067 field_maps_.Sort(); | 6074 field_maps_.Sort(); |
6068 DCHECK_EQ(num_field_maps, field_maps_.length()); | 6075 DCHECK_EQ(num_field_maps, field_maps_.length()); |
6069 | 6076 |
6070 // Determine field HType from field HeapType. | 6077 // Determine field HType from field HeapType. |
6071 field_type_ = HType::FromType<HeapType>(field_type); | 6078 field_type_ = HType::FromType<HeapType>(field_type); |
6072 DCHECK(field_type_.IsHeapObject()); | 6079 DCHECK(field_type_.IsHeapObject()); |
6073 | 6080 |
6074 // Add dependency on the map that introduced the field. | 6081 // Add dependency on the map that introduced the field. |
6075 Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map), | 6082 Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map), |
6076 DependentCode::kFieldTypeGroup, top_info()); | 6083 DependentCode::kFieldTypeGroup, top_info()); |
| 6084 return true; |
6077 } | 6085 } |
6078 | 6086 |
6079 | 6087 |
6080 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { | 6088 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { |
6081 Handle<Map> map = this->map(); | 6089 Handle<Map> map = this->map(); |
6082 | 6090 |
6083 while (map->prototype()->IsJSObject()) { | 6091 while (map->prototype()->IsJSObject()) { |
6084 holder_ = handle(JSObject::cast(map->prototype())); | 6092 holder_ = handle(JSObject::cast(map->prototype())); |
6085 if (holder_->map()->is_deprecated()) { | 6093 if (holder_->map()->is_deprecated()) { |
6086 JSObject::TryMigrateInstance(holder_); | 6094 JSObject::TryMigrateInstance(holder_); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6125 int descriptor = transition()->LastAdded(); | 6133 int descriptor = transition()->LastAdded(); |
6126 int index = | 6134 int index = |
6127 transition()->instance_descriptors()->GetFieldIndex(descriptor) - | 6135 transition()->instance_descriptors()->GetFieldIndex(descriptor) - |
6128 map_->inobject_properties(); | 6136 map_->inobject_properties(); |
6129 PropertyDetails details = | 6137 PropertyDetails details = |
6130 transition()->instance_descriptors()->GetDetails(descriptor); | 6138 transition()->instance_descriptors()->GetDetails(descriptor); |
6131 Representation representation = details.representation(); | 6139 Representation representation = details.representation(); |
6132 access_ = HObjectAccess::ForField(map_, index, representation, name_); | 6140 access_ = HObjectAccess::ForField(map_, index, representation, name_); |
6133 | 6141 |
6134 // Load field map for heap objects. | 6142 // Load field map for heap objects. |
6135 LoadFieldMaps(transition()); | 6143 return LoadFieldMaps(transition()); |
6136 return true; | |
6137 } | 6144 } |
6138 return false; | 6145 return false; |
6139 } | 6146 } |
6140 | 6147 |
6141 | 6148 |
6142 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( | 6149 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( |
6143 SmallMapList* maps) { | 6150 SmallMapList* maps) { |
6144 DCHECK(map_.is_identical_to(maps->first())); | 6151 DCHECK(map_.is_identical_to(maps->first())); |
6145 if (!CanAccessMonomorphic()) return false; | 6152 if (!CanAccessMonomorphic()) return false; |
6146 STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); | 6153 STATIC_ASSERT(kMaxLoadPolymorphism == kMaxStorePolymorphism); |
(...skipping 6806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12953 if (ShouldProduceTraceOutput()) { | 12960 if (ShouldProduceTraceOutput()) { |
12954 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 12961 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
12955 } | 12962 } |
12956 | 12963 |
12957 #ifdef DEBUG | 12964 #ifdef DEBUG |
12958 graph_->Verify(false); // No full verify. | 12965 graph_->Verify(false); // No full verify. |
12959 #endif | 12966 #endif |
12960 } | 12967 } |
12961 | 12968 |
12962 } } // namespace v8::internal | 12969 } } // namespace v8::internal |
OLD | NEW |