Index: runtime/vm/thread.h |
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h |
index 1a7d48fed1eaddf491b18012416cf24bea7aa970..93d7e0e17a8688f530df90beb07da0826b0e8eef 100644 |
--- a/runtime/vm/thread.h |
+++ b/runtime/vm/thread.h |
@@ -6,28 +6,63 @@ |
#define VM_THREAD_H_ |
#include "vm/globals.h" |
+#include "vm/handles.h" |
#include "vm/os_thread.h" |
#include "vm/store_buffer.h" |
#include "vm/runtime_entry_list.h" |
namespace dart { |
+class AbstractType; |
+class Array; |
class CHA; |
+class Class; |
+class Code; |
+class Error; |
+class ExceptionHandlers; |
+class Field; |
+class Function; |
+class GrowableObjectArray; |
class HandleScope; |
class Heap; |
+class Instance; |
class Isolate; |
+class Library; |
class Log; |
class LongJumpScope; |
class Object; |
+class PcDescriptors; |
class RawBool; |
class RawObject; |
class RawCode; |
class RawString; |
class RuntimeEntry; |
class StackResource; |
+class String; |
class TimelineEventBlock; |
+class TypeArguments; |
+class TypeParameter; |
class Zone; |
+#define REUSABLE_HANDLE_LIST(V) \ |
+ V(AbstractType) \ |
+ V(Array) \ |
+ V(Class) \ |
+ V(Code) \ |
+ V(Error) \ |
+ V(ExceptionHandlers) \ |
+ V(Field) \ |
+ V(Function) \ |
+ V(GrowableObjectArray) \ |
+ V(Instance) \ |
+ V(Library) \ |
+ V(Object) \ |
+ V(PcDescriptors) \ |
+ V(String) \ |
+ V(TypeArguments) \ |
+ V(TypeParameter) \ |
+ |
+ |
// List of VM-global objects/addresses cached in each Thread object. |
#define CACHED_VM_OBJECTS_LIST(V) \ |
V(RawObject*, object_null_, Object::null(), NULL) \ |
@@ -302,7 +337,38 @@ LEAF_RUNTIME_ENTRY_LIST(DEFINE_OFFSET_METHOD) |
bool IsThreadInterrupterEnabled(ThreadInterruptCallback* callback, |
void** data) const; |
+#if defined(DEBUG) |
+#define REUSABLE_HANDLE_SCOPE_ACCESSORS(object) \ |
+ void set_reusable_##object##_handle_scope_active(bool value) { \ |
+ reusable_##object##_handle_scope_active_ = value; \ |
+ } \ |
+ bool reusable_##object##_handle_scope_active() const { \ |
+ return reusable_##object##_handle_scope_active_; \ |
+ } |
+ REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_ACCESSORS) |
+#undef REUSABLE_HANDLE_SCOPE_ACCESSORS |
+ |
+bool IsAnyReusableHandleScopeActive() const { |
+#define IS_REUSABLE_HANDLE_SCOPE_ACTIVE(object) \ |
+ if (reusable_##object##_handle_scope_active_) return true; |
+ REUSABLE_HANDLE_LIST(IS_REUSABLE_HANDLE_SCOPE_ACTIVE) |
+ return false; |
+#undef IS_REUSABLE_HANDLE_SCOPE_ACTIVE |
+} |
+#endif // defined(DEBUG) |
+ |
+#define REUSABLE_HANDLE(object) \ |
+ object& object##Handle() const { \ |
+ return *object##_handle_; \ |
+ } |
+ REUSABLE_HANDLE_LIST(REUSABLE_HANDLE) |
+#undef REUSABLE_HANDLE |
+ |
+ void VisitObjectPointers(ObjectPointerVisitor* visitor); |
+ |
private: |
+ template<class T> T* AllocateReusableHandle(); |
+ |
static ThreadLocalKey thread_key_; |
const ThreadId id_; |
@@ -330,6 +396,21 @@ RUNTIME_ENTRY_LIST(DECLARE_MEMBERS) |
LEAF_RUNTIME_ENTRY_LIST(DECLARE_MEMBERS) |
#undef DECLARE_MEMBERS |
+ // Reusable handles support. |
+#define REUSABLE_HANDLE_FIELDS(object) \ |
+ object* object##_handle_; |
+ REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS) |
+#undef REUSABLE_HANDLE_FIELDS |
+ |
+#if defined(DEBUG) |
+#define REUSABLE_HANDLE_SCOPE_VARIABLE(object) \ |
+ bool reusable_##object##_handle_scope_active_; |
+ REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_VARIABLE); |
+#undef REUSABLE_HANDLE_SCOPE_VARIABLE |
+#endif // defined(DEBUG) |
+ |
+ VMHandles reusable_handles_; |
+ |
explicit Thread(bool init_vm_constants = true); |
void InitVMConstants(); |
@@ -355,6 +436,11 @@ LEAF_RUNTIME_ENTRY_LIST(DECLARE_MEMBERS) |
void Schedule(Isolate* isolate, bool bypass_safepoint = false); |
void Unschedule(bool bypass_safepoint = false); |
+#define REUSABLE_FRIEND_DECLARATION(name) \ |
+ friend class Reusable##name##HandleScope; |
+REUSABLE_HANDLE_LIST(REUSABLE_FRIEND_DECLARATION) |
+#undef REUSABLE_FRIEND_DECLARATION |
+ |
friend class ApiZone; |
friend class Isolate; |
friend class StackZone; |