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

Side by Side Diff: src/objects.cc

Issue 10808005: When following an accessor transition for an already existing accessor, don't load the last added d… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 5 months 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/property.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/property.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698