1 | // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
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. |
4 | |
5 | #ifndef RUNTIME_VM_REUSABLE_HANDLES_H_ |
6 | #define RUNTIME_VM_REUSABLE_HANDLES_H_ |
7 | |
8 | #include "vm/allocation.h" |
9 | #include "vm/handles.h" |
10 | #include "vm/object.h" |
11 | |
12 | namespace dart { |
13 | |
14 | // Classes registered in REUSABLE_HANDLE_LIST have an thread specific reusable |
15 | // handle. A guard class (Reusable*ClassName*HandleScope) should be used in |
16 | // regions of the virtual machine where the thread specific reusable handle |
17 | // of that type is used. The class asserts that we do not add code that will |
18 | // result in recursive uses of the class's reusable handle. |
19 | // |
20 | // Below is an example of a reusable array handle via the |
21 | // REUSABLE_*CLASSNAME*_HANDLESCOPE macro: |
22 | // |
23 | // { |
24 | // REUSABLE_ARRAY_HANDLESCOPE(thread); |
25 | // .... |
26 | // .... |
27 | // Array& funcs = reused_array_handle.Handle(); |
28 | // code that uses funcs |
29 | // .... |
30 | // } |
31 | // |
32 | |
33 | #if defined(DEBUG) |
34 | #define REUSABLE_SCOPE(name) \ |
35 | class Reusable##name##HandleScope : public ValueObject { \ |
36 | public: \ |
37 | explicit Reusable##name##HandleScope(Thread* thread) : thread_(thread) { \ |
38 | ASSERT(!thread->reusable_##name##_handle_scope_active()); \ |
39 | thread->set_reusable_##name##_handle_scope_active(true); \ |
40 | } \ |
41 | Reusable##name##HandleScope() : thread_(Thread::Current()) { \ |
42 | ASSERT(!thread_->reusable_##name##_handle_scope_active()); \ |
43 | thread_->set_reusable_##name##_handle_scope_active(true); \ |
44 | } \ |
45 | ~Reusable##name##HandleScope() { \ |
46 | ASSERT(thread_->reusable_##name##_handle_scope_active()); \ |
47 | thread_->set_reusable_##name##_handle_scope_active(false); \ |
48 | Handle().raw_ = name::null(); \ |
49 | } \ |
50 | name& Handle() const { \ |
51 | ASSERT(thread_->name##_handle_ != NULL); \ |
52 | return *thread_->name##_handle_; \ |
53 | } \ |
54 | \ |
55 | private: \ |
56 | Thread* thread_; \ |
57 | DISALLOW_COPY_AND_ASSIGN(Reusable##name##HandleScope); \ |
58 | }; |
59 | #else |
60 | #define REUSABLE_SCOPE(name) \ |
61 | class Reusable##name##HandleScope : public ValueObject { \ |
62 | public: \ |
63 | explicit Reusable##name##HandleScope(Thread* thread) \ |
64 | : handle_(thread->name##_handle_) {} \ |
65 | Reusable##name##HandleScope() \ |
66 | : handle_(Thread::Current()->name##_handle_) {} \ |
67 | ~Reusable##name##HandleScope() { handle_->raw_ = name::null(); } \ |
68 | name& Handle() const { \ |
69 | ASSERT(handle_ != NULL); \ |
70 | return *handle_; \ |
71 | } \ |
72 | \ |
73 | private: \ |
74 | name* handle_; \ |
75 | DISALLOW_COPY_AND_ASSIGN(Reusable##name##HandleScope); \ |
76 | }; |
77 | #endif // defined(DEBUG) |
78 | REUSABLE_HANDLE_LIST(REUSABLE_SCOPE) |
79 | #undef REUSABLE_SCOPE |
80 | |
81 | #define REUSABLE_ABSTRACT_TYPE_HANDLESCOPE(thread) \ |
82 | ReusableAbstractTypeHandleScope reused_abstract_type(thread); |
83 | #define REUSABLE_ARRAY_HANDLESCOPE(thread) \ |
84 | ReusableArrayHandleScope reused_array_handle(thread); |
85 | #define REUSABLE_CLASS_HANDLESCOPE(thread) \ |
86 | ReusableClassHandleScope reused_class_handle(thread); |
87 | #define REUSABLE_CODE_HANDLESCOPE(thread) \ |
88 | ReusableCodeHandleScope reused_code_handle(thread); |
89 | #define REUSABLE_BYTECODE_HANDLESCOPE(thread) \ |
90 | ReusableBytecodeHandleScope reused_bytecode_handle(thread); |
91 | #define REUSABLE_ERROR_HANDLESCOPE(thread) \ |
92 | ReusableErrorHandleScope reused_error_handle(thread); |
93 | #define REUSABLE_EXCEPTION_HANDLERS_HANDLESCOPE(thread) \ |
94 | ReusableExceptionHandlersHandleScope reused_exception_handlers_handle(thread); |
95 | #define REUSABLE_FIELD_HANDLESCOPE(thread) \ |
96 | ReusableFieldHandleScope reused_field_handle(thread); |
97 | #define REUSABLE_FUNCTION_HANDLESCOPE(thread) \ |
98 | ReusableFunctionHandleScope reused_function_handle(thread); |
99 | #define REUSABLE_GROWABLE_OBJECT_ARRAY_HANDLESCOPE(thread) \ |
100 | ReusableGrowableObjectArrayHandleScope reused_growable_object_array_handle( \ |
101 | thread) |
102 | #define REUSABLE_INSTANCE_HANDLESCOPE(thread) \ |
103 | ReusableInstanceHandleScope reused_instance_handle(thread); |
104 | #define REUSABLE_LIBRARY_HANDLESCOPE(thread) \ |
105 | ReusableLibraryHandleScope reused_library_handle(thread); |
106 | #define REUSABLE_OBJECT_HANDLESCOPE(thread) \ |
107 | ReusableObjectHandleScope reused_object_handle(thread); |
108 | #define REUSABLE_PC_DESCRIPTORS_HANDLESCOPE(thread) \ |
109 | ReusablePcDescriptorsHandleScope reused_pc_descriptors_handle(thread); |
110 | #define REUSABLE_SMI_HANDLESCOPE(thread) \ |
111 | ReusableSmiHandleScope reused_smi_handle(thread); |
112 | #define REUSABLE_STRING_HANDLESCOPE(thread) \ |
113 | ReusableStringHandleScope reused_string_handle(thread); |
114 | #define REUSABLE_TYPE_ARGUMENTS_HANDLESCOPE(thread) \ |
115 | ReusableTypeArgumentsHandleScope reused_type_arguments_handle(thread); |
116 | #define REUSABLE_TYPE_PARAMETER_HANDLESCOPE(thread) \ |
117 | ReusableTypeParameterHandleScope reused_type_parameter(thread); |
118 | |
119 | } // namespace dart |
120 | |
121 | #endif // RUNTIME_VM_REUSABLE_HANDLES_H_ |
122 | |