1// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/handles.h"
6
7#include "platform/assert.h"
8#include "platform/utils.h"
9#include "vm/dart_api_state.h"
10#include "vm/flags.h"
11#include "vm/os.h"
12#include "vm/raw_object.h"
13#include "vm/visitor.h"
14#include "vm/zone.h"
15
16#include "vm/handles_impl.h"
17
18namespace dart {
19
20DEFINE_FLAG(bool, verify_handles, false, "Verify handles.");
21
22VMHandles::~VMHandles() {
23 if (FLAG_trace_handles) {
24 OS::PrintErr("*** Handle Counts for 0x(%" Px "):Zone = %d,Scoped = %d\n",
25 reinterpret_cast<intptr_t>(this), CountZoneHandles(),
26 CountScopedHandles());
27 OS::PrintErr("*** Deleting VM handle block 0x%" Px "\n",
28 reinterpret_cast<intptr_t>(this));
29 }
30}
31
32void VMHandles::VisitObjectPointers(ObjectPointerVisitor* visitor) {
33 return Handles<kVMHandleSizeInWords, kVMHandlesPerChunk,
34 kOffsetOfRawPtr>::VisitObjectPointers(visitor);
35}
36
37#if defined(DEBUG)
38static bool IsCurrentApiNativeScope(Zone* zone) {
39 ApiNativeScope* scope = ApiNativeScope::Current();
40 return (scope != NULL) && (scope->zone() == zone);
41}
42#endif // DEBUG
43
44uword VMHandles::AllocateHandle(Zone* zone) {
45 DEBUG_ASSERT(!IsCurrentApiNativeScope(zone));
46 return Handles<kVMHandleSizeInWords, kVMHandlesPerChunk,
47 kOffsetOfRawPtr>::AllocateHandle(zone);
48}
49
50uword VMHandles::AllocateZoneHandle(Zone* zone) {
51 DEBUG_ASSERT(!IsCurrentApiNativeScope(zone));
52 return Handles<kVMHandleSizeInWords, kVMHandlesPerChunk,
53 kOffsetOfRawPtr>::AllocateZoneHandle(zone);
54}
55
56bool VMHandles::IsZoneHandle(uword handle) {
57 return Handles<kVMHandleSizeInWords, kVMHandlesPerChunk,
58 kOffsetOfRawPtr>::IsZoneHandle(handle);
59}
60
61int VMHandles::ScopedHandleCount() {
62 Thread* thread = Thread::Current();
63 ASSERT(thread->zone() != NULL);
64 VMHandles* handles = thread->zone()->handles();
65 return handles->CountScopedHandles();
66}
67
68int VMHandles::ZoneHandleCount() {
69 Thread* thread = Thread::Current();
70 ASSERT(thread->zone() != NULL);
71 VMHandles* handles = thread->zone()->handles();
72 return handles->CountZoneHandles();
73}
74
75void HandleScope::Initialize() {
76 ASSERT(thread()->MayAllocateHandles());
77 VMHandles* handles = thread()->zone()->handles();
78 ASSERT(handles != NULL);
79 saved_handle_block_ = handles->scoped_blocks_;
80 saved_handle_slot_ = handles->scoped_blocks_->next_handle_slot();
81#if defined(DEBUG)
82 link_ = thread()->top_handle_scope();
83 thread()->set_top_handle_scope(this);
84#endif
85}
86
87HandleScope::HandleScope(ThreadState* thread) : StackResource(thread) {
88 Initialize();
89}
90
91HandleScope::~HandleScope() {
92 ASSERT(thread()->zone() != NULL);
93 VMHandles* handles = thread()->zone()->handles();
94 ASSERT(handles != NULL);
95 handles->scoped_blocks_ = saved_handle_block_;
96 handles->scoped_blocks_->set_next_handle_slot(saved_handle_slot_);
97#if defined(DEBUG)
98 handles->VerifyScopedHandleState();
99 handles->ZapFreeScopedHandles();
100 ASSERT(thread()->top_handle_scope() == this);
101 thread()->set_top_handle_scope(link_);
102#endif
103}
104
105} // namespace dart
106