| OLD | NEW |
| 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 #include "vm/kernel_isolate.h" | 5 #include "vm/kernel_isolate.h" |
| 6 | 6 |
| 7 #include "vm/compiler.h" | 7 #include "vm/compiler.h" |
| 8 #include "include/dart_native_api.h" | 8 #include "include/dart_native_api.h" |
| 9 #include "vm/dart_api_impl.h" | 9 #include "vm/dart_api_impl.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 return kernel_port_; | 270 return kernel_port_; |
| 271 } | 271 } |
| 272 | 272 |
| 273 | 273 |
| 274 class KernelCompilationRequest : public ValueObject { | 274 class KernelCompilationRequest : public ValueObject { |
| 275 public: | 275 public: |
| 276 KernelCompilationRequest() | 276 KernelCompilationRequest() |
| 277 : monitor_(new Monitor()), | 277 : monitor_(new Monitor()), |
| 278 port_(Dart_NewNativePort("kernel-compilation-port", | 278 port_(Dart_NewNativePort("kernel-compilation-port", |
| 279 &HandleResponse, | 279 &HandleResponse, |
| 280 false, | 280 false)), |
| 281 this)) { | 281 next_(NULL), |
| 282 prev_(NULL) { |
| 283 ASSERT(port_ != ILLEGAL_PORT); |
| 284 RegisterRequest(this); |
| 282 result_.status = Dart_KernelCompilationStatus_Unknown; | 285 result_.status = Dart_KernelCompilationStatus_Unknown; |
| 283 result_.error = NULL; | 286 result_.error = NULL; |
| 284 result_.kernel = NULL; | 287 result_.kernel = NULL; |
| 285 result_.kernel_size = 0; | 288 result_.kernel_size = 0; |
| 286 } | 289 } |
| 287 | 290 |
| 288 ~KernelCompilationRequest() { | 291 ~KernelCompilationRequest() { |
| 292 UnregisterRequest(this); |
| 289 Dart_CloseNativePort(port_); | 293 Dart_CloseNativePort(port_); |
| 290 delete monitor_; | 294 delete monitor_; |
| 291 } | 295 } |
| 292 | 296 |
| 293 Dart_KernelCompilationResult SendAndWaitForResponse(Dart_Port kernel_port, | 297 Dart_KernelCompilationResult SendAndWaitForResponse(Dart_Port kernel_port, |
| 294 const char* script_uri) { | 298 const char* script_uri) { |
| 295 // Build the [null, send_port, script_uri] message for the Kernel isolate: | 299 // Build the [null, send_port, script_uri] message for the Kernel isolate: |
| 296 // null tag tells it that request came from this code, instead of Loader | 300 // null tag tells it that request came from this code, instead of Loader |
| 297 // so that it can given a more informative response. | 301 // so that it can given a more informative response. |
| 298 Dart_CObject tag; | 302 Dart_CObject tag; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 } else { | 361 } else { |
| 358 ASSERT(result_.status == Dart_KernelCompilationStatus_Crash || | 362 ASSERT(result_.status == Dart_KernelCompilationStatus_Crash || |
| 359 result_.status == Dart_KernelCompilationStatus_Error); | 363 result_.status == Dart_KernelCompilationStatus_Error); |
| 360 // This is an error. | 364 // This is an error. |
| 361 ASSERT(response[1]->type == Dart_CObject_kString); | 365 ASSERT(response[1]->type == Dart_CObject_kString); |
| 362 result_.error = strdup(response[1]->value.as_string); | 366 result_.error = strdup(response[1]->value.as_string); |
| 363 } | 367 } |
| 364 ml.Notify(); | 368 ml.Notify(); |
| 365 } | 369 } |
| 366 | 370 |
| 367 static void HandleResponse(Dart_Port dest_port_id, | 371 static void HandleResponse(Dart_Port port, Dart_CObject* message) { |
| 368 Dart_CObject* message, | 372 MonitorLocker locker(requests_monitor_); |
| 369 void* peer) { | 373 KernelCompilationRequest* rq = FindRequestLocked(port); |
| 370 static_cast<KernelCompilationRequest*>(peer)->HandleResponseImpl(message); | 374 if (rq == NULL) { |
| 375 return; |
| 376 } |
| 377 rq->HandleResponseImpl(message); |
| 371 } | 378 } |
| 372 | 379 |
| 380 static void RegisterRequest(KernelCompilationRequest* rq) { |
| 381 MonitorLocker locker(requests_monitor_); |
| 382 rq->next_ = requests_; |
| 383 requests_ = rq; |
| 384 } |
| 385 |
| 386 static void UnregisterRequest(KernelCompilationRequest* rq) { |
| 387 MonitorLocker locker(requests_monitor_); |
| 388 if (rq->next_ != NULL) { |
| 389 rq->next_->prev_ = rq->prev_; |
| 390 } |
| 391 if (rq->prev_ != NULL) { |
| 392 rq->prev_->next_ = rq->next_; |
| 393 } else { |
| 394 requests_ = rq->next_; |
| 395 } |
| 396 } |
| 397 |
| 398 // Note: Caller must hold requests_monitor_. |
| 399 static KernelCompilationRequest* FindRequestLocked(Dart_Port port) { |
| 400 for (KernelCompilationRequest* rq = requests_; rq != NULL; rq = rq->next_) { |
| 401 if (rq->port_ == port) { |
| 402 return rq; |
| 403 } |
| 404 } |
| 405 return NULL; |
| 406 } |
| 407 |
| 408 // This monitor must be held whenever linked list of requests is accessed. |
| 409 static Monitor* requests_monitor_; |
| 410 |
| 411 // Linked list of all active requests. Used to find a request by port number. |
| 412 // Guarded by requests_monitor_ lock. |
| 413 static KernelCompilationRequest* requests_; |
| 414 |
| 373 Monitor* monitor_; | 415 Monitor* monitor_; |
| 374 Dart_Port port_; | 416 Dart_Port port_; |
| 375 | 417 |
| 418 // Linked list of active requests. Guarded by requests_monitor_ lock. |
| 419 KernelCompilationRequest* next_; |
| 420 KernelCompilationRequest* prev_; |
| 421 |
| 376 Dart_KernelCompilationResult result_; | 422 Dart_KernelCompilationResult result_; |
| 377 }; | 423 }; |
| 378 | 424 |
| 425 Monitor* KernelCompilationRequest::requests_monitor_ = new Monitor(); |
| 426 KernelCompilationRequest* KernelCompilationRequest::requests_ = NULL; |
| 379 | 427 |
| 380 Dart_KernelCompilationResult KernelIsolate::CompileToKernel( | 428 Dart_KernelCompilationResult KernelIsolate::CompileToKernel( |
| 381 const char* script_uri) { | 429 const char* script_uri) { |
| 382 // This must be the main script to be loaded. Wait for Kernel isolate | 430 // This must be the main script to be loaded. Wait for Kernel isolate |
| 383 // to finish initialization. | 431 // to finish initialization. |
| 384 Dart_Port kernel_port = WaitForKernelPort(); | 432 Dart_Port kernel_port = WaitForKernelPort(); |
| 385 if (kernel_port == ILLEGAL_PORT) { | 433 if (kernel_port == ILLEGAL_PORT) { |
| 386 Dart_KernelCompilationResult result; | 434 Dart_KernelCompilationResult result; |
| 387 result.status = Dart_KernelCompilationStatus_Unknown; | 435 result.status = Dart_KernelCompilationStatus_Unknown; |
| 388 result.error = strdup("Error while initializing Kernel isolate"); | 436 result.error = strdup("Error while initializing Kernel isolate"); |
| 389 return result; | 437 return result; |
| 390 } | 438 } |
| 391 | 439 |
| 392 KernelCompilationRequest request; | 440 KernelCompilationRequest request; |
| 393 return request.SendAndWaitForResponse(kernel_port, script_uri); | 441 return request.SendAndWaitForResponse(kernel_port, script_uri); |
| 394 } | 442 } |
| 395 | 443 |
| 396 | 444 |
| 397 #endif // DART_PRECOMPILED_RUNTIME | 445 #endif // DART_PRECOMPILED_RUNTIME |
| 398 | 446 |
| 399 } // namespace dart | 447 } // namespace dart |
| OLD | NEW |