Home | History | Annotate | Download | only in heap
      1 // Copyright 2015 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 #ifndef HEAP_UTILS_H_
      6 #define HEAP_UTILS_H_
      7 
      8 #include "src/factory.h"
      9 #include "src/heap/heap-inl.h"
     10 #include "src/heap/incremental-marking.h"
     11 #include "src/heap/mark-compact.h"
     12 #include "src/isolate.h"
     13 
     14 
     15 namespace v8 {
     16 namespace internal {
     17 
     18 static int LenFromSize(int size) {
     19   return (size - FixedArray::kHeaderSize) / kPointerSize;
     20 }
     21 
     22 
     23 static inline std::vector<Handle<FixedArray>> CreatePadding(
     24     Heap* heap, int padding_size, PretenureFlag tenure,
     25     int object_size = Page::kMaxRegularHeapObjectSize) {
     26   std::vector<Handle<FixedArray>> handles;
     27   Isolate* isolate = heap->isolate();
     28   int allocate_memory;
     29   int length;
     30   int free_memory = padding_size;
     31   if (tenure == i::TENURED) {
     32     heap->old_space()->EmptyAllocationInfo();
     33     int overall_free_memory = static_cast<int>(heap->old_space()->Available());
     34     CHECK(padding_size <= overall_free_memory || overall_free_memory == 0);
     35   } else {
     36     heap->new_space()->DisableInlineAllocationSteps();
     37     int overall_free_memory =
     38         static_cast<int>(*heap->new_space()->allocation_limit_address() -
     39                          *heap->new_space()->allocation_top_address());
     40     CHECK(padding_size <= overall_free_memory || overall_free_memory == 0);
     41   }
     42   while (free_memory > 0) {
     43     if (free_memory > object_size) {
     44       allocate_memory = object_size;
     45       length = LenFromSize(allocate_memory);
     46     } else {
     47       allocate_memory = free_memory;
     48       length = LenFromSize(allocate_memory);
     49       if (length <= 0) {
     50         // Not enough room to create another fixed array. Let's create a filler.
     51         heap->CreateFillerObjectAt(*heap->old_space()->allocation_top_address(),
     52                                    free_memory);
     53         break;
     54       }
     55     }
     56     handles.push_back(isolate->factory()->NewFixedArray(length, tenure));
     57     CHECK((tenure == NOT_TENURED && heap->InNewSpace(*handles.back())) ||
     58           (tenure == TENURED && heap->InOldSpace(*handles.back())));
     59     free_memory -= allocate_memory;
     60   }
     61   return handles;
     62 }
     63 
     64 
     65 // Helper function that simulates a full new-space in the heap.
     66 static inline bool FillUpOnePage(v8::internal::NewSpace* space) {
     67   space->DisableInlineAllocationSteps();
     68   int space_remaining = static_cast<int>(*space->allocation_limit_address() -
     69                                          *space->allocation_top_address());
     70   if (space_remaining == 0) return false;
     71   CreatePadding(space->heap(), space_remaining, i::NOT_TENURED);
     72   return true;
     73 }
     74 
     75 
     76 // Helper function that simulates a fill new-space in the heap.
     77 static inline void AllocateAllButNBytes(v8::internal::NewSpace* space,
     78                                         int extra_bytes) {
     79   space->DisableInlineAllocationSteps();
     80   int space_remaining = static_cast<int>(*space->allocation_limit_address() -
     81                                          *space->allocation_top_address());
     82   CHECK(space_remaining >= extra_bytes);
     83   int new_linear_size = space_remaining - extra_bytes;
     84   if (new_linear_size == 0) return;
     85   CreatePadding(space->heap(), new_linear_size, i::NOT_TENURED);
     86 }
     87 
     88 
     89 static inline void FillCurrentPage(v8::internal::NewSpace* space) {
     90   AllocateAllButNBytes(space, 0);
     91 }
     92 
     93 
     94 static inline void SimulateFullSpace(v8::internal::NewSpace* space) {
     95   FillCurrentPage(space);
     96   while (FillUpOnePage(space)) {
     97   }
     98 }
     99 
    100 
    101 // Helper function that simulates a full old-space in the heap.
    102 static inline void SimulateFullSpace(v8::internal::PagedSpace* space) {
    103   space->EmptyAllocationInfo();
    104   space->ResetFreeList();
    105   space->ClearStats();
    106 }
    107 
    108 
    109 // Helper function that simulates many incremental marking steps until
    110 // marking is completed.
    111 static inline void SimulateIncrementalMarking(i::Heap* heap,
    112                                               bool force_completion = true) {
    113   i::MarkCompactCollector* collector = heap->mark_compact_collector();
    114   i::IncrementalMarking* marking = heap->incremental_marking();
    115   if (collector->sweeping_in_progress()) {
    116     collector->EnsureSweepingCompleted();
    117   }
    118   CHECK(marking->IsMarking() || marking->IsStopped());
    119   if (marking->IsStopped()) {
    120     heap->StartIncrementalMarking();
    121   }
    122   CHECK(marking->IsMarking());
    123   if (!force_completion) return;
    124 
    125   while (!marking->IsComplete()) {
    126     marking->Step(i::MB, i::IncrementalMarking::NO_GC_VIA_STACK_GUARD);
    127     if (marking->IsReadyToOverApproximateWeakClosure()) {
    128       marking->FinalizeIncrementally();
    129     }
    130   }
    131   CHECK(marking->IsComplete());
    132 }
    133 
    134 }  // namespace internal
    135 }  // namespace v8
    136 
    137 #endif  // HEAP_UTILS_H_
    138