OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "platform/assert.h" | 5 #include "platform/assert.h" |
6 #include "vm/class_finalizer.h" | 6 #include "vm/class_finalizer.h" |
7 #include "vm/code_patcher.h" | 7 #include "vm/code_patcher.h" |
8 #include "vm/compiler.h" | 8 #include "vm/compiler.h" |
9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
10 #include "vm/object.h" | 10 #include "vm/object.h" |
11 #include "vm/safepoint.h" | 11 #include "vm/safepoint.h" |
12 #include "vm/symbols.h" | 12 #include "vm/symbols.h" |
13 #include "vm/thread_pool.h" | 13 #include "vm/thread_pool.h" |
14 #include "vm/unit_test.h" | 14 #include "vm/unit_test.h" |
15 | 15 |
16 namespace dart { | 16 namespace dart { |
17 | 17 |
18 VM_TEST_CASE(CompileScript) { | 18 VM_TEST_CASE(CompileScript) { |
19 const char* kScriptChars = | 19 const char* kScriptChars = |
20 "class A {\n" | 20 "class A {\n" |
21 " static foo() { return 42; }\n" | 21 " static foo() { return 42; }\n" |
22 "}\n"; | 22 "}\n"; |
23 String& url = String::Handle(String::New("dart-test:CompileScript")); | 23 String& url = String::Handle(String::New("dart-test:CompileScript")); |
24 String& source = String::Handle(String::New(kScriptChars)); | 24 String& source = String::Handle(String::New(kScriptChars)); |
25 Script& script = Script::Handle(Script::New(url, | 25 Script& script = |
26 source, | 26 Script::Handle(Script::New(url, source, RawScript::kScriptTag)); |
27 RawScript::kScriptTag)); | |
28 Library& lib = Library::Handle(Library::CoreLibrary()); | 27 Library& lib = Library::Handle(Library::CoreLibrary()); |
29 EXPECT(CompilerTest::TestCompileScript(lib, script)); | 28 EXPECT(CompilerTest::TestCompileScript(lib, script)); |
30 } | 29 } |
31 | 30 |
32 | 31 |
33 VM_TEST_CASE(CompileFunction) { | 32 VM_TEST_CASE(CompileFunction) { |
34 const char* kScriptChars = | 33 const char* kScriptChars = |
35 "class A {\n" | 34 "class A {\n" |
36 " static foo() { return 42; }\n" | 35 " static foo() { return 42; }\n" |
37 " static moo() {\n" | 36 " static moo() {\n" |
38 " // A.foo();\n" | 37 " // A.foo();\n" |
39 " }\n" | 38 " }\n" |
40 "}\n"; | 39 "}\n"; |
41 String& url = String::Handle(String::New("dart-test:CompileFunction")); | 40 String& url = String::Handle(String::New("dart-test:CompileFunction")); |
42 String& source = String::Handle(String::New(kScriptChars)); | 41 String& source = String::Handle(String::New(kScriptChars)); |
43 Script& script = Script::Handle(Script::New(url, | 42 Script& script = |
44 source, | 43 Script::Handle(Script::New(url, source, RawScript::kScriptTag)); |
45 RawScript::kScriptTag)); | |
46 Library& lib = Library::Handle(Library::CoreLibrary()); | 44 Library& lib = Library::Handle(Library::CoreLibrary()); |
47 EXPECT(CompilerTest::TestCompileScript(lib, script)); | 45 EXPECT(CompilerTest::TestCompileScript(lib, script)); |
48 EXPECT(ClassFinalizer::ProcessPendingClasses()); | 46 EXPECT(ClassFinalizer::ProcessPendingClasses()); |
49 Class& cls = Class::Handle( | 47 Class& cls = |
50 lib.LookupClass(String::Handle(Symbols::New(thread, "A")))); | 48 Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "A")))); |
51 EXPECT(!cls.IsNull()); | 49 EXPECT(!cls.IsNull()); |
52 String& function_foo_name = String::Handle(String::New("foo")); | 50 String& function_foo_name = String::Handle(String::New("foo")); |
53 Function& function_foo = | 51 Function& function_foo = |
54 Function::Handle(cls.LookupStaticFunction(function_foo_name)); | 52 Function::Handle(cls.LookupStaticFunction(function_foo_name)); |
55 EXPECT(!function_foo.IsNull()); | 53 EXPECT(!function_foo.IsNull()); |
56 String& function_source = String::Handle(function_foo.GetSource()); | 54 String& function_source = String::Handle(function_foo.GetSource()); |
57 EXPECT_STREQ("static foo() { return 42; }", function_source.ToCString()); | 55 EXPECT_STREQ("static foo() { return 42; }", function_source.ToCString()); |
58 EXPECT(CompilerTest::TestCompileFunction(function_foo)); | 56 EXPECT(CompilerTest::TestCompileFunction(function_foo)); |
59 EXPECT(function_foo.HasCode()); | 57 EXPECT(function_foo.HasCode()); |
60 | 58 |
61 String& function_moo_name = String::Handle(String::New("moo")); | 59 String& function_moo_name = String::Handle(String::New("moo")); |
62 Function& function_moo = | 60 Function& function_moo = |
63 Function::Handle(cls.LookupStaticFunction(function_moo_name)); | 61 Function::Handle(cls.LookupStaticFunction(function_moo_name)); |
64 EXPECT(!function_moo.IsNull()); | 62 EXPECT(!function_moo.IsNull()); |
65 | 63 |
66 EXPECT(CompilerTest::TestCompileFunction(function_moo)); | 64 EXPECT(CompilerTest::TestCompileFunction(function_moo)); |
67 EXPECT(function_moo.HasCode()); | 65 EXPECT(function_moo.HasCode()); |
68 function_source = function_moo.GetSource(); | 66 function_source = function_moo.GetSource(); |
69 EXPECT_STREQ("static moo() {\n // A.foo();\n }", | 67 EXPECT_STREQ("static moo() {\n // A.foo();\n }", |
70 function_source.ToCString()); | 68 function_source.ToCString()); |
71 } | 69 } |
72 | 70 |
73 | 71 |
74 VM_TEST_CASE(CompileFunctionOnHelperThread) { | 72 VM_TEST_CASE(CompileFunctionOnHelperThread) { |
75 // Create a simple function and compile it without optimization. | 73 // Create a simple function and compile it without optimization. |
76 const char* kScriptChars = | 74 const char* kScriptChars = |
77 "class A {\n" | 75 "class A {\n" |
78 " static foo() { return 42; }\n" | 76 " static foo() { return 42; }\n" |
79 "}\n"; | 77 "}\n"; |
80 String& url = | 78 String& url = |
81 String::Handle(String::New("dart-test:CompileFunctionOnHelperThread")); | 79 String::Handle(String::New("dart-test:CompileFunctionOnHelperThread")); |
82 String& source = String::Handle(String::New(kScriptChars)); | 80 String& source = String::Handle(String::New(kScriptChars)); |
83 Script& script = Script::Handle(Script::New(url, | 81 Script& script = |
84 source, | 82 Script::Handle(Script::New(url, source, RawScript::kScriptTag)); |
85 RawScript::kScriptTag)); | |
86 Library& lib = Library::Handle(Library::CoreLibrary()); | 83 Library& lib = Library::Handle(Library::CoreLibrary()); |
87 EXPECT(CompilerTest::TestCompileScript(lib, script)); | 84 EXPECT(CompilerTest::TestCompileScript(lib, script)); |
88 EXPECT(ClassFinalizer::ProcessPendingClasses()); | 85 EXPECT(ClassFinalizer::ProcessPendingClasses()); |
89 Class& cls = Class::Handle( | 86 Class& cls = |
90 lib.LookupClass(String::Handle(Symbols::New(thread, "A")))); | 87 Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "A")))); |
91 EXPECT(!cls.IsNull()); | 88 EXPECT(!cls.IsNull()); |
92 String& function_foo_name = String::Handle(String::New("foo")); | 89 String& function_foo_name = String::Handle(String::New("foo")); |
93 Function& func = | 90 Function& func = |
94 Function::Handle(cls.LookupStaticFunction(function_foo_name)); | 91 Function::Handle(cls.LookupStaticFunction(function_foo_name)); |
95 EXPECT(!func.HasCode()); | 92 EXPECT(!func.HasCode()); |
96 CompilerTest::TestCompileFunction(func); | 93 CompilerTest::TestCompileFunction(func); |
97 EXPECT(func.HasCode()); | 94 EXPECT(func.HasCode()); |
98 EXPECT(!func.HasOptimizedCode()); | 95 EXPECT(!func.HasOptimizedCode()); |
99 #if !defined(PRODUCT) | 96 #if !defined(PRODUCT) |
100 // Constant in product mode. | 97 // Constant in product mode. |
101 FLAG_background_compilation = true; | 98 FLAG_background_compilation = true; |
102 #endif | 99 #endif |
103 BackgroundCompiler::EnsureInit(thread); | 100 BackgroundCompiler::EnsureInit(thread); |
104 Isolate* isolate = thread->isolate(); | 101 Isolate* isolate = thread->isolate(); |
105 ASSERT(isolate->background_compiler() != NULL); | 102 ASSERT(isolate->background_compiler() != NULL); |
106 isolate->background_compiler()->CompileOptimized(func); | 103 isolate->background_compiler()->CompileOptimized(func); |
107 Monitor* m = new Monitor(); | 104 Monitor* m = new Monitor(); |
108 MonitorLocker ml(m); | 105 MonitorLocker ml(m); |
109 while (!func.HasOptimizedCode()) { | 106 while (!func.HasOptimizedCode()) { |
110 ml.WaitWithSafepointCheck(thread, 1); | 107 ml.WaitWithSafepointCheck(thread, 1); |
111 } | 108 } |
112 BackgroundCompiler::Stop(isolate); | 109 BackgroundCompiler::Stop(isolate); |
113 } | 110 } |
114 | 111 |
115 | 112 |
116 TEST_CASE(RegenerateAllocStubs) { | 113 TEST_CASE(RegenerateAllocStubs) { |
117 const char* kScriptChars = | 114 const char* kScriptChars = |
118 "class A {\n" | 115 "class A {\n" |
119 "}\n" | 116 "}\n" |
120 "unOpt() => new A(); \n" | 117 "unOpt() => new A(); \n" |
121 "optIt() => new A(); \n" | 118 "optIt() => new A(); \n" |
122 "A main() {\n" | 119 "A main() {\n" |
123 " return unOpt();\n" | 120 " return unOpt();\n" |
124 "}\n"; | 121 "}\n"; |
125 | 122 |
126 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 123 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
127 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 124 Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
128 EXPECT_VALID(result); | 125 EXPECT_VALID(result); |
129 RawLibrary* raw_library = Library::RawCast(Api::UnwrapHandle(lib)); | 126 RawLibrary* raw_library = Library::RawCast(Api::UnwrapHandle(lib)); |
130 Library& lib_handle = Library::ZoneHandle(raw_library); | 127 Library& lib_handle = Library::ZoneHandle(raw_library); |
131 Class& cls = Class::Handle( | 128 Class& cls = Class::Handle( |
132 lib_handle.LookupClass(String::Handle(Symbols::New(thread, "A")))); | 129 lib_handle.LookupClass(String::Handle(Symbols::New(thread, "A")))); |
133 EXPECT(!cls.IsNull()); | 130 EXPECT(!cls.IsNull()); |
134 | 131 |
135 Zone* zone = thread->zone(); | 132 Zone* zone = thread->zone(); |
136 const Code& stub = Code::Handle(zone, | 133 const Code& stub = |
137 StubCode::GetAllocationStubForClass(cls)); | 134 Code::Handle(zone, StubCode::GetAllocationStubForClass(cls)); |
138 Class& owner = Class::Handle(); | 135 Class& owner = Class::Handle(); |
139 owner ^= stub.owner(); | 136 owner ^= stub.owner(); |
140 owner.DisableAllocationStub(); | 137 owner.DisableAllocationStub(); |
141 result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 138 result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
142 EXPECT_VALID(result); | 139 EXPECT_VALID(result); |
143 | 140 |
144 owner.DisableAllocationStub(); | 141 owner.DisableAllocationStub(); |
145 result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 142 result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
146 EXPECT_VALID(result); | 143 EXPECT_VALID(result); |
147 | 144 |
148 owner.DisableAllocationStub(); | 145 owner.DisableAllocationStub(); |
149 result = Dart_Invoke(lib, NewString("main"), 0, NULL); | 146 result = Dart_Invoke(lib, NewString("main"), 0, NULL); |
150 EXPECT_VALID(result); | 147 EXPECT_VALID(result); |
151 } | 148 } |
152 | 149 |
153 | 150 |
154 TEST_CASE(EvalExpression) { | 151 TEST_CASE(EvalExpression) { |
155 const char* kScriptChars = | 152 const char* kScriptChars = |
156 "int ten = 2 * 5; \n" | 153 "int ten = 2 * 5; \n" |
157 "get dot => '.'; \n" | 154 "get dot => '.'; \n" |
158 "class A { \n" | 155 "class A { \n" |
159 " var apa = 'Herr Nilsson'; \n" | 156 " var apa = 'Herr Nilsson'; \n" |
160 " calc(x) => '${x*ten}'; \n" | 157 " calc(x) => '${x*ten}'; \n" |
161 "} \n" | 158 "} \n" |
162 "makeObj() => new A(); \n"; | 159 "makeObj() => new A(); \n"; |
163 | 160 |
164 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); | 161 Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL); |
165 Dart_Handle obj_handle = | 162 Dart_Handle obj_handle = |
166 Dart_Invoke(lib, Dart_NewStringFromCString("makeObj"), 0, NULL); | 163 Dart_Invoke(lib, Dart_NewStringFromCString("makeObj"), 0, NULL); |
167 EXPECT(!Dart_IsNull(obj_handle)); | 164 EXPECT(!Dart_IsNull(obj_handle)); |
168 EXPECT(!Dart_IsError(obj_handle)); | 165 EXPECT(!Dart_IsError(obj_handle)); |
169 TransitionNativeToVM transition(thread); | 166 TransitionNativeToVM transition(thread); |
170 const Object& obj = Object::Handle(Api::UnwrapHandle(obj_handle)); | 167 const Object& obj = Object::Handle(Api::UnwrapHandle(obj_handle)); |
171 EXPECT(!obj.IsNull()); | 168 EXPECT(!obj.IsNull()); |
172 EXPECT(obj.IsInstance()); | 169 EXPECT(obj.IsInstance()); |
173 | 170 |
174 String& expr_text = String::Handle(); | 171 String& expr_text = String::Handle(); |
175 expr_text = String::New("apa + ' ${calc(10)}' + dot"); | 172 expr_text = String::New("apa + ' ${calc(10)}' + dot"); |
176 Object& val = Object::Handle(); | 173 Object& val = Object::Handle(); |
177 const Class& receiver_cls = Class::Handle(obj.clazz()); | 174 const Class& receiver_cls = Class::Handle(obj.clazz()); |
178 val = Instance::Cast(obj).Evaluate(receiver_cls, | 175 val = Instance::Cast(obj).Evaluate( |
179 expr_text, | 176 receiver_cls, expr_text, Array::empty_array(), Array::empty_array()); |
180 Array::empty_array(), | |
181 Array::empty_array()); | |
182 EXPECT(!val.IsNull()); | 177 EXPECT(!val.IsNull()); |
183 EXPECT(!val.IsError()); | 178 EXPECT(!val.IsError()); |
184 EXPECT(val.IsString()); | 179 EXPECT(val.IsString()); |
185 EXPECT_STREQ("Herr Nilsson 100.", val.ToCString()); | 180 EXPECT_STREQ("Herr Nilsson 100.", val.ToCString()); |
186 } | 181 } |
187 | 182 |
188 | 183 |
189 VM_TEST_CASE(EvalExpressionWithLazyCompile) { | 184 VM_TEST_CASE(EvalExpressionWithLazyCompile) { |
190 Library& lib = Library::Handle(Library::CoreLibrary()); | 185 Library& lib = Library::Handle(Library::CoreLibrary()); |
191 | 186 |
192 const String& expression = String::Handle(String::New( | 187 const String& expression = String::Handle( |
193 "(){ return (){ return (){ return 3 + 4; }(); }(); }()")); | 188 String::New("(){ return (){ return (){ return 3 + 4; }(); }(); }()")); |
194 Object& val = Object::Handle(); | 189 Object& val = Object::Handle(); |
195 val = lib.Evaluate(expression, Array::empty_array(), Array::empty_array()); | 190 val = lib.Evaluate(expression, Array::empty_array(), Array::empty_array()); |
196 | 191 |
197 EXPECT(!val.IsNull()); | 192 EXPECT(!val.IsNull()); |
198 EXPECT(!val.IsError()); | 193 EXPECT(!val.IsError()); |
199 EXPECT(val.IsInteger()); | 194 EXPECT(val.IsInteger()); |
200 EXPECT_EQ(7, Integer::Cast(val).AsInt64Value()); | 195 EXPECT_EQ(7, Integer::Cast(val).AsInt64Value()); |
201 } | 196 } |
202 | 197 |
203 | 198 |
(...skipping 19 matching lines...) Expand all Loading... |
223 EXPECT(val.IsInteger()); | 218 EXPECT(val.IsInteger()); |
224 EXPECT_EQ(7, Integer::Cast(val).AsInt64Value()); | 219 EXPECT_EQ(7, Integer::Cast(val).AsInt64Value()); |
225 | 220 |
226 intptr_t final_class_table_size = | 221 intptr_t final_class_table_size = |
227 Isolate::Current()->class_table()->NumCids(); | 222 Isolate::Current()->class_table()->NumCids(); |
228 // Eval should not eat into this non-renewable resource. | 223 // Eval should not eat into this non-renewable resource. |
229 EXPECT_EQ(initial_class_table_size, final_class_table_size); | 224 EXPECT_EQ(initial_class_table_size, final_class_table_size); |
230 } | 225 } |
231 | 226 |
232 } // namespace dart | 227 } // namespace dart |
OLD | NEW |