| OLD | NEW |
| 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 Loading... |
| 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, | 3263 FixedArrayBase* Heap::LeftTrimFixedArray(FixedArrayBase* object, |
| 3273 int elements_to_trim) { | 3264 int elements_to_trim) { |
| 3274 const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize; | 3265 const int element_size = object->IsFixedArray() ? kPointerSize : kDoubleSize; |
| 3275 const int bytes_to_trim = elements_to_trim * element_size; | 3266 const int bytes_to_trim = elements_to_trim * element_size; |
| 3276 Map* map = object->map(); | 3267 Map* map = object->map(); |
| 3277 | 3268 |
| 3278 // For now this trick is only applied to objects in new and paged space. | 3269 // 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 | 3270 // In large object space the object's start must coincide with chunk |
| 3280 // and thus the trick is just not applicable. | 3271 // and thus the trick is just not applicable. |
| 3281 DCHECK(!lo_space()->Contains(object)); | 3272 DCHECK(!lo_space()->Contains(object)); |
| 3282 DCHECK(object->map() != fixed_cow_array_map()); | 3273 DCHECK(object->map() != fixed_cow_array_map()); |
| 3283 | 3274 |
| 3284 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); | 3275 STATIC_ASSERT(FixedArrayBase::kMapOffset == 0); |
| 3285 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); | 3276 STATIC_ASSERT(FixedArrayBase::kLengthOffset == kPointerSize); |
| 3286 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); | 3277 STATIC_ASSERT(FixedArrayBase::kHeaderSize == 2 * kPointerSize); |
| 3287 | 3278 |
| 3288 const int len = object->length(); | 3279 const int len = object->length(); |
| 3289 DCHECK(elements_to_trim <= len); | 3280 DCHECK(elements_to_trim <= len); |
| 3290 | 3281 |
| 3291 // Calculate location of new array start. | 3282 // Calculate location of new array start. |
| 3292 Address new_start = object->address() + bytes_to_trim; | 3283 Address new_start = object->address() + bytes_to_trim; |
| 3293 | 3284 |
| 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); | |
| 3301 } | |
| 3302 | |
| 3303 // Technically in new space this write might be omitted (except for | 3285 // Technically in new space this write might be omitted (except for |
| 3304 // debug mode which iterates through the heap), but to play safer | 3286 // debug mode which iterates through the heap), but to play safer |
| 3305 // we still do it. | 3287 // we still do it. |
| 3306 CreateFillerObjectAt(object->address(), bytes_to_trim); | 3288 CreateFillerObjectAt(object->address(), bytes_to_trim); |
| 3307 | 3289 |
| 3308 // Initialize header of the trimmed array. Since left trimming is only | 3290 // Initialize header of the trimmed array. Since left trimming is only |
| 3309 // performed on pages which are not concurrently swept creating a filler | 3291 // performed on pages which are not concurrently swept creating a filler |
| 3310 // object does not require synchronization. | 3292 // object does not require synchronization. |
| 3311 DCHECK(CanMoveObjectStart(object)); | 3293 DCHECK(CanMoveObjectStart(object)); |
| 3312 Object** former_start = HeapObject::RawField(object, 0); | 3294 Object** former_start = HeapObject::RawField(object, 0); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3341 // For now this trick is only applied to objects in new and paged space. | 3323 // For now this trick is only applied to objects in new and paged space. |
| 3342 DCHECK(!lo_space()->Contains(object)); | 3324 DCHECK(!lo_space()->Contains(object)); |
| 3343 DCHECK(object->map() != fixed_cow_array_map()); | 3325 DCHECK(object->map() != fixed_cow_array_map()); |
| 3344 | 3326 |
| 3345 const int len = object->length(); | 3327 const int len = object->length(); |
| 3346 DCHECK(elements_to_trim < len); | 3328 DCHECK(elements_to_trim < len); |
| 3347 | 3329 |
| 3348 // Calculate location of new array end. | 3330 // Calculate location of new array end. |
| 3349 Address new_end = object->address() + object->Size() - bytes_to_trim; | 3331 Address new_end = object->address() + object->Size() - bytes_to_trim; |
| 3350 | 3332 |
| 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); | |
| 3358 } | |
| 3359 | |
| 3360 // Technically in new space this write might be omitted (except for | 3333 // Technically in new space this write might be omitted (except for |
| 3361 // debug mode which iterates through the heap), but to play safer | 3334 // debug mode which iterates through the heap), but to play safer |
| 3362 // we still do it. | 3335 // we still do it. |
| 3363 CreateFillerObjectAt(new_end, bytes_to_trim); | 3336 CreateFillerObjectAt(new_end, bytes_to_trim); |
| 3364 | 3337 |
| 3365 // Initialize header of the trimmed array. We are storing the new length | 3338 // 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 | 3339 // using release store after creating a filler for the left-over space to |
| 3367 // avoid races with the sweeper thread. | 3340 // avoid races with the sweeper thread. |
| 3368 object->synchronized_set_length(len - elements_to_trim); | 3341 object->synchronized_set_length(len - elements_to_trim); |
| 3369 | 3342 |
| (...skipping 2800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6170 static_cast<int>(object_sizes_last_time_[index])); | 6143 static_cast<int>(object_sizes_last_time_[index])); |
| 6171 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) | 6144 CODE_AGE_LIST_COMPLETE(ADJUST_LAST_TIME_OBJECT_COUNT) |
| 6172 #undef ADJUST_LAST_TIME_OBJECT_COUNT | 6145 #undef ADJUST_LAST_TIME_OBJECT_COUNT |
| 6173 | 6146 |
| 6174 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); | 6147 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_)); |
| 6175 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); | 6148 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_)); |
| 6176 ClearObjectStats(); | 6149 ClearObjectStats(); |
| 6177 } | 6150 } |
| 6178 } | 6151 } |
| 6179 } // namespace v8::internal | 6152 } // namespace v8::internal |
| OLD | NEW |