Chromium Code Reviews| Index: runtime/vm/isolate.h |
| diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h |
| index c87b56d14dda8d4222db37798b383637e6461166..da301ce6acb5518d331e28efe6516a0a03ac1874 100644 |
| --- a/runtime/vm/isolate.h |
| +++ b/runtime/vm/isolate.h |
| @@ -26,6 +26,7 @@ class HandleScope; |
| class HandleVisitor; |
| class Heap; |
| class ICData; |
| +class Instance; |
| class LongJump; |
| class MessageHandler; |
| class Mutex; |
| @@ -49,30 +50,31 @@ class RawUint32x4; |
| // Used by the deoptimization infrastructure to defer allocation of unboxed |
| // objects until frame is fully rewritten and GC is safe. |
| -// See callers of Isolate::DeferObjectMaterialization. |
| -class DeferredObject { |
| +// Describes a stack slot that should be populated with a reference to the |
| +// materialized object. |
| +class DeferredSlot { |
| public: |
| - DeferredObject(RawInstance** slot, DeferredObject* next) |
| + DeferredSlot(RawInstance** slot, DeferredSlot* next) |
| : slot_(slot), next_(next) { } |
| - virtual ~DeferredObject() { } |
| + virtual ~DeferredSlot() { } |
| RawInstance** slot() const { return slot_; } |
| - DeferredObject* next() const { return next_; } |
| + DeferredSlot* next() const { return next_; } |
| virtual void Materialize() = 0; |
| private: |
| RawInstance** const slot_; |
| - DeferredObject* const next_; |
| + DeferredSlot* const next_; |
| - DISALLOW_COPY_AND_ASSIGN(DeferredObject); |
| + DISALLOW_COPY_AND_ASSIGN(DeferredSlot); |
| }; |
| -class DeferredDouble : public DeferredObject { |
| +class DeferredDouble : public DeferredSlot { |
| public: |
| - DeferredDouble(double value, RawInstance** slot, DeferredObject* next) |
| - : DeferredObject(slot, next), value_(value) { } |
| + DeferredDouble(double value, RawInstance** slot, DeferredSlot* next) |
| + : DeferredSlot(slot, next), value_(value) { } |
| virtual void Materialize(); |
| @@ -85,10 +87,10 @@ class DeferredDouble : public DeferredObject { |
| }; |
| -class DeferredMint : public DeferredObject { |
| +class DeferredMint : public DeferredSlot { |
| public: |
| - DeferredMint(int64_t value, RawInstance** slot, DeferredObject* next) |
| - : DeferredObject(slot, next), value_(value) { } |
| + DeferredMint(int64_t value, RawInstance** slot, DeferredSlot* next) |
| + : DeferredSlot(slot, next), value_(value) { } |
| virtual void Materialize(); |
| @@ -101,11 +103,11 @@ class DeferredMint : public DeferredObject { |
| }; |
| -class DeferredFloat32x4 : public DeferredObject { |
| +class DeferredFloat32x4 : public DeferredSlot { |
| public: |
| DeferredFloat32x4(simd128_value_t value, RawInstance** slot, |
| - DeferredObject* next) |
| - : DeferredObject(slot, next), value_(value) { } |
| + DeferredSlot* next) |
| + : DeferredSlot(slot, next), value_(value) { } |
| virtual void Materialize(); |
| @@ -118,11 +120,11 @@ class DeferredFloat32x4 : public DeferredObject { |
| }; |
| -class DeferredUint32x4 : public DeferredObject { |
| +class DeferredUint32x4 : public DeferredSlot { |
| public: |
| DeferredUint32x4(simd128_value_t value, RawInstance** slot, |
| - DeferredObject* next) |
| - : DeferredObject(slot, next), value_(value) { } |
| + DeferredSlot* next) |
| + : DeferredSlot(slot, next), value_(value) { } |
| virtual void Materialize(); |
| @@ -135,6 +137,81 @@ class DeferredUint32x4 : public DeferredObject { |
| }; |
| +// Describes a slot that contains a reference to an object that had its |
| +// allocation removed by AllocationSinking pass. |
| +// Object itself is described and materialized by DeferredObject. |
| +class DeferredObjectRef : public DeferredSlot { |
| + public: |
| + DeferredObjectRef(intptr_t index, RawInstance** slot, DeferredSlot* next) |
| + : DeferredSlot(slot, next), index_(index) { } |
| + |
| + virtual void Materialize(); |
| + |
| + intptr_t index() const { return index_; } |
| + |
| + private: |
| + const intptr_t index_; |
|
srdjan
2013/05/07 23:11:45
Add DISALLOW_COPY_...
Vyacheslav Egorov (Google)
2013/05/07 23:28:21
Done.
|
| +}; |
| + |
| + |
| +// Describes an object which allocation was removed by AllocationSinking pass. |
| +// Arguments for materialization are stored as a part of expression stack |
| +// for the bottommost deoptimized frame so that GC could discover them. |
| +// They will be removed from the stack at the very end of deoptimization. |
| +class DeferredObject { |
| + public: |
| + DeferredObject(intptr_t field_count, intptr_t* args) |
| + : field_count_(field_count), |
| + args_(reinterpret_cast<RawObject**>(args)), |
| + object_(NULL) { } |
| + |
| + intptr_t ArgumentCount() const { |
| + return kFieldsStartIndex + kFieldEntrySize * field_count_; |
| + } |
| + |
| + RawInstance* object(); |
| + |
| + private: |
| + enum { |
| + kClassIndex = 0, |
| + kFieldsStartIndex = kClassIndex + 1 |
| + }; |
| + |
| + enum { |
| + kFieldIndex = 0, |
| + kValueIndex, |
| + kFieldEntrySize, |
| + }; |
| + |
| + // Materializes the object. Returns amount of values that were consumed |
| + // and should be removed from the expression stack at the very end of |
| + // deoptimization. |
| + void Materialize(); |
| + |
| + RawObject* GetClass() const { |
| + return args_[kClassIndex]; |
| + } |
| + |
| + RawObject* GetField(intptr_t index) const { |
| + return args_[kFieldsStartIndex + kFieldEntrySize * index + kFieldIndex]; |
| + } |
| + |
| + RawObject* GetValue(intptr_t index) const { |
| + return args_[kFieldsStartIndex + kFieldEntrySize * index + kValueIndex]; |
| + } |
| + |
| + // Amount of fields that have to be initialized. |
| + const intptr_t field_count_; |
| + |
| + // Pointer to the first materialization argument on the stack. |
| + // The first argument is Class of the instance to materialize followed by |
| + // Field, value pairs. |
| + RawObject** args_; |
| + |
| + const Instance* object_; |
|
srdjan
2013/05/07 23:11:45
ditto
Vyacheslav Egorov (Google)
2013/05/07 23:28:21
Done.
|
| +}; |
| + |
| + |
| class Isolate : public BaseIsolate { |
| public: |
| ~Isolate(); |
| @@ -424,40 +501,78 @@ class Isolate : public BaseIsolate { |
| } |
| intptr_t deopt_frame_copy_size() const { return deopt_frame_copy_size_; } |
| + 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_objects_ = new DeferredDouble( |
| + deferred_boxes_ = new DeferredDouble( |
| value, |
| reinterpret_cast<RawInstance**>(slot), |
| - deferred_objects_); |
| + deferred_boxes_); |
| } |
| void DeferMintMaterialization(int64_t value, RawMint** slot) { |
| - deferred_objects_ = new DeferredMint(value, |
| - reinterpret_cast<RawInstance**>(slot), |
| - deferred_objects_); |
| + deferred_boxes_ = new DeferredMint( |
| + value, |
| + reinterpret_cast<RawInstance**>(slot), |
| + deferred_boxes_); |
| } |
| void DeferFloat32x4Materialization(simd128_value_t value, |
| RawFloat32x4** slot) { |
| - deferred_objects_ = new DeferredFloat32x4( |
| + deferred_boxes_ = new DeferredFloat32x4( |
| value, |
| reinterpret_cast<RawInstance**>(slot), |
| - deferred_objects_); |
| + deferred_boxes_); |
| } |
| void DeferUint32x4Materialization(simd128_value_t value, |
| RawUint32x4** slot) { |
| - deferred_objects_ = new DeferredUint32x4( |
| + deferred_boxes_ = new DeferredUint32x4( |
| value, |
| reinterpret_cast<RawInstance**>(slot), |
| - deferred_objects_); |
| + deferred_boxes_); |
| } |
| - DeferredObject* DetachDeferredObjects() { |
| - DeferredObject* list = deferred_objects_; |
| - deferred_objects_ = NULL; |
| - return list; |
| - } |
| + // 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); |
| @@ -511,7 +626,11 @@ class Isolate : public BaseIsolate { |
| fpu_register_t* deopt_fpu_registers_copy_; |
| intptr_t* deopt_frame_copy_; |
| intptr_t deopt_frame_copy_size_; |
| - DeferredObject* deferred_objects_; |
| + DeferredSlot* deferred_boxes_; |
| + DeferredSlot* deferred_object_refs_; |
| + |
| + intptr_t deferred_objects_count_; |
| + DeferredObject** deferred_objects_; |
| // Status support. |
| char* stacktrace_; |