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 |