Index: src/deoptimizer.h |
diff --git a/src/deoptimizer.h b/src/deoptimizer.h |
index 7d74af9958ff9064c21d3c95a55c105d91830d37..b65d705a16e3b9060f04d301d3620c530f18b36b 100644 |
--- a/src/deoptimizer.h |
+++ b/src/deoptimizer.h |
@@ -20,6 +20,37 @@ class DeoptimizedFrameInfo; |
class TranslatedState; |
class RegisterValues; |
+// Safety wrapper for a 32-bit floating-point value to make sure we don't loose |
+// the exact bit pattern during deoptimization when passing this value. Note |
+// that there is intentionally no way to construct it from a {float} value. |
+class Float32 { |
+ public: |
+ Float32() : bit_pattern_(0) {} |
+ uint32_t get_bits() const { return bit_pattern_; } |
+ float get_scalar() const { return bit_cast<float>(bit_pattern_); } |
+ static Float32 FromBits(uint32_t bits) { return Float32(bits); } |
+ |
+ private: |
+ explicit Float32(uint32_t bit_pattern) : bit_pattern_(bit_pattern) {} |
+ uint32_t bit_pattern_; |
+}; |
+ |
+// Safety wrapper for a 64-bit floating-point value to make sure we don't loose |
+// the exact bit pattern during deoptimization when passing this value. Note |
+// that there is intentionally no way to construct it from a {double} value. |
+class Float64 { |
+ public: |
+ Float64() : bit_pattern_(0) {} |
+ uint64_t get_bits() const { return bit_pattern_; } |
+ double get_scalar() const { return bit_cast<double>(bit_pattern_); } |
+ bool is_hole_nan() const { return bit_pattern_ == kHoleNanInt64; } |
+ static Float64 FromBits(uint64_t bits) { return Float64(bits); } |
+ |
+ private: |
+ explicit Float64(uint64_t bit_pattern) : bit_pattern_(bit_pattern) {} |
+ uint64_t bit_pattern_; |
+}; |
+ |
class TranslatedValue { |
public: |
// Allocation-less getter of the value. |
@@ -64,8 +95,8 @@ class TranslatedValue { |
static TranslatedValue NewDeferredObject(TranslatedState* container, |
int length, int object_index); |
static TranslatedValue NewDuplicateObject(TranslatedState* container, int id); |
- static TranslatedValue NewFloat(TranslatedState* container, float value); |
- static TranslatedValue NewDouble(TranslatedState* container, double value); |
+ static TranslatedValue NewFloat(TranslatedState* container, Float32 value); |
+ static TranslatedValue NewDouble(TranslatedState* container, Float64 value); |
static TranslatedValue NewInt32(TranslatedState* container, int32_t value); |
static TranslatedValue NewUInt32(TranslatedState* container, uint32_t value); |
static TranslatedValue NewBool(TranslatedState* container, uint32_t value); |
@@ -98,9 +129,9 @@ class TranslatedValue { |
// kind is kInt32. |
int32_t int32_value_; |
// kind is kFloat |
- float float_value_; |
+ Float32 float_value_; |
// kind is kDouble |
- double double_value_; |
+ Float64 double_value_; |
// kind is kDuplicatedObject or kArgumentsObject or kCapturedObject. |
MaterializedObjectInfo materialization_info_; |
}; |
@@ -109,8 +140,8 @@ class TranslatedValue { |
Object* raw_literal() const; |
int32_t int32_value() const; |
uint32_t uint32_value() const; |
- float float_value() const; |
- double double_value() const; |
+ Float32 float_value() const; |
+ Float64 double_value() const; |
int object_length() const; |
int object_index() const; |
}; |
@@ -298,6 +329,8 @@ class TranslatedState { |
bool GetAdaptedArguments(Handle<JSObject>* result, int frame_index); |
static uint32_t GetUInt32Slot(Address fp, int slot_index); |
+ static Float32 GetFloatSlot(Address fp, int slot_index); |
+ static Float64 GetDoubleSlot(Address fp, int slot_index); |
std::vector<TranslatedFrame> frames_; |
Isolate* isolate_; |
@@ -652,12 +685,12 @@ class RegisterValues { |
return registers_[n]; |
} |
- float GetFloatRegister(unsigned n) const { |
+ Float32 GetFloatRegister(unsigned n) const { |
DCHECK(n < arraysize(float_registers_)); |
return float_registers_[n]; |
} |
- double GetDoubleRegister(unsigned n) const { |
+ Float64 GetDoubleRegister(unsigned n) const { |
DCHECK(n < arraysize(double_registers_)); |
return double_registers_[n]; |
} |
@@ -667,19 +700,24 @@ class RegisterValues { |
registers_[n] = value; |
} |
- void SetFloatRegister(unsigned n, float value) { |
+ void SetFloatRegister(unsigned n, Float32 value) { |
DCHECK(n < arraysize(float_registers_)); |
float_registers_[n] = value; |
} |
- void SetDoubleRegister(unsigned n, double value) { |
+ void SetDoubleRegister(unsigned n, Float64 value) { |
DCHECK(n < arraysize(double_registers_)); |
double_registers_[n] = value; |
} |
+ // Generated code is writing directly into the below arrays, make sure their |
+ // element sizes fit what the machine instructions expect. |
+ static_assert(sizeof(Float32) == kFloatSize, "size mismatch"); |
+ static_assert(sizeof(Float64) == kDoubleSize, "size mismatch"); |
+ |
intptr_t registers_[Register::kNumRegisters]; |
- float float_registers_[FloatRegister::kMaxNumRegisters]; |
- double double_registers_[DoubleRegister::kMaxNumRegisters]; |
+ Float32 float_registers_[FloatRegister::kMaxNumRegisters]; |
+ Float64 double_registers_[DoubleRegister::kMaxNumRegisters]; |
}; |
@@ -732,7 +770,7 @@ class FrameDescription { |
return register_values_.GetRegister(n); |
} |
- double GetDoubleRegister(unsigned n) const { |
+ Float64 GetDoubleRegister(unsigned n) const { |
return register_values_.GetDoubleRegister(n); |
} |
@@ -740,7 +778,7 @@ class FrameDescription { |
register_values_.SetRegister(n, value); |
} |
- void SetDoubleRegister(unsigned n, double value) { |
+ void SetDoubleRegister(unsigned n, Float64 value) { |
register_values_.SetDoubleRegister(n, value); |
} |