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/handles_impl.h" | 10 #include "vm/handles_impl.h" |
11 #include "vm/heap.h" | 11 #include "vm/heap.h" |
12 #include "vm/os.h" | 12 #include "vm/os.h" |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 DEFINE_DEBUG_FLAG(bool, trace_zones, | |
17 false, "Traces allocation sizes in the zone."); | |
18 | |
19 | |
20 // Zone segments represent chunks of memory: They have starting | 16 // Zone segments represent chunks of memory: They have starting |
21 // address encoded in the this pointer and a size in bytes. They are | 17 // address encoded in the this pointer and a size in bytes. They are |
22 // chained together to form the backing storage for an expanding zone. | 18 // chained together to form the backing storage for an expanding zone. |
23 class Zone::Segment { | 19 class Zone::Segment { |
24 public: | 20 public: |
25 Segment* next() const { return next_; } | 21 Segment* next() const { return next_; } |
26 intptr_t size() const { return size_; } | 22 intptr_t size() const { return size_; } |
27 | 23 |
28 uword start() { return address(sizeof(Segment)); } | 24 uword start() { return address(sizeof(Segment)); } |
29 uword end() { return address(size_); } | 25 uword end() { return address(size_); } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 } | 104 } |
109 size += initial_buffer_.size(); | 105 size += initial_buffer_.size(); |
110 for (Segment* s = head_->next(); s != NULL; s = s->next()) { | 106 for (Segment* s = head_->next(); s != NULL; s = s->next()) { |
111 size += s->size(); | 107 size += s->size(); |
112 } | 108 } |
113 return size + (position_ - head_->start()); | 109 return size + (position_ - head_->start()); |
114 } | 110 } |
115 | 111 |
116 | 112 |
117 uword Zone::AllocateExpand(intptr_t size) { | 113 uword Zone::AllocateExpand(intptr_t size) { |
118 #if defined(DEBUG) | |
119 ASSERT(size >= 0); | 114 ASSERT(size >= 0); |
120 if (FLAG_trace_zones) { | 115 if (FLAG_trace_zones) { |
121 OS::PrintErr("*** Expanding zone 0x%" Px "\n", | 116 OS::PrintErr("*** Expanding zone 0x%" Px "\n", |
122 reinterpret_cast<intptr_t>(this)); | 117 reinterpret_cast<intptr_t>(this)); |
123 DumpZoneSizes(); | 118 DumpZoneSizes(); |
124 } | 119 } |
125 // Make sure the requested size is already properly aligned and that | 120 // Make sure the requested size is already properly aligned and that |
126 // there isn't enough room in the Zone to satisfy the request. | 121 // there isn't enough room in the Zone to satisfy the request. |
127 ASSERT(Utils::IsAligned(size, kAlignment)); | 122 ASSERT(Utils::IsAligned(size, kAlignment)); |
128 intptr_t free_size = (limit_ - position_); | 123 intptr_t free_size = (limit_ - position_); |
129 ASSERT(free_size < size); | 124 ASSERT(free_size < size); |
130 #endif | |
131 | 125 |
132 // First check to see if we should just chain it as a large segment. | 126 // First check to see if we should just chain it as a large segment. |
133 intptr_t max_size = Utils::RoundDown(kSegmentSize - sizeof(Segment), | 127 intptr_t max_size = Utils::RoundDown(kSegmentSize - sizeof(Segment), |
134 kAlignment); | 128 kAlignment); |
135 ASSERT(max_size > 0); | 129 ASSERT(max_size > 0); |
136 if (size > max_size) { | 130 if (size > max_size) { |
137 return AllocateLargeSegment(size); | 131 return AllocateLargeSegment(size); |
138 } | 132 } |
139 | 133 |
140 // Allocate another segment and chain it up. | 134 // Allocate another segment and chain it up. |
141 head_ = Segment::New(kSegmentSize, head_); | 135 head_ = Segment::New(kSegmentSize, head_); |
142 | 136 |
143 // Recompute 'position' and 'limit' based on the new head segment. | 137 // Recompute 'position' and 'limit' based on the new head segment. |
144 uword result = Utils::RoundUp(head_->start(), kAlignment); | 138 uword result = Utils::RoundUp(head_->start(), kAlignment); |
145 position_ = result + size; | 139 position_ = result + size; |
146 limit_ = head_->end(); | 140 limit_ = head_->end(); |
147 ASSERT(position_ <= limit_); | 141 ASSERT(position_ <= limit_); |
148 return result; | 142 return result; |
149 } | 143 } |
150 | 144 |
151 | 145 |
152 uword Zone::AllocateLargeSegment(intptr_t size) { | 146 uword Zone::AllocateLargeSegment(intptr_t size) { |
153 #if defined(DEBUG) | |
154 ASSERT(size >= 0); | 147 ASSERT(size >= 0); |
155 // Make sure the requested size is already properly aligned and that | 148 // Make sure the requested size is already properly aligned and that |
156 // there isn't enough room in the Zone to satisfy the request. | 149 // there isn't enough room in the Zone to satisfy the request. |
157 ASSERT(Utils::IsAligned(size, kAlignment)); | 150 ASSERT(Utils::IsAligned(size, kAlignment)); |
158 intptr_t free_size = (limit_ - position_); | 151 intptr_t free_size = (limit_ - position_); |
159 ASSERT(free_size < size); | 152 ASSERT(free_size < size); |
160 #endif | |
161 | 153 |
162 // Create a new large segment and chain it up. | 154 // Create a new large segment and chain it up. |
163 ASSERT(Utils::IsAligned(sizeof(Segment), kAlignment)); | 155 ASSERT(Utils::IsAligned(sizeof(Segment), kAlignment)); |
164 size += sizeof(Segment); // Account for book keeping fields in size. | 156 size += sizeof(Segment); // Account for book keeping fields in size. |
165 large_segments_ = Segment::New(size, large_segments_); | 157 large_segments_ = Segment::New(size, large_segments_); |
166 | 158 |
167 uword result = Utils::RoundUp(large_segments_->start(), kAlignment); | 159 uword result = Utils::RoundUp(large_segments_->start(), kAlignment); |
168 return result; | 160 return result; |
169 } | 161 } |
170 | 162 |
(...skipping 14 matching lines...) Expand all Loading... |
185 if (a_len > 0) { | 177 if (a_len > 0) { |
186 strncpy(copy, a, a_len); | 178 strncpy(copy, a, a_len); |
187 // Insert join character. | 179 // Insert join character. |
188 copy[a_len++] = join; | 180 copy[a_len++] = join; |
189 } | 181 } |
190 strncpy(©[a_len], b, b_len); | 182 strncpy(©[a_len], b, b_len); |
191 return copy; | 183 return copy; |
192 } | 184 } |
193 | 185 |
194 | 186 |
195 #if defined(DEBUG) | |
196 void Zone::DumpZoneSizes() { | 187 void Zone::DumpZoneSizes() { |
197 intptr_t size = 0; | 188 intptr_t size = 0; |
198 for (Segment* s = large_segments_; s != NULL; s = s->next()) { | 189 for (Segment* s = large_segments_; s != NULL; s = s->next()) { |
199 size += s->size(); | 190 size += s->size(); |
200 } | 191 } |
201 OS::PrintErr("*** Zone(0x%" Px ") size in bytes," | 192 OS::PrintErr("*** Zone(0x%" Px ") size in bytes," |
202 " Total = %" Pd " Large Segments = %" Pd "\n", | 193 " Total = %" Pd " Large Segments = %" Pd "\n", |
203 reinterpret_cast<intptr_t>(this), SizeInBytes(), size); | 194 reinterpret_cast<intptr_t>(this), SizeInBytes(), size); |
204 } | 195 } |
205 #endif | |
206 | 196 |
207 | 197 |
208 void Zone::VisitObjectPointers(ObjectPointerVisitor* visitor) { | 198 void Zone::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
209 Zone* zone = this; | 199 Zone* zone = this; |
210 while (zone != NULL) { | 200 while (zone != NULL) { |
211 zone->handles()->VisitObjectPointers(visitor); | 201 zone->handles()->VisitObjectPointers(visitor); |
212 zone = zone->previous_; | 202 zone = zone->previous_; |
213 } | 203 } |
214 } | 204 } |
215 | 205 |
216 | 206 |
217 char* Zone::PrintToString(const char* format, ...) { | 207 char* Zone::PrintToString(const char* format, ...) { |
218 va_list args; | 208 va_list args; |
219 va_start(args, format); | 209 va_start(args, format); |
220 char* buffer = OS::VSCreate(this, format, args); | 210 char* buffer = OS::VSCreate(this, format, args); |
221 va_end(args); | 211 va_end(args); |
222 return buffer; | 212 return buffer; |
223 } | 213 } |
224 | 214 |
225 | 215 |
226 char* Zone::VPrint(const char* format, va_list args) { | 216 char* Zone::VPrint(const char* format, va_list args) { |
227 return OS::VSCreate(this, format, args); | 217 return OS::VSCreate(this, format, args); |
228 } | 218 } |
229 | 219 |
230 | 220 |
231 } // namespace dart | 221 } // namespace dart |
OLD | NEW |