| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <string.h> | 5 #include <string.h> |
| 6 | 6 |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 #include "src/zone-inl.h" | 8 #include "src/zone-inl.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 limit_(0), | 51 limit_(0), |
| 52 segment_head_(NULL), | 52 segment_head_(NULL), |
| 53 isolate_(isolate) { | 53 isolate_(isolate) { |
| 54 } | 54 } |
| 55 | 55 |
| 56 | 56 |
| 57 Zone::~Zone() { | 57 Zone::~Zone() { |
| 58 DeleteAll(); | 58 DeleteAll(); |
| 59 DeleteKeptSegment(); | 59 DeleteKeptSegment(); |
| 60 | 60 |
| 61 ASSERT(segment_bytes_allocated_ == 0); | 61 DCHECK(segment_bytes_allocated_ == 0); |
| 62 } | 62 } |
| 63 | 63 |
| 64 | 64 |
| 65 void Zone::DeleteAll() { | 65 void Zone::DeleteAll() { |
| 66 #ifdef DEBUG | 66 #ifdef DEBUG |
| 67 // Constant byte value used for zapping dead memory in debug mode. | 67 // Constant byte value used for zapping dead memory in debug mode. |
| 68 static const unsigned char kZapDeadByte = 0xcd; | 68 static const unsigned char kZapDeadByte = 0xcd; |
| 69 #endif | 69 #endif |
| 70 | 70 |
| 71 // Find a segment with a suitable size to keep around. | 71 // Find a segment with a suitable size to keep around. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 113 segment_head_ = keep; | 113 segment_head_ = keep; |
| 114 } | 114 } |
| 115 | 115 |
| 116 | 116 |
| 117 void Zone::DeleteKeptSegment() { | 117 void Zone::DeleteKeptSegment() { |
| 118 #ifdef DEBUG | 118 #ifdef DEBUG |
| 119 // Constant byte value used for zapping dead memory in debug mode. | 119 // Constant byte value used for zapping dead memory in debug mode. |
| 120 static const unsigned char kZapDeadByte = 0xcd; | 120 static const unsigned char kZapDeadByte = 0xcd; |
| 121 #endif | 121 #endif |
| 122 | 122 |
| 123 ASSERT(segment_head_ == NULL || segment_head_->next() == NULL); | 123 DCHECK(segment_head_ == NULL || segment_head_->next() == NULL); |
| 124 if (segment_head_ != NULL) { | 124 if (segment_head_ != NULL) { |
| 125 int size = segment_head_->size(); | 125 int size = segment_head_->size(); |
| 126 #ifdef DEBUG | 126 #ifdef DEBUG |
| 127 // Un-poison first so the zapping doesn't trigger ASan complaints. | 127 // Un-poison first so the zapping doesn't trigger ASan complaints. |
| 128 ASAN_UNPOISON_MEMORY_REGION(segment_head_, size); | 128 ASAN_UNPOISON_MEMORY_REGION(segment_head_, size); |
| 129 // Zap the entire kept segment (including the header). | 129 // Zap the entire kept segment (including the header). |
| 130 memset(segment_head_, kZapDeadByte, size); | 130 memset(segment_head_, kZapDeadByte, size); |
| 131 #endif | 131 #endif |
| 132 DeleteSegment(segment_head_, size); | 132 DeleteSegment(segment_head_, size); |
| 133 segment_head_ = NULL; | 133 segment_head_ = NULL; |
| 134 } | 134 } |
| 135 | 135 |
| 136 ASSERT(segment_bytes_allocated_ == 0); | 136 DCHECK(segment_bytes_allocated_ == 0); |
| 137 } | 137 } |
| 138 | 138 |
| 139 | 139 |
| 140 // Creates a new segment, sets it size, and pushes it to the front | 140 // Creates a new segment, sets it size, and pushes it to the front |
| 141 // of the segment chain. Returns the new segment. | 141 // of the segment chain. Returns the new segment. |
| 142 Segment* Zone::NewSegment(int size) { | 142 Segment* Zone::NewSegment(int size) { |
| 143 Segment* result = reinterpret_cast<Segment*>(Malloced::New(size)); | 143 Segment* result = reinterpret_cast<Segment*>(Malloced::New(size)); |
| 144 adjust_segment_bytes_allocated(size); | 144 adjust_segment_bytes_allocated(size); |
| 145 if (result != NULL) { | 145 if (result != NULL) { |
| 146 result->Initialize(segment_head_, size); | 146 result->Initialize(segment_head_, size); |
| 147 segment_head_ = result; | 147 segment_head_ = result; |
| 148 } | 148 } |
| 149 return result; | 149 return result; |
| 150 } | 150 } |
| 151 | 151 |
| 152 | 152 |
| 153 // Deletes the given segment. Does not touch the segment chain. | 153 // Deletes the given segment. Does not touch the segment chain. |
| 154 void Zone::DeleteSegment(Segment* segment, int size) { | 154 void Zone::DeleteSegment(Segment* segment, int size) { |
| 155 adjust_segment_bytes_allocated(-size); | 155 adjust_segment_bytes_allocated(-size); |
| 156 Malloced::Delete(segment); | 156 Malloced::Delete(segment); |
| 157 } | 157 } |
| 158 | 158 |
| 159 | 159 |
| 160 Address Zone::NewExpand(int size) { | 160 Address Zone::NewExpand(int size) { |
| 161 // Make sure the requested size is already properly aligned and that | 161 // Make sure the requested size is already properly aligned and that |
| 162 // there isn't enough room in the Zone to satisfy the request. | 162 // there isn't enough room in the Zone to satisfy the request. |
| 163 ASSERT(size == RoundDown(size, kAlignment)); | 163 DCHECK(size == RoundDown(size, kAlignment)); |
| 164 ASSERT(size > limit_ - position_); | 164 DCHECK(size > limit_ - position_); |
| 165 | 165 |
| 166 // Compute the new segment size. We use a 'high water mark' | 166 // Compute the new segment size. We use a 'high water mark' |
| 167 // strategy, where we increase the segment size every time we expand | 167 // strategy, where we increase the segment size every time we expand |
| 168 // except that we employ a maximum segment size when we delete. This | 168 // except that we employ a maximum segment size when we delete. This |
| 169 // is to avoid excessive malloc() and free() overhead. | 169 // is to avoid excessive malloc() and free() overhead. |
| 170 Segment* head = segment_head_; | 170 Segment* head = segment_head_; |
| 171 const size_t old_size = (head == NULL) ? 0 : head->size(); | 171 const size_t old_size = (head == NULL) ? 0 : head->size(); |
| 172 static const size_t kSegmentOverhead = sizeof(Segment) + kAlignment; | 172 static const size_t kSegmentOverhead = sizeof(Segment) + kAlignment; |
| 173 const size_t new_size_no_overhead = size + (old_size << 1); | 173 const size_t new_size_no_overhead = size + (old_size << 1); |
| 174 size_t new_size = kSegmentOverhead + new_size_no_overhead; | 174 size_t new_size = kSegmentOverhead + new_size_no_overhead; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 203 position_ = result + size; | 203 position_ = result + size; |
| 204 // Check for address overflow. | 204 // Check for address overflow. |
| 205 // (Should not happen since the segment is guaranteed to accomodate | 205 // (Should not happen since the segment is guaranteed to accomodate |
| 206 // size bytes + header and alignment padding) | 206 // size bytes + header and alignment padding) |
| 207 if (reinterpret_cast<uintptr_t>(position_) | 207 if (reinterpret_cast<uintptr_t>(position_) |
| 208 < reinterpret_cast<uintptr_t>(result)) { | 208 < reinterpret_cast<uintptr_t>(result)) { |
| 209 V8::FatalProcessOutOfMemory("Zone"); | 209 V8::FatalProcessOutOfMemory("Zone"); |
| 210 return NULL; | 210 return NULL; |
| 211 } | 211 } |
| 212 limit_ = segment->end(); | 212 limit_ = segment->end(); |
| 213 ASSERT(position_ <= limit_); | 213 DCHECK(position_ <= limit_); |
| 214 return result; | 214 return result; |
| 215 } | 215 } |
| 216 | 216 |
| 217 | 217 |
| 218 } } // namespace v8::internal | 218 } } // namespace v8::internal |
| OLD | NEW |