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 |