| OLD | NEW |
| 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dartino 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 library fletchc.program_info; | 5 library dartino_compiler.program_info; |
| 6 | 6 |
| 7 import 'dart:async' show | 7 import 'dart:async' show |
| 8 Future, | 8 Future, |
| 9 Stream, | 9 Stream, |
| 10 StreamSink; | 10 StreamSink; |
| 11 | 11 |
| 12 import 'dart:io' as io; | 12 import 'dart:io' as io; |
| 13 | 13 |
| 14 import 'dart:io' show | 14 import 'dart:io' show |
| 15 BytesBuilder; | 15 BytesBuilder; |
| 16 | 16 |
| 17 import 'dart:convert' show | 17 import 'dart:convert' show |
| 18 JSON, | 18 JSON, |
| 19 LineSplitter, | 19 LineSplitter, |
| 20 UTF8; | 20 UTF8; |
| 21 | 21 |
| 22 import 'dart:typed_data' show | 22 import 'dart:typed_data' show |
| 23 Int32List, | 23 Int32List, |
| 24 Uint8List, | 24 Uint8List, |
| 25 ByteData, | 25 ByteData, |
| 26 Endianness; | 26 Endianness; |
| 27 | 27 |
| 28 import 'package:persistent/persistent.dart' show | 28 import 'package:persistent/persistent.dart' show |
| 29 Pair; | 29 Pair; |
| 30 | 30 |
| 31 import 'vm_commands.dart' show | 31 import 'vm_commands.dart' show |
| 32 WriteSnapshotResult; | 32 WriteSnapshotResult; |
| 33 | 33 |
| 34 import 'fletch_system.dart' show | 34 import 'dartino_system.dart' show |
| 35 FletchClass, | 35 DartinoClass, |
| 36 FletchFunction, | 36 DartinoFunction, |
| 37 FletchSystem; | 37 DartinoSystem; |
| 38 | 38 |
| 39 import 'src/fletch_selector.dart' show | 39 import 'src/dartino_selector.dart' show |
| 40 FletchSelector; | 40 DartinoSelector; |
| 41 | 41 |
| 42 enum Configuration { | 42 enum Configuration { |
| 43 Offset64BitsDouble, | 43 Offset64BitsDouble, |
| 44 Offset64BitsFloat, | 44 Offset64BitsFloat, |
| 45 Offset32BitsDouble, | 45 Offset32BitsDouble, |
| 46 Offset32BitsFloat, | 46 Offset32BitsFloat, |
| 47 } | 47 } |
| 48 | 48 |
| 49 class ProgramInfo { | 49 class ProgramInfo { |
| 50 final List<String> _strings; | 50 final List<String> _strings; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 70 } | 70 } |
| 71 | 71 |
| 72 String functionName(Configuration conf, int functionOffset) { | 72 String functionName(Configuration conf, int functionOffset) { |
| 73 return _getString(_functionNames[conf][functionOffset]); | 73 return _getString(_functionNames[conf][functionOffset]); |
| 74 } | 74 } |
| 75 | 75 |
| 76 String className(Configuration conf, int classOffset) { | 76 String className(Configuration conf, int classOffset) { |
| 77 return _getString(_classNames[conf][classOffset]); | 77 return _getString(_classNames[conf][classOffset]); |
| 78 } | 78 } |
| 79 | 79 |
| 80 String selectorName(FletchSelector selector) { | 80 String selectorName(DartinoSelector selector) { |
| 81 return _getString(_selectorNames[selector.id]); | 81 return _getString(_selectorNames[selector.id]); |
| 82 } | 82 } |
| 83 | 83 |
| 84 String _getString(int stringId) { | 84 String _getString(int stringId) { |
| 85 String name = null; | 85 String name = null; |
| 86 if (stringId != null && stringId != -1) { | 86 if (stringId != null && stringId != -1) { |
| 87 name = _strings[stringId]; | 87 name = _strings[stringId]; |
| 88 if (name == '') name = null; | 88 if (name == '') name = null; |
| 89 } | 89 } |
| 90 return name; | 90 return name; |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 | 427 |
| 428 return new ProgramInfo( | 428 return new ProgramInfo( |
| 429 strings, | 429 strings, |
| 430 selectorTable, | 430 selectorTable, |
| 431 classNames, | 431 classNames, |
| 432 functionNames, | 432 functionNames, |
| 433 0); // hashtag for shapshot is not supported for binary format. | 433 0); // hashtag for shapshot is not supported for binary format. |
| 434 } | 434 } |
| 435 } | 435 } |
| 436 | 436 |
| 437 ProgramInfo buildProgramInfo(FletchSystem system, WriteSnapshotResult result) { | 437 ProgramInfo buildProgramInfo(DartinoSystem system, WriteSnapshotResult result) { |
| 438 List<String> strings = []; | 438 List<String> strings = []; |
| 439 Map<String, int> stringIndices = {}; | 439 Map<String, int> stringIndices = {}; |
| 440 List<int> selectors = []; | 440 List<int> selectors = []; |
| 441 | 441 |
| 442 int newName(String name) { | 442 int newName(String name) { |
| 443 if (name == null) return -1; | 443 if (name == null) return -1; |
| 444 | 444 |
| 445 var index = stringIndices[name]; | 445 var index = stringIndices[name]; |
| 446 if (index == null) { | 446 if (index == null) { |
| 447 index = strings.length; | 447 index = strings.length; |
| 448 strings.add(name); | 448 strings.add(name); |
| 449 stringIndices[name] = index; | 449 stringIndices[name] = index; |
| 450 } | 450 } |
| 451 return index; | 451 return index; |
| 452 } | 452 } |
| 453 | 453 |
| 454 void setIndex(List<int> list, int index, value) { | 454 void setIndex(List<int> list, int index, value) { |
| 455 while (list.length <= index) { | 455 while (list.length <= index) { |
| 456 list.add(-1); | 456 list.add(-1); |
| 457 } | 457 } |
| 458 list[index] = value; | 458 list[index] = value; |
| 459 } | 459 } |
| 460 | 460 |
| 461 system.symbolByFletchSelectorId.forEach((Pair<int, String> pair) { | 461 system.symbolByDartinoSelectorId.forEach((Pair<int, String> pair) { |
| 462 setIndex(selectors, pair.fst, newName(pair.snd)); | 462 setIndex(selectors, pair.fst, newName(pair.snd)); |
| 463 }); | 463 }); |
| 464 | 464 |
| 465 Map<int, FletchClass> functionId2Class = {}; | 465 Map<int, DartinoClass> functionId2Class = {}; |
| 466 system.classesById.forEach((Pair<int, FletchClass> pair) { | 466 system.classesById.forEach((Pair<int, DartinoClass> pair) { |
| 467 FletchClass klass = pair.snd; | 467 DartinoClass klass = pair.snd; |
| 468 klass.methodTable.forEach((Pair<int, int> pair) { | 468 klass.methodTable.forEach((Pair<int, int> pair) { |
| 469 int functionId = pair.snd; | 469 int functionId = pair.snd; |
| 470 functionId2Class[functionId] = klass; | 470 functionId2Class[functionId] = klass; |
| 471 }); | 471 }); |
| 472 }); | 472 }); |
| 473 | 473 |
| 474 Map<Configuration, Map<int, int>> newTable() { | 474 Map<Configuration, Map<int, int>> newTable() { |
| 475 return <Configuration, Map<int, int>>{ | 475 return <Configuration, Map<int, int>>{ |
| 476 Configuration.Offset64BitsDouble : <int,int>{}, | 476 Configuration.Offset64BitsDouble : <int,int>{}, |
| 477 Configuration.Offset64BitsFloat : <int,int>{}, | 477 Configuration.Offset64BitsFloat : <int,int>{}, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 498 | 498 |
| 499 var functionNames = newTable(); | 499 var functionNames = newTable(); |
| 500 var classNames = newTable(); | 500 var classNames = newTable(); |
| 501 | 501 |
| 502 fillTable(functionNames, | 502 fillTable(functionNames, |
| 503 result.functionOffsetTable, | 503 result.functionOffsetTable, |
| 504 (id) => system.functionsById[id].name); | 504 (id) => system.functionsById[id].name); |
| 505 fillTable(classNames, | 505 fillTable(classNames, |
| 506 result.classOffsetTable, | 506 result.classOffsetTable, |
| 507 (id) { | 507 (id) { |
| 508 FletchClass klass = system.classesById[id]; | 508 DartinoClass klass = system.classesById[id]; |
| 509 if (klass == null) { | 509 if (klass == null) { |
| 510 // Why do we get here? | 510 // Why do we get here? |
| 511 return null; | 511 return null; |
| 512 } | 512 } |
| 513 return klass.name; | 513 return klass.name; |
| 514 }); | 514 }); |
| 515 fillTable(classNames, | 515 fillTable(classNames, |
| 516 result.functionOffsetTable, | 516 result.functionOffsetTable, |
| 517 (id) { | 517 (id) { |
| 518 FletchClass klass = functionId2Class[id]; | 518 DartinoClass klass = functionId2Class[id]; |
| 519 if (klass != null) return klass.name; | 519 if (klass != null) return klass.name; |
| 520 return null; | 520 return null; |
| 521 }); | 521 }); |
| 522 | 522 |
| 523 return new ProgramInfo(strings, selectors, classNames, | 523 return new ProgramInfo(strings, selectors, classNames, |
| 524 functionNames, result.hashtag); | 524 functionNames, result.hashtag); |
| 525 } | 525 } |
| 526 | 526 |
| 527 final RegExp _FrameRegexp = | 527 final RegExp _FrameRegexp = |
| 528 new RegExp(r'^Frame +([0-9]+): Function\(([0-9]+)\)$'); | 528 new RegExp(r'^Frame +([0-9]+): Function\(([0-9]+)\)$'); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 543 String className = info.classNameOfFunction(conf, functionOffset); | 543 String className = info.classNameOfFunction(conf, functionOffset); |
| 544 String functionName = info.functionName(conf, functionOffset); | 544 String functionName = info.functionName(conf, functionOffset); |
| 545 | 545 |
| 546 if (className == null) { | 546 if (className == null) { |
| 547 yield ' $frameNr: $functionName\n'; | 547 yield ' $frameNr: $functionName\n'; |
| 548 } else { | 548 } else { |
| 549 yield ' $frameNr: $className.$functionName\n'; | 549 yield ' $frameNr: $className.$functionName\n'; |
| 550 } | 550 } |
| 551 } else if (nsmMatch != null) { | 551 } else if (nsmMatch != null) { |
| 552 int classOffset = int.parse(nsmMatch.group(1)); | 552 int classOffset = int.parse(nsmMatch.group(1)); |
| 553 FletchSelector selector = | 553 DartinoSelector selector = |
| 554 new FletchSelector(int.parse(nsmMatch.group(2))); | 554 new DartinoSelector(int.parse(nsmMatch.group(2))); |
| 555 String functionName = info.selectorName(selector); | 555 String functionName = info.selectorName(selector); |
| 556 String className = info.className(conf, classOffset); | 556 String className = info.className(conf, classOffset); |
| 557 | 557 |
| 558 if (className != null && functionName != null) { | 558 if (className != null && functionName != null) { |
| 559 yield 'NoSuchMethodError: $className.$functionName\n'; | 559 yield 'NoSuchMethodError: $className.$functionName\n'; |
| 560 } else if (functionName != null) { | 560 } else if (functionName != null) { |
| 561 yield 'NoSuchMethodError: $functionName\n'; | 561 yield 'NoSuchMethodError: $functionName\n'; |
| 562 } else { | 562 } else { |
| 563 yield 'NoSuchMethodError: <unknown method>\n'; | 563 yield 'NoSuchMethodError: <unknown method>\n'; |
| 564 } | 564 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 input.transform(UTF8.decoder).transform(new LineSplitter()); | 623 input.transform(UTF8.decoder).transform(new LineSplitter()); |
| 624 | 624 |
| 625 Configuration conf = _getConfiguration(bits, floatOrDouble); | 625 Configuration conf = _getConfiguration(bits, floatOrDouble); |
| 626 Stream<String> decodedFrames = decodeStackFrames(conf, info, inputLines); | 626 Stream<String> decodedFrames = decodeStackFrames(conf, info, inputLines); |
| 627 await decodedFrames.transform(UTF8.encoder).pipe(output); | 627 await decodedFrames.transform(UTF8.encoder).pipe(output); |
| 628 | 628 |
| 629 return 0; | 629 return 0; |
| 630 } | 630 } |
| 631 | 631 |
| 632 | 632 |
| 633 // We are only interested in two kind of lines in the fletch.ticks file. | 633 // We are only interested in two kind of lines in the dartino.ticks file. |
| 634 final RegExp tickRegexp = | 634 final RegExp tickRegexp = |
| 635 new RegExp(r'^0x([0-9a-f]+),0x([0-9a-f]+),0x([0-9a-f]+)'); | 635 new RegExp(r'^0x([0-9a-f]+),0x([0-9a-f]+),0x([0-9a-f]+)'); |
| 636 final RegExp propertyRegexp = new RegExp(r'^(\w+)=(.*$)'); | 636 final RegExp propertyRegexp = new RegExp(r'^(\w+)=(.*$)'); |
| 637 | 637 |
| 638 // Tick contains information from a line matching tickRegexp. | 638 // Tick contains information from a line matching tickRegexp. |
| 639 class Tick { | 639 class Tick { |
| 640 final int pc; // The actual program counter where the tick occurred. | 640 final int pc; // The actual program counter where the tick occurred. |
| 641 final int bcp; // The bytecode pointer relative to program heap start. | 641 final int bcp; // The bytecode pointer relative to program heap start. |
| 642 final int hashtag; | 642 final int hashtag; |
| 643 Tick(this.pc, this.bcp,this.hashtag); | 643 Tick(this.pc, this.bcp,this.hashtag); |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 } | 751 } |
| 752 } | 752 } |
| 753 | 753 |
| 754 Future<Profile> decodeTickSamples( | 754 Future<Profile> decodeTickSamples( |
| 755 List<String> arguments, | 755 List<String> arguments, |
| 756 Stream<List<int>> input, | 756 Stream<List<int>> input, |
| 757 StreamSink<List<int>> output) async { | 757 StreamSink<List<int>> output) async { |
| 758 | 758 |
| 759 usage(message) { | 759 usage(message) { |
| 760 print("Invalid arguments: $message"); | 760 print("Invalid arguments: $message"); |
| 761 print("Usage: ${io.Platform.script} <fletch.ticks> <snapshot.info.json>"); | 761 print("Usage: ${io.Platform.script} <dartino.ticks> <snapshot.info.json>"); |
| 762 } | 762 } |
| 763 | 763 |
| 764 if (arguments.length != 2) { | 764 if (arguments.length != 2) { |
| 765 usage("Exactly 2 arguments must be supplied"); | 765 usage("Exactly 2 arguments must be supplied"); |
| 766 return null; | 766 return null; |
| 767 } | 767 } |
| 768 | 768 |
| 769 String sample_filename = arguments[0]; | 769 String sample_filename = arguments[0]; |
| 770 io.File sample_file = new io.File(sample_filename); | 770 io.File sample_file = new io.File(sample_filename); |
| 771 if (!await sample_file.exists()) { | 771 if (!await sample_file.exists()) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 Configuration _getConfiguration(bits, floatOrDouble) { | 867 Configuration _getConfiguration(bits, floatOrDouble) { |
| 868 if (bits == '64') { | 868 if (bits == '64') { |
| 869 if (floatOrDouble == 'float') return Configuration.Offset64BitsFloat; | 869 if (floatOrDouble == 'float') return Configuration.Offset64BitsFloat; |
| 870 else if (floatOrDouble == 'double') return Configuration.Offset64BitsDouble; | 870 else if (floatOrDouble == 'double') return Configuration.Offset64BitsDouble; |
| 871 } else if (bits == '32') { | 871 } else if (bits == '32') { |
| 872 if (floatOrDouble == 'float') return Configuration.Offset32BitsFloat; | 872 if (floatOrDouble == 'float') return Configuration.Offset32BitsFloat; |
| 873 else if (floatOrDouble == 'double') return Configuration.Offset32BitsDouble; | 873 else if (floatOrDouble == 'double') return Configuration.Offset32BitsDouble; |
| 874 } | 874 } |
| 875 throw 'Invalid arguments'; | 875 throw 'Invalid arguments'; |
| 876 } | 876 } |
| OLD | NEW |