OLD | NEW |
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 #ifndef VM_ISOLATE_H_ | 5 #ifndef VM_DEFERRED_OBJECTS_H_ |
6 #define VM_ISOLATE_H_ | 6 #define VM_DEFERRED_OBJECTS_H_ |
7 | 7 |
8 #include "include/dart_api.h" | 8 #include "platform/globals.h" |
9 #include "platform/assert.h" | |
10 #include "platform/thread.h" | |
11 #include "vm/base_isolate.h" | |
12 #include "vm/class_table.h" | |
13 #include "vm/gc_callbacks.h" | |
14 #include "vm/handles.h" | |
15 #include "vm/megamorphic_cache_table.h" | |
16 #include "vm/store_buffer.h" | |
17 #include "vm/timer.h" | |
18 | 9 |
19 namespace dart { | 10 namespace dart { |
20 | 11 |
21 // Forward declarations. | 12 // Forward declarations. |
22 class AbstractType; | |
23 class ApiState; | |
24 class Array; | |
25 class Class; | |
26 class CodeIndexTable; | |
27 class Debugger; | |
28 class Field; | |
29 class Function; | |
30 class HandleScope; | |
31 class HandleVisitor; | |
32 class Heap; | |
33 class ICData; | |
34 class Instance; | 13 class Instance; |
35 class LongJump; | |
36 class MessageHandler; | |
37 class Mutex; | |
38 class Object; | |
39 class ObjectPointerVisitor; | |
40 class ObjectStore; | |
41 class RawInstance; | 14 class RawInstance; |
42 class RawArray; | |
43 class RawContext; | |
44 class RawDouble; | |
45 class RawMint; | |
46 class RawObject; | 15 class RawObject; |
47 class RawInteger; | |
48 class RawError; | |
49 class RawFloat32x4; | |
50 class RawUint32x4; | |
51 class Simulator; | |
52 class StackResource; | |
53 class StackZone; | |
54 class StubCode; | |
55 class TypeArguments; | |
56 class TypeParameter; | |
57 class ObjectHistogram; | |
58 class ObjectIdRing; | |
59 | 16 |
60 | 17 // Used by the deoptimization infrastructure to defer allocation of |
61 // Used by the deoptimization infrastructure to defer allocation of unboxed | 18 // unboxed objects until frame is fully rewritten and GC is safe. |
62 // objects until frame is fully rewritten and GC is safe. | 19 // Describes a stack slot that should be populated with a reference to |
63 // Describes a stack slot that should be populated with a reference to the | 20 // the materialized object. |
64 // materialized object. | |
65 class DeferredSlot { | 21 class DeferredSlot { |
66 public: | 22 public: |
67 DeferredSlot(RawInstance** slot, DeferredSlot* next) | 23 DeferredSlot(RawInstance** slot, DeferredSlot* next) |
68 : slot_(slot), next_(next) { } | 24 : slot_(slot), next_(next) { } |
69 virtual ~DeferredSlot() { } | 25 virtual ~DeferredSlot() { } |
70 | 26 |
71 RawInstance** slot() const { return slot_; } | 27 RawInstance** slot() const { return slot_; } |
72 DeferredSlot* next() const { return next_; } | 28 DeferredSlot* next() const { return next_; } |
73 | 29 |
74 virtual void Materialize() = 0; | 30 virtual void Materialize() = 0; |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 // The first argument is Class of the instance to materialize followed by | 175 // The first argument is Class of the instance to materialize followed by |
220 // Field, value pairs. | 176 // Field, value pairs. |
221 RawObject** args_; | 177 RawObject** args_; |
222 | 178 |
223 // Object materialized from this description. | 179 // Object materialized from this description. |
224 const Instance* object_; | 180 const Instance* object_; |
225 | 181 |
226 DISALLOW_COPY_AND_ASSIGN(DeferredObject); | 182 DISALLOW_COPY_AND_ASSIGN(DeferredObject); |
227 }; | 183 }; |
228 | 184 |
229 #define REUSABLE_HANDLE_LIST(V) \ | |
230 V(Object) \ | |
231 V(Array) \ | |
232 V(String) \ | |
233 V(Instance) \ | |
234 V(Function) \ | |
235 V(Field) \ | |
236 V(Class) \ | |
237 V(AbstractType) \ | |
238 V(TypeParameter) \ | |
239 V(TypeArguments) \ | |
240 | |
241 class Isolate : public BaseIsolate { | |
242 public: | |
243 ~Isolate(); | |
244 | |
245 static inline Isolate* Current() { | |
246 return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key)); | |
247 } | |
248 | |
249 static void SetCurrent(Isolate* isolate); | |
250 | |
251 static void InitOnce(); | |
252 static Isolate* Init(const char* name_prefix); | |
253 void Shutdown(); | |
254 | |
255 // Register a newly introduced class. | |
256 void RegisterClass(const Class& cls); | |
257 | |
258 // Visit all object pointers. | |
259 void VisitObjectPointers(ObjectPointerVisitor* visitor, | |
260 bool visit_prologue_weak_persistent_handles, | |
261 bool validate_frames); | |
262 | |
263 // Visits weak object pointers. | |
264 void VisitWeakPersistentHandles(HandleVisitor* visit, | |
265 bool visit_prologue_weak_persistent_handles); | |
266 | |
267 StoreBuffer* store_buffer() { return &store_buffer_; } | |
268 static intptr_t store_buffer_offset() { | |
269 return OFFSET_OF(Isolate, store_buffer_); | |
270 } | |
271 | |
272 ClassTable* class_table() { return &class_table_; } | |
273 static intptr_t class_table_offset() { | |
274 return OFFSET_OF(Isolate, class_table_); | |
275 } | |
276 | |
277 ObjectHistogram* object_histogram() { return object_histogram_; } | |
278 | |
279 MegamorphicCacheTable* megamorphic_cache_table() { | |
280 return &megamorphic_cache_table_; | |
281 } | |
282 | |
283 Dart_MessageNotifyCallback message_notify_callback() const { | |
284 return message_notify_callback_; | |
285 } | |
286 void set_message_notify_callback(Dart_MessageNotifyCallback value) { | |
287 message_notify_callback_ = value; | |
288 } | |
289 | |
290 const char* name() const { return name_; } | |
291 | |
292 int64_t start_time() const { return start_time_; } | |
293 | |
294 Dart_Port main_port() { return main_port_; } | |
295 void set_main_port(Dart_Port port) { | |
296 ASSERT(main_port_ == 0); // Only set main port once. | |
297 main_port_ = port; | |
298 } | |
299 | |
300 Heap* heap() const { return heap_; } | |
301 void set_heap(Heap* value) { heap_ = value; } | |
302 static intptr_t heap_offset() { return OFFSET_OF(Isolate, heap_); } | |
303 | |
304 ObjectStore* object_store() const { return object_store_; } | |
305 void set_object_store(ObjectStore* value) { object_store_ = value; } | |
306 static intptr_t object_store_offset() { | |
307 return OFFSET_OF(Isolate, object_store_); | |
308 } | |
309 | |
310 RawContext* top_context() const { return top_context_; } | |
311 void set_top_context(RawContext* value) { top_context_ = value; } | |
312 static intptr_t top_context_offset() { | |
313 return OFFSET_OF(Isolate, top_context_); | |
314 } | |
315 | |
316 uword top_exit_frame_info() const { return top_exit_frame_info_; } | |
317 void set_top_exit_frame_info(uword value) { top_exit_frame_info_ = value; } | |
318 static intptr_t top_exit_frame_info_offset() { | |
319 return OFFSET_OF(Isolate, top_exit_frame_info_); | |
320 } | |
321 | |
322 ApiState* api_state() const { return api_state_; } | |
323 void set_api_state(ApiState* value) { api_state_ = value; } | |
324 | |
325 StubCode* stub_code() const { return stub_code_; } | |
326 void set_stub_code(StubCode* value) { stub_code_ = value; } | |
327 | |
328 LongJump* long_jump_base() const { return long_jump_base_; } | |
329 void set_long_jump_base(LongJump* value) { long_jump_base_ = value; } | |
330 | |
331 TimerList& timer_list() { return timer_list_; } | |
332 | |
333 static intptr_t current_zone_offset() { | |
334 return OFFSET_OF(Isolate, current_zone_); | |
335 } | |
336 | |
337 void set_init_callback_data(void* value) { | |
338 init_callback_data_ = value; | |
339 } | |
340 void* init_callback_data() const { | |
341 return init_callback_data_; | |
342 } | |
343 | |
344 Dart_LibraryTagHandler library_tag_handler() const { | |
345 return library_tag_handler_; | |
346 } | |
347 void set_library_tag_handler(Dart_LibraryTagHandler value) { | |
348 library_tag_handler_ = value; | |
349 } | |
350 | |
351 void SetStackLimit(uword value); | |
352 void SetStackLimitFromCurrentTOS(uword isolate_stack_top); | |
353 | |
354 uword stack_limit_address() const { | |
355 return reinterpret_cast<uword>(&stack_limit_); | |
356 } | |
357 | |
358 // The current stack limit. This may be overwritten with a special | |
359 // value to trigger interrupts. | |
360 uword stack_limit() const { return stack_limit_; } | |
361 | |
362 // The true stack limit for this isolate. | |
363 uword saved_stack_limit() const { return saved_stack_limit_; } | |
364 | |
365 static uword GetSpecifiedStackSize(); | |
366 | |
367 static const intptr_t kStackSizeBuffer = (4 * KB * kWordSize); | |
368 | |
369 enum { | |
370 kApiInterrupt = 0x1, // An interrupt from Dart_InterruptIsolate. | |
371 kMessageInterrupt = 0x2, // An interrupt to process an out of band message. | |
372 kStoreBufferInterrupt = 0x4, // An interrupt to process the store buffer. | |
373 kVmStatusInterrupt = 0x8, // An interrupt to process a status request. | |
374 | |
375 kInterruptsMask = | |
376 kApiInterrupt | | |
377 kMessageInterrupt | | |
378 kStoreBufferInterrupt | | |
379 kVmStatusInterrupt, | |
380 }; | |
381 | |
382 void ScheduleInterrupts(uword interrupt_bits); | |
383 uword GetAndClearInterrupts(); | |
384 | |
385 bool MakeRunnable(); | |
386 void Run(); | |
387 | |
388 MessageHandler* message_handler() const { return message_handler_; } | |
389 void set_message_handler(MessageHandler* value) { message_handler_ = value; } | |
390 | |
391 bool is_runnable() const { return is_runnable_; } | |
392 void set_is_runnable(bool value) { is_runnable_ = value; } | |
393 | |
394 uword spawn_data() const { return spawn_data_; } | |
395 void set_spawn_data(uword value) { spawn_data_ = value; } | |
396 | |
397 static const intptr_t kNoDeoptId = -1; | |
398 static const intptr_t kDeoptIdStep = 2; | |
399 static const intptr_t kDeoptIdBeforeOffset = 0; | |
400 static const intptr_t kDeoptIdAfterOffset = 1; | |
401 intptr_t deopt_id() const { return deopt_id_; } | |
402 void set_deopt_id(int value) { | |
403 ASSERT(value >= 0); | |
404 deopt_id_ = value; | |
405 } | |
406 intptr_t GetNextDeoptId() { | |
407 ASSERT(deopt_id_ != kNoDeoptId); | |
408 const intptr_t id = deopt_id_; | |
409 deopt_id_ += kDeoptIdStep; | |
410 return id; | |
411 } | |
412 | |
413 static intptr_t ToDeoptAfter(intptr_t deopt_id) { | |
414 ASSERT(IsDeoptBefore(deopt_id)); | |
415 return deopt_id + kDeoptIdAfterOffset; | |
416 } | |
417 | |
418 static bool IsDeoptBefore(intptr_t deopt_id) { | |
419 return (deopt_id % kDeoptIdStep) == kDeoptIdBeforeOffset; | |
420 } | |
421 | |
422 static bool IsDeoptAfter(intptr_t deopt_id) { | |
423 return (deopt_id % kDeoptIdStep) == kDeoptIdAfterOffset; | |
424 } | |
425 | |
426 Mutex* mutex() const { return mutex_; } | |
427 | |
428 Debugger* debugger() const { return debugger_; } | |
429 | |
430 void set_single_step(bool value) { single_step_ = value; } | |
431 bool single_step() const { return single_step_; } | |
432 static intptr_t single_step_offset() { | |
433 return OFFSET_OF(Isolate, single_step_); | |
434 } | |
435 | |
436 Simulator* simulator() const { return simulator_; } | |
437 void set_simulator(Simulator* value) { simulator_ = value; } | |
438 | |
439 GcPrologueCallbacks& gc_prologue_callbacks() { | |
440 return gc_prologue_callbacks_; | |
441 } | |
442 | |
443 GcEpilogueCallbacks& gc_epilogue_callbacks() { | |
444 return gc_epilogue_callbacks_; | |
445 } | |
446 | |
447 static void SetCreateCallback(Dart_IsolateCreateCallback cb) { | |
448 create_callback_ = cb; | |
449 } | |
450 static Dart_IsolateCreateCallback CreateCallback() { | |
451 return create_callback_; | |
452 } | |
453 | |
454 static void SetInterruptCallback(Dart_IsolateInterruptCallback cb) { | |
455 interrupt_callback_ = cb; | |
456 } | |
457 static Dart_IsolateInterruptCallback InterruptCallback() { | |
458 return interrupt_callback_; | |
459 } | |
460 | |
461 static void SetVmStatsCallback(Dart_IsolateInterruptCallback cb) { | |
462 vmstats_callback_ = cb; | |
463 } | |
464 static Dart_IsolateInterruptCallback VmStatsCallback() { | |
465 return vmstats_callback_; | |
466 } | |
467 | |
468 static void SetUnhandledExceptionCallback( | |
469 Dart_IsolateUnhandledExceptionCallback cb) { | |
470 unhandled_exception_callback_ = cb; | |
471 } | |
472 static Dart_IsolateUnhandledExceptionCallback UnhandledExceptionCallback() { | |
473 return unhandled_exception_callback_; | |
474 } | |
475 | |
476 static void SetShutdownCallback(Dart_IsolateShutdownCallback cb) { | |
477 shutdown_callback_ = cb; | |
478 } | |
479 static Dart_IsolateShutdownCallback ShutdownCallback() { | |
480 return shutdown_callback_; | |
481 } | |
482 | |
483 static void SetFileCallbacks(Dart_FileOpenCallback file_open, | |
484 Dart_FileReadCallback file_read, | |
485 Dart_FileWriteCallback file_write, | |
486 Dart_FileCloseCallback file_close) { | |
487 file_open_callback_ = file_open; | |
488 file_read_callback_ = file_read; | |
489 file_write_callback_ = file_write; | |
490 file_close_callback_ = file_close; | |
491 } | |
492 | |
493 static Dart_FileOpenCallback file_open_callback() { | |
494 return file_open_callback_; | |
495 } | |
496 static Dart_FileReadCallback file_read_callback() { | |
497 return file_read_callback_; | |
498 } | |
499 static Dart_FileWriteCallback file_write_callback() { | |
500 return file_write_callback_; | |
501 } | |
502 static Dart_FileCloseCallback file_close_callback() { | |
503 return file_close_callback_; | |
504 } | |
505 | |
506 intptr_t* deopt_cpu_registers_copy() const { | |
507 return deopt_cpu_registers_copy_; | |
508 } | |
509 void set_deopt_cpu_registers_copy(intptr_t* value) { | |
510 ASSERT((value == NULL) || (deopt_cpu_registers_copy_ == NULL)); | |
511 deopt_cpu_registers_copy_ = value; | |
512 } | |
513 fpu_register_t* deopt_fpu_registers_copy() const { | |
514 return deopt_fpu_registers_copy_; | |
515 } | |
516 void set_deopt_fpu_registers_copy(fpu_register_t* value) { | |
517 ASSERT((value == NULL) || (deopt_fpu_registers_copy_ == NULL)); | |
518 deopt_fpu_registers_copy_ = value; | |
519 } | |
520 intptr_t* deopt_frame_copy() const { return deopt_frame_copy_; } | |
521 void SetDeoptFrameCopy(intptr_t* value, intptr_t size) { | |
522 ASSERT((value == NULL) || (size > 0)); | |
523 ASSERT((value == NULL) || (deopt_frame_copy_ == NULL)); | |
524 deopt_frame_copy_ = value; | |
525 deopt_frame_copy_size_ = size; | |
526 } | |
527 intptr_t deopt_frame_copy_size() const { return deopt_frame_copy_size_; } | |
528 | |
529 void set_object_id_ring(ObjectIdRing* ring) { | |
530 object_id_ring_ = ring; | |
531 } | |
532 ObjectIdRing* object_id_ring() { | |
533 return object_id_ring_; | |
534 } | |
535 | |
536 void PrepareForDeferredMaterialization(intptr_t count) { | |
537 if (count > 0) { | |
538 deferred_objects_ = new DeferredObject*[count]; | |
539 deferred_objects_count_ = count; | |
540 } | |
541 } | |
542 | |
543 void DeleteDeferredObjects() { | |
544 for (intptr_t i = 0; i < deferred_objects_count_; i++) { | |
545 delete deferred_objects_[i]; | |
546 } | |
547 delete[] deferred_objects_; | |
548 deferred_objects_ = NULL; | |
549 deferred_objects_count_ = 0; | |
550 } | |
551 | |
552 DeferredObject* GetDeferredObject(intptr_t idx) const { | |
553 return deferred_objects_[idx]; | |
554 } | |
555 | |
556 void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) { | |
557 deferred_objects_[idx] = object; | |
558 } | |
559 | |
560 intptr_t DeferredObjectsCount() const { | |
561 return deferred_objects_count_; | |
562 } | |
563 | |
564 void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) { | |
565 deferred_object_refs_ = new DeferredObjectRef( | |
566 idx, | |
567 reinterpret_cast<RawInstance**>(slot), | |
568 deferred_object_refs_); | |
569 } | |
570 | |
571 void DeferDoubleMaterialization(double value, RawDouble** slot) { | |
572 deferred_boxes_ = new DeferredDouble( | |
573 value, | |
574 reinterpret_cast<RawInstance**>(slot), | |
575 deferred_boxes_); | |
576 } | |
577 | |
578 void DeferMintMaterialization(int64_t value, RawMint** slot) { | |
579 deferred_boxes_ = new DeferredMint( | |
580 value, | |
581 reinterpret_cast<RawInstance**>(slot), | |
582 deferred_boxes_); | |
583 } | |
584 | |
585 void DeferFloat32x4Materialization(simd128_value_t value, | |
586 RawFloat32x4** slot) { | |
587 deferred_boxes_ = new DeferredFloat32x4( | |
588 value, | |
589 reinterpret_cast<RawInstance**>(slot), | |
590 deferred_boxes_); | |
591 } | |
592 | |
593 void DeferUint32x4Materialization(simd128_value_t value, | |
594 RawUint32x4** slot) { | |
595 deferred_boxes_ = new DeferredUint32x4( | |
596 value, | |
597 reinterpret_cast<RawInstance**>(slot), | |
598 deferred_boxes_); | |
599 } | |
600 | |
601 // Populate all deferred slots that contain boxes for double, mint, simd | |
602 // values. | |
603 void MaterializeDeferredBoxes(); | |
604 | |
605 // Populate all slots containing references to objects which allocations | |
606 // were eliminated by AllocationSinking pass. | |
607 void MaterializeDeferredObjects(); | |
608 | |
609 static char* GetStatus(const char* request); | |
610 | |
611 intptr_t BlockClassFinalization() { | |
612 ASSERT(defer_finalization_count_ >= 0); | |
613 return defer_finalization_count_++; | |
614 } | |
615 | |
616 intptr_t UnblockClassFinalization() { | |
617 ASSERT(defer_finalization_count_ > 0); | |
618 return defer_finalization_count_--; | |
619 } | |
620 | |
621 bool AllowClassFinalization() { | |
622 ASSERT(defer_finalization_count_ >= 0); | |
623 return defer_finalization_count_ == 0; | |
624 } | |
625 | |
626 private: | |
627 Isolate(); | |
628 | |
629 void BuildName(const char* name_prefix); | |
630 void PrintInvokedFunctions(); | |
631 | |
632 static bool FetchStacktrace(); | |
633 static bool FetchStackFrameDetails(); | |
634 char* GetStatusDetails(); | |
635 char* GetStatusStacktrace(); | |
636 char* GetStatusStackFrame(intptr_t index); | |
637 char* DoStacktraceInterrupt(Dart_IsolateInterruptCallback cb); | |
638 template<class T> T* AllocateReusableHandle(); | |
639 | |
640 static ThreadLocalKey isolate_key; | |
641 StoreBuffer store_buffer_; | |
642 ClassTable class_table_; | |
643 MegamorphicCacheTable megamorphic_cache_table_; | |
644 Dart_MessageNotifyCallback message_notify_callback_; | |
645 char* name_; | |
646 int64_t start_time_; | |
647 Dart_Port main_port_; | |
648 Heap* heap_; | |
649 ObjectStore* object_store_; | |
650 RawContext* top_context_; | |
651 uword top_exit_frame_info_; | |
652 void* init_callback_data_; | |
653 Dart_LibraryTagHandler library_tag_handler_; | |
654 ApiState* api_state_; | |
655 StubCode* stub_code_; | |
656 Debugger* debugger_; | |
657 bool single_step_; | |
658 Simulator* simulator_; | |
659 LongJump* long_jump_base_; | |
660 TimerList timer_list_; | |
661 intptr_t deopt_id_; | |
662 Mutex* mutex_; // protects stack_limit_ and saved_stack_limit_. | |
663 uword stack_limit_; | |
664 uword saved_stack_limit_; | |
665 MessageHandler* message_handler_; | |
666 uword spawn_data_; | |
667 bool is_runnable_; | |
668 GcPrologueCallbacks gc_prologue_callbacks_; | |
669 GcEpilogueCallbacks gc_epilogue_callbacks_; | |
670 intptr_t defer_finalization_count_; | |
671 | |
672 // Deoptimization support. | |
673 intptr_t* deopt_cpu_registers_copy_; | |
674 fpu_register_t* deopt_fpu_registers_copy_; | |
675 intptr_t* deopt_frame_copy_; | |
676 intptr_t deopt_frame_copy_size_; | |
677 DeferredSlot* deferred_boxes_; | |
678 DeferredSlot* deferred_object_refs_; | |
679 | |
680 intptr_t deferred_objects_count_; | |
681 DeferredObject** deferred_objects_; | |
682 | |
683 // Status support. | |
684 char* stacktrace_; | |
685 intptr_t stack_frame_index_; | |
686 ObjectHistogram* object_histogram_; | |
687 | |
688 // Ring buffer of objects assigned an id. | |
689 ObjectIdRing* object_id_ring_; | |
690 | |
691 // Reusable handles support. | |
692 #define REUSABLE_HANDLE_FIELDS(object) \ | |
693 object* object##_handle_; \ | |
694 | |
695 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS) | |
696 #undef REUSABLE_HANDLE_FIELDS | |
697 VMHandles reusable_handles_; | |
698 | |
699 static Dart_IsolateCreateCallback create_callback_; | |
700 static Dart_IsolateInterruptCallback interrupt_callback_; | |
701 static Dart_IsolateUnhandledExceptionCallback unhandled_exception_callback_; | |
702 static Dart_IsolateShutdownCallback shutdown_callback_; | |
703 static Dart_FileOpenCallback file_open_callback_; | |
704 static Dart_FileReadCallback file_read_callback_; | |
705 static Dart_FileWriteCallback file_write_callback_; | |
706 static Dart_FileCloseCallback file_close_callback_; | |
707 static Dart_IsolateInterruptCallback vmstats_callback_; | |
708 | |
709 friend class ReusableHandleScope; | |
710 friend class ReusableObjectHandleScope; | |
711 DISALLOW_COPY_AND_ASSIGN(Isolate); | |
712 }; | |
713 | |
714 | |
715 // When we need to execute code in an isolate, we use the | |
716 // StartIsolateScope. | |
717 class StartIsolateScope { | |
718 public: | |
719 explicit StartIsolateScope(Isolate* new_isolate) | |
720 : new_isolate_(new_isolate), saved_isolate_(Isolate::Current()) { | |
721 ASSERT(new_isolate_ != NULL); | |
722 if (saved_isolate_ != new_isolate_) { | |
723 ASSERT(Isolate::Current() == NULL); | |
724 Isolate::SetCurrent(new_isolate_); | |
725 new_isolate_->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(this)); | |
726 } | |
727 } | |
728 | |
729 ~StartIsolateScope() { | |
730 if (saved_isolate_ != new_isolate_) { | |
731 new_isolate_->SetStackLimit(~static_cast<uword>(0)); | |
732 Isolate::SetCurrent(saved_isolate_); | |
733 } | |
734 } | |
735 | |
736 private: | |
737 Isolate* new_isolate_; | |
738 Isolate* saved_isolate_; | |
739 | |
740 DISALLOW_COPY_AND_ASSIGN(StartIsolateScope); | |
741 }; | |
742 | |
743 // When we need to temporarily become another isolate, we use the | |
744 // SwitchIsolateScope. It is not permitted to run dart code while in | |
745 // a SwitchIsolateScope. | |
746 class SwitchIsolateScope { | |
747 public: | |
748 explicit SwitchIsolateScope(Isolate* new_isolate) | |
749 : new_isolate_(new_isolate), | |
750 saved_isolate_(Isolate::Current()), | |
751 saved_stack_limit_(saved_isolate_ | |
752 ? saved_isolate_->saved_stack_limit() : 0) { | |
753 if (saved_isolate_ != new_isolate_) { | |
754 Isolate::SetCurrent(new_isolate_); | |
755 if (new_isolate_ != NULL) { | |
756 // Don't allow dart code to execute. | |
757 new_isolate_->SetStackLimit(~static_cast<uword>(0)); | |
758 } | |
759 } | |
760 } | |
761 | |
762 ~SwitchIsolateScope() { | |
763 if (saved_isolate_ != new_isolate_) { | |
764 Isolate::SetCurrent(saved_isolate_); | |
765 if (saved_isolate_ != NULL) { | |
766 saved_isolate_->SetStackLimit(saved_stack_limit_); | |
767 } | |
768 } | |
769 } | |
770 | |
771 private: | |
772 Isolate* new_isolate_; | |
773 Isolate* saved_isolate_; | |
774 uword saved_stack_limit_; | |
775 | |
776 DISALLOW_COPY_AND_ASSIGN(SwitchIsolateScope); | |
777 }; | |
778 | |
779 | |
780 class IsolateSpawnState { | |
781 public: | |
782 IsolateSpawnState(const Function& func, const Function& callback_func); | |
783 explicit IsolateSpawnState(const char* script_url); | |
784 ~IsolateSpawnState(); | |
785 | |
786 Isolate* isolate() const { return isolate_; } | |
787 void set_isolate(Isolate* value) { isolate_ = value; } | |
788 char* script_url() const { return script_url_; } | |
789 char* library_url() const { return library_url_; } | |
790 char* function_name() const { return function_name_; } | |
791 char* exception_callback_name() const { return exception_callback_name_; } | |
792 | |
793 RawObject* ResolveFunction(); | |
794 void Cleanup(); | |
795 | |
796 private: | |
797 Isolate* isolate_; | |
798 char* script_url_; | |
799 char* library_url_; | |
800 char* function_name_; | |
801 char* exception_callback_name_; | |
802 }; | |
803 | |
804 } // namespace dart | 185 } // namespace dart |
805 | 186 |
806 #endif // VM_ISOLATE_H_ | 187 #endif // VM_DEFERRED_OBJECTS_H_ |
OLD | NEW |