diff options
Diffstat (limited to 'src/deoptimizer.h')
-rw-r--r-- | src/deoptimizer.h | 82 |
1 files changed, 63 insertions, 19 deletions
diff --git a/src/deoptimizer.h b/src/deoptimizer.h index 4d84fb76..5501ca6c 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; }; @@ -195,7 +226,8 @@ class TranslatedFrame { static TranslatedFrame ArgumentsAdaptorFrame(SharedFunctionInfo* shared_info, int height); static TranslatedFrame TailCallerFrame(SharedFunctionInfo* shared_info); - static TranslatedFrame ConstructStubFrame(SharedFunctionInfo* shared_info, + static TranslatedFrame ConstructStubFrame(BailoutId bailout_id, + SharedFunctionInfo* shared_info, int height); static TranslatedFrame CompiledStubFrame(int height, Isolate* isolate) { return TranslatedFrame(kCompiledStub, isolate, nullptr, height); @@ -254,7 +286,7 @@ class TranslatedState { void Prepare(bool has_adapted_arguments, Address stack_frame_pointer); // Store newly materialized values into the isolate. - void StoreMaterializedValuesAndDeopt(); + void StoreMaterializedValuesAndDeopt(JavaScriptFrame* frame); typedef std::vector<TranslatedFrame>::iterator iterator; iterator begin() { return frames_.begin(); } @@ -292,9 +324,14 @@ class TranslatedState { void UpdateFromPreviouslyMaterializedObjects(); Handle<Object> MaterializeAt(int frame_index, int* value_index); Handle<Object> MaterializeObjectAt(int object_index); + class CapturedObjectMaterializer; + Handle<Object> MaterializeCapturedObjectAt(TranslatedValue* slot, + int frame_index, int* value_index); 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_; @@ -419,8 +456,9 @@ class Deoptimizer : public Malloced { // Deoptimize the function now. Its current optimized code will never be run // again and any activations of the optimized code will get deoptimized when - // execution returns. - static void DeoptimizeFunction(JSFunction* function); + // execution returns. If {code} is specified then the given code is targeted + // instead of the function code (e.g. OSR code not installed on function). + static void DeoptimizeFunction(JSFunction* function, Code* code = nullptr); // Deoptimize all code in the given isolate. static void DeoptimizeAll(Isolate* isolate); @@ -648,12 +686,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]; } @@ -663,19 +701,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]; }; @@ -728,7 +771,7 @@ class FrameDescription { return register_values_.GetRegister(n); } - double GetDoubleRegister(unsigned n) const { + Float64 GetDoubleRegister(unsigned n) const { return register_values_.GetDoubleRegister(n); } @@ -736,7 +779,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); } @@ -932,7 +975,8 @@ class Translation BASE_EMBEDDED { void BeginCompiledStubFrame(int height); void BeginArgumentsAdaptorFrame(int literal_id, unsigned height); void BeginTailCallerFrame(int literal_id); - void BeginConstructStubFrame(int literal_id, unsigned height); + void BeginConstructStubFrame(BailoutId bailout_id, int literal_id, + unsigned height); void BeginGetterStubFrame(int literal_id); void BeginSetterStubFrame(int literal_id); void BeginArgumentsObject(int args_length); |