|  | // Copyright (c) 2012, 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. | 
|  |  | 
|  | #include "vm/allocation.h" | 
|  |  | 
|  | #include "platform/assert.h" | 
|  | #include "vm/isolate.h" | 
|  | #include "vm/thread.h" | 
|  | #include "vm/zone.h" | 
|  |  | 
|  | namespace dart { | 
|  |  | 
|  | static void* Allocate(uword size, Zone* zone) { | 
|  | ASSERT(zone != NULL); | 
|  | if (size > static_cast<uword>(kIntptrMax)) { | 
|  | FATAL1("ZoneAllocated object has unexpectedly large size %" Pu "", size); | 
|  | } | 
|  | return reinterpret_cast<void*>(zone->AllocUnsafe(size)); | 
|  | } | 
|  |  | 
|  | void* ZoneAllocated::operator new(uword size) { | 
|  | return Allocate(size, Thread::Current()->zone()); | 
|  | } | 
|  |  | 
|  | void* ZoneAllocated::operator new(uword size, Zone* zone) { | 
|  | ASSERT(Thread::Current()->ZoneIsOwnedByThread(zone)); | 
|  | return Allocate(size, zone); | 
|  | } | 
|  |  | 
|  | StackResource::~StackResource() { | 
|  | if (thread_ != NULL) { | 
|  | StackResource* top = thread_->top_resource(); | 
|  | ASSERT(top == this); | 
|  | thread_->set_top_resource(previous_); | 
|  | } | 
|  | #if defined(DEBUG) | 
|  | if (thread_ != NULL) { | 
|  | ASSERT(Thread::Current() == thread_); | 
|  | BaseIsolate::AssertCurrent(reinterpret_cast<BaseIsolate*>(isolate())); | 
|  | } | 
|  | #endif | 
|  | } | 
|  |  | 
|  | Isolate* StackResource::isolate() const { | 
|  | return thread_ == NULL ? NULL : thread_->isolate(); | 
|  | } | 
|  |  | 
|  | void StackResource::Init(Thread* thread) { | 
|  | // We can only have longjumps and exceptions when there is a current | 
|  | // thread and isolate.  If there is no current thread, we don't need to | 
|  | // protect this case. | 
|  | // TODO(23807): Eliminate this special case. | 
|  | if (thread != NULL) { | 
|  | ASSERT(Thread::Current() == thread); | 
|  | thread_ = thread; | 
|  | previous_ = thread_->top_resource(); | 
|  | ASSERT((previous_ == NULL) || (previous_->thread_ == thread)); | 
|  | thread_->set_top_resource(this); | 
|  | } | 
|  | } | 
|  |  | 
|  | void StackResource::UnwindAbove(Thread* thread, StackResource* new_top) { | 
|  | StackResource* current_resource = thread->top_resource(); | 
|  | while (current_resource != new_top) { | 
|  | current_resource->~StackResource(); | 
|  | current_resource = thread->top_resource(); | 
|  | } | 
|  | } | 
|  |  | 
|  | #if defined(DEBUG) | 
|  | NoSafepointScope::NoSafepointScope(Thread* current_thread) | 
|  | : StackResource(current_thread != nullptr ? current_thread | 
|  | : Thread::Current()) { | 
|  | thread()->IncrementNoSafepointScopeDepth(); | 
|  | } | 
|  |  | 
|  | NoSafepointScope::~NoSafepointScope() { | 
|  | thread()->DecrementNoSafepointScopeDepth(); | 
|  | } | 
|  | #endif  // defined(DEBUG) | 
|  |  | 
|  | }  // namespace dart |