blob: 2af338da4ac2daf60ae0e462aed53b680cf95a1a [file] [log] [blame]
// 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_