Index: src/hydrogen-instructions.cc |
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc |
index 28511f714208f6fcc9eb84a4d1812723f09ba01b..df53ad75b7df447bcf6caa12ecb30767a45184a5 100644 |
--- a/src/hydrogen-instructions.cc |
+++ b/src/hydrogen-instructions.cc |
@@ -2817,119 +2817,6 @@ void HLoadNamedField::PrintDataTo(StringStream* stream) { |
} |
-// Returns true if an instance of this map can never find a property with this |
-// name in its prototype chain. This means all prototypes up to the top are |
-// fast and don't have the name in them. It would be good if we could optimize |
-// polymorphic loads where the property is sometimes found in the prototype |
-// chain. |
-static bool PrototypeChainCanNeverResolve( |
- Handle<Map> map, Handle<String> name) { |
- Isolate* isolate = map->GetIsolate(); |
- Object* current = map->prototype(); |
- while (current != isolate->heap()->null_value()) { |
- if (current->IsJSGlobalProxy() || |
- current->IsGlobalObject() || |
- !current->IsJSObject() || |
- JSObject::cast(current)->map()->has_named_interceptor() || |
- JSObject::cast(current)->IsAccessCheckNeeded() || |
- !JSObject::cast(current)->HasFastProperties()) { |
- return false; |
- } |
- |
- LookupResult lookup(isolate); |
- Map* map = JSObject::cast(current)->map(); |
- map->LookupDescriptor(NULL, *name, &lookup); |
- if (lookup.IsFound()) return false; |
- if (!lookup.IsCacheable()) return false; |
- current = JSObject::cast(current)->GetPrototype(); |
- } |
- return true; |
-} |
- |
- |
-HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, |
- HValue* object, |
- SmallMapList* types, |
- Handle<String> name, |
- Zone* zone) |
- : types_(Min(types->length(), kMaxLoadPolymorphism), zone), |
- name_(name), |
- types_unique_ids_(0, zone), |
- name_unique_id_(), |
- need_generic_(false) { |
- SetOperandAt(0, context); |
- SetOperandAt(1, object); |
- set_representation(Representation::Tagged()); |
- SetGVNFlag(kDependsOnMaps); |
- SmallMapList negative_lookups; |
- for (int i = 0; |
- i < types->length() && types_.length() < kMaxLoadPolymorphism; |
- ++i) { |
- Handle<Map> map = types->at(i); |
- // Deprecated maps are updated to the current map in the type oracle. |
- ASSERT(!map->is_deprecated()); |
- LookupResult lookup(map->GetIsolate()); |
- map->LookupDescriptor(NULL, *name, &lookup); |
- if (lookup.IsFound()) { |
- switch (lookup.type()) { |
- case FIELD: { |
- int index = lookup.GetLocalFieldIndexFromMap(*map); |
- if (index < 0) { |
- SetGVNFlag(kDependsOnInobjectFields); |
- } else { |
- SetGVNFlag(kDependsOnBackingStoreFields); |
- } |
- if (FLAG_track_double_fields && |
- lookup.representation().IsDouble()) { |
- // Since the value needs to be boxed, use a generic handler for |
- // loading doubles. |
- continue; |
- } |
- types_.Add(types->at(i), zone); |
- break; |
- } |
- case CONSTANT: |
- types_.Add(types->at(i), zone); |
- break; |
- case CALLBACKS: |
- break; |
- case TRANSITION: |
- case INTERCEPTOR: |
- case NONEXISTENT: |
- case NORMAL: |
- case HANDLER: |
- UNREACHABLE(); |
- break; |
- } |
- } else if (lookup.IsCacheable() && |
- // For dicts the lookup on the map will fail, but the object may |
- // contain the property so we cannot generate a negative lookup |
- // (which would just be a map check and return undefined). |
- !map->is_dictionary_map() && |
- !map->has_named_interceptor() && |
- PrototypeChainCanNeverResolve(map, name)) { |
- negative_lookups.Add(types->at(i), zone); |
- } |
- } |
- |
- bool need_generic = |
- (types->length() != negative_lookups.length() + types_.length()); |
- if (!need_generic && FLAG_deoptimize_uncommon_cases) { |
- SetFlag(kUseGVN); |
- for (int i = 0; i < negative_lookups.length(); i++) { |
- types_.Add(negative_lookups.at(i), zone); |
- } |
- } else { |
- // We don't have an easy way to handle both a call (to the generic stub) and |
- // a deopt in the same hydrogen instruction, so in this case we don't add |
- // the negative lookups which can deopt - just let the generic stub handle |
- // them. |
- SetAllSideEffects(); |
- need_generic_ = true; |
- } |
-} |
- |
- |
HCheckMaps* HCheckMaps::New(Zone* zone, |
HValue* context, |
HValue* value, |
@@ -2958,46 +2845,6 @@ void HCheckMaps::FinalizeUniqueValueId() { |
} |
-void HLoadNamedFieldPolymorphic::FinalizeUniqueValueId() { |
- if (!types_unique_ids_.is_empty()) return; |
- Zone* zone = block()->zone(); |
- types_unique_ids_.Initialize(types_.length(), zone); |
- for (int i = 0; i < types_.length(); i++) { |
- types_unique_ids_.Add(UniqueValueId(types_.at(i)), zone); |
- } |
- name_unique_id_ = UniqueValueId(name_); |
-} |
- |
- |
-bool HLoadNamedFieldPolymorphic::DataEquals(HValue* value) { |
- ASSERT_EQ(types_.length(), types_unique_ids_.length()); |
- HLoadNamedFieldPolymorphic* other = HLoadNamedFieldPolymorphic::cast(value); |
- if (name_unique_id_ != other->name_unique_id_) return false; |
- if (types_unique_ids_.length() != other->types_unique_ids_.length()) { |
- return false; |
- } |
- if (need_generic_ != other->need_generic_) return false; |
- for (int i = 0; i < types_unique_ids_.length(); i++) { |
- bool found = false; |
- for (int j = 0; j < types_unique_ids_.length(); j++) { |
- if (types_unique_ids_.at(j) == other->types_unique_ids_.at(i)) { |
- found = true; |
- break; |
- } |
- } |
- if (!found) return false; |
- } |
- return true; |
-} |
- |
- |
-void HLoadNamedFieldPolymorphic::PrintDataTo(StringStream* stream) { |
- object()->PrintNameTo(stream); |
- stream->Add("."); |
- stream->Add(*String::cast(*name())->ToCString()); |
-} |
- |
- |
void HLoadNamedGeneric::PrintDataTo(StringStream* stream) { |
object()->PrintNameTo(stream); |
stream->Add("."); |