// 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 RUNTIME_VM_REUSABLE_HANDLES_H_ #define RUNTIME_VM_REUSABLE_HANDLES_H_ #include "vm/allocation.h" #include "vm/handles.h" #include "vm/object.h" namespace dart { // Classes registered in REUSABLE_HANDLE_LIST have an thread specific reusable // handle. A guard class (Reusable*ClassName*HandleScope) should be used in // regions of the virtual machine where the thread specific reusable handle // of that type is used. The class asserts that we do not add code that will // result in recursive uses of the class's reusable handle. // // Below is an example of a reusable array handle via the // REUSABLE_*CLASSNAME*_HANDLESCOPE macro: // // { // REUSABLE_ARRAY_HANDLESCOPE(thread); // .... // .... // Array& funcs = reused_array_handle.Handle(); // code that uses funcs // .... // } // #if defined(DEBUG) #define REUSABLE_SCOPE(name) \ class Reusable##name##HandleScope : public ValueObject { \ public: \ explicit Reusable##name##HandleScope(Thread* thread) : thread_(thread) { \ ASSERT(!thread->reusable_##name##_handle_scope_active()); \ thread->set_reusable_##name##_handle_scope_active(true); \ } \ Reusable##name##HandleScope() : thread_(Thread::Current()) { \ ASSERT(!thread_->reusable_##name##_handle_scope_active()); \ thread_->set_reusable_##name##_handle_scope_active(true); \ } \ ~Reusable##name##HandleScope() { \ ASSERT(thread_->reusable_##name##_handle_scope_active()); \ thread_->set_reusable_##name##_handle_scope_active(false); \ Handle().ptr_ = name::null(); \ } \ name& Handle() const { \ ASSERT(thread_->name##_handle_ != NULL); \ return *thread_->name##_handle_; \ } \ \ private: \ Thread* thread_; \ DISALLOW_COPY_AND_ASSIGN(Reusable##name##HandleScope); \ }; #else #define REUSABLE_SCOPE(name) \ class Reusable##name##HandleScope : public ValueObject { \ public: \ explicit Reusable##name##HandleScope(Thread* thread) \ : handle_(thread->name##_handle_) {} \ Reusable##name##HandleScope() \ : handle_(Thread::Current()->name##_handle_) {} \ ~Reusable##name##HandleScope() { handle_->ptr_ = name::null(); } \ name& Handle() const { \ ASSERT(handle_ != NULL); \ return *handle_; \ } \ \ private: \ name* handle_; \ DISALLOW_COPY_AND_ASSIGN(Reusable##name##HandleScope); \ }; #endif // defined(DEBUG) REUSABLE_HANDLE_LIST(REUSABLE_SCOPE) #undef REUSABLE_SCOPE #define REUSABLE_ABSTRACT_TYPE_HANDLESCOPE(thread) \ ReusableAbstractTypeHandleScope reused_abstract_type(thread); #define REUSABLE_ARRAY_HANDLESCOPE(thread) \ ReusableArrayHandleScope reused_array_handle(thread); #define REUSABLE_CLASS_HANDLESCOPE(thread) \ ReusableClassHandleScope reused_class_handle(thread); #define REUSABLE_CODE_HANDLESCOPE(thread) \ ReusableCodeHandleScope reused_code_handle(thread); #define REUSABLE_ERROR_HANDLESCOPE(thread) \ ReusableErrorHandleScope reused_error_handle(thread); #define REUSABLE_EXCEPTION_HANDLERS_HANDLESCOPE(thread) \ ReusableExceptionHandlersHandleScope reused_exception_handlers_handle(thread); #define REUSABLE_FIELD_HANDLESCOPE(thread) \ ReusableFieldHandleScope reused_field_handle(thread); #define REUSABLE_FUNCTION_HANDLESCOPE(thread) \ ReusableFunctionHandleScope reused_function_handle(thread); #define REUSABLE_GROWABLE_OBJECT_ARRAY_HANDLESCOPE(thread) \ ReusableGrowableObjectArrayHandleScope reused_growable_object_array_handle( \ thread) #define REUSABLE_INSTANCE_HANDLESCOPE(thread) \ ReusableInstanceHandleScope reused_instance_handle(thread); #define REUSABLE_LIBRARY_HANDLESCOPE(thread) \ ReusableLibraryHandleScope reused_library_handle(thread); #define REUSABLE_OBJECT_HANDLESCOPE(thread) \ ReusableObjectHandleScope reused_object_handle(thread); #define REUSABLE_PC_DESCRIPTORS_HANDLESCOPE(thread) \ ReusablePcDescriptorsHandleScope reused_pc_descriptors_handle(thread); #define REUSABLE_SMI_HANDLESCOPE(thread) \ ReusableSmiHandleScope reused_smi_handle(thread); #define REUSABLE_STRING_HANDLESCOPE(thread) \ ReusableStringHandleScope reused_string_handle(thread); #define REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread) \ ReusableTypeArgumentsHandleScope reused_type_arguments_handle(thread); #define REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread) \ ReusableTypeParameterHandleScope reused_type_parameter(thread); } // namespace dart #endif // RUNTIME_VM_REUSABLE_HANDLES_H_