V8 Project
v8::internal::Zone Class Reference

#include <zone.h>

+ Collaboration diagram for v8::internal::Zone:

Public Member Functions

 Zone (Isolate *isolate)
 
 ~Zone ()
 
void * New (int size)
 
template<typename T >
TNewArray (int length)
 
void DeleteAll ()
 
void DeleteKeptSegment ()
 
bool excess_allocation ()
 
void adjust_segment_bytes_allocated (int delta)
 
unsigned allocation_size () const
 
Isolateisolate () const
 

Private Member Functions

Address NewExpand (int size)
 
 INLINE (Segment *NewSegment(int size))
 
 INLINE (void DeleteSegment(Segment *segment, int size))
 

Private Attributes

unsigned allocation_size_
 
int segment_bytes_allocated_
 
Address position_
 
Address limit_
 
Segmentsegment_head_
 
Isolateisolate_
 

Static Private Attributes

static const int kAlignment = kPointerSize
 
static const int kMinimumSegmentSize = 8 * KB
 
static const int kMaximumSegmentSize = 1 * MB
 
static const int kMaximumKeptSegmentSize = 64 * KB
 
static const int kExcessLimit = 256 * MB
 

Friends

class Isolate
 

Detailed Description

Definition at line 37 of file zone.h.

Constructor & Destructor Documentation

◆ Zone()

v8::internal::Zone::Zone ( Isolate isolate)
explicit

Definition at line 47 of file zone.cc.

48  : allocation_size_(0),
50  position_(0),
51  limit_(0),
53  isolate_(isolate) {
54 }
Isolate * isolate_
Definition: zone.h:123
Address position_
Definition: zone.h:119
int segment_bytes_allocated_
Definition: zone.h:101
Isolate * isolate() const
Definition: zone.h:68
unsigned allocation_size_
Definition: zone.h:96
Address limit_
Definition: zone.h:120
Segment * segment_head_
Definition: zone.h:122
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL

◆ ~Zone()

v8::internal::Zone::~Zone ( )

Definition at line 57 of file zone.cc.

57  {
58  DeleteAll();
60 
62 }
void DeleteKeptSegment()
Definition: zone.cc:158
void DeleteAll()
Definition: zone.cc:106
#define DCHECK(condition)
Definition: logging.h:205

References DCHECK, DeleteAll(), DeleteKeptSegment(), and segment_bytes_allocated_.

+ Here is the call graph for this function:

Member Function Documentation

◆ adjust_segment_bytes_allocated()

void v8::internal::Zone::adjust_segment_bytes_allocated ( int  delta)
inline

Definition at line 32 of file zone-inl.h.

32  {
33  segment_bytes_allocated_ += delta;
34  isolate_->counters()->zone_segment_bytes()->Set(segment_bytes_allocated_);
35 }
Counters * counters()
Definition: isolate.h:857

References v8::internal::Isolate::counters(), isolate_, and segment_bytes_allocated_.

+ Here is the call graph for this function:

◆ allocation_size()

unsigned v8::internal::Zone::allocation_size ( ) const
inline

Definition at line 66 of file zone.h.

66 { return allocation_size_; }

References allocation_size_.

Referenced by v8::internal::compiler::PhaseStats::~PhaseStats().

+ Here is the caller graph for this function:

◆ DeleteAll()

void v8::internal::Zone::DeleteAll ( )

Definition at line 106 of file zone.cc.

106  {
107 #ifdef DEBUG
108  // Constant byte value used for zapping dead memory in debug mode.
109  static const unsigned char kZapDeadByte = 0xcd;
110 #endif
111 
112  // Find a segment with a suitable size to keep around.
113  Segment* keep = NULL;
114  // Traverse the chained list of segments, zapping (in debug mode)
115  // and freeing every segment except the one we wish to keep.
116  for (Segment* current = segment_head_; current != NULL; ) {
117  Segment* next = current->next();
118  if (keep == NULL && current->size() <= kMaximumKeptSegmentSize) {
119  // Unlink the segment we wish to keep from the list.
120  keep = current;
121  keep->clear_next();
122  } else {
123  int size = current->size();
124 #ifdef DEBUG
125  // Un-poison first so the zapping doesn't trigger ASan complaints.
127  // Zap the entire current segment (including the header).
128  memset(current, kZapDeadByte, size);
129 #endif
130  DeleteSegment(current, size);
131  }
132  current = next;
133  }
134 
135  // If we have found a segment we want to keep, we must recompute the
136  // variables 'position' and 'limit' to prepare for future allocate
137  // attempts. Otherwise, we must clear the position and limit to
138  // force a new segment to be allocated on demand.
139  if (keep != NULL) {
140  Address start = keep->start();
141  position_ = RoundUp(start, kAlignment);
142  limit_ = keep->end();
143  // Un-poison so we can re-use the segment later.
144  ASAN_UNPOISON_MEMORY_REGION(start, keep->capacity());
145 #ifdef DEBUG
146  // Zap the contents of the kept segment (but not the header).
147  memset(start, kZapDeadByte, keep->capacity());
148 #endif
149  } else {
150  position_ = limit_ = 0;
151  }
152 
153  // Update the head segment to be the kept segment (if any).
154  segment_head_ = keep;
155 }
static const int kAlignment
Definition: zone.h:80
static const int kMaximumKeptSegmentSize
Definition: zone.h:90
enable harmony numeric enable harmony object literal extensions Optimize object size
byte * Address
Definition: globals.h:101
static void RoundUp(Vector< char > buffer, int *length, int *decimal_point)
Definition: fixed-dtoa.cc:171
#define ASAN_UNPOISON_MEMORY_REGION(start, size)
Definition: zone-inl.h:13

References ASAN_UNPOISON_MEMORY_REGION, v8::internal::Segment::capacity(), v8::internal::Segment::clear_next(), v8::internal::Segment::end(), kAlignment, kMaximumKeptSegmentSize, limit_, v8::internal::Segment::next(), NULL, position_, v8::internal::RoundUp(), segment_head_, size, and v8::internal::Segment::start().

Referenced by ~Zone(), and v8::internal::ZoneScope::~ZoneScope().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ DeleteKeptSegment()

void v8::internal::Zone::DeleteKeptSegment ( )

Definition at line 158 of file zone.cc.

158  {
159 #ifdef DEBUG
160  // Constant byte value used for zapping dead memory in debug mode.
161  static const unsigned char kZapDeadByte = 0xcd;
162 #endif
163 
165  if (segment_head_ != NULL) {
166  int size = segment_head_->size();
167 #ifdef DEBUG
168  // Un-poison first so the zapping doesn't trigger ASan complaints.
170  // Zap the entire kept segment (including the header).
171  memset(segment_head_, kZapDeadByte, size);
172 #endif
173  DeleteSegment(segment_head_, size);
175  }
176 
178 }
Segment * next() const
Definition: zone.cc:27
int size() const
Definition: zone.cc:30

References ASAN_UNPOISON_MEMORY_REGION, DCHECK, v8::internal::Segment::next(), NULL, segment_bytes_allocated_, segment_head_, size, and v8::internal::Segment::size().

Referenced by v8::internal::Isolate::~Isolate(), and ~Zone().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ excess_allocation()

bool v8::internal::Zone::excess_allocation ( )
inline

Definition at line 27 of file zone-inl.h.

27  {
29 }
static const int kExcessLimit
Definition: zone.h:93

References kExcessLimit, and segment_bytes_allocated_.

◆ INLINE() [1/2]

v8::internal::Zone::INLINE ( Segment NewSegmentint size)
private

◆ INLINE() [2/2]

v8::internal::Zone::INLINE ( void   DeleteSegmentSegment *segment, int size)
private

◆ isolate()

◆ New()

void * v8::internal::Zone::New ( int  size)

Definition at line 65 of file zone.cc.

65  {
66  // Round up the requested size to fit the alignment.
68 
69  // If the allocation size is divisible by 8 then we return an 8-byte aligned
70  // address.
71  if (kPointerSize == 4 && kAlignment == 4) {
72  position_ += ((~size) & 4) & (reinterpret_cast<intptr_t>(position_) & 4);
73  } else {
75  }
76 
77  // Check if the requested size is available without expanding.
78  Address result = position_;
79 
80  int size_with_redzone =
81 #ifdef V8_USE_ADDRESS_SANITIZER
83 #else
84  size;
85 #endif
86 
87  if (size_with_redzone > limit_ - position_) {
88  result = NewExpand(size_with_redzone);
89  } else {
90  position_ += size_with_redzone;
91  }
92 
93 #ifdef V8_USE_ADDRESS_SANITIZER
94  Address redzone_position = result + size;
95  DCHECK(redzone_position + kASanRedzoneBytes == position_);
96  ASAN_POISON_MEMORY_REGION(redzone_position, kASanRedzoneBytes);
97 #endif
98 
99  // Check that the result has the proper alignment and return it.
100  DCHECK(IsAddressAligned(result, kAlignment, 0));
102  return reinterpret_cast<void*>(result);
103 }
Address NewExpand(int size)
Definition: zone.cc:201
const int kPointerSize
Definition: globals.h:129
bool IsAddressAligned(Address addr, intptr_t alignment, int offset=0)
Definition: utils.h:129
static const int kASanRedzoneBytes
Definition: zone-inl.h:24

References allocation_size_, DCHECK, v8::internal::IsAddressAligned(), kAlignment, v8::internal::kASanRedzoneBytes, v8::internal::kPointerSize, limit_, NewExpand(), position_, v8::internal::RoundUp(), and size.

Referenced by v8::internal::compiler::BlockList::Add(), v8::internal::Interface::DoAdd(), v8::internal::DynamicScopePart::DynamicScopePart(), v8::internal::compiler::GenericNode< B, S >::EnsureAppendableInputs(), v8::internal::compiler::GenericNode< B, S >::New(), v8::internal::compiler::GapInstruction::New(), v8::internal::compiler::FINAL< kOperandKind, kNumCachedOperands >::New(), v8::internal::compiler::Instruction::New(), NewArray(), v8::internal::HOptimizedGraphBuilder::operator new(), and v8::internal::ZoneTypeConfig::struct_create().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ NewArray()

template<typename T >
T* v8::internal::Zone::NewArray ( int  length)
inline

Definition at line 46 of file zone.h.

46  {
47  CHECK(std::numeric_limits<int>::max() / static_cast<int>(sizeof(T)) >
48  length);
49  return static_cast<T*>(New(length * sizeof(T)));
50  }
void * New(int size)
Definition: zone.cc:65
#define CHECK(condition)
Definition: logging.h:36
#define T(name, string, precedence)
Definition: token.cc:25

References CHECK, New(), and T.

Referenced by v8::internal::zone_allocator< T >::allocate(), v8::internal::compiler::ComputeLoopInfo(), v8::internal::compiler::Scheduler::ComputeSpecialRPO(), v8::internal::HPositionInfo::ensure_storage_for_operand_positions(), v8::internal::compiler::NodeCache< Key >::Find(), v8::internal::AstValueFactory::GetString(), v8::internal::FINAL< kOperandKind, kNumCachedOperands >::Grow(), v8::internal::compiler::StructuredGraphBuilder::MakeNode(), v8::internal::compiler::StructuredGraphBuilder::NewEffectPhi(), v8::internal::compiler::StructuredGraphBuilder::NewPhi(), v8::internal::compiler::AstGraphBuilder::ProcessArguments(), v8::internal::compiler::RawMachineAssembler::RawMachineAssembler(), and v8::internal::compiler::NodeCache< Key >::Resize().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ NewExpand()

Address v8::internal::Zone::NewExpand ( int  size)
private

Definition at line 201 of file zone.cc.

201  {
202  // Make sure the requested size is already properly aligned and that
203  // there isn't enough room in the Zone to satisfy the request.
206 
207  // Compute the new segment size. We use a 'high water mark'
208  // strategy, where we increase the segment size every time we expand
209  // except that we employ a maximum segment size when we delete. This
210  // is to avoid excessive malloc() and free() overhead.
211  Segment* head = segment_head_;
212  const size_t old_size = (head == NULL) ? 0 : head->size();
213  static const size_t kSegmentOverhead = sizeof(Segment) + kAlignment;
214  const size_t new_size_no_overhead = size + (old_size << 1);
215  size_t new_size = kSegmentOverhead + new_size_no_overhead;
216  const size_t min_new_size = kSegmentOverhead + static_cast<size_t>(size);
217  // Guard against integer overflow.
218  if (new_size_no_overhead < static_cast<size_t>(size) ||
219  new_size < static_cast<size_t>(kSegmentOverhead)) {
221  return NULL;
222  }
223  if (new_size < static_cast<size_t>(kMinimumSegmentSize)) {
224  new_size = kMinimumSegmentSize;
225  } else if (new_size > static_cast<size_t>(kMaximumSegmentSize)) {
226  // Limit the size of new segments to avoid growing the segment size
227  // exponentially, thus putting pressure on contiguous virtual address space.
228  // All the while making sure to allocate a segment large enough to hold the
229  // requested size.
230  new_size = Max(min_new_size, static_cast<size_t>(kMaximumSegmentSize));
231  }
232  if (new_size > INT_MAX) {
234  return NULL;
235  }
236  Segment* segment = NewSegment(static_cast<int>(new_size));
237  if (segment == NULL) {
239  return NULL;
240  }
241 
242  // Recompute 'top' and 'limit' based on the new segment.
243  Address result = RoundUp(segment->start(), kAlignment);
244  position_ = result + size;
245  // Check for address overflow.
246  // (Should not happen since the segment is guaranteed to accomodate
247  // size bytes + header and alignment padding)
248  if (reinterpret_cast<uintptr_t>(position_)
249  < reinterpret_cast<uintptr_t>(result)) {
251  return NULL;
252  }
253  limit_ = segment->end();
254  DCHECK(position_ <= limit_);
255  return result;
256 }
static void FatalProcessOutOfMemory(const char *location, bool take_snapshot=false)
static const int kMaximumSegmentSize
Definition: zone.h:87
static const int kMinimumSegmentSize
Definition: zone.h:84
T RoundDown(T x, intptr_t m)
Definition: macros.h:399
static LifetimePosition Max(LifetimePosition a, LifetimePosition b)

References DCHECK, v8::internal::Segment::end(), v8::internal::V8::FatalProcessOutOfMemory(), kAlignment, kMaximumSegmentSize, kMinimumSegmentSize, limit_, v8::internal::Max(), NULL, position_, RoundDown(), v8::internal::RoundUp(), segment_head_, size, v8::internal::Segment::size(), and v8::internal::Segment::start().

Referenced by New().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Friends And Related Function Documentation

◆ Isolate

friend class Isolate
friend

Definition at line 71 of file zone.h.

Member Data Documentation

◆ allocation_size_

unsigned v8::internal::Zone::allocation_size_
private

Definition at line 96 of file zone.h.

Referenced by allocation_size(), and New().

◆ isolate_

Isolate* v8::internal::Zone::isolate_
private

Definition at line 123 of file zone.h.

Referenced by adjust_segment_bytes_allocated(), and isolate().

◆ kAlignment

const int v8::internal::Zone::kAlignment = kPointerSize
staticprivate

Definition at line 80 of file zone.h.

Referenced by DeleteAll(), New(), and NewExpand().

◆ kExcessLimit

const int v8::internal::Zone::kExcessLimit = 256 * MB
staticprivate

Definition at line 93 of file zone.h.

Referenced by excess_allocation().

◆ kMaximumKeptSegmentSize

const int v8::internal::Zone::kMaximumKeptSegmentSize = 64 * KB
staticprivate

Definition at line 90 of file zone.h.

Referenced by DeleteAll().

◆ kMaximumSegmentSize

const int v8::internal::Zone::kMaximumSegmentSize = 1 * MB
staticprivate

Definition at line 87 of file zone.h.

Referenced by NewExpand().

◆ kMinimumSegmentSize

const int v8::internal::Zone::kMinimumSegmentSize = 8 * KB
staticprivate

Definition at line 84 of file zone.h.

Referenced by NewExpand().

◆ limit_

Address v8::internal::Zone::limit_
private

Definition at line 120 of file zone.h.

Referenced by DeleteAll(), New(), and NewExpand().

◆ position_

Address v8::internal::Zone::position_
private

Definition at line 119 of file zone.h.

Referenced by DeleteAll(), New(), and NewExpand().

◆ segment_bytes_allocated_

int v8::internal::Zone::segment_bytes_allocated_
private

◆ segment_head_

Segment* v8::internal::Zone::segment_head_
private

Definition at line 122 of file zone.h.

Referenced by DeleteAll(), DeleteKeptSegment(), and NewExpand().


The documentation for this class was generated from the following files: