Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: runtime/vm/zone.h

Issue 2762323002: Reimplemented zone memory tracking to avoid race conditions that were causing crashes in the previo… (Closed)
Patch Set: Reimplemented zone memory tracking to avoid race conditions that were causing crashes in the previo… Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #ifndef RUNTIME_VM_ZONE_H_ 5 #ifndef RUNTIME_VM_ZONE_H_
6 #define RUNTIME_VM_ZONE_H_ 6 #define RUNTIME_VM_ZONE_H_
7 7
8 #include "platform/utils.h" 8 #include "platform/utils.h"
9 #include "vm/allocation.h" 9 #include "vm/allocation.h"
10 #include "vm/handles.h" 10 #include "vm/handles.h"
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // TODO(zra): Remove these calls and replace them with calls to OS::SCreate 57 // TODO(zra): Remove these calls and replace them with calls to OS::SCreate
58 // and OS::VSCreate. 58 // and OS::VSCreate.
59 // These calls are deprecated. Do not add further calls to these functions. 59 // These calls are deprecated. Do not add further calls to these functions.
60 // instead use OS::SCreate and OS::VSCreate. 60 // instead use OS::SCreate and OS::VSCreate.
61 // Make a zone-allocated string based on printf format and args. 61 // Make a zone-allocated string based on printf format and args.
62 char* PrintToString(const char* format, ...) PRINTF_ATTRIBUTE(2, 3); 62 char* PrintToString(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
63 char* VPrint(const char* format, va_list args); 63 char* VPrint(const char* format, va_list args);
64 64
65 // Compute the total size of this zone. This includes wasted space that is 65 // Compute the total size of this zone. This includes wasted space that is
66 // due to internal fragmentation in the segments. 66 // due to internal fragmentation in the segments.
67 intptr_t SizeInBytes() const; 67 uintptr_t SizeInBytes() const;
68 68
69 // Computes the amount of space used in the zone. 69 // Computes the amount of space used in the zone.
70 intptr_t CapacityInBytes() const; 70 intptr_t CapacityInBytes() const;
71 71
72 // Computes the amount of space remaining in the zone.
73 intptr_t FreeCapacityInBytes() const;
74
72 // Structure for managing handles allocation. 75 // Structure for managing handles allocation.
73 VMHandles* handles() { return &handles_; } 76 VMHandles* handles() { return &handles_; }
74 77
75 void VisitObjectPointers(ObjectPointerVisitor* visitor); 78 void VisitObjectPointers(ObjectPointerVisitor* visitor);
76 79
77 Zone* previous() const { return previous_; } 80 Zone* previous() const { return previous_; }
78 81
79 #ifndef PRODUCT
80 void PrintJSON(JSONStream* stream) const;
81 #endif
82
83 private: 82 private:
84 Zone(); 83 Zone();
85 ~Zone(); // Delete all memory associated with the zone. 84 ~Zone(); // Delete all memory associated with the zone.
86 85
87 // All pointers returned from AllocateUnsafe() and New() have this alignment. 86 // All pointers returned from AllocateUnsafe() and New() have this alignment.
88 static const intptr_t kAlignment = kDoubleSize; 87 static const intptr_t kAlignment = kDoubleSize;
89 88
90 // Default initial chunk size. 89 // Default initial chunk size.
91 static const intptr_t kInitialChunkSize = 1 * KB; 90 static const intptr_t kInitialChunkSize = 1 * KB;
92 91
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
173 class StackZone : public StackResource { 172 class StackZone : public StackResource {
174 public: 173 public:
175 // Create an empty zone and set is at the current zone for the Thread. 174 // Create an empty zone and set is at the current zone for the Thread.
176 explicit StackZone(Thread* thread); 175 explicit StackZone(Thread* thread);
177 176
178 // Delete all memory associated with the zone. 177 // Delete all memory associated with the zone.
179 ~StackZone(); 178 ~StackZone();
180 179
181 // Compute the total size of this zone. This includes wasted space that is 180 // Compute the total size of this zone. This includes wasted space that is
182 // due to internal fragmentation in the segments. 181 // due to internal fragmentation in the segments.
183 intptr_t SizeInBytes() const { return zone_.SizeInBytes(); } 182 uintptr_t SizeInBytes() const { return zone_.SizeInBytes(); }
184 183
185 // Computes the used space in the zone. 184 // Computes the used space in the zone.
186 intptr_t CapacityInBytes() const { return zone_.CapacityInBytes(); } 185 intptr_t CapacityInBytes() const { return zone_.CapacityInBytes(); }
187 186
188 Zone* GetZone() { return &zone_; } 187 Zone* GetZone() { return &zone_; }
189 188
190 private: 189 private:
191 Zone zone_; 190 Zone zone_;
192 191
193 template <typename T> 192 template <typename T>
194 friend class GrowableArray; 193 friend class GrowableArray;
195 template <typename T> 194 template <typename T>
196 friend class ZoneGrowableArray; 195 friend class ZoneGrowableArray;
197 196
198 DISALLOW_IMPLICIT_CONSTRUCTORS(StackZone); 197 DISALLOW_IMPLICIT_CONSTRUCTORS(StackZone);
199 }; 198 };
200 199
201 inline uword Zone::AllocUnsafe(intptr_t size) { 200 inline uword Zone::AllocUnsafe(intptr_t size) {
202 ASSERT(size >= 0); 201 ASSERT(size >= 0);
203
204 // Round up the requested size to fit the alignment. 202 // Round up the requested size to fit the alignment.
205 if (size > (kIntptrMax - kAlignment)) { 203 if (size > (kIntptrMax - kAlignment)) {
206 FATAL1("Zone::Alloc: 'size' is too large: size=%" Pd "", size); 204 FATAL1("Zone::Alloc: 'size' is too large: size=%" Pd "", size);
207 } 205 }
208 size = Utils::RoundUp(size, kAlignment); 206 size = Utils::RoundUp(size, kAlignment);
209 207
210 // Check if the requested size is available without expanding. 208 // Check if the requested size is available without expanding.
211 uword result; 209 uword result;
212 intptr_t free_size = (limit_ - position_); 210 intptr_t free_size = (limit_ - position_);
213 if (free_size >= size) { 211 if (free_size >= size) {
214 result = position_; 212 result = position_;
215 position_ += size; 213 position_ += size;
214 Thread* current_thread = Thread::Current();
siva 2017/03/22 17:50:55 This is an overhead on every zone allocation path,
bkonyi 2017/03/22 18:01:48 No, I haven't run a performance test yet. Now that
215 if (current_thread != NULL) {
Cutch 2017/03/22 17:21:49 Refactor this code so there are two helper functio
bkonyi 2017/03/22 18:01:48 Done.
216 current_thread->IncrementMemoryUsage(size);
217 }
216 } else { 218 } else {
217 result = AllocateExpand(size); 219 result = AllocateExpand(size);
218 } 220 }
219 221
220 // Check that the result has the proper alignment and return it. 222 // Check that the result has the proper alignment and return it.
221 ASSERT(Utils::IsAligned(result, kAlignment)); 223 ASSERT(Utils::IsAligned(result, kAlignment));
222 return result; 224 return result;
223 } 225 }
224 226
225 227
(...skipping 11 matching lines...) Expand all
237 inline ElementType* Zone::Alloc(intptr_t len) { 239 inline ElementType* Zone::Alloc(intptr_t len) {
238 CheckLength<ElementType>(len); 240 CheckLength<ElementType>(len);
239 return reinterpret_cast<ElementType*>(AllocUnsafe(len * sizeof(ElementType))); 241 return reinterpret_cast<ElementType*>(AllocUnsafe(len * sizeof(ElementType)));
240 } 242 }
241 243
242 template <class ElementType> 244 template <class ElementType>
243 inline ElementType* Zone::Realloc(ElementType* old_data, 245 inline ElementType* Zone::Realloc(ElementType* old_data,
244 intptr_t old_len, 246 intptr_t old_len,
245 intptr_t new_len) { 247 intptr_t new_len) {
246 CheckLength<ElementType>(new_len); 248 CheckLength<ElementType>(new_len);
249 Thread* current_thread = Thread::Current();
Cutch 2017/03/22 17:21:50 move this Thread::Current() call so it only happen
bkonyi 2017/03/22 18:01:48 Done.
247 const intptr_t kElementSize = sizeof(ElementType); 250 const intptr_t kElementSize = sizeof(ElementType);
248 uword old_end = reinterpret_cast<uword>(old_data) + (old_len * kElementSize); 251 uword old_end = reinterpret_cast<uword>(old_data) + (old_len * kElementSize);
249 // Resize existing allocation if nothing was allocated in between... 252 // Resize existing allocation if nothing was allocated in between...
250 if (Utils::RoundUp(old_end, kAlignment) == position_) { 253 if (Utils::RoundUp(old_end, kAlignment) == position_) {
251 uword new_end = 254 uword new_end =
252 reinterpret_cast<uword>(old_data) + (new_len * kElementSize); 255 reinterpret_cast<uword>(old_data) + (new_len * kElementSize);
253 // ...and there is sufficient space. 256 // ...and there is sufficient space.
254 if (new_end <= limit_) { 257 if (new_end <= limit_) {
258 ASSERT(new_len >= old_len);
259 uword previous = position_;
255 position_ = Utils::RoundUp(new_end, kAlignment); 260 position_ = Utils::RoundUp(new_end, kAlignment);
261 if (current_thread != NULL && previous != position_) {
Cutch 2017/03/22 17:21:50 Wrap each of these != expressions in parens.
bkonyi 2017/03/22 18:01:48 Acknowledged.
262 current_thread->IncrementMemoryUsage((new_len - old_len) *
263 kElementSize);
264 }
256 return old_data; 265 return old_data;
257 } 266 }
258 } 267 }
259 if (new_len <= old_len) { 268 if (new_len <= old_len) {
260 return old_data; 269 return old_data;
261 } 270 }
262 ElementType* new_data = Alloc<ElementType>(new_len); 271 ElementType* new_data = Alloc<ElementType>(new_len);
263 if (old_data != 0) { 272 if (old_data != 0) {
264 memmove(reinterpret_cast<void*>(new_data), 273 memmove(reinterpret_cast<void*>(new_data),
265 reinterpret_cast<void*>(old_data), old_len * kElementSize); 274 reinterpret_cast<void*>(old_data), old_len * kElementSize);
266 } 275 }
267 return new_data; 276 return new_data;
268 } 277 }
269 278
270 } // namespace dart 279 } // namespace dart
271 280
272 #endif // RUNTIME_VM_ZONE_H_ 281 #endif // RUNTIME_VM_ZONE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698