Files
sdk/runtime/vm/allocation.h
T
koda@google.com 9c181ec6d5 Thread/Isolate refactoring: new(Isolate*) -> new(Zone*)
Refactor all remaning cases where the current zone is used through new(Isolate*) and remove this interface.

Removing this interface is needed to move towards multiple threads per isolate, and also makes the caller more aware of the scope of the zone used, reducing the risk of use-after-free.

Make the current thread and the stack zone created around native/runtime entries directly available in their body, saving an indirection (and optimized away if unused).

R=iposva@google.com

Review URL: https://codereview.chromium.org//982873004

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@44541 260f80e4-7a28-3924-810f-c04153c831b5
2015-03-17 19:24:26 +00:00

121 lines
3.9 KiB
C++

// 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_ALLOCATION_H_
#define VM_ALLOCATION_H_
#include "platform/assert.h"
#include "vm/base_isolate.h"
#include "vm/globals.h"
namespace dart {
// Forward declarations.
class Isolate;
// Stack allocated objects subclass from this base class. Objects of this type
// cannot be allocated on either the C or object heaps. Destructors for objects
// of this type will not be run unless the stack is unwound through normal
// program control flow.
class ValueObject {
public:
ValueObject() { }
~ValueObject() { }
private:
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ValueObject);
};
// Stack resources subclass from this base class. The VM will ensure that the
// destructors of these objects are called before the stack is unwound past the
// objects location on the stack. Use stack resource objects if objects
// need to be destroyed even in the case of exceptions when a Longjump is done
// to a stack frame above the frame where these objects were allocated.
class StackResource {
public:
explicit StackResource(Isolate* isolate)
: isolate_(reinterpret_cast<BaseIsolate*>(isolate)), previous_(NULL) {
// We can only have longjumps and exceptions when there is a current
// isolate. If there is no current isolate, we don't need to
// protect this case.
if (isolate_ != NULL) {
previous_ = isolate_->top_resource();
isolate_->set_top_resource(this);
}
}
virtual ~StackResource() {
if (isolate_ != NULL) {
StackResource* top = isolate_->top_resource();
ASSERT(top == this);
isolate_->set_top_resource(previous_);
}
#if defined(DEBUG)
if (isolate_ != NULL) {
BaseIsolate::AssertCurrent(isolate_);
}
#endif
}
// We can only create StackResources with Isolates, so provide the original
// isolate to the subclasses. The only reason we have a BaseIsolate in the
// StackResource is to break the header include cycles.
Isolate* isolate() const { return reinterpret_cast<Isolate*>(isolate_); }
// Destroy stack resources of isolate until top exit frame.
static void Unwind(Isolate* isolate) { UnwindAbove(isolate, NULL); }
// Destroy stack resources of isolate above new_top, exclusive.
static void UnwindAbove(Isolate* isolate, StackResource* new_top);
private:
BaseIsolate* const isolate_; // Current isolate for this stack resource.
StackResource* previous_;
DISALLOW_ALLOCATION();
DISALLOW_IMPLICIT_CONSTRUCTORS(StackResource);
};
// Static allocated classes only contain static members and can never
// be instantiated in the heap or on the stack.
class AllStatic {
private:
DISALLOW_ALLOCATION();
DISALLOW_IMPLICIT_CONSTRUCTORS(AllStatic);
};
// Zone allocated objects cannot be individually deallocated, but have
// to rely on the destructor of Zone which is called when the Zone
// goes out of scope to reclaim memory.
class ZoneAllocated {
public:
ZoneAllocated() { }
// Implicitly allocate the object in the current zone.
void* operator new(uword size);
// Allocate the object in the given zone, which must be the current zone.
void* operator new(uword size, Zone* zone);
// Ideally, the delete operator should be protected instead of
// public, but unfortunately the compiler sometimes synthesizes
// (unused) destructors for classes derived from ZoneObject, which
// require the operator to be visible. MSVC requires the delete
// operator to be public.
// Disallow explicit deallocation of nodes. Nodes can only be
// deallocated by invoking DeleteAll() on the zone they live in.
void operator delete(void* pointer) { UNREACHABLE(); }
private:
DISALLOW_COPY_AND_ASSIGN(ZoneAllocated);
};
} // namespace dart
#endif // VM_ALLOCATION_H_