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 #ifndef RUNTIME_VM_DART_API_STATE_H_ | 5 #ifndef RUNTIME_VM_DART_API_STATE_H_ |
6 #define RUNTIME_VM_DART_API_STATE_H_ | 6 #define RUNTIME_VM_DART_API_STATE_H_ |
7 | 7 |
8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
9 | 9 |
10 #include "platform/utils.h" | 10 #include "platform/utils.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 | 25 |
26 namespace dart { | 26 namespace dart { |
27 | 27 |
28 class FinalizablePersistentHandle; | 28 class FinalizablePersistentHandle; |
29 typedef MallocGrowableArray<FinalizablePersistentHandle*> FinalizationQueue; | 29 typedef MallocGrowableArray<FinalizablePersistentHandle*> FinalizationQueue; |
30 | 30 |
31 | 31 |
32 class BackgroundFinalizer : public ThreadPool::Task { | 32 class BackgroundFinalizer : public ThreadPool::Task { |
33 public: | 33 public: |
34 BackgroundFinalizer(Isolate* isolate, FinalizationQueue* queue); | 34 BackgroundFinalizer(Isolate* isolate, FinalizationQueue* queue); |
35 virtual ~BackgroundFinalizer() { } | 35 virtual ~BackgroundFinalizer() {} |
36 | 36 |
37 void Run(); | 37 void Run(); |
38 | 38 |
39 private: | 39 private: |
40 Isolate* isolate_; | 40 Isolate* isolate_; |
41 FinalizationQueue* queue_; | 41 FinalizationQueue* queue_; |
42 | 42 |
43 DISALLOW_IMPLICIT_CONSTRUCTORS(BackgroundFinalizer); | 43 DISALLOW_IMPLICIT_CONSTRUCTORS(BackgroundFinalizer); |
44 }; | 44 }; |
45 | 45 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 OS::PrintErr("*** Deleting Api zone 0x%" Px "(0x%" Px ")\n", | 81 OS::PrintErr("*** Deleting Api zone 0x%" Px "(0x%" Px ")\n", |
82 reinterpret_cast<intptr_t>(this), | 82 reinterpret_cast<intptr_t>(this), |
83 reinterpret_cast<intptr_t>(&zone_)); | 83 reinterpret_cast<intptr_t>(&zone_)); |
84 } | 84 } |
85 } | 85 } |
86 | 86 |
87 // Allocates an array sized to hold 'len' elements of type | 87 // Allocates an array sized to hold 'len' elements of type |
88 // 'ElementType'. Checks for integer overflow when performing the | 88 // 'ElementType'. Checks for integer overflow when performing the |
89 // size computation. | 89 // size computation. |
90 template <class ElementType> | 90 template <class ElementType> |
91 ElementType* Alloc(intptr_t len) { return zone_.Alloc<ElementType>(len); } | 91 ElementType* Alloc(intptr_t len) { |
| 92 return zone_.Alloc<ElementType>(len); |
| 93 } |
92 | 94 |
93 // Allocates an array sized to hold 'len' elements of type | 95 // Allocates an array sized to hold 'len' elements of type |
94 // 'ElementType'. The new array is initialized from the memory of | 96 // 'ElementType'. The new array is initialized from the memory of |
95 // 'old_array' up to 'old_len'. | 97 // 'old_array' up to 'old_len'. |
96 template <class ElementType> | 98 template <class ElementType> |
97 ElementType* Realloc(ElementType* old_array, | 99 ElementType* Realloc(ElementType* old_array, |
98 intptr_t old_len, | 100 intptr_t old_len, |
99 intptr_t new_len) { | 101 intptr_t new_len) { |
100 return zone_.Realloc<ElementType>(old_array, old_len, new_len); | 102 return zone_.Realloc<ElementType>(old_array, old_len, new_len); |
101 } | 103 } |
(...skipping 24 matching lines...) Expand all Loading... |
126 void Reset(Thread* thread) { | 128 void Reset(Thread* thread) { |
127 if ((thread != NULL) && (thread->zone() == &zone_)) { | 129 if ((thread != NULL) && (thread->zone() == &zone_)) { |
128 thread->set_zone(zone_.previous_); | 130 thread->set_zone(zone_.previous_); |
129 } | 131 } |
130 zone_.DeleteAll(); | 132 zone_.DeleteAll(); |
131 } | 133 } |
132 | 134 |
133 private: | 135 private: |
134 Zone zone_; | 136 Zone zone_; |
135 | 137 |
136 template<typename T> friend class ApiGrowableArray; | 138 template <typename T> |
| 139 friend class ApiGrowableArray; |
137 DISALLOW_COPY_AND_ASSIGN(ApiZone); | 140 DISALLOW_COPY_AND_ASSIGN(ApiZone); |
138 }; | 141 }; |
139 | 142 |
140 | 143 |
141 // Implementation of local handles which are handed out from every | 144 // Implementation of local handles which are handed out from every |
142 // dart API call, these handles are valid only in the present scope | 145 // dart API call, these handles are valid only in the present scope |
143 // and are destroyed when a Dart_ExitScope() is called. | 146 // and are destroyed when a Dart_ExitScope() is called. |
144 class LocalHandle { | 147 class LocalHandle { |
145 public: | 148 public: |
146 // Accessors. | 149 // Accessors. |
147 RawObject* raw() const { return raw_; } | 150 RawObject* raw() const { return raw_; } |
148 void set_raw(RawObject* raw) { raw_ = raw; } | 151 void set_raw(RawObject* raw) { raw_ = raw; } |
149 static intptr_t raw_offset() { return OFFSET_OF(LocalHandle, raw_); } | 152 static intptr_t raw_offset() { return OFFSET_OF(LocalHandle, raw_); } |
150 | 153 |
151 Dart_Handle apiHandle() { | 154 Dart_Handle apiHandle() { return reinterpret_cast<Dart_Handle>(this); } |
152 return reinterpret_cast<Dart_Handle>(this); | |
153 } | |
154 | 155 |
155 private: | 156 private: |
156 LocalHandle() { } | 157 LocalHandle() {} |
157 ~LocalHandle() { } | 158 ~LocalHandle() {} |
158 | 159 |
159 RawObject* raw_; | 160 RawObject* raw_; |
160 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. | 161 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
161 DISALLOW_COPY_AND_ASSIGN(LocalHandle); | 162 DISALLOW_COPY_AND_ASSIGN(LocalHandle); |
162 }; | 163 }; |
163 | 164 |
164 | 165 |
165 // A distinguished callback which indicates that a persistent handle | 166 // A distinguished callback which indicates that a persistent handle |
166 // should not be deleted from the dart api. | 167 // should not be deleted from the dart api. |
167 void ProtectedHandleCallback(void* peer); | 168 void ProtectedHandleCallback(void* peer); |
(...skipping 13 matching lines...) Expand all Loading... |
181 return reinterpret_cast<Dart_PersistentHandle>(this); | 182 return reinterpret_cast<Dart_PersistentHandle>(this); |
182 } | 183 } |
183 | 184 |
184 static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); } | 185 static intptr_t raw_offset() { return OFFSET_OF(PersistentHandle, raw_); } |
185 | 186 |
186 static PersistentHandle* Cast(Dart_PersistentHandle handle); | 187 static PersistentHandle* Cast(Dart_PersistentHandle handle); |
187 | 188 |
188 private: | 189 private: |
189 friend class PersistentHandles; | 190 friend class PersistentHandles; |
190 | 191 |
191 PersistentHandle() { } | 192 PersistentHandle() {} |
192 ~PersistentHandle() { } | 193 ~PersistentHandle() {} |
193 | 194 |
194 // Overload the raw_ field as a next pointer when adding freed | 195 // Overload the raw_ field as a next pointer when adding freed |
195 // handles to the free list. | 196 // handles to the free list. |
196 PersistentHandle* Next() { | 197 PersistentHandle* Next() { return reinterpret_cast<PersistentHandle*>(raw_); } |
197 return reinterpret_cast<PersistentHandle*>(raw_); | |
198 } | |
199 void SetNext(PersistentHandle* free_list) { | 198 void SetNext(PersistentHandle* free_list) { |
200 raw_ = reinterpret_cast<RawObject*>(free_list); | 199 raw_ = reinterpret_cast<RawObject*>(free_list); |
201 ASSERT(!raw_->IsHeapObject()); | 200 ASSERT(!raw_->IsHeapObject()); |
202 } | 201 } |
203 void FreeHandle(PersistentHandle* free_list) { | 202 void FreeHandle(PersistentHandle* free_list) { SetNext(free_list); } |
204 SetNext(free_list); | |
205 } | |
206 | 203 |
207 RawObject* raw_; | 204 RawObject* raw_; |
208 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. | 205 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
209 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); | 206 DISALLOW_COPY_AND_ASSIGN(PersistentHandle); |
210 }; | 207 }; |
211 | 208 |
212 | 209 |
213 // Implementation of persistent handles which are handed out through the | 210 // Implementation of persistent handles which are handed out through the |
214 // dart API. | 211 // dart API. |
215 class FinalizablePersistentHandle { | 212 class FinalizablePersistentHandle { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 kExternalSizeBitsSize = (kBitsPerWord - 2), | 283 kExternalSizeBitsSize = (kBitsPerWord - 2), |
287 }; | 284 }; |
288 | 285 |
289 // This part of external_data_ is the number of externally allocated bytes. | 286 // This part of external_data_ is the number of externally allocated bytes. |
290 class ExternalSizeInWordsBits : public BitField<uword, | 287 class ExternalSizeInWordsBits : public BitField<uword, |
291 intptr_t, | 288 intptr_t, |
292 kExternalSizeBits, | 289 kExternalSizeBits, |
293 kExternalSizeBitsSize> {}; | 290 kExternalSizeBitsSize> {}; |
294 // This bit of external_data_ is true if the referent was created in new | 291 // This bit of external_data_ is true if the referent was created in new |
295 // space and UpdateRelocated has not yet detected any promotion. | 292 // space and UpdateRelocated has not yet detected any promotion. |
296 class ExternalNewSpaceBit : | 293 class ExternalNewSpaceBit |
297 public BitField<uword, bool, kExternalNewSpaceBit, 1> {}; | 294 : public BitField<uword, bool, kExternalNewSpaceBit, 1> {}; |
298 class QueuedForFinalizationBit : | 295 class QueuedForFinalizationBit |
299 public BitField<uword, bool, kQueuedForFinalizationBit, 1> {}; | 296 : public BitField<uword, bool, kQueuedForFinalizationBit, 1> {}; |
300 | 297 |
301 friend class FinalizablePersistentHandles; | 298 friend class FinalizablePersistentHandles; |
302 | 299 |
303 FinalizablePersistentHandle() | 300 FinalizablePersistentHandle() |
304 : raw_(NULL), | 301 : raw_(NULL), peer_(NULL), external_data_(0), callback_(NULL) {} |
305 peer_(NULL), | 302 ~FinalizablePersistentHandle() {} |
306 external_data_(0), | |
307 callback_(NULL) { } | |
308 ~FinalizablePersistentHandle() { } | |
309 | 303 |
310 static void Finalize(Isolate* isolate, FinalizablePersistentHandle* handle); | 304 static void Finalize(Isolate* isolate, FinalizablePersistentHandle* handle); |
311 | 305 |
312 // Overload the raw_ field as a next pointer when adding freed | 306 // Overload the raw_ field as a next pointer when adding freed |
313 // handles to the free list. | 307 // handles to the free list. |
314 FinalizablePersistentHandle* Next() { | 308 FinalizablePersistentHandle* Next() { |
315 return reinterpret_cast<FinalizablePersistentHandle*>(raw_); | 309 return reinterpret_cast<FinalizablePersistentHandle*>(raw_); |
316 } | 310 } |
317 void SetNext(FinalizablePersistentHandle* free_list) { | 311 void SetNext(FinalizablePersistentHandle* free_list) { |
318 raw_ = reinterpret_cast<RawObject*>(free_list); | 312 raw_ = reinterpret_cast<RawObject*>(free_list); |
(...skipping 22 matching lines...) Expand all Loading... |
341 | 335 |
342 void set_peer(void* peer) { peer_ = peer; } | 336 void set_peer(void* peer) { peer_ = peer; } |
343 | 337 |
344 void set_callback(Dart_WeakPersistentHandleFinalizer callback) { | 338 void set_callback(Dart_WeakPersistentHandleFinalizer callback) { |
345 callback_ = callback; | 339 callback_ = callback; |
346 } | 340 } |
347 | 341 |
348 void set_external_size(intptr_t size) { | 342 void set_external_size(intptr_t size) { |
349 intptr_t size_in_words = Utils::RoundUp(size, kObjectAlignment) / kWordSize; | 343 intptr_t size_in_words = Utils::RoundUp(size, kObjectAlignment) / kWordSize; |
350 ASSERT(ExternalSizeInWordsBits::is_valid(size_in_words)); | 344 ASSERT(ExternalSizeInWordsBits::is_valid(size_in_words)); |
351 external_data_ = ExternalSizeInWordsBits::update(size_in_words, | 345 external_data_ = |
352 external_data_); | 346 ExternalSizeInWordsBits::update(size_in_words, external_data_); |
353 } | 347 } |
354 | 348 |
355 bool is_queued_for_finalization() const { | 349 bool is_queued_for_finalization() const { |
356 return QueuedForFinalizationBit::decode(external_data_); | 350 return QueuedForFinalizationBit::decode(external_data_); |
357 } | 351 } |
358 void set_is_queued_for_finalization(bool value) { | 352 void set_is_queued_for_finalization(bool value) { |
359 external_data_ = QueuedForFinalizationBit::update(value, external_data_); | 353 external_data_ = QueuedForFinalizationBit::update(value, external_data_); |
360 } | 354 } |
361 | 355 |
362 bool IsSetNewSpaceBit() const { | 356 bool IsSetNewSpaceBit() const { |
363 return ExternalNewSpaceBit::decode(external_data_); | 357 return ExternalNewSpaceBit::decode(external_data_); |
364 } | 358 } |
365 | 359 |
366 void SetExternalNewSpaceBit() { | 360 void SetExternalNewSpaceBit() { |
367 external_data_ = ExternalNewSpaceBit::update(true, external_data_); | 361 external_data_ = ExternalNewSpaceBit::update(true, external_data_); |
368 } | 362 } |
369 | 363 |
370 void ClearExternalNewSpaceBit() { | 364 void ClearExternalNewSpaceBit() { |
371 external_data_ = ExternalNewSpaceBit::update(false, external_data_); | 365 external_data_ = ExternalNewSpaceBit::update(false, external_data_); |
372 } | 366 } |
373 | 367 |
374 // Returns the space to charge for the external size. | 368 // Returns the space to charge for the external size. |
375 Heap::Space SpaceForExternal() const { | 369 Heap::Space SpaceForExternal() const { |
376 // Non-heap and VM-heap objects count as old space here. | 370 // Non-heap and VM-heap objects count as old space here. |
377 return (raw_->IsHeapObject() && raw_->IsNewObject()) ? | 371 return (raw_->IsHeapObject() && raw_->IsNewObject()) ? Heap::kNew |
378 Heap::kNew : Heap::kOld; | 372 : Heap::kOld; |
379 } | 373 } |
380 | 374 |
381 friend class BackgroundFinalizer; | 375 friend class BackgroundFinalizer; |
382 | 376 |
383 RawObject* raw_; | 377 RawObject* raw_; |
384 void* peer_; | 378 void* peer_; |
385 uword external_data_; | 379 uword external_data_; |
386 Dart_WeakPersistentHandleFinalizer callback_; | 380 Dart_WeakPersistentHandleFinalizer callback_; |
387 | 381 |
388 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. | 382 DISALLOW_ALLOCATION(); // Allocated through AllocateHandle methods. |
389 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle); | 383 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandle); |
390 }; | 384 }; |
391 | 385 |
392 | 386 |
393 // Local handles repository structure. | 387 // Local handles repository structure. |
394 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; | 388 static const int kLocalHandleSizeInWords = sizeof(LocalHandle) / kWordSize; |
395 static const int kLocalHandlesPerChunk = 64; | 389 static const int kLocalHandlesPerChunk = 64; |
396 static const int kOffsetOfRawPtrInLocalHandle = 0; | 390 static const int kOffsetOfRawPtrInLocalHandle = 0; |
397 class LocalHandles : Handles<kLocalHandleSizeInWords, | 391 class LocalHandles : Handles<kLocalHandleSizeInWords, |
398 kLocalHandlesPerChunk, | 392 kLocalHandlesPerChunk, |
399 kOffsetOfRawPtrInLocalHandle> { | 393 kOffsetOfRawPtrInLocalHandle> { |
400 public: | 394 public: |
401 LocalHandles() : Handles<kLocalHandleSizeInWords, | 395 LocalHandles() |
402 kLocalHandlesPerChunk, | 396 : Handles<kLocalHandleSizeInWords, |
403 kOffsetOfRawPtrInLocalHandle>() { | 397 kLocalHandlesPerChunk, |
| 398 kOffsetOfRawPtrInLocalHandle>() { |
404 if (FLAG_trace_handles) { | 399 if (FLAG_trace_handles) { |
405 OS::PrintErr("*** Starting a new Local handle block 0x%" Px "\n", | 400 OS::PrintErr("*** Starting a new Local handle block 0x%" Px "\n", |
406 reinterpret_cast<intptr_t>(this)); | 401 reinterpret_cast<intptr_t>(this)); |
407 } | 402 } |
408 } | 403 } |
409 ~LocalHandles() { | 404 ~LocalHandles() { |
410 if (FLAG_trace_handles) { | 405 if (FLAG_trace_handles) { |
411 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n", | 406 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n", |
412 reinterpret_cast<intptr_t>(this), | 407 reinterpret_cast<intptr_t>(this), CountHandles()); |
413 CountHandles()); | |
414 OS::PrintErr("*** Deleting Local handle block 0x%" Px "\n", | 408 OS::PrintErr("*** Deleting Local handle block 0x%" Px "\n", |
415 reinterpret_cast<intptr_t>(this)); | 409 reinterpret_cast<intptr_t>(this)); |
416 } | 410 } |
417 } | 411 } |
418 | 412 |
419 | 413 |
420 // Visit all object pointers stored in the various handles. | 414 // Visit all object pointers stored in the various handles. |
421 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 415 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
422 Handles<kLocalHandleSizeInWords, | 416 Handles<kLocalHandleSizeInWords, kLocalHandlesPerChunk, |
423 kLocalHandlesPerChunk, | |
424 kOffsetOfRawPtrInLocalHandle>::VisitObjectPointers(visitor); | 417 kOffsetOfRawPtrInLocalHandle>::VisitObjectPointers(visitor); |
425 } | 418 } |
426 | 419 |
427 // Reset the local handles block for reuse. | 420 // Reset the local handles block for reuse. |
428 void Reset() { | 421 void Reset() { |
429 Handles<kLocalHandleSizeInWords, | 422 Handles<kLocalHandleSizeInWords, kLocalHandlesPerChunk, |
430 kLocalHandlesPerChunk, | |
431 kOffsetOfRawPtrInLocalHandle>::Reset(); | 423 kOffsetOfRawPtrInLocalHandle>::Reset(); |
432 } | 424 } |
433 | 425 |
434 // Allocates a handle in the current handle scope. This handle is valid only | 426 // Allocates a handle in the current handle scope. This handle is valid only |
435 // in the current handle scope and is destroyed when the current handle | 427 // in the current handle scope and is destroyed when the current handle |
436 // scope ends. | 428 // scope ends. |
437 LocalHandle* AllocateHandle() { | 429 LocalHandle* AllocateHandle() { |
438 return reinterpret_cast<LocalHandle*>(AllocateScopedHandle()); | 430 return reinterpret_cast<LocalHandle*>(AllocateScopedHandle()); |
439 } | 431 } |
440 | 432 |
441 // Validate if passed in handle is a Local Handle. | 433 // Validate if passed in handle is a Local Handle. |
442 bool IsValidHandle(Dart_Handle object) const { | 434 bool IsValidHandle(Dart_Handle object) const { |
443 return IsValidScopedHandle(reinterpret_cast<uword>(object)); | 435 return IsValidScopedHandle(reinterpret_cast<uword>(object)); |
444 } | 436 } |
445 | 437 |
446 // Returns a count of active handles (used for testing purposes). | 438 // Returns a count of active handles (used for testing purposes). |
447 int CountHandles() const { | 439 int CountHandles() const { return CountScopedHandles(); } |
448 return CountScopedHandles(); | |
449 } | |
450 | 440 |
451 private: | 441 private: |
452 DISALLOW_COPY_AND_ASSIGN(LocalHandles); | 442 DISALLOW_COPY_AND_ASSIGN(LocalHandles); |
453 }; | 443 }; |
454 | 444 |
455 | 445 |
456 // Persistent handles repository structure. | 446 // Persistent handles repository structure. |
457 static const int kPersistentHandleSizeInWords = | 447 static const int kPersistentHandleSizeInWords = |
458 sizeof(PersistentHandle) / kWordSize; | 448 sizeof(PersistentHandle) / kWordSize; |
459 static const int kPersistentHandlesPerChunk = 64; | 449 static const int kPersistentHandlesPerChunk = 64; |
460 static const int kOffsetOfRawPtrInPersistentHandle = 0; | 450 static const int kOffsetOfRawPtrInPersistentHandle = 0; |
461 class PersistentHandles : Handles<kPersistentHandleSizeInWords, | 451 class PersistentHandles : Handles<kPersistentHandleSizeInWords, |
462 kPersistentHandlesPerChunk, | 452 kPersistentHandlesPerChunk, |
463 kOffsetOfRawPtrInPersistentHandle> { | 453 kOffsetOfRawPtrInPersistentHandle> { |
464 public: | 454 public: |
465 PersistentHandles() : Handles<kPersistentHandleSizeInWords, | 455 PersistentHandles() |
466 kPersistentHandlesPerChunk, | 456 : Handles<kPersistentHandleSizeInWords, |
467 kOffsetOfRawPtrInPersistentHandle>(), | 457 kPersistentHandlesPerChunk, |
| 458 kOffsetOfRawPtrInPersistentHandle>(), |
468 free_list_(NULL) { | 459 free_list_(NULL) { |
469 if (FLAG_trace_handles) { | 460 if (FLAG_trace_handles) { |
470 OS::PrintErr("*** Starting a new Persistent handle block 0x%" Px "\n", | 461 OS::PrintErr("*** Starting a new Persistent handle block 0x%" Px "\n", |
471 reinterpret_cast<intptr_t>(this)); | 462 reinterpret_cast<intptr_t>(this)); |
472 } | 463 } |
473 } | 464 } |
474 ~PersistentHandles() { | 465 ~PersistentHandles() { |
475 free_list_ = NULL; | 466 free_list_ = NULL; |
476 if (FLAG_trace_handles) { | 467 if (FLAG_trace_handles) { |
477 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n", | 468 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Scoped = %d\n", |
478 reinterpret_cast<intptr_t>(this), | 469 reinterpret_cast<intptr_t>(this), CountHandles()); |
479 CountHandles()); | |
480 OS::PrintErr("*** Deleting Persistent handle block 0x%" Px "\n", | 470 OS::PrintErr("*** Deleting Persistent handle block 0x%" Px "\n", |
481 reinterpret_cast<intptr_t>(this)); | 471 reinterpret_cast<intptr_t>(this)); |
482 } | 472 } |
483 } | 473 } |
484 | 474 |
485 // Accessors. | 475 // Accessors. |
486 PersistentHandle* free_list() const { return free_list_; } | 476 PersistentHandle* free_list() const { return free_list_; } |
487 void set_free_list(PersistentHandle* value) { free_list_ = value; } | 477 void set_free_list(PersistentHandle* value) { free_list_ = value; } |
488 | 478 |
489 // Visit all object pointers stored in the various handles. | 479 // Visit all object pointers stored in the various handles. |
490 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 480 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
491 Handles<kPersistentHandleSizeInWords, | 481 Handles<kPersistentHandleSizeInWords, kPersistentHandlesPerChunk, |
492 kPersistentHandlesPerChunk, | |
493 kOffsetOfRawPtrInPersistentHandle>::VisitObjectPointers(visitor); | 482 kOffsetOfRawPtrInPersistentHandle>::VisitObjectPointers(visitor); |
494 } | 483 } |
495 | 484 |
496 // Visit all the handles. | 485 // Visit all the handles. |
497 void Visit(HandleVisitor* visitor) { | 486 void Visit(HandleVisitor* visitor) { |
498 Handles<kPersistentHandleSizeInWords, | 487 Handles<kPersistentHandleSizeInWords, kPersistentHandlesPerChunk, |
499 kPersistentHandlesPerChunk, | |
500 kOffsetOfRawPtrInPersistentHandle>::Visit(visitor); | 488 kOffsetOfRawPtrInPersistentHandle>::Visit(visitor); |
501 } | 489 } |
502 | 490 |
503 // Allocates a persistent handle, these have to be destroyed explicitly | 491 // Allocates a persistent handle, these have to be destroyed explicitly |
504 // by calling FreeHandle. | 492 // by calling FreeHandle. |
505 PersistentHandle* AllocateHandle() { | 493 PersistentHandle* AllocateHandle() { |
506 PersistentHandle* handle; | 494 PersistentHandle* handle; |
507 if (free_list_ != NULL) { | 495 if (free_list_ != NULL) { |
508 handle = free_list_; | 496 handle = free_list_; |
509 free_list_ = handle->Next(); | 497 free_list_ = handle->Next(); |
510 } else { | 498 } else { |
511 handle = reinterpret_cast<PersistentHandle*>(AllocateScopedHandle()); | 499 handle = reinterpret_cast<PersistentHandle*>(AllocateScopedHandle()); |
512 } | 500 } |
513 handle->set_raw(Object::null()); | 501 handle->set_raw(Object::null()); |
514 return handle; | 502 return handle; |
515 } | 503 } |
516 | 504 |
517 void FreeHandle(PersistentHandle* handle) { | 505 void FreeHandle(PersistentHandle* handle) { |
518 handle->FreeHandle(free_list()); | 506 handle->FreeHandle(free_list()); |
519 set_free_list(handle); | 507 set_free_list(handle); |
520 } | 508 } |
521 | 509 |
522 // Validate if passed in handle is a Persistent Handle. | 510 // Validate if passed in handle is a Persistent Handle. |
523 bool IsValidHandle(Dart_PersistentHandle object) const { | 511 bool IsValidHandle(Dart_PersistentHandle object) const { |
524 return IsValidScopedHandle(reinterpret_cast<uword>(object)); | 512 return IsValidScopedHandle(reinterpret_cast<uword>(object)); |
525 } | 513 } |
526 | 514 |
527 // Returns a count of active handles (used for testing purposes). | 515 // Returns a count of active handles (used for testing purposes). |
528 int CountHandles() const { | 516 int CountHandles() const { return CountScopedHandles(); } |
529 return CountScopedHandles(); | |
530 } | |
531 | 517 |
532 private: | 518 private: |
533 PersistentHandle* free_list_; | 519 PersistentHandle* free_list_; |
534 DISALLOW_COPY_AND_ASSIGN(PersistentHandles); | 520 DISALLOW_COPY_AND_ASSIGN(PersistentHandles); |
535 }; | 521 }; |
536 | 522 |
537 | 523 |
538 // Finalizable persistent handles repository structure. | 524 // Finalizable persistent handles repository structure. |
539 static const int kFinalizablePersistentHandleSizeInWords = | 525 static const int kFinalizablePersistentHandleSizeInWords = |
540 sizeof(FinalizablePersistentHandle) / kWordSize; | 526 sizeof(FinalizablePersistentHandle) / kWordSize; |
541 static const int kFinalizablePersistentHandlesPerChunk = 64; | 527 static const int kFinalizablePersistentHandlesPerChunk = 64; |
542 static const int kOffsetOfRawPtrInFinalizablePersistentHandle = 0; | 528 static const int kOffsetOfRawPtrInFinalizablePersistentHandle = 0; |
543 class FinalizablePersistentHandles | 529 class FinalizablePersistentHandles |
544 : Handles<kFinalizablePersistentHandleSizeInWords, | 530 : Handles<kFinalizablePersistentHandleSizeInWords, |
545 kFinalizablePersistentHandlesPerChunk, | 531 kFinalizablePersistentHandlesPerChunk, |
546 kOffsetOfRawPtrInFinalizablePersistentHandle> { | 532 kOffsetOfRawPtrInFinalizablePersistentHandle> { |
547 public: | 533 public: |
548 FinalizablePersistentHandles() | 534 FinalizablePersistentHandles() |
549 : Handles<kFinalizablePersistentHandleSizeInWords, | 535 : Handles<kFinalizablePersistentHandleSizeInWords, |
550 kFinalizablePersistentHandlesPerChunk, | 536 kFinalizablePersistentHandlesPerChunk, |
551 kOffsetOfRawPtrInFinalizablePersistentHandle>(), | 537 kOffsetOfRawPtrInFinalizablePersistentHandle>(), |
552 free_list_(NULL), mutex_(new Mutex()) { } | 538 free_list_(NULL), |
| 539 mutex_(new Mutex()) {} |
553 ~FinalizablePersistentHandles() { | 540 ~FinalizablePersistentHandles() { |
554 free_list_ = NULL; | 541 free_list_ = NULL; |
555 delete mutex_; | 542 delete mutex_; |
556 mutex_ = NULL; | 543 mutex_ = NULL; |
557 } | 544 } |
558 | 545 |
559 // Accessors. | 546 // Accessors. |
560 FinalizablePersistentHandle* free_list() const { return free_list_; } | 547 FinalizablePersistentHandle* free_list() const { return free_list_; } |
561 void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; } | 548 void set_free_list(FinalizablePersistentHandle* value) { free_list_ = value; } |
562 | 549 |
563 // Visit all handles stored in the various handle blocks. | 550 // Visit all handles stored in the various handle blocks. |
564 void VisitHandles(HandleVisitor* visitor) { | 551 void VisitHandles(HandleVisitor* visitor) { |
565 Handles<kFinalizablePersistentHandleSizeInWords, | 552 Handles<kFinalizablePersistentHandleSizeInWords, |
566 kFinalizablePersistentHandlesPerChunk, | 553 kFinalizablePersistentHandlesPerChunk, |
567 kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit( | 554 kOffsetOfRawPtrInFinalizablePersistentHandle>::Visit(visitor); |
568 visitor); | |
569 } | 555 } |
570 | 556 |
571 // Visit all object pointers stored in the various handles. | 557 // Visit all object pointers stored in the various handles. |
572 void VisitObjectPointers(ObjectPointerVisitor* visitor) { | 558 void VisitObjectPointers(ObjectPointerVisitor* visitor) { |
573 Handles<kFinalizablePersistentHandleSizeInWords, | 559 Handles<kFinalizablePersistentHandleSizeInWords, |
574 kFinalizablePersistentHandlesPerChunk, | 560 kFinalizablePersistentHandlesPerChunk, |
575 kOffsetOfRawPtrInFinalizablePersistentHandle>::VisitObjectPointers( | 561 kOffsetOfRawPtrInFinalizablePersistentHandle>:: |
576 visitor); | 562 VisitObjectPointers(visitor); |
577 } | 563 } |
578 | 564 |
579 // Allocates a persistent handle, these have to be destroyed explicitly | 565 // Allocates a persistent handle, these have to be destroyed explicitly |
580 // by calling FreeHandle. | 566 // by calling FreeHandle. |
581 FinalizablePersistentHandle* AllocateHandle() { | 567 FinalizablePersistentHandle* AllocateHandle() { |
582 FinalizablePersistentHandle* handle; | 568 FinalizablePersistentHandle* handle; |
583 { | 569 { |
584 MutexLocker ml(mutex_); | 570 MutexLocker ml(mutex_); |
585 if (free_list_ != NULL) { | 571 if (free_list_ != NULL) { |
586 handle = free_list_; | 572 handle = free_list_; |
587 free_list_ = handle->Next(); | 573 free_list_ = handle->Next(); |
588 handle->set_raw(Object::null()); | 574 handle->set_raw(Object::null()); |
589 return handle; | 575 return handle; |
590 } | 576 } |
591 } | 577 } |
592 | 578 |
593 handle = reinterpret_cast<FinalizablePersistentHandle*>( | 579 handle = |
594 AllocateScopedHandle()); | 580 reinterpret_cast<FinalizablePersistentHandle*>(AllocateScopedHandle()); |
595 handle->Clear(); | 581 handle->Clear(); |
596 return handle; | 582 return handle; |
597 } | 583 } |
598 | 584 |
599 void FreeHandle(FinalizablePersistentHandle* handle) { | 585 void FreeHandle(FinalizablePersistentHandle* handle) { |
600 MutexLocker ml(mutex_); | 586 MutexLocker ml(mutex_); |
601 handle->FreeHandle(free_list()); | 587 handle->FreeHandle(free_list()); |
602 set_free_list(handle); | 588 set_free_list(handle); |
603 } | 589 } |
604 | 590 |
605 // Validate if passed in handle is a Persistent Handle. | 591 // Validate if passed in handle is a Persistent Handle. |
606 bool IsValidHandle(Dart_WeakPersistentHandle object) const { | 592 bool IsValidHandle(Dart_WeakPersistentHandle object) const { |
607 MutexLocker ml(mutex_); | 593 MutexLocker ml(mutex_); |
608 return IsValidScopedHandle(reinterpret_cast<uword>(object)); | 594 return IsValidScopedHandle(reinterpret_cast<uword>(object)); |
609 } | 595 } |
610 | 596 |
611 // Returns a count of active handles (used for testing purposes). | 597 // Returns a count of active handles (used for testing purposes). |
612 int CountHandles() const { | 598 int CountHandles() const { return CountScopedHandles(); } |
613 return CountScopedHandles(); | |
614 } | |
615 | 599 |
616 private: | 600 private: |
617 FinalizablePersistentHandle* free_list_; | 601 FinalizablePersistentHandle* free_list_; |
618 Mutex* mutex_; | 602 Mutex* mutex_; |
619 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles); | 603 DISALLOW_COPY_AND_ASSIGN(FinalizablePersistentHandles); |
620 }; | 604 }; |
621 | 605 |
622 | 606 |
623 // Structure used for the implementation of local scopes used in dart_api. | 607 // Structure used for the implementation of local scopes used in dart_api. |
624 // These local scopes manage handles and memory allocated in the scope. | 608 // These local scopes manage handles and memory allocated in the scope. |
625 class ApiLocalScope { | 609 class ApiLocalScope { |
626 public: | 610 public: |
627 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) : | 611 ApiLocalScope(ApiLocalScope* previous, uword stack_marker) |
628 previous_(previous), stack_marker_(stack_marker) { } | 612 : previous_(previous), stack_marker_(stack_marker) {} |
629 ~ApiLocalScope() { | 613 ~ApiLocalScope() { previous_ = NULL; } |
630 previous_ = NULL; | |
631 } | |
632 | 614 |
633 // Reinit the ApiLocalScope to new values. | 615 // Reinit the ApiLocalScope to new values. |
634 void Reinit(Thread* thread, ApiLocalScope* previous, uword stack_marker) { | 616 void Reinit(Thread* thread, ApiLocalScope* previous, uword stack_marker) { |
635 previous_ = previous; | 617 previous_ = previous; |
636 stack_marker_ = stack_marker; | 618 stack_marker_ = stack_marker; |
637 zone_.Reinit(thread); | 619 zone_.Reinit(thread); |
638 } | 620 } |
639 | 621 |
640 // Reset the ApiLocalScope so that it can be reused again. | 622 // Reset the ApiLocalScope so that it can be reused again. |
641 void Reset(Thread* thread) { | 623 void Reset(Thread* thread) { |
(...skipping 19 matching lines...) Expand all Loading... |
661 DISALLOW_COPY_AND_ASSIGN(ApiLocalScope); | 643 DISALLOW_COPY_AND_ASSIGN(ApiLocalScope); |
662 }; | 644 }; |
663 | 645 |
664 | 646 |
665 class ApiNativeScope { | 647 class ApiNativeScope { |
666 public: | 648 public: |
667 ApiNativeScope() { | 649 ApiNativeScope() { |
668 // Currently no support for nesting native scopes. | 650 // Currently no support for nesting native scopes. |
669 ASSERT(Current() == NULL); | 651 ASSERT(Current() == NULL); |
670 OSThread::SetThreadLocal(Api::api_native_key_, | 652 OSThread::SetThreadLocal(Api::api_native_key_, |
671 reinterpret_cast<uword>(this)); | 653 reinterpret_cast<uword>(this)); |
672 } | 654 } |
673 | 655 |
674 ~ApiNativeScope() { | 656 ~ApiNativeScope() { |
675 ASSERT(Current() == this); | 657 ASSERT(Current() == this); |
676 OSThread::SetThreadLocal(Api::api_native_key_, 0); | 658 OSThread::SetThreadLocal(Api::api_native_key_, 0); |
677 } | 659 } |
678 | 660 |
679 static inline ApiNativeScope* Current() { | 661 static inline ApiNativeScope* Current() { |
680 return reinterpret_cast<ApiNativeScope*>( | 662 return reinterpret_cast<ApiNativeScope*>( |
681 OSThread::GetThreadLocal(Api::api_native_key_)); | 663 OSThread::GetThreadLocal(Api::api_native_key_)); |
682 } | 664 } |
683 | 665 |
684 Zone* zone() { | 666 Zone* zone() { |
685 Zone* result = zone_.GetZone(); | 667 Zone* result = zone_.GetZone(); |
686 ASSERT(result->handles()->CountScopedHandles() == 0); | 668 ASSERT(result->handles()->CountScopedHandles() == 0); |
687 ASSERT(result->handles()->CountZoneHandles() == 0); | 669 ASSERT(result->handles()->CountZoneHandles() == 0); |
688 return result; | 670 return result; |
689 } | 671 } |
690 | 672 |
691 private: | 673 private: |
692 ApiZone zone_; | 674 ApiZone zone_; |
693 }; | 675 }; |
694 | 676 |
695 | 677 |
696 // Api growable arrays use a zone for allocation. The constructor | 678 // Api growable arrays use a zone for allocation. The constructor |
697 // picks the zone from the current isolate if in an isolate | 679 // picks the zone from the current isolate if in an isolate |
698 // environment. When outside an isolate environment it picks the zone | 680 // environment. When outside an isolate environment it picks the zone |
699 // from the current native scope. | 681 // from the current native scope. |
700 template<typename T> | 682 template <typename T> |
701 class ApiGrowableArray : public BaseGrowableArray<T, ValueObject> { | 683 class ApiGrowableArray : public BaseGrowableArray<T, ValueObject> { |
702 public: | 684 public: |
703 explicit ApiGrowableArray(int initial_capacity) | 685 explicit ApiGrowableArray(int initial_capacity) |
704 : BaseGrowableArray<T, ValueObject>( | 686 : BaseGrowableArray<T, ValueObject>(initial_capacity, |
705 initial_capacity, | 687 ApiNativeScope::Current()->zone()) {} |
706 ApiNativeScope::Current()->zone()) {} | |
707 ApiGrowableArray() | 688 ApiGrowableArray() |
708 : BaseGrowableArray<T, ValueObject>( | 689 : BaseGrowableArray<T, ValueObject>(ApiNativeScope::Current()->zone()) {} |
709 ApiNativeScope::Current()->zone()) {} | |
710 ApiGrowableArray(intptr_t initial_capacity, Zone* zone) | 690 ApiGrowableArray(intptr_t initial_capacity, Zone* zone) |
711 : BaseGrowableArray<T, ValueObject>(initial_capacity, zone) {} | 691 : BaseGrowableArray<T, ValueObject>(initial_capacity, zone) {} |
712 }; | 692 }; |
713 | 693 |
714 | 694 |
715 // Implementation of the API State used in dart api for maintaining | 695 // Implementation of the API State used in dart api for maintaining |
716 // local scopes, persistent handles etc. These are setup on a per isolate | 696 // local scopes, persistent handles etc. These are setup on a per isolate |
717 // basis and destroyed when the isolate is shutdown. | 697 // basis and destroyed when the isolate is shutdown. |
718 class ApiState { | 698 class ApiState { |
719 public: | 699 public: |
720 ApiState() : persistent_handles_(), | 700 ApiState() |
721 weak_persistent_handles_(), | 701 : persistent_handles_(), |
722 null_(NULL), | 702 weak_persistent_handles_(), |
723 true_(NULL), | 703 null_(NULL), |
724 false_(NULL), | 704 true_(NULL), |
725 acquired_error_(NULL) {} | 705 false_(NULL), |
| 706 acquired_error_(NULL) {} |
726 ~ApiState() { | 707 ~ApiState() { |
727 if (null_ != NULL) { | 708 if (null_ != NULL) { |
728 persistent_handles().FreeHandle(null_); | 709 persistent_handles().FreeHandle(null_); |
729 null_ = NULL; | 710 null_ = NULL; |
730 } | 711 } |
731 if (true_ != NULL) { | 712 if (true_ != NULL) { |
732 persistent_handles().FreeHandle(true_); | 713 persistent_handles().FreeHandle(true_); |
733 true_ = NULL; | 714 true_ = NULL; |
734 } | 715 } |
735 if (false_ != NULL) { | 716 if (false_ != NULL) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 ref->set_callback(callback); | 801 ref->set_callback(callback); |
821 ref->set_is_queued_for_finalization(false); | 802 ref->set_is_queued_for_finalization(false); |
822 // This may trigger GC, so it must be called last. | 803 // This may trigger GC, so it must be called last. |
823 ref->SetExternalSize(external_size, isolate); | 804 ref->SetExternalSize(external_size, isolate); |
824 return ref; | 805 return ref; |
825 } | 806 } |
826 | 807 |
827 } // namespace dart | 808 } // namespace dart |
828 | 809 |
829 #endif // RUNTIME_VM_DART_API_STATE_H_ | 810 #endif // RUNTIME_VM_DART_API_STATE_H_ |
OLD | NEW |