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

Side by Side Diff: src/objects.cc

Issue 7862036: Share Maps for ElementsKind transitions (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 9 years, 3 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 | « src/objects.h ('k') | src/objects-inl.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1981 matching lines...) Expand 10 before | Expand all | Expand 10 after
1992 cache->Update(descriptors, name, number); 1992 cache->Update(descriptors, name, number);
1993 } 1993 }
1994 if (number != DescriptorArray::kNotFound) { 1994 if (number != DescriptorArray::kNotFound) {
1995 result->DescriptorResult(holder, descriptors->GetDetails(number), number); 1995 result->DescriptorResult(holder, descriptors->GetDetails(number), number);
1996 } else { 1996 } else {
1997 result->NotFound(); 1997 result->NotFound();
1998 } 1998 }
1999 } 1999 }
2000 2000
2001 2001
2002 MaybeObject* Map::GetElementsTransitionMap(ElementsKind elements_kind, 2002 MaybeObject* JSObject::GetElementsTransitionMap(ElementsKind elements_kind) {
2003 bool safe_to_add_transition) { 2003 Heap* current_heap = GetHeap();
2004 Heap* current_heap = heap(); 2004 Map* current_map = map();
2005 DescriptorArray* descriptors = instance_descriptors(); 2005 DescriptorArray* descriptors = current_map->instance_descriptors();
2006 String* elements_transition_sentinel_name = current_heap->empty_symbol(); 2006 String* elements_transition_sentinel_name = current_heap->empty_symbol();
2007 2007
2008 if (current_map->elements_kind() == elements_kind) return current_map;
2009
2010 // Only objects with FastProperties can have DescriptorArrays and can track
2011 // element-related maps. Also don't add descriptors to maps that are shared.
2012 bool safe_to_add_transition = HasFastProperties() &&
2013 !current_map->IsUndefined() &&
2014 !current_map->is_shared();
2015
2016 // Prevent long chains of DICTIONARY -> FAST_ELEMENTS maps cause by objects
2017 // with elements that switch back and forth between dictionary and fast
2018 // element mode.
2019 if ((current_map->elements_kind() == DICTIONARY_ELEMENTS &&
2020 elements_kind == FAST_ELEMENTS)) {
2021 safe_to_add_transition = false;
2022 }
2023
2008 if (safe_to_add_transition) { 2024 if (safe_to_add_transition) {
2009 // It's only safe to manipulate the descriptor array if it would be 2025 // It's only safe to manipulate the descriptor array if it would be
2010 // safe to add a transition. 2026 // safe to add a transition.
2011 2027
2012 ASSERT(!is_shared()); // no transitions can be added to shared maps.
2013 // Check if the elements transition already exists. 2028 // Check if the elements transition already exists.
2014 DescriptorLookupCache* cache = 2029 DescriptorLookupCache* cache =
2015 current_heap->isolate()->descriptor_lookup_cache(); 2030 current_heap->isolate()->descriptor_lookup_cache();
2016 int index = cache->Lookup(descriptors, elements_transition_sentinel_name); 2031 int index = cache->Lookup(descriptors, elements_transition_sentinel_name);
2017 if (index == DescriptorLookupCache::kAbsent) { 2032 if (index == DescriptorLookupCache::kAbsent) {
2018 index = descriptors->Search(elements_transition_sentinel_name); 2033 index = descriptors->Search(elements_transition_sentinel_name);
2019 cache->Update(descriptors, 2034 cache->Update(descriptors,
2020 elements_transition_sentinel_name, 2035 elements_transition_sentinel_name,
2021 index); 2036 index);
2022 } 2037 }
2023 2038
2024 // If the transition already exists, check the type. If there is a match, 2039 // If the transition already exists, check the type. If there is a match,
2025 // return it. 2040 // return it.
2026 if (index != DescriptorArray::kNotFound) { 2041 if (index != DescriptorArray::kNotFound) {
2027 PropertyDetails details(PropertyDetails(descriptors->GetDetails(index))); 2042 PropertyDetails details(PropertyDetails(descriptors->GetDetails(index)));
2028 if (details.type() == ELEMENTS_TRANSITION && 2043 if (details.type() == ELEMENTS_TRANSITION &&
2029 details.elements_kind() == elements_kind) { 2044 details.elements_kind() == elements_kind) {
2030 return descriptors->GetValue(index); 2045 return descriptors->GetValue(index);
2031 } else { 2046 } else {
2032 safe_to_add_transition = false; 2047 safe_to_add_transition = false;
2033 } 2048 }
2034 } 2049 }
2035 } 2050 }
2036 2051
2037 // No transition to an existing map for the given ElementsKind. Make a new 2052 // No transition to an existing map for the given ElementsKind. Make a new
2038 // one. 2053 // one.
2039 Object* obj; 2054 Object* obj;
2040 { MaybeObject* maybe_map = CopyDropTransitions(); 2055 { MaybeObject* maybe_map = current_map->CopyDropTransitions();
2041 if (!maybe_map->ToObject(&obj)) return maybe_map; 2056 if (!maybe_map->ToObject(&obj)) return maybe_map;
2042 } 2057 }
2043 Map* new_map = Map::cast(obj); 2058 Map* new_map = Map::cast(obj);
2044 2059
2045 new_map->set_elements_kind(elements_kind); 2060 new_map->set_elements_kind(elements_kind);
2046 GetIsolate()->counters()->map_to_external_array_elements()->Increment();
2047 2061
2048 // Only remember the map transition if the object's map is NOT equal to the 2062 // Only remember the map transition if the object's map is NOT equal to the
2049 // global object_function's map and there is not an already existing 2063 // global object_function's map and there is not an already existing
2050 // non-matching element transition. 2064 // non-matching element transition.
2051 bool allow_map_transition = 2065 bool allow_map_transition =
2052 safe_to_add_transition && 2066 safe_to_add_transition &&
2053 (GetIsolate()->context()->global_context()->object_function()->map() != 2067 (GetIsolate()->context()->global_context()->object_function()->map() !=
2054 map()); 2068 map());
2055 if (allow_map_transition) { 2069 if (allow_map_transition) {
2056 // Allocate new instance descriptors for the old map with map transition. 2070 // Allocate new instance descriptors for the old map with map transition.
2057 ElementsTransitionDescriptor desc(elements_transition_sentinel_name, 2071 ElementsTransitionDescriptor desc(elements_transition_sentinel_name,
2058 Map::cast(new_map), 2072 Map::cast(new_map),
2059 elements_kind); 2073 elements_kind);
2060 Object* new_descriptors; 2074 Object* new_descriptors;
2061 MaybeObject* maybe_new_descriptors = descriptors->CopyInsert( 2075 MaybeObject* maybe_new_descriptors = descriptors->CopyInsert(
2062 &desc, 2076 &desc,
2063 KEEP_TRANSITIONS); 2077 KEEP_TRANSITIONS);
2064 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { 2078 if (!maybe_new_descriptors->ToObject(&new_descriptors)) {
2065 return maybe_new_descriptors; 2079 return maybe_new_descriptors;
2066 } 2080 }
2067 descriptors = DescriptorArray::cast(new_descriptors); 2081 descriptors = DescriptorArray::cast(new_descriptors);
2068 set_instance_descriptors(descriptors); 2082 current_map->set_instance_descriptors(descriptors);
2069 } 2083 }
2070 2084
2071 return new_map; 2085 return new_map;
2072 } 2086 }
2073 2087
2074 2088
2075 void JSObject::LocalLookupRealNamedProperty(String* name, 2089 void JSObject::LocalLookupRealNamedProperty(String* name,
2076 LookupResult* result) { 2090 LookupResult* result) {
2077 if (IsJSGlobalProxy()) { 2091 if (IsJSGlobalProxy()) {
2078 Object* proto = GetPrototype(); 2092 Object* proto = GetPrototype();
(...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after
2966 } 2980 }
2967 } 2981 }
2968 2982
2969 // Switch to using the dictionary as the backing storage for elements. 2983 // Switch to using the dictionary as the backing storage for elements.
2970 if (is_arguments) { 2984 if (is_arguments) {
2971 FixedArray::cast(elements())->set(1, dictionary); 2985 FixedArray::cast(elements())->set(1, dictionary);
2972 } else { 2986 } else {
2973 // Set the new map first to satify the elements type assert in 2987 // Set the new map first to satify the elements type assert in
2974 // set_elements(). 2988 // set_elements().
2975 Object* new_map; 2989 Object* new_map;
2976 MaybeObject* maybe = map()->GetSlowElementsMap(); 2990 MaybeObject* maybe = GetElementsTransitionMap(DICTIONARY_ELEMENTS);
2977 if (!maybe->ToObject(&new_map)) return maybe; 2991 if (!maybe->ToObject(&new_map)) return maybe;
2978 set_map(Map::cast(new_map)); 2992 set_map(Map::cast(new_map));
2979 set_elements(dictionary); 2993 set_elements(dictionary);
2980 } 2994 }
2981 2995
2982 old_map->isolate()->counters()->elements_to_dictionary()->Increment(); 2996 old_map->isolate()->counters()->elements_to_dictionary()->Increment();
2983 2997
2984 #ifdef DEBUG 2998 #ifdef DEBUG
2985 if (FLAG_trace_normalization) { 2999 if (FLAG_trace_normalization) {
2986 PrintF("Object elements have been normalized:\n"); 3000 PrintF("Object elements have been normalized:\n");
(...skipping 4287 matching lines...) Expand 10 before | Expand all | Expand 10 after
7274 { Object* object; 7288 { Object* object;
7275 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity); 7289 MaybeObject* maybe = heap->AllocateFixedArrayWithHoles(capacity);
7276 if (!maybe->ToObject(&object)) return maybe; 7290 if (!maybe->ToObject(&object)) return maybe;
7277 new_elements = FixedArray::cast(object); 7291 new_elements = FixedArray::cast(object);
7278 } 7292 }
7279 7293
7280 // Find the new map to use for this object if there is a map change. 7294 // Find the new map to use for this object if there is a map change.
7281 Map* new_map = NULL; 7295 Map* new_map = NULL;
7282 if (elements()->map() != heap->non_strict_arguments_elements_map()) { 7296 if (elements()->map() != heap->non_strict_arguments_elements_map()) {
7283 Object* object; 7297 Object* object;
7284 MaybeObject* maybe = map()->GetFastElementsMap(); 7298 MaybeObject* maybe = GetElementsTransitionMap(FAST_ELEMENTS);
7285 if (!maybe->ToObject(&object)) return maybe; 7299 if (!maybe->ToObject(&object)) return maybe;
7286 new_map = Map::cast(object); 7300 new_map = Map::cast(object);
7287 } 7301 }
7288 7302
7289 switch (GetElementsKind()) { 7303 switch (GetElementsKind()) {
7290 case FAST_ELEMENTS: { 7304 case FAST_ELEMENTS: {
7291 AssertNoAllocation no_gc; 7305 AssertNoAllocation no_gc;
7292 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc); 7306 WriteBarrierMode mode = new_elements->GetWriteBarrierMode(no_gc);
7293 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode); 7307 CopyFastElementsToFast(FixedArray::cast(elements()), new_elements, mode);
7294 set_map(new_map); 7308 set_map(new_map);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
7377 // We should never end in here with a pixel or external array. 7391 // We should never end in here with a pixel or external array.
7378 ASSERT(!HasExternalArrayElements()); 7392 ASSERT(!HasExternalArrayElements());
7379 7393
7380 Object* obj; 7394 Object* obj;
7381 { MaybeObject* maybe_obj = 7395 { MaybeObject* maybe_obj =
7382 heap->AllocateUninitializedFixedDoubleArray(capacity); 7396 heap->AllocateUninitializedFixedDoubleArray(capacity);
7383 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7397 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7384 } 7398 }
7385 FixedDoubleArray* elems = FixedDoubleArray::cast(obj); 7399 FixedDoubleArray* elems = FixedDoubleArray::cast(obj);
7386 7400
7387 { MaybeObject* maybe_obj = map()->GetFastDoubleElementsMap(); 7401 { MaybeObject* maybe_obj =
7402 GetElementsTransitionMap(FAST_DOUBLE_ELEMENTS);
7388 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 7403 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
7389 } 7404 }
7390 Map* new_map = Map::cast(obj); 7405 Map* new_map = Map::cast(obj);
7391 7406
7392 AssertNoAllocation no_gc; 7407 AssertNoAllocation no_gc;
7393 switch (GetElementsKind()) { 7408 switch (GetElementsKind()) {
7394 case FAST_ELEMENTS: { 7409 case FAST_ELEMENTS: {
7395 elems->Initialize(FixedArray::cast(elements())); 7410 elems->Initialize(FixedArray::cast(elements()));
7396 break; 7411 break;
7397 } 7412 }
(...skipping 2736 matching lines...) Expand 10 before | Expand all | Expand 10 after
10134 // Convert to fast elements containing only the existing properties. 10149 // Convert to fast elements containing only the existing properties.
10135 // Ordering is irrelevant, since we are going to sort anyway. 10150 // Ordering is irrelevant, since we are going to sort anyway.
10136 NumberDictionary* dict = element_dictionary(); 10151 NumberDictionary* dict = element_dictionary();
10137 if (IsJSArray() || dict->requires_slow_elements() || 10152 if (IsJSArray() || dict->requires_slow_elements() ||
10138 dict->max_number_key() >= limit) { 10153 dict->max_number_key() >= limit) {
10139 return PrepareSlowElementsForSort(limit); 10154 return PrepareSlowElementsForSort(limit);
10140 } 10155 }
10141 // Convert to fast elements. 10156 // Convert to fast elements.
10142 10157
10143 Object* obj; 10158 Object* obj;
10144 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); 10159 { MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
10145 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10160 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10146 } 10161 }
10147 Map* new_map = Map::cast(obj); 10162 Map* new_map = Map::cast(obj);
10148 10163
10149 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED; 10164 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED;
10150 Object* new_array; 10165 Object* new_array;
10151 { MaybeObject* maybe_new_array = 10166 { MaybeObject* maybe_new_array =
10152 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); 10167 heap->AllocateFixedArray(dict->NumberOfElements(), tenure);
10153 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; 10168 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array;
10154 } 10169 }
(...skipping 1436 matching lines...) Expand 10 before | Expand all | Expand 10 after
11591 if (break_point_objects()->IsUndefined()) return 0; 11606 if (break_point_objects()->IsUndefined()) return 0;
11592 // Single break point. 11607 // Single break point.
11593 if (!break_point_objects()->IsFixedArray()) return 1; 11608 if (!break_point_objects()->IsFixedArray()) return 1;
11594 // Multiple break points. 11609 // Multiple break points.
11595 return FixedArray::cast(break_point_objects())->length(); 11610 return FixedArray::cast(break_point_objects())->length();
11596 } 11611 }
11597 #endif 11612 #endif
11598 11613
11599 11614
11600 } } // namespace v8::internal 11615 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698