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/heap/heap.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
« no previous file with comments | « src/heap/heap.h ('k') | src/objects.cc » ('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 // 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/api.h" 8 #include "src/api.h"
9 #include "src/base/once.h" 9 #include "src/base/once.h"
10 #include "src/base/utils/random-number-generator.h" 10 #include "src/base/utils/random-number-generator.h"
(...skipping 3242 matching lines...) Expand 10 before | Expand all | Expand 10 after
3253 Marking::IsBlack(Marking::MarkBitFrom(address))) { 3253 Marking::IsBlack(Marking::MarkBitFrom(address))) {
3254 if (mode == FROM_GC) { 3254 if (mode == FROM_GC) {
3255 MemoryChunk::IncrementLiveBytesFromGC(address, by); 3255 MemoryChunk::IncrementLiveBytesFromGC(address, by);
3256 } else { 3256 } else {
3257 MemoryChunk::IncrementLiveBytesFromMutator(address, by); 3257 MemoryChunk::IncrementLiveBytesFromMutator(address, by);
3258 } 3258 }
3259 } 3259 }
3260 } 3260 }
3261 3261
3262 3262
3263 static void ZapFixedArrayForTrimming(Address address, int elements_to_trim) {
3264 Object** zap = reinterpret_cast<Object**>(address);
3265 zap++; // Header of filler must be at least one word so skip that.
3266 for (int i = 1; i < elements_to_trim; i++) {
3267 *zap++ = Smi::FromInt(0);
3268 }
3269 }
3270
3271
3272 FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object,
3273 int elements_to_trim) {
3274 const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize;
3275 const int bytes_to_trim = elements_to_trim * element_size;
3276 Map* map = object->map();
3277
3278 // For now this trick is only applied to objects in new and paged space.
3279 // In large object space the object's start must coincide with chunk
3280 // and thus the trick is just not applicable.
3281 DCHECK(!lo_space()->Contains(object));
3282 DCHECK(object->map() != fixed_cow_array_map());
3283
3284 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0);
3285 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize);
3286 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize);
3287
3288 const int len = object->length();
3289 DCHECK(elements_to_trim <= len);
3290
3291 // Calculate location of new array start.
3292 Address new_start = object->address() + bytes_to_trim;
3293
3294 if (bytes_to_trim > FreeSpace::kHeaderSize &&
3295 object->IsFixedArray() &&
3296 !new_space()->Contains(object)) {
3297 // If we are doing a big trim in old space then we zap the space that was
3298 // formerly part of the array so that the GC (aided by the card-based
3299 // remembered set) won't find pointers to new-space there.
3300 ZapFixedArrayForTrimming(object->address(), elements_to_trim);
Hannes Payer (out of office) 2014/08/05 11:08:14 As discussed offline, zapping should not be needed
3301 }
3302
3303 // Technically in new space this write might be omitted (except for
3304 // debug mode which iterates through the heap), but to play safer
3305 // we still do it.
3306 CreateFillerObjectAt(object->address(), bytes_to_trim);
3307
3308 // Initialize header of the trimmed array. Since left trimming is only
3309 // performed on pages which are not concurrently swept creating a filler
3310 // object does not require synchronization.
3311 DCHECK(CanMoveObjectStart(object));
3312 Object** former_start = HeapObject::RawField(object, 0);
3313 int new_start_index = elements_to_trim * (element_size / kPointerSize);
3314 former_start[new_start_index] = map;
3315 former_start[new_start_index + 1] = Smi::FromInt(len - elements_to_trim);
3316 FixedArrayBase* new_object =
3317 FixedArrayBase::cast(HeapObject::FromAddress(new_start));
3318
3319 // Maintain consistency of live bytes during incremental marking
3320 marking()->TransferMark(object->address(), new_start);
3321 AdjustLiveBytes(new_start, -bytes_to_trim, Heap::FROM_MUTATOR);
3322
3323 // Notify the heap profiler of change in object layout.
3324 OnMoveEvent(new_object, object, new_object->Size());
3325 return new_object;
3326 }
3327
3328
3329 // Force instantiation of templatized method.
3330 template
3331 void Heap::RightTrimFixedArray<Heap::FROM_GC>(FixedArrayBase*, int);
3332 template
3333 void Heap::RightTrimFixedArray<Heap::FROM_MUTATOR>(FixedArrayBase*, int);
3334
3335
3336 template<Heap::InvocationMode mode>
3337 void Heap::RightTrimFixedArray(FixedArrayBase* object, int elements_to_trim) {
3338 const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize;
3339 const int bytes_to_trim = elements_to_trim * element_size;
3340
3341 // For now this trick is only applied to objects in new and paged space.
3342 DCHECK(!lo_space()->Contains(object));
3343 DCHECK(object->map() != fixed_cow_array_map());
3344
3345 const int len = object->length();
3346 DCHECK(elements_to_trim < len);
3347
3348 // Calculate location of new array end.
3349 Address new_end = object->address() + object->Size() - bytes_to_trim;
3350
3351 if (bytes_to_trim > FreeSpace::kHeaderSize &&
3352 object->IsFixedArray() &&
3353 (mode != Heap::FROM_GC || Heap::ShouldZapGarbage())) {
3354 // If we are doing a big trim in old space then we zap the space that was
3355 // formerly part of the array so that the GC (aided by the card-based
3356 // remembered set) won't find pointers to new-space there.
3357 ZapFixedArrayForTrimming(new_end, elements_to_trim);
Hannes Payer (out of office) 2014/08/05 11:08:14 Same same.
3358 }
3359
3360 // Technically in new space this write might be omitted (except for
3361 // debug mode which iterates through the heap), but to play safer
3362 // we still do it.
3363 CreateFillerObjectAt(new_end, bytes_to_trim);
3364
3365 // Initialize header of the trimmed array. We are storing the new length
3366 // using release store after creating a filler for the left-over space to
3367 // avoid races with the sweeper thread.
3368 object->synchronized_set_length(len - elements_to_trim);
3369
3370 // Maintain consistency of live bytes during incremental marking
3371 AdjustLiveBytes(object->address(), -bytes_to_trim, mode);
3372
3373 // Notify the heap profiler of change in object layout. The array may not be
3374 // moved during GC, and size has to be adjusted nevertheless.
3375 HeapProfiler* profiler = isolate()->heap_profiler();
3376 if (profiler->is_tracking_allocations()) {
3377 profiler->UpdateObjectSizeEvent(object->address(), object->Size());
3378 }
3379 }
3380
3381
3263 AllocationResult Heap::AllocateExternalArray(int length, 3382 AllocationResult Heap::AllocateExternalArray(int length,
3264 ExternalArrayType array_type, 3383 ExternalArrayType array_type,
3265 void* external_pointer, 3384 void* external_pointer,
3266 PretenureFlag pretenure) { 3385 PretenureFlag pretenure) {
3267 int size = ExternalArray::kAlignedSize; 3386 int size = ExternalArray::kAlignedSize;
3268 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure); 3387 AllocationSpace space = SelectSpace(size, OLD_DATA_SPACE, pretenure);
3269 HeapObject* result; 3388 HeapObject* result;
3270 { 3389 {
3271 AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE); 3390 AllocationResult allocation = AllocateRaw(size, space, OLD_DATA_SPACE);
3272 if (!allocation.To(&result)) return allocation; 3391 if (!allocation.To(&result)) return allocation;
(...skipping 2778 matching lines...) Expand 10 before | Expand all | Expand 10 after
6051 static_cast<int>(object_sizes_last_time_[index])); 6170 static_cast<int>(object_sizes_last_time_[index]));
6052 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) 6171 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT)
6053 #undef ADJUST_LAST_TIME_OBJECT_COUNT 6172 #undef ADJUST_LAST_TIME_OBJECT_COUNT
6054 6173
6055 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); 6174 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
6056 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); 6175 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
6057 ClearObjectStats(); 6176 ClearObjectStats();
6058 } 6177 }
6059 } 6178 }
6060 } // namespace v8::internal 6179 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap/heap.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698