| 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(".");
|
|
|