aboutsummaryrefslogtreecommitdiff
path: root/src/deoptimizer.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/deoptimizer.h')
-rw-r--r--src/deoptimizer.h82
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);