• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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