Flutter Engine
The Flutter Engine
code_descriptors_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 "platform/assert.h"
6#include "vm/globals.h"
7
11#include "vm/dart_entry.h"
12#include "vm/native_entry.h"
13#include "vm/parser.h"
14#include "vm/symbols.h"
15#include "vm/thread.h"
16#include "vm/unit_test.h"
17
18namespace dart {
19
23 int64_t value = -1;
25 EXPECT_EQ(10, value);
27 EXPECT_EQ(20, value);
28 {
31 }
32}
33
36 bool* auto_setup_scope) {
37 ASSERT(auto_setup_scope);
38 *auto_setup_scope = false;
39 return NativeFunc;
40}
41
42TEST_CASE(StackMapGC) {
43 const char* kScriptChars = R"(
44class A {
45 @pragma("vm:external-name", "NativeFunc")
46 external static void func(var i, var k);
47 static foo() {
48 var i;
49 var s1;
50 var k;
51 var s2;
52 var s3;
53 i = 10; s1 = 'abcd'; k = 20; s2 = 'B'; s3 = 'C';
54 func(i, k);
55 return i + k; }
56 static void moo() {
57 var i = A.foo();
58 if (i != 30) throw '$i != 30';
59 }
60})";
61 // First setup the script and compile the script.
63 TransitionNativeToVM transition(thread);
64
68 EXPECT(!lib.IsNull());
69 Class& cls =
71 EXPECT(!cls.IsNull());
72
73 // Now compile the two functions 'A.foo' and 'A.moo'
74 String& function_moo_name = String::Handle(String::New("moo"));
75 const auto& error = cls.EnsureIsFinalized(thread);
77 Function& function_moo =
78 Function::Handle(cls.LookupStaticFunction(function_moo_name));
80 EXPECT(function_moo.HasCode());
81
82 String& function_foo_name = String::Handle(String::New("foo"));
83 Function& function_foo =
84 Function::Handle(cls.LookupStaticFunction(function_foo_name));
86 EXPECT(function_foo.HasCode());
87
88 // Build and setup a stackmap for the call to 'func' in 'A.foo' in order
89 // to test the traversal of stack maps when a GC happens.
90 BitmapBuilder* stack_bitmap = new BitmapBuilder();
91 EXPECT(stack_bitmap != nullptr);
92 stack_bitmap->Set(0, false); // var i.
93 stack_bitmap->Set(1, true); // var s1.
94 stack_bitmap->Set(2, false); // var k.
95 stack_bitmap->Set(3, true); // var s2.
96 stack_bitmap->Set(4, true); // var s3.
97 const Code& code = Code::Handle(function_foo.unoptimized_code());
98 // Search for the pc of the call to 'func'.
99 const PcDescriptors& descriptors =
100 PcDescriptors::Handle(code.pc_descriptors());
101 int call_count = 0;
102 PcDescriptors::Iterator iter(descriptors,
103 UntaggedPcDescriptors::kUnoptStaticCall);
104 CompressedStackMapsBuilder compressed_maps_builder(thread->zone());
105 while (iter.MoveNext()) {
106 compressed_maps_builder.AddEntry(iter.PcOffset(), stack_bitmap, 0);
107 ++call_count;
108 }
109 // We can't easily check that we put the stackmap at the correct pc, but
110 // we did if there was exactly one call seen.
111 EXPECT(call_count == 1);
112 const auto& compressed_maps =
113 CompressedStackMaps::Handle(compressed_maps_builder.Finalize());
114 code.set_compressed_stackmaps(compressed_maps);
115
116 // Now invoke 'A.moo' and it will trigger a GC when the native function
117 // is called, this should then cause the stack map of function 'A.foo'
118 // to be traversed and the appropriate objects visited.
120 DartEntry::InvokeFunction(function_foo, Object::empty_array()));
121 EXPECT(!result.IsError());
122}
123
124ISOLATE_UNIT_TEST_CASE(DescriptorList_TokenPositions) {
125 DescriptorList* descriptors = new DescriptorList(thread->zone());
126 ASSERT(descriptors != nullptr);
127 const int32_t token_positions[] = {
128 kMinInt32,
129 5,
130 13,
131 13,
132 13,
133 13,
134 31,
135 23,
136 23,
137 23,
138 33,
139 33,
140 5,
141 5,
144 };
145 const intptr_t num_token_positions = ARRAY_SIZE(token_positions);
146
147 for (intptr_t i = 0; i < num_token_positions; i++) {
148 const TokenPosition& tp = TokenPosition::Deserialize(token_positions[i]);
149 descriptors->AddDescriptor(UntaggedPcDescriptors::kRuntimeCall, 0, 0, tp, 0,
150 1);
151 }
152
153 const PcDescriptors& finalized_descriptors =
155
156 ASSERT(!finalized_descriptors.IsNull());
157 PcDescriptors::Iterator it(finalized_descriptors,
158 UntaggedPcDescriptors::kRuntimeCall);
159
160 intptr_t i = 0;
161 while (it.MoveNext()) {
162 const TokenPosition& tp = TokenPosition::Deserialize(token_positions[i]);
163 if (tp != it.TokenPos()) {
164 OS::PrintErr("[%" Pd "]: Expected: %s != %s\n", i, tp.ToCString(),
165 it.TokenPos().ToCString());
166 }
167 EXPECT(tp == it.TokenPos());
168 i++;
169 }
170}
171
172} // namespace dart
#define EXPECT(type, expectedAlignment, expectedSize)
void Set(intptr_t bit_offset, bool value)
Definition: bitmap.cc:44
static bool ProcessPendingClasses()
FunctionPtr LookupStaticFunction(const String &name) const
Definition: object.cc:6137
ErrorPtr EnsureIsFinalized(Thread *thread) const
Definition: object.cc:4924
static bool TestCompileFunction(const Function &function)
Definition: unit_test.cc:781
CompressedStackMapsPtr Finalize() const
void AddEntry(intptr_t pc_offset, BitmapBuilder *bitmap, intptr_t spill_slot_bit_count)
static ObjectPtr InvokeFunction(const Function &function, const Array &arguments)
Definition: dart_entry.cc:31
void AddDescriptor(UntaggedPcDescriptors::Kind kind, intptr_t pc_offset, intptr_t deopt_id, TokenPosition token_pos, intptr_t try_index, intptr_t yield_index)
PcDescriptorsPtr FinalizePcDescriptors(uword entry_point)
bool HasCode() const
Definition: object.cc:7936
CodePtr unoptimized_code() const
Definition: object.h:3185
void CollectAllGarbage(GCReason reason=GCReason::kFull, bool compact=false)
Definition: heap.cc:573
Heap * heap() const
Definition: isolate.h:296
static IsolateGroup * Current()
Definition: isolate.h:539
ClassPtr LookupClass(const String &name) const
Definition: object.cc:14105
static LibraryPtr LookupLibrary(Thread *thread, const String &url)
Definition: object.cc:14599
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
static ObjectPtr null()
Definition: object.h:433
bool IsNull() const
Definition: object.h:363
static Object & Handle()
Definition: object.h:407
TokenPosition TokenPos() const
Definition: object.h:6156
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition: object.cc:23698
static StringPtr New(Thread *thread, const char *cstr)
Definition: symbols.h:723
static Dart_Handle LoadTestScript(const char *script, Dart_NativeEntryResolver resolver, const char *lib_uri=RESOLVED_USER_TEST_URI, bool finalize=true, bool allow_compile_errors=false)
Definition: unit_test.cc:436
static const char * url()
Definition: unit_test.cc:185
static Thread * Current()
Definition: thread.h:362
static constexpr int32_t kMinSourcePos
const char * ToCString() const
static TokenPosition Deserialize(int32_t value)
static constexpr int32_t kMaxSourcePos
struct _Dart_Handle * Dart_Handle
Definition: dart_api.h:258
struct _Dart_NativeArguments * Dart_NativeArguments
Definition: dart_api.h:3019
void(* Dart_NativeFunction)(Dart_NativeArguments arguments)
Definition: dart_api.h:3207
#define ASSERT(E)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
GAsyncResult * result
int argument_count
Definition: fuchsia.cc:52
Definition: dart_vm.cc:33
const char *const name
static void NativeFunc(Dart_NativeArguments args)
constexpr int32_t kMinInt32
Definition: globals.h:482
ISOLATE_UNIT_TEST_CASE(StackAllocatedDestruction)
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args, int index)
static Dart_NativeFunction native_resolver(Dart_Handle name, int argument_count, bool *auto_setup_scope)
TEST_CASE(DirectoryCurrent)
DART_EXPORT Dart_Handle Dart_IntegerToInt64(Dart_Handle integer, int64_t *value)
#define Pd
Definition: globals.h:408
#define EXPECT_VALID(handle)
Definition: unit_test.h:643
#define ARRAY_SIZE(array)
Definition: globals.h:72