5 #include "src/zone/zone.h" 10 #include "src/utils.h" 18 #ifdef V8_USE_ADDRESS_SANITIZER 20 constexpr
size_t kASanRedzoneBytes = 24;
22 #else // !V8_USE_ADDRESS_SANITIZER 24 constexpr
size_t kASanRedzoneBytes = 0;
26 #endif // V8_USE_ADDRESS_SANITIZER 30 Zone::Zone(AccountingAllocator* allocator,
const char* name,
31 SegmentSize segment_size)
32 : allocation_size_(0),
33 segment_bytes_allocated_(0),
36 allocator_(allocator),
37 segment_head_(nullptr),
40 segment_size_(segment_size) {
41 allocator_->ZoneCreation(
this);
45 allocator_->ZoneDestruction(
this);
48 DCHECK_EQ(segment_bytes_allocated_, 0);
51 void* Zone::AsanNew(
size_t size) {
55 size = RoundUp(size, kAlignmentInBytes);
58 Address result = position_;
60 const size_t size_with_redzone = size + kASanRedzoneBytes;
61 DCHECK_LE(position_, limit_);
62 if (size_with_redzone > limit_ - position_) {
63 result = NewExpand(size_with_redzone);
65 position_ += size_with_redzone;
68 Address redzone_position = result + size;
69 DCHECK_EQ(redzone_position + kASanRedzoneBytes, position_);
70 ASAN_POISON_MEMORY_REGION(reinterpret_cast<void*>(redzone_position),
74 DCHECK(IsAligned(result, kAlignmentInBytes));
75 return reinterpret_cast<void*
>(result);
78 void Zone::ReleaseMemory() {
79 allocator_->ZoneDestruction(
this);
81 allocator_->ZoneCreation(
this);
84 void Zone::DeleteAll() {
86 for (Segment* current = segment_head_; current;) {
87 Segment* next = current->next();
88 size_t size = current->size();
91 ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<void*>(current->start()),
94 segment_bytes_allocated_ -= size;
95 allocator_->ReturnSegment(current);
99 position_ = limit_ = 0;
100 allocation_size_ = 0;
101 segment_head_ =
nullptr;
106 Segment* Zone::NewSegment(
size_t requested_size) {
107 Segment* result = allocator_->GetSegment(requested_size);
108 if (result !=
nullptr) {
109 DCHECK_GE(result->size(), requested_size);
110 segment_bytes_allocated_ += result->size();
111 result->set_zone(
this);
112 result->set_next(segment_head_);
113 segment_head_ = result;
118 Address Zone::NewExpand(
size_t size) {
121 DCHECK_EQ(size, RoundDown(size, kAlignmentInBytes));
122 DCHECK(limit_ - position_ < size);
125 allocation_size_ = allocation_size();
130 Segment* head = segment_head_;
131 const size_t old_size = (head ==
nullptr) ? 0 : head->size();
132 static const size_t kSegmentOverhead =
sizeof(Segment) + kAlignmentInBytes;
133 const size_t new_size_no_overhead = size + (old_size << 1);
134 size_t new_size = kSegmentOverhead + new_size_no_overhead;
135 const size_t min_new_size = kSegmentOverhead + size;
137 if (new_size_no_overhead < size || new_size < kSegmentOverhead) {
138 V8::FatalProcessOutOfMemory(
nullptr,
"Zone");
141 if (segment_size_ == SegmentSize::kLarge) {
142 new_size = kMaximumSegmentSize;
144 if (new_size < kMinimumSegmentSize) {
145 new_size = kMinimumSegmentSize;
146 }
else if (new_size > kMaximumSegmentSize) {
151 new_size = Max(min_new_size, kMaximumSegmentSize);
153 if (new_size > INT_MAX) {
154 V8::FatalProcessOutOfMemory(
nullptr,
"Zone");
157 Segment* segment = NewSegment(new_size);
158 if (segment ==
nullptr) {
159 V8::FatalProcessOutOfMemory(
nullptr,
"Zone");
164 Address result = RoundUp(segment->start(), kAlignmentInBytes);
165 position_ = result + size;
169 DCHECK(position_ >= result);
170 limit_ = segment->end();
171 DCHECK(position_ <= limit_);