| // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #ifndef VM_REUSABLE_HANDLES_H_ |
| #define VM_REUSABLE_HANDLES_H_ |
| |
| #include "vm/allocation.h" |
| #include "vm/handles.h" |
| #include "vm/object.h" |
| |
| namespace dart { |
| |
| // The class ReusableHandleScope is used in regions of the |
| // virtual machine where isolate specific reusable handles are used. |
| // This class asserts that we do not add code that will result in recursive |
| // uses of reusable handles. |
| // It is used as follows: |
| // { |
| // ReusableHandleScope reused_handles(isolate); |
| // .... |
| // ..... |
| // code that uses isolate specific reusable handles. |
| // Array& funcs = reused_handles.ArrayHandle(); |
| // .... |
| // } |
| #if defined(DEBUG) |
| class ReusableObjectHandleScope : public StackResource { |
| public: |
| explicit ReusableObjectHandleScope(Isolate* isolate) |
| : StackResource(isolate), isolate_(isolate) { |
| ASSERT(!isolate->reusable_handle_scope_active()); |
| isolate->set_reusable_handle_scope_active(true); |
| } |
| ReusableObjectHandleScope() |
| : StackResource(Isolate::Current()), isolate_(Isolate::Current()) { |
| ASSERT(!isolate()->reusable_handle_scope_active()); |
| isolate()->set_reusable_handle_scope_active(true); |
| } |
| ~ReusableObjectHandleScope() { |
| ASSERT(isolate()->reusable_handle_scope_active()); |
| isolate()->set_reusable_handle_scope_active(false); |
| Handle().raw_ = Object::null(); |
| } |
| Object& Handle() { |
| ASSERT(isolate_->Object_handle_ != NULL); |
| return *isolate_->Object_handle_; |
| } |
| |
| private: |
| Isolate* isolate_; |
| DISALLOW_COPY_AND_ASSIGN(ReusableObjectHandleScope); |
| }; |
| |
| |
| class ReusableHandleScope : public StackResource { |
| public: |
| explicit ReusableHandleScope(Isolate* isolate) |
| : StackResource(isolate), isolate_(isolate) { |
| ASSERT(!isolate->reusable_handle_scope_active()); |
| isolate->set_reusable_handle_scope_active(true); |
| } |
| ReusableHandleScope() |
| : StackResource(Isolate::Current()), isolate_(Isolate::Current()) { |
| ASSERT(!isolate()->reusable_handle_scope_active()); |
| isolate()->set_reusable_handle_scope_active(true); |
| } |
| ~ReusableHandleScope() { |
| ASSERT(isolate()->reusable_handle_scope_active()); |
| isolate()->set_reusable_handle_scope_active(false); |
| #define CLEAR_REUSABLE_HANDLE(object) \ |
| object##Handle().raw_ = Object::null(); \ |
| |
| REUSABLE_HANDLE_LIST(CLEAR_REUSABLE_HANDLE); |
| } |
| |
| #define REUSABLE_HANDLE_ACCESSORS(object) \ |
| object& object##Handle() { \ |
| ASSERT(isolate_->object##_handle_ != NULL); \ |
| return *isolate_->object##_handle_; \ |
| } \ |
| |
| REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ACCESSORS) |
| #undef REUSABLE_HANDLE_ACCESSORS |
| |
| private: |
| void ResetHandles(); |
| Isolate* isolate_; |
| DISALLOW_COPY_AND_ASSIGN(ReusableHandleScope); |
| }; |
| #else |
| class ReusableObjectHandleScope : public ValueObject { |
| public: |
| explicit ReusableObjectHandleScope(Isolate* isolate) |
| : handle_(isolate->Object_handle_) { |
| } |
| ReusableObjectHandleScope() : handle_(Isolate::Current()->Object_handle_) { |
| } |
| ~ReusableObjectHandleScope() { |
| handle_->raw_ = Object::null(); |
| } |
| Object& Handle() { |
| ASSERT(handle_ != NULL); |
| return *handle_; |
| } |
| |
| private: |
| Object* handle_; |
| DISALLOW_COPY_AND_ASSIGN(ReusableObjectHandleScope); |
| }; |
| |
| |
| class ReusableHandleScope : public ValueObject { |
| public: |
| explicit ReusableHandleScope(Isolate* isolate) : isolate_(isolate) { |
| } |
| ReusableHandleScope() : isolate_(Isolate::Current()) { |
| } |
| ~ReusableHandleScope() { |
| #define CLEAR_REUSABLE_HANDLE(object) \ |
| object##Handle().raw_ = Object::null(); \ |
| |
| REUSABLE_HANDLE_LIST(CLEAR_REUSABLE_HANDLE); |
| } |
| |
| #define REUSABLE_HANDLE_ACCESSORS(object) \ |
| object& object##Handle() { \ |
| ASSERT(isolate_->object##_handle_ != NULL); \ |
| return *isolate_->object##_handle_; \ |
| } \ |
| |
| REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_ACCESSORS) |
| #undef REUSABLE_HANDLE_ACCESSORS |
| |
| private: |
| void ResetHandles(); |
| Isolate* isolate_; |
| DISALLOW_COPY_AND_ASSIGN(ReusableHandleScope); |
| }; |
| #endif // defined(DEBUG) |
| |
| } // namespace dart |
| |
| #endif // VM_REUSABLE_HANDLES_H_ |