| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/zone.h" | 5 #include "vm/zone.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
| 10 #include "vm/heap.h" | 10 #include "vm/heap.h" |
| 11 #include "vm/heap_trace.h" | 11 #include "vm/heap_trace.h" |
| 12 #include "vm/isolate.h" | 12 #include "vm/isolate.h" |
| 13 #include "vm/os.h" | 13 #include "vm/os.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 DEFINE_DEBUG_FLAG(bool, trace_zone_sizes, | 17 DEFINE_DEBUG_FLAG(bool, trace_zones, |
| 18 false, "Traces allocation sizes in the zone."); | 18 false, "Traces allocation sizes in the zone."); |
| 19 | 19 |
| 20 | 20 |
| 21 // Zone segments represent chunks of memory: They have starting | 21 // Zone segments represent chunks of memory: They have starting |
| 22 // address encoded in the this pointer and a size in bytes. They are | 22 // address encoded in the this pointer and a size in bytes. They are |
| 23 // chained together to form the backing storage for an expanding zone. | 23 // chained together to form the backing storage for an expanding zone. |
| 24 class Zone::Segment { | 24 class Zone::Segment { |
| 25 public: | 25 public: |
| 26 Segment* next() const { return next_; } | 26 Segment* next() const { return next_; } |
| 27 intptr_t size() const { return size_; } | 27 intptr_t size() const { return size_; } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 | 77 |
| 78 Zone::Zone() | 78 Zone::Zone() |
| 79 : initial_buffer_(buffer_, kInitialChunkSize), | 79 : initial_buffer_(buffer_, kInitialChunkSize), |
| 80 position_(initial_buffer_.start()), | 80 position_(initial_buffer_.start()), |
| 81 limit_(initial_buffer_.end()), | 81 limit_(initial_buffer_.end()), |
| 82 head_(NULL), | 82 head_(NULL), |
| 83 large_segments_(NULL), | 83 large_segments_(NULL), |
| 84 handles_(), | 84 handles_(), |
| 85 previous_(NULL) { | 85 previous_(NULL) { |
| 86 #ifdef DEBUG | 86 #ifdef DEBUG |
| 87 // Zap the entire initial buffer. | 87 // Zap the entire initial buffer. |
| 88 memset(initial_buffer_.pointer(), kZapUninitializedByte, | 88 memset(initial_buffer_.pointer(), kZapUninitializedByte, |
| 89 initial_buffer_.size()); | 89 initial_buffer_.size()); |
| 90 #endif | 90 #endif |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 Zone::~Zone() { | 94 Zone::~Zone() { |
| 95 #if defined(DEBUG) |
| 96 if (FLAG_trace_zones) { |
| 97 DumpZoneSizes(); |
| 98 } |
| 99 #endif |
| 95 DeleteAll(); | 100 DeleteAll(); |
| 96 if (HeapTrace::is_enabled()) { | 101 if (HeapTrace::is_enabled()) { |
| 97 Isolate* isolate = Isolate::Current(); | 102 Isolate* isolate = Isolate::Current(); |
| 98 isolate->heap()->trace()->TraceDeleteZone(this); | 103 isolate->heap()->trace()->TraceDeleteZone(this); |
| 99 } | 104 } |
| 100 #if defined(DEBUG) | |
| 101 if (FLAG_trace_zone_sizes) { | |
| 102 DumpZoneSizes(); | |
| 103 } | |
| 104 #endif | |
| 105 } | 105 } |
| 106 | 106 |
| 107 | 107 |
| 108 void Zone::DeleteAll() { | 108 void Zone::DeleteAll() { |
| 109 // Traverse the chained list of segments, zapping (in debug mode) | 109 // Traverse the chained list of segments, zapping (in debug mode) |
| 110 // and freeing every zone segment. | 110 // and freeing every zone segment. |
| 111 Segment::DeleteSegmentList(head_); | 111 Segment::DeleteSegmentList(head_); |
| 112 Segment::DeleteSegmentList(large_segments_); | 112 Segment::DeleteSegmentList(large_segments_); |
| 113 | 113 |
| 114 // Reset zone state. | 114 // Reset zone state. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 134 for (Segment* s = head_->next(); s != NULL; s = s->next()) { | 134 for (Segment* s = head_->next(); s != NULL; s = s->next()) { |
| 135 size += s->size(); | 135 size += s->size(); |
| 136 } | 136 } |
| 137 return size + (position_ - head_->start()); | 137 return size + (position_ - head_->start()); |
| 138 } | 138 } |
| 139 | 139 |
| 140 | 140 |
| 141 uword Zone::AllocateExpand(intptr_t size) { | 141 uword Zone::AllocateExpand(intptr_t size) { |
| 142 #if defined(DEBUG) | 142 #if defined(DEBUG) |
| 143 ASSERT(size >= 0); | 143 ASSERT(size >= 0); |
| 144 if (FLAG_trace_zone_sizes) { | 144 if (FLAG_trace_zones) { |
| 145 OS::PrintErr("*** Expanding zone 0x%"Px"\n", |
| 146 reinterpret_cast<intptr_t>(this)); |
| 145 DumpZoneSizes(); | 147 DumpZoneSizes(); |
| 146 } | 148 } |
| 147 // Make sure the requested size is already properly aligned and that | 149 // Make sure the requested size is already properly aligned and that |
| 148 // there isn't enough room in the Zone to satisfy the request. | 150 // there isn't enough room in the Zone to satisfy the request. |
| 149 ASSERT(Utils::IsAligned(size, kAlignment)); | 151 ASSERT(Utils::IsAligned(size, kAlignment)); |
| 150 intptr_t free_size = (limit_ - position_); | 152 intptr_t free_size = (limit_ - position_); |
| 151 ASSERT(free_size < size); | 153 ASSERT(free_size < size); |
| 152 #endif | 154 #endif |
| 153 | 155 |
| 154 // First check to see if we should just chain it as a large segment. | 156 // First check to see if we should just chain it as a large segment. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 return copy; | 200 return copy; |
| 199 } | 201 } |
| 200 | 202 |
| 201 | 203 |
| 202 #if defined(DEBUG) | 204 #if defined(DEBUG) |
| 203 void Zone::DumpZoneSizes() { | 205 void Zone::DumpZoneSizes() { |
| 204 intptr_t size = 0; | 206 intptr_t size = 0; |
| 205 for (Segment* s = large_segments_; s != NULL; s = s->next()) { | 207 for (Segment* s = large_segments_; s != NULL; s = s->next()) { |
| 206 size += s->size(); | 208 size += s->size(); |
| 207 } | 209 } |
| 208 OS::Print("Size in bytes allocated, Total = %"Pd" Large Segments = %"Pd"\n", | 210 OS::PrintErr("*** Zone(0x%"Px") size in bytes," |
| 209 SizeInBytes(), size); | 211 " Total = %"Pd" Large Segments = %"Pd"\n", |
| 212 reinterpret_cast<intptr_t>(this), SizeInBytes(), size); |
| 210 } | 213 } |
| 211 #endif | 214 #endif |
| 212 | 215 |
| 213 | 216 |
| 214 StackZone::StackZone(BaseIsolate* isolate) | 217 StackZone::StackZone(BaseIsolate* isolate) |
| 215 : StackResource(isolate), | 218 : StackResource(isolate), |
| 216 zone_() { | 219 zone_() { |
| 220 #ifdef DEBUG |
| 221 if (FLAG_trace_zones) { |
| 222 OS::PrintErr("*** Starting a new Stack zone 0x%"Px"(0x%"Px")\n", |
| 223 reinterpret_cast<intptr_t>(this), |
| 224 reinterpret_cast<intptr_t>(&zone_)); |
| 225 } |
| 226 #endif |
| 217 zone_.Link(isolate->current_zone()); | 227 zone_.Link(isolate->current_zone()); |
| 218 isolate->set_current_zone(&zone_); | 228 isolate->set_current_zone(&zone_); |
| 219 } | 229 } |
| 220 | 230 |
| 221 | 231 |
| 222 StackZone::~StackZone() { | 232 StackZone::~StackZone() { |
| 223 ASSERT(isolate()->current_zone() == &zone_); | 233 ASSERT(isolate()->current_zone() == &zone_); |
| 224 isolate()->set_current_zone(zone_.previous_); | 234 isolate()->set_current_zone(zone_.previous_); |
| 235 #ifdef DEBUG |
| 236 if (FLAG_trace_zones) { |
| 237 OS::PrintErr("*** Deleting Stack zone 0x%"Px"(0x%"Px")\n", |
| 238 reinterpret_cast<intptr_t>(this), |
| 239 reinterpret_cast<intptr_t>(&zone_)); |
| 240 } |
| 241 #endif |
| 225 } | 242 } |
| 226 | 243 |
| 227 | 244 |
| 228 void Zone::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 245 void Zone::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 229 Zone* zone = this; | 246 Zone* zone = this; |
| 230 while (zone != NULL) { | 247 while (zone != NULL) { |
| 231 zone->handles()->VisitObjectPointers(visitor); | 248 zone->handles()->VisitObjectPointers(visitor); |
| 232 zone = zone->previous_; | 249 zone = zone->previous_; |
| 233 } | 250 } |
| 234 } | 251 } |
| 235 | 252 |
| 236 | 253 |
| 237 char* Zone::PrintToString(const char* format, ...) { | 254 char* Zone::PrintToString(const char* format, ...) { |
| 238 va_list args; | 255 va_list args; |
| 239 va_start(args, format); | 256 va_start(args, format); |
| 240 intptr_t len = OS::VSNPrint(NULL, 0, format, args); | 257 intptr_t len = OS::VSNPrint(NULL, 0, format, args); |
| 241 va_end(args); | 258 va_end(args); |
| 242 | 259 |
| 243 char* buffer = Alloc<char>(len + 1); | 260 char* buffer = Alloc<char>(len + 1); |
| 244 va_list args2; | 261 va_list args2; |
| 245 va_start(args2, format); | 262 va_start(args2, format); |
| 246 OS::VSNPrint(buffer, (len + 1), format, args2); | 263 OS::VSNPrint(buffer, (len + 1), format, args2); |
| 247 va_end(args2); | 264 va_end(args2); |
| 248 | 265 |
| 249 return buffer; | 266 return buffer; |
| 250 } | 267 } |
| 251 | 268 |
| 252 | 269 |
| 253 } // namespace dart | 270 } // namespace dart |
| OLD | NEW |