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

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

Issue 1686963002: [Interpreter] Print constant pool in generate-bytecode-expectations (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <fstream>
6 #include <iostream> 6 #include <iostream>
7 7
8 #include "include/libplatform/libplatform.h" 8 #include "include/libplatform/libplatform.h"
9 #include "include/v8.h" 9 #include "include/v8.h"
10 10
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 157
158 stream << "B(" << Bytecodes::ToString(bytecode) << ')'; 158 stream << "B(" << Bytecodes::ToString(bytecode) << ')';
159 159
160 int operands_count = Bytecodes::NumberOfOperands(bytecode); 160 int operands_count = Bytecodes::NumberOfOperands(bytecode);
161 for (int op_index = 0; op_index < operands_count; ++op_index) { 161 for (int op_index = 0; op_index < operands_count; ++op_index) {
162 stream << ", "; 162 stream << ", ";
163 PrintBytecodeOperand(stream, bytecode_iter, bytecode, op_index); 163 PrintBytecodeOperand(stream, bytecode_iter, bytecode, op_index);
164 } 164 }
165 } 165 }
166 166
167 void PrintQuotedUC16Char(std::ostream& stream, uint16_t c) {
168 switch (c) {
169 case '"':
170 stream << "\\\"";
171 break;
172 case '\n':
173 stream << "\\n";
174 break;
175 case '\t':
176 stream << "\\t";
177 break;
178 case '\\':
179 stream << "\\\\";
180 break;
181 default:
182 stream << i::AsUC16(c);
183 break;
184 }
185 }
186
167 std::string QuoteCString(const std::string& source) { 187 std::string QuoteCString(const std::string& source) {
168 std::string quoted_buffer; 188 std::stringstream quoted_buffer;
169 for (char c : source) { 189 for (char c : source) {
170 switch (c) { 190 PrintQuotedUC16Char(quoted_buffer, c);
171 case '"':
172 quoted_buffer += "\\\"";
173 break;
174 case '\n':
175 quoted_buffer += "\\n";
176 break;
177 case '\t':
178 quoted_buffer += "\\t";
179 break;
180 case '\\':
181 quoted_buffer += "\\\\";
182 break;
183 default:
184 quoted_buffer += c;
185 break;
186 }
187 } 191 }
188 return quoted_buffer; 192 return quoted_buffer.str();
189 } 193 }
rmcilroy 2016/02/10 15:20:32 nit - move these PrintQuotedUC16Char and QuoteCStr
Stefano Sanfilippo 2016/02/10 15:40:16 Done. Also, please notice that I got rid of the f
190 194
191 void PrintBytecodeArray(std::ostream& stream, 195 enum ConstantPoolType {
192 i::Handle<i::BytecodeArray> bytecode_array, 196 kConstantPoolTypeUnknown,
193 const std::string& body, bool print_banner = true) { 197 kConstantPoolTypeString,
198 kConstantPoolTypeInteger,
199 kConstantPoolTypeDouble,
200 kConstantPoolTypeMixed,
201 };
rmcilroy 2016/02/10 15:20:32 nit - move this to the top of the namespace
Stefano Sanfilippo 2016/02/10 15:40:15 Done.
202
203 void PrintConstantString(std::ostream& stream, i::String* constant_string) {
rmcilroy 2016/02/10 15:20:32 /s/PrintConstantString/PrintV8String/ /s/constant_
Stefano Sanfilippo 2016/02/10 15:40:15 Done.
204 stream << '"';
205 for (int i = 0, length = constant_string->length(); i < length; ++i) {
206 PrintQuotedUC16Char(stream, constant_string->Get(i));
207 }
208 stream << '"';
209 }
210
211 void PrintConstant(std::ostream& stream,
212 ConstantPoolType expected_constant_type,
213 i::Handle<i::Object> constant) {
214 switch (expected_constant_type) {
215 case kConstantPoolTypeString:
216 CHECK(constant->IsString());
217 PrintConstantString(std::cout, i::String::cast(*constant));
rmcilroy 2016/02/10 15:20:32 /s/std::cout/stream
Stefano Sanfilippo 2016/02/10 15:40:15 Done.
218 break;
219 case kConstantPoolTypeInteger:
220 if (constant->IsSmi()) {
221 i::Smi::cast(*constant)->SmiPrint(stream);
222 } else if (constant->IsHeapNumber()) {
223 i::HeapNumber::cast(*constant)->HeapNumberPrint(stream);
224 } else {
225 UNREACHABLE();
226 }
227 break;
228 case kConstantPoolTypeDouble:
229 i::HeapNumber::cast(*constant)->HeapNumberPrint(stream);
230 break;
231 case kConstantPoolTypeMixed:
232 if (constant->IsSmi()) {
233 stream << "kInstanceTypeDontCare";
234 } else {
235 stream << "InstanceType::"
236 << i::HeapObject::cast(*constant)->map()->instance_type();
237 }
238 break;
239 default:
240 UNREACHABLE();
241 return;
242 }
243 }
244
245 void PrintConstantPool(std::ostream& stream, i::FixedArray* constant_pool,
246 ConstantPoolType expected_constant_type,
247 v8::Isolate* isolate) {
248 int num_constants = constant_pool->length();
249 stream << "\n" << kIndent << " },\n" << kIndent << ' ' << num_constants;
250 if (num_constants > 0) {
rmcilroy 2016/02/10 15:20:32 I would be fine with just always emitting a '{}' e
Stefano Sanfilippo 2016/02/10 15:40:15 You are right, although I'd prefer to skip the {}
251 stream << ",\n" << kIndent << " {";
252 for (int i = 0; i < num_constants; ++i) {
253 // Print separator before each constant, except the first one
254 if (i != 0) stream << ", ";
255 PrintConstant(
256 stream, expected_constant_type,
257 i::FixedArray::get(constant_pool, i, GetInternalIsolate(isolate)));
258 }
259 stream << '}';
260 }
261 stream << '\n';
262 }
263
264 void PrintBytecodeSequence(std::ostream& stream,
265 i::Handle<i::BytecodeArray> bytecode_array) {
266 BytecodeArrayIterator bytecode_iter{bytecode_array};
267 for (; !bytecode_iter.done(); bytecode_iter.Advance()) {
268 // Print separator before each instruction, except the first one.
269 if (bytecode_iter.current_offset() > 0) {
270 stream << ",\n" << kIndent << " ";
271 }
272 PrintBytecode(stream, bytecode_iter);
273 }
274 }
275
276 void PrintFrameSize(std::ostream& stream, int frame_size) {
rmcilroy 2016/02/10 15:20:32 nit - order the functions in the same order as the
Stefano Sanfilippo 2016/02/10 15:40:15 Done.
194 const int kPointerSize = sizeof(void*); 277 const int kPointerSize = sizeof(void*);
195 278
196 if (print_banner) {
197 stream << kIndent << "// === ExpectedSnippet generated by "
198 "generate-bytecode-expectations. ===\n";
199 }
200
201 // Print the code snippet as a quoted C string.
202 stream << kIndent << "{" << '"' << QuoteCString(body) << "\",\n" << kIndent;
203
204 // Print the frame size, in multiples of kPointerSize.
205 int frame_size = bytecode_array->frame_size();
206 DCHECK(frame_size % kPointerSize == 0); 279 DCHECK(frame_size % kPointerSize == 0);
207 if (frame_size > kPointerSize) { 280 if (frame_size > kPointerSize) {
208 stream << ' ' << frame_size / kPointerSize << " * kPointerSize,\n" 281 stream << ' ' << frame_size / kPointerSize << " * kPointerSize,\n"
209 << kIndent; 282 << kIndent;
210 } else if (frame_size == kPointerSize) { 283 } else if (frame_size == kPointerSize) {
211 stream << " kPointerSize,\n" << kIndent; 284 stream << " kPointerSize,\n" << kIndent;
212 } else if (frame_size == 0) { 285 } else if (frame_size == 0) {
213 stream << " 0,\n" << kIndent; 286 stream << " 0,\n" << kIndent;
214 } 287 }
288 }
289
290 void PrintBytecodeArray(std::ostream& stream,
291 i::Handle<i::BytecodeArray> bytecode_array,
292 const std::string& body, v8::Isolate* isolate,
293 ConstantPoolType constant_pool_type,
294 bool print_banner = true) {
295 if (print_banner) {
296 stream << kIndent << "// === ExpectedSnippet generated by "
297 "generate-bytecode-expectations. ===\n";
298 }
299
300 // Print the code snippet as a quoted C string.
301 stream << kIndent << "{" << '"' << QuoteCString(body) << "\",\n" << kIndent;
302
303 PrintFrameSize(stream, bytecode_array->frame_size());
215 304
216 // Print parameter count and size of the bytecode array. 305 // Print parameter count and size of the bytecode array.
217 stream << ' ' << bytecode_array->parameter_count() << ",\n" 306 stream << ' ' << bytecode_array->parameter_count() << ",\n"
218 << kIndent << ' ' << bytecode_array->length() << ",\n" 307 << kIndent << ' ' << bytecode_array->length() << ",\n"
rmcilroy 2016/02/10 15:20:32 move printing of parameter_count into PrintFrameSi
Stefano Sanfilippo 2016/02/10 15:40:15 Done.
219 << kIndent << " {\n" 308 << kIndent << " {\n"
220 << kIndent << " "; 309 << kIndent << " ";
221 310
222 // Print bytecodes. 311 PrintBytecodeSequence(stream, bytecode_array);
223 BytecodeArrayIterator bytecode_iter{bytecode_array}; 312
224 for (; !bytecode_iter.done(); bytecode_iter.Advance()) { 313 PrintConstantPool(stream, bytecode_array->constant_pool(), constant_pool_type,
225 // Print separator before each instruction, except the first one. 314 isolate);
226 if (bytecode_iter.current_offset() > 0) { 315
227 stream << ",\n" << kIndent << " "; 316 // TODO(ssanfilippo) print handlers.
228 } 317 //
229 PrintBytecode(stream, bytecode_iter); 318 // Remember that if we have handlers but not constants, we still need
319 // to emit " 0, {},\n" before the following section.
320 //
321 // For now we leave here a check.
322 //
rmcilroy 2016/02/10 15:20:32 nit - remove the comment (other than the TODO) giv
Stefano Sanfilippo 2016/02/10 15:40:15 Done.
323 i::HandlerTable* handlers =
324 i::HandlerTable::cast(bytecode_array->handler_table());
325 CHECK_EQ(handlers->NumberOfRangeEntries(), 0);
326
327 stream << kIndent << "}\n";
328 }
329
330 void PrintExpectedSnippet(ConstantPoolType parsed_constant_pool_type,
rmcilroy 2016/02/10 15:20:32 /s/parsed_constant_pool_type/constant_pool_type/
Stefano Sanfilippo 2016/02/10 15:40:15 Done.
331 char* exec_path, std::string body) {
332 const char* wrapper_function_name = "__genbckexp_wrapper__";
333
334 V8InitializationScope platform(exec_path);
335 {
336 v8::Isolate::Scope isolate_scope(platform.isolate());
337 v8::HandleScope handle_scope(platform.isolate());
338 v8::Local<v8::Context> context = v8::Context::New(platform.isolate());
339 v8::Context::Scope context_scope(context);
340
341 std::string source_code = WrapCodeInFunction(wrapper_function_name, body);
342 CompileAndRun(platform.isolate(), context, source_code.c_str());
343
344 i::Handle<i::BytecodeArray> bytecode_array = GetBytecodeArrayForGlobal(
345 platform.isolate(), context, wrapper_function_name);
346
347 PrintBytecodeArray(std::cout, bytecode_array, body, platform.isolate(),
348 parsed_constant_pool_type);
230 } 349 }
231
232 stream << "\n" << kIndent << " },\n";
233 // TODO(ssanfilippo) add representation of constant pool and handlers.
234 stream << kIndent << " // constant pool and handlers here\n";
235 stream << kIndent << "}\n";
236 } 350 }
237 351
238 bool ReadFromFileOrStdin(std::string* body, const char* body_filename) { 352 bool ReadFromFileOrStdin(std::string* body, const char* body_filename) {
239 std::stringstream body_buffer; 353 std::stringstream body_buffer;
240 if (strcmp(body_filename, "-") == 0) { 354 if (strcmp(body_filename, "-") == 0) {
241 body_buffer << std::cin.rdbuf(); 355 body_buffer << std::cin.rdbuf();
242 } else { 356 } else {
243 std::ifstream body_file{body_filename}; 357 std::ifstream body_file{body_filename};
244 if (!body_file) return false; 358 if (!body_file) return false;
245 body_buffer << body_file.rdbuf(); 359 body_buffer << body_file.rdbuf();
246 } 360 }
247 *body = body_buffer.str(); 361 *body = body_buffer.str();
248 return true; 362 return true;
249 } 363 }
250 364
365 ConstantPoolType ParseConstantPoolType(const char* type_string) {
366 if (strcmp(type_string, "int") == 0) {
367 return kConstantPoolTypeInteger;
368 } else if (strcmp(type_string, "double") == 0) {
369 return kConstantPoolTypeDouble;
370 } else if (strcmp(type_string, "string") == 0) {
371 return kConstantPoolTypeString;
372 } else if (strcmp(type_string, "mixed") == 0) {
373 return kConstantPoolTypeMixed;
374 }
375 return kConstantPoolTypeUnknown;
376 }
377
251 void PrintUsage(const char* exec_path) { 378 void PrintUsage(const char* exec_path) {
252 std::cerr << "Usage: " << exec_path 379 std::cerr << "Usage: " << exec_path
253 << " [filename.js|-]\n\n" 380 << " (int|double|string|mixed) [filename.js|-]\n\n"
254 "No arguments or - reads from standard input.\n" 381 "First argument is the type of objects in the constant pool.\n\n"
382 "Omitting the second argument or - reads from standard input.\n"
255 "Anything else is interpreted as a filename.\n\n" 383 "Anything else is interpreted as a filename.\n\n"
256 "This tool is intended as a help in writing tests.\n" 384 "This tool is intended as a help in writing tests.\n"
257 "Please, DO NOT blindly copy and paste the output " 385 "Please, DO NOT blindly copy and paste the output "
258 "into the test suite.\n"; 386 "into the test suite.\n";
259 } 387 }
260 388
261 } // namespace 389 } // namespace
262 390
263 int main(int argc, char** argv) { 391 int main(int argc, char** argv) {
392 if (argc < 2) {
393 PrintUsage(argv[0]);
394 return 1;
395 }
396
264 if (argc > 1 && strcmp(argv[1], "--help") == 0) { 397 if (argc > 1 && strcmp(argv[1], "--help") == 0) {
265 PrintUsage(argv[0]); 398 PrintUsage(argv[0]);
266 return 0; 399 return 0;
267 } 400 }
268 401
269 const char* body_filename = (argc > 1 ? argv[1] : "-"); 402 const char* body_filename = (argc > 2 ? argv[2] : "-");
270 const char* wrapper_function_name = "__genbckexp_wrapper__"; 403 const char* const_pool_type_string = argv[1];
271 404
272 std::string body; 405 std::string body;
273 if (!ReadFromFileOrStdin(&body, body_filename)) { 406 if (!ReadFromFileOrStdin(&body, body_filename)) {
274 std::cerr << "Could not open '" << body_filename << "'.\n\n"; 407 std::cerr << "Could not open '" << body_filename << "'.\n\n";
275 PrintUsage(argv[0]); 408 PrintUsage(argv[0]);
276 return 1; 409 return 1;
277 } 410 }
278 411
279 V8InitializationScope platform(argv[0]); 412 PrintExpectedSnippet(ParseConstantPoolType(const_pool_type_string), argv[0],
280 { 413 body);
281 v8::Isolate::Scope isolate_scope(platform.isolate());
282 v8::HandleScope handle_scope(platform.isolate());
283 v8::Local<v8::Context> context = v8::Context::New(platform.isolate());
284 v8::Context::Scope context_scope(context);
285
286 std::string source_code = WrapCodeInFunction(wrapper_function_name, body);
287 CompileAndRun(platform.isolate(), context, source_code.c_str());
288
289 i::Handle<i::BytecodeArray> bytecode_array = GetBytecodeArrayForGlobal(
290 platform.isolate(), context, wrapper_function_name);
291
292 PrintBytecodeArray(std::cout, bytecode_array, body);
293 }
294 } 414 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698