| 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 |