Line data Source code
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
3 : // found in the LICENSE file.
4 :
5 : #include "src/runtime/runtime-utils.h"
6 :
7 : #include <iomanip>
8 :
9 : #include "src/arguments.h"
10 : #include "src/frames-inl.h"
11 : #include "src/interpreter/bytecode-array-iterator.h"
12 : #include "src/interpreter/bytecode-decoder.h"
13 : #include "src/interpreter/bytecode-flags.h"
14 : #include "src/interpreter/bytecode-register.h"
15 : #include "src/interpreter/bytecodes.h"
16 : #include "src/isolate-inl.h"
17 : #include "src/ostreams.h"
18 :
19 : namespace v8 {
20 : namespace internal {
21 :
22 20275666 : RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) {
23 6758556 : HandleScope scope(isolate);
24 : DCHECK_EQ(4, args.length());
25 13517112 : CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
26 13517112 : CONVERT_ARG_HANDLE_CHECKED(FeedbackVector, vector, 1);
27 13517112 : CONVERT_SMI_ARG_CHECKED(index, 2);
28 13517110 : CONVERT_SMI_ARG_CHECKED(pretenured_flag, 3);
29 6758555 : Handle<Context> context(isolate->context(), isolate);
30 6758555 : FeedbackSlot slot = FeedbackVector::ToSlot(index);
31 6758555 : Handle<Cell> vector_cell(Cell::cast(vector->Get(slot)), isolate);
32 : return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
33 : shared, context, vector_cell,
34 13517109 : static_cast<PretenureFlag>(pretenured_flag));
35 : }
36 :
37 : #ifdef V8_TRACE_IGNITION
38 :
39 : namespace {
40 :
41 : void AdvanceToOffsetForTracing(
42 : interpreter::BytecodeArrayIterator& bytecode_iterator, int offset) {
43 : while (bytecode_iterator.current_offset() +
44 : bytecode_iterator.current_bytecode_size() <=
45 : offset) {
46 : bytecode_iterator.Advance();
47 : }
48 : DCHECK(bytecode_iterator.current_offset() == offset ||
49 : ((bytecode_iterator.current_offset() + 1) == offset &&
50 : bytecode_iterator.current_operand_scale() >
51 : interpreter::OperandScale::kSingle));
52 : }
53 :
54 : void PrintRegisters(std::ostream& os, bool is_input,
55 : interpreter::BytecodeArrayIterator& bytecode_iterator,
56 : Handle<Object> accumulator) {
57 : static const char kAccumulator[] = "accumulator";
58 : static const int kRegFieldWidth = static_cast<int>(sizeof(kAccumulator) - 1);
59 : static const char* kInputColourCode = "\033[0;36m";
60 : static const char* kOutputColourCode = "\033[0;35m";
61 : static const char* kNormalColourCode = "\033[0;m";
62 : const char* kArrowDirection = is_input ? " -> " : " <- ";
63 : if (FLAG_log_colour) {
64 : os << (is_input ? kInputColourCode : kOutputColourCode);
65 : }
66 :
67 : interpreter::Bytecode bytecode = bytecode_iterator.current_bytecode();
68 :
69 : // Print accumulator.
70 : if ((is_input && interpreter::Bytecodes::ReadsAccumulator(bytecode)) ||
71 : (!is_input && interpreter::Bytecodes::WritesAccumulator(bytecode))) {
72 : os << " [ " << kAccumulator << kArrowDirection;
73 : accumulator->ShortPrint();
74 : os << " ]" << std::endl;
75 : }
76 :
77 : // Print the registers.
78 : JavaScriptFrameIterator frame_iterator(
79 : bytecode_iterator.bytecode_array()->GetIsolate());
80 : InterpretedFrame* frame =
81 : reinterpret_cast<InterpretedFrame*>(frame_iterator.frame());
82 : int operand_count = interpreter::Bytecodes::NumberOfOperands(bytecode);
83 : for (int operand_index = 0; operand_index < operand_count; operand_index++) {
84 : interpreter::OperandType operand_type =
85 : interpreter::Bytecodes::GetOperandType(bytecode, operand_index);
86 : bool should_print =
87 : is_input
88 : ? interpreter::Bytecodes::IsRegisterInputOperandType(operand_type)
89 : : interpreter::Bytecodes::IsRegisterOutputOperandType(operand_type);
90 : if (should_print) {
91 : interpreter::Register first_reg =
92 : bytecode_iterator.GetRegisterOperand(operand_index);
93 : int range = bytecode_iterator.GetRegisterOperandRange(operand_index);
94 : for (int reg_index = first_reg.index();
95 : reg_index < first_reg.index() + range; reg_index++) {
96 : Object* reg_object = frame->ReadInterpreterRegister(reg_index);
97 : os << " [ " << std::setw(kRegFieldWidth)
98 : << interpreter::Register(reg_index).ToString(
99 : bytecode_iterator.bytecode_array()->parameter_count())
100 : << kArrowDirection;
101 : reg_object->ShortPrint(os);
102 : os << " ]" << std::endl;
103 : }
104 : }
105 : }
106 : if (FLAG_log_colour) {
107 : os << kNormalColourCode;
108 : }
109 : }
110 :
111 : } // namespace
112 :
113 : RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeEntry) {
114 : if (!FLAG_trace_ignition) {
115 : return isolate->heap()->undefined_value();
116 : }
117 :
118 : SealHandleScope shs(isolate);
119 : DCHECK_EQ(3, args.length());
120 : CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
121 : CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
122 : CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
123 :
124 : int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
125 : interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
126 : AdvanceToOffsetForTracing(bytecode_iterator, offset);
127 : if (offset == bytecode_iterator.current_offset()) {
128 : OFStream os(stdout);
129 :
130 : // Print bytecode.
131 : const uint8_t* base_address = bytecode_array->GetFirstBytecodeAddress();
132 : const uint8_t* bytecode_address = base_address + offset;
133 : os << " -> " << static_cast<const void*>(bytecode_address) << " @ "
134 : << std::setw(4) << offset << " : ";
135 : interpreter::BytecodeDecoder::Decode(os, bytecode_address,
136 : bytecode_array->parameter_count());
137 : os << std::endl;
138 : // Print all input registers and accumulator.
139 : PrintRegisters(os, true, bytecode_iterator, accumulator);
140 :
141 : os << std::flush;
142 : }
143 : return isolate->heap()->undefined_value();
144 : }
145 :
146 : RUNTIME_FUNCTION(Runtime_InterpreterTraceBytecodeExit) {
147 : if (!FLAG_trace_ignition) {
148 : return isolate->heap()->undefined_value();
149 : }
150 :
151 : SealHandleScope shs(isolate);
152 : DCHECK_EQ(3, args.length());
153 : CONVERT_ARG_HANDLE_CHECKED(BytecodeArray, bytecode_array, 0);
154 : CONVERT_SMI_ARG_CHECKED(bytecode_offset, 1);
155 : CONVERT_ARG_HANDLE_CHECKED(Object, accumulator, 2);
156 :
157 : int offset = bytecode_offset - BytecodeArray::kHeaderSize + kHeapObjectTag;
158 : interpreter::BytecodeArrayIterator bytecode_iterator(bytecode_array);
159 : AdvanceToOffsetForTracing(bytecode_iterator, offset);
160 : // The offset comparison here ensures registers only printed when the
161 : // (potentially) widened bytecode has completed. The iterator reports
162 : // the offset as the offset of the prefix bytecode.
163 : if (bytecode_iterator.current_operand_scale() ==
164 : interpreter::OperandScale::kSingle ||
165 : offset > bytecode_iterator.current_offset()) {
166 : OFStream os(stdout);
167 : // Print all output registers and accumulator.
168 : PrintRegisters(os, false, bytecode_iterator, accumulator);
169 : os << std::flush;
170 : }
171 : return isolate->heap()->undefined_value();
172 : }
173 :
174 : #endif
175 :
176 : } // namespace internal
177 : } // namespace v8
|