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/heap/heap.h" | 5 #include "src/heap/heap.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/ast/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1098 | 1098 |
1099 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, | 1099 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, |
1100 int len) { | 1100 int len) { |
1101 if (len == 0) return; | 1101 if (len == 0) return; |
1102 | 1102 |
1103 DCHECK(array->map() != fixed_cow_array_map()); | 1103 DCHECK(array->map() != fixed_cow_array_map()); |
1104 Object** dst_objects = array->data_start() + dst_index; | 1104 Object** dst_objects = array->data_start() + dst_index; |
1105 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); | 1105 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); |
1106 if (!InNewSpace(array)) { | 1106 if (!InNewSpace(array)) { |
1107 for (int i = 0; i < len; i++) { | 1107 for (int i = 0; i < len; i++) { |
1108 // TODO(hpayer): check store buffer for entries | 1108 RecordWrite(array, array->OffsetOfElementAt(dst_index + i), |
1109 if (InNewSpace(dst_objects[i])) { | 1109 dst_objects[i]); |
1110 RecordWrite(array->address(), array->OffsetOfElementAt(dst_index + i)); | |
1111 } | |
1112 } | 1110 } |
1113 } | 1111 } |
1114 incremental_marking()->RecordWrites(array); | 1112 incremental_marking()->RecordWrites(array); |
1115 } | 1113 } |
1116 | 1114 |
1117 | 1115 |
1118 #ifdef VERIFY_HEAP | 1116 #ifdef VERIFY_HEAP |
1119 // Helper class for verifying the string table. | 1117 // Helper class for verifying the string table. |
1120 class StringTableVerifier : public ObjectVisitor { | 1118 class StringTableVerifier : public ObjectVisitor { |
1121 public: | 1119 public: |
(...skipping 1973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3095 | 3093 |
3096 if (lo_space()->Contains(object)) return false; | 3094 if (lo_space()->Contains(object)) return false; |
3097 | 3095 |
3098 Page* page = Page::FromAddress(address); | 3096 Page* page = Page::FromAddress(address); |
3099 // We can move the object start if: | 3097 // We can move the object start if: |
3100 // (1) the object is not in old space, | 3098 // (1) the object is not in old space, |
3101 // (2) the page of the object was already swept, | 3099 // (2) the page of the object was already swept, |
3102 // (3) the page was already concurrently swept. This case is an optimization | 3100 // (3) the page was already concurrently swept. This case is an optimization |
3103 // for concurrent sweeping. The WasSwept predicate for concurrently swept | 3101 // for concurrent sweeping. The WasSwept predicate for concurrently swept |
3104 // pages is set after sweeping all pages. | 3102 // pages is set after sweeping all pages. |
3105 return !InOldSpace(address) || page->SweepingDone(); | 3103 return !InOldSpace(object) || page->SweepingDone(); |
3106 } | 3104 } |
3107 | 3105 |
3108 | 3106 |
3109 void Heap::AdjustLiveBytes(HeapObject* object, int by, InvocationMode mode) { | 3107 void Heap::AdjustLiveBytes(HeapObject* object, int by, InvocationMode mode) { |
3110 // As long as the inspected object is black and we are currently not iterating | 3108 // As long as the inspected object is black and we are currently not iterating |
3111 // the heap using HeapIterator, we can update the live byte count. We cannot | 3109 // the heap using HeapIterator, we can update the live byte count. We cannot |
3112 // update while using HeapIterator because the iterator is temporarily | 3110 // update while using HeapIterator because the iterator is temporarily |
3113 // marking the whole object graph, without updating live bytes. | 3111 // marking the whole object graph, without updating live bytes. |
3114 if (!in_heap_iterator() && | 3112 if (!in_heap_iterator() && |
3115 !mark_compact_collector()->sweeping_in_progress() && | 3113 !mark_compact_collector()->sweeping_in_progress() && |
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4352 code_space_->ReportStatistics(); | 4350 code_space_->ReportStatistics(); |
4353 PrintF("Map space : "); | 4351 PrintF("Map space : "); |
4354 map_space_->ReportStatistics(); | 4352 map_space_->ReportStatistics(); |
4355 PrintF("Large object space : "); | 4353 PrintF("Large object space : "); |
4356 lo_space_->ReportStatistics(); | 4354 lo_space_->ReportStatistics(); |
4357 PrintF(">>>>>> ========================================= >>>>>>\n"); | 4355 PrintF(">>>>>> ========================================= >>>>>>\n"); |
4358 } | 4356 } |
4359 | 4357 |
4360 #endif // DEBUG | 4358 #endif // DEBUG |
4361 | 4359 |
4362 bool Heap::Contains(HeapObject* value) { return Contains(value->address()); } | 4360 bool Heap::Contains(HeapObject* value) { |
4363 | 4361 if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(value->address())) { |
4364 | 4362 return false; |
4365 bool Heap::Contains(Address addr) { | 4363 } |
4366 if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(addr)) return false; | |
4367 return HasBeenSetUp() && | 4364 return HasBeenSetUp() && |
4368 (new_space_.ToSpaceContains(addr) || old_space_->Contains(addr) || | 4365 (new_space_.ToSpaceContains(value) || old_space_->Contains(value) || |
4369 code_space_->Contains(addr) || map_space_->Contains(addr) || | 4366 code_space_->Contains(value) || map_space_->Contains(value) || |
4370 lo_space_->SlowContains(addr)); | 4367 lo_space_->Contains(value)); |
4371 } | 4368 } |
4372 | 4369 |
| 4370 bool Heap::ContainsSlow(Address addr) { |
| 4371 if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(addr)) { |
| 4372 return false; |
| 4373 } |
| 4374 return HasBeenSetUp() && |
| 4375 (new_space_.ToSpaceContainsSlow(addr) || |
| 4376 old_space_->ContainsSlow(addr) || code_space_->ContainsSlow(addr) || |
| 4377 map_space_->ContainsSlow(addr) || lo_space_->ContainsSlow(addr)); |
| 4378 } |
4373 | 4379 |
4374 bool Heap::InSpace(HeapObject* value, AllocationSpace space) { | 4380 bool Heap::InSpace(HeapObject* value, AllocationSpace space) { |
4375 return InSpace(value->address(), space); | 4381 if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(value->address())) { |
4376 } | 4382 return false; |
4377 | 4383 } |
4378 | |
4379 bool Heap::InSpace(Address addr, AllocationSpace space) { | |
4380 if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(addr)) return false; | |
4381 if (!HasBeenSetUp()) return false; | 4384 if (!HasBeenSetUp()) return false; |
4382 | 4385 |
4383 switch (space) { | 4386 switch (space) { |
4384 case NEW_SPACE: | 4387 case NEW_SPACE: |
4385 return new_space_.ToSpaceContains(addr); | 4388 return new_space_.ToSpaceContains(value); |
4386 case OLD_SPACE: | 4389 case OLD_SPACE: |
4387 return old_space_->Contains(addr); | 4390 return old_space_->Contains(value); |
4388 case CODE_SPACE: | 4391 case CODE_SPACE: |
4389 return code_space_->Contains(addr); | 4392 return code_space_->Contains(value); |
4390 case MAP_SPACE: | 4393 case MAP_SPACE: |
4391 return map_space_->Contains(addr); | 4394 return map_space_->Contains(value); |
4392 case LO_SPACE: | 4395 case LO_SPACE: |
4393 return lo_space_->SlowContains(addr); | 4396 return lo_space_->Contains(value); |
4394 } | 4397 } |
4395 UNREACHABLE(); | 4398 UNREACHABLE(); |
4396 return false; | 4399 return false; |
| 4400 } |
| 4401 |
| 4402 bool Heap::InSpaceSlow(Address addr, AllocationSpace space) { |
| 4403 if (isolate_->memory_allocator()->IsOutsideAllocatedSpace(addr)) { |
| 4404 return false; |
| 4405 } |
| 4406 if (!HasBeenSetUp()) return false; |
| 4407 |
| 4408 switch (space) { |
| 4409 case NEW_SPACE: |
| 4410 return new_space_.ToSpaceContainsSlow(addr); |
| 4411 case OLD_SPACE: |
| 4412 return old_space_->ContainsSlow(addr); |
| 4413 case CODE_SPACE: |
| 4414 return code_space_->ContainsSlow(addr); |
| 4415 case MAP_SPACE: |
| 4416 return map_space_->ContainsSlow(addr); |
| 4417 case LO_SPACE: |
| 4418 return lo_space_->ContainsSlow(addr); |
| 4419 } |
| 4420 UNREACHABLE(); |
| 4421 return false; |
4397 } | 4422 } |
4398 | 4423 |
4399 | 4424 |
4400 bool Heap::IsValidAllocationSpace(AllocationSpace space) { | 4425 bool Heap::IsValidAllocationSpace(AllocationSpace space) { |
4401 switch (space) { | 4426 switch (space) { |
4402 case NEW_SPACE: | 4427 case NEW_SPACE: |
4403 case OLD_SPACE: | 4428 case OLD_SPACE: |
4404 case CODE_SPACE: | 4429 case CODE_SPACE: |
4405 case MAP_SPACE: | 4430 case MAP_SPACE: |
4406 case LO_SPACE: | 4431 case LO_SPACE: |
(...skipping 1815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6222 } | 6247 } |
6223 | 6248 |
6224 | 6249 |
6225 // static | 6250 // static |
6226 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6251 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6227 return StaticVisitorBase::GetVisitorId(map); | 6252 return StaticVisitorBase::GetVisitorId(map); |
6228 } | 6253 } |
6229 | 6254 |
6230 } // namespace internal | 6255 } // namespace internal |
6231 } // namespace v8 | 6256 } // namespace v8 |
OLD | NEW |