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()) {
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.
// 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()) {
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);
}
}
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;
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();
}
// DefinePropertyAccessor below.
Object* obj = result.GetCallbackObject();
if (obj->IsAccessorPair()) {
- return AccessorPair::cast(obj)->CopyWithoutTransitions();
+ return AccessorPair::cast(obj)->Copy();
}
}
return GetHeap()->AllocateAccessorPair();
}
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);
}
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
// 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();
}
}
-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();
}
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;
}
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);
}
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();
}
-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,
// 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());
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());
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);
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);
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++;
// 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());
}
}
-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;
}
}
-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.
// 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++;
}
LookupResult result(isolate);
LocalLookupRealNamedProperty(key, &result);
- return result.IsCallbacks();
+ return result.IsPropertyCallbacks();
}
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());
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());
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);