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 | |
18 | namespace dart { |
19 | |
20 | DEFINE_FLAG(bool, verify_handles, false, "Verify handles." ); |
21 | |
22 | VMHandles::~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 | |
32 | void VMHandles::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
33 | return Handles<kVMHandleSizeInWords, kVMHandlesPerChunk, |
34 | kOffsetOfRawPtr>::VisitObjectPointers(visitor); |
35 | } |
36 | |
37 | #if defined(DEBUG) |
38 | static bool IsCurrentApiNativeScope(Zone* zone) { |
39 | ApiNativeScope* scope = ApiNativeScope::Current(); |
40 | return (scope != NULL) && (scope->zone() == zone); |
41 | } |
42 | #endif // DEBUG |
43 | |
44 | uword VMHandles::AllocateHandle(Zone* zone) { |
45 | DEBUG_ASSERT(!IsCurrentApiNativeScope(zone)); |
46 | return Handles<kVMHandleSizeInWords, kVMHandlesPerChunk, |
47 | kOffsetOfRawPtr>::AllocateHandle(zone); |
48 | } |
49 | |
50 | uword VMHandles::AllocateZoneHandle(Zone* zone) { |
51 | DEBUG_ASSERT(!IsCurrentApiNativeScope(zone)); |
52 | return Handles<kVMHandleSizeInWords, kVMHandlesPerChunk, |
53 | kOffsetOfRawPtr>::AllocateZoneHandle(zone); |
54 | } |
55 | |
56 | bool VMHandles::IsZoneHandle(uword handle) { |
57 | return Handles<kVMHandleSizeInWords, kVMHandlesPerChunk, |
58 | kOffsetOfRawPtr>::IsZoneHandle(handle); |
59 | } |
60 | |
61 | int VMHandles::ScopedHandleCount() { |
62 | Thread* thread = Thread::Current(); |
63 | ASSERT(thread->zone() != NULL); |
64 | VMHandles* handles = thread->zone()->handles(); |
65 | return handles->CountScopedHandles(); |
66 | } |
67 | |
68 | int VMHandles::ZoneHandleCount() { |
69 | Thread* thread = Thread::Current(); |
70 | ASSERT(thread->zone() != NULL); |
71 | VMHandles* handles = thread->zone()->handles(); |
72 | return handles->CountZoneHandles(); |
73 | } |
74 | |
75 | void 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 | |
87 | HandleScope::HandleScope(ThreadState* thread) : StackResource(thread) { |
88 | Initialize(); |
89 | } |
90 | |
91 | HandleScope::~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 | |