Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: runtime/vm/unit_test.cc

Issue 1965823002: Initial isolate reload support (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "vm/unit_test.h" 5 #include "vm/unit_test.h"
6 6
7 #include <stdio.h> 7 #include <stdio.h>
8 8
9 #include "bin/builtin.h" 9 #include "bin/builtin.h"
10 #include "bin/dartutils.h" 10 #include "bin/dartutils.h"
11 #include "bin/isolate_data.h" 11 #include "bin/isolate_data.h"
12 12
13 #include "platform/globals.h" 13 #include "platform/globals.h"
14 14
15 #include "vm/assembler.h" 15 #include "vm/assembler.h"
16 #include "vm/ast_printer.h" 16 #include "vm/ast_printer.h"
17 #include "vm/compiler.h" 17 #include "vm/compiler.h"
18 #include "vm/dart_api_impl.h" 18 #include "vm/dart_api_impl.h"
19 #include "vm/disassembler.h" 19 #include "vm/disassembler.h"
20 #include "vm/isolate_reload.h"
20 #include "vm/parser.h" 21 #include "vm/parser.h"
21 #include "vm/symbols.h" 22 #include "vm/symbols.h"
22 #include "vm/thread.h" 23 #include "vm/thread.h"
23 #include "vm/virtual_memory.h" 24 #include "vm/virtual_memory.h"
24 25
25 using dart::bin::Builtin; 26 using dart::bin::Builtin;
26 using dart::bin::DartUtils; 27 using dart::bin::DartUtils;
27 28
28 namespace dart { 29 namespace dart {
29 30
(...skipping 29 matching lines...) Expand all
59 OS::Print("Creation of isolate failed '%s'\n", err); 60 OS::Print("Creation of isolate failed '%s'\n", err);
60 free(err); 61 free(err);
61 } 62 }
62 EXPECT(isolate != NULL); 63 EXPECT(isolate != NULL);
63 return isolate; 64 return isolate;
64 } 65 }
65 66
66 67
67 static const char* kPackageScheme = "package:"; 68 static const char* kPackageScheme = "package:";
68 69
70
69 static bool IsPackageSchemeURL(const char* url_name) { 71 static bool IsPackageSchemeURL(const char* url_name) {
70 static const intptr_t kPackageSchemeLen = strlen(kPackageScheme); 72 static const intptr_t kPackageSchemeLen = strlen(kPackageScheme);
71 return (strncmp(url_name, kPackageScheme, kPackageSchemeLen) == 0); 73 return (strncmp(url_name, kPackageScheme, kPackageSchemeLen) == 0);
72 } 74 }
73 75
76
77 static bool IsImportableTestLib(const char* url_name) {
78 const char* kImportTestLibUri = "importable_test_lib";
79 static const intptr_t kImportTestLibUriLen = strlen(kImportTestLibUri);
80 return (strncmp(url_name, kImportTestLibUri, kImportTestLibUriLen) == 0);
81 }
82
83
84 static Dart_Handle ImportableTestLibSource() {
85 const char* kScript =
86 "importedFunc() => 'a';\n"
87 "importedIntFunc() => 4;\n"
88 "class ImportedMixin {\n"
89 " mixinFunc() => 'mixin';\n"
90 "}\n";
91 return DartUtils::NewString(kScript);
92 }
93
94
95 static bool IsIsolateReloadTestLib(const char* url_name) {
96 const char* kIsolateReloadTestLibUri = "isolate_reload_test_helper";
97 static const intptr_t kIsolateReloadTestLibUriLen =
98 strlen(kIsolateReloadTestLibUri);
99 return (strncmp(url_name,
100 kIsolateReloadTestLibUri,
101 kIsolateReloadTestLibUriLen) == 0);
102 }
103
104
105 #ifndef PRODUCT
106 static Dart_Handle IsolateReloadTestLibSource() {
107 // Special library with one function.
108 return DartUtils::NewString("void reloadTest() native 'Reload_Test';\n");
109 }
110
111
112 static void ReloadTest(Dart_NativeArguments native_args) {
113 DART_CHECK_VALID(TestCase::TriggerReload());
114 }
115
116
117 static Dart_NativeFunction IsolateReloadTestNativeResolver(
118 Dart_Handle name,
119 int num_of_arguments,
120 bool* auto_setup_scope) {
121 return ReloadTest;
122 }
123 #endif // !PRODUCT
124
125
74 static Dart_Handle ResolvePackageUri(const char* uri_chars) { 126 static Dart_Handle ResolvePackageUri(const char* uri_chars) {
75 const int kNumArgs = 1; 127 const int kNumArgs = 1;
76 Dart_Handle dart_args[kNumArgs]; 128 Dart_Handle dart_args[kNumArgs];
77 dart_args[0] = DartUtils::NewString(uri_chars); 129 dart_args[0] = DartUtils::NewString(uri_chars);
78 return Dart_Invoke(DartUtils::BuiltinLib(), 130 return Dart_Invoke(DartUtils::BuiltinLib(),
79 DartUtils::NewString("_filePathFromUri"), 131 DartUtils::NewString("_filePathFromUri"),
80 kNumArgs, 132 kNumArgs,
81 dart_args); 133 dart_args);
82 } 134 }
83 135
136
137 static ThreadLocalKey script_reload_key = kUnsetThreadLocalKey;
138
84 static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag, 139 static Dart_Handle LibraryTagHandler(Dart_LibraryTag tag,
85 Dart_Handle library, 140 Dart_Handle library,
86 Dart_Handle url) { 141 Dart_Handle url) {
142 if (tag == Dart_kScriptTag) {
143 // Reload request.
144 ASSERT(script_reload_key != kUnsetThreadLocalKey);
145 const char* script_source =
146 reinterpret_cast<const char*>(
147 OSThread::GetThreadLocal(script_reload_key));
148 ASSERT(script_source != NULL);
149 OSThread::SetThreadLocal(script_reload_key, NULL);
150 return Dart_LoadScript(url,
151 NewString(script_source),
152 0,
153 0);
154 }
87 if (!Dart_IsLibrary(library)) { 155 if (!Dart_IsLibrary(library)) {
88 return Dart_NewApiError("not a library"); 156 return Dart_NewApiError("not a library");
89 } 157 }
90 if (!Dart_IsString(url)) { 158 if (!Dart_IsString(url)) {
91 return Dart_NewApiError("url is not a string"); 159 return Dart_NewApiError("url is not a string");
92 } 160 }
93 const char* url_chars = NULL; 161 const char* url_chars = NULL;
94 Dart_Handle result = Dart_StringToCString(url, &url_chars); 162 Dart_Handle result = Dart_StringToCString(url, &url_chars);
95 if (Dart_IsError(result)) { 163 if (Dart_IsError(result)) {
96 return Dart_NewApiError("accessing url characters failed"); 164 return Dart_NewApiError("accessing url characters failed");
97 } 165 }
98 Dart_Handle library_url = Dart_LibraryUrl(library); 166 Dart_Handle library_url = Dart_LibraryUrl(library);
99 const char* library_url_string = NULL; 167 const char* library_url_string = NULL;
100 result = Dart_StringToCString(library_url, &library_url_string); 168 result = Dart_StringToCString(library_url, &library_url_string);
101 if (Dart_IsError(result)) { 169 if (Dart_IsError(result)) {
102 return result; 170 return result;
103 } 171 }
104 172
105 bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_chars); 173 bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_chars);
106 bool is_io_library = DartUtils::IsDartIOLibURL(library_url_string); 174 bool is_io_library = DartUtils::IsDartIOLibURL(library_url_string);
107 if (tag == Dart_kCanonicalizeUrl) { 175 if (tag == Dart_kCanonicalizeUrl) {
176 // Already canonicalized.
177 if (IsImportableTestLib(url_chars) || IsIsolateReloadTestLib(url_chars)) {
178 return url;
179 }
108 // If this is a Dart Scheme URL then it is not modified as it will be 180 // If this is a Dart Scheme URL then it is not modified as it will be
109 // handled by the VM internally. 181 // handled by the VM internally.
110 if (is_dart_scheme_url || is_io_library) { 182 if (is_dart_scheme_url || is_io_library) {
111 return url; 183 return url;
112 } 184 }
113 185
114 Dart_Handle library_url = Dart_LibraryUrl(library); 186 Dart_Handle library_url = Dart_LibraryUrl(library);
115 if (Dart_IsError(library_url)) { 187 if (Dart_IsError(library_url)) {
116 return library_url; 188 return library_url;
117 } 189 }
118 return DartUtils::ResolveUri(library_url, url); 190 return DartUtils::ResolveUri(library_url, url);
119 } 191 }
120 if (is_dart_scheme_url) { 192 if (is_dart_scheme_url) {
121 ASSERT(tag == Dart_kImportTag); 193 ASSERT(tag == Dart_kImportTag);
122 // Handle imports of other built-in libraries present in the SDK. 194 // Handle imports of other built-in libraries present in the SDK.
123 if (DartUtils::IsDartIOLibURL(url_chars)) { 195 if (DartUtils::IsDartIOLibURL(url_chars)) {
124 return Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary); 196 return Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
125 } else if (DartUtils::IsDartBuiltinLibURL(url_chars)) { 197 } else if (DartUtils::IsDartBuiltinLibURL(url_chars)) {
126 return Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary); 198 return Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
127 } else { 199 } else {
128 return DartUtils::NewError("Do not know how to load '%s'", url_chars); 200 return DartUtils::NewError("Do not know how to load '%s'", url_chars);
129 } 201 }
130 } 202 }
203 if (IsImportableTestLib(url_chars)) {
204 return Dart_LoadLibrary(url, ImportableTestLibSource(), 0, 0);
205 }
206 NOT_IN_PRODUCT(
207 if (IsIsolateReloadTestLib(url_chars)) {
208 Dart_Handle library =
209 Dart_LoadLibrary(url, IsolateReloadTestLibSource(), 0, 0);
210 DART_CHECK_VALID(library);
211 Dart_SetNativeResolver(library, IsolateReloadTestNativeResolver, 0);
212 return library;
213 })
131 if (is_io_library) { 214 if (is_io_library) {
132 ASSERT(tag == Dart_kSourceTag); 215 ASSERT(tag == Dart_kSourceTag);
133 return Dart_LoadSource(library, 216 return Dart_LoadSource(library,
134 url, 217 url,
135 Builtin::PartSource(Builtin::kIOLibrary, 218 Builtin::PartSource(Builtin::kIOLibrary,
136 url_chars), 219 url_chars),
137 0, 0); 220 0, 0);
138 } 221 }
139 if (IsPackageSchemeURL(url_chars)) { 222 if (IsPackageSchemeURL(url_chars)) {
140 Dart_Handle resolved_uri = ResolvePackageUri(url_chars); 223 Dart_Handle resolved_uri = ResolvePackageUri(url_chars);
(...skipping 29 matching lines...) Expand all
170 result = Dart_SetNativeResolver(lib, resolver, NULL); 253 result = Dart_SetNativeResolver(lib, resolver, NULL);
171 DART_CHECK_VALID(result); 254 DART_CHECK_VALID(result);
172 if (finalize_classes) { 255 if (finalize_classes) {
173 result = Dart_FinalizeLoading(false); 256 result = Dart_FinalizeLoading(false);
174 DART_CHECK_VALID(result); 257 DART_CHECK_VALID(result);
175 } 258 }
176 return lib; 259 return lib;
177 } 260 }
178 261
179 262
263 #ifndef PRODUCT
264
265
266 void TestCase::SetReloadTestScript(const char* script) {
267 if (script_reload_key == kUnsetThreadLocalKey) {
268 script_reload_key = OSThread::CreateThreadLocal();
269 }
270 ASSERT(script_reload_key != kUnsetThreadLocalKey);
271 ASSERT(OSThread::GetThreadLocal(script_reload_key) == 0);
272 // Store the new script in TLS.
273 OSThread::SetThreadLocal(script_reload_key, reinterpret_cast<uword>(script));
274 }
275
276
277 Dart_Handle TestCase::TriggerReload() {
278 Isolate* isolate = Isolate::Current();
279
280 {
281 TransitionNativeToVM transition(Thread::Current());
282 isolate->ReloadSources(/* test_mode = */ true);
283 }
284
285 return Dart_FinalizeLoading(false);
286 }
287
288
289 Dart_Handle TestCase::GetReloadErrorOrRootLibrary() {
290 Isolate* isolate = Isolate::Current();
291
292 if (isolate->reload_context() != NULL) {
293 // We should only have a reload context hanging around if an error occurred.
294 ASSERT(isolate->reload_context()->has_error());
295 // Return a handle to the error.
296 return Api::NewHandle(Thread::Current(),
297 isolate->reload_context()->error());
298 }
299 return Dart_RootLibrary();
300 }
301
302
303 Dart_Handle TestCase::ReloadTestScript(const char* script) {
304 SetReloadTestScript(script);
305
306 Dart_Handle result = TriggerReload();
307 if (Dart_IsError(result)) {
308 return result;
309 }
310
311 return GetReloadErrorOrRootLibrary();
312 }
313
314
315 #endif // !PRODUCT
316
317
180 Dart_Handle TestCase::LoadCoreTestScript(const char* script, 318 Dart_Handle TestCase::LoadCoreTestScript(const char* script,
181 Dart_NativeEntryResolver resolver) { 319 Dart_NativeEntryResolver resolver) {
182 return LoadTestScript(script, resolver, CORELIB_TEST_URI); 320 return LoadTestScript(script, resolver, CORELIB_TEST_URI);
183 } 321 }
184 322
185 323
186 Dart_Handle TestCase::lib() { 324 Dart_Handle TestCase::lib() {
187 Dart_Handle url = NewString(TestCase::url()); 325 Dart_Handle url = NewString(TestCase::url());
188 Dart_Handle lib = Dart_LookupLibrary(url); 326 Dart_Handle lib = Dart_LookupLibrary(url);
189 DART_CHECK_VALID(lib); 327 DART_CHECK_VALID(lib);
(...skipping 22 matching lines...) Expand all
212 Symbols::New(Thread::Current(), name_)); 350 Symbols::New(Thread::Current(), name_));
213 351
214 // We make a dummy script so that exception objects can be composed for 352 // We make a dummy script so that exception objects can be composed for
215 // assembler instructions that do runtime calls, in particular on DBC. 353 // assembler instructions that do runtime calls, in particular on DBC.
216 const char* kDummyScript = "assembler_test_dummy_function() {}"; 354 const char* kDummyScript = "assembler_test_dummy_function() {}";
217 const Script& script = Script::Handle(Script::New( 355 const Script& script = Script::Handle(Script::New(
218 function_name, 356 function_name,
219 String::Handle(String::New(kDummyScript)), 357 String::Handle(String::New(kDummyScript)),
220 RawScript::kSourceTag)); 358 RawScript::kSourceTag));
221 script.Tokenize(String::Handle()); 359 script.Tokenize(String::Handle());
222 360 const Library& lib = Library::Handle(Library::CoreLibrary());
223 const Class& cls = Class::ZoneHandle( 361 const Class& cls = Class::ZoneHandle(
224 Class::New(function_name, 362 Class::New(lib,
363 function_name,
225 script, 364 script,
226 TokenPosition::kMinSource)); 365 TokenPosition::kMinSource));
227 const Library& lib = Library::ZoneHandle(Library::New(function_name));
228 cls.set_library(lib);
229 Function& function = Function::ZoneHandle( 366 Function& function = Function::ZoneHandle(
230 Function::New(function_name, RawFunction::kRegularFunction, 367 Function::New(function_name, RawFunction::kRegularFunction,
231 true, false, false, false, false, cls, 368 true, false, false, false, false, cls,
232 TokenPosition::kMinSource)); 369 TokenPosition::kMinSource));
233 code_ = Code::FinalizeCode(function, assembler_); 370 code_ = Code::FinalizeCode(function, assembler_);
234 code_.set_owner(function); 371 code_.set_owner(function);
235 code_.set_exception_handlers(Object::empty_exception_handlers()); 372 code_.set_exception_handlers(Object::empty_exception_handlers());
236 if (FLAG_disassemble) { 373 if (FLAG_disassemble) {
237 OS::Print("Code for test '%s' {\n", name_); 374 OS::Print("Code for test '%s' {\n", name_);
238 const Instructions& instructions = 375 const Instructions& instructions =
239 Instructions::Handle(code_.instructions()); 376 Instructions::Handle(code_.instructions());
240 uword start = instructions.EntryPoint(); 377 uword start = instructions.EntryPoint();
241 Disassembler::Disassemble(start, start + assembler_->CodeSize()); 378 Disassembler::Disassemble(start, start + assembler_->CodeSize());
242 OS::Print("}\n"); 379 OS::Print("}\n");
243 } 380 }
244 } 381 }
245 382
246 383
247 CodeGenTest::CodeGenTest(const char* name) 384 CodeGenTest::CodeGenTest(const char* name)
248 : function_(Function::ZoneHandle()), 385 : function_(Function::ZoneHandle()),
249 node_sequence_(new SequenceNode(TokenPosition::kMinSource, 386 node_sequence_(new SequenceNode(TokenPosition::kMinSource,
250 new LocalScope(NULL, 0, 0))), 387 new LocalScope(NULL, 0, 0))),
251 default_parameter_values_(new ZoneGrowableArray<const Instance*> ()) { 388 default_parameter_values_(new ZoneGrowableArray<const Instance*> ()) {
252 ASSERT(name != NULL); 389 ASSERT(name != NULL);
253 const String& function_name = String::ZoneHandle( 390 const String& function_name = String::ZoneHandle(
254 Symbols::New(Thread::Current(), name)); 391 Symbols::New(Thread::Current(), name));
255 // Add function to a class and that class to the class dictionary so that 392 // Add function to a class and that class to the class dictionary so that
256 // frame walking can be used. 393 // frame walking can be used.
394 Library& lib = Library::Handle(Library::CoreLibrary());
257 const Class& cls = Class::ZoneHandle( 395 const Class& cls = Class::ZoneHandle(
258 Class::New(function_name, Script::Handle(), 396 Class::New(lib, function_name, Script::Handle(),
259 TokenPosition::kMinSource)); 397 TokenPosition::kMinSource));
260 function_ = Function::New( 398 function_ = Function::New(
261 function_name, RawFunction::kRegularFunction, 399 function_name, RawFunction::kRegularFunction,
262 true, false, false, false, false, cls, TokenPosition::kMinSource); 400 true, false, false, false, false, cls, TokenPosition::kMinSource);
263 function_.set_result_type(Type::Handle(Type::DynamicType())); 401 function_.set_result_type(Type::Handle(Type::DynamicType()));
264 const Array& functions = Array::Handle(Array::New(1)); 402 const Array& functions = Array::Handle(Array::New(1));
265 functions.SetAt(0, function_); 403 functions.SetAt(0, function_);
266 cls.SetFunctions(functions); 404 cls.SetFunctions(functions);
267 Library& lib = Library::Handle(Library::CoreLibrary());
268 lib.AddClass(cls); 405 lib.AddClass(cls);
269 } 406 }
270 407
271 408
272 void CodeGenTest::Compile() { 409 void CodeGenTest::Compile() {
273 if (function_.HasCode()) return; 410 if (function_.HasCode()) return;
274 ParsedFunction* parsed_function = 411 ParsedFunction* parsed_function =
275 new ParsedFunction(Thread::Current(), function_); 412 new ParsedFunction(Thread::Current(), function_);
276 parsed_function->SetNodeSequence(node_sequence_); 413 parsed_function->SetNodeSequence(node_sequence_);
277 parsed_function->set_instantiator(NULL); 414 parsed_function->set_instantiator(NULL);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 461 }
325 // Copy the remainder of in to out. 462 // Copy the remainder of in to out.
326 while (*in != '\0') { 463 while (*in != '\0') {
327 *out++ = *in++; 464 *out++ = *in++;
328 } 465 }
329 *out = '\0'; 466 *out = '\0';
330 } 467 }
331 468
332 469
333 } // namespace dart 470 } // namespace dart
OLDNEW
« runtime/vm/object.cc ('K') | « runtime/vm/unit_test.h ('k') | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698