| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include <iomanip> | 7 #include <iomanip> |
| 8 | 8 |
| 9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
| 10 #include "src/frames-inl.h" | 10 #include "src/frames-inl.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 DCHECK_EQ(2, args.length()); | 21 DCHECK_EQ(2, args.length()); |
| 22 CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); | 22 CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0); |
| 23 CONVERT_SMI_ARG_CHECKED(pretenured_flag, 1); | 23 CONVERT_SMI_ARG_CHECKED(pretenured_flag, 1); |
| 24 Handle<Context> context(isolate->context(), isolate); | 24 Handle<Context> context(isolate->context(), isolate); |
| 25 return *isolate->factory()->NewFunctionFromSharedFunctionInfo( | 25 return *isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| 26 shared, context, static_cast<PretenureFlag>(pretenured_flag)); | 26 shared, context, static_cast<PretenureFlag>(pretenured_flag)); |
| 27 } | 27 } |
| 28 | 28 |
| 29 namespace { | 29 namespace { |
| 30 | 30 |
| 31 void AdvanceToOffsetForTracing( |
| 32 interpreter::BytecodeArrayIterator& bytecode_iterator, int offset) { |
| 33 if (offset > 0) { |
| 34 uint8_t last_byte = bytecode_iterator.bytecode_array()->get(offset - 1); |
| 35 auto maybe_bytecode = static_cast<interpreter::Bytecode>(last_byte); |
| 36 if (interpreter::Bytecodes::IsPrefixScalingBytecode(maybe_bytecode)) { |
| 37 // Previous byte looks like a prefix byte so scan forward slowly. |
| 38 while (bytecode_iterator.current_offset() + |
| 39 bytecode_iterator.current_bytecode_size() <= |
| 40 offset) { |
| 41 bytecode_iterator.Advance(); |
| 42 } |
| 43 DCHECK(bytecode_iterator.current_offset() == offset || |
| 44 ((bytecode_iterator.current_offset() == offset - 1) && |
| 45 bytecode_iterator.current_operand_scale() > 1)); |
| 46 } else { |
| 47 bytecode_iterator.set_current_offset(offset); |
| 48 } |
| 49 } |
| 50 DCHECK(bytecode_iterator.current_bytecode() != interpreter::Bytecode::kWide); |
| 51 } |
| 52 |
| 31 void PrintRegisters(std::ostream& os, bool is_input, | 53 void PrintRegisters(std::ostream& os, bool is_input, |
| 32 Handle<BytecodeArray> bytecode_array, int bytecode_offset, | 54 interpreter::BytecodeArrayIterator& bytecode_iterator, |
| 33 Handle<Object> accumulator) { | 55 Handle<Object> accumulator) { |
| 34 static const int kRegFieldWidth = static_cast<int>(strlen("accumulator")); | 56 static const int kRegFieldWidth = static_cast<int>(strlen("accumulator")); |
| 35 static const char* kInputColourCode = "\033[0;36m"; | 57 static const char* kInputColourCode = "\033[0;36m"; |
| 36 static const char* kOutputColourCode = "\033[0;35m"; | 58 static const char* kOutputColourCode = "\033[0;35m"; |
| 37 static const char* kNormalColourCode = "\033[0;m"; | 59 static const char* kNormalColourCode = "\033[0;m"; |
| 38 const char* kArrowDirection = is_input ? " -> " : " <- "; | 60 const char* kArrowDirection = is_input ? " -> " : " <- "; |
| 39 if (FLAG_log_colour) { | 61 if (FLAG_log_colour) { |
| 40 os << (is_input ? kInputColourCode : kOutputColourCode); | 62 os << (is_input ? kInputColourCode : kOutputColourCode); |
| 41 } | 63 } |
| 42 | 64 |
| 43 // Print accumulator. | 65 // Print accumulator. |
| 44 os << " [ accumulator" << kArrowDirection; | 66 os << " [ accumulator" << kArrowDirection; |
| 45 accumulator->ShortPrint(); | 67 accumulator->ShortPrint(); |
| 46 os << " ]" << std::endl; | 68 os << " ]" << std::endl; |
| 47 | 69 |
| 48 // Find the location of the register file. | 70 // Find the location of the register file. |
| 49 JavaScriptFrameIterator frame_iterator(bytecode_array->GetIsolate()); | 71 JavaScriptFrameIterator frame_iterator( |
| 72 bytecode_iterator.bytecode_array()->GetIsolate()); |
| 50 JavaScriptFrame* frame = frame_iterator.frame(); | 73 JavaScriptFrame* frame = frame_iterator.frame(); |
| 51 Address register_file = | 74 Address register_file = |
| 52 frame->fp() + InterpreterFrameConstants::kRegisterFilePointerFromFp; | 75 frame->fp() + InterpreterFrameConstants::kRegisterFilePointerFromFp; |
| 53 | 76 |
| 54 // Print the registers. | 77 // Print the registers. |
| 55 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array); | |
| 56 bytecode_iterator.set_current_offset( | |
| 57 bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag); | |
| 58 interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode(); | 78 interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode(); |
| 59 int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode); | 79 int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode); |
| 60 for (int operand_index = 0; operand_index < operand_count; operand_index++) { | 80 for (int operand_index = 0; operand_index < operand_count; operand_index++) { |
| 61 interpreter::OperandType operand_type = | 81 interpreter::OperandType operand_type = |
| 62 interpreter::Bytecodes::GetOperandType(bytecode, operand_index); | 82 interpreter::Bytecodes::GetOperandType(bytecode, operand_index); |
| 63 bool should_print = | 83 bool should_print = |
| 64 is_input | 84 is_input |
| 65 ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type) | 85 ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type) |
| 66 : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type); | 86 : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type); |
| 67 if (should_print) { | 87 if (should_print) { |
| 68 interpreter::Register first_reg = | 88 interpreter::Register first_reg = |
| 69 bytecode_iterator.GetRegisterOperand(operand_index); | 89 bytecode_iterator.GetRegisterOperand(operand_index); |
| 70 int range = bytecode_iterator.GetRegisterOperandRange(operand_index); | 90 int range = bytecode_iterator.GetRegisterOperandRange(operand_index); |
| 71 for (int reg_index = first_reg.index(); | 91 for (int reg_index = first_reg.index(); |
| 72 reg_index < first_reg.index() + range; reg_index++) { | 92 reg_index < first_reg.index() + range; reg_index++) { |
| 73 Address reg_location = register_file - reg_index * kPointerSize; | 93 Address reg_location = register_file - reg_index * kPointerSize; |
| 74 Object* reg_object = Memory::Object_at(reg_location); | 94 Object* reg_object = Memory::Object_at(reg_location); |
| 75 os << " [ " << std::setw(kRegFieldWidth) | 95 os << " [ " << std::setw(kRegFieldWidth) |
| 76 << interpreter::Register(reg_index).ToString( | 96 << interpreter::Register(reg_index).ToString( |
| 77 bytecode_array->parameter_count()) | 97 bytecode_iterator.bytecode_array()->parameter_count()) |
| 78 << kArrowDirection; | 98 << kArrowDirection; |
| 79 reg_object->ShortPrint(os); | 99 reg_object->ShortPrint(os); |
| 80 os << " ]" << std::endl; | 100 os << " ]" << std::endl; |
| 81 } | 101 } |
| 82 } | 102 } |
| 83 } | 103 } |
| 84 if (FLAG_log_colour) { | 104 if (FLAG_log_colour) { |
| 85 os << kNormalColourCode; | 105 os << kNormalColourCode; |
| 86 } | 106 } |
| 87 } | 107 } |
| 88 | 108 |
| 89 } // namespace | 109 } // namespace |
| 90 | 110 |
| 91 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) { | 111 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) { |
| 92 SealHandleScope shs(isolate); | 112 SealHandleScope shs(isolate); |
| 93 DCHECK_EQ(3, args.length()); | 113 DCHECK_EQ(3, args.length()); |
| 94 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0); | 114 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0); |
| 95 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1); | 115 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1); |
| 96 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2); | 116 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2); |
| 97 OFStream os(stdout); | 117 OFStream os(stdout); |
| 98 | 118 |
| 99 // Print bytecode. | 119 int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag; |
| 100 const uint8_t* bytecode_address = | 120 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array); |
| 101 reinterpret_cast<const uint8_t*>(*bytecode_array) + bytecode_offset; | 121 AdvanceToOffsetForTracing(bytecode_iterator, offset); |
| 102 Vector<char> buf = Vector<char>::New(50); | 122 if (offset == bytecode_iterator.current_offset()) { |
| 103 SNPrintF(buf, "%p", bytecode_address); | 123 // Print bytecode. |
| 104 os << " -> " << buf.start() << " (" << bytecode_offset << ") : "; | 124 const uint8_t* bytecode_address = |
| 105 interpreter::Bytecodes::Decode(os, bytecode_address, | 125 reinterpret_cast<const uint8_t*>(*bytecode_array) + bytecode_offset; |
| 106 bytecode_array->parameter_count()); | 126 Vector<char> buf = Vector<char>::New(50); |
| 107 os << std::endl; | 127 SNPrintF(buf, "%p", bytecode_address); |
| 128 os << " -> " << buf.start() << " (" << bytecode_offset << ") : "; |
| 129 interpreter::Bytecodes::Decode(os, bytecode_address, |
| 130 bytecode_array->parameter_count()); |
| 131 os << std::endl; |
| 132 // Print all input registers and accumulator. |
| 133 PrintRegisters(os, true, bytecode_iterator, accumulator); |
| 108 | 134 |
| 109 // Print all input registers and accumulator. | 135 os << std::flush; |
| 110 PrintRegisters(os, true, bytecode_array, bytecode_offset, accumulator); | 136 } |
| 111 | |
| 112 os << std::flush; | |
| 113 return isolate->heap()->undefined_value(); | 137 return isolate->heap()->undefined_value(); |
| 114 } | 138 } |
| 115 | 139 |
| 116 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) { | 140 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) { |
| 117 SealHandleScope shs(isolate); | 141 SealHandleScope shs(isolate); |
| 118 DCHECK_EQ(3, args.length()); | 142 DCHECK_EQ(3, args.length()); |
| 119 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0); | 143 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0); |
| 120 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1); | 144 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1); |
| 121 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2); | 145 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2); |
| 122 OFStream os(stdout); | |
| 123 | 146 |
| 124 // Print all output registers and accumulator. | 147 int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag; |
| 125 PrintRegisters(os, false, bytecode_array, bytecode_offset, accumulator); | 148 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array); |
| 126 os << std::flush; | 149 AdvanceToOffsetForTracing(bytecode_iterator, offset); |
| 150 if (bytecode_iterator.current_operand_scale() == 1 || |
| 151 offset > bytecode_iterator.current_offset()) { |
| 152 OFStream os(stdout); |
| 153 // Print all output registers and accumulator. |
| 154 PrintRegisters(os, false, bytecode_iterator, accumulator); |
| 155 os << std::flush; |
| 156 } |
| 127 return isolate->heap()->undefined_value(); | 157 return isolate->heap()->undefined_value(); |
| 128 } | 158 } |
| 129 | 159 |
| 130 RUNTIME_FUNCTION(Runtime_InterpreterClearPendingMessage) { | 160 RUNTIME_FUNCTION(Runtime_InterpreterClearPendingMessage) { |
| 131 SealHandleScope shs(isolate); | 161 SealHandleScope shs(isolate); |
| 132 DCHECK_EQ(0, args.length()); | 162 DCHECK_EQ(0, args.length()); |
| 133 Object* message = isolate->thread_local_top()->pending_message_obj_; | 163 Object* message = isolate->thread_local_top()->pending_message_obj_; |
| 134 isolate->clear_pending_message(); | 164 isolate->clear_pending_message(); |
| 135 return message; | 165 return message; |
| 136 } | 166 } |
| 137 | 167 |
| 138 RUNTIME_FUNCTION(Runtime_InterpreterSetPendingMessage) { | 168 RUNTIME_FUNCTION(Runtime_InterpreterSetPendingMessage) { |
| 139 SealHandleScope shs(isolate); | 169 SealHandleScope shs(isolate); |
| 140 DCHECK_EQ(1, args.length()); | 170 DCHECK_EQ(1, args.length()); |
| 141 CONVERT_ARG_HANDLE_CHECKED(Object, message, 0); | 171 CONVERT_ARG_HANDLE_CHECKED(Object, message, 0); |
| 142 isolate->thread_local_top()->pending_message_obj_ = *message; | 172 isolate->thread_local_top()->pending_message_obj_ = *message; |
| 143 return isolate->heap()->undefined_value(); | 173 return isolate->heap()->undefined_value(); |
| 144 } | 174 } |
| 145 | 175 |
| 146 } // namespace internal | 176 } // namespace internal |
| 147 } // namespace v8 | 177 } // namespace v8 |
| OLD | NEW |