| 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 |