Chromium Code Reviews| Index: src/objects.cc |
| diff --git a/src/objects.cc b/src/objects.cc |
| index 6e47946d128fc7957383f571e3b80b446e697665..f4e9fa9a882b7c946e3008621cf500b37c6f9e68 100644 |
| --- a/src/objects.cc |
| +++ b/src/objects.cc |
| @@ -1780,6 +1780,67 @@ void Map::LookupInDescriptors(JSObject* holder, |
| } |
| +MaybeObject* Map::GetExternalArrayElementsMap(ExternalArrayType array_type) { |
| + DescriptorArray* descriptors = instance_descriptors(); |
| + String* external_array_sentinel_name = Heap::empty_string(); |
|
Mads Ager (chromium)
2011/03/21 08:32:40
The empty string is a valid property name (every s
|
| + |
| + // Check if the external array transition already exists. |
| + int index = DescriptorLookupCache::Lookup(descriptors, |
| + external_array_sentinel_name); |
| + if (index == DescriptorLookupCache::kAbsent) { |
| + index = descriptors->Search(external_array_sentinel_name); |
| + DescriptorLookupCache::Update(descriptors, |
| + external_array_sentinel_name, |
| + index); |
| + } |
| + |
| + // If the transition already exists, check the type. If thee is a match, |
|
Mads Ager (chromium)
2011/03/21 08:32:40
thee -> there
|
| + // return it. |
| + if (index != DescriptorArray::kNotFound) { |
| + PropertyDetails details(PropertyDetails(descriptors->GetDetails(index))); |
| + if (details.type() == EXTERNAL_ARRAY_TRANSITION && |
| + details.array_type() == array_type) { |
| + return descriptors->GetValue(index); |
| + } |
| + } |
| + |
| + // No transition to an existing external array map. Make a new one. |
| + Object* obj; |
| + { MaybeObject* maybe_map = CopyDropTransitions(); |
| + if (!maybe_map->ToObject(&obj)) return maybe_map; |
| + } |
| + Map* new_map = Map::cast(obj); |
| + |
| + new_map->set_has_fast_elements(false); |
| + new_map->set_has_external_array_elements(true); |
| + Counters::map_to_external_array_elements.Increment(); |
| + |
| + // Only remember the map transition if the object's map is NOT equal to the |
| + // global object_function's map and there is not an already existing |
| + // non-matching external array transition. |
| + bool allow_map_transition = |
| + index == DescriptorArray::kNotFound && |
| + (Top::context()->global_context()->object_function()->map() != map()); |
| + if (allow_map_transition) { |
| + // Allocate new instance descriptors for the old map with map transition. |
| + ExternalArrayTransitionDescriptor desc(external_array_sentinel_name, |
| + Map::cast(new_map), |
| + array_type); |
| + Object* new_descriptors; |
| + MaybeObject* maybe_new_descriptors = descriptors->CopyInsert( |
| + &desc, |
| + KEEP_TRANSITIONS); |
| + if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
| + return maybe_new_descriptors; |
| + } |
| + descriptors = DescriptorArray::cast(new_descriptors); |
| + set_instance_descriptors(descriptors); |
| + } |
| + |
| + return new_map; |
| +} |
| + |
| + |
| void JSObject::LocalLookupRealNamedProperty(String* name, |
| LookupResult* result) { |
| if (IsJSGlobalProxy()) { |
| @@ -6278,6 +6339,7 @@ const char* Code::PropertyType2String(PropertyType type) { |
| case CALLBACKS: return "CALLBACKS"; |
| case INTERCEPTOR: return "INTERCEPTOR"; |
| case MAP_TRANSITION: return "MAP_TRANSITION"; |
| + case EXTERNAL_ARRAY_TRANSITION: return "EXTERNAL_ARRAY_TRANSITION"; |
| case CONSTANT_TRANSITION: return "CONSTANT_TRANSITION"; |
| case NULL_DESCRIPTOR: return "NULL_DESCRIPTOR"; |
| } |