Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Side by Side Diff: src/hydrogen.cc

Issue 495483003: Indirect LookupResult accesses over PropertyAccessInfo (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: More private Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 5584 matching lines...) Expand 10 before | Expand all | Expand 10 after
5595 Handle<String> name = property->key()->AsPropertyName(); 5595 Handle<String> name = property->key()->AsPropertyName();
5596 HInstruction* store; 5596 HInstruction* store;
5597 if (map.is_null()) { 5597 if (map.is_null()) {
5598 // If we don't know the monomorphic type, do a generic store. 5598 // If we don't know the monomorphic type, do a generic store.
5599 CHECK_ALIVE(store = BuildNamedGeneric( 5599 CHECK_ALIVE(store = BuildNamedGeneric(
5600 STORE, NULL, literal, name, value)); 5600 STORE, NULL, literal, name, value));
5601 } else { 5601 } else {
5602 PropertyAccessInfo info(this, STORE, ToType(map), name); 5602 PropertyAccessInfo info(this, STORE, ToType(map), name);
5603 if (info.CanAccessMonomorphic()) { 5603 if (info.CanAccessMonomorphic()) {
5604 HValue* checked_literal = Add<HCheckMaps>(literal, map); 5604 HValue* checked_literal = Add<HCheckMaps>(literal, map);
5605 DCHECK(!info.lookup()->IsPropertyCallbacks()); 5605 DCHECK(!info.IsAccessor());
5606 store = BuildMonomorphicAccess( 5606 store = BuildMonomorphicAccess(
5607 &info, literal, checked_literal, value, 5607 &info, literal, checked_literal, value,
5608 BailoutId::None(), BailoutId::None()); 5608 BailoutId::None(), BailoutId::None());
5609 } else { 5609 } else {
5610 CHECK_ALIVE(store = BuildNamedGeneric( 5610 CHECK_ALIVE(store = BuildNamedGeneric(
5611 STORE, NULL, literal, name, value)); 5611 STORE, NULL, literal, name, value));
5612 } 5612 }
5613 } 5613 }
5614 AddInstruction(store); 5614 AddInstruction(store);
5615 if (store->HasObservableSideEffects()) { 5615 if (store->HasObservableSideEffects()) {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
5782 Handle<Map> map) { 5782 Handle<Map> map) {
5783 BuildCheckHeapObject(object); 5783 BuildCheckHeapObject(object);
5784 return Add<HCheckMaps>(object, map); 5784 return Add<HCheckMaps>(object, map);
5785 } 5785 }
5786 5786
5787 5787
5788 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField( 5788 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField(
5789 PropertyAccessInfo* info, 5789 PropertyAccessInfo* info,
5790 HValue* checked_object) { 5790 HValue* checked_object) {
5791 // See if this is a load for an immutable property 5791 // See if this is a load for an immutable property
5792 if (checked_object->ActualValue()->IsConstant() && 5792 if (checked_object->ActualValue()->IsConstant() && info->IsCacheable() &&
5793 info->lookup()->IsCacheable() && 5793 info->IsReadOnly() && !info->IsConfigurable()) {
5794 info->lookup()->IsReadOnly() && info->lookup()->IsDontDelete()) {
5795 Handle<Object> object( 5794 Handle<Object> object(
5796 HConstant::cast(checked_object->ActualValue())->handle(isolate())); 5795 HConstant::cast(checked_object->ActualValue())->handle(isolate()));
5797 5796
5798 if (object->IsJSObject()) { 5797 if (object->IsJSObject()) {
5799 LookupIterator it(object, info->name(), LookupIterator::CHECK_PROPERTY); 5798 LookupIterator it(object, info->name(), LookupIterator::CHECK_PROPERTY);
5800 Handle<Object> value = JSObject::GetDataProperty(&it); 5799 Handle<Object> value = JSObject::GetDataProperty(&it);
5801 CHECK(it.IsFound()); 5800 CHECK(it.IsFound());
5802 return New<HConstant>(value); 5801 return New<HConstant>(value);
5803 } 5802 }
5804 } 5803 }
(...skipping 19 matching lines...) Expand all
5824 } 5823 }
5825 return New<HLoadNamedField>( 5824 return New<HLoadNamedField>(
5826 checked_object, checked_object, access, maps, info->field_type()); 5825 checked_object, checked_object, access, maps, info->field_type());
5827 } 5826 }
5828 5827
5829 5828
5830 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( 5829 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
5831 PropertyAccessInfo* info, 5830 PropertyAccessInfo* info,
5832 HValue* checked_object, 5831 HValue* checked_object,
5833 HValue* value) { 5832 HValue* value) {
5834 bool transition_to_field = info->lookup()->IsTransition(); 5833 bool transition_to_field = info->IsTransition();
5835 // TODO(verwaest): Move this logic into PropertyAccessInfo. 5834 // TODO(verwaest): Move this logic into PropertyAccessInfo.
5836 HObjectAccess field_access = info->access(); 5835 HObjectAccess field_access = info->access();
5837 5836
5838 HStoreNamedField *instr; 5837 HStoreNamedField *instr;
5839 if (field_access.representation().IsDouble()) { 5838 if (field_access.representation().IsDouble()) {
5840 HObjectAccess heap_number_access = 5839 HObjectAccess heap_number_access =
5841 field_access.WithRepresentation(Representation::Tagged()); 5840 field_access.WithRepresentation(Representation::Tagged());
5842 if (transition_to_field) { 5841 if (transition_to_field) {
5843 // The store requires a mutable HeapNumber to be allocated. 5842 // The store requires a mutable HeapNumber to be allocated.
5844 NoObservableSideEffectsScope no_side_effects(this); 5843 NoObservableSideEffectsScope no_side_effects(this);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
5901 // Values are only compatible for monomorphic load if they all behave the same 5900 // Values are only compatible for monomorphic load if they all behave the same
5902 // regarding value wrappers. 5901 // regarding value wrappers.
5903 if (type_->Is(Type::NumberOrString())) { 5902 if (type_->Is(Type::NumberOrString())) {
5904 if (!info->type_->Is(Type::NumberOrString())) return false; 5903 if (!info->type_->Is(Type::NumberOrString())) return false;
5905 } else { 5904 } else {
5906 if (info->type_->Is(Type::NumberOrString())) return false; 5905 if (info->type_->Is(Type::NumberOrString())) return false;
5907 } 5906 }
5908 5907
5909 if (!LookupDescriptor()) return false; 5908 if (!LookupDescriptor()) return false;
5910 5909
5911 if (!lookup_.IsFound()) { 5910 if (!IsFound()) {
5912 return (!info->lookup_.IsFound() || info->has_holder()) && 5911 return (!info->IsFound() || info->has_holder()) &&
5913 map()->prototype() == info->map()->prototype(); 5912 map()->prototype() == info->map()->prototype();
5914 } 5913 }
5915 5914
5916 // Mismatch if the other access info found the property in the prototype 5915 // Mismatch if the other access info found the property in the prototype
5917 // chain. 5916 // chain.
5918 if (info->has_holder()) return false; 5917 if (info->has_holder()) return false;
5919 5918
5920 if (lookup_.IsPropertyCallbacks()) { 5919 if (IsAccessor()) {
5921 return accessor_.is_identical_to(info->accessor_) && 5920 return accessor_.is_identical_to(info->accessor_) &&
5922 api_holder_.is_identical_to(info->api_holder_); 5921 api_holder_.is_identical_to(info->api_holder_);
5923 } 5922 }
5924 5923
5925 if (lookup_.IsConstant()) { 5924 if (IsConstant()) {
5926 return constant_.is_identical_to(info->constant_); 5925 return constant_.is_identical_to(info->constant_);
5927 } 5926 }
5928 5927
5929 DCHECK(lookup_.IsField()); 5928 DCHECK(IsField());
5930 if (!info->lookup_.IsField()) return false; 5929 if (!info->IsField()) return false;
5931 5930
5932 Representation r = access_.representation(); 5931 Representation r = access_.representation();
5933 if (IsLoad()) { 5932 if (IsLoad()) {
5934 if (!info->access_.representation().IsCompatibleForLoad(r)) return false; 5933 if (!info->access_.representation().IsCompatibleForLoad(r)) return false;
5935 } else { 5934 } else {
5936 if (!info->access_.representation().IsCompatibleForStore(r)) return false; 5935 if (!info->access_.representation().IsCompatibleForStore(r)) return false;
5937 } 5936 }
5938 if (info->access_.offset() != access_.offset()) return false; 5937 if (info->access_.offset() != access_.offset()) return false;
5939 if (info->access_.IsInobject() != access_.IsInobject()) return false; 5938 if (info->access_.IsInobject() != access_.IsInobject()) return false;
5940 if (IsLoad()) { 5939 if (IsLoad()) {
(...skipping 22 matching lines...) Expand all
5963 5962
5964 5963
5965 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() { 5964 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() {
5966 if (!type_->IsClass()) return true; 5965 if (!type_->IsClass()) return true;
5967 map()->LookupDescriptor(NULL, *name_, &lookup_); 5966 map()->LookupDescriptor(NULL, *name_, &lookup_);
5968 return LoadResult(map()); 5967 return LoadResult(map());
5969 } 5968 }
5970 5969
5971 5970
5972 bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) { 5971 bool HOptimizedGraphBuilder::PropertyAccessInfo::LoadResult(Handle<Map> map) {
5973 if (!IsLoad() && lookup_.IsProperty() && 5972 if (!IsLoad() && IsProperty() && (IsReadOnly() || !IsCacheable())) {
5974 (lookup_.IsReadOnly() || !lookup_.IsCacheable())) {
5975 return false; 5973 return false;
5976 } 5974 }
5977 5975
5978 if (lookup_.IsField()) { 5976 if (IsField()) {
5979 // Construct the object field access. 5977 // Construct the object field access.
5980 int index = lookup_.GetLocalFieldIndexFromMap(*map); 5978 int index = GetLocalFieldIndexFromMap(map);
5981 Representation representation = lookup_.representation(); 5979 access_ = HObjectAccess::ForField(map, index, representation(), name_);
5982 access_ = HObjectAccess::ForField(map, index, representation, name_);
5983 5980
5984 // Load field map for heap objects. 5981 // Load field map for heap objects.
5985 LoadFieldMaps(map); 5982 LoadFieldMaps(map);
5986 } else if (lookup_.IsPropertyCallbacks()) { 5983 } else if (IsAccessor()) {
5987 Handle<Object> callback(lookup_.GetValueFromMap(*map), isolate()); 5984 Handle<Object> accessors = GetAccessorsFromMap(map);
5988 if (!callback->IsAccessorPair()) return false; 5985 if (!accessors->IsAccessorPair()) return false;
5989 Object* raw_accessor = IsLoad() 5986 Object* raw_accessor =
5990 ? Handle<AccessorPair>::cast(callback)->getter() 5987 IsLoad() ? Handle<AccessorPair>::cast(accessors)->getter()
5991 : Handle<AccessorPair>::cast(callback)->setter(); 5988 : Handle<AccessorPair>::cast(accessors)->setter();
5992 if (!raw_accessor->IsJSFunction()) return false; 5989 if (!raw_accessor->IsJSFunction()) return false;
5993 Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor)); 5990 Handle<JSFunction> accessor = handle(JSFunction::cast(raw_accessor));
5994 if (accessor->shared()->IsApiFunction()) { 5991 if (accessor->shared()->IsApiFunction()) {
5995 CallOptimization call_optimization(accessor); 5992 CallOptimization call_optimization(accessor);
5996 if (call_optimization.is_simple_api_call()) { 5993 if (call_optimization.is_simple_api_call()) {
5997 CallOptimization::HolderLookup holder_lookup; 5994 CallOptimization::HolderLookup holder_lookup;
5998 Handle<Map> receiver_map = this->map(); 5995 Handle<Map> receiver_map = this->map();
5999 api_holder_ = call_optimization.LookupHolderOfExpectedType( 5996 api_holder_ = call_optimization.LookupHolderOfExpectedType(
6000 receiver_map, &holder_lookup); 5997 receiver_map, &holder_lookup);
6001 } 5998 }
6002 } 5999 }
6003 accessor_ = accessor; 6000 accessor_ = accessor;
6004 } else if (lookup_.IsConstant()) { 6001 } else if (IsConstant()) {
6005 constant_ = handle(lookup_.GetConstantFromMap(*map), isolate()); 6002 constant_ = GetConstantFromMap(map);
6006 } 6003 }
6007 6004
6008 return true; 6005 return true;
6009 } 6006 }
6010 6007
6011 6008
6012 void HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( 6009 void HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps(
6013 Handle<Map> map) { 6010 Handle<Map> map) {
6014 // Clear any previously collected field maps/type. 6011 // Clear any previously collected field maps/type.
6015 field_maps_.Clear(); 6012 field_maps_.Clear();
6016 field_type_ = HType::Tagged(); 6013 field_type_ = HType::Tagged();
6017 6014
6018 // Figure out the field type from the accessor map. 6015 // Figure out the field type from the accessor map.
6019 Handle<HeapType> field_type(lookup_.GetFieldTypeFromMap(*map), isolate()); 6016 Handle<HeapType> field_type = GetFieldTypeFromMap(map);
6020 6017
6021 // Collect the (stable) maps from the field type. 6018 // Collect the (stable) maps from the field type.
6022 int num_field_maps = field_type->NumClasses(); 6019 int num_field_maps = field_type->NumClasses();
6023 if (num_field_maps == 0) return; 6020 if (num_field_maps == 0) return;
6024 DCHECK(access_.representation().IsHeapObject()); 6021 DCHECK(access_.representation().IsHeapObject());
6025 field_maps_.Reserve(num_field_maps, zone()); 6022 field_maps_.Reserve(num_field_maps, zone());
6026 HeapType::Iterator<Map> it = field_type->Classes(); 6023 HeapType::Iterator<Map> it = field_type->Classes();
6027 while (!it.Done()) { 6024 while (!it.Done()) {
6028 Handle<Map> field_map = it.Current(); 6025 Handle<Map> field_map = it.Current();
6029 if (!field_map->is_stable()) { 6026 if (!field_map->is_stable()) {
6030 field_maps_.Clear(); 6027 field_maps_.Clear();
6031 return; 6028 return;
6032 } 6029 }
6033 field_maps_.Add(field_map, zone()); 6030 field_maps_.Add(field_map, zone());
6034 it.Advance(); 6031 it.Advance();
6035 } 6032 }
6036 field_maps_.Sort(); 6033 field_maps_.Sort();
6037 DCHECK_EQ(num_field_maps, field_maps_.length()); 6034 DCHECK_EQ(num_field_maps, field_maps_.length());
6038 6035
6039 // Determine field HType from field HeapType. 6036 // Determine field HType from field HeapType.
6040 field_type_ = HType::FromType<HeapType>(field_type); 6037 field_type_ = HType::FromType<HeapType>(field_type);
6041 DCHECK(field_type_.IsHeapObject()); 6038 DCHECK(field_type_.IsHeapObject());
6042 6039
6043 // Add dependency on the map that introduced the field. 6040 // Add dependency on the map that introduced the field.
6044 Map::AddDependentCompilationInfo( 6041 Map::AddDependentCompilationInfo(GetFieldOwnerFromMap(map),
6045 handle(lookup_.GetFieldOwnerFromMap(*map), isolate()), 6042 DependentCode::kFieldTypeGroup, top_info());
6046 DependentCode::kFieldTypeGroup, top_info());
6047 } 6043 }
6048 6044
6049 6045
6050 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { 6046 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() {
6051 Handle<Map> map = this->map(); 6047 Handle<Map> map = this->map();
6052 6048
6053 while (map->prototype()->IsJSObject()) { 6049 while (map->prototype()->IsJSObject()) {
6054 holder_ = handle(JSObject::cast(map->prototype())); 6050 holder_ = handle(JSObject::cast(map->prototype()));
6055 if (holder_->map()->is_deprecated()) { 6051 if (holder_->map()->is_deprecated()) {
6056 JSObject::TryMigrateInstance(holder_); 6052 JSObject::TryMigrateInstance(holder_);
6057 } 6053 }
6058 map = Handle<Map>(holder_->map()); 6054 map = Handle<Map>(holder_->map());
6059 if (!CanInlinePropertyAccess(ToType(map))) { 6055 if (!CanInlinePropertyAccess(ToType(map))) {
6060 lookup_.NotFound(); 6056 lookup_.NotFound();
6061 return false; 6057 return false;
6062 } 6058 }
6063 map->LookupDescriptor(*holder_, *name_, &lookup_); 6059 map->LookupDescriptor(*holder_, *name_, &lookup_);
6064 if (lookup_.IsFound()) return LoadResult(map); 6060 if (IsFound()) return LoadResult(map);
6065 } 6061 }
6066 lookup_.NotFound(); 6062 lookup_.NotFound();
6067 return true; 6063 return true;
6068 } 6064 }
6069 6065
6070 6066
6071 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() { 6067 bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessMonomorphic() {
6072 if (!CanInlinePropertyAccess(type_)) return false; 6068 if (!CanInlinePropertyAccess(type_)) return false;
6073 if (IsJSObjectFieldAccessor()) return IsLoad(); 6069 if (IsJSObjectFieldAccessor()) return IsLoad();
6074 if (this->map()->function_with_prototype() && 6070 if (this->map()->function_with_prototype() &&
6075 !this->map()->has_non_instance_prototype() && 6071 !this->map()->has_non_instance_prototype() &&
6076 name_.is_identical_to(isolate()->factory()->prototype_string())) { 6072 name_.is_identical_to(isolate()->factory()->prototype_string())) {
6077 return IsLoad(); 6073 return IsLoad();
6078 } 6074 }
6079 if (!LookupDescriptor()) return false; 6075 if (!LookupDescriptor()) return false;
6080 if (lookup_.IsFound()) { 6076 if (IsFound()) {
6081 if (IsLoad()) return true; 6077 if (IsLoad()) return true;
6082 return !lookup_.IsReadOnly() && lookup_.IsCacheable(); 6078 return !IsReadOnly() && IsCacheable();
6083 } 6079 }
6084 if (!LookupInPrototypes()) return false; 6080 if (!LookupInPrototypes()) return false;
6085 if (IsLoad()) return true; 6081 if (IsLoad()) return true;
6086 6082
6087 if (lookup_.IsPropertyCallbacks()) return true; 6083 if (IsAccessor()) return true;
6088 Handle<Map> map = this->map(); 6084 Handle<Map> map = this->map();
6089 map->LookupTransition(NULL, *name_, &lookup_); 6085 map->LookupTransition(NULL, *name_, &lookup_);
6090 if (lookup_.IsTransitionToField() && map->unused_property_fields() > 0) { 6086 if (lookup_.IsTransitionToField() && map->unused_property_fields() > 0) {
6091 // Construct the object field access. 6087 // Construct the object field access.
6092 int descriptor = transition()->LastAdded(); 6088 int descriptor = transition()->LastAdded();
6093 int index = 6089 int index =
6094 transition()->instance_descriptors()->GetFieldIndex(descriptor) - 6090 transition()->instance_descriptors()->GetFieldIndex(descriptor) -
6095 map->inobject_properties(); 6091 map->inobject_properties();
6096 PropertyDetails details = 6092 PropertyDetails details =
6097 transition()->instance_descriptors()->GetDetails(descriptor); 6093 transition()->instance_descriptors()->GetDetails(descriptor);
(...skipping 26 matching lines...) Expand all
6124 } 6120 }
6125 return true; 6121 return true;
6126 } 6122 }
6127 6123
6128 // Currently only handle Type::Number as a polymorphic case. 6124 // Currently only handle Type::Number as a polymorphic case.
6129 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber 6125 // TODO(verwaest): Support monomorphic handling of numbers with a HCheckNumber
6130 // instruction. 6126 // instruction.
6131 if (type_->Is(Type::Number())) return false; 6127 if (type_->Is(Type::Number())) return false;
6132 6128
6133 // Multiple maps cannot transition to the same target map. 6129 // Multiple maps cannot transition to the same target map.
6134 DCHECK(!IsLoad() || !lookup_.IsTransition()); 6130 DCHECK(!IsLoad() || !IsTransition());
6135 if (lookup_.IsTransition() && types->length() > 1) return false; 6131 if (IsTransition() && types->length() > 1) return false;
6136 6132
6137 for (int i = 1; i < types->length(); ++i) { 6133 for (int i = 1; i < types->length(); ++i) {
6138 PropertyAccessInfo test_info( 6134 PropertyAccessInfo test_info(
6139 builder_, access_type_, ToType(types->at(i)), name_); 6135 builder_, access_type_, ToType(types->at(i)), name_);
6140 if (!test_info.IsCompatible(this)) return false; 6136 if (!test_info.IsCompatible(this)) return false;
6141 } 6137 }
6142 6138
6143 return true; 6139 return true;
6144 } 6140 }
6145 6141
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
6179 DCHECK(!info->map()->has_non_instance_prototype()); 6175 DCHECK(!info->map()->has_non_instance_prototype());
6180 return New<HLoadFunctionPrototype>(checked_object); 6176 return New<HLoadFunctionPrototype>(checked_object);
6181 } 6177 }
6182 6178
6183 HValue* checked_holder = checked_object; 6179 HValue* checked_holder = checked_object;
6184 if (info->has_holder()) { 6180 if (info->has_holder()) {
6185 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); 6181 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype()));
6186 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); 6182 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder());
6187 } 6183 }
6188 6184
6189 if (!info->lookup()->IsFound()) { 6185 if (!info->IsFound()) {
6190 DCHECK(info->IsLoad()); 6186 DCHECK(info->IsLoad());
6191 return graph()->GetConstantUndefined(); 6187 return graph()->GetConstantUndefined();
6192 } 6188 }
6193 6189
6194 if (info->lookup()->IsField()) { 6190 if (info->IsField()) {
6195 if (info->IsLoad()) { 6191 if (info->IsLoad()) {
6196 return BuildLoadNamedField(info, checked_holder); 6192 return BuildLoadNamedField(info, checked_holder);
6197 } else { 6193 } else {
6198 return BuildStoreNamedField(info, checked_object, value); 6194 return BuildStoreNamedField(info, checked_object, value);
6199 } 6195 }
6200 } 6196 }
6201 6197
6202 if (info->lookup()->IsTransition()) { 6198 if (info->IsTransition()) {
6203 DCHECK(!info->IsLoad()); 6199 DCHECK(!info->IsLoad());
6204 return BuildStoreNamedField(info, checked_object, value); 6200 return BuildStoreNamedField(info, checked_object, value);
6205 } 6201 }
6206 6202
6207 if (info->lookup()->IsPropertyCallbacks()) { 6203 if (info->IsAccessor()) {
6208 Push(checked_object); 6204 Push(checked_object);
6209 int argument_count = 1; 6205 int argument_count = 1;
6210 if (!info->IsLoad()) { 6206 if (!info->IsLoad()) {
6211 argument_count = 2; 6207 argument_count = 2;
6212 Push(value); 6208 Push(value);
6213 } 6209 }
6214 6210
6215 if (NeedsWrappingFor(info->type(), info->accessor())) { 6211 if (NeedsWrappingFor(info->type(), info->accessor())) {
6216 HValue* function = Add<HConstant>(info->accessor()); 6212 HValue* function = Add<HConstant>(info->accessor());
6217 PushArgumentsFromEnvironment(argument_count); 6213 PushArgumentsFromEnvironment(argument_count);
6218 return New<HCallFunction>(function, argument_count, WRAP_AND_CALL); 6214 return New<HCallFunction>(function, argument_count, WRAP_AND_CALL);
6219 } else if (FLAG_inline_accessors && can_inline_accessor) { 6215 } else if (FLAG_inline_accessors && can_inline_accessor) {
6220 bool success = info->IsLoad() 6216 bool success = info->IsLoad()
6221 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id) 6217 ? TryInlineGetter(info->accessor(), info->map(), ast_id, return_id)
6222 : TryInlineSetter( 6218 : TryInlineSetter(
6223 info->accessor(), info->map(), ast_id, return_id, value); 6219 info->accessor(), info->map(), ast_id, return_id, value);
6224 if (success || HasStackOverflow()) return NULL; 6220 if (success || HasStackOverflow()) return NULL;
6225 } 6221 }
6226 6222
6227 PushArgumentsFromEnvironment(argument_count); 6223 PushArgumentsFromEnvironment(argument_count);
6228 return BuildCallConstantFunction(info->accessor(), argument_count); 6224 return BuildCallConstantFunction(info->accessor(), argument_count);
6229 } 6225 }
6230 6226
6231 DCHECK(info->lookup()->IsConstant()); 6227 DCHECK(info->IsConstant());
6232 if (info->IsLoad()) { 6228 if (info->IsLoad()) {
6233 return New<HConstant>(info->constant()); 6229 return New<HConstant>(info->constant());
6234 } else { 6230 } else {
6235 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant())); 6231 return New<HCheckValue>(value, Handle<JSFunction>::cast(info->constant()));
6236 } 6232 }
6237 } 6233 }
6238 6234
6239 6235
6240 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess( 6236 void HOptimizedGraphBuilder::HandlePolymorphicNamedFieldAccess(
6241 PropertyAccessType access_type, 6237 PropertyAccessType access_type,
(...skipping 1235 matching lines...) Expand 10 before | Expand all | Expand 10 after
7477 FunctionSorter order[kMaxCallPolymorphism]; 7473 FunctionSorter order[kMaxCallPolymorphism];
7478 7474
7479 bool handle_smi = false; 7475 bool handle_smi = false;
7480 bool handled_string = false; 7476 bool handled_string = false;
7481 int ordered_functions = 0; 7477 int ordered_functions = 0;
7482 7478
7483 for (int i = 0; 7479 for (int i = 0;
7484 i < types->length() && ordered_functions < kMaxCallPolymorphism; 7480 i < types->length() && ordered_functions < kMaxCallPolymorphism;
7485 ++i) { 7481 ++i) {
7486 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name); 7482 PropertyAccessInfo info(this, LOAD, ToType(types->at(i)), name);
7487 if (info.CanAccessMonomorphic() && 7483 if (info.CanAccessMonomorphic() && info.IsConstant() &&
7488 info.lookup()->IsConstant() &&
7489 info.constant()->IsJSFunction()) { 7484 info.constant()->IsJSFunction()) {
7490 if (info.type()->Is(Type::String())) { 7485 if (info.type()->Is(Type::String())) {
7491 if (handled_string) continue; 7486 if (handled_string) continue;
7492 handled_string = true; 7487 handled_string = true;
7493 } 7488 }
7494 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant()); 7489 Handle<JSFunction> target = Handle<JSFunction>::cast(info.constant());
7495 if (info.type()->Is(Type::Number())) { 7490 if (info.type()->Is(Type::Number())) {
7496 handle_smi = true; 7491 handle_smi = true;
7497 } 7492 }
7498 expr->set_target(target); 7493 expr->set_target(target);
(...skipping 4996 matching lines...) Expand 10 before | Expand all | Expand 10 after
12495 if (ShouldProduceTraceOutput()) { 12490 if (ShouldProduceTraceOutput()) {
12496 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 12491 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
12497 } 12492 }
12498 12493
12499 #ifdef DEBUG 12494 #ifdef DEBUG
12500 graph_->Verify(false); // No full verify. 12495 graph_->Verify(false); // No full verify.
12501 #endif 12496 #endif
12502 } 12497 }
12503 12498
12504 } } // namespace v8::internal 12499 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698