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

Unified Diff: src/objects.cc

Issue 661133002: TransitionArray now uses <is_data_property, name, attributes> tuple as a key, which allows to have … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 6 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 9933e9c61497c8d3307ea4643cc96b65bc0eca07..22fc58c7ed82040ed553165c179306799a06a910 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1934,7 +1934,7 @@ bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
void Map::ConnectElementsTransition(Handle<Map> parent, Handle<Map> child) {
Isolate* isolate = parent->GetIsolate();
Handle<Name> name = isolate->factory()->elements_transition_symbol();
- ConnectTransition(parent, child, name, FULL_TRANSITION);
+ ConnectTransition(parent, child, name, SPECIAL_TRANSITION);
}
@@ -2228,10 +2228,12 @@ void Map::DeprecateTransitionTree() {
// Invalidates a transition target at |key|, and installs |new_descriptors| over
// the current instance_descriptors to ensure proper sharing of descriptor
// arrays.
-void Map::DeprecateTarget(Name* key, DescriptorArray* new_descriptors) {
+void Map::DeprecateTarget(PropertyType type, Name* key,
+ PropertyAttributes attributes,
+ DescriptorArray* new_descriptors) {
if (HasTransitionArray()) {
TransitionArray* transitions = this->transitions();
- int transition = transitions->Search(key);
+ int transition = transitions->Search(type, key, attributes);
if (transition != TransitionArray::kNotFound) {
transitions->GetTarget(transition)->DeprecateTransitionTree();
}
@@ -2278,14 +2280,15 @@ Map* Map::FindLastMatchMap(int verbatim,
for (int i = verbatim; i < length; i++) {
if (!current->HasTransitionArray()) break;
Name* name = descriptors->GetKey(i);
+ PropertyDetails details = descriptors->GetDetails(i);
TransitionArray* transitions = current->transitions();
- int transition = transitions->Search(name);
+ int transition =
+ transitions->Search(details.type(), name, details.attributes());
if (transition == TransitionArray::kNotFound) break;
Map* next = transitions->GetTarget(transition);
DescriptorArray* next_descriptors = next->instance_descriptors();
- PropertyDetails details = descriptors->GetDetails(i);
PropertyDetails next_details = next_descriptors->GetDetails(i);
if (details.type() != next_details.type()) break;
if (details.attributes() != next_details.attributes()) break;
@@ -2475,21 +2478,23 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
Handle<Map> target_map = root_map;
for (int i = root_nof; i < old_nof; ++i) {
- int j = target_map->SearchTransition(old_descriptors->GetKey(i));
+ PropertyDetails old_details = old_descriptors->GetDetails(i);
+ int j = target_map->SearchTransition(old_details.type(),
+ old_descriptors->GetKey(i),
+ old_details.attributes());
if (j == TransitionArray::kNotFound) break;
Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
Handle<DescriptorArray> tmp_descriptors = handle(
tmp_map->instance_descriptors(), isolate);
// Check if target map is incompatible.
- PropertyDetails old_details = old_descriptors->GetDetails(i);
PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
PropertyType old_type = old_details.type();
PropertyType tmp_type = tmp_details.type();
- if (tmp_details.attributes() != old_details.attributes() ||
- ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
- (tmp_type != old_type ||
- tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
+ DCHECK_EQ(old_details.attributes(), tmp_details.attributes());
+ if ((tmp_type == CALLBACKS || old_type == CALLBACKS) &&
+ (tmp_type != old_type ||
+ tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
return CopyGeneralizeAllRepresentations(
old_map, modify_index, store_mode, "incompatible");
}
@@ -2541,19 +2546,21 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
// Find the last compatible target map in the transition tree.
for (int i = target_nof; i < old_nof; ++i) {
- int j = target_map->SearchTransition(old_descriptors->GetKey(i));
+ PropertyDetails old_details = old_descriptors->GetDetails(i);
+ int j = target_map->SearchTransition(old_details.type(),
+ old_descriptors->GetKey(i),
+ old_details.attributes());
if (j == TransitionArray::kNotFound) break;
Handle<Map> tmp_map(target_map->GetTransition(j), isolate);
Handle<DescriptorArray> tmp_descriptors(
tmp_map->instance_descriptors(), isolate);
// Check if target map is compatible.
- PropertyDetails old_details = old_descriptors->GetDetails(i);
PropertyDetails tmp_details = tmp_descriptors->GetDetails(i);
- if (tmp_details.attributes() != old_details.attributes() ||
- ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) &&
- (tmp_details.type() != old_details.type() ||
- tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i)))) {
+ DCHECK_EQ(old_details.attributes(), tmp_details.attributes());
+ if ((tmp_details.type() == CALLBACKS || old_details.type() == CALLBACKS) &&
+ (tmp_details.type() != old_details.type() ||
+ tmp_descriptors->GetValue(i) != old_descriptors->GetValue(i))) {
return CopyGeneralizeAllRepresentations(
old_map, modify_index, store_mode, "incompatible");
}
@@ -2685,8 +2692,10 @@ Handle<Map> Map::GeneralizeRepresentation(Handle<Map> old_map,
int split_nof = split_map->NumberOfOwnDescriptors();
DCHECK_NE(old_nof, split_nof);
- split_map->DeprecateTarget(
- old_descriptors->GetKey(split_nof), *new_descriptors);
+ PropertyDetails split_prop_details = old_descriptors->GetDetails(split_nof);
+ split_map->DeprecateTarget(split_prop_details.type(),
+ old_descriptors->GetKey(split_nof),
+ split_prop_details.attributes(), *new_descriptors);
if (FLAG_trace_generalization) {
PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
@@ -2775,13 +2784,15 @@ MaybeHandle<Map> Map::TryUpdateInternal(Handle<Map> old_map) {
Map* new_map = root_map;
for (int i = root_nof; i < old_nof; ++i) {
- int j = new_map->SearchTransition(old_descriptors->GetKey(i));
+ PropertyDetails old_details = old_descriptors->GetDetails(i);
+ int j = new_map->SearchTransition(old_details.type(),
+ old_descriptors->GetKey(i),
+ old_details.attributes());
if (j == TransitionArray::kNotFound) return MaybeHandle<Map>();
new_map = new_map->GetTransition(j);
DescriptorArray* new_descriptors = new_map->instance_descriptors();
PropertyDetails new_details = new_descriptors->GetDetails(i);
- PropertyDetails old_details = old_descriptors->GetDetails(i);
if (old_details.attributes() != new_details.attributes() ||
!old_details.representation().fits_into(new_details.representation())) {
return MaybeHandle<Map>();
@@ -5380,8 +5391,8 @@ MaybeHandle<Object> JSObject::Freeze(Handle<JSObject> object) {
}
Handle<Map> old_map(object->map(), isolate);
- int transition_index = old_map->SearchTransition(
- isolate->heap()->frozen_symbol());
+ int transition_index =
+ old_map->SearchSpecialTransition(isolate->heap()->frozen_symbol());
if (transition_index != TransitionArray::kNotFound) {
Handle<Map> transition_map(old_map->GetTransition(transition_index));
DCHECK(transition_map->has_dictionary_elements());
@@ -5433,8 +5444,8 @@ void JSObject::SetObserved(Handle<JSObject> object) {
Handle<Map> new_map;
Handle<Map> old_map(object->map(), isolate);
DCHECK(!old_map->is_observed());
- int transition_index = old_map->SearchTransition(
- isolate->heap()->observed_symbol());
+ int transition_index =
+ old_map->SearchSpecialTransition(isolate->heap()->observed_symbol());
if (transition_index != TransitionArray::kNotFound) {
new_map = handle(old_map->GetTransition(transition_index), isolate);
DCHECK(new_map->is_observed());
@@ -6601,7 +6612,7 @@ Handle<Map> Map::ShareDescriptor(Handle<Map> map,
}
DCHECK(result->NumberOfOwnDescriptors() == map->NumberOfOwnDescriptors() + 1);
- ConnectTransition(map, result, name, SIMPLE_TRANSITION);
+ ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION);
return result;
}
@@ -6677,7 +6688,7 @@ Handle<Map> Map::CopyInstallDescriptors(Handle<Map> map,
result->set_unused_property_fields(unused_property_fields);
Handle<Name> name = handle(descriptors->GetKey(new_descriptor));
- ConnectTransition(map, result, name, SIMPLE_TRANSITION);
+ ConnectTransition(map, result, name, SIMPLE_PROPERTY_TRANSITION);
return result;
}
@@ -6751,7 +6762,7 @@ Handle<Map> Map::CopyForObserved(Handle<Map> map) {
if (map->CanHaveMoreTransitions()) {
Handle<Name> name = isolate->factory()->observed_symbol();
- ConnectTransition(map, new_map, name, FULL_TRANSITION);
+ ConnectTransition(map, new_map, name, SPECIAL_TRANSITION);
}
return new_map;
}
@@ -6762,8 +6773,8 @@ Handle<Map> Map::Copy(Handle<Map> map) {
int number_of_own_descriptors = map->NumberOfOwnDescriptors();
Handle<DescriptorArray> new_descriptors =
DescriptorArray::CopyUpTo(descriptors, number_of_own_descriptors);
- return CopyReplaceDescriptors(
- map, new_descriptors, OMIT_TRANSITION, MaybeHandle<Name>());
+ return CopyReplaceDescriptors(map, new_descriptors, OMIT_TRANSITION,
+ MaybeHandle<Name>(), SPECIAL_TRANSITION);
}
@@ -6798,7 +6809,8 @@ Handle<Map> Map::CopyForFreeze(Handle<Map> map) {
Handle<DescriptorArray> new_desc = DescriptorArray::CopyUpToAddAttributes(
handle(map->instance_descriptors(), isolate), num_descriptors, FROZEN);
Handle<Map> new_map = CopyReplaceDescriptors(
- map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol());
+ map, new_desc, INSERT_TRANSITION, isolate->factory()->frozen_symbol(),
+ SPECIAL_TRANSITION);
new_map->freeze();
new_map->set_is_extensible(false);
new_map->set_elements_kind(DICTIONARY_ELEMENTS);
@@ -6862,16 +6874,14 @@ Handle<Map> Map::TransitionToDataProperty(Handle<Map> map, Handle<Name> name,
// Migrate to the newest map before storing the property.
map = Update(map);
- int index = map->SearchTransition(*name);
+ int index = map->SearchTransition(FIELD, *name, attributes);
if (index != TransitionArray::kNotFound) {
Handle<Map> transition(map->GetTransition(index));
int descriptor = transition->LastAdded();
- // TODO(verwaest): Handle attributes better.
- DescriptorArray* descriptors = transition->instance_descriptors();
- if (descriptors->GetDetails(descriptor).attributes() != attributes) {
- return Map::Normalize(map, CLEAR_INOBJECT_PROPERTIES);
- }
+ DCHECK_EQ(attributes, transition->instance_descriptors()
+ ->GetDetails(descriptor)
+ .attributes());
return Map::PrepareForDataProperty(transition, descriptor, value);
}
@@ -6931,25 +6941,15 @@ Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map,
? KEEP_INOBJECT_PROPERTIES
: CLEAR_INOBJECT_PROPERTIES;
- int index = map->SearchTransition(*name);
+ int index = map->SearchTransition(CALLBACKS, *name, attributes);
if (index != TransitionArray::kNotFound) {
Handle<Map> transition(map->GetTransition(index));
DescriptorArray* descriptors = transition->instance_descriptors();
- // Fast path, assume that we're modifying the last added descriptor.
int descriptor = transition->LastAdded();
- if (descriptors->GetKey(descriptor) != *name) {
- // If not, search for the descriptor.
- descriptor = descriptors->SearchWithCache(*name, *transition);
- }
+ DCHECK(descriptors->GetKey(descriptor)->Equals(*name));
- if (descriptors->GetDetails(descriptor).type() != CALLBACKS) {
- return Map::Normalize(map, mode);
- }
-
- // TODO(verwaest): Handle attributes better.
- if (descriptors->GetDetails(descriptor).attributes() != attributes) {
- return Map::Normalize(map, mode);
- }
+ DCHECK_EQ(CALLBACKS, descriptors->GetDetails(descriptor).type());
+ DCHECK_EQ(attributes, descriptors->GetDetails(descriptor).attributes());
Handle<Object> maybe_pair(descriptors->GetValue(descriptor), isolate);
if (!maybe_pair->IsAccessorPair()) {
@@ -6968,6 +6968,9 @@ Handle<Map> Map::TransitionToAccessorProperty(Handle<Map> map,
DescriptorArray* old_descriptors = map->instance_descriptors();
int descriptor = old_descriptors->SearchWithCache(*name, *map);
if (descriptor != DescriptorArray::kNotFound) {
+ if (descriptor != map->LastAdded()) {
+ return Map::Normalize(map, mode);
+ }
PropertyDetails old_details = old_descriptors->GetDetails(descriptor);
if (old_details.type() != CALLBACKS) {
return Map::Normalize(map, mode);
@@ -7022,8 +7025,9 @@ Handle<Map> Map::CopyAddDescriptor(Handle<Map> map,
descriptors, map->NumberOfOwnDescriptors(), 1);
new_descriptors->Append(descriptor);
- return CopyReplaceDescriptors(
- map, new_descriptors, flag, descriptor->GetKey(), SIMPLE_TRANSITION);
+ return CopyReplaceDescriptors(map, new_descriptors, flag,
+ descriptor->GetKey(),
+ SIMPLE_PROPERTY_TRANSITION);
}
@@ -7117,8 +7121,8 @@ Handle<Map> Map::CopyReplaceDescriptor(Handle<Map> map,
SimpleTransitionFlag simple_flag =
(insertion_index == descriptors->number_of_descriptors() - 1)
- ? SIMPLE_TRANSITION
- : FULL_TRANSITION;
+ ? SIMPLE_PROPERTY_TRANSITION
+ : PROPERTY_TRANSITION;
return CopyReplaceDescriptors(map, new_descriptors, flag, key, simple_flag);
}
« no previous file with comments | « src/objects.h ('k') | src/objects-debug.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698