// 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/handles.h" #include "platform/assert.h" #include "platform/utils.h" #include "vm/dart_api_state.h" #include "vm/flags.h" #include "vm/os.h" #include "vm/raw_object.h" #include "vm/visitor.h" #include "vm/zone.h" #include "vm/handles_impl.h" namespace dart { DEFINE_FLAG(bool, verify_handles, false, "Verify handles."); VMHandles::~VMHandles() { if (FLAG_trace_handles) { OS::PrintErr("*** Handle Counts for 0x(%" Px "):Zone = %d,Scoped = %d\n", reinterpret_cast(this), CountZoneHandles(), CountScopedHandles()); OS::PrintErr("*** Deleting VM handle block 0x%" Px "\n", reinterpret_cast(this)); } } void VMHandles::VisitObjectPointers(ObjectPointerVisitor* visitor) { return Handles::VisitObjectPointers(visitor); } #if defined(DEBUG) static bool IsCurrentApiNativeScope(Zone* zone) { ApiNativeScope* scope = ApiNativeScope::Current(); return (scope != NULL) && (scope->zone() == zone); } #endif // DEBUG uword VMHandles::AllocateHandle(Zone* zone) { DEBUG_ASSERT(!IsCurrentApiNativeScope(zone)); return Handles::AllocateHandle(zone); } uword VMHandles::AllocateZoneHandle(Zone* zone) { DEBUG_ASSERT(!IsCurrentApiNativeScope(zone)); return Handles::AllocateZoneHandle(zone); } bool VMHandles::IsZoneHandle(uword handle) { return Handles::IsZoneHandle(handle); } int VMHandles::ScopedHandleCount() { Thread* thread = Thread::Current(); ASSERT(thread->zone() != NULL); VMHandles* handles = thread->zone()->handles(); return handles->CountScopedHandles(); } int VMHandles::ZoneHandleCount() { Thread* thread = Thread::Current(); ASSERT(thread->zone() != NULL); VMHandles* handles = thread->zone()->handles(); return handles->CountZoneHandles(); } void HandleScope::Initialize() { ASSERT(thread()->MayAllocateHandles()); VMHandles* handles = thread()->zone()->handles(); ASSERT(handles != NULL); saved_handle_block_ = handles->scoped_blocks_; saved_handle_slot_ = handles->scoped_blocks_->next_handle_slot(); #if defined(DEBUG) link_ = thread()->top_handle_scope(); thread()->set_top_handle_scope(this); #endif } HandleScope::HandleScope(ThreadState* thread) : StackResource(thread) { Initialize(); } HandleScope::~HandleScope() { ASSERT(thread()->zone() != NULL); VMHandles* handles = thread()->zone()->handles(); ASSERT(handles != NULL); handles->scoped_blocks_ = saved_handle_block_; handles->scoped_blocks_->set_next_handle_slot(saved_handle_slot_); #if defined(DEBUG) handles->VerifyScopedHandleState(); handles->ZapFreeScopedHandles(); ASSERT(thread()->top_handle_scope() == this); thread()->set_top_handle_scope(link_); #endif } } // namespace dart