Chromium Code Reviews| Index: runtime/vm/deopt_instructions.h |
| diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h |
| index 93def972d78d504f3e48674dd9b700c419c9e461..e0e81f820d4e90d7f14bdc06d8f06424dfef8f83 100644 |
| --- a/runtime/vm/deopt_instructions.h |
| +++ b/runtime/vm/deopt_instructions.h |
| @@ -10,6 +10,7 @@ |
| #include "vm/code_generator.h" |
| #include "vm/deferred_objects.h" |
| #include "vm/growable_array.h" |
| +#include "vm/locations.h" |
| #include "vm/object.h" |
| namespace dart { |
| @@ -70,13 +71,6 @@ class DeoptContext { |
| return *reinterpret_cast<double*>(&fpu_registers_[reg]); |
| } |
| - int64_t FpuRegisterValueAsInt64(FpuRegister reg) const { |
| - ASSERT(fpu_registers_ != NULL); |
| - ASSERT(reg >= 0); |
| - ASSERT(reg < kNumberOfFpuRegisters); |
| - return *reinterpret_cast<int64_t*>(&fpu_registers_[reg]); |
| - } |
| - |
| simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const { |
| ASSERT(fpu_registers_ != NULL); |
| ASSERT(reg >= 0); |
| @@ -120,7 +114,7 @@ class DeoptContext { |
| deferred_slots_); |
| } |
| - void DeferDoubleMaterialization(double value, RawDouble** slot) { |
| + void DeferMaterialization(double value, RawDouble** slot) { |
| deferred_slots_ = new DeferredDouble( |
| value, |
| reinterpret_cast<RawInstance**>(slot), |
| @@ -134,24 +128,21 @@ class DeoptContext { |
| deferred_slots_); |
| } |
| - void DeferFloat32x4Materialization(simd128_value_t value, |
| - RawFloat32x4** slot) { |
| + void DeferMaterialization(simd128_value_t value, RawFloat32x4** slot) { |
| deferred_slots_ = new DeferredFloat32x4( |
| value, |
| reinterpret_cast<RawInstance**>(slot), |
| deferred_slots_); |
| } |
| - void DeferFloat64x2Materialization(simd128_value_t value, |
| - RawFloat64x2** slot) { |
| + void DeferMaterialization(simd128_value_t value, RawFloat64x2** slot) { |
| deferred_slots_ = new DeferredFloat64x2( |
| value, |
| reinterpret_cast<RawInstance**>(slot), |
| deferred_slots_); |
| } |
| - void DeferInt32x4Materialization(simd128_value_t value, |
| - RawInt32x4** slot) { |
| + void DeferMaterialization(simd128_value_t value, RawInt32x4** slot) { |
| deferred_slots_ = new DeferredInt32x4( |
| value, |
| reinterpret_cast<RawInstance**>(slot), |
| @@ -221,23 +212,15 @@ class DeoptInstr : public ZoneAllocated { |
| enum Kind { |
| kRetAddress, |
| kConstant, |
| - kRegister, |
| - kFpuRegister, |
| - kFloat32x4FpuRegister, |
| - kFloat64x2FpuRegister, |
| - kInt32x4FpuRegister, |
| - kStackSlot, |
| - kDoubleStackSlot, |
| - kFloat32x4StackSlot, |
| - kFloat64x2StackSlot, |
| - kInt32x4StackSlot, |
| + kWord, |
| + kDouble, |
| + kFloat32x4, |
| + kFloat64x2, |
| + kInt32x4, |
| // Mints are split into low and high words. Each word can be in a register |
| // or stack slot. Note Mints are only used on 32-bit architectures. |
| - kMintRegisterPair, |
| - kMintStackSlotPair, |
| - kMintStackSlotRegister, |
| - kUint32Register, |
| - kUint32StackSlot, |
| + kMintPair, |
| + kUint32, |
| kPcMarker, |
| kPp, |
| kCallerFp, |
| @@ -253,7 +236,15 @@ class DeoptInstr : public ZoneAllocated { |
| DeoptInstr() {} |
| virtual ~DeoptInstr() {} |
| - virtual const char* ToCString() const = 0; |
| + virtual const char* ToCString() const { |
| + const char* args = ArgumentsToCString(); |
| + if (args != NULL) { |
| + return Isolate::Current()->current_zone()->PrintToString( |
| + "%s(%s)", KindToCString(kind()), args); |
| + } else { |
| + return KindToCString(kind()); |
| + } |
| + } |
| virtual void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) = 0; |
| @@ -285,11 +276,106 @@ class DeoptInstr : public ZoneAllocated { |
| virtual intptr_t source_index() const = 0; |
| + virtual const char* ArgumentsToCString() const { |
| + return NULL; |
| + } |
| + |
| private: |
| + static const char* KindToCString(Kind kind); |
| + |
| DISALLOW_COPY_AND_ASSIGN(DeoptInstr); |
| }; |
| +template<typename RegisterType, typename DestinationType> struct SourceReader; |
| + |
| +template<typename T> |
| +struct SourceReader<Register, T> { |
| + static intptr_t Read(DeoptContext* context, Register reg) { |
| + return context->RegisterValue(reg); |
| + } |
| +}; |
| + |
| +template<> |
| +struct SourceReader<FpuRegister, double> { |
| + static double Read(DeoptContext* context, FpuRegister reg) { |
| + return context->FpuRegisterValue(reg); |
| + } |
| +}; |
| + |
| + |
| +template<> |
| +struct SourceReader<FpuRegister, simd128_value_t> { |
| + static simd128_value_t Read(DeoptContext* context, FpuRegister reg) { |
| + return context->FpuRegisterValueAsSimd128(reg); |
| + } |
| +}; |
| + |
| + |
| +template<typename RegisterType> |
| +class GenericDeoptSource { |
| + public: |
| + enum Kind { |
| + kStackSlot = 0, |
| + kRegister = 1 |
| + }; |
| + |
| + explicit GenericDeoptSource(intptr_t source_index) |
|
Florian Schneider
2014/08/22 17:05:45
Is this constructor used at all, or is is dead cod
Vyacheslav Egorov (Google)
2014/08/23 00:26:45
It is used when deserializing deopt instructions.
|
| + : source_index_(source_index) { } |
| + |
| + GenericDeoptSource(Kind kind, intptr_t index) |
| + : source_index_(IsRegister::encode(kind) | RawIndex::encode(index)) { |
| + } |
| + |
| + template<typename T> |
| + T Value(DeoptContext* context) const { |
| + if (is_register()) { |
| + return static_cast<T>(SourceReader<RegisterType, T>::Read( |
| + context, reg())); |
| + } else { |
| + return *reinterpret_cast<T*>(context->GetSourceFrameAddressAt( |
| + context->source_frame_size() - raw_index() - 1)); |
| + } |
| + } |
| + |
| + intptr_t source_index() const { return source_index_; } |
| + |
| + const char* ToCString() const { |
| + if (is_register()) { |
| + return Name(reg()); |
| + } else { |
| + return Isolate::Current()->current_zone()->PrintToString( |
| + "s%" Pd "", raw_index()); |
| + } |
| + } |
| + |
| + private: |
| + class IsRegister : public BitField<intptr_t, 0, 1> { }; |
| + class RawIndex : public BitField<intptr_t, 1, kBitsPerWord - 1> { }; |
| + |
| + bool is_register() const { |
| + return IsRegister::decode(source_index_) == kRegister; |
| + } |
| + intptr_t raw_index() const { return RawIndex::decode(source_index_); } |
| + |
| + RegisterType reg() const { return static_cast<RegisterType>(raw_index()); } |
| + |
| + static const char* Name(Register reg) { |
| + return Assembler::RegisterName(reg); |
| + } |
| + |
| + static const char* Name(FpuRegister fpu_reg) { |
| + return Assembler::FpuRegisterName(fpu_reg); |
| + } |
| + |
| + const intptr_t source_index_; |
| +}; |
| + |
| + |
| +typedef GenericDeoptSource<Register> MachineWordSource; |
| +typedef GenericDeoptSource<FpuRegister> MachineFpuSource; |
| + |
| + |
| // Builds a deoptimization info table, one DeoptInfo at a time. Call AddXXX |
| // methods in the order of their target, starting wih deoptimized code |
| // continuation pc and ending with the first argument of the deoptimized |
| @@ -342,6 +428,10 @@ class DeoptInfoBuilder : public ValueObject { |
| private: |
| class TrieNode; |
| + MachineWordSource ToMachineWordSource(const Location& loc); |
| + MachineFpuSource ToMachineFpuSource(const Location& loc, |
| + Location::Kind expected_stack_slot_kind); |
| + |
| intptr_t FindOrAddObjectInTable(const Object& obj) const; |
| intptr_t FindMaterialization(MaterializeObjectInstr* mat) const; |
| intptr_t CalculateStackIndex(const Location& source_loc) const; |