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

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

Issue 584023004: Service isolate rework (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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/service.h" 5 #include "vm/service.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/globals.h" 8 #include "platform/globals.h"
9 9
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id)); 316 const SendPort& send_port = SendPort::Handle(SendPort::New(port_id));
317 const String& name = String::Handle(String::New(isolate->name())); 317 const String& name = String::Handle(String::New(isolate->name()));
318 ASSERT(!name.IsNull()); 318 ASSERT(!name.IsNull());
319 const Array& args = Array::Handle(Array::New(3)); 319 const Array& args = Array::Handle(Array::New(3));
320 ASSERT(!args.IsNull()); 320 ASSERT(!args.IsNull());
321 args.SetAt(0, port_int); 321 args.SetAt(0, port_int);
322 args.SetAt(1, send_port); 322 args.SetAt(1, send_port);
323 args.SetAt(2, name); 323 args.SetAt(2, name);
324 Object& r = Object::Handle(service_isolate_); 324 Object& r = Object::Handle(service_isolate_);
325 r = DartEntry::InvokeFunction(register_function_, args); 325 r = DartEntry::InvokeFunction(register_function_, args);
326 if (FLAG_trace_service) {
327 OS::Print("Isolate %s %" Pd64 " registered with service \n",
328 name.ToCString(),
329 port_id);
330 }
326 ASSERT(!r.IsError()); 331 ASSERT(!r.IsError());
327 } 332 }
328 333
329 private: 334 private:
330 Function& register_function_; 335 Function& register_function_;
331 Isolate* service_isolate_; 336 Isolate* service_isolate_;
332 }; 337 };
333 338
334 339
335 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) { 340 static Dart_Port ExtractPort(Isolate* isolate, Dart_Handle receivePort) {
336 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort); 341 const ReceivePort& rp = Api::UnwrapReceivePortHandle(isolate, receivePort);
337 if (rp.IsNull()) { 342 if (rp.IsNull()) {
338 return ILLEGAL_PORT; 343 return ILLEGAL_PORT;
339 } 344 }
340 return rp.Id(); 345 return rp.Id();
341 } 346 }
342 347
343 348
344 static void OnStart(Dart_NativeArguments args) { 349 static void OnStart(Dart_NativeArguments args) {
345 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args); 350 NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
346 Isolate* isolate = arguments->isolate(); 351 Isolate* isolate = arguments->isolate();
347 StackZone zone(isolate); 352 StackZone zone(isolate);
348 HANDLESCOPE(isolate); 353 HANDLESCOPE(isolate);
349 { 354 {
355 if (FLAG_trace_service) {
356 OS::Print("Booting dart:vmservice library\n");
357 }
350 // Boot the dart:vmservice library. 358 // Boot the dart:vmservice library.
351 Dart_EnterScope(); 359 Dart_EnterScope();
352 Dart_Handle url_str = 360 Dart_Handle url_str =
353 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId)); 361 Dart_NewStringFromCString(Symbols::Name(Symbols::kDartVMServiceId));
354 Dart_Handle library = Dart_LookupLibrary(url_str); 362 Dart_Handle library = Dart_LookupLibrary(url_str);
355 ASSERT(Dart_IsLibrary(library)); 363 ASSERT(Dart_IsLibrary(library));
356 Dart_Handle result = 364 Dart_Handle result =
357 Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL); 365 Dart_Invoke(library, Dart_NewStringFromCString("boot"), 0, NULL);
358 ASSERT(!Dart_IsError(result)); 366 ASSERT(!Dart_IsError(result));
359 Dart_Port port = ExtractPort(isolate, result); 367 Dart_Port port = ExtractPort(isolate, result);
360 ASSERT(port != ILLEGAL_PORT); 368 ASSERT(port != ILLEGAL_PORT);
361 Service::set_port(port); 369 Service::set_port(port);
362 Dart_ExitScope(); 370 Dart_ExitScope();
363 } 371 }
372
364 { 373 {
374 if (FLAG_trace_service) {
375 OS::Print("Registering running isolates\n");
376 }
365 // Register running isolates with service. 377 // Register running isolates with service.
366 RegisterRunningIsolatesVisitor register_isolates(isolate); 378 RegisterRunningIsolatesVisitor register_isolates(isolate);
367 Isolate::VisitIsolates(&register_isolates); 379 Isolate::VisitIsolates(&register_isolates);
368 } 380 }
369 } 381 }
370 382
371 383
372 struct VmServiceNativeEntry { 384 struct VmServiceNativeEntry {
373 const char* name; 385 const char* name;
374 int num_arguments; 386 int num_arguments;
(...skipping 29 matching lines...) Expand all
404 return entry.function; 416 return entry.function;
405 } 417 }
406 } 418 }
407 return NULL; 419 return NULL;
408 } 420 }
409 421
410 422
411 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL; 423 EmbedderServiceHandler* Service::isolate_service_handler_head_ = NULL;
412 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL; 424 EmbedderServiceHandler* Service::root_service_handler_head_ = NULL;
413 Isolate* Service::service_isolate_ = NULL; 425 Isolate* Service::service_isolate_ = NULL;
414 Dart_LibraryTagHandler Service::embedder_provided_handler_ = NULL;
415 Dart_Port Service::port_ = ILLEGAL_PORT; 426 Dart_Port Service::port_ = ILLEGAL_PORT;
416 uint32_t Service::event_mask_ = 0; 427 uint32_t Service::event_mask_ = 0;
417 428
418 Isolate* Service::GetServiceIsolate(void* callback_data) {
419 if (service_isolate_ != NULL) {
420 // Already initialized, return service isolate.
421 return service_isolate_;
422 }
423 Dart_ServiceIsolateCreateCalback create_callback =
424 Isolate::ServiceCreateCallback();
425 if (create_callback == NULL) {
426 return NULL;
427 }
428 Isolate::SetCurrent(NULL);
429 char* error = NULL;
430 Isolate* isolate =
431 reinterpret_cast<Isolate*>(create_callback(callback_data, &error));
432 if (isolate == NULL) {
433 return NULL;
434 }
435 StartIsolateScope isolate_scope(isolate);
436 {
437 // Install the dart:vmservice library.
438 StackZone zone(isolate);
439 HANDLESCOPE(isolate);
440 Library& library =
441 Library::Handle(isolate, isolate->object_store()->root_library());
442 // Isolate is empty.
443 ASSERT(library.IsNull());
444 // Grab embedder tag handler.
445 embedder_provided_handler_ = isolate->library_tag_handler();
446 // Temporarily install our own.
447 isolate->set_library_tag_handler(LibraryTagHandler);
448 // Get script resource.
449 const char* resource = NULL;
450 const char* path = "/vmservice.dart";
451 intptr_t r = Resources::ResourceLookup(path, &resource);
452 ASSERT(r != Resources::kNoSuchInstance);
453 ASSERT(resource != NULL);
454 const String& source_str = String::Handle(
455 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r));
456 ASSERT(!source_str.IsNull());
457 const String& url_str = String::Handle(Symbols::DartVMService().raw());
458 library ^= Library::LookupLibrary(url_str);
459 ASSERT(library.IsNull());
460 // Setup library.
461 library = Library::New(url_str);
462 library.Register();
463 const Script& script = Script::Handle(
464 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag));
465 library.SetLoadInProgress();
466 Dart_EnterScope(); // Need to enter scope for tag handler.
467 const Error& error = Error::Handle(isolate,
468 Compiler::Compile(library, script));
469 ASSERT(error.IsNull());
470 Dart_Handle result = Dart_FinalizeLoading(false);
471 ASSERT(!Dart_IsError(result));
472 Dart_ExitScope();
473
474 // Install embedder default library tag handler again.
475 isolate->set_library_tag_handler(embedder_provided_handler_);
476 embedder_provided_handler_ = NULL;
477 library.set_native_entry_resolver(VmServiceNativeResolver);
478 }
479 service_isolate_ = reinterpret_cast<Isolate*>(isolate);
480 return service_isolate_;
481 }
482
483
484 bool Service::SendIsolateStartupMessage() { 429 bool Service::SendIsolateStartupMessage() {
485 if (!IsRunning()) { 430 if (!IsRunning()) {
486 return false; 431 return false;
487 } 432 }
488 Isolate* isolate = Isolate::Current(); 433 Isolate* isolate = Isolate::Current();
489 ASSERT(isolate != NULL); 434 ASSERT(isolate != NULL);
490 HANDLESCOPE(isolate); 435 HANDLESCOPE(isolate);
491 const String& name = String::Handle(String::New(isolate->name())); 436 const String& name = String::Handle(String::New(isolate->name()));
492 ASSERT(!name.IsNull()); 437 ASSERT(!name.IsNull());
493 const Array& list = Array::Handle( 438 const Array& list = Array::Handle(
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 } 511 }
567 if (!Dart_IsString(url)) { 512 if (!Dart_IsString(url)) {
568 return Dart_NewApiError("url is not a string"); 513 return Dart_NewApiError("url is not a string");
569 } 514 }
570 const char* url_string = NULL; 515 const char* url_string = NULL;
571 Dart_Handle result = Dart_StringToCString(url, &url_string); 516 Dart_Handle result = Dart_StringToCString(url, &url_string);
572 if (Dart_IsError(result)) { 517 if (Dart_IsError(result)) {
573 return result; 518 return result;
574 } 519 }
575 if (tag == Dart_kImportTag) { 520 if (tag == Dart_kImportTag) {
576 // Embedder handles all requests for external libraries. 521 return Dart_NewApiError("Unable to import module as no library tag "
577 if (embedder_provided_handler_ == NULL) { 522 "is available");
578 return Dart_NewApiError("Unable to import module as no library tag "
579 "handler has been provided by embedder");
580 }
581 return embedder_provided_handler_(tag, library, url);
582 } 523 }
583 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl)); 524 ASSERT((tag == Dart_kSourceTag) || (tag == Dart_kCanonicalizeUrl));
584 if (tag == Dart_kCanonicalizeUrl) { 525 if (tag == Dart_kCanonicalizeUrl) {
585 // url is already canonicalized. 526 // url is already canonicalized.
586 return url; 527 return url;
587 } 528 }
588 Dart_Handle source = GetSource(url_string); 529 Dart_Handle source = GetSource(url_string);
589 if (Dart_IsError(source)) { 530 if (Dart_IsError(source)) {
590 return source; 531 return source;
591 } 532 }
592 return Dart_LoadSource(library, url, source, 0, 0); 533 return Dart_LoadSource(library, url, source, 0, 0);
593 } 534 }
594 535
595 536
537 void Service::MaybeInjectVMServiceLibrary(Isolate* isolate) {
538 if (service_isolate_ != NULL) {
539 // vm-service isolate already exists.
540 return;
541 }
542 const char* vm_service_prefix = "vm-service$main";
543 const intptr_t vm_service_prefix_len = strlen(vm_service_prefix);
544 if (strncmp(isolate->name(), vm_service_prefix, vm_service_prefix_len) != 0) {
545 // Not vm-service isolate.
546 return;
547 }
548 service_isolate_ = isolate;
549 ASSERT(isolate != NULL);
550 StackZone zone(isolate);
551 HANDLESCOPE(isolate);
552 Library& library =
553 Library::Handle(isolate, isolate->object_store()->root_library());
554 // Isolate is empty.
555 ASSERT(library.IsNull());
556 // Temporarily install our library tag handler.
557 isolate->set_library_tag_handler(LibraryTagHandler);
558 // Get script resource.
559 const char* resource = NULL;
560 const char* path = "/vmservice.dart";
561 intptr_t r = Resources::ResourceLookup(path, &resource);
562 ASSERT(r != Resources::kNoSuchInstance);
563 ASSERT(resource != NULL);
564 const String& source_str = String::Handle(
565 String::FromUTF8(reinterpret_cast<const uint8_t*>(resource), r));
566 ASSERT(!source_str.IsNull());
567 const String& url_str = String::Handle(Symbols::DartVMService().raw());
568 library ^= Library::LookupLibrary(url_str);
569 ASSERT(library.IsNull());
570 // Setup library.
571 library = Library::New(url_str);
572 library.Register();
573 const Script& script = Script::Handle(
574 isolate, Script::New(url_str, source_str, RawScript::kLibraryTag));
575 library.SetLoadInProgress();
576 Dart_EnterScope(); // Need to enter scope for tag handler.
577 const Error& error = Error::Handle(isolate,
578 Compiler::Compile(library, script));
579 ASSERT(error.IsNull());
580 Dart_Handle result = Dart_FinalizeLoading(false);
581 ASSERT(!Dart_IsError(result));
582 Dart_ExitScope();
583
584 // Uninstall our library tag handler.
585 isolate->set_library_tag_handler(NULL);
586 library.set_native_entry_resolver(VmServiceNativeResolver);
587 }
588
589
590 class RunServiceTask : public ThreadPool::Task {
591 public:
592 virtual void Run() {
593 ASSERT(Isolate::Current() == NULL);
594
595 Dart_IsolateCreateCallback create_callback = Isolate::CreateCallback();
596 if (create_callback == NULL) {
597 return;
598 }
599
600 char* error = NULL;
601 Isolate* isolate =
602 reinterpret_cast<Isolate*>(create_callback("vm-service",
603 NULL,
604 NULL,
605 &error));
606 if (isolate == NULL) {
607 printf("error: %s\n", error);
608 return;
609 }
610
611 ASSERT(Isolate::Current() == NULL);
612
613 // Quick hack to test invocation:
614 Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(isolate));
615 Dart_EnterScope();
616 Dart_Handle library = Dart_RootLibrary();
617 ASSERT(!Dart_IsError(library));
618 Dart_Handle function_name =
619 Dart_NewStringFromCString("main");
620 ASSERT(!Dart_IsError(function_name));
621 Dart_Handle result = Dart_Invoke(library, function_name, 0, NULL);
622 ASSERT(!Dart_IsError(result));
623
624 result = Dart_RunLoop();
625 if (Dart_IsError(result)) {
626 printf("Service exited with an error:\n%s\n", Dart_GetError(result));
627 }
628 Dart_ExitScope();
629 Dart_ExitIsolate();
630 }
631 };
632
633
634 void Service::RunService() {
635 Dart::thread_pool()->Run(new RunServiceTask());
636 }
637
596 // A handler for a per-isolate request. 638 // A handler for a per-isolate request.
597 // 639 //
598 // If a handler returns true, the reply is complete and ready to be 640 // If a handler returns true, the reply is complete and ready to be
599 // posted. If a handler returns false, then it is responsible for 641 // posted. If a handler returns false, then it is responsible for
600 // posting the reply (this can be used for asynchronous delegation of 642 // posting the reply (this can be used for asynchronous delegation of
601 // the response handling). 643 // the response handling).
602 typedef bool (*IsolateMessageHandler)(Isolate* isolate, JSONStream* stream); 644 typedef bool (*IsolateMessageHandler)(Isolate* isolate, JSONStream* stream);
603 645
604 struct IsolateMessageHandlerEntry { 646 struct IsolateMessageHandlerEntry {
605 const char* command; 647 const char* command;
(...skipping 2107 matching lines...) Expand 10 before | Expand all | Expand 10 after
2713 while (current != NULL) { 2755 while (current != NULL) {
2714 if (strcmp(name, current->name()) == 0) { 2756 if (strcmp(name, current->name()) == 0) {
2715 return current; 2757 return current;
2716 } 2758 }
2717 current = current->next(); 2759 current = current->next();
2718 } 2760 }
2719 return NULL; 2761 return NULL;
2720 } 2762 }
2721 2763
2722 } // namespace dart 2764 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698