| 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 |