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

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: Reorganize help message, --fix => --rebaseline for real. 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
53 void BytecodeExpectationsPrinter::Run(v8::Local<v8::Script> script) const {
48 v8::Local<v8::Value> result; 54 v8::Local<v8::Value> result;
49 CHECK(script->Run(isolate_->GetCurrentContext()).ToLocal(&result)); 55 CHECK(script->Run(isolate_->GetCurrentContext()).ToLocal(&result));
50 56 (void)result;
rmcilroy 2016/02/17 15:24:08 Just remove result variable and instead call: CHE
Stefano Sanfilippo 2016/02/17 16:40:49 Done.
51 return result;
52 } 57 }
53 58
54 i::Handle<v8::internal::BytecodeArray> 59 i::Handle<v8::internal::BytecodeArray>
55 BytecodeExpectationsPrinter::GetBytecodeArrayForGlobal( 60 BytecodeExpectationsPrinter::GetBytecodeArrayForGlobal(
56 const char* global_name) const { 61 const char* global_name) const {
57 const v8::Local<v8::Context>& context = isolate_->GetCurrentContext(); 62 const v8::Local<v8::Context>& context = isolate_->GetCurrentContext();
58 v8::Local<v8::String> v8_global_name = V8StringFromUTF8(global_name); 63 v8::Local<v8::String> v8_global_name = V8StringFromUTF8(global_name);
59 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( 64 v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
60 context->Global()->Get(context, v8_global_name).ToLocalChecked()); 65 context->Global()->Get(context, v8_global_name).ToLocalChecked());
61 i::Handle<i::JSFunction> js_function = 66 i::Handle<i::JSFunction> js_function =
(...skipping 17 matching lines...) Expand all
79 break; 84 break;
80 default: 85 default:
81 stream << c; 86 stream << c;
82 break; 87 break;
83 } 88 }
84 } 89 }
85 } 90 }
86 91
87 void BytecodeExpectationsPrinter::PrintBytecodeOperand( 92 void BytecodeExpectationsPrinter::PrintBytecodeOperand(
88 std::ostream& stream, const BytecodeArrayIterator& bytecode_iter, 93 std::ostream& stream, const BytecodeArrayIterator& bytecode_iter,
89 const Bytecode& bytecode, int op_index) const { 94 const Bytecode& bytecode, int op_index, int parameter_count) const {
90 OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index); 95 OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index);
91 OperandSize op_size = Bytecodes::GetOperandSize(bytecode, op_index); 96 OperandSize op_size = Bytecodes::GetOperandSize(bytecode, op_index);
92 97
93 const char* size_tag; 98 const char* size_tag;
94 switch (op_size) { 99 switch (op_size) {
95 case OperandSize::kByte: 100 case OperandSize::kByte:
96 size_tag = "8"; 101 size_tag = "8";
97 break; 102 break;
98 case OperandSize::kShort: 103 case OperandSize::kShort:
99 size_tag = "16"; 104 size_tag = "16";
100 break; 105 break;
101 default: 106 default:
102 UNREACHABLE(); 107 UNREACHABLE();
103 return; 108 return;
104 } 109 }
105 110
106 if (Bytecodes::IsRegisterOperandType(op_type)) { 111 if (Bytecodes::IsRegisterOperandType(op_type)) {
107 Register register_value = bytecode_iter.GetRegisterOperand(op_index); 112 Register register_value = bytecode_iter.GetRegisterOperand(op_index);
108 stream << 'R'; 113 stream << 'R';
109 if (op_size != OperandSize::kByte) stream << size_tag; 114 if (op_size != OperandSize::kByte) stream << size_tag;
110 stream << '(' << register_value.index() << ')'; 115 if (register_value.is_new_target()) {
116 stream << "(new_target)";
117 } else if (register_value.is_current_context()) {
118 stream << "(context)";
119 } else if (register_value.is_function_closure()) {
120 stream << "(closure)";
121 } else if (register_value.is_parameter()) {
122 int parameter_index = register_value.ToParameterIndex(parameter_count);
123 if (parameter_index == 0) {
124 stream << "(this)";
125 } else {
126 stream << "(arg" << (parameter_index - 1) << ')';
127 }
128 } else {
129 stream << '(' << register_value.index() << ')';
130 }
111 } else { 131 } else {
112 stream << 'U' << size_tag << '('; 132 stream << 'U' << size_tag << '(';
113 133
114 if (Bytecodes::IsImmediateOperandType(op_type)) { 134 if (Bytecodes::IsImmediateOperandType(op_type)) {
115 // We need a cast, otherwise the result is printed as char. 135 // We need a cast, otherwise the result is printed as char.
116 stream << static_cast<int>(bytecode_iter.GetImmediateOperand(op_index)); 136 stream << static_cast<int>(bytecode_iter.GetImmediateOperand(op_index));
117 } else if (Bytecodes::IsRegisterCountOperandType(op_type)) { 137 } else if (Bytecodes::IsRegisterCountOperandType(op_type)) {
118 stream << bytecode_iter.GetRegisterCountOperand(op_index); 138 stream << bytecode_iter.GetRegisterCountOperand(op_index);
119 } else if (Bytecodes::IsIndexOperandType(op_type)) { 139 } else if (Bytecodes::IsIndexOperandType(op_type)) {
120 stream << bytecode_iter.GetIndexOperand(op_index); 140 stream << bytecode_iter.GetIndexOperand(op_index);
121 } else { 141 } else {
122 UNREACHABLE(); 142 UNREACHABLE();
123 } 143 }
124 144
125 stream << ')'; 145 stream << ')';
126 } 146 }
127 } 147 }
128 148
129 void BytecodeExpectationsPrinter::PrintBytecode( 149 void BytecodeExpectationsPrinter::PrintBytecode(
130 std::ostream& stream, const BytecodeArrayIterator& bytecode_iter) const { 150 std::ostream& stream, const BytecodeArrayIterator& bytecode_iter,
151 int parameter_count) const {
131 Bytecode bytecode = bytecode_iter.current_bytecode(); 152 Bytecode bytecode = bytecode_iter.current_bytecode();
132 153
133 stream << "B(" << Bytecodes::ToString(bytecode) << ')'; 154 stream << "B(" << Bytecodes::ToString(bytecode) << ')';
134 155
135 int operands_count = Bytecodes::NumberOfOperands(bytecode); 156 int operands_count = Bytecodes::NumberOfOperands(bytecode);
136 for (int op_index = 0; op_index < operands_count; ++op_index) { 157 for (int op_index = 0; op_index < operands_count; ++op_index) {
137 stream << ", "; 158 stream << ", ";
138 PrintBytecodeOperand(stream, bytecode_iter, bytecode, op_index); 159 PrintBytecodeOperand(stream, bytecode_iter, bytecode, op_index,
160 parameter_count);
139 } 161 }
140 } 162 }
141 163
142 void BytecodeExpectationsPrinter::PrintV8String(std::ostream& stream, 164 void BytecodeExpectationsPrinter::PrintV8String(std::ostream& stream,
143 i::String* string) const { 165 i::String* string) const {
144 stream << '"'; 166 stream << '"';
145 for (int i = 0, length = string->length(); i < length; ++i) { 167 for (int i = 0, length = string->length(); i < length; ++i) {
146 stream << i::AsEscapedUC16ForJSON(string->Get(i)); 168 stream << i::AsEscapedUC16ForJSON(string->Get(i));
147 } 169 }
148 stream << '"'; 170 stream << '"';
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 if (frame_size > 0) stream << " # in multiples of sizeof(void*)"; 214 if (frame_size > 0) stream << " # in multiples of sizeof(void*)";
193 stream << "\nparameter count: " << bytecode_array->parameter_count() << '\n'; 215 stream << "\nparameter count: " << bytecode_array->parameter_count() << '\n';
194 } 216 }
195 217
196 void BytecodeExpectationsPrinter::PrintBytecodeSequence( 218 void BytecodeExpectationsPrinter::PrintBytecodeSequence(
197 std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const { 219 std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const {
198 stream << "bytecodes: [\n"; 220 stream << "bytecodes: [\n";
199 BytecodeArrayIterator bytecode_iter(bytecode_array); 221 BytecodeArrayIterator bytecode_iter(bytecode_array);
200 for (; !bytecode_iter.done(); bytecode_iter.Advance()) { 222 for (; !bytecode_iter.done(); bytecode_iter.Advance()) {
201 stream << " "; 223 stream << " ";
202 PrintBytecode(stream, bytecode_iter); 224 PrintBytecode(stream, bytecode_iter, bytecode_array->parameter_count());
203 stream << ",\n"; 225 stream << ",\n";
204 } 226 }
205 stream << "]\n"; 227 stream << "]\n";
206 } 228 }
207 229
208 void BytecodeExpectationsPrinter::PrintConstantPool( 230 void BytecodeExpectationsPrinter::PrintConstantPool(
209 std::ostream& stream, i::FixedArray* constant_pool) const { 231 std::ostream& stream, i::FixedArray* constant_pool) const {
210 stream << "constant pool: [\n"; 232 stream << "constant pool: [\n";
211 int num_constants = constant_pool->length(); 233 int num_constants = constant_pool->length();
212 if (num_constants > 0) { 234 if (num_constants > 0) {
(...skipping 12 matching lines...) Expand all
225 std::stringstream body_stream(body); 247 std::stringstream body_stream(body);
226 std::string body_line; 248 std::string body_line;
227 while (std::getline(body_stream, body_line)) { 249 while (std::getline(body_stream, body_line)) {
228 stream << " "; 250 stream << " ";
229 PrintEscapedString(stream, body_line); 251 PrintEscapedString(stream, body_line);
230 stream << '\n'; 252 stream << '\n';
231 } 253 }
232 stream << "\"\n"; 254 stream << "\"\n";
233 } 255 }
234 256
257 void BytecodeExpectationsPrinter::PrintHandlers(
258 std::ostream& stream, i::Handle<i::BytecodeArray> bytecode_array) const {
259 stream << "handlers: [\n";
260 HandlerTable* table = HandlerTable::cast(bytecode_array->handler_table());
261 for (int i = 0, num_entries = table->NumberOfRangeEntries(); i < num_entries;
262 ++i) {
263 stream << " [" << table->GetRangeStart(i) << ", " << table->GetRangeEnd(i)
264 << ", " << table->GetRangeHandler(i) << "],\n";
265 }
266 stream << "]\n";
267 }
268
235 void BytecodeExpectationsPrinter::PrintBytecodeArray( 269 void BytecodeExpectationsPrinter::PrintBytecodeArray(
236 std::ostream& stream, const std::string& body, 270 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); 271 PrintFrameSize(stream, bytecode_array);
241 PrintBytecodeSequence(stream, bytecode_array); 272 PrintBytecodeSequence(stream, bytecode_array);
242 PrintConstantPool(stream, bytecode_array->constant_pool()); 273 PrintConstantPool(stream, bytecode_array->constant_pool());
243 274 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 } 275 }
249 276
250 void BytecodeExpectationsPrinter::PrintExpectation( 277 void BytecodeExpectationsPrinter::PrintExpectation(
251 std::ostream& stream, const std::string& snippet) const { 278 std::ostream& stream, const std::string& snippet) const {
252 const char* wrapper_function_name = "__genbckexp_wrapper__"; 279 std::string source_code =
280 wrap_ ? WrapCodeInFunction(top_function_name_.c_str(), snippet) : snippet;
253 281
254 std::string source_code = WrapCodeInFunction(wrapper_function_name, snippet); 282 v8::Local<v8::Script> script = Compile(source_code.c_str());
255 CompileAndRun(source_code.c_str()); 283
284 if (execute_) Run(script);
256 285
257 i::Handle<i::BytecodeArray> bytecode_array = 286 i::Handle<i::BytecodeArray> bytecode_array =
258 GetBytecodeArrayForGlobal(wrapper_function_name); 287 GetBytecodeArrayForGlobal(top_function_name_.c_str());
259 288
260 PrintBytecodeArray(stream, snippet, bytecode_array); 289 stream << "---\n";
290 PrintCodeSnippet(stream, snippet);
291 PrintBytecodeArray(stream, bytecode_array);
261 stream << '\n'; 292 stream << '\n';
262 } 293 }
263 294
295 namespace {
296
297 const char* ConstantPoolTypeToString(
298 BytecodeExpectationsPrinter::ConstantPoolType type) {
299 switch (type) {
300 case BytecodeExpectationsPrinter::ConstantPoolType::kDouble:
301 return "double";
302 case BytecodeExpectationsPrinter::ConstantPoolType::kInteger:
303 return "integer";
304 case BytecodeExpectationsPrinter::ConstantPoolType::kMixed:
305 return "mixed";
306 case BytecodeExpectationsPrinter::ConstantPoolType::kString:
307 return "string";
308 default:
309 UNREACHABLE();
310 return nullptr;
311 }
312 }
313
314 const char* BooleanToString(bool value) { return value ? "yes" : "no"; }
315
316 } // namespace
317
318 void BytecodeExpectationsPrinter::PrintOptionsHeader(std::ostream& stream) {
319 stream << "---"
320 "\npool type: "
321 << ConstantPoolTypeToString(const_pool_type_)
322 << "\nexecute: " << BooleanToString(execute_)
323 << "\nwrap: " << BooleanToString(wrap_);
324
325 if (top_function_name_ != kDefaultTopFunctionName) {
326 stream << "\nwrapper name: " << top_function_name_;
327 }
328
329 stream << "\n\n";
330 }
331
332 void BytecodeExpectationsPrinter::PrintExpectationsArray(
333 std::ostream& stream, const std::vector<std::string>& snippet_list) {
334 stream << "#\n# Autogenerated by generate-bytecode-expectations\n#\n\n";
rmcilroy 2016/02/17 15:24:08 I meant to move this into the generate-bytecode-ex
Stefano Sanfilippo 2016/02/17 16:40:49 The issue is that if we don't have this code insid
rmcilroy 2016/02/17 17:06:36 The tests should just ignore the headers and only
Stefano Sanfilippo 2016/02/17 17:31:18 OK, then I'll make the test harness skip the golde
335 PrintOptionsHeader(stream);
336 for (const std::string& snippet : snippet_list) {
337 PrintExpectation(stream, snippet);
338 }
339 }
340
264 } // namespace interpreter 341 } // namespace interpreter
265 } // namespace internal 342 } // namespace internal
266 } // namespace v8 343 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698