Index: runtime/vm/deopt_instructions.h |
=================================================================== |
--- runtime/vm/deopt_instructions.h (revision 28111) |
+++ runtime/vm/deopt_instructions.h (working copy) |
@@ -8,6 +8,7 @@ |
#include "vm/allocation.h" |
#include "vm/assembler.h" |
#include "vm/code_generator.h" |
+#include "vm/deferred_objects.h" |
#include "vm/growable_array.h" |
#include "vm/object.h" |
@@ -18,75 +19,167 @@ |
class MaterializeObjectInstr; |
// Holds all data relevant for execution of deoptimization instructions. |
-class DeoptimizationContext : public ValueObject { |
+class DeoptContext { |
public: |
- // 'to_frame_start' points to the fixed size portion of the frame under sp. |
// 'num_args' is 0 if there are no arguments or if there are optional |
// arguments. |
- DeoptimizationContext(intptr_t* to_frame_start, |
- intptr_t to_frame_size, |
- const Array& object_table, |
- intptr_t num_args, |
- DeoptReasonId deopt_reason); |
+ DeoptContext(const Array& object_table, |
+ intptr_t num_args, |
+ DeoptReasonId deopt_reason); |
- intptr_t* GetFromFrameAddressAt(intptr_t index) const { |
- ASSERT((0 <= index) && (index < from_frame_size_)); |
- return &from_frame_[index]; |
+ virtual ~DeoptContext(); |
+ |
+ // Sets the sources (frame and registers) for this deoptimization. |
+ // |
+ // if 'frame_is_copy' is true, DeoptContext will delete the frame |
+ // when it is done. |
+ void SetSourceArgs(intptr_t* frame_start, |
+ intptr_t frame_size, |
+ fpu_register_t* fpu_registers, |
+ intptr_t* cpu_registers, |
+ bool frame_is_copy); |
+ |
+ // Sets the destination fraem for this deoptimization. |
+ // |
+ // 'frame_start' oints to the fixed size portion of the frame under |
+ // sp. |
+ // |
+ // DeoptContext does not claim ownership of the frame memory. |
+ void SetDestArgs(intptr_t* frame_start, intptr_t frame_size); |
+ |
+ intptr_t* GetSourceFrameAddressAt(intptr_t index) const { |
+ ASSERT(source_frame_ != NULL); |
+ ASSERT((0 <= index) && (index < source_frame_size_)); |
+ return &source_frame_[index]; |
} |
- intptr_t* GetToFrameAddressAt(intptr_t index) const { |
- ASSERT((0 <= index) && (index < to_frame_size_)); |
- return &to_frame_[index]; |
+ intptr_t* GetDestFrameAddressAt(intptr_t index) const { |
+ ASSERT(dest_frame_ != NULL); |
+ ASSERT((0 <= index) && (index < dest_frame_size_)); |
+ return &dest_frame_[index]; |
} |
- intptr_t GetFromFp() const; |
- intptr_t GetFromPp() const; |
- intptr_t GetFromPc() const; |
+ intptr_t GetSourceFp() const; |
+ intptr_t GetSourcePp() const; |
+ intptr_t GetSourcePc() const; |
intptr_t GetCallerFp() const; |
void SetCallerFp(intptr_t callers_fp); |
RawObject* ObjectAt(intptr_t index) const { |
- return object_table_.At(index); |
+ const Array& object_table = Array::Handle(object_table_); |
+ return object_table.At(index); |
} |
intptr_t RegisterValue(Register reg) const { |
- return registers_copy_[reg]; |
+ return cpu_registers_[reg]; |
} |
double FpuRegisterValue(FpuRegister reg) const { |
- return *reinterpret_cast<double*>(&fpu_registers_copy_[reg]); |
+ return *reinterpret_cast<double*>(&fpu_registers_[reg]); |
} |
int64_t FpuRegisterValueAsInt64(FpuRegister reg) const { |
- return *reinterpret_cast<int64_t*>(&fpu_registers_copy_[reg]); |
+ return *reinterpret_cast<int64_t*>(&fpu_registers_[reg]); |
} |
simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { |
- const float* address = reinterpret_cast<float*>(&fpu_registers_copy_[reg]); |
+ const float* address = reinterpret_cast<float*>(&fpu_registers_[reg]); |
return simd128_value_t().readFrom(address); |
} |
Isolate* isolate() const { return isolate_; } |
- intptr_t from_frame_size() const { return from_frame_size_; } |
+ intptr_t source_frame_size() const { return source_frame_size_; } |
DeoptReasonId deopt_reason() const { return deopt_reason_; } |
+ void VisitObjectPointers(ObjectPointerVisitor* visitor); |
+ |
+ void PrepareForDeferredMaterialization(intptr_t count) { |
+ if (count > 0) { |
+ deferred_objects_ = new DeferredObject*[count]; |
+ deferred_objects_count_ = count; |
+ } |
+ } |
+ |
+ DeferredObject* GetDeferredObject(intptr_t idx) const { |
+ return deferred_objects_[idx]; |
+ } |
+ |
+ // Sets the materialized value for some deferred object. |
+ // |
+ // Claims ownership of the memory for 'object'. |
+ 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_); |
+ } |
+ |
+ // Materializes all deferred objects. Returns the total number of |
+ // artificial arguments used during deoptimization. |
+ intptr_t MaterializeDeferredObjects(); |
+ |
private: |
- const Array& object_table_; |
- intptr_t* to_frame_; |
- const intptr_t to_frame_size_; |
- intptr_t* from_frame_; |
- intptr_t from_frame_size_; |
- intptr_t* registers_copy_; |
- fpu_register_t* fpu_registers_copy_; |
+ RawArray* object_table_; |
+ intptr_t* dest_frame_; |
+ intptr_t dest_frame_size_; |
+ bool source_frame_is_copy_; |
+ intptr_t* source_frame_; |
+ intptr_t source_frame_size_; |
+ intptr_t* cpu_registers_; |
+ fpu_register_t* fpu_registers_; |
const intptr_t num_args_; |
const DeoptReasonId deopt_reason_; |
intptr_t caller_fp_; |
Isolate* isolate_; |
- DISALLOW_COPY_AND_ASSIGN(DeoptimizationContext); |
+ DeferredSlot* deferred_boxes_; |
+ DeferredSlot* deferred_object_refs_; |
+ |
+ intptr_t deferred_objects_count_; |
+ DeferredObject** deferred_objects_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(DeoptContext); |
}; |
@@ -119,25 +212,24 @@ |
kMaterializeObject |
}; |
- static DeoptInstr* Create(intptr_t kind_as_int, intptr_t from_index); |
+ static DeoptInstr* Create(intptr_t kind_as_int, intptr_t source_index); |
DeoptInstr() {} |
virtual ~DeoptInstr() {} |
virtual const char* ToCString() const = 0; |
- virtual void Execute(DeoptimizationContext* deopt_context, |
- intptr_t* to_addr) = 0; |
+ virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0; |
virtual DeoptInstr::Kind kind() const = 0; |
bool Equals(const DeoptInstr& other) const { |
- return (kind() == other.kind()) && (from_index() == other.from_index()); |
+ return (kind() == other.kind()) && (source_index() == other.source_index()); |
} |
// Decode the payload of a suffix command. Return the suffix length and |
// set the output parameter info_number to the index of the shared suffix. |
- static intptr_t DecodeSuffix(intptr_t from_index, intptr_t* info_number); |
+ static intptr_t DecodeSuffix(intptr_t source_index, intptr_t* info_number); |
// Get the function and return address which is encoded in this |
// kRetAfterAddress deopt instruction. |
@@ -149,13 +241,13 @@ |
// materialized by kMaterializeObject instruction. |
static intptr_t GetFieldCount(DeoptInstr* instr) { |
ASSERT(instr->kind() == DeoptInstr::kMaterializeObject); |
- return instr->from_index(); |
+ return instr->source_index(); |
} |
protected: |
friend class DeoptInfoBuilder; |
- virtual intptr_t from_index() const = 0; |
+ virtual intptr_t source_index() const = 0; |
private: |
DISALLOW_COPY_AND_ASSIGN(DeoptInstr); |
@@ -178,15 +270,15 @@ |
// Return address before instruction. |
void AddReturnAddress(const Function& function, |
intptr_t deopt_id, |
- intptr_t to_index); |
+ intptr_t dest_index); |
// Copy from optimized frame to unoptimized. |
- void AddCopy(Value* value, const Location& from_loc, intptr_t to_index); |
- void AddPcMarker(const Function& function, intptr_t to_index); |
- void AddPp(const Function& function, intptr_t to_index); |
- void AddCallerFp(intptr_t to_index); |
- void AddCallerPp(intptr_t to_index); |
- void AddCallerPc(intptr_t to_index); |
+ void AddCopy(Value* value, const Location& source_loc, intptr_t dest_index); |
+ void AddPcMarker(const Function& function, intptr_t dest_index); |
+ void AddPp(const Function& function, intptr_t dest_index); |
+ void AddCallerFp(intptr_t dest_index); |
+ void AddCallerPp(intptr_t dest_index); |
+ void AddCallerPc(intptr_t dest_index); |
// Add object to be materialized. Emit kMaterializeObject instruction. |
void AddMaterialization(MaterializeObjectInstr* mat); |
@@ -200,7 +292,7 @@ |
// At deoptimization they will be removed by the stub at the very end: |
// after they were used to materialize objects. |
// Returns the index of the next stack slot. Used for verification. |
- intptr_t EmitMaterializationArguments(intptr_t to_index); |
+ intptr_t EmitMaterializationArguments(intptr_t dest_index); |
RawDeoptInfo* CreateDeoptInfo(const Array& deopt_table); |
@@ -216,13 +308,13 @@ |
intptr_t FindOrAddObjectInTable(const Object& obj) const; |
intptr_t FindMaterialization(MaterializeObjectInstr* mat) const; |
- intptr_t CalculateStackIndex(const Location& from_loc) const; |
+ intptr_t CalculateStackIndex(const Location& source_loc) const; |
intptr_t FrameSize() const { |
return instructions_.length() - frame_start_; |
} |
- void AddConstant(const Object& obj, intptr_t to_index); |
+ void AddConstant(const Object& obj, intptr_t dest_index); |
GrowableArray<DeoptInstr*> instructions_; |
const GrowableObjectArray& object_table_; |