Index: runtime/vm/deferred_objects.h |
=================================================================== |
--- runtime/vm/deferred_objects.h (revision 27855) |
+++ runtime/vm/deferred_objects.h (working copy) |
@@ -2,66 +2,22 @@ |
// for details. All rights reserved. Use of this source code is governed by a |
// BSD-style license that can be found in the LICENSE file. |
-#ifndef VM_ISOLATE_H_ |
-#define VM_ISOLATE_H_ |
+#ifndef VM_DEFERRED_OBJECTS_H_ |
+#define VM_DEFERRED_OBJECTS_H_ |
-#include "include/dart_api.h" |
-#include "platform/assert.h" |
-#include "platform/thread.h" |
-#include "vm/base_isolate.h" |
-#include "vm/class_table.h" |
-#include "vm/gc_callbacks.h" |
-#include "vm/handles.h" |
-#include "vm/megamorphic_cache_table.h" |
-#include "vm/store_buffer.h" |
-#include "vm/timer.h" |
+#include "platform/globals.h" |
namespace dart { |
// Forward declarations. |
-class AbstractType; |
-class ApiState; |
-class Array; |
-class Class; |
-class CodeIndexTable; |
-class Debugger; |
-class Field; |
-class Function; |
-class HandleScope; |
-class HandleVisitor; |
-class Heap; |
-class ICData; |
class Instance; |
-class LongJump; |
-class MessageHandler; |
-class Mutex; |
-class Object; |
-class ObjectPointerVisitor; |
-class ObjectStore; |
class RawInstance; |
-class RawArray; |
-class RawContext; |
-class RawDouble; |
-class RawMint; |
class RawObject; |
-class RawInteger; |
-class RawError; |
-class RawFloat32x4; |
-class RawUint32x4; |
-class Simulator; |
-class StackResource; |
-class StackZone; |
-class StubCode; |
-class TypeArguments; |
-class TypeParameter; |
-class ObjectHistogram; |
-class ObjectIdRing; |
- |
-// Used by the deoptimization infrastructure to defer allocation of unboxed |
-// objects until frame is fully rewritten and GC is safe. |
-// Describes a stack slot that should be populated with a reference to the |
-// materialized object. |
+// Used by the deoptimization infrastructure to defer allocation of |
+// unboxed objects until frame is fully rewritten and GC is safe. |
+// Describes a stack slot that should be populated with a reference to |
+// the materialized object. |
class DeferredSlot { |
public: |
DeferredSlot(RawInstance** slot, DeferredSlot* next) |
@@ -226,581 +182,6 @@ |
DISALLOW_COPY_AND_ASSIGN(DeferredObject); |
}; |
-#define REUSABLE_HANDLE_LIST(V) \ |
- V(Object) \ |
- V(Array) \ |
- V(String) \ |
- V(Instance) \ |
- V(Function) \ |
- V(Field) \ |
- V(Class) \ |
- V(AbstractType) \ |
- V(TypeParameter) \ |
- V(TypeArguments) \ |
- |
-class Isolate : public BaseIsolate { |
- public: |
- ~Isolate(); |
- |
- static inline Isolate* Current() { |
- return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key)); |
- } |
- |
- static void SetCurrent(Isolate* isolate); |
- |
- static void InitOnce(); |
- static Isolate* Init(const char* name_prefix); |
- void Shutdown(); |
- |
- // Register a newly introduced class. |
- void RegisterClass(const Class& cls); |
- |
- // Visit all object pointers. |
- void VisitObjectPointers(ObjectPointerVisitor* visitor, |
- bool visit_prologue_weak_persistent_handles, |
- bool validate_frames); |
- |
- // Visits weak object pointers. |
- void VisitWeakPersistentHandles(HandleVisitor* visit, |
- bool visit_prologue_weak_persistent_handles); |
- |
- StoreBuffer* store_buffer() { return &store_buffer_; } |
- static intptr_t store_buffer_offset() { |
- return OFFSET_OF(Isolate, store_buffer_); |
- } |
- |
- ClassTable* class_table() { return &class_table_; } |
- static intptr_t class_table_offset() { |
- return OFFSET_OF(Isolate, class_table_); |
- } |
- |
- ObjectHistogram* object_histogram() { return object_histogram_; } |
- |
- MegamorphicCacheTable* megamorphic_cache_table() { |
- return &megamorphic_cache_table_; |
- } |
- |
- Dart_MessageNotifyCallback message_notify_callback() const { |
- return message_notify_callback_; |
- } |
- void set_message_notify_callback(Dart_MessageNotifyCallback value) { |
- message_notify_callback_ = value; |
- } |
- |
- const char* name() const { return name_; } |
- |
- int64_t start_time() const { return start_time_; } |
- |
- Dart_Port main_port() { return main_port_; } |
- void set_main_port(Dart_Port port) { |
- ASSERT(main_port_ == 0); // Only set main port once. |
- main_port_ = port; |
- } |
- |
- Heap* heap() const { return heap_; } |
- void set_heap(Heap* value) { heap_ = value; } |
- static intptr_t heap_offset() { return OFFSET_OF(Isolate, heap_); } |
- |
- ObjectStore* object_store() const { return object_store_; } |
- void set_object_store(ObjectStore* value) { object_store_ = value; } |
- static intptr_t object_store_offset() { |
- return OFFSET_OF(Isolate, object_store_); |
- } |
- |
- RawContext* top_context() const { return top_context_; } |
- void set_top_context(RawContext* value) { top_context_ = value; } |
- static intptr_t top_context_offset() { |
- return OFFSET_OF(Isolate, top_context_); |
- } |
- |
- uword top_exit_frame_info() const { return top_exit_frame_info_; } |
- void set_top_exit_frame_info(uword value) { top_exit_frame_info_ = value; } |
- static intptr_t top_exit_frame_info_offset() { |
- return OFFSET_OF(Isolate, top_exit_frame_info_); |
- } |
- |
- ApiState* api_state() const { return api_state_; } |
- void set_api_state(ApiState* value) { api_state_ = value; } |
- |
- StubCode* stub_code() const { return stub_code_; } |
- void set_stub_code(StubCode* value) { stub_code_ = value; } |
- |
- LongJump* long_jump_base() const { return long_jump_base_; } |
- void set_long_jump_base(LongJump* value) { long_jump_base_ = value; } |
- |
- TimerList& timer_list() { return timer_list_; } |
- |
- static intptr_t current_zone_offset() { |
- return OFFSET_OF(Isolate, current_zone_); |
- } |
- |
- void set_init_callback_data(void* value) { |
- init_callback_data_ = value; |
- } |
- void* init_callback_data() const { |
- return init_callback_data_; |
- } |
- |
- Dart_LibraryTagHandler library_tag_handler() const { |
- return library_tag_handler_; |
- } |
- void set_library_tag_handler(Dart_LibraryTagHandler value) { |
- library_tag_handler_ = value; |
- } |
- |
- void SetStackLimit(uword value); |
- void SetStackLimitFromCurrentTOS(uword isolate_stack_top); |
- |
- uword stack_limit_address() const { |
- return reinterpret_cast<uword>(&stack_limit_); |
- } |
- |
- // The current stack limit. This may be overwritten with a special |
- // value to trigger interrupts. |
- uword stack_limit() const { return stack_limit_; } |
- |
- // The true stack limit for this isolate. |
- uword saved_stack_limit() const { return saved_stack_limit_; } |
- |
- static uword GetSpecifiedStackSize(); |
- |
- static const intptr_t kStackSizeBuffer = (4 * KB * kWordSize); |
- |
- enum { |
- kApiInterrupt = 0x1, // An interrupt from Dart_InterruptIsolate. |
- kMessageInterrupt = 0x2, // An interrupt to process an out of band message. |
- kStoreBufferInterrupt = 0x4, // An interrupt to process the store buffer. |
- kVmStatusInterrupt = 0x8, // An interrupt to process a status request. |
- |
- kInterruptsMask = |
- kApiInterrupt | |
- kMessageInterrupt | |
- kStoreBufferInterrupt | |
- kVmStatusInterrupt, |
- }; |
- |
- void ScheduleInterrupts(uword interrupt_bits); |
- uword GetAndClearInterrupts(); |
- |
- bool MakeRunnable(); |
- void Run(); |
- |
- MessageHandler* message_handler() const { return message_handler_; } |
- void set_message_handler(MessageHandler* value) { message_handler_ = value; } |
- |
- bool is_runnable() const { return is_runnable_; } |
- void set_is_runnable(bool value) { is_runnable_ = value; } |
- |
- uword spawn_data() const { return spawn_data_; } |
- void set_spawn_data(uword value) { spawn_data_ = value; } |
- |
- static const intptr_t kNoDeoptId = -1; |
- static const intptr_t kDeoptIdStep = 2; |
- static const intptr_t kDeoptIdBeforeOffset = 0; |
- static const intptr_t kDeoptIdAfterOffset = 1; |
- intptr_t deopt_id() const { return deopt_id_; } |
- void set_deopt_id(int value) { |
- ASSERT(value >= 0); |
- deopt_id_ = value; |
- } |
- intptr_t GetNextDeoptId() { |
- ASSERT(deopt_id_ != kNoDeoptId); |
- const intptr_t id = deopt_id_; |
- deopt_id_ += kDeoptIdStep; |
- return id; |
- } |
- |
- static intptr_t ToDeoptAfter(intptr_t deopt_id) { |
- ASSERT(IsDeoptBefore(deopt_id)); |
- return deopt_id + kDeoptIdAfterOffset; |
- } |
- |
- static bool IsDeoptBefore(intptr_t deopt_id) { |
- return (deopt_id % kDeoptIdStep) == kDeoptIdBeforeOffset; |
- } |
- |
- static bool IsDeoptAfter(intptr_t deopt_id) { |
- return (deopt_id % kDeoptIdStep) == kDeoptIdAfterOffset; |
- } |
- |
- Mutex* mutex() const { return mutex_; } |
- |
- Debugger* debugger() const { return debugger_; } |
- |
- void set_single_step(bool value) { single_step_ = value; } |
- bool single_step() const { return single_step_; } |
- static intptr_t single_step_offset() { |
- return OFFSET_OF(Isolate, single_step_); |
- } |
- |
- Simulator* simulator() const { return simulator_; } |
- void set_simulator(Simulator* value) { simulator_ = value; } |
- |
- GcPrologueCallbacks& gc_prologue_callbacks() { |
- return gc_prologue_callbacks_; |
- } |
- |
- GcEpilogueCallbacks& gc_epilogue_callbacks() { |
- return gc_epilogue_callbacks_; |
- } |
- |
- static void SetCreateCallback(Dart_IsolateCreateCallback cb) { |
- create_callback_ = cb; |
- } |
- static Dart_IsolateCreateCallback CreateCallback() { |
- return create_callback_; |
- } |
- |
- static void SetInterruptCallback(Dart_IsolateInterruptCallback cb) { |
- interrupt_callback_ = cb; |
- } |
- static Dart_IsolateInterruptCallback InterruptCallback() { |
- return interrupt_callback_; |
- } |
- |
- static void SetVmStatsCallback(Dart_IsolateInterruptCallback cb) { |
- vmstats_callback_ = cb; |
- } |
- static Dart_IsolateInterruptCallback VmStatsCallback() { |
- return vmstats_callback_; |
- } |
- |
- static void SetUnhandledExceptionCallback( |
- Dart_IsolateUnhandledExceptionCallback cb) { |
- unhandled_exception_callback_ = cb; |
- } |
- static Dart_IsolateUnhandledExceptionCallback UnhandledExceptionCallback() { |
- return unhandled_exception_callback_; |
- } |
- |
- static void SetShutdownCallback(Dart_IsolateShutdownCallback cb) { |
- shutdown_callback_ = cb; |
- } |
- static Dart_IsolateShutdownCallback ShutdownCallback() { |
- return shutdown_callback_; |
- } |
- |
- static void SetFileCallbacks(Dart_FileOpenCallback file_open, |
- Dart_FileReadCallback file_read, |
- Dart_FileWriteCallback file_write, |
- Dart_FileCloseCallback file_close) { |
- file_open_callback_ = file_open; |
- file_read_callback_ = file_read; |
- file_write_callback_ = file_write; |
- file_close_callback_ = file_close; |
- } |
- |
- static Dart_FileOpenCallback file_open_callback() { |
- return file_open_callback_; |
- } |
- static Dart_FileReadCallback file_read_callback() { |
- return file_read_callback_; |
- } |
- static Dart_FileWriteCallback file_write_callback() { |
- return file_write_callback_; |
- } |
- static Dart_FileCloseCallback file_close_callback() { |
- return file_close_callback_; |
- } |
- |
- intptr_t* deopt_cpu_registers_copy() const { |
- return deopt_cpu_registers_copy_; |
- } |
- void set_deopt_cpu_registers_copy(intptr_t* value) { |
- ASSERT((value == NULL) || (deopt_cpu_registers_copy_ == NULL)); |
- deopt_cpu_registers_copy_ = value; |
- } |
- fpu_register_t* deopt_fpu_registers_copy() const { |
- return deopt_fpu_registers_copy_; |
- } |
- void set_deopt_fpu_registers_copy(fpu_register_t* value) { |
- ASSERT((value == NULL) || (deopt_fpu_registers_copy_ == NULL)); |
- deopt_fpu_registers_copy_ = value; |
- } |
- intptr_t* deopt_frame_copy() const { return deopt_frame_copy_; } |
- void SetDeoptFrameCopy(intptr_t* value, intptr_t size) { |
- ASSERT((value == NULL) || (size > 0)); |
- ASSERT((value == NULL) || (deopt_frame_copy_ == NULL)); |
- deopt_frame_copy_ = value; |
- deopt_frame_copy_size_ = size; |
- } |
- intptr_t deopt_frame_copy_size() const { return deopt_frame_copy_size_; } |
- |
- void set_object_id_ring(ObjectIdRing* ring) { |
- object_id_ring_ = ring; |
- } |
- ObjectIdRing* object_id_ring() { |
- return object_id_ring_; |
- } |
- |
- void PrepareForDeferredMaterialization(intptr_t count) { |
- if (count > 0) { |
- deferred_objects_ = new DeferredObject*[count]; |
- deferred_objects_count_ = count; |
- } |
- } |
- |
- void DeleteDeferredObjects() { |
- for (intptr_t i = 0; i < deferred_objects_count_; i++) { |
- delete deferred_objects_[i]; |
- } |
- delete[] deferred_objects_; |
- deferred_objects_ = NULL; |
- deferred_objects_count_ = 0; |
- } |
- |
- DeferredObject* GetDeferredObject(intptr_t idx) const { |
- return deferred_objects_[idx]; |
- } |
- |
- void SetDeferredObjectAt(intptr_t idx, DeferredObject* object) { |
- deferred_objects_[idx] = object; |
- } |
- |
- intptr_t DeferredObjectsCount() const { |
- return deferred_objects_count_; |
- } |
- |
- void DeferMaterializedObjectRef(intptr_t idx, intptr_t* slot) { |
- deferred_object_refs_ = new DeferredObjectRef( |
- idx, |
- reinterpret_cast<RawInstance**>(slot), |
- deferred_object_refs_); |
- } |
- |
- void DeferDoubleMaterialization(double value, RawDouble** slot) { |
- deferred_boxes_ = new DeferredDouble( |
- value, |
- reinterpret_cast<RawInstance**>(slot), |
- deferred_boxes_); |
- } |
- |
- void DeferMintMaterialization(int64_t value, RawMint** slot) { |
- deferred_boxes_ = new DeferredMint( |
- value, |
- reinterpret_cast<RawInstance**>(slot), |
- deferred_boxes_); |
- } |
- |
- void DeferFloat32x4Materialization(simd128_value_t value, |
- RawFloat32x4** slot) { |
- deferred_boxes_ = new DeferredFloat32x4( |
- value, |
- reinterpret_cast<RawInstance**>(slot), |
- deferred_boxes_); |
- } |
- |
- void DeferUint32x4Materialization(simd128_value_t value, |
- RawUint32x4** slot) { |
- deferred_boxes_ = new DeferredUint32x4( |
- value, |
- reinterpret_cast<RawInstance**>(slot), |
- deferred_boxes_); |
- } |
- |
- // Populate all deferred slots that contain boxes for double, mint, simd |
- // values. |
- void MaterializeDeferredBoxes(); |
- |
- // Populate all slots containing references to objects which allocations |
- // were eliminated by AllocationSinking pass. |
- void MaterializeDeferredObjects(); |
- |
- static char* GetStatus(const char* request); |
- |
- intptr_t BlockClassFinalization() { |
- ASSERT(defer_finalization_count_ >= 0); |
- return defer_finalization_count_++; |
- } |
- |
- intptr_t UnblockClassFinalization() { |
- ASSERT(defer_finalization_count_ > 0); |
- return defer_finalization_count_--; |
- } |
- |
- bool AllowClassFinalization() { |
- ASSERT(defer_finalization_count_ >= 0); |
- return defer_finalization_count_ == 0; |
- } |
- |
- private: |
- Isolate(); |
- |
- void BuildName(const char* name_prefix); |
- void PrintInvokedFunctions(); |
- |
- static bool FetchStacktrace(); |
- static bool FetchStackFrameDetails(); |
- char* GetStatusDetails(); |
- char* GetStatusStacktrace(); |
- char* GetStatusStackFrame(intptr_t index); |
- char* DoStacktraceInterrupt(Dart_IsolateInterruptCallback cb); |
- template<class T> T* AllocateReusableHandle(); |
- |
- static ThreadLocalKey isolate_key; |
- StoreBuffer store_buffer_; |
- ClassTable class_table_; |
- MegamorphicCacheTable megamorphic_cache_table_; |
- Dart_MessageNotifyCallback message_notify_callback_; |
- char* name_; |
- int64_t start_time_; |
- Dart_Port main_port_; |
- Heap* heap_; |
- ObjectStore* object_store_; |
- RawContext* top_context_; |
- uword top_exit_frame_info_; |
- void* init_callback_data_; |
- Dart_LibraryTagHandler library_tag_handler_; |
- ApiState* api_state_; |
- StubCode* stub_code_; |
- Debugger* debugger_; |
- bool single_step_; |
- Simulator* simulator_; |
- LongJump* long_jump_base_; |
- TimerList timer_list_; |
- intptr_t deopt_id_; |
- Mutex* mutex_; // protects stack_limit_ and saved_stack_limit_. |
- uword stack_limit_; |
- uword saved_stack_limit_; |
- MessageHandler* message_handler_; |
- uword spawn_data_; |
- bool is_runnable_; |
- GcPrologueCallbacks gc_prologue_callbacks_; |
- GcEpilogueCallbacks gc_epilogue_callbacks_; |
- intptr_t defer_finalization_count_; |
- |
- // Deoptimization support. |
- intptr_t* deopt_cpu_registers_copy_; |
- fpu_register_t* deopt_fpu_registers_copy_; |
- intptr_t* deopt_frame_copy_; |
- intptr_t deopt_frame_copy_size_; |
- DeferredSlot* deferred_boxes_; |
- DeferredSlot* deferred_object_refs_; |
- |
- intptr_t deferred_objects_count_; |
- DeferredObject** deferred_objects_; |
- |
- // Status support. |
- char* stacktrace_; |
- intptr_t stack_frame_index_; |
- ObjectHistogram* object_histogram_; |
- |
- // Ring buffer of objects assigned an id. |
- ObjectIdRing* object_id_ring_; |
- |
- // Reusable handles support. |
-#define REUSABLE_HANDLE_FIELDS(object) \ |
- object* object##_handle_; \ |
- |
- REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS) |
-#undef REUSABLE_HANDLE_FIELDS |
- VMHandles reusable_handles_; |
- |
- static Dart_IsolateCreateCallback create_callback_; |
- static Dart_IsolateInterruptCallback interrupt_callback_; |
- static Dart_IsolateUnhandledExceptionCallback unhandled_exception_callback_; |
- static Dart_IsolateShutdownCallback shutdown_callback_; |
- static Dart_FileOpenCallback file_open_callback_; |
- static Dart_FileReadCallback file_read_callback_; |
- static Dart_FileWriteCallback file_write_callback_; |
- static Dart_FileCloseCallback file_close_callback_; |
- static Dart_IsolateInterruptCallback vmstats_callback_; |
- |
- friend class ReusableHandleScope; |
- friend class ReusableObjectHandleScope; |
- DISALLOW_COPY_AND_ASSIGN(Isolate); |
-}; |
- |
- |
-// When we need to execute code in an isolate, we use the |
-// StartIsolateScope. |
-class StartIsolateScope { |
- public: |
- explicit StartIsolateScope(Isolate* new_isolate) |
- : new_isolate_(new_isolate), saved_isolate_(Isolate::Current()) { |
- ASSERT(new_isolate_ != NULL); |
- if (saved_isolate_ != new_isolate_) { |
- ASSERT(Isolate::Current() == NULL); |
- Isolate::SetCurrent(new_isolate_); |
- new_isolate_->SetStackLimitFromCurrentTOS(reinterpret_cast<uword>(this)); |
- } |
- } |
- |
- ~StartIsolateScope() { |
- if (saved_isolate_ != new_isolate_) { |
- new_isolate_->SetStackLimit(~static_cast<uword>(0)); |
- Isolate::SetCurrent(saved_isolate_); |
- } |
- } |
- |
- private: |
- Isolate* new_isolate_; |
- Isolate* saved_isolate_; |
- |
- DISALLOW_COPY_AND_ASSIGN(StartIsolateScope); |
-}; |
- |
-// When we need to temporarily become another isolate, we use the |
-// SwitchIsolateScope. It is not permitted to run dart code while in |
-// a SwitchIsolateScope. |
-class SwitchIsolateScope { |
- public: |
- explicit SwitchIsolateScope(Isolate* new_isolate) |
- : new_isolate_(new_isolate), |
- saved_isolate_(Isolate::Current()), |
- saved_stack_limit_(saved_isolate_ |
- ? saved_isolate_->saved_stack_limit() : 0) { |
- if (saved_isolate_ != new_isolate_) { |
- Isolate::SetCurrent(new_isolate_); |
- if (new_isolate_ != NULL) { |
- // Don't allow dart code to execute. |
- new_isolate_->SetStackLimit(~static_cast<uword>(0)); |
- } |
- } |
- } |
- |
- ~SwitchIsolateScope() { |
- if (saved_isolate_ != new_isolate_) { |
- Isolate::SetCurrent(saved_isolate_); |
- if (saved_isolate_ != NULL) { |
- saved_isolate_->SetStackLimit(saved_stack_limit_); |
- } |
- } |
- } |
- |
- private: |
- Isolate* new_isolate_; |
- Isolate* saved_isolate_; |
- uword saved_stack_limit_; |
- |
- DISALLOW_COPY_AND_ASSIGN(SwitchIsolateScope); |
-}; |
- |
- |
-class IsolateSpawnState { |
- public: |
- IsolateSpawnState(const Function& func, const Function& callback_func); |
- explicit IsolateSpawnState(const char* script_url); |
- ~IsolateSpawnState(); |
- |
- Isolate* isolate() const { return isolate_; } |
- void set_isolate(Isolate* value) { isolate_ = value; } |
- char* script_url() const { return script_url_; } |
- char* library_url() const { return library_url_; } |
- char* function_name() const { return function_name_; } |
- char* exception_callback_name() const { return exception_callback_name_; } |
- |
- RawObject* ResolveFunction(); |
- void Cleanup(); |
- |
- private: |
- Isolate* isolate_; |
- char* script_url_; |
- char* library_url_; |
- char* function_name_; |
- char* exception_callback_name_; |
-}; |
- |
} // namespace dart |
-#endif // VM_ISOLATE_H_ |
+#endif // VM_DEFERRED_OBJECTS_H_ |