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 |