From 22942716db3a9cc78246cb429696e6dfd858258e Mon Sep 17 00:00:00 2001 From: "verwaest@chromium.org" Date: Thu, 22 Aug 2013 13:43:06 +0000 Subject: [PATCH] Remove special case code for generalizing constants to fields. R=bmeurer@chromium.org Review URL: https://chromiumcodereview.appspot.com/22911018 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16275 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/bootstrapper.cc | 4 +- src/ic.cc | 3 +- src/objects-inl.h | 3 +- src/objects.cc | 410 +++++++++++++++++++------------------------- src/objects.h | 39 +++-- src/property.h | 2 - src/runtime.cc | 4 +- 7 files changed, 205 insertions(+), 260 deletions(-) diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index c69ab757cc..85c2a7c1f5 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -1143,12 +1143,12 @@ void Genesis::InitializeGlobal(Handle inner_global, JSObject::SetLocalPropertyIgnoreAttributes( result, factory->length_string(), factory->undefined_value(), DONT_ENUM, - Object::FORCE_TAGGED, JSReceiver::FORCE_FIELD)); + Object::FORCE_TAGGED, FORCE_FIELD)); CHECK_NOT_EMPTY_HANDLE(isolate, JSObject::SetLocalPropertyIgnoreAttributes( result, factory->callee_string(), factory->undefined_value(), DONT_ENUM, - Object::FORCE_TAGGED, JSReceiver::FORCE_FIELD)); + Object::FORCE_TAGGED, FORCE_FIELD)); #ifdef DEBUG LookupResult lookup(isolate); diff --git a/src/ic.cc b/src/ic.cc index cc7fee5468..a8d3527244 100644 --- a/src/ic.cc +++ b/src/ic.cc @@ -1615,7 +1615,8 @@ static bool LookupForWrite(Handle receiver, if (!value->FitsRepresentation(target_details.representation())) { Handle target(lookup->GetTransitionMapFromMap(receiver->map())); Map::GeneralizeRepresentation( - target, target->LastAdded(), value->OptimalRepresentation()); + target, target->LastAdded(), + value->OptimalRepresentation(), FORCE_FIELD); // Lookup the transition again since the transition tree may have changed // entirely by the migration above. receiver->map()->LookupTransition(*holder, *name, lookup); diff --git a/src/objects-inl.h b/src/objects-inl.h index 4c74b10c81..e1d321b19a 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -1569,7 +1569,7 @@ MaybeObject* JSObject::MigrateInstance() { // transition that matches the object. This achieves what is needed. Map* original_map = map(); MaybeObject* maybe_result = GeneralizeFieldRepresentation( - 0, Representation::None()); + 0, Representation::None(), ALLOW_AS_CONSTANT); JSObject* result; if (FLAG_trace_migration && maybe_result->To(&result)) { PrintInstanceMigration(stdout, original_map, result->map()); @@ -2361,6 +2361,7 @@ PropertyType DescriptorArray::GetType(int descriptor_number) { int DescriptorArray::GetFieldIndex(int descriptor_number) { + ASSERT(GetDetails(descriptor_number).type() == FIELD); return GetDetails(descriptor_number).field_index(); } diff --git a/src/objects.cc b/src/objects.cc index 7e15f3005d..567a16dc33 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -1450,19 +1450,31 @@ void JSObject::PrintElementsTransition( void Map::PrintGeneralization(FILE* file, + const char* reason, int modify_index, int split, int descriptors, + bool constant_to_field, Representation old_representation, Representation new_representation) { PrintF(file, "[generalizing "); constructor_name()->PrintOn(file); PrintF(file, "] "); String::cast(instance_descriptors()->GetKey(modify_index))->PrintOn(file); - PrintF(file, ":%s->%s (+%i maps) [", - old_representation.Mnemonic(), - new_representation.Mnemonic(), - descriptors - split); + if (constant_to_field) { + PrintF(file, ":c->f"); + } else { + PrintF(file, ":%s->%s", + old_representation.Mnemonic(), + new_representation.Mnemonic()); + } + PrintF(file, " ("); + if (strlen(reason) > 0) { + PrintF(file, "%s", reason); + } else { + PrintF(file, "+%i maps", descriptors - split); + } + PrintF(file, ") ["); JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); PrintF(file, "]\n"); } @@ -1988,7 +2000,7 @@ MaybeObject* JSObject::AddConstantProperty( ConstantDescriptor d(name, constant, attributes); TransitionFlag flag = - // Do not add transitions to global objects. + // Do not add transitions to global objects. (IsGlobalObject() || // Don't add transitions to special properties with non-trivial // attributes. @@ -2190,55 +2202,6 @@ MaybeObject* JSObject::ReplaceSlowProperty(Name* name, } -MaybeObject* JSObject::ConvertTransitionToMapTransition( - int transition_index, - Name* name, - Object* new_value, - PropertyAttributes attributes) { - Map* old_map = map(); - Map* old_target = old_map->GetTransition(transition_index); - Object* result; - - MaybeObject* maybe_result = ConvertDescriptorToField( - name, new_value, attributes, OMIT_TRANSITION_KEEP_REPRESENTATIONS); - if (!maybe_result->To(&result)) return maybe_result; - - if (!HasFastProperties()) return result; - - // This method should only be used to convert existing transitions. - Map* new_map = map(); - - // TODO(verwaest): From here on we lose existing map transitions, causing - // invalid back pointers. This will change once we can store multiple - // transitions with the same key. - bool owned_descriptors = old_map->owns_descriptors(); - if (owned_descriptors || - old_target->instance_descriptors() == old_map->instance_descriptors()) { - // Since the conversion above generated a new fast map with an additional - // property which can be shared as well, install this descriptor pointer - // along the entire chain of smaller maps. - Map* map; - DescriptorArray* new_descriptors = new_map->instance_descriptors(); - DescriptorArray* old_descriptors = old_map->instance_descriptors(); - for (Object* current = old_map; - !current->IsUndefined(); - current = map->GetBackPointer()) { - map = Map::cast(current); - if (map->instance_descriptors() != old_descriptors) break; - map->SetEnumLength(Map::kInvalidEnumCache); - map->set_instance_descriptors(new_descriptors); - } - old_map->set_owns_descriptors(false); - } - - old_target->DeprecateTransitionTree(); - - old_map->SetTransition(transition_index, new_map); - new_map->SetBackPointer(old_map); - return result; -} - - MaybeObject* JSObject::ConvertDescriptorToField(Name* name, Object* new_value, PropertyAttributes attributes, @@ -2491,10 +2454,11 @@ MaybeObject* JSObject::MigrateToMap(Map* new_map) { MaybeObject* JSObject::GeneralizeFieldRepresentation( int modify_index, - Representation new_representation) { + Representation new_representation, + StoreMode store_mode) { Map* new_map; - MaybeObject* maybe_new_map = - map()->GeneralizeRepresentation(modify_index, new_representation); + MaybeObject* maybe_new_map = map()->GeneralizeRepresentation( + modify_index, new_representation, store_mode); if (!maybe_new_map->To(&new_map)) return maybe_new_map; if (map() == new_map) return this; @@ -2512,16 +2476,39 @@ int Map::NumberOfFields() { } -MaybeObject* Map::CopyGeneralizeAllRepresentations() { +MaybeObject* Map::CopyGeneralizeAllRepresentations( + int modify_index, + StoreMode store_mode, + const char* reason) { Map* new_map; MaybeObject* maybe_map = this->Copy(); if (!maybe_map->To(&new_map)) return maybe_map; - new_map->instance_descriptors()->InitializeRepresentations( - Representation::Tagged()); + DescriptorArray* descriptors = new_map->instance_descriptors(); + descriptors->InitializeRepresentations(Representation::Tagged()); + + // Unless the instance is being migrated, ensure that modify_index is a field. + PropertyDetails details = descriptors->GetDetails(modify_index); + if (store_mode == FORCE_FIELD && details.type() != FIELD) { + FieldDescriptor d(descriptors->GetKey(modify_index), + new_map->NumberOfFields(), + details.attributes(), + Representation::Tagged()); + d.SetSortedKeyIndex(details.pointer()); + descriptors->Set(modify_index, &d); + int unused_property_fields = new_map->unused_property_fields() - 1; + if (unused_property_fields < 0) { + unused_property_fields += JSObject::kFieldsAdded; + } + new_map->set_unused_property_fields(unused_property_fields); + } + if (FLAG_trace_generalization) { - PrintF("failed generalization %p -> %p\n", - static_cast(this), static_cast(new_map)); + PrintGeneralization(stdout, reason, modify_index, + new_map->NumberOfOwnDescriptors(), + new_map->NumberOfOwnDescriptors(), + details.type() == CONSTANT && store_mode == FORCE_FIELD, + Representation::Tagged(), Representation::Tagged()); } return new_map; } @@ -2666,7 +2653,8 @@ Map* Map::FindLastMatchMap(int verbatim, // - Otherwise, invalidate the outdated transition target from |updated|, and // replace its transition tree with a new branch for the updated descriptors. MaybeObject* Map::GeneralizeRepresentation(int modify_index, - Representation new_representation) { + Representation new_representation, + StoreMode store_mode) { Map* old_map = this; DescriptorArray* old_descriptors = old_map->instance_descriptors(); Representation old_representation = @@ -2688,38 +2676,45 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, // Check the state of the root map. if (!old_map->EquivalentToForTransition(root_map)) { - return CopyGeneralizeAllRepresentations(); + return CopyGeneralizeAllRepresentations( + modify_index, store_mode, "not equivalent"); } int verbatim = root_map->NumberOfOwnDescriptors(); + if (store_mode != ALLOW_AS_CONSTANT && modify_index < verbatim) { + return CopyGeneralizeAllRepresentations( + modify_index, store_mode, "root modification"); + } + Map* updated = root_map->FindUpdatedMap( verbatim, descriptors, old_descriptors); - if (updated == NULL) return CopyGeneralizeAllRepresentations(); + if (updated == NULL) { + return CopyGeneralizeAllRepresentations( + modify_index, store_mode, "incompatible"); + } DescriptorArray* updated_descriptors = updated->instance_descriptors(); int valid = updated->NumberOfOwnDescriptors(); + + // Directly change the map if the target map is more general. Ensure that the + // target type of the modify_index is a FIELD, unless we are migrating. if (updated_descriptors->IsMoreGeneralThan( - verbatim, valid, descriptors, old_descriptors)) { + verbatim, valid, descriptors, old_descriptors) && + (store_mode == ALLOW_AS_CONSTANT || + updated_descriptors->GetDetails(modify_index).type() == FIELD)) { Representation updated_representation = updated_descriptors->GetDetails(modify_index).representation(); - if (new_representation.fits_into(updated_representation)) { - if (FLAG_trace_generalization && - !(modify_index == 0 && new_representation.IsNone())) { - PropertyDetails old_details = old_descriptors->GetDetails(modify_index); - PrintGeneralization(stdout, modify_index, descriptors, descriptors, - old_details.representation(), - updated_representation); - } - return updated; - } + if (new_representation.fits_into(updated_representation)) return updated; } DescriptorArray* new_descriptors; MaybeObject* maybe_descriptors = updated_descriptors->Merge( - verbatim, valid, descriptors, old_descriptors); + verbatim, valid, descriptors, modify_index, store_mode, old_descriptors); if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; + ASSERT(store_mode == ALLOW_AS_CONSTANT || + new_descriptors->GetDetails(modify_index).type() == FIELD); old_representation = new_descriptors->GetDetails(modify_index).representation(); @@ -2741,10 +2736,12 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index, split_map->DeprecateTarget( old_descriptors->GetKey(descriptor), new_descriptors); - if (FLAG_trace_generalization && - !(modify_index == 0 && new_representation.IsNone())) { - PrintGeneralization(stdout, modify_index, descriptor, descriptors, - old_representation, updated_representation); + if (FLAG_trace_generalization) { + PrintGeneralization( + stdout, "", modify_index, descriptor, descriptors, + old_descriptors->GetDetails(modify_index).type() == CONSTANT && + store_mode == FORCE_FIELD, + old_representation, updated_representation); } Map* new_map = split_map; @@ -3782,14 +3779,92 @@ Handle JSObject::TryMigrateInstance(Handle object) { Handle Map::GeneralizeRepresentation(Handle map, int modify_index, - Representation representation) { + Representation representation, + StoreMode store_mode) { CALL_HEAP_FUNCTION( map->GetIsolate(), - map->GeneralizeRepresentation(modify_index, representation), + map->GeneralizeRepresentation(modify_index, representation, store_mode), Map); } +static MaybeObject* SetPropertyUsingTransition(LookupResult* lookup, + Handle name, + Handle value, + PropertyAttributes attributes) { + Map* transition_map = lookup->GetTransitionTarget(); + int descriptor = transition_map->LastAdded(); + + DescriptorArray* descriptors = transition_map->instance_descriptors(); + PropertyDetails details = descriptors->GetDetails(descriptor); + + if (details.type() == CALLBACKS || attributes != details.attributes()) { + return lookup->holder()->ConvertDescriptorToField( + *name, *value, attributes); + } + + // Keep the target CONSTANT if the same value is stored. + // TODO(verwaest): Also support keeping the placeholder + // (value->IsUninitialized) as constant. + if (details.type() == CONSTANT && + descriptors->GetValue(descriptor) == *value) { + lookup->holder()->set_map(transition_map); + return *value; + } + + Representation representation = details.representation(); + + if (!value->FitsRepresentation(representation) || + details.type() == CONSTANT) { + MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( + descriptor, value->OptimalRepresentation(), FORCE_FIELD); + if (!maybe_map->To(&transition_map)) return maybe_map; + Object* back = transition_map->GetBackPointer(); + if (back->IsMap()) { + MaybeObject* maybe_failure = + lookup->holder()->MigrateToMap(Map::cast(back)); + if (maybe_failure->IsFailure()) return maybe_failure; + } + descriptors = transition_map->instance_descriptors(); + representation = descriptors->GetDetails(descriptor).representation(); + } + + int field_index = descriptors->GetFieldIndex(descriptor); + return lookup->holder()->AddFastPropertyUsingMap( + transition_map, *name, *value, field_index, representation); +} + + +static MaybeObject* SetPropertyToField(LookupResult* lookup, + Handle name, + Handle value) { + Representation representation = lookup->representation(); + if (!value->FitsRepresentation(representation) || + lookup->type() == CONSTANT) { + MaybeObject* maybe_failure = + lookup->holder()->GeneralizeFieldRepresentation( + lookup->GetDescriptorIndex(), + value->OptimalRepresentation(), + FORCE_FIELD); + if (maybe_failure->IsFailure()) return maybe_failure; + DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); + int descriptor = lookup->GetDescriptorIndex(); + representation = desc->GetDetails(descriptor).representation(); + } + + if (FLAG_track_double_fields && representation.IsDouble()) { + HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( + lookup->GetFieldIndex().field_index())); + storage->set_value(value->Number()); + return *value; + } + + lookup->holder()->FastPropertyAtPut( + lookup->GetFieldIndex().field_index(), *value); + return *value; +} + + MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, Name* name_raw, Object* value_raw, @@ -3878,37 +3953,13 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, case NORMAL: result = lookup->holder()->SetNormalizedProperty(lookup, *value); break; - case FIELD: { - Representation representation = lookup->representation(); - if (!value->FitsRepresentation(representation)) { - MaybeObject* maybe_failure = - lookup->holder()->GeneralizeFieldRepresentation( - lookup->GetDescriptorIndex(), value->OptimalRepresentation()); - if (maybe_failure->IsFailure()) return maybe_failure; - DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); - int descriptor = lookup->GetDescriptorIndex(); - representation = desc->GetDetails(descriptor).representation(); - } - if (FLAG_track_double_fields && representation.IsDouble()) { - HeapNumber* storage = - HeapNumber::cast(lookup->holder()->RawFastPropertyAt( - lookup->GetFieldIndex().field_index())); - storage->set_value(value->Number()); - result = *value; - break; - } - lookup->holder()->FastPropertyAtPut( - lookup->GetFieldIndex().field_index(), *value); - result = *value; + case FIELD: + result = SetPropertyToField(lookup, name, value); break; - } case CONSTANT: // Only replace the constant if necessary. if (*value == lookup->GetConstant()) return *value; - // Preserve the attributes of this existing property. - attributes = lookup->GetAttributes(); - result = lookup->holder()->ConvertDescriptorToField( - *name, *value, attributes); + result = SetPropertyToField(lookup, name, value); break; case CALLBACKS: { Object* callback_object = lookup->GetCallbackObject(); @@ -3920,55 +3971,7 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* lookup, *name, *value, attributes, strict_mode); break; case TRANSITION: { - Map* transition_map = lookup->GetTransitionTarget(); - int descriptor = transition_map->LastAdded(); - - DescriptorArray* descriptors = transition_map->instance_descriptors(); - PropertyDetails details = descriptors->GetDetails(descriptor); - - if (details.type() == FIELD) { - if (attributes == details.attributes()) { - Representation representation = details.representation(); - if (!value->FitsRepresentation(representation)) { - MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( - descriptor, value->OptimalRepresentation()); - if (!maybe_map->To(&transition_map)) return maybe_map; - Object* back = transition_map->GetBackPointer(); - if (back->IsMap()) { - MaybeObject* maybe_failure = - lookup->holder()->MigrateToMap(Map::cast(back)); - if (maybe_failure->IsFailure()) return maybe_failure; - } - DescriptorArray* desc = transition_map->instance_descriptors(); - int descriptor = transition_map->LastAdded(); - representation = desc->GetDetails(descriptor).representation(); - } - int field_index = descriptors->GetFieldIndex(descriptor); - result = lookup->holder()->AddFastPropertyUsingMap( - transition_map, *name, *value, field_index, representation); - } else { - result = lookup->holder()->ConvertDescriptorToField( - *name, *value, attributes); - } - } else if (details.type() == CALLBACKS) { - result = lookup->holder()->ConvertDescriptorToField( - *name, *value, attributes); - } else { - ASSERT(details.type() == CONSTANT); - - Object* constant = descriptors->GetValue(descriptor); - if (constant == *value) { - // If the same constant function is being added we can simply - // transition to the target map. - lookup->holder()->set_map(transition_map); - result = constant; - } else { - // Otherwise, replace with a map transition to a new map with a FIELD, - // even if the value is a constant function. - result = lookup->holder()->ConvertTransitionToMapTransition( - lookup->GetTransitionIndex(), *name, *value, attributes); - } - } + result = SetPropertyUsingTransition(lookup, name, value, attributes); break; } case HANDLER: @@ -4088,87 +4091,24 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( result = self->SetNormalizedProperty(*name, *value, details); break; } - case FIELD: { - Representation representation = lookup.representation(); - Representation value_representation = - value->OptimalRepresentation(value_type); - if (value_representation.IsNone()) break; - if (!value_representation.fits_into(representation)) { - MaybeObject* maybe_failure = self->GeneralizeFieldRepresentation( - lookup.GetDescriptorIndex(), value_representation); - if (maybe_failure->IsFailure()) return maybe_failure; - DescriptorArray* desc = self->map()->instance_descriptors(); - int descriptor = lookup.GetDescriptorIndex(); - representation = desc->GetDetails(descriptor).representation(); - } - if (FLAG_track_double_fields && representation.IsDouble()) { - HeapNumber* storage = - HeapNumber::cast(self->RawFastPropertyAt( - lookup.GetFieldIndex().field_index())); - storage->set_value(value->Number()); - result = *value; - break; - } - self->FastPropertyAtPut(lookup.GetFieldIndex().field_index(), *value); - result = *value; + case FIELD: + if (value->IsUninitialized()) break; + result = SetPropertyToField(&lookup, name, value); break; - } case CONSTANT: - // Only replace the function if necessary. - if (*value != lookup.GetConstant()) { - // Preserve the attributes of this existing property. - attributes = lookup.GetAttributes(); - result = self->ConvertDescriptorToField(*name, *value, attributes); - } + // Only replace the constant if necessary. + if (*value == lookup.GetConstant()) return *value; + if (value->IsUninitialized()) break; + result = SetPropertyToField(&lookup, name, value); break; case CALLBACKS: case INTERCEPTOR: // Override callback in clone result = self->ConvertDescriptorToField(*name, *value, attributes); break; - case TRANSITION: { - Map* transition_map = lookup.GetTransitionTarget(); - int descriptor = transition_map->LastAdded(); - - DescriptorArray* descriptors = transition_map->instance_descriptors(); - PropertyDetails details = descriptors->GetDetails(descriptor); - - if (details.type() == FIELD) { - if (attributes == details.attributes()) { - Representation representation = details.representation(); - Representation value_representation = - value->OptimalRepresentation(value_type); - if (!value_representation.fits_into(representation)) { - MaybeObject* maybe_map = transition_map->GeneralizeRepresentation( - descriptor, value_representation); - if (!maybe_map->To(&transition_map)) return maybe_map; - Object* back = transition_map->GetBackPointer(); - if (back->IsMap()) { - MaybeObject* maybe_failure = self->MigrateToMap(Map::cast(back)); - if (maybe_failure->IsFailure()) return maybe_failure; - } - DescriptorArray* desc = transition_map->instance_descriptors(); - int descriptor = transition_map->LastAdded(); - representation = desc->GetDetails(descriptor).representation(); - } - int field_index = descriptors->GetFieldIndex(descriptor); - result = self->AddFastPropertyUsingMap( - transition_map, *name, *value, field_index, representation); - } else { - result = self->ConvertDescriptorToField(*name, *value, attributes); - } - } else if (details.type() == CALLBACKS) { - result = self->ConvertDescriptorToField(*name, *value, attributes); - } else { - ASSERT(details.type() == CONSTANT); - - // Replace transition to CONSTANT FUNCTION with a map transition to a - // new map with a FIELD, even if the value is a function. - result = self->ConvertTransitionToMapTransition( - lookup.GetTransitionIndex(), *name, *value, attributes); - } + case TRANSITION: + result = SetPropertyUsingTransition(&lookup, name, value, attributes); break; - } case HANDLER: case NONEXISTENT: UNREACHABLE(); @@ -6675,7 +6615,7 @@ MaybeObject* Map::CopyReplaceDescriptors(DescriptorArray* descriptors, if (!maybe_transitions->To(&transitions)) return maybe_transitions; set_transitions(transitions); result->SetBackPointer(this); - } else if (flag != OMIT_TRANSITION_KEEP_REPRESENTATIONS) { + } else { descriptors->InitializeRepresentations(Representation::Tagged()); } @@ -7803,6 +7743,8 @@ void DescriptorArray::CopyFrom(int dst_index, MaybeObject* DescriptorArray::Merge(int verbatim, int valid, int new_size, + int modify_index, + StoreMode store_mode, DescriptorArray* other) { ASSERT(verbatim <= valid); ASSERT(valid <= new_size); @@ -7836,6 +7778,7 @@ MaybeObject* DescriptorArray::Merge(int verbatim, PropertyDetails other_details = other->GetDetails(descriptor); if (details.type() == FIELD || other_details.type() == FIELD || + (store_mode == FORCE_FIELD && descriptor == modify_index) || (details.type() == CONSTANT && other_details.type() == CONSTANT && GetValue(descriptor) != other->GetValue(descriptor))) { @@ -7854,7 +7797,8 @@ MaybeObject* DescriptorArray::Merge(int verbatim, // |valid| -> |new_size| for (; descriptor < new_size; descriptor++) { PropertyDetails details = other->GetDetails(descriptor); - if (details.type() == FIELD) { + if (details.type() == FIELD || + (store_mode == FORCE_FIELD && descriptor == modify_index)) { Name* key = other->GetKey(descriptor); FieldDescriptor d(key, current_offset++, diff --git a/src/objects.h b/src/objects.h index ffd8584d56..8597d4507f 100644 --- a/src/objects.h +++ b/src/objects.h @@ -232,6 +232,13 @@ static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) { enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER }; +// Indicates whether a value can be loaded as a constant. +enum StoreMode { + ALLOW_AS_CONSTANT, + FORCE_FIELD +}; + + // PropertyNormalizationMode is used to specify whether to keep // inobject properties when normalizing properties of a JSObject. enum PropertyNormalizationMode { @@ -258,7 +265,6 @@ enum CreationFlag { // Indicates whether transitions can be added to a source map or not. enum TransitionFlag { INSERT_TRANSITION, - OMIT_TRANSITION_KEEP_REPRESENTATIONS, OMIT_TRANSITION }; @@ -1926,12 +1932,6 @@ class JSReceiver: public HeapObject { CERTAINLY_NOT_STORE_FROM_KEYED }; - // Indicates whether a value can be loaded as a constant. - enum StoreMode { - ALLOW_AS_CONSTANT, - FORCE_FIELD - }; - // Internal properties (e.g. the hidden properties dictionary) might // be added even though the receiver is non-extensible. enum ExtensibilityCheck { @@ -2522,13 +2522,6 @@ class JSObject: public JSReceiver { MUST_USE_RESULT MaybeObject* TransitionElementsKind(ElementsKind to_kind); MUST_USE_RESULT MaybeObject* UpdateAllocationSite(ElementsKind to_kind); - // Replaces an existing transition with a transition to a map with a FIELD. - MUST_USE_RESULT MaybeObject* ConvertTransitionToMapTransition( - int transition_index, - Name* name, - Object* new_value, - PropertyAttributes attributes); - // Converts a descriptor of any other type to a real field, backed by the // properties array. MUST_USE_RESULT MaybeObject* ConvertDescriptorToField( @@ -2540,7 +2533,8 @@ class JSObject: public JSReceiver { MUST_USE_RESULT MaybeObject* MigrateToMap(Map* new_map); MUST_USE_RESULT MaybeObject* GeneralizeFieldRepresentation( int modify_index, - Representation new_representation); + Representation new_representation, + StoreMode store_mode); // Add a property to a fast-case object. MUST_USE_RESULT MaybeObject* AddFastProperty( @@ -3190,6 +3184,8 @@ class DescriptorArray: public FixedArray { MUST_USE_RESULT MaybeObject* Merge(int verbatim, int valid, int new_size, + int modify_index, + StoreMode store_mode, DescriptorArray* other); bool IsMoreGeneralThan(int verbatim, @@ -5619,16 +5615,23 @@ class Map: public HeapObject { static Handle GeneralizeRepresentation( Handle map, int modify_index, - Representation new_representation); + Representation new_representation, + StoreMode store_mode); MUST_USE_RESULT MaybeObject* GeneralizeRepresentation( int modify_index, - Representation representation); - MUST_USE_RESULT MaybeObject* CopyGeneralizeAllRepresentations(); + Representation representation, + StoreMode store_mode); + MUST_USE_RESULT MaybeObject* CopyGeneralizeAllRepresentations( + int modify_index, + StoreMode store_mode, + const char* reason); void PrintGeneralization(FILE* file, + const char* reason, int modify_index, int split, int descriptors, + bool constant_to_field, Representation old_representation, Representation new_representation); diff --git a/src/property.h b/src/property.h index d109de91d1..19425ed281 100644 --- a/src/property.h +++ b/src/property.h @@ -422,12 +422,10 @@ class LookupResult BASE_EMBEDDED { PropertyIndex GetFieldIndex() { ASSERT(lookup_type_ == DESCRIPTOR_TYPE); - ASSERT(IsField()); return PropertyIndex::NewFieldIndex(GetFieldIndexFromMap(holder()->map())); } int GetLocalFieldIndexFromMap(Map* map) { - ASSERT(IsField()); return GetFieldIndexFromMap(map) - map->inobject_properties(); } diff --git a/src/runtime.cc b/src/runtime.cc index da0229429d..3f4889e1cd 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -290,9 +290,7 @@ static Handle CreateObjectLiteralBoilerplate( } Handle result; uint32_t element_index = 0; - JSReceiver::StoreMode mode = value->IsJSObject() - ? JSReceiver::FORCE_FIELD - : JSReceiver::ALLOW_AS_CONSTANT; + StoreMode mode = value->IsJSObject() ? FORCE_FIELD : ALLOW_AS_CONSTANT; if (key->IsInternalizedString()) { if (Handle::cast(key)->AsArrayIndex(&element_index)) { // Array index as string (uint32).