Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
compiler_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
6#include "platform/assert.h"
8#include "vm/code_patcher.h"
9#include "vm/dart_api_impl.h"
10#include "vm/heap/safepoint.h"
11#include "vm/kernel_isolate.h"
12#include "vm/object.h"
13#include "vm/symbols.h"
14#include "vm/thread_pool.h"
15#include "vm/unit_test.h"
16
17namespace dart {
18
19ISOLATE_UNIT_TEST_CASE(CompileFunction) {
20 const char* kScriptChars =
21 "class A {\n"
22 " static foo() { return 42; }\n"
23 " static moo() {\n"
24 " // A.foo();\n"
25 " }\n"
26 "}\n";
27 Dart_Handle library;
28 {
29 TransitionVMToNative transition(thread);
30 library = TestCase::LoadTestScript(kScriptChars, nullptr);
31 }
32 const Library& lib =
35 Class& cls =
37 EXPECT(!cls.IsNull());
38 const auto& error = cls.EnsureIsFinalized(thread);
40 String& function_foo_name = String::Handle(String::New("foo"));
41 Function& function_foo =
42 Function::Handle(cls.LookupStaticFunction(function_foo_name));
43 EXPECT(!function_foo.IsNull());
44 String& function_source = String::Handle(function_foo.GetSource());
45 EXPECT_STREQ("static foo() { return 42; }", function_source.ToCString());
47 EXPECT(function_foo.HasCode());
48
49 String& function_moo_name = String::Handle(String::New("moo"));
50 Function& function_moo =
51 Function::Handle(cls.LookupStaticFunction(function_moo_name));
52 EXPECT(!function_moo.IsNull());
53
55 EXPECT(function_moo.HasCode());
56 function_source = function_moo.GetSource();
57 EXPECT_STREQ("static moo() {\n // A.foo();\n }",
58 function_source.ToCString());
59}
60
61ISOLATE_UNIT_TEST_CASE(OptimizeCompileFunctionOnHelperThread) {
62 // Create a simple function and compile it without optimization.
63 const char* kScriptChars =
64 "class A {\n"
65 " static foo() { return 42; }\n"
66 "}\n";
67 Dart_Handle library;
68 {
69 TransitionVMToNative transition(thread);
70 library = TestCase::LoadTestScript(kScriptChars, nullptr);
71 }
72 const Library& lib =
75 Class& cls =
77 EXPECT(!cls.IsNull());
78 String& function_foo_name = String::Handle(String::New("foo"));
79 const auto& error = cls.EnsureIsFinalized(thread);
81 Function& func =
82 Function::Handle(cls.LookupStaticFunction(function_foo_name));
83 EXPECT(!func.HasCode());
85 EXPECT(func.HasCode());
86 EXPECT(!func.HasOptimizedCode());
87#if !defined(PRODUCT)
88 // Constant in product mode.
89 FLAG_background_compilation = true;
90#endif
91 auto isolate_group = thread->isolate_group();
92 isolate_group->background_compiler()->EnqueueCompilation(func);
93 Monitor* m = new Monitor();
94 {
96 while (!func.HasOptimizedCode()) {
97 ml.Wait(1);
98 }
99 }
100 delete m;
101}
102
103ISOLATE_UNIT_TEST_CASE(CompileFunctionOnHelperThread) {
104 // Create a simple function and compile it without optimization.
105 const char* kScriptChars =
106 "class A {\n"
107 " static foo() { return 42; }\n"
108 "}\n";
109 Dart_Handle library;
110 {
111 TransitionVMToNative transition(thread);
112 library = TestCase::LoadTestScript(kScriptChars, nullptr);
113 }
114 const Library& lib =
117 Class& cls =
119 EXPECT(!cls.IsNull());
120 const auto& error = cls.EnsureIsFinalized(thread);
122 String& function_foo_name = String::Handle(String::New("foo"));
123 Function& func =
124 Function::Handle(cls.LookupStaticFunction(function_foo_name));
125 EXPECT(!func.HasCode());
127 EXPECT(func.HasCode());
128}
129
130ISOLATE_UNIT_TEST_CASE(RegenerateAllocStubs) {
131 const char* kScriptChars =
132 "class A {\n"
133 "}\n"
134 "unOpt() => new A(); \n"
135 "optIt() => new A(); \n"
136 "A main() {\n"
137 " return unOpt();\n"
138 "}\n";
139
140 Class& cls = Class::Handle();
141 TransitionVMToNative transition(thread);
142
143 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
144 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, nullptr);
146
147 {
148 TransitionNativeToVM transition(thread);
149 Library& lib_handle =
151 cls = lib_handle.LookupClass(String::Handle(Symbols::New(thread, "A")));
152 EXPECT(!cls.IsNull());
153 }
154
155 {
156 TransitionNativeToVM transition(thread);
158 }
159 result = Dart_Invoke(lib, NewString("main"), 0, nullptr);
161
162 {
163 TransitionNativeToVM transition(thread);
165 }
166 result = Dart_Invoke(lib, NewString("main"), 0, nullptr);
168
169 {
170 TransitionNativeToVM transition(thread);
172 }
173 result = Dart_Invoke(lib, NewString("main"), 0, nullptr);
175}
176
177TEST_CASE(EvalExpression) {
178 const char* kScriptChars =
179 "int ten = 2 * 5; \n"
180 "get dot => '.'; \n"
181 "class A { \n"
182 " var apa = 'Herr Nilsson'; \n"
183 " calc(x) => '${x*ten}'; \n"
184 "} \n"
185 "makeObj() => new A(); \n";
186
187 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, nullptr);
188 Dart_Handle obj_handle =
189 Dart_Invoke(lib, Dart_NewStringFromCString("makeObj"), 0, nullptr);
190 EXPECT_VALID(obj_handle);
191 TransitionNativeToVM transition(thread);
192 const Object& obj = Object::Handle(Api::UnwrapHandle(obj_handle));
193 EXPECT(!obj.IsNull());
194 EXPECT(obj.IsInstance());
195
196 String& expr_text = String::Handle();
197 expr_text = String::New("apa + ' ${calc(10)}' + dot");
198 Object& val = Object::Handle();
199 const Class& receiver_cls = Class::Handle(obj.clazz());
200
202 UNREACHABLE();
203 } else {
204 LibraryPtr raw_library = Library::RawCast(Api::UnwrapHandle(lib));
205 Library& lib_handle = Library::ZoneHandle(raw_library);
206
207 Dart_KernelCompilationResult compilation_result =
209 /*platform_kernel=*/nullptr, /*platform_kernel_size=*/0,
210 expr_text.ToCString(), Array::empty_array(), Array::empty_array(),
211 Array::empty_array(), Array::empty_array(), Array::empty_array(),
212 String::Handle(lib_handle.url()).ToCString(), "A",
213 /* method= */ nullptr,
214 /* token_pos= */ TokenPosition::kNoSource,
215 /* script_uri= */ String::Handle(lib_handle.url()).ToCString(),
216 /* is_static= */ false);
217 EXPECT_EQ(Dart_KernelCompilationStatus_Ok, compilation_result.status);
218
219 const ExternalTypedData& kernel_buffer =
221 const_cast<uint8_t*>(compilation_result.kernel),
222 compilation_result.kernel_size));
223
224 val = Instance::Cast(obj).EvaluateCompiledExpression(
225 receiver_cls, kernel_buffer, Array::empty_array(), Array::empty_array(),
226 TypeArguments::null_type_arguments());
227 }
228 EXPECT(!val.IsNull());
229 EXPECT(!val.IsError());
230 EXPECT(val.IsString());
231 EXPECT_STREQ("Herr Nilsson 100.", val.ToCString());
232}
233
234ISOLATE_UNIT_TEST_CASE(EvalExpressionWithLazyCompile) {
235 { // Initialize an incremental compiler in DFE mode.
236 TransitionVMToNative transition(thread);
237 TestCase::LoadTestScript("", nullptr);
238 }
240 const String& expression = String::Handle(
241 String::New("(){ return (){ return (){ return 3 + 4; }(); }(); }()"));
242 Object& val = Object::Handle();
243 val = Api::UnwrapHandle(
244 TestCase::EvaluateExpression(lib, expression,
245 /* param_names= */ Array::empty_array(),
246 /* param_values= */ Array::empty_array()));
247
248 EXPECT(!val.IsNull());
249 EXPECT(!val.IsError());
250 EXPECT(val.IsInteger());
251 EXPECT_EQ(7, Integer::Cast(val).AsInt64Value());
252}
253
254ISOLATE_UNIT_TEST_CASE(EvalExpressionExhaustCIDs) {
255 { // Initialize an incremental compiler in DFE mode.
256 TransitionVMToNative transition(thread);
257 TestCase::LoadTestScript("", nullptr);
258 }
260 const String& expression = String::Handle(String::New("3 + 4"));
261 Object& val = Object::Handle();
262 val = Api::UnwrapHandle(
263 TestCase::EvaluateExpression(lib, expression,
264 /* param_names= */ Array::empty_array(),
265 /* param_values= */ Array::empty_array()));
266
267 EXPECT(!val.IsNull());
268 EXPECT(!val.IsError());
269 EXPECT(val.IsInteger());
270 EXPECT_EQ(7, Integer::Cast(val).AsInt64Value());
271
272 auto class_table = IsolateGroup::Current()->class_table();
273
274 intptr_t initial_class_table_size = class_table->NumCids();
275
276 val = Api::UnwrapHandle(
277 TestCase::EvaluateExpression(lib, expression,
278 /* param_names= */ Array::empty_array(),
279 /* param_values= */ Array::empty_array()));
280 EXPECT(!val.IsNull());
281 EXPECT(!val.IsError());
282 EXPECT(val.IsInteger());
283 EXPECT_EQ(7, Integer::Cast(val).AsInt64Value());
284
285 intptr_t final_class_table_size = class_table->NumCids();
286 // Eval should not eat into this non-renewable resource.
287 EXPECT_EQ(initial_class_table_size, final_class_table_size);
288}
289
290// Too slow in debug mode.
291#if !defined(DEBUG) && !defined(TARGET_USES_THREAD_SANITIZER)
292TEST_CASE(ManyClasses) {
293 // Limit is 20 bits. Check only more than 16 bits so test completes in
294 // reasonable time.
295 const intptr_t kNumClasses = (1 << 16) + 1;
296
298 for (intptr_t i = 0; i < kNumClasses; i++) {
299 buffer.Printf("class C%" Pd " { String toString() => 'C%" Pd "'; }\n", i,
300 i);
301 }
302 buffer.Printf("main() {\n");
303 for (intptr_t i = 0; i < kNumClasses; i++) {
304 buffer.Printf(" new C%" Pd "().toString();\n", i);
305 }
306 buffer.Printf("}\n");
307
308 Dart_Handle lib = TestCase::LoadTestScript(buffer.buffer(), nullptr);
309 EXPECT_VALID(lib);
310 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, nullptr);
312
313 EXPECT(IsolateGroup::Current()->class_table()->NumCids() >= kNumClasses);
314}
315#endif // !defined(DEBUG) && !defined(TARGET_USES_THREAD_SANITIZER)
316
317} // namespace dart
#define EXPECT(type, expectedAlignment, expectedSize)
#define UNREACHABLE()
Definition assert.h:248
static ObjectPtr UnwrapHandle(Dart_Handle object)
static bool ProcessPendingClasses()
intptr_t NumCids() const
FunctionPtr LookupStaticFunction(const String &name) const
Definition object.cc:6192
void DisableAllocationStub() const
Definition object.cc:5934
ErrorPtr EnsureIsFinalized(Thread *thread) const
Definition object.cc:4979
static bool TestCompileFunction(const Function &function)
Definition unit_test.cc:767
static ExternalTypedDataPtr NewFinalizeWithFree(uint8_t *data, intptr_t len)
Definition object.cc:25728
StringPtr GetSource() const
Definition object.cc:11177
bool HasCode() const
Definition object.cc:7994
bool HasOptimizedCode() const
Definition object.cc:11032
static IsolateGroup * Current()
Definition isolate.h:534
ClassTable * class_table() const
Definition isolate.h:491
static bool IsRunning()
static Dart_KernelCompilationResult CompileExpressionToKernel(const uint8_t *platform_kernel, intptr_t platform_kernel_size, const char *expression, const Array &definitions, const Array &definition_types, const Array &type_definitions, const Array &type_bounds, const Array &type_defaults, const char *library_url, const char *klass, const char *method, TokenPosition token_pos, char const *script_uri, bool is_static)
static LibraryPtr CoreLibrary()
Definition object.cc:14834
ClassPtr LookupClass(const String &name) const
Definition object.cc:14152
StringPtr url() const
Definition object.h:5068
static ObjectPtr null()
Definition object.h:433
virtual const char * ToCString() const
Definition object.h:366
bool IsNull() const
Definition object.h:363
static Object & Handle()
Definition object.h:407
static ObjectPtr RawCast(ObjectPtr obj)
Definition object.h:325
static Object & ZoneHandle()
Definition object.h:419
ClassPtr clazz() const
Definition object.h:13192
Monitor::WaitResult Wait(int64_t millis=Monitor::kNoTimeout)
Definition lockers.cc:77
static StringPtr New(const char *cstr, Heap::Space space=Heap::kNew)
Definition object.cc:23777
static const char * ToCString(Thread *thread, StringPtr ptr)
Definition object.cc:24205
static StringPtr New(Thread *thread, const char *cstr)
Definition symbols.h:722
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:422
static Dart_Handle EvaluateExpression(const Library &lib, const String &expr, const Array &param_names, const Array &param_values)
Definition unit_test.cc:646
@ Dart_KernelCompilationStatus_Ok
Definition dart_api.h:3728
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
static const uint8_t buffer[]
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
constexpr intptr_t MB
Definition globals.h:530
DART_EXPORT Dart_Handle Dart_Invoke(Dart_Handle target, Dart_Handle name, int number_of_arguments, Dart_Handle *arguments)
Dart_Handle NewString(const char *str)
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
#define Pd
Definition globals.h:408
Dart_KernelCompilationStatus status
Definition dart_api.h:3735
#define ISOLATE_UNIT_TEST_CASE(name)
Definition unit_test.h:64
#define TEST_CASE(name)
Definition unit_test.h:85
#define EXPECT_VALID(handle)
Definition unit_test.h:650