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 VM_DART_API_STATE_H_ | 5 #ifndef VM_DART_API_STATE_H_ |
6 #define VM_DART_API_STATE_H_ | 6 #define VM_DART_API_STATE_H_ |
7 | 7 |
8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
9 | 9 |
10 #include "platform/thread.h" | 10 #include "platform/thread.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 | 21 |
22 namespace dart { | 22 namespace dart { |
23 | 23 |
24 // Implementation of Zone support for very fast allocation of small chunks | 24 // Implementation of Zone support for very fast allocation of small chunks |
25 // of memory. The chunks cannot be deallocated individually, but instead | 25 // of memory. The chunks cannot be deallocated individually, but instead |
26 // zones support deallocating all chunks in one fast operation when the | 26 // zones support deallocating all chunks in one fast operation when the |
27 // scope is exited. | 27 // scope is exited. |
28 class ApiZone { | 28 class ApiZone { |
29 public: | 29 public: |
30 // Create an empty zone. | 30 // Create an empty zone. |
31 ApiZone() : zone_() { } | 31 ApiZone() : zone_() { |
| 32 Isolate* isolate = Isolate::Current(); |
| 33 Zone* current_zone = isolate != NULL ? isolate->current_zone() : NULL; |
| 34 zone_.Link(current_zone); |
| 35 if (isolate != NULL) { |
| 36 isolate->set_current_zone(&zone_); |
| 37 } |
| 38 } |
32 | 39 |
33 // Delete all memory associated with the zone. | 40 // Delete all memory associated with the zone. |
34 ~ApiZone() { } | 41 ~ApiZone() { |
| 42 Isolate* isolate = Isolate::Current(); |
| 43 if (isolate != NULL && isolate->current_zone() == &zone_) { |
| 44 isolate->set_current_zone(zone_.previous_); |
| 45 } |
| 46 } |
35 | 47 |
36 // Allocates an array sized to hold 'len' elements of type | 48 // Allocates an array sized to hold 'len' elements of type |
37 // 'ElementType'. Checks for integer overflow when performing the | 49 // 'ElementType'. Checks for integer overflow when performing the |
38 // size computation. | 50 // size computation. |
39 template <class ElementType> | 51 template <class ElementType> |
40 ElementType* Alloc(intptr_t len) { return zone_.Alloc<ElementType>(len); } | 52 ElementType* Alloc(intptr_t len) { return zone_.Alloc<ElementType>(len); } |
41 | 53 |
42 // Allocates an array sized to hold 'len' elements of type | 54 // Allocates an array sized to hold 'len' elements of type |
43 // 'ElementType'. The new array is initialized from the memory of | 55 // 'ElementType'. The new array is initialized from the memory of |
44 // 'old_array' up to 'old_len'. | 56 // 'old_array' up to 'old_len'. |
45 template <class ElementType> | 57 template <class ElementType> |
46 ElementType* Realloc(ElementType* old_array, | 58 ElementType* Realloc(ElementType* old_array, |
47 intptr_t old_len, | 59 intptr_t old_len, |
48 intptr_t new_len) { | 60 intptr_t new_len) { |
49 return zone_.Realloc<ElementType>(old_array, old_len, new_len); | 61 return zone_.Realloc<ElementType>(old_array, old_len, new_len); |
50 } | 62 } |
51 | 63 |
52 // Allocates 'size' bytes of memory in the zone; expands the zone by | 64 // Allocates 'size' bytes of memory in the zone; expands the zone by |
53 // allocating new segments of memory on demand using 'new'. | 65 // allocating new segments of memory on demand using 'new'. |
54 // | 66 // |
55 // It is preferred to use Alloc<T>() instead, as that function can | 67 // It is preferred to use Alloc<T>() instead, as that function can |
56 // check for integer overflow. If you use AllocUnsafe, you are | 68 // check for integer overflow. If you use AllocUnsafe, you are |
57 // responsible for avoiding integer overflow yourself. | 69 // responsible for avoiding integer overflow yourself. |
58 uword AllocUnsafe(intptr_t size) { return zone_.AllocUnsafe(size); } | 70 uword AllocUnsafe(intptr_t size) { return zone_.AllocUnsafe(size); } |
59 | 71 |
60 // Compute the total size of this zone. This includes wasted space that is | 72 // Compute the total size of this zone. This includes wasted space that is |
61 // due to internal fragmentation in the segments. | 73 // due to internal fragmentation in the segments. |
62 intptr_t SizeInBytes() const { return zone_.SizeInBytes(); } | 74 intptr_t SizeInBytes() const { return zone_.SizeInBytes(); } |
63 | 75 |
| 76 Zone* GetZone() { return &zone_; } |
| 77 |
64 private: | 78 private: |
65 Zone* GetBaseZone() { return &zone_; } | |
66 | |
67 Zone zone_; | 79 Zone zone_; |
68 | 80 |
69 template<typename T> friend class ApiGrowableArray; | 81 template<typename T> friend class ApiGrowableArray; |
70 DISALLOW_COPY_AND_ASSIGN(ApiZone); | 82 DISALLOW_COPY_AND_ASSIGN(ApiZone); |
71 }; | 83 }; |
72 | 84 |
73 | 85 |
74 // Implementation of local handles which are handed out from every | 86 // Implementation of local handles which are handed out from every |
75 // dart API call, these handles are valid only in the present scope | 87 // dart API call, these handles are valid only in the present scope |
76 // and are destroyed when a Dart_ExitScope() is called. | 88 // and are destroyed when a Dart_ExitScope() is called. |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 previous_(previous), stack_marker_(stack_marker) { } | 451 previous_(previous), stack_marker_(stack_marker) { } |
440 ~ApiLocalScope() { | 452 ~ApiLocalScope() { |
441 previous_ = NULL; | 453 previous_ = NULL; |
442 } | 454 } |
443 | 455 |
444 // Accessors. | 456 // Accessors. |
445 ApiLocalScope* previous() const { return previous_; } | 457 ApiLocalScope* previous() const { return previous_; } |
446 uword stack_marker() const { return stack_marker_; } | 458 uword stack_marker() const { return stack_marker_; } |
447 void set_previous(ApiLocalScope* value) { previous_ = value; } | 459 void set_previous(ApiLocalScope* value) { previous_ = value; } |
448 LocalHandles* local_handles() { return &local_handles_; } | 460 LocalHandles* local_handles() { return &local_handles_; } |
449 ApiZone* zone() { return &zone_; } | 461 Zone* zone() { return zone_.GetZone(); } |
450 | 462 |
451 private: | 463 private: |
452 ApiLocalScope* previous_; | 464 ApiLocalScope* previous_; |
453 uword stack_marker_; | 465 uword stack_marker_; |
454 LocalHandles local_handles_; | 466 LocalHandles local_handles_; |
455 ApiZone zone_; | 467 ApiZone zone_; |
456 | 468 |
457 DISALLOW_COPY_AND_ASSIGN(ApiLocalScope); | 469 DISALLOW_COPY_AND_ASSIGN(ApiLocalScope); |
458 }; | 470 }; |
459 | 471 |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 ~ApiNativeScope() { | 658 ~ApiNativeScope() { |
647 ASSERT(Current() == this); | 659 ASSERT(Current() == this); |
648 Thread::SetThreadLocal(Api::api_native_key_, 0); | 660 Thread::SetThreadLocal(Api::api_native_key_, 0); |
649 } | 661 } |
650 | 662 |
651 static inline ApiNativeScope* Current() { | 663 static inline ApiNativeScope* Current() { |
652 return reinterpret_cast<ApiNativeScope*>( | 664 return reinterpret_cast<ApiNativeScope*>( |
653 Thread::GetThreadLocal(Api::api_native_key_)); | 665 Thread::GetThreadLocal(Api::api_native_key_)); |
654 } | 666 } |
655 | 667 |
656 ApiZone* zone() { return &zone_; } | 668 Zone* zone() { return zone_.GetZone(); } |
657 | 669 |
658 private: | 670 private: |
659 ApiZone zone_; | 671 ApiZone zone_; |
660 ThreadLocalKey key_; | 672 ThreadLocalKey key_; |
661 }; | 673 }; |
662 | 674 |
663 | 675 |
664 // Api growable arrays use a zone for allocation. The constructor | 676 // Api growable arrays use a zone for allocation. The constructor |
665 // picks the zone from the current isolate if in an isolate | 677 // picks the zone from the current isolate if in an isolate |
666 // environment. When outside an isolate environment it picks the zone | 678 // environment. When outside an isolate environment it picks the zone |
667 // from the current native scope. | 679 // from the current native scope. |
668 template<typename T> | 680 template<typename T> |
669 class ApiGrowableArray : public BaseGrowableArray<T, ValueObject> { | 681 class ApiGrowableArray : public BaseGrowableArray<T, ValueObject> { |
670 public: | 682 public: |
671 explicit ApiGrowableArray(int initial_capacity) | 683 explicit ApiGrowableArray(int initial_capacity) |
672 : BaseGrowableArray<T, ValueObject>( | 684 : BaseGrowableArray<T, ValueObject>( |
673 initial_capacity, | 685 initial_capacity, |
674 ApiNativeScope::Current()->zone()->GetBaseZone()) {} | 686 ApiNativeScope::Current()->zone()) {} |
675 ApiGrowableArray() | 687 ApiGrowableArray() |
676 : BaseGrowableArray<T, ValueObject>( | 688 : BaseGrowableArray<T, ValueObject>( |
677 ApiNativeScope::Current()->zone()->GetBaseZone()) {} | 689 ApiNativeScope::Current()->zone()) {} |
678 }; | 690 }; |
679 | 691 |
680 | 692 |
681 } // namespace dart | 693 } // namespace dart |
682 | 694 |
683 #endif // VM_DART_API_STATE_H_ | 695 #endif // VM_DART_API_STATE_H_ |
OLD | NEW |