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

Side by Side Diff: runtime/bin/loader.cc

Issue 2475523002: Reload native extensions when starting from a snapshot. (Closed)
Patch Set: Use temp directory for snapshot Created 4 years, 1 month 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) 2016, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2016, 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 5
6 #include "bin/loader.h" 6 #include "bin/loader.h"
7 7
8 #include "bin/builtin.h" 8 #include "bin/builtin.h"
9 #include "bin/dartutils.h" 9 #include "bin/dartutils.h"
10 #include "bin/extensions.h" 10 #include "bin/extensions.h"
11 #include "bin/file.h" 11 #include "bin/file.h"
12 #include "bin/lockers.h" 12 #include "bin/lockers.h"
13 #include "bin/utils.h" 13 #include "bin/utils.h"
14 #include "include/dart_tools_api.h"
14 15
15 namespace dart { 16 namespace dart {
16 namespace bin { 17 namespace bin {
17 18
18 // Development flag. 19 // Development flag.
19 static bool trace_loader = false; 20 static bool trace_loader = false;
20 // Keep in sync with loader.dart. 21 // Keep in sync with loader.dart.
21 static const intptr_t _Dart_kImportExtension = 9; 22 static const intptr_t _Dart_kImportExtension = 9;
22 23
23 Loader::Loader(IsolateData* isolate_data) 24 Loader::Loader(IsolateData* isolate_data)
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 intptr_t tag = result->tag; 355 intptr_t tag = result->tag;
355 356
356 // No touching. 357 // No touching.
357 result = NULL; 358 result = NULL;
358 359
359 // We must drop the lock here because the tag handler may be recursively 360 // We must drop the lock here because the tag handler may be recursively
360 // invoked and it will attempt to acquire the lock to queue more work. 361 // invoked and it will attempt to acquire the lock to queue more work.
361 loader->monitor_->Exit(); 362 loader->monitor_->Exit();
362 363
363 Dart_Handle dart_result = Dart_Null(); 364 Dart_Handle dart_result = Dart_Null();
365 bool reload_extensions = false;
364 366
365 switch (tag) { 367 switch (tag) {
366 case Dart_kImportTag: 368 case Dart_kImportTag:
367 dart_result = Dart_LoadLibrary(uri, resolved_uri, source, 0, 0); 369 dart_result = Dart_LoadLibrary(uri, resolved_uri, source, 0, 0);
368 break; 370 break;
369 case Dart_kSourceTag: { 371 case Dart_kSourceTag: {
370 ASSERT(library_uri != Dart_Null()); 372 ASSERT(library_uri != Dart_Null());
371 Dart_Handle library = Dart_LookupLibrary(library_uri); 373 Dart_Handle library = Dart_LookupLibrary(library_uri);
372 ASSERT(!Dart_IsError(library)); 374 ASSERT(!Dart_IsError(library));
373 dart_result = Dart_LoadSource(library, uri, resolved_uri, source, 0, 0); 375 dart_result = Dart_LoadSource(library, uri, resolved_uri, source, 0, 0);
374 } 376 }
375 break; 377 break;
376 case Dart_kScriptTag: 378 case Dart_kScriptTag:
377 if (payload_type == DartUtils::kSnapshotMagicNumber) { 379 if (payload_type == DartUtils::kSnapshotMagicNumber) {
378 dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length); 380 dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length);
381 reload_extensions = true;
379 } else if (payload_type == DartUtils::kKernelMagicNumber) { 382 } else if (payload_type == DartUtils::kKernelMagicNumber) {
380 dart_result = Dart_LoadKernel(payload, payload_length); 383 dart_result = Dart_LoadKernel(payload, payload_length);
381 } else { 384 } else {
382 dart_result = Dart_LoadScript(uri, resolved_uri, source, 0, 0); 385 dart_result = Dart_LoadScript(uri, resolved_uri, source, 0, 0);
383 } 386 }
384 break; 387 break;
385 default: 388 default:
386 UNREACHABLE(); 389 UNREACHABLE();
387 } 390 }
388 391
389 // Re-acquire the lock before exiting the function (it was held before entry), 392 // Re-acquire the lock before exiting the function (it was held before entry),
390 loader->monitor_->Enter(); 393 loader->monitor_->Enter();
391 if (Dart_IsError(dart_result)) { 394 if (Dart_IsError(dart_result)) {
392 // Remember the error if we encountered one. 395 // Remember the error if we encountered one.
393 loader->error_ = dart_result; 396 loader->error_ = dart_result;
394 return false; 397 return false;
395 } 398 }
396 399
400 if (reload_extensions) {
401 dart_result = ReloadNativeExtensions();
402 if (Dart_IsError(dart_result)) {
403 // Remember the error if we encountered one.
404 loader->error_ = dart_result;
405 return false;
406 }
407 }
408
397 return true; 409 return true;
398 } 410 }
399 411
400 412
401 bool Loader::ProcessUrlLoadResultLocked(Loader* loader, 413 bool Loader::ProcessUrlLoadResultLocked(Loader* loader,
402 Loader::IOResult* result) { 414 Loader::IOResult* result) {
403 // A negative result tag indicates a loading error occurred in the service 415 // A negative result tag indicates a loading error occurred in the service
404 // isolate. The payload is a C string of the error message. 416 // isolate. The payload is a C string of the error message.
405 if (result->tag < 0) { 417 if (result->tag < 0) {
406 Dart_Handle error = Dart_NewStringFromUTF8(result->payload, 418 Dart_Handle error = Dart_NewStringFromUTF8(result->payload,
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 // Send the init message. 453 // Send the init message.
442 loader->Init(isolate_data->package_root, 454 loader->Init(isolate_data->package_root,
443 isolate_data->packages_file, 455 isolate_data->packages_file,
444 DartUtils::original_working_directory, 456 DartUtils::original_working_directory,
445 snapshot_uri); 457 snapshot_uri);
446 // Destroy the loader. The destructor does a bunch of leg work. 458 // Destroy the loader. The destructor does a bunch of leg work.
447 delete loader; 459 delete loader;
448 } 460 }
449 461
450 462
463 #define RETURN_ERROR(result) \
464 if (Dart_IsError(result)) return result;
465
466 Dart_Handle Loader::ReloadNativeExtensions() {
467 // For each library
468 Dart_Handle library_ids = Dart_GetLibraryIds();
469 RETURN_ERROR(library_ids);
470 intptr_t libraries_length = -1;
471 Dart_Handle result = Dart_ListLength(library_ids, &libraries_length);
472 RETURN_ERROR(result);
473 for (intptr_t i = 0; i < libraries_length; i++) {
474 int64_t library_id = -1;
475 result = Dart_IntegerToInt64(Dart_ListGetAt(library_ids, i),
476 &library_id);
siva 2016/11/02 23:48:38 You could use Dart_ListGetRange to extract the lib
477 RETURN_ERROR(result);
478 Dart_Handle import_ids = Dart_GetLibraryImports(library_id);
479 RETURN_ERROR(import_ids);
480 intptr_t imports_length = -1;
481 result = Dart_ListLength(import_ids, &imports_length);
482 RETURN_ERROR(result);
483
484 // For each import
485 for (intptr_t j = 1; j < imports_length; j += 2) {
486 int64_t import_id = -1;
487 result = Dart_IntegerToInt64(Dart_ListGetAt(import_ids, j),
488 &import_id);
siva 2016/11/02 23:48:38 Ditto comment about Dart_ListGetAt
489 RETURN_ERROR(result);
490 const char* extension_uri = NULL;
491 result = Dart_StringToCString(Dart_GetLibraryURL(import_id),
492 &extension_uri);
493 RETURN_ERROR(result);
494
495 // If import starts with dart-ext:
496 if (strncmp(extension_uri, "dart-ext:", 9) == 0) {
siva 2016/11/02 23:48:38 magic numbers 9 , 7 etc. use named constants.
Cutch 2016/11/03 17:45:34 Also, these schemes already exist: DartUtils::kDar
497 const char* extension_path = DartUtils::RemoveScheme(extension_uri);
498
499 Dart_Handle library = Dart_GetLibraryFromId(library_id);
500 RETURN_ERROR(library);
501 const char* lib_uri = NULL;
502 result = Dart_StringToCString(Dart_GetLibraryURL(library_id),
503 &lib_uri);
504 RETURN_ERROR(result);
505
506 char* lib_path = NULL;
507 if (strncmp(lib_uri, "file://", 7) == 0) {
508 lib_path = DartUtils::RemoveFilename(
509 DartUtils::RemoveScheme(lib_uri));
510 } else {
511 lib_path = strdup(lib_uri);
512 }
513
514 result = Extensions::LoadExtension(lib_path,
515 extension_path,
516 library);
517 free(lib_path);
518 RETURN_ERROR(result);
519 }
520 }
521 }
siva 2016/11/02 23:48:38 This seems like an expensive loop we have to run t
Cutch 2016/11/03 17:45:34 I agree with the spirit, but, extensions are techn
siva 2016/11/03 17:53:01 Agree, maybe the API could be something like Dart_
522
523 return Dart_True();
524 }
525
526
451 Dart_Handle Loader::LoadUrlContents(Dart_Handle url, 527 Dart_Handle Loader::LoadUrlContents(Dart_Handle url,
452 uint8_t** payload, 528 uint8_t** payload,
453 intptr_t* payload_length) { 529 intptr_t* payload_length) {
454 IsolateData* isolate_data = 530 IsolateData* isolate_data =
455 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData()); 531 reinterpret_cast<IsolateData*>(Dart_CurrentIsolateData());
456 ASSERT(isolate_data != NULL); 532 ASSERT(isolate_data != NULL);
457 ASSERT(!isolate_data->HasLoader()); 533 ASSERT(!isolate_data->HasLoader());
458 Loader* loader = NULL; 534 Loader* loader = NULL;
459 535
460 // Setup the loader. The constructor does a bunch of leg work. 536 // Setup the loader. The constructor does a bunch of leg work.
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 MutexLocker ml(loader_infos_lock_); 831 MutexLocker ml(loader_infos_lock_);
756 Loader* loader = LoaderForLocked(dest_port_id); 832 Loader* loader = LoaderForLocked(dest_port_id);
757 if (loader == NULL) { 833 if (loader == NULL) {
758 return; 834 return;
759 } 835 }
760 loader->QueueMessage(message); 836 loader->QueueMessage(message);
761 } 837 }
762 838
763 } // namespace bin 839 } // namespace bin
764 } // namespace dart 840 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698