// 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(BaseIsolate* isolate) : isolate_(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 } BaseIsolate* isolate() const { return isolate_; } // The delete operator should be private instead of public, but unfortunately // the compiler complains when compiling the destructors for subclasses. void operator delete(void* pointer) { UNREACHABLE(); } private: BaseIsolate* isolate_; // Current isolate for this stack resource. StackResource* previous_; void* operator new(uword size); 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() { } // It would be ideal if the destructor method could be made private, // but the g++ compiler complains when this is subclassed. virtual ~ZoneAllocated(); // Implicitly allocate the object in the current zone. void* operator new(uword size); // 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_