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

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

Issue 1688383003: [Interpreter] Change the output format of generate-bytecode-expectations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Do not create a static lib target. 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 <fstream> 5 #include "test/cctest/interpreter/bytecode-expectations.h"
6
6 #include <iostream> 7 #include <iostream>
7 8
8 #include "include/libplatform/libplatform.h" 9 #include "include/libplatform/libplatform.h"
9 #include "include/v8.h" 10 #include "include/v8.h"
10 11
11 #include "src/base/logging.h" 12 #include "src/base/logging.h"
12 #include "src/base/smart-pointers.h" 13 #include "src/base/smart-pointers.h"
13 #include "src/compiler.h" 14 #include "src/compiler.h"
14 15
15 #include "src/interpreter/bytecode-array-iterator.h" 16 #include "src/interpreter/bytecode-array-iterator.h"
16 #include "src/interpreter/bytecode-generator.h" 17 #include "src/interpreter/bytecode-generator.h"
17 #include "src/interpreter/bytecodes.h" 18 #include "src/interpreter/bytecodes.h"
18 #include "src/interpreter/interpreter.h" 19 #include "src/interpreter/interpreter.h"
19 20
20 using namespace i::interpreter; 21 using namespace v8::internal::interpreter;
21 22
22 namespace { 23 namespace {
23 24
24 const char* kIndent = " ";
25
26 enum ConstantPoolType {
27 kConstantPoolTypeUnknown,
28 kConstantPoolTypeString,
29 kConstantPoolTypeInteger,
30 kConstantPoolTypeDouble,
31 kConstantPoolTypeMixed,
32 };
33
34 class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator { 25 class ArrayBufferAllocator final : public v8::ArrayBuffer::Allocator {
35 public: 26 public:
36 void* Allocate(size_t length) override { 27 void* Allocate(size_t length) override {
37 void* data = AllocateUninitialized(length); 28 void* data = AllocateUninitialized(length);
38 if (data != nullptr) memset(data, 0, length); 29 if (data != nullptr) memset(data, 0, length);
39 return data; 30 return data;
40 } 31 }
41 void* AllocateUninitialized(size_t length) override { return malloc(length); } 32 void* AllocateUninitialized(size_t length) override { return malloc(length); }
42 void Free(void* data, size_t) override { free(data); } 33 void Free(void* data, size_t) override { free(data); }
43 }; 34 };
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 context->Global()->Get(context, v8_global_name).ToLocalChecked()); 113 context->Global()->Get(context, v8_global_name).ToLocalChecked());
123 i::Handle<i::JSFunction> js_function = 114 i::Handle<i::JSFunction> js_function =
124 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function)); 115 i::Handle<i::JSFunction>::cast(v8::Utils::OpenHandle(*function));
125 116
126 i::Handle<i::BytecodeArray> bytecodes = i::handle( 117 i::Handle<i::BytecodeArray> bytecodes = i::handle(
127 js_function->shared()->bytecode_array(), GetInternalIsolate(isolate)); 118 js_function->shared()->bytecode_array(), GetInternalIsolate(isolate));
128 119
129 return bytecodes; 120 return bytecodes;
130 } 121 }
131 122
132 std::string QuoteCString(const std::string& source) { 123 void PrintEscapedString(std::ostream& stream, const std::string& string) {
133 std::string quoted_buffer; 124 for (char c : string) {
134 for (char c : source) {
135 switch (c) { 125 switch (c) {
136 case '"': 126 case '"':
137 quoted_buffer += "\\\""; 127 stream << "\\\"";
138 break;
139 case '\n':
140 quoted_buffer += "\\n";
141 break;
142 case '\t':
143 quoted_buffer += "\\t";
144 break; 128 break;
145 case '\\': 129 case '\\':
146 quoted_buffer += "\\\\"; 130 stream << "\\\\";
147 break; 131 break;
148 default: 132 default:
149 quoted_buffer += c; 133 stream << c;
150 break; 134 break;
151 } 135 }
152 } 136 }
153 return quoted_buffer;
154 } 137 }
155 138
156 void PrintBytecodeOperand(std::ostream& stream, 139 void PrintBytecodeOperand(std::ostream& stream,
157 const BytecodeArrayIterator& bytecode_iter, 140 const BytecodeArrayIterator& bytecode_iter,
158 const Bytecode& bytecode, int op_index) { 141 const Bytecode& bytecode, int op_index) {
159 OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index); 142 OperandType op_type = Bytecodes::GetOperandType(bytecode, op_index);
160 OperandSize op_size = Bytecodes::GetOperandSize(bytecode, op_index); 143 OperandSize op_size = Bytecodes::GetOperandSize(bytecode, op_index);
161 144
162 const char* size_tag; 145 const char* size_tag;
163 switch (op_size) { 146 switch (op_size) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 UNREACHABLE(); 231 UNREACHABLE();
249 return; 232 return;
250 } 233 }
251 } 234 }
252 235
253 void PrintFrameSize(std::ostream& stream, 236 void PrintFrameSize(std::ostream& stream,
254 i::Handle<i::BytecodeArray> bytecode_array) { 237 i::Handle<i::BytecodeArray> bytecode_array) {
255 const int kPointerSize = sizeof(void*); 238 const int kPointerSize = sizeof(void*);
256 int frame_size = bytecode_array->frame_size(); 239 int frame_size = bytecode_array->frame_size();
257 240
258 stream << kIndent; 241 DCHECK_EQ(frame_size % kPointerSize, 0);
259 242 stream << "frame size: " << frame_size / kPointerSize;
260 DCHECK(frame_size % kPointerSize == 0); 243 if (frame_size > 0) stream << " # in multiples of sizeof(void*)";
261 if (frame_size > kPointerSize) { 244 stream << "\nparameter count: " << bytecode_array->parameter_count() << '\n';
262 stream << ' ' << frame_size / kPointerSize << " * kPointerSize,\n"
263 << kIndent;
264 } else if (frame_size == kPointerSize) {
265 stream << " kPointerSize,\n" << kIndent;
266 } else if (frame_size == 0) {
267 stream << " 0,\n" << kIndent;
268 }
269
270 stream << ' ' << bytecode_array->parameter_count() << ",\n";
271 } 245 }
272 246
273 void PrintBytecodeSequence(std::ostream& stream, 247 void PrintBytecodeSequence(std::ostream& stream,
274 i::Handle<i::BytecodeArray> bytecode_array) { 248 i::Handle<i::BytecodeArray> bytecode_array) {
275 stream << kIndent << ' ' << bytecode_array->length() << ",\n" 249 stream << "bytecodes: [\n";
276 << kIndent << " {\n"
277 << kIndent << " ";
278
279 BytecodeArrayIterator bytecode_iter{bytecode_array}; 250 BytecodeArrayIterator bytecode_iter{bytecode_array};
280 for (; !bytecode_iter.done(); bytecode_iter.Advance()) { 251 for (; !bytecode_iter.done(); bytecode_iter.Advance()) {
281 // Print separator before each instruction, except the first one. 252 stream << " ";
282 if (bytecode_iter.current_offset() > 0) {
283 stream << ",\n" << kIndent << " ";
284 }
285 PrintBytecode(stream, bytecode_iter); 253 PrintBytecode(stream, bytecode_iter);
254 stream << ",\n";
286 } 255 }
256 stream << "]\n";
287 } 257 }
288 258
289 void PrintConstantPool(std::ostream& stream, i::FixedArray* constant_pool, 259 void PrintConstantPool(std::ostream& stream, i::FixedArray* constant_pool,
290 ConstantPoolType expected_constant_type, 260 ConstantPoolType expected_constant_type,
291 v8::Isolate* isolate) { 261 v8::Isolate* isolate) {
262 stream << "constant pool: [\n";
292 int num_constants = constant_pool->length(); 263 int num_constants = constant_pool->length();
293 stream << "\n" << kIndent << " },\n" << kIndent << ' ' << num_constants;
294 if (num_constants > 0) { 264 if (num_constants > 0) {
295 stream << ",\n" << kIndent << " {";
296 for (int i = 0; i < num_constants; ++i) { 265 for (int i = 0; i < num_constants; ++i) {
297 // Print separator before each constant, except the first one 266 stream << " ";
298 if (i != 0) stream << ", ";
299 PrintConstant( 267 PrintConstant(
300 stream, expected_constant_type, 268 stream, expected_constant_type,
301 i::FixedArray::get(constant_pool, i, GetInternalIsolate(isolate))); 269 i::FixedArray::get(constant_pool, i, GetInternalIsolate(isolate)));
270 stream << ",\n";
302 } 271 }
303 stream << '}';
304 } 272 }
305 stream << '\n'; 273 stream << "]\n";
274 }
275
276 void PrintCodeSnippet(std::ostream& stream, const std::string& body) {
277 stream << "snippet: \"\n";
278 std::stringstream body_stream{body};
279 std::string body_line;
280 while (std::getline(body_stream, body_line)) {
281 stream << " ";
282 PrintEscapedString(stream, body_line);
283 stream << '\n';
284 }
285 stream << "\"\n";
306 } 286 }
307 287
308 void PrintBytecodeArray(std::ostream& stream, 288 void PrintBytecodeArray(std::ostream& stream,
309 i::Handle<i::BytecodeArray> bytecode_array, 289 i::Handle<i::BytecodeArray> bytecode_array,
310 const std::string& body, v8::Isolate* isolate, 290 const std::string& body, v8::Isolate* isolate,
311 ConstantPoolType constant_pool_type, 291 ConstantPoolType constant_pool_type) {
312 bool print_banner = true) { 292 stream << "\n---\n";
313 if (print_banner) { 293 PrintCodeSnippet(stream, body);
314 stream << kIndent << "// === ExpectedSnippet generated by "
315 "generate-bytecode-expectations. ===\n";
316 }
317
318 // Print the code snippet as a quoted C string.
319 stream << kIndent << "{" << '"' << QuoteCString(body) << "\",\n";
320
321 PrintFrameSize(stream, bytecode_array); 294 PrintFrameSize(stream, bytecode_array);
322 PrintBytecodeSequence(stream, bytecode_array); 295 PrintBytecodeSequence(stream, bytecode_array);
323 PrintConstantPool(stream, bytecode_array->constant_pool(), constant_pool_type, 296 PrintConstantPool(stream, bytecode_array->constant_pool(), constant_pool_type,
324 isolate); 297 isolate);
325 298
326 // TODO(ssanfilippo) print handlers. 299 // TODO(ssanfilippo) print handlers.
327 i::HandlerTable* handlers = 300 i::HandlerTable* handlers =
328 i::HandlerTable::cast(bytecode_array->handler_table()); 301 i::HandlerTable::cast(bytecode_array->handler_table());
329 CHECK_EQ(handlers->NumberOfRangeEntries(), 0); 302 CHECK_EQ(handlers->NumberOfRangeEntries(), 0);
330
331 stream << kIndent << "}\n";
332 } 303 }
333 304
334 void PrintExpectedSnippet(ConstantPoolType constant_pool_type, char* exec_path, 305 void PrintExpectation(std::ostream& stream, const std::string& snippet,
335 std::string body) { 306 ConstantPoolType const_pool_type,
307 v8::Local<v8::Context> context, v8::Isolate* isolate) {
336 const char* wrapper_function_name = "__genbckexp_wrapper__"; 308 const char* wrapper_function_name = "__genbckexp_wrapper__";
337 309
338 V8InitializationScope platform(exec_path); 310 std::string source_code = WrapCodeInFunction(wrapper_function_name, snippet);
339 { 311 CompileAndRun(isolate, context, source_code.c_str());
340 v8::Isolate::Scope isolate_scope(platform.isolate());
341 v8::HandleScope handle_scope(platform.isolate());
342 v8::Local<v8::Context> context = v8::Context::New(platform.isolate());
343 v8::Context::Scope context_scope(context);
344 312
345 std::string source_code = WrapCodeInFunction(wrapper_function_name, body); 313 i::Handle<i::BytecodeArray> bytecode_array =
346 CompileAndRun(platform.isolate(), context, source_code.c_str()); 314 GetBytecodeArrayForGlobal(isolate, context, wrapper_function_name);
347 315
348 i::Handle<i::BytecodeArray> bytecode_array = GetBytecodeArrayForGlobal( 316 PrintBytecodeArray(std::cout, bytecode_array, snippet, isolate,
349 platform.isolate(), context, wrapper_function_name); 317 const_pool_type);
350
351 PrintBytecodeArray(std::cout, bytecode_array, body, platform.isolate(),
352 constant_pool_type);
353 }
354 }
355
356 bool ReadFromFileOrStdin(std::string* body, const char* body_filename) {
357 std::stringstream body_buffer;
358 if (strcmp(body_filename, "-") == 0) {
359 body_buffer << std::cin.rdbuf();
360 } else {
361 std::ifstream body_file{body_filename};
362 if (!body_file) return false;
363 body_buffer << body_file.rdbuf();
364 }
365 *body = body_buffer.str();
366 return true;
367 }
368
369 ConstantPoolType ParseConstantPoolType(const char* type_string) {
370 if (strcmp(type_string, "int") == 0) {
371 return kConstantPoolTypeInteger;
372 } else if (strcmp(type_string, "double") == 0) {
373 return kConstantPoolTypeDouble;
374 } else if (strcmp(type_string, "string") == 0) {
375 return kConstantPoolTypeString;
376 } else if (strcmp(type_string, "mixed") == 0) {
377 return kConstantPoolTypeMixed;
378 }
379 return kConstantPoolTypeUnknown;
380 }
381
382 void PrintUsage(const char* exec_path) {
383 std::cerr << "Usage: " << exec_path
384 << " (int|double|string|mixed) [filename.js|-]\n\n"
385 "First argument is the type of objects in the constant pool.\n\n"
386 "Omitting the second argument or - reads from standard input.\n"
387 "Anything else is interpreted as a filename.\n\n"
388 "This tool is intended as a help in writing tests.\n"
389 "Please, DO NOT blindly copy and paste the output "
390 "into the test suite.\n";
391 } 318 }
392 319
393 } // namespace 320 } // namespace
394 321
395 int main(int argc, char** argv) { 322 namespace v8 {
396 if (argc < 2) { 323 namespace internal {
397 PrintUsage(argv[0]); 324 namespace interpreter {
398 return 1; 325
326 void GenerateExpectationsFile(std::ostream& stream,
327 const std::vector<TestInput>& test_list,
328 const char* exec_path) {
329 V8InitializationScope platform(exec_path);
330 {
331 v8::Isolate::Scope isolate_scope{platform.isolate()};
332 v8::HandleScope handle_scope{platform.isolate()};
333 v8::Local<v8::Context> context = v8::Context::New(platform.isolate());
334 v8::Context::Scope context_scope{context};
335
336 stream << "#\n# Autogenerated by generate-bytecode-expectations\n#\n";
337
338 for (const TestInput& test : test_list) {
339 PrintExpectation(stream, test.snippet, test.const_pool_type, context,
340 platform.isolate());
341 }
399 } 342 }
343 }
400 344
401 if (argc > 1 && strcmp(argv[1], "--help") == 0) { 345 } // namespace interpreter
402 PrintUsage(argv[0]); 346 } // namespace internal
403 return 0; 347 } // namespace v8
404 }
405
406 const char* body_filename = (argc > 2 ? argv[2] : "-");
407 const char* const_pool_type_string = argv[1];
408
409 std::string body;
410 if (!ReadFromFileOrStdin(&body, body_filename)) {
411 std::cerr << "Could not open '" << body_filename << "'.\n\n";
412 PrintUsage(argv[0]);
413 return 1;
414 }
415
416 PrintExpectedSnippet(ParseConstantPoolType(const_pool_type_string), argv[0],
417 body);
418 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698