Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2034)

Unified Diff: runtime/vm/deopt_instructions.h

Issue 462403004: Refactor deopt_instructions.cc to minimize boilerplate and duplication. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | runtime/vm/deopt_instructions.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
« no previous file with comments | « no previous file | runtime/vm/deopt_instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698