Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(436)

Side by Side Diff: test/cctest/interpreter/bytecode-expectations-printer.cc

Issue 1698403002: [Interpreter] generate-bytecode-expectations improvements. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rename wrapper-name, merge kInteger and kDouble, top level code. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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 "test/cctest/interpreter/bytecode-expectations-printer.h" 5 #include "test/cctest/interpreter/bytecode-expectations-printer.h"
6 6
7 #include <iostream> 7 #include <iostream>
8 #include <vector>
8 9
9 #include "include/libplatform/libplatform.h" 10 #include "include/libplatform/libplatform.h"
10 #include "include/v8.h" 11 #include "include/v8.h"
11 12
12 #include "src/base/logging.h" 13 #include "src/base/logging.h"
13 #include "src/base/smart-pointers.h" 14 #include "src/base/smart-pointers.h"
14 #include "src/compiler.h" 15 #include "src/compiler.h"
15 16
16 #include "src/interpreter/bytecode-array-iterator.h" 17 #include "src/interpreter/bytecode-array-iterator.h"
17 #include "src/interpreter/bytecode-generator.h" 18 #include "src/interpreter/bytecode-generator.h"
18 #include "src/interpreter/bytecodes.h" 19 #include "src/interpreter/bytecodes.h"
19 #include "src/interpreter/interpreter.h" 20 #include "src/interpreter/interpreter.h"
20 21
21 namespace v8 { 22 namespace v8 {
22 namespace internal { 23 namespace internal {
23 namespace interpreter { 24 namespace interpreter {
24 25
26 // static
27 const char* const BytecodeExpectationsPrinter::kDefaultTopFunctionName =
28 "__genbckexp_wrapper__";
29
25 v8::Local<v8::String> BytecodeExpectationsPrinter::V8StringFromUTF8( 30 v8::Local<v8::String> BytecodeExpectationsPrinter::V8StringFromUTF8(
26 const char* data) const { 31 const char* data) const {
27 return v8::String::NewFromUtf8(isolate_, data, v8::NewStringType::kNormal) 32 return v8::String::NewFromUtf8(isolate_, data, v8::NewStringType::kNormal)
28 .ToLocalChecked(); 33 .ToLocalChecked();
29 } 34 }
30 35
31 std::string BytecodeExpectationsPrinter::WrapCodeInFunction( 36 std::string BytecodeExpectationsPrinter::WrapCodeInFunction(
32 const char* function_name, const std::string& function_body) const { 37 const char* function_name, const std::string& function_body) const {
33 std::ostringstream program_stream; 38 std::ostringstream program_stream;
34 program_stream << "function " << function_name << "() {" << function_body 39 program_stream << "function " << function_name << "() {" << function_body
35 << "}\n" 40 << "}\n"
36 << function_name << "();"; 41 << function_name << "();";
37 42
38 return program_stream.str(); 43 return program_stream.str();
39 } 44 }
40 45
41 v8::Local<v8::Value> BytecodeExpectationsPrinter::CompileAndRun( 46 v8::Local<v8::Script> BytecodeExpectationsPrinter::Compile(
42 const char* program) const { 47 const char* program) const {
43 v8::Local<v8::String> source = V8StringFromUTF8(program); 48 v8::Local<v8::String> source = V8StringFromUTF8(program);
44 v8::Local<v8::Script> script = 49 return v8::Script::Compile(isolate_->GetCurrentContext(), source)
45 v8::Script::Compile(isolate_->GetCurrentContext(), source) 50 .ToLocalChecked();
46 .ToLocalChecked(); 51 }
47 52
48 v8::Local<v8::Value> result; 53 void BytecodeExpectationsPrinter::Run(v8::Local<v8::Script> script) const {
49 CHECK(script->Run(isolate_->GetCurrentContext()).ToLocal(&result)); 54 (void)script->Run(isolate_->GetCurrentContext());
50
51 return result;
52 } 55 }
53 56
54 i::Handle<v8::internal::BytecodeArray> 57 i::Handle<v8::internal::BytecodeArray>
55 BytecodeExpectationsPrinter::GetBytecodeArrayForGlobal( 58 BytecodeExpectationsPrinter::GetBytecodeArrayForGlobal(
56 const char* global_name) const { 59 const char* global_name) const {
57 const v8::Local<v8::Context>& context = isolate_->GetCurrentContext(); 60 const v8::Local<v8::Context>& context = isolate_->GetCurrentContext();
58 v8::Local<v8::String> v8_global_name = V8StringFromUTF8(global_name); 61 v8::Local<v8::String> v8_global_name = V8StringFromUTF8(global_name);
59 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( 62 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
60 context->Global()->Get(context, v8_global_name).ToLocalChecked()); 63 context->Global()->Get(context, v8_global_name).ToLocalChecked());
61 i::Handle<i::JSFunction> js_function = 64 i::Handle<i::JSFunction> js_function =
62 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function)); 65 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function));
63 66
64 i::Handle<i::BytecodeArray> bytecodes = 67 i::Handle<i::BytecodeArray> bytecodes =
65 i::handle(js_function->shared()->bytecode_array(), i_isolate()); 68 i::handle(js_function->shared()->bytecode_array(), i_isolate());
66 69
67 return bytecodes; 70 return bytecodes;
68 } 71 }
69 72
73 i::Handle<i::BytecodeArray>
74 BytecodeExpectationsPrinter::GetBytecodeArrayForScript(
75 v8::Local<v8::Script> script) const {
76 i::Handle<i::JSFunction> js_function = v8::Utils::OpenHandle(*script);
77 return i::handle(js_function->shared()->bytecode_array(), i_isolate());
78 }
79
70 void BytecodeExpectationsPrinter::PrintEscapedString( 80 void BytecodeExpectationsPrinter::PrintEscapedString(
71 std::ostream& stream, const std::string& string) const { 81 std::ostream& stream, const std::string& string) const {
72 for (char c : string) { 82 for (char c : string) {
73 switch (c) { 83 switch (c) {
74 case '"': 84 case '"':
75 stream << "\\\""; 85 stream << "\\\"";
76 break; 86 break;
77 case '\\': 87 case '\\':
78 stream << "\\\\"; 88 stream << "\\\\";
79 break; 89 break;
80 default: 90 default:
81 stream << c; 91 stream << c;
82 break; 92 break;
83 } 93 }
84 } 94 }
85 } 95 }
86 96
87 void BytecodeExpectationsPrinter::PrintBytecodeOperand( 97 void BytecodeExpectationsPrinter::PrintBytecodeOperand(
88 std::ostream& stream, const BytecodeArrayIterator& bytecode_iter, 98 std::ostream& stream, const BytecodeArrayIterator& bytecode_iter,
89 const Bytecode& bytecode, int op_index) const { 99 const Bytecode& bytecode, int op_index, int parameter_count) const {
90 OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index); 100 OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index);
91 OperandSize op_size = Bytecodes::GetOperandSize(bytecode, op_index); 101 OperandSize op_size = Bytecodes::GetOperandSize(bytecode, op_index);
92 102
93 const char* size_tag; 103 const char* size_tag;
94 switch (op_size) { 104 switch (op_size) {
95 case OperandSize::kByte: 105 case OperandSize::kByte:
96 size_tag = "8"; 106 size_tag = "8";
97 break; 107 break;
98 case OperandSize::kShort: 108 case OperandSize::kShort:
99 size_tag = "16"; 109 size_tag = "16";
100 break; 110 break;
101 default: 111 default:
102 UNREACHABLE(); 112 UNREACHABLE();
103 return; 113 return;
104 } 114 }
105 115
106 if (Bytecodes::IsRegisterOperandType(op_type)) { 116 if (Bytecodes::IsRegisterOperandType(op_type)) {
107 Register register_value = bytecode_iter.GetRegisterOperand(op_index); 117 Register register_value = bytecode_iter.GetRegisterOperand(op_index);
108 stream << 'R'; 118 stream << 'R';
109 if (op_size != OperandSize::kByte) stream << size_tag; 119 if (op_size != OperandSize::kByte) stream << size_tag;
110 stream << '(' << register_value.index() << ')'; 120 if (register_value.is_new_target()) {
121 stream << "(new_target)";
122 } else if (register_value.is_current_context()) {
123 stream << "(context)";
124 } else if (register_value.is_function_closure()) {
125 stream << "(closure)";
126 } else if (register_value.is_parameter()) {
127 int parameter_index = register_value.ToParameterIndex(parameter_count);
128 if (parameter_index == 0) {
129 stream << "(this)";
130 } else {
131 stream << "(arg" << (parameter_index - 1) << ')';
132 }
133 } else {
134 stream << '(' << register_value.index() << ')';
135 }
111 } else { 136 } else {
112 stream << 'U' << size_tag << '('; 137 stream << 'U' << size_tag << '(';
113 138
114 if (Bytecodes::IsImmediateOperandType(op_type)) { 139 if (Bytecodes::IsImmediateOperandType(op_type)) {
115 // We need a cast, otherwise the result is printed as char. 140 // We need a cast, otherwise the result is printed as char.
116 stream << static_cast<int>(bytecode_iter.GetImmediateOperand(op_index)); 141 stream << static_cast<int>(bytecode_iter.GetImmediateOperand(op_index));
117 } else if (Bytecodes::IsRegisterCountOperandType(op_type)) { 142 } else if (Bytecodes::IsRegisterCountOperandType(op_type)) {
118 stream << bytecode_iter.GetRegisterCountOperand(op_index); 143 stream << bytecode_iter.GetRegisterCountOperand(op_index);
119 } else if (Bytecodes::IsIndexOperandType(op_type)) { 144 } else if (Bytecodes::IsIndexOperandType(op_type)) {
120 stream << bytecode_iter.GetIndexOperand(op_index); 145 stream << bytecode_iter.GetIndexOperand(op_index);
121 } else { 146 } else {
122 UNREACHABLE(); 147 UNREACHABLE();
123 } 148 }
124 149
125 stream << ')'; 150 stream << ')';
126 } 151 }
127 } 152 }
128 153
129 void BytecodeExpectationsPrinter::PrintBytecode( 154 void BytecodeExpectationsPrinter::PrintBytecode(
130 std::ostream& stream, const BytecodeArrayIterator& bytecode_iter) const { 155 std::ostream& stream, const BytecodeArrayIterator& bytecode_iter,
156 int parameter_count) const {
131 Bytecode bytecode = bytecode_iter.current_bytecode(); 157 Bytecode bytecode = bytecode_iter.current_bytecode();
132 158
133 stream << "B(" << Bytecodes::ToString(bytecode) << ')'; 159 stream << "B(" << Bytecodes::ToString(bytecode) << ')';
134 160
135 int operands_count = Bytecodes::NumberOfOperands(bytecode); 161 int operands_count = Bytecodes::NumberOfOperands(bytecode);
136 for (int op_index = 0; op_index < operands_count; ++op_index) { 162 for (int op_index = 0; op_index < operands_count; ++op_index) {
137 stream << ", "; 163 stream << ", ";
138 PrintBytecodeOperand(stream, bytecode_iter, bytecode, op_index); 164 PrintBytecodeOperand(stream, bytecode_iter, bytecode, op_index,
165 parameter_count);
139 } 166 }
140 } 167 }
141 168
142 void BytecodeExpectationsPrinter::PrintV8String(std::ostream& stream, 169 void BytecodeExpectationsPrinter::PrintV8String(std::ostream& stream,
143 i::String* string) const { 170 i::String* string) const {
144 stream << '"'; 171 stream << '"';
145 for (int i = 0, length = string->length(); i < length; ++i) { 172 for (int i = 0, length = string->length(); i < length; ++i) {
146 stream << i::AsEscapedUC16ForJSON(string->Get(i)); 173 stream << i::AsEscapedUC16ForJSON(string->Get(i));
147 } 174 }
148 stream << '"'; 175 stream << '"';
149 } 176 }
150 177
151 void BytecodeExpectationsPrinter::PrintConstant( 178 void BytecodeExpectationsPrinter::PrintConstant(
152 std::ostream& stream, i::Handle<i::Object> constant) const { 179 std::ostream& stream, i::Handle<i::Object> constant) const {
153 switch (const_pool_type_) { 180 switch (const_pool_type_) {
154 case ConstantPoolType::kString: 181 case ConstantPoolType::kString:
155 CHECK(constant->IsString()); 182 CHECK(constant->IsString());
156 PrintV8String(stream, i::String::cast(*constant)); 183 PrintV8String(stream, i::String::cast(*constant));
157 break; 184 break;
158 case ConstantPoolType::kInteger: 185 case ConstantPoolType::kNumber:
159 if (constant->IsSmi()) { 186 if (constant->IsSmi()) {
160 i::Smi::cast(*constant)->SmiPrint(stream); 187 i::Smi::cast(*constant)->SmiPrint(stream);
161 } else if (constant->IsHeapNumber()) { 188 } else if (constant->IsHeapNumber()) {
162 i::HeapNumber::cast(*constant)->HeapNumberPrint(stream); 189 i::HeapNumber::cast(*constant)->HeapNumberPrint(stream);
163 } else { 190 } else {
164 UNREACHABLE(); 191 UNREACHABLE();
165 } 192 }
166 break; 193 break;
167 case ConstantPoolType::kDouble:
168 i::HeapNumber::cast(*constant)->HeapNumberPrint(stream);
169 break;
170 case ConstantPoolType::kMixed: 194 case ConstantPoolType::kMixed:
171 if (constant->IsSmi()) { 195 if (constant->IsSmi()) {
172 stream << "kInstanceTypeDontCare"; 196 stream << "kInstanceTypeDontCare";
173 } else { 197 } else {
174 stream << "InstanceType::" 198 stream << "InstanceType::"
175 << i::HeapObject::cast(*constant)->map()->instance_type(); 199 << i::HeapObject::cast(*constant)->map()->instance_type();
176 } 200 }
177 break; 201 break;
178 case ConstantPoolType::kUnknown: 202 case ConstantPoolType::kUnknown:
179 default: 203 default:
(...skipping 12 matching lines...) Expand all
192 if (frame_size > 0) stream << " # in multiples of sizeof(void*)"; 216 if (frame_size > 0) stream << " # in multiples of sizeof(void*)";
193 stream << "\nparameter count: " << bytecode_array->parameter_count() << '\n'; 217 stream << "\nparameter count: " << bytecode_array->parameter_count() << '\n';
194 } 218 }
195 219
196 void BytecodeExpectationsPrinter::PrintBytecodeSequence( 220 void BytecodeExpectationsPrinter::PrintBytecodeSequence(
197 std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { 221 std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const {
198 stream << "bytecodes: [\n"; 222 stream << "bytecodes: [\n";
199 BytecodeArrayIterator bytecode_iter(bytecode_array); 223 BytecodeArrayIterator bytecode_iter(bytecode_array);
200 for (; !bytecode_iter.done(); bytecode_iter.Advance()) { 224 for (; !bytecode_iter.done(); bytecode_iter.Advance()) {
201 stream << " "; 225 stream << " ";
202 PrintBytecode(stream, bytecode_iter); 226 PrintBytecode(stream, bytecode_iter, bytecode_array->parameter_count());
203 stream << ",\n"; 227 stream << ",\n";
204 } 228 }
205 stream << "]\n"; 229 stream << "]\n";
206 } 230 }
207 231
208 void BytecodeExpectationsPrinter::PrintConstantPool( 232 void BytecodeExpectationsPrinter::PrintConstantPool(
209 std::ostream& stream, i::FixedArray* constant_pool) const { 233 std::ostream& stream, i::FixedArray* constant_pool) const {
210 stream << "constant pool: [\n"; 234 stream << "constant pool: [\n";
211 int num_constants = constant_pool->length(); 235 int num_constants = constant_pool->length();
212 if (num_constants > 0) { 236 if (num_constants > 0) {
(...skipping 12 matching lines...) Expand all
225 std::stringstream body_stream(body); 249 std::stringstream body_stream(body);
226 std::string body_line; 250 std::string body_line;
227 while (std::getline(body_stream, body_line)) { 251 while (std::getline(body_stream, body_line)) {
228 stream << " "; 252 stream << " ";
229 PrintEscapedString(stream, body_line); 253 PrintEscapedString(stream, body_line);
230 stream << '\n'; 254 stream << '\n';
231 } 255 }
232 stream << "\"\n"; 256 stream << "\"\n";
233 } 257 }
234 258
259 void BytecodeExpectationsPrinter::PrintHandlers(
260 std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const {
261 stream << "handlers: [\n";
262 HandlerTable* table = HandlerTable::cast(bytecode_array->handler_table());
263 for (int i = 0, num_entries = table->NumberOfRangeEntries(); i < num_entries;
264 ++i) {
265 stream << " [" << table->GetRangeStart(i) << ", " << table->GetRangeEnd(i)
266 << ", " << table->GetRangeHandler(i) << "],\n";
267 }
268 stream << "]\n";
269 }
270
235 void BytecodeExpectationsPrinter::PrintBytecodeArray( 271 void BytecodeExpectationsPrinter::PrintBytecodeArray(
236 std::ostream& stream, const std::string& body, 272 std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const {
237 i::Handle<i::BytecodeArray> bytecode_array) const {
238 stream << "---\n";
239 PrintCodeSnippet(stream, body);
240 PrintFrameSize(stream, bytecode_array); 273 PrintFrameSize(stream, bytecode_array);
241 PrintBytecodeSequence(stream, bytecode_array); 274 PrintBytecodeSequence(stream, bytecode_array);
242 PrintConstantPool(stream, bytecode_array->constant_pool()); 275 PrintConstantPool(stream, bytecode_array->constant_pool());
243 276 PrintHandlers(stream, bytecode_array);
244 // TODO(ssanfilippo) print handlers.
245 i::HandlerTable* handlers =
246 i::HandlerTable::cast(bytecode_array->handler_table());
247 CHECK_EQ(handlers->NumberOfRangeEntries(), 0);
248 } 277 }
249 278
250 void BytecodeExpectationsPrinter::PrintExpectation( 279 void BytecodeExpectationsPrinter::PrintExpectation(
251 std::ostream& stream, const std::string& snippet) const { 280 std::ostream& stream, const std::string& snippet) const {
252 const char* wrapper_function_name = "__genbckexp_wrapper__"; 281 std::string source_code =
282 wrap_ ? WrapCodeInFunction(top_function_name_.c_str(), snippet) : snippet;
253 283
254 std::string source_code = WrapCodeInFunction(wrapper_function_name, snippet); 284 v8::Local<v8::Script> script = Compile(source_code.c_str());
255 CompileAndRun(source_code.c_str()); 285
286 if (execute_) Run(script);
256 287
257 i::Handle<i::BytecodeArray> bytecode_array = 288 i::Handle<i::BytecodeArray> bytecode_array =
258 GetBytecodeArrayForGlobal(wrapper_function_name); 289 top_level_code_ ? GetBytecodeArrayForScript(script)
290 : GetBytecodeArrayForGlobal(top_function_name_.c_str());
259 291
260 PrintBytecodeArray(stream, snippet, bytecode_array); 292 stream << "---\n";
293 PrintCodeSnippet(stream, snippet);
294 PrintBytecodeArray(stream, bytecode_array);
261 stream << '\n'; 295 stream << '\n';
262 } 296 }
263 297
264 } // namespace interpreter 298 } // namespace interpreter
265 } // namespace internal 299 } // namespace internal
266 } // namespace v8 300 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698