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