Minor refactoring for Zone class and friends.
R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/885813002 Cr-Commit-Position: refs/heads/master@{#26315}
This commit is contained in:
parent
1f2e5973eb
commit
d0f3e5302c
1
BUILD.gn
1
BUILD.gn
@ -986,7 +986,6 @@ source_set("v8_base") {
|
|||||||
"src/version.h",
|
"src/version.h",
|
||||||
"src/vm-state-inl.h",
|
"src/vm-state-inl.h",
|
||||||
"src/vm-state.h",
|
"src/vm-state.h",
|
||||||
"src/zone-inl.h",
|
|
||||||
"src/zone.cc",
|
"src/zone.cc",
|
||||||
"src/zone.h",
|
"src/zone.h",
|
||||||
"src/third_party/fdlibm/fdlibm.cc",
|
"src/third_party/fdlibm/fdlibm.cc",
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
#include "src/types.h"
|
#include "src/types.h"
|
||||||
#include "src/utils.h"
|
#include "src/utils.h"
|
||||||
#include "src/variables.h"
|
#include "src/variables.h"
|
||||||
#include "src/zone-inl.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "src/allocation.h"
|
#include "src/allocation.h"
|
||||||
#include "src/ast.h"
|
#include "src/ast.h"
|
||||||
#include "src/compiler.h"
|
#include "src/compiler.h"
|
||||||
#include "src/zone-inl.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
#include "src/base/lazy-instance.h"
|
#include "src/base/lazy-instance.h"
|
||||||
#include "src/compiler/opcodes.h"
|
#include "src/compiler/opcodes.h"
|
||||||
#include "src/compiler/operator.h"
|
#include "src/compiler/operator.h"
|
||||||
#include "src/v8.h"
|
|
||||||
#include "src/zone-inl.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include "src/allocation.h"
|
#include "src/allocation.h"
|
||||||
#include "src/macro-assembler.h"
|
#include "src/macro-assembler.h"
|
||||||
#include "src/zone-inl.h"
|
|
||||||
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#define V8_INTERFACE_H_
|
#define V8_INTERFACE_H_
|
||||||
|
|
||||||
#include "src/ast-value-factory.h"
|
#include "src/ast-value-factory.h"
|
||||||
#include "src/zone-inl.h" // For operator new.
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include "src/allocation.h"
|
#include "src/allocation.h"
|
||||||
#include "src/assembler.h"
|
#include "src/assembler.h"
|
||||||
#include "src/zone-inl.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include "src/sampler.h"
|
#include "src/sampler.h"
|
||||||
#include "src/scopeinfo.h"
|
#include "src/scopeinfo.h"
|
||||||
#include "src/unicode.h"
|
#include "src/unicode.h"
|
||||||
#include "src/zone-inl.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "src/disasm.h"
|
#include "src/disasm.h"
|
||||||
#include "src/macro-assembler.h"
|
#include "src/macro-assembler.h"
|
||||||
#include "src/ostreams.h"
|
#include "src/ostreams.h"
|
||||||
#include "src/zone-inl.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include "src/allocation.h"
|
#include "src/allocation.h"
|
||||||
#include "src/variables.h"
|
#include "src/variables.h"
|
||||||
#include "src/zone-inl.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "src/allocation.h"
|
#include "src/allocation.h"
|
||||||
#include "src/globals.h"
|
#include "src/globals.h"
|
||||||
#include "src/types.h"
|
#include "src/types.h"
|
||||||
#include "src/zone-inl.h"
|
#include "src/zone.h"
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
1
src/v8.h
1
src/v8.h
@ -44,7 +44,6 @@
|
|||||||
#include "src/log-inl.h" // NOLINT
|
#include "src/log-inl.h" // NOLINT
|
||||||
#include "src/handles-inl.h" // NOLINT
|
#include "src/handles-inl.h" // NOLINT
|
||||||
#include "src/types-inl.h" // NOLINT
|
#include "src/types-inl.h" // NOLINT
|
||||||
#include "src/zone-inl.h" // NOLINT
|
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef V8_ZONE_INL_H_
|
|
||||||
#define V8_ZONE_INL_H_
|
|
||||||
|
|
||||||
#include "src/zone.h"
|
|
||||||
|
|
||||||
#ifdef V8_USE_ADDRESS_SANITIZER
|
|
||||||
#include <sanitizer/asan_interface.h>
|
|
||||||
#else
|
|
||||||
#define ASAN_UNPOISON_MEMORY_REGION(start, size) ((void) 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "src/counters.h"
|
|
||||||
#include "src/isolate.h"
|
|
||||||
#include "src/utils.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
|
|
||||||
static const int kASanRedzoneBytes = 24; // Must be a multiple of 8.
|
|
||||||
|
|
||||||
|
|
||||||
bool Zone::excess_allocation() {
|
|
||||||
return segment_bytes_allocated_ > kExcessLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Zone::adjust_segment_bytes_allocated(int delta) {
|
|
||||||
segment_bytes_allocated_ += delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Config>
|
|
||||||
ZoneSplayTree<Config>::~ZoneSplayTree() {
|
|
||||||
// Reset the root to avoid unneeded iteration over all tree nodes
|
|
||||||
// in the destructor. For a zone-allocated tree, nodes will be
|
|
||||||
// freed by the Zone.
|
|
||||||
SplayTree<Config, ZoneAllocationPolicy>::ResetRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void* ZoneObject::operator new(size_t size, Zone* zone) {
|
|
||||||
return zone->New(static_cast<int>(size));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void* ZoneAllocationPolicy::New(size_t size) {
|
|
||||||
DCHECK(zone_);
|
|
||||||
return zone_->New(static_cast<int>(size));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void* ZoneList<T>::operator new(size_t size, Zone* zone) {
|
|
||||||
return zone->New(static_cast<int>(size));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void* ZoneSplayTree<T>::operator new(size_t size, Zone* zone) {
|
|
||||||
return zone->New(static_cast<int>(size));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace v8::internal
|
|
||||||
|
|
||||||
#endif // V8_ZONE_INL_H_
|
|
100
src/zone.cc
100
src/zone.cc
@ -2,14 +2,43 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include <string.h>
|
#include "src/zone.h"
|
||||||
|
|
||||||
#include "src/v8.h"
|
#include <cstring>
|
||||||
#include "src/zone-inl.h"
|
|
||||||
|
#ifdef V8_USE_ADDRESS_SANITIZER
|
||||||
|
#include <sanitizer/asan_interface.h>
|
||||||
|
#endif // V8_USE_ADDRESS_SANITIZER
|
||||||
|
|
||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
#if V8_USE_ADDRESS_SANITIZER
|
||||||
|
|
||||||
|
const int kASanRedzoneBytes = 24; // Must be a multiple of 8.
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ASAN_POISON_MEMORY_REGION(start, size) \
|
||||||
|
do { \
|
||||||
|
USE(start); \
|
||||||
|
USE(size); \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
#define ASAN_UNPOISON_MEMORY_REGION(start, size) \
|
||||||
|
do { \
|
||||||
|
USE(start); \
|
||||||
|
USE(size); \
|
||||||
|
} while (false)
|
||||||
|
|
||||||
|
const int kASanRedzoneBytes = 0;
|
||||||
|
|
||||||
|
#endif // V8_USE_ADDRESS_SANITIZER
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
// Segments represent chunks of memory: They have starting address
|
// Segments represent chunks of memory: They have starting address
|
||||||
// (encoded in the this pointer) and a size in bytes. Segments are
|
// (encoded in the this pointer) and a size in bytes. Segments are
|
||||||
@ -25,7 +54,7 @@ class Segment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Segment* next() const { return next_; }
|
Segment* next() const { return next_; }
|
||||||
void clear_next() { next_ = NULL; }
|
void clear_next() { next_ = nullptr; }
|
||||||
|
|
||||||
int size() const { return size_; }
|
int size() const { return size_; }
|
||||||
int capacity() const { return size_ - sizeof(Segment); }
|
int capacity() const { return size_ - sizeof(Segment); }
|
||||||
@ -49,7 +78,7 @@ Zone::Zone()
|
|||||||
segment_bytes_allocated_(0),
|
segment_bytes_allocated_(0),
|
||||||
position_(0),
|
position_(0),
|
||||||
limit_(0),
|
limit_(0),
|
||||||
segment_head_(NULL) {}
|
segment_head_(nullptr) {}
|
||||||
|
|
||||||
|
|
||||||
Zone::~Zone() {
|
Zone::~Zone() {
|
||||||
@ -75,24 +104,16 @@ void* Zone::New(int size) {
|
|||||||
// Check if the requested size is available without expanding.
|
// Check if the requested size is available without expanding.
|
||||||
Address result = position_;
|
Address result = position_;
|
||||||
|
|
||||||
int size_with_redzone =
|
const int size_with_redzone = size + kASanRedzoneBytes;
|
||||||
#ifdef V8_USE_ADDRESS_SANITIZER
|
|
||||||
size + kASanRedzoneBytes;
|
|
||||||
#else
|
|
||||||
size;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (size_with_redzone > limit_ - position_) {
|
if (size_with_redzone > limit_ - position_) {
|
||||||
result = NewExpand(size_with_redzone);
|
result = NewExpand(size_with_redzone);
|
||||||
} else {
|
} else {
|
||||||
position_ += size_with_redzone;
|
position_ += size_with_redzone;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef V8_USE_ADDRESS_SANITIZER
|
|
||||||
Address redzone_position = result + size;
|
Address redzone_position = result + size;
|
||||||
DCHECK(redzone_position + kASanRedzoneBytes == position_);
|
DCHECK(redzone_position + kASanRedzoneBytes == position_);
|
||||||
ASAN_POISON_MEMORY_REGION(redzone_position, kASanRedzoneBytes);
|
ASAN_POISON_MEMORY_REGION(redzone_position, kASanRedzoneBytes);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Check that the result has the proper alignment and return it.
|
// Check that the result has the proper alignment and return it.
|
||||||
DCHECK(IsAddressAligned(result, kAlignment, 0));
|
DCHECK(IsAddressAligned(result, kAlignment, 0));
|
||||||
@ -108,12 +129,12 @@ void Zone::DeleteAll() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Find a segment with a suitable size to keep around.
|
// Find a segment with a suitable size to keep around.
|
||||||
Segment* keep = NULL;
|
Segment* keep = nullptr;
|
||||||
// Traverse the chained list of segments, zapping (in debug mode)
|
// Traverse the chained list of segments, zapping (in debug mode)
|
||||||
// and freeing every segment except the one we wish to keep.
|
// and freeing every segment except the one we wish to keep.
|
||||||
for (Segment* current = segment_head_; current != NULL; ) {
|
for (Segment* current = segment_head_; current;) {
|
||||||
Segment* next = current->next();
|
Segment* next = current->next();
|
||||||
if (keep == NULL && current->size() <= kMaximumKeptSegmentSize) {
|
if (!keep && current->size() <= kMaximumKeptSegmentSize) {
|
||||||
// Unlink the segment we wish to keep from the list.
|
// Unlink the segment we wish to keep from the list.
|
||||||
keep = current;
|
keep = current;
|
||||||
keep->clear_next();
|
keep->clear_next();
|
||||||
@ -134,7 +155,7 @@ void Zone::DeleteAll() {
|
|||||||
// variables 'position' and 'limit' to prepare for future allocate
|
// variables 'position' and 'limit' to prepare for future allocate
|
||||||
// attempts. Otherwise, we must clear the position and limit to
|
// attempts. Otherwise, we must clear the position and limit to
|
||||||
// force a new segment to be allocated on demand.
|
// force a new segment to be allocated on demand.
|
||||||
if (keep != NULL) {
|
if (keep) {
|
||||||
Address start = keep->start();
|
Address start = keep->start();
|
||||||
position_ = RoundUp(start, kAlignment);
|
position_ = RoundUp(start, kAlignment);
|
||||||
limit_ = keep->end();
|
limit_ = keep->end();
|
||||||
@ -160,8 +181,8 @@ void Zone::DeleteKeptSegment() {
|
|||||||
static const unsigned char kZapDeadByte = 0xcd;
|
static const unsigned char kZapDeadByte = 0xcd;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DCHECK(segment_head_ == NULL || segment_head_->next() == NULL);
|
DCHECK(segment_head_ == nullptr || segment_head_->next() == nullptr);
|
||||||
if (segment_head_ != NULL) {
|
if (segment_head_ != nullptr) {
|
||||||
int size = segment_head_->size();
|
int size = segment_head_->size();
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// Un-poison first so the zapping doesn't trigger ASan complaints.
|
// Un-poison first so the zapping doesn't trigger ASan complaints.
|
||||||
@ -170,7 +191,7 @@ void Zone::DeleteKeptSegment() {
|
|||||||
memset(segment_head_, kZapDeadByte, size);
|
memset(segment_head_, kZapDeadByte, size);
|
||||||
#endif
|
#endif
|
||||||
DeleteSegment(segment_head_, size);
|
DeleteSegment(segment_head_, size);
|
||||||
segment_head_ = NULL;
|
segment_head_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
DCHECK(segment_bytes_allocated_ == 0);
|
DCHECK(segment_bytes_allocated_ == 0);
|
||||||
@ -181,8 +202,8 @@ void Zone::DeleteKeptSegment() {
|
|||||||
// of the segment chain. Returns the new segment.
|
// of the segment chain. Returns the new segment.
|
||||||
Segment* Zone::NewSegment(int size) {
|
Segment* Zone::NewSegment(int size) {
|
||||||
Segment* result = reinterpret_cast<Segment*>(Malloced::New(size));
|
Segment* result = reinterpret_cast<Segment*>(Malloced::New(size));
|
||||||
adjust_segment_bytes_allocated(size);
|
segment_bytes_allocated_ += size;
|
||||||
if (result != NULL) {
|
if (result != nullptr) {
|
||||||
result->Initialize(segment_head_, size);
|
result->Initialize(segment_head_, size);
|
||||||
segment_head_ = result;
|
segment_head_ = result;
|
||||||
}
|
}
|
||||||
@ -192,7 +213,7 @@ Segment* Zone::NewSegment(int size) {
|
|||||||
|
|
||||||
// Deletes the given segment. Does not touch the segment chain.
|
// Deletes the given segment. Does not touch the segment chain.
|
||||||
void Zone::DeleteSegment(Segment* segment, int size) {
|
void Zone::DeleteSegment(Segment* segment, int size) {
|
||||||
adjust_segment_bytes_allocated(-size);
|
segment_bytes_allocated_ -= size;
|
||||||
Malloced::Delete(segment);
|
Malloced::Delete(segment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +229,7 @@ Address Zone::NewExpand(int size) {
|
|||||||
// except that we employ a maximum segment size when we delete. This
|
// except that we employ a maximum segment size when we delete. This
|
||||||
// is to avoid excessive malloc() and free() overhead.
|
// is to avoid excessive malloc() and free() overhead.
|
||||||
Segment* head = segment_head_;
|
Segment* head = segment_head_;
|
||||||
const size_t old_size = (head == NULL) ? 0 : head->size();
|
const size_t old_size = (head == nullptr) ? 0 : head->size();
|
||||||
static const size_t kSegmentOverhead = sizeof(Segment) + kAlignment;
|
static const size_t kSegmentOverhead = sizeof(Segment) + kAlignment;
|
||||||
const size_t new_size_no_overhead = size + (old_size << 1);
|
const size_t new_size_no_overhead = size + (old_size << 1);
|
||||||
size_t new_size = kSegmentOverhead + new_size_no_overhead;
|
size_t new_size = kSegmentOverhead + new_size_no_overhead;
|
||||||
@ -216,8 +237,8 @@ Address Zone::NewExpand(int size) {
|
|||||||
// Guard against integer overflow.
|
// Guard against integer overflow.
|
||||||
if (new_size_no_overhead < static_cast<size_t>(size) ||
|
if (new_size_no_overhead < static_cast<size_t>(size) ||
|
||||||
new_size < static_cast<size_t>(kSegmentOverhead)) {
|
new_size < static_cast<size_t>(kSegmentOverhead)) {
|
||||||
V8::FatalProcessOutOfMemory("Zone");
|
FatalProcessOutOfMemory("Zone");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (new_size < static_cast<size_t>(kMinimumSegmentSize)) {
|
if (new_size < static_cast<size_t>(kMinimumSegmentSize)) {
|
||||||
new_size = kMinimumSegmentSize;
|
new_size = kMinimumSegmentSize;
|
||||||
@ -229,13 +250,13 @@ Address Zone::NewExpand(int size) {
|
|||||||
new_size = Max(min_new_size, static_cast<size_t>(kMaximumSegmentSize));
|
new_size = Max(min_new_size, static_cast<size_t>(kMaximumSegmentSize));
|
||||||
}
|
}
|
||||||
if (new_size > INT_MAX) {
|
if (new_size > INT_MAX) {
|
||||||
V8::FatalProcessOutOfMemory("Zone");
|
FatalProcessOutOfMemory("Zone");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
Segment* segment = NewSegment(static_cast<int>(new_size));
|
Segment* segment = NewSegment(static_cast<int>(new_size));
|
||||||
if (segment == NULL) {
|
if (segment == nullptr) {
|
||||||
V8::FatalProcessOutOfMemory("Zone");
|
FatalProcessOutOfMemory("Zone");
|
||||||
return NULL;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recompute 'top' and 'limit' based on the new segment.
|
// Recompute 'top' and 'limit' based on the new segment.
|
||||||
@ -244,15 +265,12 @@ Address Zone::NewExpand(int size) {
|
|||||||
// Check for address overflow.
|
// Check for address overflow.
|
||||||
// (Should not happen since the segment is guaranteed to accomodate
|
// (Should not happen since the segment is guaranteed to accomodate
|
||||||
// size bytes + header and alignment padding)
|
// size bytes + header and alignment padding)
|
||||||
if (reinterpret_cast<uintptr_t>(position_)
|
DCHECK_GE(reinterpret_cast<uintptr_t>(position_),
|
||||||
< reinterpret_cast<uintptr_t>(result)) {
|
reinterpret_cast<uintptr_t>(result));
|
||||||
V8::FatalProcessOutOfMemory("Zone");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
limit_ = segment->end();
|
limit_ = segment->end();
|
||||||
DCHECK(position_ <= limit_);
|
DCHECK(position_ <= limit_);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
} } // namespace v8::internal
|
} // namespace v8
|
||||||
|
84
src/zone.h
84
src/zone.h
@ -17,35 +17,35 @@
|
|||||||
namespace v8 {
|
namespace v8 {
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
|
// Forward declarations.
|
||||||
class Segment;
|
class Segment;
|
||||||
class Isolate;
|
|
||||||
|
|
||||||
// The Zone supports very fast allocation of small chunks of
|
// The Zone supports very fast allocation of small chunks of
|
||||||
// memory. The chunks cannot be deallocated individually, but instead
|
// memory. The chunks cannot be deallocated individually, but instead
|
||||||
// the Zone supports deallocating all chunks in one fast
|
// the Zone supports deallocating all chunks in one fast
|
||||||
// operation. The Zone is used to hold temporary data structures like
|
// operation. The Zone is used to hold temporary data structures like
|
||||||
// the abstract syntax tree, which is deallocated after compilation.
|
// the abstract syntax tree, which is deallocated after compilation.
|
||||||
|
//
|
||||||
// Note: There is no need to initialize the Zone; the first time an
|
// Note: There is no need to initialize the Zone; the first time an
|
||||||
// allocation is attempted, a segment of memory will be requested
|
// allocation is attempted, a segment of memory will be requested
|
||||||
// through a call to malloc().
|
// through a call to malloc().
|
||||||
|
//
|
||||||
// Note: The implementation is inherently not thread safe. Do not use
|
// Note: The implementation is inherently not thread safe. Do not use
|
||||||
// from multi-threaded code.
|
// from multi-threaded code.
|
||||||
|
class Zone FINAL {
|
||||||
class Zone {
|
|
||||||
public:
|
public:
|
||||||
Zone();
|
Zone();
|
||||||
~Zone();
|
~Zone();
|
||||||
|
|
||||||
// Allocate 'size' bytes of memory in the Zone; expands the Zone by
|
// Allocate 'size' bytes of memory in the Zone; expands the Zone by
|
||||||
// allocating new segments of memory on demand using malloc().
|
// allocating new segments of memory on demand using malloc().
|
||||||
void* New(int size);
|
void* New(int size);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T* NewArray(int length) {
|
T* NewArray(int length) {
|
||||||
CHECK(std::numeric_limits<int>::max() / static_cast<int>(sizeof(T)) >
|
DCHECK(std::numeric_limits<int>::max() / static_cast<int>(sizeof(T)) >
|
||||||
length);
|
length);
|
||||||
return static_cast<T*>(New(length * sizeof(T)));
|
return static_cast<T*>(New(length * sizeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,15 +59,13 @@ class Zone {
|
|||||||
|
|
||||||
// Returns true if more memory has been allocated in zones than
|
// Returns true if more memory has been allocated in zones than
|
||||||
// the limit allows.
|
// the limit allows.
|
||||||
inline bool excess_allocation();
|
bool excess_allocation() const {
|
||||||
|
return segment_bytes_allocated_ > kExcessLimit;
|
||||||
|
}
|
||||||
|
|
||||||
inline void adjust_segment_bytes_allocated(int delta);
|
unsigned allocation_size() const { return allocation_size_; }
|
||||||
|
|
||||||
inline unsigned allocation_size() const { return allocation_size_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Isolate;
|
|
||||||
|
|
||||||
// All pointers returned from New() have this alignment. In addition, if the
|
// All pointers returned from New() have this alignment. In addition, if the
|
||||||
// object being allocated has a size that is divisible by 8 then its alignment
|
// object being allocated has a size that is divisible by 8 then its alignment
|
||||||
// will be 8. ASan requires 8-byte alignment.
|
// will be 8. ASan requires 8-byte alignment.
|
||||||
@ -106,10 +104,10 @@ class Zone {
|
|||||||
|
|
||||||
// Creates a new segment, sets it size, and pushes it to the front
|
// Creates a new segment, sets it size, and pushes it to the front
|
||||||
// of the segment chain. Returns the new segment.
|
// of the segment chain. Returns the new segment.
|
||||||
INLINE(Segment* NewSegment(int size));
|
inline Segment* NewSegment(int size);
|
||||||
|
|
||||||
// Deletes the given segment. Does not touch the segment chain.
|
// Deletes the given segment. Does not touch the segment chain.
|
||||||
INLINE(void DeleteSegment(Segment* segment, int size));
|
inline void DeleteSegment(Segment* segment, int size);
|
||||||
|
|
||||||
// The free region in the current (front) segment is represented as
|
// The free region in the current (front) segment is represented as
|
||||||
// the half-open interval [position, limit). The 'position' variable
|
// the half-open interval [position, limit). The 'position' variable
|
||||||
@ -126,7 +124,9 @@ class Zone {
|
|||||||
class ZoneObject {
|
class ZoneObject {
|
||||||
public:
|
public:
|
||||||
// Allocate a new ZoneObject of 'size' bytes in the Zone.
|
// Allocate a new ZoneObject of 'size' bytes in the Zone.
|
||||||
INLINE(void* operator new(size_t size, Zone* zone));
|
void* operator new(size_t size, Zone* zone) {
|
||||||
|
return zone->New(static_cast<int>(size));
|
||||||
|
}
|
||||||
|
|
||||||
// Ideally, the delete operator should be private instead of
|
// Ideally, the delete operator should be private instead of
|
||||||
// public, but unfortunately the compiler sometimes synthesizes
|
// public, but unfortunately the compiler sometimes synthesizes
|
||||||
@ -143,12 +143,12 @@ class ZoneObject {
|
|||||||
|
|
||||||
// The ZoneScope is used to automatically call DeleteAll() on a
|
// The ZoneScope is used to automatically call DeleteAll() on a
|
||||||
// Zone when the ZoneScope is destroyed (i.e. goes out of scope)
|
// Zone when the ZoneScope is destroyed (i.e. goes out of scope)
|
||||||
struct ZoneScope {
|
class ZoneScope FINAL {
|
||||||
public:
|
public:
|
||||||
explicit ZoneScope(Zone* zone) : zone_(zone) { }
|
explicit ZoneScope(Zone* zone) : zone_(zone) { }
|
||||||
~ZoneScope() { zone_->DeleteAll(); }
|
~ZoneScope() { zone_->DeleteAll(); }
|
||||||
|
|
||||||
Zone* zone() { return zone_; }
|
Zone* zone() const { return zone_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Zone* zone_;
|
Zone* zone_;
|
||||||
@ -157,12 +157,12 @@ struct ZoneScope {
|
|||||||
|
|
||||||
// The ZoneAllocationPolicy is used to specialize generic data
|
// The ZoneAllocationPolicy is used to specialize generic data
|
||||||
// structures to allocate themselves and their elements in the Zone.
|
// structures to allocate themselves and their elements in the Zone.
|
||||||
struct ZoneAllocationPolicy {
|
class ZoneAllocationPolicy FINAL {
|
||||||
public:
|
public:
|
||||||
explicit ZoneAllocationPolicy(Zone* zone) : zone_(zone) { }
|
explicit ZoneAllocationPolicy(Zone* zone) : zone_(zone) { }
|
||||||
INLINE(void* New(size_t size));
|
void* New(size_t size) { return zone()->New(static_cast<int>(size)); }
|
||||||
INLINE(static void Delete(void *pointer)) { }
|
static void Delete(void* pointer) {}
|
||||||
Zone* zone() { return zone_; }
|
Zone* zone() const { return zone_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Zone* zone_;
|
Zone* zone_;
|
||||||
@ -173,15 +173,17 @@ struct ZoneAllocationPolicy {
|
|||||||
// elements. The list itself and all its elements are allocated in the
|
// elements. The list itself and all its elements are allocated in the
|
||||||
// Zone. ZoneLists cannot be deleted individually; you can delete all
|
// Zone. ZoneLists cannot be deleted individually; you can delete all
|
||||||
// objects in the Zone by calling Zone::DeleteAll().
|
// objects in the Zone by calling Zone::DeleteAll().
|
||||||
template<typename T>
|
template <typename T>
|
||||||
class ZoneList: public List<T, ZoneAllocationPolicy> {
|
class ZoneList FINAL : public List<T, ZoneAllocationPolicy> {
|
||||||
public:
|
public:
|
||||||
// Construct a new ZoneList with the given capacity; the length is
|
// Construct a new ZoneList with the given capacity; the length is
|
||||||
// always zero. The capacity must be non-negative.
|
// always zero. The capacity must be non-negative.
|
||||||
ZoneList(int capacity, Zone* zone)
|
ZoneList(int capacity, Zone* zone)
|
||||||
: List<T, ZoneAllocationPolicy>(capacity, ZoneAllocationPolicy(zone)) { }
|
: List<T, ZoneAllocationPolicy>(capacity, ZoneAllocationPolicy(zone)) { }
|
||||||
|
|
||||||
INLINE(void* operator new(size_t size, Zone* zone));
|
void* operator new(size_t size, Zone* zone) {
|
||||||
|
return zone->New(static_cast<int>(size));
|
||||||
|
}
|
||||||
|
|
||||||
// Construct a new ZoneList by copying the elements of the given ZoneList.
|
// Construct a new ZoneList by copying the elements of the given ZoneList.
|
||||||
ZoneList(const ZoneList<T>& other, Zone* zone)
|
ZoneList(const ZoneList<T>& other, Zone* zone)
|
||||||
@ -192,27 +194,27 @@ class ZoneList: public List<T, ZoneAllocationPolicy> {
|
|||||||
|
|
||||||
// We add some convenience wrappers so that we can pass in a Zone
|
// We add some convenience wrappers so that we can pass in a Zone
|
||||||
// instead of a (less convenient) ZoneAllocationPolicy.
|
// instead of a (less convenient) ZoneAllocationPolicy.
|
||||||
INLINE(void Add(const T& element, Zone* zone)) {
|
void Add(const T& element, Zone* zone) {
|
||||||
List<T, ZoneAllocationPolicy>::Add(element, ZoneAllocationPolicy(zone));
|
List<T, ZoneAllocationPolicy>::Add(element, ZoneAllocationPolicy(zone));
|
||||||
}
|
}
|
||||||
INLINE(void AddAll(const List<T, ZoneAllocationPolicy>& other, Zone* zone)) {
|
void AddAll(const List<T, ZoneAllocationPolicy>& other, Zone* zone) {
|
||||||
List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
|
List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
|
||||||
}
|
}
|
||||||
INLINE(void AddAll(const Vector<T>& other, Zone* zone)) {
|
void AddAll(const Vector<T>& other, Zone* zone) {
|
||||||
List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
|
List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
|
||||||
}
|
}
|
||||||
INLINE(void InsertAt(int index, const T& element, Zone* zone)) {
|
void InsertAt(int index, const T& element, Zone* zone) {
|
||||||
List<T, ZoneAllocationPolicy>::InsertAt(index, element,
|
List<T, ZoneAllocationPolicy>::InsertAt(index, element,
|
||||||
ZoneAllocationPolicy(zone));
|
ZoneAllocationPolicy(zone));
|
||||||
}
|
}
|
||||||
INLINE(Vector<T> AddBlock(T value, int count, Zone* zone)) {
|
Vector<T> AddBlock(T value, int count, Zone* zone) {
|
||||||
return List<T, ZoneAllocationPolicy>::AddBlock(value, count,
|
return List<T, ZoneAllocationPolicy>::AddBlock(value, count,
|
||||||
ZoneAllocationPolicy(zone));
|
ZoneAllocationPolicy(zone));
|
||||||
}
|
}
|
||||||
INLINE(void Allocate(int length, Zone* zone)) {
|
void Allocate(int length, Zone* zone) {
|
||||||
List<T, ZoneAllocationPolicy>::Allocate(length, ZoneAllocationPolicy(zone));
|
List<T, ZoneAllocationPolicy>::Allocate(length, ZoneAllocationPolicy(zone));
|
||||||
}
|
}
|
||||||
INLINE(void Initialize(int capacity, Zone* zone)) {
|
void Initialize(int capacity, Zone* zone) {
|
||||||
List<T, ZoneAllocationPolicy>::Initialize(capacity,
|
List<T, ZoneAllocationPolicy>::Initialize(capacity,
|
||||||
ZoneAllocationPolicy(zone));
|
ZoneAllocationPolicy(zone));
|
||||||
}
|
}
|
||||||
@ -226,13 +228,20 @@ class ZoneList: public List<T, ZoneAllocationPolicy> {
|
|||||||
// different configurations of a concrete splay tree (see splay-tree.h).
|
// different configurations of a concrete splay tree (see splay-tree.h).
|
||||||
// The tree itself and all its elements are allocated in the Zone.
|
// The tree itself and all its elements are allocated in the Zone.
|
||||||
template <typename Config>
|
template <typename Config>
|
||||||
class ZoneSplayTree: public SplayTree<Config, ZoneAllocationPolicy> {
|
class ZoneSplayTree FINAL : public SplayTree<Config, ZoneAllocationPolicy> {
|
||||||
public:
|
public:
|
||||||
explicit ZoneSplayTree(Zone* zone)
|
explicit ZoneSplayTree(Zone* zone)
|
||||||
: SplayTree<Config, ZoneAllocationPolicy>(ZoneAllocationPolicy(zone)) {}
|
: SplayTree<Config, ZoneAllocationPolicy>(ZoneAllocationPolicy(zone)) {}
|
||||||
~ZoneSplayTree();
|
~ZoneSplayTree() {
|
||||||
|
// Reset the root to avoid unneeded iteration over all tree nodes
|
||||||
|
// in the destructor. For a zone-allocated tree, nodes will be
|
||||||
|
// freed by the Zone.
|
||||||
|
SplayTree<Config, ZoneAllocationPolicy>::ResetRoot();
|
||||||
|
}
|
||||||
|
|
||||||
INLINE(void* operator new(size_t size, Zone* zone));
|
void* operator new(size_t size, Zone* zone) {
|
||||||
|
return zone->New(static_cast<int>(size));
|
||||||
|
}
|
||||||
|
|
||||||
void operator delete(void* pointer) { UNREACHABLE(); }
|
void operator delete(void* pointer) { UNREACHABLE(); }
|
||||||
void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
|
void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
|
||||||
@ -241,6 +250,7 @@ class ZoneSplayTree: public SplayTree<Config, ZoneAllocationPolicy> {
|
|||||||
|
|
||||||
typedef TemplateHashMapImpl<ZoneAllocationPolicy> ZoneHashMap;
|
typedef TemplateHashMapImpl<ZoneAllocationPolicy> ZoneHashMap;
|
||||||
|
|
||||||
} } // namespace v8::internal
|
} // namespace internal
|
||||||
|
} // namespace v8
|
||||||
|
|
||||||
#endif // V8_ZONE_H_
|
#endif // V8_ZONE_H_
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#include "src/regexp-macro-assembler.h"
|
#include "src/regexp-macro-assembler.h"
|
||||||
#include "src/regexp-macro-assembler-irregexp.h"
|
#include "src/regexp-macro-assembler-irregexp.h"
|
||||||
#include "src/string-stream.h"
|
#include "src/string-stream.h"
|
||||||
#include "src/zone-inl.h"
|
|
||||||
#ifdef V8_INTERPRETED_REGEXP
|
#ifdef V8_INTERPRETED_REGEXP
|
||||||
#include "src/interpreter-irregexp.h"
|
#include "src/interpreter-irregexp.h"
|
||||||
#else // V8_INTERPRETED_REGEXP
|
#else // V8_INTERPRETED_REGEXP
|
||||||
|
@ -895,7 +895,6 @@
|
|||||||
'../../src/version.h',
|
'../../src/version.h',
|
||||||
'../../src/vm-state-inl.h',
|
'../../src/vm-state-inl.h',
|
||||||
'../../src/vm-state.h',
|
'../../src/vm-state.h',
|
||||||
'../../src/zone-inl.h',
|
|
||||||
'../../src/zone.cc',
|
'../../src/zone.cc',
|
||||||
'../../src/zone.h',
|
'../../src/zone.h',
|
||||||
'../../src/third_party/fdlibm/fdlibm.cc',
|
'../../src/third_party/fdlibm/fdlibm.cc',
|
||||||
|
Loading…
Reference in New Issue
Block a user