OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library dart2js.ir_tracer; | 5 library dart2js.ir_tracer; |
6 | 6 |
7 import 'dart:async' show EventSink; | 7 import 'dart:async' show EventSink; |
8 import 'cps_ir_nodes.dart' as cps_ir; | 8 import 'cps_ir_nodes.dart' as cps_ir; |
9 import '../tracer.dart'; | 9 import '../tracer.dart'; |
10 | 10 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 unexpectedNode(node); | 45 unexpectedNode(node); |
46 } | 46 } |
47 | 47 |
48 // Bodies and initializers are not visited. They contain continuations which | 48 // Bodies and initializers are not visited. They contain continuations which |
49 // are found by a BlockCollector, then those continuations are processed by | 49 // are found by a BlockCollector, then those continuations are processed by |
50 // this visitor. | 50 // this visitor. |
51 unexpectedNode(cps_ir.Node node) { | 51 unexpectedNode(cps_ir.Node node) { |
52 throw 'The IR tracer reached an unexpected IR instruction: $node'; | 52 throw 'The IR tracer reached an unexpected IR instruction: $node'; |
53 } | 53 } |
54 | 54 |
55 | |
56 int countUses(cps_ir.Definition definition) { | 55 int countUses(cps_ir.Definition definition) { |
57 int count = 0; | 56 int count = 0; |
58 cps_ir.Reference ref = definition.firstRef; | 57 cps_ir.Reference ref = definition.firstRef; |
59 while (ref != null) { | 58 while (ref != null) { |
60 ++count; | 59 ++count; |
61 ref = ref.next; | 60 ref = ref.next; |
62 } | 61 } |
63 return count; | 62 return count; |
64 } | 63 } |
65 | 64 |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
300 | 299 |
301 visitCreateInstance(cps_ir.CreateInstance node) { | 300 visitCreateInstance(cps_ir.CreateInstance node) { |
302 String className = node.classElement.name; | 301 String className = node.classElement.name; |
303 String arguments = node.argumentRefs.map(formatReference).join(', '); | 302 String arguments = node.argumentRefs.map(formatReference).join(', '); |
304 String typeInformation = formatReference(node.typeInformationRef); | 303 String typeInformation = formatReference(node.typeInformationRef); |
305 return 'CreateInstance $className ($arguments) <$typeInformation>'; | 304 return 'CreateInstance $className ($arguments) <$typeInformation>'; |
306 } | 305 } |
307 | 306 |
308 visitInterceptor(cps_ir.Interceptor node) { | 307 visitInterceptor(cps_ir.Interceptor node) { |
309 return 'Interceptor(${formatReference(node.inputRef)}, ' | 308 return 'Interceptor(${formatReference(node.inputRef)}, ' |
310 '${node.interceptedClasses})'; | 309 '${node.interceptedClasses})'; |
311 } | 310 } |
312 | 311 |
313 visitGetMutable(cps_ir.GetMutable node) { | 312 visitGetMutable(cps_ir.GetMutable node) { |
314 String variable = names.name(node.variable); | 313 String variable = names.name(node.variable); |
315 return 'GetMutable $variable'; | 314 return 'GetMutable $variable'; |
316 } | 315 } |
317 | 316 |
318 visitReadTypeVariable(cps_ir.ReadTypeVariable node) { | 317 visitReadTypeVariable(cps_ir.ReadTypeVariable node) { |
319 return "ReadTypeVariable ${node.variable.element} " | 318 return "ReadTypeVariable ${node.variable.element} " |
320 "${formatReference(node.targetRef)}"; | 319 "${formatReference(node.targetRef)}"; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) { | 353 visitApplyBuiltinMethod(cps_ir.ApplyBuiltinMethod node) { |
355 String method = node.method.toString(); | 354 String method = node.method.toString(); |
356 String receiver = formatReference(node.receiverRef); | 355 String receiver = formatReference(node.receiverRef); |
357 String args = node.argumentRefs.map(formatReference).join(', '); | 356 String args = node.argumentRefs.map(formatReference).join(', '); |
358 return 'ApplyBuiltinMethod $method $receiver ($args)'; | 357 return 'ApplyBuiltinMethod $method $receiver ($args)'; |
359 } | 358 } |
360 | 359 |
361 visitForeignCode(cps_ir.ForeignCode node) { | 360 visitForeignCode(cps_ir.ForeignCode node) { |
362 String id = names.name(node); | 361 String id = names.name(node); |
363 String arguments = node.argumentRefs.map(formatReference).join(', '); | 362 String arguments = node.argumentRefs.map(formatReference).join(', '); |
364 printStmt(id, | 363 printStmt( |
365 "ForeignCode ${node.type} ${node.codeTemplate.source} $arguments"); | 364 id, "ForeignCode ${node.type} ${node.codeTemplate.source} $arguments"); |
366 } | 365 } |
367 | 366 |
368 visitGetLength(cps_ir.GetLength node) { | 367 visitGetLength(cps_ir.GetLength node) { |
369 String object = formatReference(node.objectRef); | 368 String object = formatReference(node.objectRef); |
370 String finalFlag = node.isFinal ? 'final' : 'non-final'; | 369 String finalFlag = node.isFinal ? 'final' : 'non-final'; |
371 return 'GetLength $object $finalFlag'; | 370 return 'GetLength $object $finalFlag'; |
372 } | 371 } |
373 | 372 |
374 visitGetIndex(cps_ir.GetIndex node) { | 373 visitGetIndex(cps_ir.GetIndex node) { |
375 String object = formatReference(node.objectRef); | 374 String object = formatReference(node.objectRef); |
376 String index = formatReference(node.indexRef); | 375 String index = formatReference(node.indexRef); |
377 return 'GetIndex $object $index'; | 376 return 'GetIndex $object $index'; |
378 } | 377 } |
379 | 378 |
380 visitSetIndex(cps_ir.SetIndex node) { | 379 visitSetIndex(cps_ir.SetIndex node) { |
381 String object = formatReference(node.objectRef); | 380 String object = formatReference(node.objectRef); |
382 String index = formatReference(node.indexRef); | 381 String index = formatReference(node.indexRef); |
383 String value = formatReference(node.valueRef); | 382 String value = formatReference(node.valueRef); |
384 return 'SetIndex $object $index $value'; | 383 return 'SetIndex $object $index $value'; |
385 } | 384 } |
386 | 385 |
387 visitRefinement(cps_ir.Refinement node) { | 386 visitRefinement(cps_ir.Refinement node) { |
388 String value = formatReference(node.value); | 387 String value = formatReference(node.value); |
389 return 'Refinement $value ${node.refineType}'; | 388 return 'Refinement $value ${node.refineType}'; |
390 } | 389 } |
391 | 390 |
392 visitBoundsCheck(cps_ir.BoundsCheck node) { | 391 visitBoundsCheck(cps_ir.BoundsCheck node) { |
393 String object = formatReference(node.objectRef); | 392 String object = formatReference(node.objectRef); |
394 String index = node.indexRef == null | 393 String index = |
395 ? 'no-index' | 394 node.indexRef == null ? 'no-index' : formatReference(node.indexRef); |
396 : formatReference(node.indexRef); | 395 String length = |
397 String length = node.lengthRef == null | 396 node.lengthRef == null ? 'no-length' : formatReference(node.lengthRef); |
398 ? 'no-length' | |
399 : formatReference(node.lengthRef); | |
400 return 'BoundsCheck $object $index $length ${node.checkString}'; | 397 return 'BoundsCheck $object $index $length ${node.checkString}'; |
401 } | 398 } |
402 | 399 |
403 visitReceiverCheck(cps_ir.ReceiverCheck node) { | 400 visitReceiverCheck(cps_ir.ReceiverCheck node) { |
404 String value = formatReference(node.valueRef); | 401 String value = formatReference(node.valueRef); |
405 String condition = formatReference(node.conditionRef); | 402 String condition = formatReference(node.conditionRef); |
406 return 'ReceiverCheck $value $condition ${node.selector} ' | 403 return 'ReceiverCheck $value $condition ${node.selector} ' |
407 '${node.flagString}'; | 404 '${node.flagString}'; |
408 } | 405 } |
409 } | 406 } |
410 | 407 |
411 /** | 408 /** |
412 * Invents (and remembers) names for Continuations, Parameters, etc. | 409 * Invents (and remembers) names for Continuations, Parameters, etc. |
413 * The names must match the conventions used by IR Hydra, e.g. | 410 * The names must match the conventions used by IR Hydra, e.g. |
414 * Continuations and Functions must have names of form B### since they | 411 * Continuations and Functions must have names of form B### since they |
415 * are visualized as basic blocks. | 412 * are visualized as basic blocks. |
416 */ | 413 */ |
417 class Names { | 414 class Names { |
418 final Map<Object, String> names = {}; | 415 final Map<Object, String> names = {}; |
419 final Map<String, int> counters = { | 416 final Map<String, int> counters = {'r': 0, 'B': 0, 'v': 0, 'x': 0, 'c': 0}; |
420 'r': 0, | |
421 'B': 0, | |
422 'v': 0, | |
423 'x': 0, | |
424 'c': 0 | |
425 }; | |
426 | 417 |
427 String prefix(x) { | 418 String prefix(x) { |
428 if (x is cps_ir.Parameter) return 'r'; | 419 if (x is cps_ir.Parameter) return 'r'; |
429 if (x is cps_ir.Continuation || x is cps_ir.FunctionDefinition) return 'B'; | 420 if (x is cps_ir.Continuation || x is cps_ir.FunctionDefinition) return 'B'; |
430 if (x is cps_ir.Primitive) return 'v'; | 421 if (x is cps_ir.Primitive) return 'v'; |
431 if (x is cps_ir.MutableVariable) return 'c'; | 422 if (x is cps_ir.MutableVariable) return 'c'; |
432 return 'x'; | 423 return 'x'; |
433 } | 424 } |
434 | 425 |
435 String name(x) { | 426 String name(x) { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
525 } | 516 } |
526 | 517 |
527 visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { | 518 visitInvokeMethodDirectly(cps_ir.InvokeMethodDirectly node) { |
528 unexpectedNode(node); | 519 unexpectedNode(node); |
529 } | 520 } |
530 | 521 |
531 visitInvokeConstructor(cps_ir.InvokeConstructor node) { | 522 visitInvokeConstructor(cps_ir.InvokeConstructor node) { |
532 unexpectedNode(node); | 523 unexpectedNode(node); |
533 } | 524 } |
534 | 525 |
535 visitThrow(cps_ir.Throw exp) { | 526 visitThrow(cps_ir.Throw exp) {} |
536 } | |
537 | 527 |
538 visitRethrow(cps_ir.Rethrow exp) { | 528 visitRethrow(cps_ir.Rethrow exp) {} |
539 } | |
540 | 529 |
541 visitUnreachable(cps_ir.Unreachable node) { | 530 visitUnreachable(cps_ir.Unreachable node) {} |
542 } | |
543 | 531 |
544 visitGetLazyStatic(cps_ir.GetLazyStatic node) { | 532 visitGetLazyStatic(cps_ir.GetLazyStatic node) { |
545 unexpectedNode(node); | 533 unexpectedNode(node); |
546 } | 534 } |
547 | 535 |
548 visitBranch(cps_ir.Branch exp) { | 536 visitBranch(cps_ir.Branch exp) { |
549 cps_ir.Continuation trueTarget = exp.trueContinuation; | 537 cps_ir.Continuation trueTarget = exp.trueContinuation; |
550 if (!trueTarget.isReturnContinuation) { | 538 if (!trueTarget.isReturnContinuation) { |
551 currentBlock.addEdgeTo(getBlock(trueTarget)); | 539 currentBlock.addEdgeTo(getBlock(trueTarget)); |
552 } | 540 } |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 } | 674 } |
687 | 675 |
688 visitBoundsCheck(cps_ir.BoundsCheck node) { | 676 visitBoundsCheck(cps_ir.BoundsCheck node) { |
689 unexpectedNode(node); | 677 unexpectedNode(node); |
690 } | 678 } |
691 | 679 |
692 visitReceiverCheck(cps_ir.ReceiverCheck node) { | 680 visitReceiverCheck(cps_ir.ReceiverCheck node) { |
693 unexpectedNode(node); | 681 unexpectedNode(node); |
694 } | 682 } |
695 } | 683 } |
OLD | NEW |