| 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 |