Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index de41ce1eb99781b7a1ad8a9745e03d393e0c37b0..1a3500c3abd7801b981117f2f9dea976263cd7d1 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -2859,18 +2859,11 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, |
attributes, |
strict_mode); |
case TRANSITION: { |
- Object* transition = result->GetTransitionValue(); |
+ Map* transition_map = result->GetTransitionTarget(); |
- if (transition->IsAccessorPair()) { |
- ASSERT(!AccessorPair::cast(transition)->ContainsAccessor()); |
- return ConvertDescriptorToField(*name, *value, attributes); |
- } |
- |
- Map* transition_map = Map::cast(transition); |
DescriptorArray* descriptors = transition_map->instance_descriptors(); |
int descriptor = descriptors->LastAdded(); |
PropertyDetails details = descriptors->GetDetails(descriptor); |
- ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION); |
if (details.type() == FIELD) { |
if (attributes == details.attributes()) { |
@@ -2881,9 +2874,12 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, |
field_index); |
} |
return self->ConvertDescriptorToField(*name, *value, attributes); |
+ } else if (details.type() == CALLBACKS) { |
+ return ConvertDescriptorToField(*name, *value, attributes); |
} |
- // Is transition to CONSTANT_FUNCTION. |
+ ASSERT(details.type() == CONSTANT_FUNCTION); |
+ |
Object* constant_function = descriptors->GetValue(descriptor); |
// If the same constant function is being added we can simply |
// transition to the target map. |
@@ -2983,18 +2979,11 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
// Override callback in clone |
return ConvertDescriptorToField(name, value, attributes); |
case TRANSITION: { |
- Object* transition = result.GetTransitionValue(); |
- |
- if (transition->IsAccessorPair()) { |
- ASSERT(!AccessorPair::cast(transition)->ContainsAccessor()); |
- return ConvertDescriptorToField(name, value, attributes); |
- } |
+ Map* transition_map = result.GetTransitionTarget(); |
- Map* transition_map = Map::cast(transition); |
DescriptorArray* descriptors = transition_map->instance_descriptors(); |
int descriptor = descriptors->LastAdded(); |
PropertyDetails details = descriptors->GetDetails(descriptor); |
- ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION); |
if (details.type() == FIELD) { |
if (attributes == details.attributes()) { |
@@ -3005,10 +2994,14 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
field_index); |
} |
return ConvertDescriptorToField(name, value, attributes); |
+ } else if (details.type() == CALLBACKS) { |
+ return ConvertDescriptorToField(name, value, attributes); |
} |
- // Was transition to CONSTANT_FUNCTION. Replace with a map transition to a |
- // new map with a FIELD, even if the value is a function. |
+ ASSERT(details.type() == CONSTANT_FUNCTION); |
+ |
+ // Replace transition to CONSTANT FUNCTION with a map transition to a new |
+ // map with a FIELD, even if the value is a function. |
return ConvertTransitionToMapTransition( |
result.GetTransitionIndex(), name, value, attributes); |
} |
@@ -3294,11 +3287,6 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, |
} |
case CALLBACKS: { |
Object* value = descs->GetCallbacksObject(i); |
- if (value->IsAccessorPair()) { |
- MaybeObject* maybe_copy = |
- AccessorPair::cast(value)->CopyWithoutTransitions(); |
- if (!maybe_copy->To(&value)) return maybe_copy; |
- } |
MaybeObject* maybe_dictionary = |
dictionary->Add(descs->GetKey(i), value, details); |
if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; |
@@ -4231,7 +4219,7 @@ void JSObject::LookupCallback(String* name, LookupResult* result) { |
current != heap->null_value() && current->IsJSObject(); |
current = JSObject::cast(current)->GetPrototype()) { |
JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); |
- if (result->IsCallbacks()) return; |
+ if (result->IsPropertyCallbacks()) return; |
} |
result->NotFound(); |
} |
@@ -4343,7 +4331,7 @@ MaybeObject* JSObject::CreateAccessorPairFor(String* name) { |
// DefinePropertyAccessor below. |
Object* obj = result.GetCallbackObject(); |
if (obj->IsAccessorPair()) { |
- return AccessorPair::cast(obj)->CopyWithoutTransitions(); |
+ return AccessorPair::cast(obj)->Copy(); |
} |
} |
return GetHeap()->AllocateAccessorPair(); |
@@ -4377,9 +4365,9 @@ MaybeObject* JSObject::DefinePropertyAccessor(String* name, |
} |
AccessorPair* accessors; |
- { MaybeObject* maybe_accessors = CreateAccessorPairFor(name); |
- if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
- } |
+ MaybeObject* maybe_accessors = CreateAccessorPairFor(name); |
+ if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
+ |
accessors->SetComponents(getter, setter); |
return SetPropertyCallback(name, accessors, attributes); |
} |
@@ -4451,17 +4439,16 @@ MaybeObject* JSObject::SetPropertyCallback(String* name, |
Object* structure, |
PropertyAttributes attributes) { |
// Normalize object to make this operation simple. |
- { MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
- if (maybe_ok->IsFailure()) return maybe_ok; |
- } |
+ MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
+ if (maybe_ok->IsFailure()) return maybe_ok; |
// For the global object allocate a new map to invalidate the global inline |
// caches which have a global property cell reference directly in the code. |
if (IsGlobalObject()) { |
Map* new_map; |
- { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
- if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
- } |
+ MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
+ |
set_map(new_map); |
// When running crankshaft, changing the map is not enough. We |
// need to deoptimize all functions that rely on this global |
@@ -4471,9 +4458,8 @@ MaybeObject* JSObject::SetPropertyCallback(String* name, |
// Update the dictionary with the new CALLBACKS property. |
PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
- { MaybeObject* maybe_ok = SetNormalizedProperty(name, structure, details); |
- if (maybe_ok->IsFailure()) return maybe_ok; |
- } |
+ maybe_ok = SetNormalizedProperty(name, structure, details); |
+ if (maybe_ok->IsFailure()) return maybe_ok; |
return GetHeap()->undefined_value(); |
} |
@@ -4525,73 +4511,32 @@ MaybeObject* JSObject::DefineAccessor(String* name, |
} |
-static MaybeObject* CreateFreshAccessor(JSObject* obj, |
- String* name, |
- AccessorComponent component, |
- Object* accessor, |
- PropertyAttributes attributes) { |
- // step 1: create a new getter/setter pair with only the accessor in it |
- Heap* heap = obj->GetHeap(); |
- AccessorPair* accessors2; |
- { MaybeObject* maybe_accessors2 = heap->AllocateAccessorPair(); |
- if (!maybe_accessors2->To(&accessors2)) return maybe_accessors2; |
- } |
- accessors2->set(component, accessor); |
- |
- // step 2: create a copy of the descriptors, incl. the new getter/setter pair |
- Map* map1 = obj->map(); |
- CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0); |
- DescriptorArray* descriptors2; |
- { MaybeObject* maybe_descriptors2 = |
- map1->instance_descriptors()->CopyAdd(&callbacks_descr2); |
- if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2; |
- } |
- |
- // step 3: create a new map with the new descriptors |
- Map* map2; |
- { MaybeObject* maybe_map2 = map1->CopyReplaceDescriptors(descriptors2); |
- if (!maybe_map2->To(&map2)) return maybe_map2; |
- } |
+static MaybeObject* TryAccessorTransition(JSObject* self, |
+ Map* transitioned_map, |
+ String* name, |
+ AccessorComponent component, |
+ Object* accessor, |
+ PropertyAttributes attributes) { |
+ DescriptorArray* descs = transitioned_map->instance_descriptors(); |
+ int number = descs->LastAdded(); |
+ PropertyDetails details = descs->GetDetails(number); |
- // step 4: create a new getter/setter pair with a transition to the new map |
- AccessorPair* accessors1; |
- { MaybeObject* maybe_accessors1 = heap->AllocateAccessorPair(); |
- if (!maybe_accessors1->To(&accessors1)) return maybe_accessors1; |
- } |
- accessors1->set(component, map2); |
+ // If the transition target was not callbacks, fall back to the slow case. |
+ if (details.type() != CALLBACKS) return self->GetHeap()->null_value(); |
- // step 5: create a copy of the descriptors, incl. the new getter/setter pair |
- // with the transition |
- TransitionArray* new_transitions; |
- { MaybeObject* maybe_new_transitions = map1->AddTransition(name, accessors1); |
- if (!maybe_new_transitions->To(&new_transitions)) { |
- return maybe_new_transitions; |
- } |
- } |
+ Object* target_accessor = |
+ AccessorPair::cast(descs->GetCallbacksObject(number))->get(component); |
+ PropertyAttributes target_attributes = details.attributes(); |
- // step 6: everything went well so far, so we make our changes visible |
- { MaybeObject* transition_added = map1->set_transitions(new_transitions); |
- if (transition_added->IsFailure()) return transition_added; |
+ // Reuse transition if adding same accessor with same attributes. |
+ if (target_accessor == accessor && target_attributes == attributes) { |
+ self->set_map(transitioned_map); |
+ return self; |
} |
- map2->SetBackPointer(map1); |
- obj->set_map(map2); |
- return obj; |
-} |
- |
- |
-static bool TransitionToSameAccessor(Object* map, |
- String* name, |
- AccessorComponent component, |
- Object* accessor, |
- PropertyAttributes attributes ) { |
- Map* transitioned_map = Map::cast(map); |
- DescriptorArray* descs = transitioned_map->instance_descriptors(); |
- int number = descs->LastAdded(); |
- Object* target_accessor = |
- AccessorPair::cast(descs->GetCallbacksObject(number))->get(component); |
- PropertyAttributes target_attributes = descs->GetDetails(number).attributes(); |
- return target_accessor == accessor && target_attributes == attributes; |
+ // If either not the same accessor, or not the same attributes, fall back to |
+ // the slow case. |
+ return self->GetHeap()->null_value(); |
} |
@@ -4600,43 +4545,31 @@ static MaybeObject* NewCallbackTransition(JSObject* obj, |
AccessorComponent component, |
Object* accessor, |
PropertyAttributes attributes, |
- AccessorPair* accessors2) { |
- // step 1: copy the old getter/setter pair and set the new accessor |
- AccessorPair* accessors3; |
- { MaybeObject* maybe_accessors3 = accessors2->CopyWithoutTransitions(); |
- if (!maybe_accessors3->To(&accessors3)) return maybe_accessors3; |
- } |
- accessors3->set(component, accessor); |
- |
- // step 2: create a copy of the descriptors, incl. the new getter/setter pair |
- Map* map2 = obj->map(); |
- CallbacksDescriptor callbacks_descr3(name, accessors3, attributes, 0); |
- DescriptorArray* descriptors3; |
- { MaybeObject* maybe_descriptors3 = |
- map2->instance_descriptors()->CopyInsert(&callbacks_descr3); |
- if (!maybe_descriptors3->To(&descriptors3)) return maybe_descriptors3; |
- } |
+ AccessorPair* new_accessors) { |
+ // step 1: create a copy of the descriptors, incl. the new getter/setter pair |
+ Map* old_map = obj->map(); |
+ CallbacksDescriptor new_accessors_desc(name, new_accessors, attributes); |
+ DescriptorArray* descriptors; |
+ MaybeObject* maybe_descriptors = |
+ old_map->instance_descriptors()->CopyInsert(&new_accessors_desc); |
+ if (!maybe_descriptors->To(&descriptors)) return maybe_descriptors; |
- // step 3: create a new map with the new descriptors |
- Map* map3; |
- { MaybeObject* maybe_map3 = map2->CopyReplaceDescriptors(descriptors3); |
- if (!maybe_map3->To(&map3)) return maybe_map3; |
- } |
+ // step 2: create a new map with the new descriptors |
+ Map* new_map; |
+ MaybeObject* maybe_new_map = old_map->CopyReplaceDescriptors(descriptors); |
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
- // step 4: add a new transition to the new map |
- TransitionArray* new_transitions; |
- { MaybeObject* maybe_transitions = map2->AddTransition(name, accessors2); |
- if (!maybe_transitions->To(&new_transitions)) return maybe_transitions; |
- } |
+ // step 3: add a new transition to the new map |
+ TransitionArray* transitions; |
+ MaybeObject* maybe_transitions = old_map->AddTransition(name, new_map); |
+ if (!maybe_transitions->To(&transitions)) return maybe_transitions; |
- // step 5: everything went well so far, so we make our changes visible |
- { MaybeObject* transition_added = map2->set_transitions(new_transitions); |
- if (transition_added->IsFailure()) return transition_added; |
- } |
+ // step 4: everything went well so far, so we make our changes visible |
+ MaybeObject* transition_added = old_map->set_transitions(transitions); |
+ if (transition_added->IsFailure()) return transition_added; |
- map3->SetBackPointer(map2); |
- obj->set_map(map3); |
- accessors2->set(component, map3); |
+ new_map->SetBackPointer(old_map); |
+ obj->set_map(new_map); |
return obj; |
} |
@@ -4649,40 +4582,54 @@ MaybeObject* JSObject::DefineFastAccessor(String* name, |
LookupResult result(GetIsolate()); |
LocalLookup(name, &result); |
- // If we have a new property, create a fresh accessor plus a transition to it. |
- if (!result.IsFound()) { |
- return CreateFreshAccessor(this, name, component, accessor, attributes); |
- } |
+ if (result.IsFound() |
+ && !result.IsPropertyCallbacks() |
+ && !result.IsTransition()) return GetHeap()->null_value(); |
- // If the property is not a JavaScript accessor, fall back to the slow case. |
- if (!result.IsCallbacks()) return GetHeap()->null_value(); |
+ // Return success if the same accessor with the same attributes already exist. |
+ AccessorPair* source_accessors = NULL; |
+ if (result.IsPropertyCallbacks()) { |
+ Object* callback_value = result.GetCallbackObject(); |
+ if (callback_value->IsAccessorPair()) { |
+ source_accessors = AccessorPair::cast(callback_value); |
+ Object* entry = source_accessors->get(component); |
+ if (entry == accessor && result.GetAttributes() == attributes) { |
+ return this; |
+ } |
+ } |
+ } |
- Object* callback_value = result.GetCallbackObject(); |
- if (!callback_value->IsAccessorPair()) return GetHeap()->null_value(); |
- AccessorPair* accessors = AccessorPair::cast(callback_value); |
+ // If not, lookup a transition. |
+ map()->LookupTransition(this, name, &result); |
- // Follow a callback transition, if there is a fitting one. |
- Object* entry = accessors->get(component); |
- if (entry->IsMap() && |
- TransitionToSameAccessor(entry, name, component, accessor, attributes)) { |
- set_map(Map::cast(entry)); |
- return this; |
+ // If there is a transition, try to follow it. |
+ if (result.IsFound()) { |
+ Map* target = result.GetTransitionTarget(); |
+ return TryAccessorTransition( |
+ this, target, name, component, accessor, attributes); |
} |
- if (entry == accessor && result.GetAttributes() == attributes) return this; |
+ // If there is no transition yet, add a transition to the a new accessor pair |
+ // containing the accessor. |
+ AccessorPair* accessors; |
+ MaybeObject* maybe_accessors; |
- // Only the other accessor has been set so far, create a new transition. |
- if (entry->IsTheHole()) { |
- return NewCallbackTransition(this, |
- name, |
- component, |
- accessor, |
- attributes, |
- accessors); |
+ // Allocate a new pair if there were no source accessors. Otherwise, copy the |
+ // pair and modify the accessor. |
+ if (source_accessors != NULL) { |
+ maybe_accessors = source_accessors->Copy(); |
+ } else { |
+ maybe_accessors = GetHeap()->AllocateAccessorPair(); |
} |
+ if (!maybe_accessors->To(&accessors)) return maybe_accessors; |
+ accessors->set(component, accessor); |
- // Nothing from the above worked, so we have to fall back to the slow case. |
- return GetHeap()->null_value(); |
+ return NewCallbackTransition(this, |
+ name, |
+ component, |
+ accessor, |
+ attributes, |
+ accessors); |
} |
@@ -5012,44 +4959,17 @@ class IntrusiveMapTransitionIterator { |
Map* Next() { |
ASSERT(IsIterating()); |
- // Attention, tricky index manipulation ahead: Two consecutive indices are |
- // assigned to each descriptor. Most descriptors directly advance to the |
- // next descriptor by adding 2 to the index. The exceptions are the |
- // CALLBACKS entries: An even index means we look at its getter, and an odd |
- // index means we look at its setter. |
- int raw_index = Smi::cast(*TransitionArrayHeader())->value(); |
- int index = raw_index / 2; |
+ int index = Smi::cast(*TransitionArrayHeader())->value(); |
int number_of_transitions = transition_array_->number_of_transitions(); |
while (index < number_of_transitions) { |
- Object* value = transition_array_->GetValue(index); |
- |
- if (value->IsMap()) { |
- *TransitionArrayHeader() = Smi::FromInt(raw_index + 2); |
- return static_cast<Map*>(value); |
- } |
- |
- ASSERT(value->IsAccessorPair()); |
- |
- // We might have a map transition in a getter or in a setter. |
- AccessorPair* accessors = static_cast<AccessorPair*>(value); |
- Object* accessor; |
- if ((raw_index & 1) == 0) { |
- accessor = accessors->setter(); |
- } else { |
- ++index; |
- accessor = accessors->getter(); |
- } |
- ++raw_index; |
- if (accessor->IsMap()) { |
- *TransitionArrayHeader() = Smi::FromInt(raw_index); |
- return static_cast<Map*>(accessor); |
- } |
+ *TransitionArrayHeader() = Smi::FromInt(index + 1); |
+ return transition_array_->GetTarget(index); |
} |
- if (index == transition_array_->number_of_transitions() && |
+ if (index == number_of_transitions && |
transition_array_->HasElementsTransition()) { |
Map* elements_transition = transition_array_->elements_transition(); |
- *TransitionArrayHeader() = Smi::FromInt(raw_index + 2); |
+ *TransitionArrayHeader() = Smi::FromInt(index + 1); |
return elements_transition; |
} |
*TransitionArrayHeader() = transition_array_->GetHeap()->fixed_array_map(); |
@@ -5786,30 +5706,14 @@ static bool InsertionPointFound(String* key1, String* key2) { |
} |
-void DescriptorArray::CopyFrom(Handle<DescriptorArray> dst, |
- int dst_index, |
- Handle<DescriptorArray> src, |
+void DescriptorArray::CopyFrom(int dst_index, |
+ DescriptorArray* src, |
int src_index, |
const WhitenessWitness& witness) { |
- CALL_HEAP_FUNCTION_VOID(dst->GetIsolate(), |
- dst->CopyFrom(dst_index, *src, src_index, witness)); |
-} |
- |
- |
-MaybeObject* DescriptorArray::CopyFrom(int dst_index, |
- DescriptorArray* src, |
- int src_index, |
- const WhitenessWitness& witness) { |
Object* value = src->GetValue(src_index); |
PropertyDetails details = src->GetDetails(src_index); |
- if (details.type() == CALLBACKS && value->IsAccessorPair()) { |
- MaybeObject* maybe_copy = |
- AccessorPair::cast(value)->CopyWithoutTransitions(); |
- if (!maybe_copy->To(&value)) return maybe_copy; |
- } |
Descriptor desc(src->GetKey(src_index), value, details); |
Set(dst_index, &desc, witness); |
- return this; |
} |
MaybeObject* DescriptorArray::CopyReplace(Descriptor* descriptor, |
@@ -5833,9 +5737,7 @@ MaybeObject* DescriptorArray::CopyReplace(Descriptor* descriptor, |
// Copy the descriptors, replacing a descriptor. |
for (int index = 0; index < size; ++index) { |
if (index == insertion_index) continue; |
- MaybeObject* copy_result = |
- new_descriptors->CopyFrom(index, this, index, witness); |
- if (copy_result->IsFailure()) return copy_result; |
+ new_descriptors->CopyFrom(index, this, index, witness); |
} |
descriptor->SetEnumerationIndex(GetDetails(insertion_index).index()); |
@@ -5850,9 +5752,8 @@ MaybeObject* DescriptorArray::CopyReplace(Descriptor* descriptor, |
MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) { |
// Ensure the key is a symbol. |
- { MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
- if (maybe_result->IsFailure()) return maybe_result; |
- } |
+ MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
+ if (maybe_result->IsFailure()) return maybe_result; |
// We replace the key if it is already present. |
int index = SearchWithCache(descriptor->GetKey()); |
@@ -5863,9 +5764,8 @@ MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) { |
MaybeObject* DescriptorArray::CopyAdd(Descriptor* descriptor) { |
// Ensure the key is a symbol. |
- { MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
- if (maybe_result->IsFailure()) return maybe_result; |
- } |
+ MaybeObject* maybe_result = descriptor->KeyToSymbol(); |
+ if (maybe_result->IsFailure()) return maybe_result; |
String* key = descriptor->GetKey(); |
ASSERT(Search(key) == kNotFound); |
@@ -5873,9 +5773,8 @@ MaybeObject* DescriptorArray::CopyAdd(Descriptor* descriptor) { |
int new_size = number_of_descriptors() + 1; |
DescriptorArray* new_descriptors; |
- { MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED); |
- if (!maybe_result->To(&new_descriptors)) return maybe_result; |
- } |
+ MaybeObject* maybe_descriptors = Allocate(new_size, MAY_BE_SHARED); |
+ if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors; |
FixedArray::WhitenessWitness witness(new_descriptors); |
@@ -5886,9 +5785,7 @@ MaybeObject* DescriptorArray::CopyAdd(Descriptor* descriptor) { |
if (insertion_index < 0 && InsertionPointFound(GetKey(from), key)) { |
insertion_index = to++; |
} |
- MaybeObject* copy_result = |
- new_descriptors->CopyFrom(to++, this, from, witness); |
- if (copy_result->IsFailure()) return copy_result; |
+ new_descriptors->CopyFrom(to++, this, from, witness); |
} |
if (insertion_index < 0) insertion_index = to++; |
@@ -5909,18 +5806,14 @@ MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) { |
// Allocate the new descriptor array. |
int number_of_descriptors = this->number_of_descriptors(); |
DescriptorArray* new_descriptors; |
- { MaybeObject* maybe_result = Allocate(number_of_descriptors, |
- shared_mode); |
- if (!maybe_result->To(&new_descriptors)) return maybe_result; |
- } |
+ MaybeObject* maybe_result = Allocate(number_of_descriptors, shared_mode); |
+ if (!maybe_result->To(&new_descriptors)) return maybe_result; |
// Copy the content. |
if (number_of_descriptors > 0) { |
FixedArray::WhitenessWitness witness(new_descriptors); |
for (int i = 0; i < number_of_descriptors; i++) { |
- MaybeObject* copy_result = |
- new_descriptors->CopyFrom(i, this, i, witness); |
- if (copy_result->IsFailure()) return copy_result; |
+ new_descriptors->CopyFrom(i, this, i, witness); |
} |
new_descriptors->SetLastAdded(LastAdded()); |
} |
@@ -6020,14 +5913,14 @@ void DescriptorArray::Sort(const WhitenessWitness& witness) { |
} |
-MaybeObject* AccessorPair::CopyWithoutTransitions() { |
+MaybeObject* AccessorPair::Copy() { |
Heap* heap = GetHeap(); |
AccessorPair* copy; |
- { MaybeObject* maybe_copy = heap->AllocateAccessorPair(); |
- if (!maybe_copy->To(©)) return maybe_copy; |
- } |
- copy->set_getter(getter()->IsMap() ? heap->the_hole_value() : getter()); |
- copy->set_setter(setter()->IsMap() ? heap->the_hole_value() : setter()); |
+ MaybeObject* maybe_copy = heap->AllocateAccessorPair(); |
+ if (!maybe_copy->To(©)) return maybe_copy; |
+ |
+ copy->set_getter(getter()); |
+ copy->set_setter(setter()); |
return copy; |
} |
@@ -7313,40 +7206,6 @@ static bool ClearBackPointer(Heap* heap, Object* target) { |
} |
-static bool ClearAccessorComponent(Heap* heap, |
- AccessorPair* accessors, |
- AccessorComponent component) { |
- Object* component_value = accessors->get(component); |
- if (!component_value->IsMap()) return true; |
- if (ClearBackPointer(heap, component_value)) { |
- accessors->set(component, heap->the_hole_value()); |
- return true; |
- } |
- return false; |
-} |
- |
- |
-static bool ClearNonLiveTransition(Heap* heap, |
- TransitionArray* t, |
- int transition_index) { |
- // If the value is a map, check if the target is live. If not, clear the |
- // transition. Also drop the back pointer for that map transition, so that |
- // this map is not reached again by following a back pointer from that |
- // non-live map. |
- Object* value = t->GetValue(transition_index); |
- if (value->IsMap()) { |
- return ClearBackPointer(heap, t->GetValue(transition_index)); |
- } |
- |
- ASSERT(value->IsAccessorPair()); |
- |
- AccessorPair* accessors = AccessorPair::cast(value); |
- bool getter = ClearAccessorComponent(heap, accessors, ACCESSOR_GETTER); |
- bool setter = ClearAccessorComponent(heap, accessors, ACCESSOR_SETTER); |
- return getter && setter; |
-} |
- |
- |
// TODO(mstarzinger): This method should be moved into MarkCompactCollector, |
// because it cannot be called from outside the GC and we already have methods |
// depending on the transitions layout in the GC anyways. |
@@ -7362,17 +7221,17 @@ void Map::ClearNonLiveTransitions(Heap* heap) { |
// Compact all live descriptors to the left. |
for (int i = 0; i < t->number_of_transitions(); ++i) { |
- if (!ClearNonLiveTransition(heap, t, i)) { |
+ if (!ClearBackPointer(heap, t->GetTarget(i))) { |
if (i != transition_index) { |
String* key = t->GetKey(i); |
- Object* value = t->GetValue(i); |
+ Map* target = t->GetTarget(i); |
t->SetKey(transition_index, key); |
- t->SetValue(transition_index, value); |
+ t->SetTarget(transition_index, target); |
MarkCompactCollector* collector = heap->mark_compact_collector(); |
Object** key_slot = t->GetKeySlot(transition_index); |
collector->RecordSlot(key_slot, key_slot, key); |
- Object** value_slot = t->GetValueSlot(transition_index); |
- collector->RecordSlot(value_slot, value_slot, value); |
+ Object** target_slot = t->GetTargetSlot(transition_index); |
+ collector->RecordSlot(target_slot, target_slot, target); |
} |
transition_index++; |
} |
@@ -10472,7 +10331,7 @@ bool JSObject::HasRealNamedCallbackProperty(String* key) { |
LookupResult result(isolate); |
LocalLookupRealNamedProperty(key, &result); |
- return result.IsCallbacks(); |
+ return result.IsPropertyCallbacks(); |
} |
@@ -12696,15 +12555,15 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor( |
if (IsKey(k)) { |
Object* value = ValueAt(i); |
// Ensure the key is a symbol before writing into the instance descriptor. |
- Object* key; |
- { MaybeObject* maybe_key = heap->LookupSymbol(String::cast(k)); |
- if (!maybe_key->ToObject(&key)) return maybe_key; |
- } |
+ String* key; |
+ MaybeObject* maybe_key = heap->LookupSymbol(String::cast(k)); |
+ if (!maybe_key->To(&key)) return maybe_key; |
+ |
PropertyDetails details = DetailsAt(i); |
PropertyType type = details.type(); |
if (value->IsJSFunction() && !heap->InNewSpace(value)) { |
- ConstantFunctionDescriptor d(String::cast(key), |
+ ConstantFunctionDescriptor d(key, |
JSFunction::cast(value), |
details.attributes(), |
details.index()); |
@@ -12718,18 +12577,13 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor( |
int offset = current_offset - inobject_props; |
FixedArray::cast(fields)->set(offset, value); |
} |
- FieldDescriptor d(String::cast(key), |
+ FieldDescriptor d(key, |
current_offset++, |
details.attributes(), |
details.index()); |
descriptors->Set(next_descriptor, &d, witness); |
} else if (type == CALLBACKS) { |
- if (value->IsAccessorPair()) { |
- MaybeObject* maybe_copy = |
- AccessorPair::cast(value)->CopyWithoutTransitions(); |
- if (!maybe_copy->To(&value)) return maybe_copy; |
- } |
- CallbacksDescriptor d(String::cast(key), |
+ CallbacksDescriptor d(key, |
value, |
details.attributes(), |
details.index()); |
@@ -12745,10 +12599,8 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor( |
descriptors->Sort(witness); |
// Allocate new map. |
Map* new_map; |
- { MaybeObject* maybe_new_map = |
- obj->map()->CopyReplaceDescriptors(descriptors); |
- if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
- } |
+ MaybeObject* maybe_new_map = obj->map()->CopyReplaceDescriptors(descriptors); |
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
new_map->set_unused_property_fields(unused_property_fields); |