| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 4f99d590c89b85061307e6c761eda1ebf6dd21be..2ce145104693c26f371290267a7aa4410e3d7c9f 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -4424,19 +4424,19 @@ MaybeObject* JSObject::DefineAccessor(String* name,
|
|
|
| static MaybeObject* TryAccessorTransition(JSObject* self,
|
| Map* transitioned_map,
|
| - String* name,
|
| + int target_descriptor,
|
| AccessorComponent component,
|
| Object* accessor,
|
| PropertyAttributes attributes) {
|
| DescriptorArray* descs = transitioned_map->instance_descriptors();
|
| - int number = descs->LastAdded();
|
| - PropertyDetails details = descs->GetDetails(number);
|
| + PropertyDetails details = descs->GetDetails(target_descriptor);
|
|
|
| // If the transition target was not callbacks, fall back to the slow case.
|
| if (details.type() != CALLBACKS) return self->GetHeap()->null_value();
|
| + Object* descriptor = descs->GetCallbacksObject(target_descriptor);
|
| + if (!descriptor->IsAccessorPair()) return self->GetHeap()->null_value();
|
|
|
| - Object* target_accessor =
|
| - AccessorPair::cast(descs->GetCallbacksObject(number))->get(component);
|
| + Object* target_accessor = AccessorPair::cast(descriptor)->get(component);
|
| PropertyAttributes target_attributes = details.attributes();
|
|
|
| // Reuse transition if adding same accessor with same attributes.
|
| @@ -4473,17 +4473,34 @@ MaybeObject* JSObject::DefineFastAccessor(String* name,
|
| if (entry == accessor && result.GetAttributes() == attributes) {
|
| return this;
|
| }
|
| + } else {
|
| + return GetHeap()->null_value();
|
| }
|
| - }
|
|
|
| - // If not, lookup a transition.
|
| - map()->LookupTransition(this, name, &result);
|
| + int descriptor_number = result.GetDescriptorIndex();
|
|
|
| - // If there is a transition, try to follow it.
|
| - if (result.IsFound()) {
|
| - Map* target = result.GetTransitionTarget();
|
| - return TryAccessorTransition(
|
| - this, target, name, component, accessor, attributes);
|
| + map()->LookupTransition(this, name, &result);
|
| +
|
| + if (result.IsFound()) {
|
| + Map* target = result.GetTransitionTarget();
|
| + ASSERT(target->instance_descriptors()->number_of_descriptors() ==
|
| + map()->instance_descriptors()->number_of_descriptors());
|
| + ASSERT(target->instance_descriptors()->GetKey(descriptor_number) == name);
|
| + return TryAccessorTransition(
|
| + this, target, descriptor_number, component, accessor, attributes);
|
| + }
|
| + } else {
|
| + // If not, lookup a transition.
|
| + map()->LookupTransition(this, name, &result);
|
| +
|
| + // If there is a transition, try to follow it.
|
| + if (result.IsFound()) {
|
| + Map* target = result.GetTransitionTarget();
|
| + int descriptor_number = target->instance_descriptors()->LastAdded();
|
| + ASSERT(target->instance_descriptors()->GetKey(descriptor_number) == name);
|
| + return TryAccessorTransition(
|
| + this, target, descriptor_number, component, accessor, attributes);
|
| + }
|
| }
|
|
|
| // If there is no transition yet, add a transition to the a new accessor pair
|
|
|