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
12namespace 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)
78REUSABLE_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