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) widend bytecode has completed. The iterator reports | |
rmcilroy
2016/03/21 12:41:36
/s/widend/widened/
oth
2016/03/21 14:21:49
Done.
| |
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 |