frame-states.h 6.97 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_FRAME_STATES_H_
#define V8_COMPILER_FRAME_STATES_H_

8
#include "src/builtins/builtins.h"
9
#include "src/compiler/node.h"
10
#include "src/handles/handles.h"
11
#include "src/objects/shared-function-info.h"
12
#include "src/utils/utils.h"
13 14 15

namespace v8 {
namespace internal {
16

17 18 19 20 21
namespace wasm {
class ValueType;
using FunctionSig = Signature<ValueType>;
}  // namespace wasm

22 23
namespace compiler {

24 25
class JSGraph;
class Node;
26
class SharedFunctionInfoRef;
27

28 29 30 31
// Flag that describes how to combine the current environment with
// the output of a node to obtain a framestate for lazy bailout.
class OutputFrameStateCombine {
 public:
32
  static const size_t kInvalidIndex = SIZE_MAX;
33 34

  static OutputFrameStateCombine Ignore() {
35
    return OutputFrameStateCombine(kInvalidIndex);
36 37
  }
  static OutputFrameStateCombine PokeAt(size_t index) {
38
    return OutputFrameStateCombine(index);
39 40 41
  }

  size_t GetOffsetToPokeAt() const {
42
    DCHECK_NE(parameter_, kInvalidIndex);
43 44 45
    return parameter_;
  }

46
  bool IsOutputIgnored() const { return parameter_ == kInvalidIndex; }
47

48
  size_t ConsumedOutputCount() const { return IsOutputIgnored() ? 0 : 1; }
49 50

  bool operator==(OutputFrameStateCombine const& other) const {
51
    return parameter_ == other.parameter_;
52 53 54 55 56 57 58 59 60 61
  }
  bool operator!=(OutputFrameStateCombine const& other) const {
    return !(*this == other);
  }

  friend size_t hash_value(OutputFrameStateCombine const&);
  friend std::ostream& operator<<(std::ostream&,
                                  OutputFrameStateCombine const&);

 private:
62
  explicit OutputFrameStateCombine(size_t parameter) : parameter_(parameter) {}
63 64 65 66 67 68

  size_t const parameter_;
};


// The type of stack frame that a FrameState node represents.
69
enum class FrameStateType {
70
  kUnoptimizedFunction,            // Represents an UnoptimizedFrame.
71
  kInlinedExtraArguments,          // Represents inlined extra arguments.
72 73
  kConstructStub,                  // Represents a ConstructStubFrame.
  kBuiltinContinuation,            // Represents a continuation to a stub.
74
#if V8_ENABLE_WEBASSEMBLY          // ↓ WebAssembly only
75 76
  kJSToWasmBuiltinContinuation,    // Represents a lazy deopt continuation for a
                                   // JS to Wasm call.
77
#endif                             // ↑ WebAssembly only
78 79 80 81 82
  kJavaScriptBuiltinContinuation,  // Represents a continuation to a JavaScipt
                                   // builtin.
  kJavaScriptBuiltinContinuationWithCatch  // Represents a continuation to a
                                           // JavaScipt builtin with a catch
                                           // handler.
83 84
};

85
class FrameStateFunctionInfo {
86
 public:
87 88
  FrameStateFunctionInfo(FrameStateType type, int parameter_count,
                         int local_count,
89
                         Handle<SharedFunctionInfo> shared_info)
90
      : type_(type),
91 92
        parameter_count_(parameter_count),
        local_count_(local_count),
93
        shared_info_(shared_info) {}
94

95 96 97
  int local_count() const { return local_count_; }
  int parameter_count() const { return parameter_count_; }
  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
98
  FrameStateType type() const { return type_; }
99

100
  static bool IsJSFunctionType(FrameStateType type) {
101
    return type == FrameStateType::kUnoptimizedFunction ||
102 103
           type == FrameStateType::kJavaScriptBuiltinContinuation ||
           type == FrameStateType::kJavaScriptBuiltinContinuationWithCatch;
104 105
  }

106 107 108 109 110 111 112
 private:
  FrameStateType const type_;
  int const parameter_count_;
  int const local_count_;
  Handle<SharedFunctionInfo> const shared_info_;
};

113
#if V8_ENABLE_WEBASSEMBLY
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
class JSToWasmFrameStateFunctionInfo : public FrameStateFunctionInfo {
 public:
  JSToWasmFrameStateFunctionInfo(FrameStateType type, int parameter_count,
                                 int local_count,
                                 Handle<SharedFunctionInfo> shared_info,
                                 const wasm::FunctionSig* signature)
      : FrameStateFunctionInfo(type, parameter_count, local_count, shared_info),
        signature_(signature) {
    DCHECK_NOT_NULL(signature);
  }

  const wasm::FunctionSig* signature() const { return signature_; }

 private:
  const wasm::FunctionSig* const signature_;
};
130
#endif  // V8_ENABLE_WEBASSEMBLY
131 132 133

class FrameStateInfo final {
 public:
134 135
  FrameStateInfo(BytecodeOffset bailout_id,
                 OutputFrameStateCombine state_combine,
136 137 138 139 140 141
                 const FrameStateFunctionInfo* info)
      : bailout_id_(bailout_id),
        frame_state_combine_(state_combine),
        info_(info) {}

  FrameStateType type() const {
142
    return info_ == nullptr ? FrameStateType::kUnoptimizedFunction
143 144
                            : info_->type();
  }
145
  BytecodeOffset bailout_id() const { return bailout_id_; }
146
  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
147 148 149 150 151 152 153 154 155 156
  MaybeHandle<SharedFunctionInfo> shared_info() const {
    return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
                            : info_->shared_info();
  }
  int parameter_count() const {
    return info_ == nullptr ? 0 : info_->parameter_count();
  }
  int local_count() const {
    return info_ == nullptr ? 0 : info_->local_count();
  }
157 158 159
  int stack_count() const {
    return type() == FrameStateType::kUnoptimizedFunction ? 1 : 0;
  }
160
  const FrameStateFunctionInfo* function_info() const { return info_; }
161 162

 private:
163
  BytecodeOffset const bailout_id_;
164
  OutputFrameStateCombine const frame_state_combine_;
165
  const FrameStateFunctionInfo* const info_;
166 167
};

168 169
bool operator==(FrameStateInfo const&, FrameStateInfo const&);
bool operator!=(FrameStateInfo const&, FrameStateInfo const&);
170

171
size_t hash_value(FrameStateInfo const&);
172

173
std::ostream& operator<<(std::ostream&, FrameStateInfo const&);
174

175
enum class ContinuationFrameStateMode { EAGER, LAZY, LAZY_WITH_CATCH };
176

177 178
class FrameState;

179
FrameState CreateStubBuiltinContinuationFrameState(
180
    JSGraph* graph, Builtin name, Node* context, Node* const* parameters,
181
    int parameter_count, Node* outer_frame_state,
182 183 184
    ContinuationFrameStateMode mode,
    const wasm::FunctionSig* signature = nullptr);

185
#if V8_ENABLE_WEBASSEMBLY
186 187 188
FrameState CreateJSWasmCallBuiltinContinuationFrameState(
    JSGraph* jsgraph, Node* context, Node* outer_frame_state,
    const wasm::FunctionSig* signature);
189
#endif  // V8_ENABLE_WEBASSEMBLY
190

191
FrameState CreateJavaScriptBuiltinContinuationFrameState(
192
    JSGraph* graph, const SharedFunctionInfoRef& shared, Builtin name,
193
    Node* target, Node* context, Node* const* stack_parameters,
194 195 196
    int stack_parameter_count, Node* outer_frame_state,
    ContinuationFrameStateMode mode);

197
FrameState CreateGenericLazyDeoptContinuationFrameState(
198 199 200
    JSGraph* graph, const SharedFunctionInfoRef& shared, Node* target,
    Node* context, Node* receiver, Node* outer_frame_state);

201 202 203 204 205
}  // namespace compiler
}  // namespace internal
}  // namespace v8

#endif  // V8_COMPILER_FRAME_STATES_H_