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

Side by Side Diff: src/objects.cc

Issue 200443004: Move left and right trimming of FixedArray into Heap. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Hannes Payer. Created 6 years, 4 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
« src/heap/heap.cc ('K') | « src/heap/heap.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/allocation-site-scopes.h" 8 #include "src/allocation-site-scopes.h"
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 1973 matching lines...) Expand 10 before | Expand all | Expand 10 after
1984 case kInteger32: return "i"; 1984 case kInteger32: return "i";
1985 case kHeapObject: return "h"; 1985 case kHeapObject: return "h";
1986 case kExternal: return "x"; 1986 case kExternal: return "x";
1987 default: 1987 default:
1988 UNREACHABLE(); 1988 UNREACHABLE();
1989 return NULL; 1989 return NULL;
1990 } 1990 }
1991 } 1991 }
1992 1992
1993 1993
1994 static void ZapEndOfFixedArray(Address new_end, int to_trim) {
1995 // If we are doing a big trim in old space then we zap the space.
1996 Object** zap = reinterpret_cast<Object**>(new_end);
1997 zap++; // Header of filler must be at least one word so skip that.
1998 for (int i = 1; i < to_trim; i++) {
1999 *zap++ = Smi::FromInt(0);
2000 }
2001 }
2002
2003
2004 template<Heap::InvocationMode mode>
2005 static void RightTrimFixedArray(Heap* heap, FixedArray* elms, int to_trim) {
2006 DCHECK(elms->map() != heap->fixed_cow_array_map());
2007 // For now this trick is only applied to fixed arrays in new and paged space.
2008 DCHECK(!heap->lo_space()->Contains(elms));
2009
2010 const int len = elms->length();
2011
2012 DCHECK(to_trim < len);
2013
2014 Address new_end = elms->address() + FixedArray::SizeFor(len - to_trim);
2015
2016 if (mode != Heap::FROM_GC || Heap::ShouldZapGarbage()) {
2017 ZapEndOfFixedArray(new_end, to_trim);
2018 }
2019
2020 int size_delta = to_trim * kPointerSize;
2021
2022 // Technically in new space this write might be omitted (except for
2023 // debug mode which iterates through the heap), but to play safer
2024 // we still do it.
2025 heap->CreateFillerObjectAt(new_end, size_delta);
2026
2027 // We are storing the new length using release store after creating a filler
2028 // for the left-over space to avoid races with the sweeper thread.
2029 elms->synchronized_set_length(len - to_trim);
2030
2031 heap->AdjustLiveBytes(elms->address(), -size_delta, mode);
2032
2033 // The array may not be moved during GC,
2034 // and size has to be adjusted nevertheless.
2035 HeapProfiler* profiler = heap->isolate()->heap_profiler();
2036 if (profiler->is_tracking_allocations()) {
2037 profiler->UpdateObjectSizeEvent(elms->address(), elms->Size());
2038 }
2039 }
2040
2041
2042 bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields, 1994 bool Map::InstancesNeedRewriting(Map* target, int target_number_of_fields,
2043 int target_inobject, int target_unused, 1995 int target_inobject, int target_unused,
2044 int* old_number_of_fields) { 1996 int* old_number_of_fields) {
2045 // If fields were added (or removed), rewrite the instance. 1997 // If fields were added (or removed), rewrite the instance.
2046 *old_number_of_fields = NumberOfFields(); 1998 *old_number_of_fields = NumberOfFields();
2047 DCHECK(target_number_of_fields >= *old_number_of_fields); 1999 DCHECK(target_number_of_fields >= *old_number_of_fields);
2048 if (target_number_of_fields != *old_number_of_fields) return true; 2000 if (target_number_of_fields != *old_number_of_fields) return true;
2049 2001
2050 // If smi descriptors were replaced by double descriptors, rewrite. 2002 // If smi descriptors were replaced by double descriptors, rewrite.
2051 DescriptorArray* old_desc = instance_descriptors(); 2003 DescriptorArray* old_desc = instance_descriptors();
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
2239 for (int i = 0; i < limit; i++) { 2191 for (int i = 0; i < limit; i++) {
2240 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i); 2192 FieldIndex index = FieldIndex::ForPropertyIndex(*new_map, i);
2241 object->FastPropertyAtPut(index, array->get(external + i)); 2193 object->FastPropertyAtPut(index, array->get(external + i));
2242 } 2194 }
2243 2195
2244 Heap* heap = isolate->heap(); 2196 Heap* heap = isolate->heap();
2245 2197
2246 // If there are properties in the new backing store, trim it to the correct 2198 // If there are properties in the new backing store, trim it to the correct
2247 // size and install the backing store into the object. 2199 // size and install the backing store into the object.
2248 if (external > 0) { 2200 if (external > 0) {
2249 RightTrimFixedArray<Heap::FROM_MUTATOR>(heap, *array, inobject); 2201 heap->RightTrimFixedArray<Heap::FROM_MUTATOR>(*array, inobject);
2250 object->set_properties(*array); 2202 object->set_properties(*array);
2251 } 2203 }
2252 2204
2253 // Create filler object past the new instance size. 2205 // Create filler object past the new instance size.
2254 int new_instance_size = new_map->instance_size(); 2206 int new_instance_size = new_map->instance_size();
2255 int instance_size_delta = old_map->instance_size() - new_instance_size; 2207 int instance_size_delta = old_map->instance_size() - new_instance_size;
2256 DCHECK(instance_size_delta >= 0); 2208 DCHECK(instance_size_delta >= 0);
2257 2209
2258 if (instance_size_delta > 0) { 2210 if (instance_size_delta > 0) {
2259 Address address = object->address(); 2211 Address address = object->address();
(...skipping 5958 matching lines...) Expand 10 before | Expand all | Expand 10 after
8218 cache->set(EntryToIndex(entry), *obj); 8170 cache->set(EntryToIndex(entry), *obj);
8219 cache->set(EntryToIndex(entry) + 1, *code); 8171 cache->set(EntryToIndex(entry) + 1, *code);
8220 cache->ElementAdded(); 8172 cache->ElementAdded();
8221 return cache; 8173 return cache;
8222 } 8174 }
8223 8175
8224 8176
8225 void FixedArray::Shrink(int new_length) { 8177 void FixedArray::Shrink(int new_length) {
8226 DCHECK(0 <= new_length && new_length <= length()); 8178 DCHECK(0 <= new_length && new_length <= length());
8227 if (new_length < length()) { 8179 if (new_length < length()) {
8228 RightTrimFixedArray<Heap::FROM_MUTATOR>( 8180 GetHeap()->RightTrimFixedArray<Heap::FROM_MUTATOR>(
8229 GetHeap(), this, length() - new_length); 8181 this, length() - new_length);
8230 } 8182 }
8231 } 8183 }
8232 8184
8233 8185
8234 MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike( 8186 MaybeHandle<FixedArray> FixedArray::AddKeysFromArrayLike(
8235 Handle<FixedArray> content, 8187 Handle<FixedArray> content,
8236 Handle<JSObject> array) { 8188 Handle<JSObject> array) {
8237 DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements()); 8189 DCHECK(array->IsJSArray() || array->HasSloppyArgumentsElements());
8238 ElementsAccessor* accessor = array->GetElementsAccessor(); 8190 ElementsAccessor* accessor = array->GetElementsAccessor();
8239 Handle<FixedArray> result; 8191 Handle<FixedArray> result;
(...skipping 1345 matching lines...) Expand 10 before | Expand all | Expand 10 after
9585 int live_enum = map->EnumLength(); 9537 int live_enum = map->EnumLength();
9586 if (live_enum == kInvalidEnumCacheSentinel) { 9538 if (live_enum == kInvalidEnumCacheSentinel) {
9587 live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM); 9539 live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM);
9588 } 9540 }
9589 if (live_enum == 0) return descriptors->ClearEnumCache(); 9541 if (live_enum == 0) return descriptors->ClearEnumCache();
9590 9542
9591 FixedArray* enum_cache = descriptors->GetEnumCache(); 9543 FixedArray* enum_cache = descriptors->GetEnumCache();
9592 9544
9593 int to_trim = enum_cache->length() - live_enum; 9545 int to_trim = enum_cache->length() - live_enum;
9594 if (to_trim <= 0) return; 9546 if (to_trim <= 0) return;
9595 RightTrimFixedArray<Heap::FROM_GC>( 9547 heap->RightTrimFixedArray<Heap::FROM_GC>(
9596 heap, descriptors->GetEnumCache(), to_trim); 9548 descriptors->GetEnumCache(), to_trim);
9597 9549
9598 if (!descriptors->HasEnumIndicesCache()) return; 9550 if (!descriptors->HasEnumIndicesCache()) return;
9599 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache(); 9551 FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache();
9600 RightTrimFixedArray<Heap::FROM_GC>(heap, enum_indices_cache, to_trim); 9552 heap->RightTrimFixedArray<Heap::FROM_GC>(enum_indices_cache, to_trim);
9601 } 9553 }
9602 9554
9603 9555
9604 static void TrimDescriptorArray(Heap* heap, 9556 static void TrimDescriptorArray(Heap* heap,
9605 Map* map, 9557 Map* map,
9606 DescriptorArray* descriptors, 9558 DescriptorArray* descriptors,
9607 int number_of_own_descriptors) { 9559 int number_of_own_descriptors) {
9608 int number_of_descriptors = descriptors->number_of_descriptors_storage(); 9560 int number_of_descriptors = descriptors->number_of_descriptors_storage();
9609 int to_trim = number_of_descriptors - number_of_own_descriptors; 9561 int to_trim = number_of_descriptors - number_of_own_descriptors;
9610 if (to_trim == 0) return; 9562 if (to_trim == 0) return;
9611 9563
9612 RightTrimFixedArray<Heap::FROM_GC>( 9564 heap->RightTrimFixedArray<Heap::FROM_GC>(
9613 heap, descriptors, to_trim * DescriptorArray::kDescriptorSize); 9565 descriptors, to_trim * DescriptorArray::kDescriptorSize);
9614 descriptors->SetNumberOfDescriptors(number_of_own_descriptors); 9566 descriptors->SetNumberOfDescriptors(number_of_own_descriptors);
9615 9567
9616 if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors); 9568 if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors);
9617 descriptors->Sort(); 9569 descriptors->Sort();
9618 } 9570 }
9619 9571
9620 9572
9621 // Clear a possible back pointer in case the transition leads to a dead map. 9573 // Clear a possible back pointer in case the transition leads to a dead map.
9622 // Return true in case a back pointer has been cleared and false otherwise. 9574 // Return true in case a back pointer has been cleared and false otherwise.
9623 static bool ClearBackPointer(Heap* heap, Map* target) { 9575 static bool ClearBackPointer(Heap* heap, Map* target) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
9680 DCHECK(descriptors == GetHeap()->empty_descriptor_array()); 9632 DCHECK(descriptors == GetHeap()->empty_descriptor_array());
9681 } 9633 }
9682 } 9634 }
9683 9635
9684 // Note that we never eliminate a transition array, though we might right-trim 9636 // Note that we never eliminate a transition array, though we might right-trim
9685 // such that number_of_transitions() == 0. If this assumption changes, 9637 // such that number_of_transitions() == 0. If this assumption changes,
9686 // TransitionArray::CopyInsert() will need to deal with the case that a 9638 // TransitionArray::CopyInsert() will need to deal with the case that a
9687 // transition array disappeared during GC. 9639 // transition array disappeared during GC.
9688 int trim = t->number_of_transitions() - transition_index; 9640 int trim = t->number_of_transitions() - transition_index;
9689 if (trim > 0) { 9641 if (trim > 0) {
9690 RightTrimFixedArray<Heap::FROM_GC>(heap, t, t->IsSimpleTransition() 9642 heap->RightTrimFixedArray<Heap::FROM_GC>(t, t->IsSimpleTransition()
9691 ? trim : trim * TransitionArray::kTransitionSize); 9643 ? trim : trim * TransitionArray::kTransitionSize);
9692 } 9644 }
9693 DCHECK(HasTransitionArray()); 9645 DCHECK(HasTransitionArray());
9694 } 9646 }
9695 9647
9696 9648
9697 int Map::Hash() { 9649 int Map::Hash() {
9698 // For performance reasons we only hash the 3 most variable fields of a map: 9650 // For performance reasons we only hash the 3 most variable fields of a map:
9699 // constructor, prototype and bit_field2. 9651 // constructor, prototype and bit_field2.
9700 9652
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
9956 code_map->set(dst + kLiteralsOffset, 9908 code_map->set(dst + kLiteralsOffset,
9957 code_map->get(src + kLiteralsOffset)); 9909 code_map->get(src + kLiteralsOffset));
9958 code_map->set(dst + kOsrAstIdOffset, 9910 code_map->set(dst + kOsrAstIdOffset,
9959 code_map->get(src + kOsrAstIdOffset)); 9911 code_map->get(src + kOsrAstIdOffset));
9960 } 9912 }
9961 dst += kEntryLength; 9913 dst += kEntryLength;
9962 } 9914 }
9963 } 9915 }
9964 if (dst != length) { 9916 if (dst != length) {
9965 // Always trim even when array is cleared because of heap verifier. 9917 // Always trim even when array is cleared because of heap verifier.
9966 RightTrimFixedArray<Heap::FROM_MUTATOR>(GetHeap(), code_map, length - dst); 9918 GetHeap()->RightTrimFixedArray<Heap::FROM_MUTATOR>(code_map, length - dst);
9967 if (code_map->length() == kEntriesStart) ClearOptimizedCodeMap(); 9919 if (code_map->length() == kEntriesStart) ClearOptimizedCodeMap();
9968 } 9920 }
9969 } 9921 }
9970 9922
9971 9923
9972 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) { 9924 void SharedFunctionInfo::TrimOptimizedCodeMap(int shrink_by) {
9973 FixedArray* code_map = FixedArray::cast(optimized_code_map()); 9925 FixedArray* code_map = FixedArray::cast(optimized_code_map());
9974 DCHECK(shrink_by % kEntryLength == 0); 9926 DCHECK(shrink_by % kEntryLength == 0);
9975 DCHECK(shrink_by <= code_map->length() - kEntriesStart); 9927 DCHECK(shrink_by <= code_map->length() - kEntriesStart);
9976 // Always trim even when array is cleared because of heap verifier. 9928 // Always trim even when array is cleared because of heap verifier.
9977 RightTrimFixedArray<Heap::FROM_GC>(GetHeap(), code_map, shrink_by); 9929 GetHeap()->RightTrimFixedArray<Heap::FROM_GC>(code_map, shrink_by);
9978 if (code_map->length() == kEntriesStart) { 9930 if (code_map->length() == kEntriesStart) {
9979 ClearOptimizedCodeMap(); 9931 ClearOptimizedCodeMap();
9980 } 9932 }
9981 } 9933 }
9982 9934
9983 9935
9984 void JSObject::OptimizeAsPrototype(Handle<JSObject> object) { 9936 void JSObject::OptimizeAsPrototype(Handle<JSObject> object) {
9985 if (object->IsGlobalObject()) return; 9937 if (object->IsGlobalObject()) return;
9986 9938
9987 // Make sure prototypes are fast objects and their maps have the bit set 9939 // Make sure prototypes are fast objects and their maps have the bit set
(...skipping 7063 matching lines...) Expand 10 before | Expand all | Expand 10 after
17051 #define ERROR_MESSAGES_TEXTS(C, T) T, 17003 #define ERROR_MESSAGES_TEXTS(C, T) T,
17052 static const char* error_messages_[] = { 17004 static const char* error_messages_[] = {
17053 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 17005 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
17054 }; 17006 };
17055 #undef ERROR_MESSAGES_TEXTS 17007 #undef ERROR_MESSAGES_TEXTS
17056 return error_messages_[reason]; 17008 return error_messages_[reason];
17057 } 17009 }
17058 17010
17059 17011
17060 } } // namespace v8::internal 17012 } } // namespace v8::internal
OLDNEW
« src/heap/heap.cc ('K') | « src/heap/heap.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698