OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 4406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4417 | 4417 |
4418 uint32_t index = 0; | 4418 uint32_t index = 0; |
4419 return name->AsArrayIndex(&index) ? | 4419 return name->AsArrayIndex(&index) ? |
4420 DefineElementAccessor(index, getter, setter, attributes) : | 4420 DefineElementAccessor(index, getter, setter, attributes) : |
4421 DefinePropertyAccessor(name, getter, setter, attributes); | 4421 DefinePropertyAccessor(name, getter, setter, attributes); |
4422 } | 4422 } |
4423 | 4423 |
4424 | 4424 |
4425 static MaybeObject* TryAccessorTransition(JSObject* self, | 4425 static MaybeObject* TryAccessorTransition(JSObject* self, |
4426 Map* transitioned_map, | 4426 Map* transitioned_map, |
4427 String* name, | 4427 int target_descriptor, |
4428 AccessorComponent component, | 4428 AccessorComponent component, |
4429 Object* accessor, | 4429 Object* accessor, |
4430 PropertyAttributes attributes) { | 4430 PropertyAttributes attributes) { |
4431 DescriptorArray* descs = transitioned_map->instance_descriptors(); | 4431 DescriptorArray* descs = transitioned_map->instance_descriptors(); |
4432 int number = descs->LastAdded(); | 4432 PropertyDetails details = descs->GetDetails(target_descriptor); |
4433 PropertyDetails details = descs->GetDetails(number); | |
4434 | 4433 |
4435 // If the transition target was not callbacks, fall back to the slow case. | 4434 // If the transition target was not callbacks, fall back to the slow case. |
4436 if (details.type() != CALLBACKS) return self->GetHeap()->null_value(); | 4435 if (details.type() != CALLBACKS) return self->GetHeap()->null_value(); |
| 4436 Object* descriptor = descs->GetCallbacksObject(target_descriptor); |
| 4437 if (!descriptor->IsAccessorPair()) return self->GetHeap()->null_value(); |
4437 | 4438 |
4438 Object* target_accessor = | 4439 Object* target_accessor = AccessorPair::cast(descriptor)->get(component); |
4439 AccessorPair::cast(descs->GetCallbacksObject(number))->get(component); | |
4440 PropertyAttributes target_attributes = details.attributes(); | 4440 PropertyAttributes target_attributes = details.attributes(); |
4441 | 4441 |
4442 // Reuse transition if adding same accessor with same attributes. | 4442 // Reuse transition if adding same accessor with same attributes. |
4443 if (target_accessor == accessor && target_attributes == attributes) { | 4443 if (target_accessor == accessor && target_attributes == attributes) { |
4444 self->set_map(transitioned_map); | 4444 self->set_map(transitioned_map); |
4445 return self; | 4445 return self; |
4446 } | 4446 } |
4447 | 4447 |
4448 // If either not the same accessor, or not the same attributes, fall back to | 4448 // If either not the same accessor, or not the same attributes, fall back to |
4449 // the slow case. | 4449 // the slow case. |
(...skipping 16 matching lines...) Expand all Loading... |
4466 // Return success if the same accessor with the same attributes already exist. | 4466 // Return success if the same accessor with the same attributes already exist. |
4467 AccessorPair* source_accessors = NULL; | 4467 AccessorPair* source_accessors = NULL; |
4468 if (result.IsPropertyCallbacks()) { | 4468 if (result.IsPropertyCallbacks()) { |
4469 Object* callback_value = result.GetCallbackObject(); | 4469 Object* callback_value = result.GetCallbackObject(); |
4470 if (callback_value->IsAccessorPair()) { | 4470 if (callback_value->IsAccessorPair()) { |
4471 source_accessors = AccessorPair::cast(callback_value); | 4471 source_accessors = AccessorPair::cast(callback_value); |
4472 Object* entry = source_accessors->get(component); | 4472 Object* entry = source_accessors->get(component); |
4473 if (entry == accessor && result.GetAttributes() == attributes) { | 4473 if (entry == accessor && result.GetAttributes() == attributes) { |
4474 return this; | 4474 return this; |
4475 } | 4475 } |
| 4476 } else { |
| 4477 return GetHeap()->null_value(); |
| 4478 } |
| 4479 |
| 4480 int descriptor_number = result.GetDescriptorIndex(); |
| 4481 |
| 4482 map()->LookupTransition(this, name, &result); |
| 4483 |
| 4484 if (result.IsFound()) { |
| 4485 Map* target = result.GetTransitionTarget(); |
| 4486 ASSERT(target->instance_descriptors()->number_of_descriptors() == |
| 4487 map()->instance_descriptors()->number_of_descriptors()); |
| 4488 ASSERT(target->instance_descriptors()->GetKey(descriptor_number) == name); |
| 4489 return TryAccessorTransition( |
| 4490 this, target, descriptor_number, component, accessor, attributes); |
| 4491 } |
| 4492 } else { |
| 4493 // If not, lookup a transition. |
| 4494 map()->LookupTransition(this, name, &result); |
| 4495 |
| 4496 // If there is a transition, try to follow it. |
| 4497 if (result.IsFound()) { |
| 4498 Map* target = result.GetTransitionTarget(); |
| 4499 int descriptor_number = target->instance_descriptors()->LastAdded(); |
| 4500 ASSERT(target->instance_descriptors()->GetKey(descriptor_number) == name); |
| 4501 return TryAccessorTransition( |
| 4502 this, target, descriptor_number, component, accessor, attributes); |
4476 } | 4503 } |
4477 } | 4504 } |
4478 | 4505 |
4479 // If not, lookup a transition. | |
4480 map()->LookupTransition(this, name, &result); | |
4481 | |
4482 // If there is a transition, try to follow it. | |
4483 if (result.IsFound()) { | |
4484 Map* target = result.GetTransitionTarget(); | |
4485 return TryAccessorTransition( | |
4486 this, target, name, component, accessor, attributes); | |
4487 } | |
4488 | |
4489 // If there is no transition yet, add a transition to the a new accessor pair | 4506 // If there is no transition yet, add a transition to the a new accessor pair |
4490 // containing the accessor. | 4507 // containing the accessor. |
4491 AccessorPair* accessors; | 4508 AccessorPair* accessors; |
4492 MaybeObject* maybe_accessors; | 4509 MaybeObject* maybe_accessors; |
4493 | 4510 |
4494 // Allocate a new pair if there were no source accessors. Otherwise, copy the | 4511 // Allocate a new pair if there were no source accessors. Otherwise, copy the |
4495 // pair and modify the accessor. | 4512 // pair and modify the accessor. |
4496 if (source_accessors != NULL) { | 4513 if (source_accessors != NULL) { |
4497 maybe_accessors = source_accessors->Copy(); | 4514 maybe_accessors = source_accessors->Copy(); |
4498 } else { | 4515 } else { |
(...skipping 8555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13054 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13071 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
13055 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13072 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
13056 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13073 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
13057 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13074 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
13058 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13075 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
13059 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13076 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
13060 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13077 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
13061 } | 13078 } |
13062 | 13079 |
13063 } } // namespace v8::internal | 13080 } } // namespace v8::internal |
OLD | NEW |