| Index: src/runtime/runtime-interpreter.cc
|
| diff --git a/src/runtime/runtime-interpreter.cc b/src/runtime/runtime-interpreter.cc
|
| index 96ebe5d4d3f48cfe77ab1239e8ef0c530a1a213d..726190805cbe6d41094284bda9086ecd419075b7 100644
|
| --- a/src/runtime/runtime-interpreter.cc
|
| +++ b/src/runtime/runtime-interpreter.cc
|
| @@ -4,7 +4,12 @@
|
|
|
| #include "src/runtime/runtime-utils.h"
|
|
|
| +#include <iomanip>
|
| +
|
| #include "src/arguments.h"
|
| +#include "src/frames-inl.h"
|
| +#include "src/interpreter/bytecode-array-iterator.h"
|
| +#include "src/interpreter/bytecodes.h"
|
| #include "src/isolate-inl.h"
|
|
|
| namespace v8 {
|
| @@ -147,5 +152,106 @@ RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) {
|
| shared, context, static_cast<PretenureFlag>(pretenured_flag));
|
| }
|
|
|
| +namespace {
|
| +
|
| +void PrintRegisters(std::ostream& os, bool is_input,
|
| + Handle<BytecodeArray> bytecode_array, int bytecode_offset,
|
| + Handle<Object> accumulator) {
|
| + static const int kRegFieldWidth = static_cast<int>(strlen("accumulator"));
|
| + static const char* kInputColourCode = "\033[0;36m";
|
| + static const char* kOutputColourCode = "\033[0;35m";
|
| + static const char* kNormalColourCode = "\033[0;m";
|
| + const char* kArrowDirection = is_input ? " -> " : " <- ";
|
| + if (FLAG_log_colour) {
|
| + os << (is_input ? kInputColourCode : kOutputColourCode);
|
| + }
|
| +
|
| + // Print accumulator.
|
| + os << " [ accumulator" << kArrowDirection;
|
| + accumulator->ShortPrint();
|
| + os << " ]" << std::endl;
|
| +
|
| + // Find the location of the register file.
|
| + JavaScriptFrameIterator frame_iterator(bytecode_array->GetIsolate());
|
| + JavaScriptFrame* frame = frame_iterator.frame();
|
| + Address register_file =
|
| + frame->fp() + InterpreterFrameConstants::kRegisterFilePointerFromFp;
|
| +
|
| + // Print the registers.
|
| + interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
|
| + bytecode_iterator.set_current_offset(
|
| + bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag);
|
| + interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode();
|
| + int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode);
|
| + for (int operand_index = 0; operand_index < operand_count; operand_index++) {
|
| + interpreter::OperandType operand_type =
|
| + interpreter::Bytecodes::GetOperandType(bytecode, operand_index);
|
| + bool should_print =
|
| + is_input
|
| + ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type)
|
| + : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type);
|
| + if (should_print) {
|
| + interpreter::Register first_reg =
|
| + bytecode_iterator.GetRegisterOperand(operand_index);
|
| + int range = bytecode_iterator.GetRegisterOperandRange(operand_index);
|
| + for (int reg_index = first_reg.index();
|
| + reg_index < first_reg.index() + range; reg_index++) {
|
| + Address reg_location = register_file - reg_index * kPointerSize;
|
| + Object* reg_object = Memory::Object_at(reg_location);
|
| + os << " [ " << std::setw(kRegFieldWidth)
|
| + << interpreter::Register(reg_index).ToString(
|
| + bytecode_array->parameter_count())
|
| + << kArrowDirection;
|
| + reg_object->ShortPrint(os);
|
| + os << " ]" << std::endl;
|
| + }
|
| + }
|
| + }
|
| + if (FLAG_log_colour) {
|
| + os << kNormalColourCode;
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) {
|
| + SealHandleScope shs(isolate);
|
| + DCHECK_EQ(3, args.length());
|
| + CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
|
| + CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
|
| + OFStream os(stdout);
|
| +
|
| + // Print bytecode.
|
| + const uint8_t* bytecode_address =
|
| + reinterpret_cast<const uint8_t*>(*bytecode_array) + bytecode_offset;
|
| + Vector<char> buf = Vector<char>::New(50);
|
| + SNPrintF(buf, "%p", bytecode_address);
|
| + os << " -> " << buf.start() << " (" << bytecode_offset << ") : ";
|
| + interpreter::Bytecodes::Decode(os, bytecode_address,
|
| + bytecode_array->parameter_count());
|
| + os << std::endl;
|
| +
|
| + // Print all input registers and accumulator.
|
| + PrintRegisters(os, true, bytecode_array, bytecode_offset, accumulator);
|
| +
|
| + os << std::flush;
|
| + return isolate->heap()->undefined_value();
|
| +}
|
| +
|
| +RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) {
|
| + SealHandleScope shs(isolate);
|
| + DCHECK_EQ(3, args.length());
|
| + CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
|
| + CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
|
| + OFStream os(stdout);
|
| +
|
| + // Print all output registers and accumulator.
|
| + PrintRegisters(os, false, bytecode_array, bytecode_offset, accumulator);
|
| + os << std::flush;
|
| + return isolate->heap()->undefined_value();
|
| +}
|
| +
|
| } // namespace internal
|
| } // namespace v8
|
|
|