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 | #include "platform/assert.h" |
7 | #include "vm/dart_api_state.h" |
8 | #include "vm/flags.h" |
9 | #include "vm/heap/heap.h" |
10 | #include "vm/object.h" |
11 | #include "vm/unit_test.h" |
12 | #include "vm/zone.h" |
13 | |
14 | namespace dart { |
15 | |
16 | // Unit test for Zone handle allocation. |
17 | ISOLATE_UNIT_TEST_CASE(AllocateZoneHandle) { |
18 | #if defined(DEBUG) |
19 | FLAG_trace_handles = true; |
20 | #endif |
21 | // The previously run stub code generation may have created zone handles. |
22 | int initial_count = VMHandles::ZoneHandleCount(); |
23 | static const int kNumHandles = 65; |
24 | // Create some zone handles. |
25 | for (int i = 0; i < kNumHandles; i++) { |
26 | const Smi& handle = Smi::ZoneHandle(Smi::New(i)); |
27 | EXPECT(handle.IsSmi()); |
28 | EXPECT_EQ(i, handle.Value()); |
29 | } |
30 | EXPECT_EQ(kNumHandles + initial_count, VMHandles::ZoneHandleCount()); |
31 | // Create some more zone handles. |
32 | for (int i = kNumHandles; i < (2 * kNumHandles); i++) { |
33 | const Smi& handle = Smi::ZoneHandle(Smi::New(i)); |
34 | EXPECT(handle.IsSmi()); |
35 | EXPECT_EQ(i, handle.Value()); |
36 | } |
37 | EXPECT_EQ((2 * kNumHandles) + initial_count, VMHandles::ZoneHandleCount()); |
38 | } |
39 | |
40 | // Unit test for Scope handle allocation. |
41 | ISOLATE_UNIT_TEST_CASE(AllocateScopeHandle) { |
42 | #if defined(DEBUG) |
43 | FLAG_trace_handles = true; |
44 | #endif |
45 | int32_t handle_count = VMHandles::ScopedHandleCount(); |
46 | static const int kNumHandles = 65; |
47 | // Create some scoped handles. |
48 | { |
49 | Thread* thread = Thread::Current(); |
50 | HANDLESCOPE(thread); |
51 | for (int i = 0; i < kNumHandles; i++) { |
52 | const Smi& handle = Smi::Handle(Smi::New(i)); |
53 | EXPECT(handle.IsSmi()); |
54 | EXPECT_EQ(i, handle.Value()); |
55 | } |
56 | EXPECT_EQ((handle_count + kNumHandles), VMHandles::ScopedHandleCount()); |
57 | // Create lots of scoped handles in a loop with a nested scope. |
58 | for (int loop = 0; loop < 1000; loop++) { |
59 | HANDLESCOPE(thread); |
60 | for (int i = 0; i < 2; i++) { |
61 | const Smi& handle = Smi::Handle(Smi::New(i + loop)); |
62 | EXPECT(handle.IsSmi()); |
63 | EXPECT_EQ(i + loop, handle.Value()); |
64 | } |
65 | EXPECT_EQ((handle_count + kNumHandles + 2), |
66 | VMHandles::ScopedHandleCount()); |
67 | } |
68 | EXPECT_EQ((handle_count + kNumHandles), VMHandles::ScopedHandleCount()); |
69 | for (int i = 0; i < kNumHandles; i++) { |
70 | const Smi& handle = Smi::Handle(Smi::New(i)); |
71 | EXPECT(handle.IsSmi()); |
72 | EXPECT_EQ(i, handle.Value()); |
73 | } |
74 | EXPECT_EQ((handle_count + (2 * kNumHandles)), |
75 | VMHandles::ScopedHandleCount()); |
76 | } |
77 | EXPECT_EQ(handle_count, VMHandles::ScopedHandleCount()); |
78 | } |
79 | |
80 | static void NoopCallback(void* isolate_callback_data, |
81 | Dart_WeakPersistentHandle handle, |
82 | void* peer) {} |
83 | |
84 | // Unit test for handle validity checks. |
85 | TEST_CASE(CheckHandleValidity) { |
86 | #if defined(DEBUG) |
87 | FLAG_trace_handles = true; |
88 | #endif |
89 | Dart_Handle handle = NULL; |
90 | // Check validity using zone handles. |
91 | { |
92 | TransitionNativeToVM transition(thread); |
93 | StackZone sz(thread); |
94 | handle = reinterpret_cast<Dart_Handle>(&Smi::ZoneHandle(Smi::New(1))); |
95 | { |
96 | TransitionVMToNative to_native(thread); |
97 | EXPECT_VALID(handle); |
98 | } |
99 | } |
100 | EXPECT(!Api::IsValid(handle)); |
101 | |
102 | // Check validity using scoped handles. |
103 | { |
104 | Dart_EnterScope(); |
105 | { |
106 | TransitionNativeToVM transition(thread); |
107 | HANDLESCOPE(thread); |
108 | handle = reinterpret_cast<Dart_Handle>(&Smi::Handle(Smi::New(1))); |
109 | { |
110 | TransitionVMToNative to_native(thread); |
111 | EXPECT_VALID(handle); |
112 | } |
113 | } |
114 | Dart_ExitScope(); |
115 | } |
116 | EXPECT(!Api::IsValid(handle)); |
117 | |
118 | // Check validity using persistent handle. |
119 | Dart_Handle scoped_handle; |
120 | { |
121 | TransitionNativeToVM transition(thread); |
122 | scoped_handle = Api::NewHandle(thread, Smi::New(1)); |
123 | } |
124 | Dart_PersistentHandle persistent_handle = |
125 | Dart_NewPersistentHandle(scoped_handle); |
126 | EXPECT_VALID(persistent_handle); |
127 | |
128 | Dart_DeletePersistentHandle(persistent_handle); |
129 | EXPECT(!Api::IsValid(persistent_handle)); |
130 | |
131 | // Check validity using weak persistent handle. |
132 | handle = reinterpret_cast<Dart_Handle>(Dart_NewWeakPersistentHandle( |
133 | Dart_NewStringFromCString("foo" ), NULL, 0, NoopCallback)); |
134 | |
135 | EXPECT_NOTNULL(handle); |
136 | EXPECT_VALID(handle); |
137 | |
138 | Dart_DeleteWeakPersistentHandle( |
139 | reinterpret_cast<Dart_WeakPersistentHandle>(handle)); |
140 | EXPECT(!Api::IsValid(handle)); |
141 | } |
142 | |
143 | } // namespace dart |
144 | |