24#ifdef V8_TRACE_UNOPTIMIZED
28void AdvanceToOffsetForTracing(
29 interpreter::BytecodeArrayIterator& bytecode_iterator,
int offset) {
30 while (bytecode_iterator.current_offset() +
31 bytecode_iterator.current_bytecode_size() <=
33 bytecode_iterator.Advance();
36 ((bytecode_iterator.current_offset() + 1) ==
offset &&
37 bytecode_iterator.current_operand_scale() >
38 interpreter::OperandScale::kSingle));
41void PrintRegisterRange(UnoptimizedJSFrame* frame, std::ostream& os,
42 interpreter::BytecodeArrayIterator& bytecode_iterator,
43 const int& reg_field_width,
const char* arrow_direction,
44 interpreter::Register first_reg,
int range) {
45 for (
int reg_index = first_reg.index(); reg_index < first_reg.index() + range;
47 Tagged<Object> reg_object = frame->ReadInterpreterRegister(reg_index);
48 os <<
" [ " << std::setw(reg_field_width)
49 << interpreter::Register(reg_index).ToString() << arrow_direction;
51 os <<
" ]" << std::endl;
55void PrintRegisters(UnoptimizedJSFrame* frame, std::ostream& os,
bool is_input,
56 interpreter::BytecodeArrayIterator& bytecode_iterator,
57 Handle<Object> accumulator) {
58 static const char kAccumulator[] =
"accumulator";
59 static const int kRegFieldWidth =
static_cast<int>(
sizeof(kAccumulator) - 1);
60 static const char* kInputColourCode =
"\033[0;36m";
61 static const char* kOutputColourCode =
"\033[0;35m";
62 static const char* kNormalColourCode =
"\033[0;m";
63 const char* kArrowDirection = is_input ?
" -> " :
" <- ";
65 os << (is_input ? kInputColourCode : kOutputColourCode);
74 os <<
" [ " << kAccumulator << kArrowDirection;
76 os <<
" ]" << std::endl;
81 for (
int operand_index = 0; operand_index < operand_count; operand_index++) {
87 : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type);
89 interpreter::Register first_reg =
90 bytecode_iterator.GetRegisterOperand(operand_index);
91 int range = bytecode_iterator.GetRegisterOperandRange(operand_index);
92 PrintRegisterRange(frame, os, bytecode_iterator, kRegFieldWidth,
93 kArrowDirection, first_reg, range);
97 PrintRegisterRange(frame, os, bytecode_iterator, kRegFieldWidth,
102 os << kNormalColourCode;
110 return ReadOnlyRoots(isolate).undefined_value();
113 JavaScriptStackFrameIterator frame_iterator(isolate);
114 UnoptimizedJSFrame* frame =
115 reinterpret_cast<UnoptimizedJSFrame*
>(frame_iterator.frame());
117 if (frame->is_interpreted() && !
v8_flags.trace_ignition) {
118 return ReadOnlyRoots(isolate).undefined_value();
120 if (frame->is_baseline() && !
v8_flags.trace_baseline_exec) {
121 return ReadOnlyRoots(isolate).undefined_value();
124 SealHandleScope shs(isolate);
127 int bytecode_offset =
args.smi_value_at(1);
128 Handle<Object> accumulator =
args.at(2);
131 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
132 AdvanceToOffsetForTracing(bytecode_iterator,
offset);
133 if (
offset == bytecode_iterator.current_offset()) {
137 const uint8_t* base_address =
reinterpret_cast<const uint8_t*
>(
138 bytecode_array->GetFirstBytecodeAddress());
139 const uint8_t* bytecode_address = base_address +
offset;
141 if (frame->is_baseline()) {
146 os << static_cast<const void*>(bytecode_address) <<
" @ " << std::setw(4)
151 PrintRegisters(frame, os,
true, bytecode_iterator, accumulator);
155 return ReadOnlyRoots(isolate).undefined_value();
160 return ReadOnlyRoots(isolate).undefined_value();
163 JavaScriptStackFrameIterator frame_iterator(isolate);
164 UnoptimizedJSFrame* frame =
165 reinterpret_cast<UnoptimizedJSFrame*
>(frame_iterator.frame());
167 if (frame->is_interpreted() && !
v8_flags.trace_ignition) {
168 return ReadOnlyRoots(isolate).undefined_value();
170 if (frame->is_baseline() && !
v8_flags.trace_baseline_exec) {
171 return ReadOnlyRoots(isolate).undefined_value();
174 SealHandleScope shs(isolate);
177 int bytecode_offset =
args.smi_value_at(1);
178 Handle<Object> accumulator =
args.at(2);
181 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
182 AdvanceToOffsetForTracing(bytecode_iterator,
offset);
186 if (bytecode_iterator.current_operand_scale() ==
187 interpreter::OperandScale::kSingle ||
188 offset > bytecode_iterator.current_offset()) {
192 PrintRegisters(frame, os,
false, bytecode_iterator, accumulator);
195 return ReadOnlyRoots(isolate).undefined_value();
200#ifdef V8_TRACE_FEEDBACK_UPDATES
203 if (!
v8_flags.trace_feedback_updates) {
204 return ReadOnlyRoots(isolate).undefined_value();
207 SealHandleScope shs(isolate);
210 int slot =
args.smi_value_at(1);
213 FeedbackVector::TraceFeedbackChange(isolate, *vector, FeedbackSlot(slot),
214 reason->ToCString().get());
216 return ReadOnlyRoots(isolate).undefined_value();
static constexpr int kHeaderSize
static std::ostream & Decode(std::ostream &os, const uint8_t *bytecode_start, bool with_hex=true)
static bool ReadsAccumulator(Bytecode bytecode)
static OperandType GetOperandType(Bytecode bytecode, int i)
static bool IsRegisterInputOperandType(OperandType operand_type)
static int NumberOfOperands(Bytecode bytecode)
static constexpr bool IsShortStar(Bytecode bytecode)
static bool WritesOrClobbersAccumulator(Bytecode bytecode)
static constexpr Register FromShortStar(Bytecode bytecode)
#define RUNTIME_FUNCTION(Name)
base::Vector< const DirectHandle< Object > > args
void ShortPrint(Tagged< Object > obj, FILE *out)
V8_EXPORT_PRIVATE FlagValues v8_flags
Tagged< To > Cast(Tagged< From > value, const v8::SourceLocation &loc=INIT_SOURCE_LOCATION_IN_DEBUG)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)