v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
deoptimization-data.h
Go to the documentation of this file.
1// Copyright 2023 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_OBJECTS_DEOPTIMIZATION_DATA_H_
6#define V8_OBJECTS_DEOPTIMIZATION_DATA_H_
7
8#include <vector>
9
13
14// Has to be the last include (doesn't have include guards):
16
17namespace v8 {
18namespace internal {
19
20// This class holds data required during deoptimization. It does not have its
21// own instance type.
23 public:
24 // Getters for literals. These include runtime checks that the pointer was not
25 // cleared, if the literal was held weakly.
26 inline Tagged<Object> get(int index) const;
27 inline Tagged<Object> get(PtrComprCageBase cage_base, int index) const;
28
29 // TODO(jgruber): Swap these names around. It's confusing that this
30 // WeakFixedArray subclass redefines `get` with different semantics.
31 inline Tagged<MaybeObject> get_raw(int index) const;
32
33 // Setter for literals. This will set the object as strong or weak depending
34 // on InstructionStream::IsWeakObjectInOptimizedCode.
35 inline void set(int index, Tagged<Object> value);
36};
37
39
41 kObject,
42 kNumber,
47
48 // These kinds are used by wasm only (as unoptimized JS doesn't have these
49 // types).
55};
56
57// A deoptimization literal during code generation. For JS this is transformed
58// into a heap object after code generation. For wasm the DeoptimizationLiteral
59// is directly used by the deoptimizer.
61 public:
72 explicit DeoptimizationLiteral(double number)
74 explicit DeoptimizationLiteral(int64_t signed_bigint64)
76 int64_(signed_bigint64) {}
77 explicit DeoptimizationLiteral(uint64_t unsigned_bigint64)
79 uint64_(unsigned_bigint64) {}
80 explicit DeoptimizationLiteral(int32_t int32)
84
90
92
93 bool operator==(const DeoptimizationLiteral& other) const {
94 if (kind_ != other.kind_) {
95 return false;
96 }
97 switch (kind_) {
99 return object_.equals(other.object_);
102 base::bit_cast<uint64_t>(other.number_);
106 return int64_ == other.int64_;
108 return uint64_ == other.uint64_;
110 return other.kind() == DeoptimizationLiteralKind::kHoleNaN;
112 return true;
114 return float32_.get_bits() == other.float32_.get_bits();
116 return float64_.get_bits() == other.float64_.get_bits();
117 }
118 UNREACHABLE();
119 }
120
121 DirectHandle<Object> Reify(Isolate* isolate) const;
122
123#if V8_ENABLE_WEBASSEMBLY
124 Float64 GetFloat64() const {
126 return float64_;
127 }
128
129 Float32 GetFloat32() const {
131 return float32_;
132 }
133
134 int64_t GetInt64() const {
136 return int64_;
137 }
138
139 int32_t GetInt32() const {
141 return static_cast<int32_t>(int64_);
142 }
143
144 Tagged<Smi> GetSmi() const {
146 return Smi::FromInt(static_cast<int>(int64_));
147 }
148#endif
149
153
155 Validate();
156 return kind_;
157 }
158
159 private:
161
162 union {
164 double number_;
167 int64_t int64_;
168 uint64_t uint64_;
169 };
170};
171
172// The DeoptimizationFrameTranslation is the on-heap representation of
173// translations created during code generation in a (zone-allocated)
174// DeoptimizationFrameTranslationBuilder. The translation specifies how to
175// transform an optimized frame back into one or more unoptimized frames.
176enum class TranslationOpcode;
178 public:
183
184 class Iterator;
185
186#ifdef V8_USE_ZLIB
187 // Constants describing compressed DeoptimizationFrameTranslation layout. Only
188 // relevant if
189 // --turbo-compress-frame-translation is enabled.
190 static constexpr int kUncompressedSizeOffset = 0;
191 static constexpr int kUncompressedSizeSize = kInt32Size;
192 static constexpr int kCompressedDataOffset =
193 kUncompressedSizeOffset + kUncompressedSizeSize;
194 static constexpr int kDeoptimizationFrameTranslationElementSize = kInt32Size;
195#endif // V8_USE_ZLIB
196
197#ifdef ENABLE_DISASSEMBLER
198 void PrintFrameTranslation(
199 std::ostream& os, int index,
200 Tagged<ProtectedDeoptimizationLiteralArray> protected_literal_array,
201 Tagged<DeoptimizationLiteralArray> literal_array) const;
202#endif
203};
204
206 public:
208
209 int32_t NextOperand();
210
211 uint32_t NextOperandUnsigned();
212
214
216
219
220 bool HasNextOpcode() const;
221
222 void SkipOperands(int n) {
223 for (int i = 0; i < n; i++) NextOperand();
224 }
225
226 private:
230
231 std::vector<int32_t> uncompressed_contents_;
234
235 // This decrementing counter indicates how many more times to read operations
236 // from the previous translation before continuing to move the index forward.
238
239 // An index into buffer_ for operations starting at a previous BEGIN, which
240 // can be used to read operations referred to by MATCH_PREVIOUS_TRANSLATION.
242
243 // When starting a new MATCH_PREVIOUS_TRANSLATION operation, we'll need to
244 // advance the previous_index_ by this many steps.
246};
247
248// Iterator over the deoptimization values. The iterator is not GC-safe.
255
256// DeoptimizationData is a fixed array used to hold the deoptimization data for
257// optimized code. It also contains information about functions that were
258// inlined. If N different functions were inlined then the first N elements of
259// the literal array will contain these functions.
260//
261// It can be empty.
263 public:
266
267 // Layout description. Indices in the array.
268 static const int kFrameTranslationIndex = 0;
269 static const int kInlinedFunctionCountIndex = 1;
270 static const int kProtectedLiteralArrayIndex = 2;
271 static const int kLiteralArrayIndex = 3;
272 static const int kOsrBytecodeOffsetIndex = 4;
273 static const int kOsrPcOffsetIndex = 5;
274 static const int kOptimizationIdIndex = 6;
276 static const int kInliningPositionsIndex = 8;
277 static const int kDeoptExitStartIndex = 9;
278 static const int kEagerDeoptCountIndex = 10;
279 static const int kLazyDeoptCountIndex = 11;
280 static const int kFirstDeoptEntryIndex = 12;
281
282 // Offsets of deopt entry elements relative to the start of the entry.
283 static const int kBytecodeOffsetRawOffset = 0;
284 static const int kTranslationIndexOffset = 1;
285 static const int kPcOffset = 2;
286#ifdef DEBUG
287 static const int kNodeIdOffset = 3;
288 static const int kDeoptEntrySize = 4;
289#else // DEBUG
290 static const int kDeoptEntrySize = 3;
291#endif // DEBUG
292
293// Simple element accessors.
294#define DECL_ELEMENT_ACCESSORS(name, type) \
295 inline type name() const; \
296 inline void Set##name(type value);
297
298 DECL_ELEMENT_ACCESSORS(FrameTranslation,
300 DECL_ELEMENT_ACCESSORS(InlinedFunctionCount, Tagged<Smi>)
301 DECL_ELEMENT_ACCESSORS(ProtectedLiteralArray,
304 DECL_ELEMENT_ACCESSORS(OsrBytecodeOffset, Tagged<Smi>)
306 DECL_ELEMENT_ACCESSORS(OptimizationId, Tagged<Smi>)
307 DECL_ELEMENT_ACCESSORS(WrappedSharedFunctionInfo,
309 DECL_ELEMENT_ACCESSORS(InliningPositions,
311 DECL_ELEMENT_ACCESSORS(DeoptExitStart, Tagged<Smi>)
312 DECL_ELEMENT_ACCESSORS(EagerDeoptCount, Tagged<Smi>)
313 DECL_ELEMENT_ACCESSORS(LazyDeoptCount, Tagged<Smi>)
314
315#undef DECL_ELEMENT_ACCESSORS
316
318
319// Accessors for elements of the ith deoptimization entry.
320#define DECL_ENTRY_ACCESSORS(name, type) \
321 inline type name(int i) const; \
322 inline void Set##name(int i, type value);
323
324 DECL_ENTRY_ACCESSORS(BytecodeOffsetRaw, Tagged<Smi>)
325 DECL_ENTRY_ACCESSORS(TranslationIndex, Tagged<Smi>)
327#ifdef DEBUG
329#endif // DEBUG
330
331#undef DECL_ENTRY_ACCESSORS
332
333 // In case the innermost frame is a builtin continuation stub, then this field
334 // actually contains the builtin id. See uses of
335 // `Builtins::GetBuiltinFromBytecodeOffset`.
336 // TODO(olivf): Add some validation that callers do not misinterpret the
337 // result.
339
340 inline void SetBytecodeOffset(int i, BytecodeOffset value);
341
342 inline int DeoptCount() const;
343
344 static const int kNotInlinedIndex = -1;
345
346 // Returns the inlined function at the given position in LiteralArray, or the
347 // outer function if index == kNotInlinedIndex.
349
350 // Allocates a DeoptimizationData.
351 static Handle<DeoptimizationData> New(Isolate* isolate,
352 int deopt_entry_count);
354 int deopt_entry_count);
355
356 // Return an empty DeoptimizationData.
359 LocalIsolate* isolate);
360
361#ifdef DEBUG
362 void Verify(Handle<BytecodeArray> bytecode) const;
363#endif
364#ifdef ENABLE_DISASSEMBLER
365 void PrintDeoptimizationData(std::ostream& os) const;
366#endif
367
368 private:
369 static int IndexForEntry(int i) {
371 }
372
373 static int LengthFor(int entry_count) { return IndexForEntry(entry_count); }
374};
375
376} // namespace internal
377} // namespace v8
378
380
381#endif // V8_OBJECTS_DEOPTIMIZATION_DATA_H_
DeoptimizationFrameTranslation::FrameCount EnterBeginOpcode()
const base::Vector< const uint8_t > buffer_
DeoptTranslationIterator(base::Vector< const uint8_t > buffer, int index)
static int LengthFor(int entry_count)
Tagged< ProtectedDeoptimizationLiteralArray > Tagged< TrustedPodArray< InliningPosition > > Tagged< SharedFunctionInfo > GetSharedFunctionInfo() const
BytecodeOffset GetBytecodeOffsetOrBuiltinContinuationId(int i) const
static Handle< DeoptimizationData > New(Isolate *isolate, int deopt_entry_count)
Tagged< SharedFunctionInfo > GetInlinedFunction(int index)
DECL_ELEMENT_ACCESSORS(FrameTranslation, Tagged< DeoptimizationFrameTranslation >) DECL_ELEMENT_ACCESSORS(ProtectedLiteralArray
UnionOf< Smi, SharedFunctionInfoWrapper > SharedFunctionInfoWrapperOrSmi
void SetBytecodeOffset(int i, BytecodeOffset value)
static V8_EXPORT_PRIVATE Handle< DeoptimizationData > Empty(Isolate *isolate)
Iterator(Tagged< DeoptimizationFrameTranslation > buffer, int index)
void set(int index, Tagged< Object > value)
Tagged< MaybeObject > get_raw(int index) const
DirectHandle< Object > Reify(Isolate *isolate) const
DeoptimizationLiteral(IndirectHandle< Object > object)
DeoptimizationLiteralKind kind() const
DeoptimizationLiteral(uint64_t unsigned_bigint64)
bool operator==(const DeoptimizationLiteral &other) const
DeoptimizationLiteral(int64_t signed_bigint64)
IndirectHandle< Object > object() const
static DeoptimizationLiteral HoleNaN()
uint32_t get_bits() const
Definition boxed-float.h:36
uint64_t get_bits() const
Definition boxed-float.h:80
static constexpr Tagged< Smi > FromInt(int value)
Definition smi.h:38
#define DECL_ENTRY_ACCESSORS(name, type)
#define DECL_ELEMENT_ACCESSORS(name, type)
FunctionLiteral * literal
Definition liveedit.cc:294
int n
Definition mul-fft.cc:296
int int32_t
Definition unicode.cc:40
V8_INLINE Dest bit_cast(Source const &source)
Definition macros.h:95
FloatWithBits< 32 > Float32
Definition index.h:233
typename detail::FlattenUnionHelper< Union<>, Ts... >::type UnionOf
Definition union.h:123
constexpr int kInt32Size
Definition globals.h:401
#define CHECK(condition)
Definition logging.h:124
#define CHECK_NE(lhs, rhs)
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
#define V8_EXPORT_PRIVATE
Definition macros.h:460