| 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 while (bytecode_iterator.current_offset() + |
| 34 bytecode_iterator.current_bytecode_size() <= |
| 35 offset) { |
| 36 bytecode_iterator.Advance(); |
| 37 } |
| 38 DCHECK_EQ(offset, bytecode_iterator.current_offset()); |
| 39 } |
| 40 |
| 31 void PrintRegisters(std::ostream& os, bool is_input, | 41 void PrintRegisters(std::ostream& os, bool is_input, |
| 32 Handle<BytecodeArray> bytecode_array, int bytecode_offset, | 42 interpreter::BytecodeArrayIterator& bytecode_iterator, |
| 33 Handle<Object> accumulator) { | 43 Handle<Object> accumulator) { |
| 34 static const int kRegFieldWidth = static_cast<int>(strlen("accumulator")); | 44 static const int kRegFieldWidth = static_cast<int>(strlen("accumulator")); |
| 35 static const char* kInputColourCode = "\033[0;36m"; | 45 static const char* kInputColourCode = "\033[0;36m"; |
| 36 static const char* kOutputColourCode = "\033[0;35m"; | 46 static const char* kOutputColourCode = "\033[0;35m"; |
| 37 static const char* kNormalColourCode = "\033[0;m"; | 47 static const char* kNormalColourCode = "\033[0;m"; |
| 38 const char* kArrowDirection = is_input ? " -> " : " <- "; | 48 const char* kArrowDirection = is_input ? " -> " : " <- "; |
| 39 if (FLAG_log_colour) { | 49 if (FLAG_log_colour) { |
| 40 os << (is_input ? kInputColourCode : kOutputColourCode); | 50 os << (is_input ? kInputColourCode : kOutputColourCode); |
| 41 } | 51 } |
| 42 | 52 |
| 43 // Print accumulator. | 53 // Print accumulator. |
| 44 os << " [ accumulator" << kArrowDirection; | 54 os << " [ accumulator" << kArrowDirection; |
| 45 accumulator->ShortPrint(); | 55 accumulator->ShortPrint(); |
| 46 os << " ]" << std::endl; | 56 os << " ]" << std::endl; |
| 47 | 57 |
| 48 // Find the location of the register file. | 58 // Find the location of the register file. |
| 49 JavaScriptFrameIterator frame_iterator(bytecode_array->GetIsolate()); | 59 JavaScriptFrameIterator frame_iterator( |
| 60 bytecode_iterator.bytecode_array()->GetIsolate()); |
| 50 JavaScriptFrame* frame = frame_iterator.frame(); | 61 JavaScriptFrame* frame = frame_iterator.frame(); |
| 51 Address register_file = | 62 Address register_file = |
| 52 frame->fp() + InterpreterFrameConstants::kRegisterFilePointerFromFp; | 63 frame->fp() + InterpreterFrameConstants::kRegisterFilePointerFromFp; |
| 53 | 64 |
| 54 // Print the registers. | 65 // 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(); | 66 interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode(); |
| 59 int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode); | 67 int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode); |
| 60 for (int operand_index = 0; operand_index < operand_count; operand_index++) { | 68 for (int operand_index = 0; operand_index < operand_count; operand_index++) { |
| 61 interpreter::OperandType operand_type = | 69 interpreter::OperandType operand_type = |
| 62 interpreter::Bytecodes::GetOperandType(bytecode, operand_index); | 70 interpreter::Bytecodes::GetOperandType(bytecode, operand_index); |
| 63 bool should_print = | 71 bool should_print = |
| 64 is_input | 72 is_input |
| 65 ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type) | 73 ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type) |
| 66 : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type); | 74 : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type); |
| 67 if (should_print) { | 75 if (should_print) { |
| 68 interpreter::Register first_reg = | 76 interpreter::Register first_reg = |
| 69 bytecode_iterator.GetRegisterOperand(operand_index); | 77 bytecode_iterator.GetRegisterOperand(operand_index); |
| 70 int range = bytecode_iterator.GetRegisterOperandRange(operand_index); | 78 int range = bytecode_iterator.GetRegisterOperandRange(operand_index); |
| 71 for (int reg_index = first_reg.index(); | 79 for (int reg_index = first_reg.index(); |
| 72 reg_index < first_reg.index() + range; reg_index++) { | 80 reg_index < first_reg.index() + range; reg_index++) { |
| 73 Address reg_location = register_file - reg_index * kPointerSize; | 81 Address reg_location = register_file - reg_index * kPointerSize; |
| 74 Object* reg_object = Memory::Object_at(reg_location); | 82 Object* reg_object = Memory::Object_at(reg_location); |
| 75 os << " [ " << std::setw(kRegFieldWidth) | 83 os << " [ " << std::setw(kRegFieldWidth) |
| 76 << interpreter::Register(reg_index).ToString( | 84 << interpreter::Register(reg_index).ToString( |
| 77 bytecode_array->parameter_count()) | 85 bytecode_iterator.bytecode_array()->parameter_count()) |
| 78 << kArrowDirection; | 86 << kArrowDirection; |
| 79 reg_object->ShortPrint(os); | 87 reg_object->ShortPrint(os); |
| 80 os << " ]" << std::endl; | 88 os << " ]" << std::endl; |
| 81 } | 89 } |
| 82 } | 90 } |
| 83 } | 91 } |
| 84 if (FLAG_log_colour) { | 92 if (FLAG_log_colour) { |
| 85 os << kNormalColourCode; | 93 os << kNormalColourCode; |
| 86 } | 94 } |
| 87 } | 95 } |
| 88 | 96 |
| 89 } // namespace | 97 } // namespace |
| 90 | 98 |
| 91 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) { | 99 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) { |
| 92 SealHandleScope shs(isolate); | 100 SealHandleScope shs(isolate); |
| 93 DCHECK_EQ(3, args.length()); | 101 DCHECK_EQ(3, args.length()); |
| 94 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0); | 102 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0); |
| 95 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1); | 103 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1); |
| 96 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2); | 104 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2); |
| 97 OFStream os(stdout); | 105 OFStream os(stdout); |
| 98 | 106 |
| 99 // Print bytecode. | 107 int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag; |
| 100 const uint8_t* bytecode_address = | 108 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array); |
| 101 reinterpret_cast<const uint8_t*>(*bytecode_array) + bytecode_offset; | 109 AdvanceToOffsetForTracing(bytecode_iterator, offset); |
| 102 Vector<char> buf = Vector<char>::New(50); | 110 if (offset == bytecode_iterator.current_offset()) { |
| 103 SNPrintF(buf, "%p", bytecode_address); | 111 // Print bytecode. |
| 104 os << " -> " << buf.start() << " (" << bytecode_offset << ") : "; | 112 const uint8_t* bytecode_address = |
| 105 interpreter::Bytecodes::Decode(os, bytecode_address, | 113 reinterpret_cast<const uint8_t*>(*bytecode_array) + bytecode_offset; |
| 106 bytecode_array->parameter_count()); | 114 Vector<char> buf = Vector<char>::New(50); |
| 107 os << std::endl; | 115 SNPrintF(buf, "%p", bytecode_address); |
| 116 os << " -> " << buf.start() << " (" << bytecode_offset << ") : "; |
| 117 interpreter::Bytecodes::Decode(os, bytecode_address, |
| 118 bytecode_array->parameter_count()); |
| 119 os << std::endl; |
| 120 // Print all input registers and accumulator. |
| 121 PrintRegisters(os, true, bytecode_iterator, accumulator); |
| 108 | 122 |
| 109 // Print all input registers and accumulator. | 123 os << std::flush; |
| 110 PrintRegisters(os, true, bytecode_array, bytecode_offset, accumulator); | 124 } |
| 111 | |
| 112 os << std::flush; | |
| 113 return isolate->heap()->undefined_value(); | 125 return isolate->heap()->undefined_value(); |
| 114 } | 126 } |
| 115 | 127 |
| 116 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) { | 128 RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) { |
| 117 SealHandleScope shs(isolate); | 129 SealHandleScope shs(isolate); |
| 118 DCHECK_EQ(3, args.length()); | 130 DCHECK_EQ(3, args.length()); |
| 119 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0); | 131 CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0); |
| 120 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1); | 132 CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1); |
| 121 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2); | 133 CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2); |
| 122 OFStream os(stdout); | |
| 123 | 134 |
| 124 // Print all output registers and accumulator. | 135 int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag; |
| 125 PrintRegisters(os, false, bytecode_array, bytecode_offset, accumulator); | 136 interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array); |
| 126 os << std::flush; | 137 AdvanceToOffsetForTracing(bytecode_iterator, offset); |
| 138 // The offset comparison here ensures registers only printed when the |
| 139 // (potentially) widened bytecode has completed. The iterator reports |
| 140 // the offset as the offset of the prefix bytecode. |
| 141 if (bytecode_iterator.current_operand_scale() == |
| 142 interpreter::OperandScale::kSingle || |
| 143 offset > bytecode_iterator.current_offset()) { |
| 144 OFStream os(stdout); |
| 145 // Print all output registers and accumulator. |
| 146 PrintRegisters(os, false, bytecode_iterator, accumulator); |
| 147 os << std::flush; |
| 148 } |
| 127 return isolate->heap()->undefined_value(); | 149 return isolate->heap()->undefined_value(); |
| 128 } | 150 } |
| 129 | 151 |
| 130 RUNTIME_FUNCTION(Runtime_InterpreterClearPendingMessage) { | 152 RUNTIME_FUNCTION(Runtime_InterpreterClearPendingMessage) { |
| 131 SealHandleScope shs(isolate); | 153 SealHandleScope shs(isolate); |
| 132 DCHECK_EQ(0, args.length()); | 154 DCHECK_EQ(0, args.length()); |
| 133 Object* message = isolate->thread_local_top()->pending_message_obj_; | 155 Object* message = isolate->thread_local_top()->pending_message_obj_; |
| 134 isolate->clear_pending_message(); | 156 isolate->clear_pending_message(); |
| 135 return message; | 157 return message; |
| 136 } | 158 } |
| 137 | 159 |
| 138 RUNTIME_FUNCTION(Runtime_InterpreterSetPendingMessage) { | 160 RUNTIME_FUNCTION(Runtime_InterpreterSetPendingMessage) { |
| 139 SealHandleScope shs(isolate); | 161 SealHandleScope shs(isolate); |
| 140 DCHECK_EQ(1, args.length()); | 162 DCHECK_EQ(1, args.length()); |
| 141 CONVERT_ARG_HANDLE_CHECKED(Object, message, 0); | 163 CONVERT_ARG_HANDLE_CHECKED(Object, message, 0); |
| 142 isolate->thread_local_top()->pending_message_obj_ = *message; | 164 isolate->thread_local_top()->pending_message_obj_ = *message; |
| 143 return isolate->heap()->undefined_value(); | 165 return isolate->heap()->undefined_value(); |
| 144 } | 166 } |
| 145 | 167 |
| 146 } // namespace internal | 168 } // namespace internal |
| 147 } // namespace v8 | 169 } // namespace v8 |
| OLD | NEW |