Revision: 16275
Author: [email protected]
Date: Thu Aug 22 13:43:06 2013 UTC
Log: Remove special case code for generalizing constants to fields.
[email protected]
Review URL: https://chromiumcodereview.appspot.com/22911018
http://code.google.com/p/v8/source/detail?r=16275
Modified:
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/property.h
/branches/bleeding_edge/src/runtime.cc
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Tue Aug 20 13:55:52 2013 UTC
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Aug 22 13:43:06 2013 UTC
@@ -1143,12 +1143,12 @@
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);
=======================================
--- /branches/bleeding_edge/src/ic.cc Thu Aug 22 12:16:00 2013 UTC
+++ /branches/bleeding_edge/src/ic.cc Thu Aug 22 13:43:06 2013 UTC
@@ -1615,7 +1615,8 @@
if (!value->FitsRepresentation(target_details.representation())) {
Handle<Map> 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);
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Thu Aug 22 12:16:00 2013 UTC
+++ /branches/bleeding_edge/src/objects-inl.h Thu Aug 22 13:43:06 2013 UTC
@@ -1569,7 +1569,7 @@
// 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 @@
int DescriptorArray::GetFieldIndex(int descriptor_number) {
+ ASSERT(GetDetails(descriptor_number).type() == FIELD);
return GetDetails(descriptor_number).field_index();
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Tue Aug 20 10:52:23 2013 UTC
+++ /branches/bleeding_edge/src/objects.cc Thu Aug 22 13:43:06 2013 UTC
@@ -1450,19 +1450,31 @@
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 @@
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.
@@ -2188,55 +2200,6 @@
PropertyDetails new_details(attributes, NORMAL, new_enumeration_index);
return SetNormalizedProperty(name, value, new_details);
}
-
-
-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,
@@ -2491,10 +2454,11 @@
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 @@
}
-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<void*>(this), static_cast<void*>(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 @@
// - 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 @@
// 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 @@
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,13 +3779,91 @@
Handle<Map> Map::GeneralizeRepresentation(Handle<Map> 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> name,
+ Handle<Object> 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> name,
+ Handle<Object> 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,
@@ -3878,37 +3953,13 @@
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 @@
*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 @@
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 @@
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 @@
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 @@
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 @@
// |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++,
=======================================
--- /branches/bleeding_edge/src/objects.h Thu Aug 22 12:16:00 2013 UTC
+++ /branches/bleeding_edge/src/objects.h Thu Aug 22 13:43:06 2013 UTC
@@ -232,6 +232,13 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
static Handle<Map> GeneralizeRepresentation(
Handle<Map> 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);
=======================================
--- /branches/bleeding_edge/src/property.h Wed Jul 24 12:34:50 2013 UTC
+++ /branches/bleeding_edge/src/property.h Thu Aug 22 13:43:06 2013 UTC
@@ -422,12 +422,10 @@
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();
}
=======================================
--- /branches/bleeding_edge/src/runtime.cc Thu Aug 22 13:03:40 2013 UTC
+++ /branches/bleeding_edge/src/runtime.cc Thu Aug 22 13:43:06 2013 UTC
@@ -290,9 +290,7 @@
}
Handle<Object> 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<String>::cast(key)->AsArrayIndex(&element_index)) {
// Array index as string (uint32).
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.