19namespace interpreter {
30 constant_array_builder_(constant_array_builder),
32 last_bytecode_offset_(0),
33 last_bytecode_had_source_info_(false),
34 elide_noneffectful_bytecodes_(
35 v8_flags.ignition_elide_noneffectful_bytecodes),
36 exit_seen_in_block_(false) {
40template <
typename IsolateT>
53 return bytecode_array;
65template <
typename IsolateT>
71 ? isolate->factory()->empty_trusted_byte_array()
73 return source_position_table;
85 int mismatches =
false;
88 if (bytecode_size != bytecode->length()) mismatches =
true;
92 int first_mismatch = std::min(bytecode_size, bytecode->length());
93 for (
int i = 0;
i < first_mismatch; ++
i) {
94 if (bytecode_ptr[
i] != bytecode->get(
i)) {
102 return first_mismatch;
132 DCHECK_EQ(node->bytecode(), Bytecode::kJumpLoop);
165 loop_header->
bind_to(current_offset);
173 DCHECK(!jump_table->is_bound(case_value));
212 bool is_statement =
false;
235 case Bytecode::kReturn:
236 case Bytecode::kThrow:
237 case Bytecode::kReThrow:
238 case Bytecode::kAbort:
239 case Bytecode::kJump:
240 case Bytecode::kJumpLoop:
241 case Bytecode::kJumpConstant:
242 case Bytecode::kSuspendGenerator:
251 bool has_source_info) {
277 DCHECK_NE(node->bytecode(), Bytecode::kIllegal);
279 Bytecode bytecode = node->bytecode();
282 if (operand_scale != OperandScale::kSingle) {
288 const uint32_t*
const operands = node->operands();
289 const int operand_count = node->operand_count();
292 for (
int i = 0;
i < operand_count; ++
i) {
293 switch (operand_sizes[
i]) {
300 uint16_t operand =
static_cast<uint16_t
>(operands[
i]);
301 const uint8_t* raw_operand =
reinterpret_cast<const uint8_t*
>(&operand);
307 const uint8_t* raw_operand =
308 reinterpret_cast<const uint8_t*
>(&operands[
i]);
321 switch (jump_bytecode) {
322 case Bytecode::kJump:
323 return Bytecode::kJumpConstant;
324 case Bytecode::kJumpIfTrue:
325 return Bytecode::kJumpIfTrueConstant;
326 case Bytecode::kJumpIfFalse:
327 return Bytecode::kJumpIfFalseConstant;
328 case Bytecode::kJumpIfToBooleanTrue:
329 return Bytecode::kJumpIfToBooleanTrueConstant;
330 case Bytecode::kJumpIfToBooleanFalse:
331 return Bytecode::kJumpIfToBooleanFalseConstant;
332 case Bytecode::kJumpIfNull:
333 return Bytecode::kJumpIfNullConstant;
334 case Bytecode::kJumpIfNotNull:
335 return Bytecode::kJumpIfNotNullConstant;
336 case Bytecode::kJumpIfUndefined:
337 return Bytecode::kJumpIfUndefinedConstant;
338 case Bytecode::kJumpIfNotUndefined:
339 return Bytecode::kJumpIfNotUndefinedConstant;
340 case Bytecode::kJumpIfUndefinedOrNull:
341 return Bytecode::kJumpIfUndefinedOrNullConstant;
342 case Bytecode::kJumpIfJSReceiver:
343 return Bytecode::kJumpIfJSReceiverConstant;
344 case Bytecode::kJumpIfForInDone:
345 return Bytecode::kJumpIfForInDoneConstant;
358 size_t operand_location = jump_location + 1;
364 bytecodes()->
at(operand_location) =
static_cast<uint8_t
>(delta);
375 bytecodes()->
at(operand_location) =
static_cast<uint8_t
>(entry);
386 size_t operand_location = jump_location + 1;
387 uint8_t operand_bytes[2];
393 reinterpret_cast<Address>(operand_bytes),
static_cast<uint16_t
>(delta));
403 reinterpret_cast<Address>(operand_bytes),
static_cast<uint16_t
>(entry));
407 bytecodes()->
at(operand_location++) = operand_bytes[0];
408 bytecodes()->
at(operand_location) = operand_bytes[1];
416 uint8_t operand_bytes[4];
418 static_cast<uint32_t
>(delta));
419 size_t operand_location = jump_location + 1;
424 bytecodes()->
at(operand_location++) = operand_bytes[0];
425 bytecodes()->
at(operand_location++) = operand_bytes[1];
426 bytecodes()->
at(operand_location++) = operand_bytes[2];
427 bytecodes()->
at(operand_location) = operand_bytes[3];
432 int delta =
static_cast<int>(jump_target - jump_location);
433 int prefix_offset = 0;
446 switch (operand_scale) {
447 case OperandScale::kSingle:
450 case OperandScale::kDouble:
453 case OperandScale::kQuadruple:
464 DCHECK_EQ(node->bytecode(), Bytecode::kJumpLoop);
477 static_cast<uint32_t
>(current_offset - loop_header->
offset());
480 const bool emits_prefix_bytecode =
484 if (emits_prefix_bytecode) {
485 static constexpr int kPrefixBytecodeSize = 1;
486 delta += kPrefixBytecodeSize;
488 kPrefixBytecodeSize);
490 kPrefixBytecodeSize);
492 node->update_operand0(delta);
495 emits_prefix_bytecode);
513 label->set_referrer(current_offset);
517 DCHECK_NE(Bytecode::kJumpLoop, node->bytecode());
518 switch (reserved_operand_size) {
539 if (node->operand_scale() > OperandScale::kSingle) {
static constexpr Tagged< Smi > FromInt(int value)
Handle< TrustedByteArray > ToSourcePositionTable(IsolateT *isolate)
void AddPosition(size_t code_offset, SourcePosition source_position, bool is_statement)
void reserve(size_t new_cap)
void resize(size_t new_size)
void push_back(const T &value)
void Write(BytecodeNode *node)
void BindLoopHeader(BytecodeLoopHeader *loop_header)
void SetFunctionEntrySourcePosition(int position)
const uint32_t k8BitJumpPlaceholder
ZoneVector< uint8_t > bytecodes_
void WriteSwitch(BytecodeNode *node, BytecodeJumpTable *jump_table)
void WriteJump(BytecodeNode *node, BytecodeLabel *label)
bool last_bytecode_had_source_info_
Handle< BytecodeArray > ToBytecodeArray(IsolateT *isolate, int register_count, uint16_t parameter_count, uint16_t max_arguments, DirectHandle< TrustedByteArray > handler_table)
void EmitJump(BytecodeNode *node, BytecodeLabel *label)
void PatchJumpWith8BitOperand(size_t jump_location, int delta)
SourcePositionTableBuilder source_position_table_builder_
void UpdateExitSeenInBlock(Bytecode bytecode)
DirectHandle< TrustedByteArray > ToSourcePositionTable(IsolateT *isolate)
void InvalidateLastBytecode()
void BindLabel(BytecodeLabel *label)
BytecodeArrayWriter(Zone *zone, ConstantArrayBuilder *constant_array_builder, SourcePositionTableBuilder::RecordingMode source_position_mode)
SourcePositionTableBuilder * source_position_table_builder()
void BindTryRegionEnd(HandlerTableBuilder *handler_table_builder, int handler_id)
void MaybeElideLastBytecode(Bytecode next_bytecode, bool has_source_info)
void PatchJumpWith32BitOperand(size_t jump_location, int delta)
ConstantArrayBuilder * constant_array_builder()
bool elide_noneffectful_bytecodes_
void BindHandlerTarget(HandlerTableBuilder *handler_table_builder, int handler_id)
void BindJumpTableEntry(BytecodeJumpTable *jump_table, int case_value)
void UpdateSourcePositionTable(const BytecodeNode *const node)
void EmitSwitch(BytecodeNode *node, BytecodeJumpTable *jump_table)
static const size_t kMaxSizeOfPackedBytecode
void PatchJump(size_t jump_target, size_t jump_location)
void WriteJumpLoop(BytecodeNode *node, BytecodeLoopHeader *loop_header)
ZoneVector< uint8_t > * bytecodes()
void PatchJumpWith16BitOperand(size_t jump_location, int delta)
const uint32_t k32BitJumpPlaceholder
size_t last_bytecode_offset_
void EmitJumpLoop(BytecodeNode *node, BytecodeLoopHeader *loop_header)
void BindTryRegionStart(HandlerTableBuilder *handler_table_builder, int handler_id)
const uint32_t k16BitJumpPlaceholder
void EmitBytecode(const BytecodeNode *const node)
void mark_bound(int case_value)
size_t ConstantPoolEntryFor(int case_value)
void set_switch_bytecode_offset(size_t offset)
size_t switch_bytecode_offset() const
int source_position() const
bool is_statement() const
static ImplicitRegisterUse GetImplicitRegisterUse(Bytecode bytecode)
static OperandScale ScaleForUnsignedOperand(uint32_t value)
static Bytecode FromByte(uint8_t value)
static OperandScale PrefixBytecodeToOperandScale(Bytecode bytecode)
static constexpr bool IsJumpImmediate(Bytecode bytecode)
static constexpr bool IsForwardJump(Bytecode bytecode)
static constexpr bool IsSwitch(Bytecode bytecode)
static Bytecode OperandScaleToPrefixBytecode(OperandScale operand_scale)
static constexpr bool IsAccumulatorLoadWithoutEffects(Bytecode bytecode)
static uint8_t ToByte(Bytecode bytecode)
static OperandType GetOperandType(Bytecode bytecode, int i)
static int Size(Bytecode bytecode, OperandScale operand_scale)
static constexpr bool IsPrefixScalingBytecode(Bytecode bytecode)
static OperandSize SizeForUnsignedOperand(uint32_t value)
static bool OperandScaleRequiresPrefixBytecode(OperandScale operand_scale)
static constexpr bool IsJump(Bytecode bytecode)
static const OperandSize * GetOperandSizes(Bytecode bytecode, OperandScale operand_scale)
void SetJumpTableSmi(size_t index, Tagged< Smi > smi)
void DiscardReservedEntry(OperandSize operand_size)
Handle< TrustedFixedArray > ToFixedArray(IsolateT *isolate)
size_t CommitReservedEntry(OperandSize operand_size, Tagged< Smi > value)
OperandSize CreateReservedEntry(OperandSize minimum_operand_size=OperandSize::kNone)
void SetTryRegionStart(int handler_id, size_t offset)
void SetHandlerTarget(int handler_id, size_t offset)
void SetTryRegionEnd(int handler_id, size_t offset)
#define EXPORT_TEMPLATE_DEFINE(export)
SourcePositionTableBuilder source_position_table_builder_
static void WriteUnalignedValue(Address p, V value)
Bytecode GetJumpWithConstantOperand(Bytecode jump_bytecode)
constexpr int kFunctionEntryBytecodeOffset
constexpr int kSystemPointerSize
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr uint32_t kMaxUInt32
#define STATIC_CONST_MEMBER_DEFINITION
#define CHECK_GE(lhs, rhs)
#define CHECK_LE(lhs, rhs)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DCHECK_GT(v1, v2)
#define V8_EXPORT_PRIVATE