7 #include "src/arguments-inl.h" 8 #include "src/counters.h" 9 #include "src/frames-inl.h" 10 #include "src/interpreter/bytecode-array-iterator.h" 11 #include "src/interpreter/bytecode-decoder.h" 12 #include "src/interpreter/bytecode-flags.h" 13 #include "src/interpreter/bytecode-register.h" 14 #include "src/interpreter/bytecodes.h" 15 #include "src/interpreter/interpreter.h" 16 #include "src/isolate-inl.h" 17 #include "src/ostreams.h" 18 #include "src/runtime/runtime-utils.h" 19 #include "src/snapshot/snapshot.h" 24 #ifdef V8_TRACE_IGNITION 28 void AdvanceToOffsetForTracing(
29 interpreter::BytecodeArrayIterator& bytecode_iterator,
int offset) {
30 while (bytecode_iterator.current_offset() +
31 bytecode_iterator.current_bytecode_size() <=
33 bytecode_iterator.Advance();
35 DCHECK(bytecode_iterator.current_offset() == offset ||
36 ((bytecode_iterator.current_offset() + 1) == offset &&
37 bytecode_iterator.current_operand_scale() >
38 interpreter::OperandScale::kSingle));
41 void PrintRegisters(Isolate* isolate, std::ostream& os,
bool is_input,
42 interpreter::BytecodeArrayIterator& bytecode_iterator,
43 Handle<Object> accumulator) {
44 static const char kAccumulator[] =
"accumulator";
45 static const int kRegFieldWidth =
static_cast<int>(
sizeof(kAccumulator) - 1);
46 static const char* kInputColourCode =
"\033[0;36m";
47 static const char* kOutputColourCode =
"\033[0;35m";
48 static const char* kNormalColourCode =
"\033[0;m";
49 const char* kArrowDirection = is_input ?
" -> " :
" <- ";
50 if (FLAG_log_colour) {
51 os << (is_input ? kInputColourCode : kOutputColourCode);
54 interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode();
57 if ((is_input && interpreter::Bytecodes::ReadsAccumulator(bytecode)) ||
58 (!is_input && interpreter::Bytecodes::WritesAccumulator(bytecode))) {
59 os <<
" [ " << kAccumulator << kArrowDirection;
60 accumulator->ShortPrint();
61 os <<
" ]" << std::endl;
65 JavaScriptFrameIterator frame_iterator(isolate);
66 InterpretedFrame* frame =
67 reinterpret_cast<InterpretedFrame*
>(frame_iterator.frame());
68 int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode);
69 for (
int operand_index = 0; operand_index < operand_count; operand_index++) {
70 interpreter::OperandType operand_type =
71 interpreter::Bytecodes::GetOperandType(bytecode, operand_index);
74 ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type)
75 : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type);
77 interpreter::Register first_reg =
78 bytecode_iterator.GetRegisterOperand(operand_index);
79 int range = bytecode_iterator.GetRegisterOperandRange(operand_index);
80 for (
int reg_index = first_reg.index();
81 reg_index < first_reg.index() + range; reg_index++) {
82 Object* reg_object = frame->ReadInterpreterRegister(reg_index);
83 os <<
" [ " << std::setw(kRegFieldWidth)
84 << interpreter::Register(reg_index).ToString(
85 bytecode_iterator.bytecode_array()->parameter_count())
87 reg_object->ShortPrint(os);
88 os <<
" ]" << std::endl;
92 if (FLAG_log_colour) {
93 os << kNormalColourCode;
99 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) {
100 if (!FLAG_trace_ignition) {
101 return ReadOnlyRoots(isolate).undefined_value();
104 SealHandleScope shs(isolate);
105 DCHECK_EQ(3, args.length());
106 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
107 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
108 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
110 int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
111 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
112 AdvanceToOffsetForTracing(bytecode_iterator, offset);
113 if (offset == bytecode_iterator.current_offset()) {
117 const uint8_t* base_address =
reinterpret_cast<const uint8_t*
>(
118 bytecode_array->GetFirstBytecodeAddress());
119 const uint8_t* bytecode_address = base_address + offset;
120 os <<
" -> " <<
static_cast<const void*
>(bytecode_address) <<
" @ " 121 << std::setw(4) << offset <<
" : ";
122 interpreter::BytecodeDecoder::Decode(os, bytecode_address,
123 bytecode_array->parameter_count());
126 PrintRegisters(isolate, os,
true, bytecode_iterator, accumulator);
130 return ReadOnlyRoots(isolate).undefined_value();
133 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) {
134 if (!FLAG_trace_ignition) {
135 return ReadOnlyRoots(isolate).undefined_value();
138 SealHandleScope shs(isolate);
139 DCHECK_EQ(3, args.length());
140 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
141 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
142 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
144 int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
145 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
146 AdvanceToOffsetForTracing(bytecode_iterator, offset);
150 if (bytecode_iterator.current_operand_scale() ==
151 interpreter::OperandScale::kSingle ||
152 offset > bytecode_iterator.current_offset()) {
155 PrintRegisters(isolate, os,
false, bytecode_iterator, accumulator);
158 return ReadOnlyRoots(isolate).undefined_value();
163 #ifdef V8_TRACE_FEEDBACK_UPDATES 165 RUNTIME_FUNCTION(Runtime_InterpreterTraceUpdateFeedback) {
166 if (!FLAG_trace_feedback_updates) {
167 return ReadOnlyRoots(isolate).undefined_value();
170 SealHandleScope shs(isolate);
171 DCHECK_EQ(3, args.length());
172 CONVERT_ARG_HANDLE_CHECKED(JSFunction,
function, 0);
173 CONVERT_SMI_ARG_CHECKED(slot, 1);
174 CONVERT_ARG_CHECKED(String, reason, 2);
176 int slot_count =
function->feedback_vector()->metadata()->slot_count();
179 os <<
"[Feedback slot " << slot <<
"/" << slot_count <<
" in ";
180 function->shared()->ShortPrint(os);
181 os <<
" updated to ";
182 function->feedback_vector()->FeedbackSlotPrint(os, FeedbackSlot(slot));
185 StringCharacterStream stream(reason);
186 while (stream.HasMore()) {
187 uint16_t character = stream.GetNext();
188 PrintF(
"%c", character);
191 os <<
"]" << std::endl;
193 return ReadOnlyRoots(isolate).undefined_value();