1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "test/cctest/heap/heap-utils.h"
6
7 #include "src/factory.h"
8 #include "src/heap/heap-inl.h"
9 #include "src/heap/incremental-marking.h"
10 #include "src/heap/mark-compact.h"
11 #include "src/isolate.h"
12
13 namespace v8 {
14 namespace internal {
15 namespace heap {
16
SealCurrentObjects(Heap * heap)17 void SealCurrentObjects(Heap* heap) {
18 heap->CollectAllGarbage();
19 heap->CollectAllGarbage();
20 heap->mark_compact_collector()->EnsureSweepingCompleted();
21 heap->old_space()->EmptyAllocationInfo();
22 for (Page* page : *heap->old_space()) {
23 page->MarkNeverAllocateForTesting();
24 }
25 }
26
FixedArrayLenFromSize(int size)27 int FixedArrayLenFromSize(int size) {
28 return (size - FixedArray::kHeaderSize) / kPointerSize;
29 }
30
CreatePadding(Heap * heap,int padding_size,PretenureFlag tenure,int object_size)31 std::vector<Handle<FixedArray>> CreatePadding(Heap* heap, int padding_size,
32 PretenureFlag tenure,
33 int object_size) {
34 std::vector<Handle<FixedArray>> handles;
35 Isolate* isolate = heap->isolate();
36 int allocate_memory;
37 int length;
38 int free_memory = padding_size;
39 if (tenure == i::TENURED) {
40 heap->old_space()->EmptyAllocationInfo();
41 int overall_free_memory = static_cast<int>(heap->old_space()->Available());
42 CHECK(padding_size <= overall_free_memory || overall_free_memory == 0);
43 } else {
44 heap->new_space()->DisableInlineAllocationSteps();
45 int overall_free_memory =
46 static_cast<int>(*heap->new_space()->allocation_limit_address() -
47 *heap->new_space()->allocation_top_address());
48 CHECK(padding_size <= overall_free_memory || overall_free_memory == 0);
49 }
50 while (free_memory > 0) {
51 if (free_memory > object_size) {
52 allocate_memory = object_size;
53 length = FixedArrayLenFromSize(allocate_memory);
54 } else {
55 allocate_memory = free_memory;
56 length = FixedArrayLenFromSize(allocate_memory);
57 if (length <= 0) {
58 // Not enough room to create another fixed array. Let's create a filler.
59 if (free_memory > (2 * kPointerSize)) {
60 heap->CreateFillerObjectAt(
61 *heap->old_space()->allocation_top_address(), free_memory,
62 ClearRecordedSlots::kNo);
63 }
64 break;
65 }
66 }
67 handles.push_back(isolate->factory()->NewFixedArray(length, tenure));
68 CHECK((tenure == NOT_TENURED && heap->InNewSpace(*handles.back())) ||
69 (tenure == TENURED && heap->InOldSpace(*handles.back())));
70 free_memory -= allocate_memory;
71 }
72 return handles;
73 }
74
AllocateAllButNBytes(v8::internal::NewSpace * space,int extra_bytes,std::vector<Handle<FixedArray>> * out_handles)75 void AllocateAllButNBytes(v8::internal::NewSpace* space, int extra_bytes,
76 std::vector<Handle<FixedArray>>* out_handles) {
77 space->DisableInlineAllocationSteps();
78 int space_remaining = static_cast<int>(*space->allocation_limit_address() -
79 *space->allocation_top_address());
80 CHECK(space_remaining >= extra_bytes);
81 int new_linear_size = space_remaining - extra_bytes;
82 if (new_linear_size == 0) return;
83 std::vector<Handle<FixedArray>> handles =
84 heap::CreatePadding(space->heap(), new_linear_size, i::NOT_TENURED);
85 if (out_handles != nullptr)
86 out_handles->insert(out_handles->end(), handles.begin(), handles.end());
87 }
88
FillCurrentPage(v8::internal::NewSpace * space,std::vector<Handle<FixedArray>> * out_handles)89 void FillCurrentPage(v8::internal::NewSpace* space,
90 std::vector<Handle<FixedArray>>* out_handles) {
91 heap::AllocateAllButNBytes(space, 0, out_handles);
92 }
93
FillUpOnePage(v8::internal::NewSpace * space,std::vector<Handle<FixedArray>> * out_handles)94 bool FillUpOnePage(v8::internal::NewSpace* space,
95 std::vector<Handle<FixedArray>>* out_handles) {
96 space->DisableInlineAllocationSteps();
97 int space_remaining = static_cast<int>(*space->allocation_limit_address() -
98 *space->allocation_top_address());
99 if (space_remaining == 0) return false;
100 std::vector<Handle<FixedArray>> handles =
101 heap::CreatePadding(space->heap(), space_remaining, i::NOT_TENURED);
102 if (out_handles != nullptr)
103 out_handles->insert(out_handles->end(), handles.begin(), handles.end());
104 return true;
105 }
106
SimulateFullSpace(v8::internal::NewSpace * space,std::vector<Handle<FixedArray>> * out_handles)107 void SimulateFullSpace(v8::internal::NewSpace* space,
108 std::vector<Handle<FixedArray>>* out_handles) {
109 heap::FillCurrentPage(space, out_handles);
110 while (heap::FillUpOnePage(space, out_handles) || space->AddFreshPage()) {
111 }
112 }
113
SimulateIncrementalMarking(i::Heap * heap,bool force_completion)114 void SimulateIncrementalMarking(i::Heap* heap, bool force_completion) {
115 i::MarkCompactCollector* collector = heap->mark_compact_collector();
116 i::IncrementalMarking* marking = heap->incremental_marking();
117 if (collector->sweeping_in_progress()) {
118 collector->EnsureSweepingCompleted();
119 }
120 CHECK(marking->IsMarking() || marking->IsStopped());
121 if (marking->IsStopped()) {
122 heap->StartIncrementalMarking();
123 }
124 CHECK(marking->IsMarking());
125 if (!force_completion) return;
126
127 while (!marking->IsComplete()) {
128 marking->Step(i::MB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD);
129 if (marking->IsReadyToOverApproximateWeakClosure()) {
130 marking->FinalizeIncrementally();
131 }
132 }
133 CHECK(marking->IsComplete());
134 }
135
SimulateFullSpace(v8::internal::PagedSpace * space)136 void SimulateFullSpace(v8::internal::PagedSpace* space) {
137 space->EmptyAllocationInfo();
138 space->ResetFreeList();
139 space->ClearStats();
140 }
141
AbandonCurrentlyFreeMemory(PagedSpace * space)142 void AbandonCurrentlyFreeMemory(PagedSpace* space) {
143 space->EmptyAllocationInfo();
144 for (Page* page : *space) {
145 page->MarkNeverAllocateForTesting();
146 }
147 }
148
GcAndSweep(Heap * heap,AllocationSpace space)149 void GcAndSweep(Heap* heap, AllocationSpace space) {
150 heap->CollectGarbage(space);
151 if (heap->mark_compact_collector()->sweeping_in_progress()) {
152 heap->mark_compact_collector()->EnsureSweepingCompleted();
153 }
154 }
155
156 } // namespace heap
157 } // namespace internal
158 } // namespace v8
159