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