Profile.hx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package hl;
  2. typedef Symbol = hl.Abstract<"hl_symbol">;
  3. class Allocation {
  4. public var t : hl.Type;
  5. public var count : Int;
  6. public var size : Int;
  7. public var stack : Array<String>;
  8. public function new(t, count, size) {
  9. this.t = t;
  10. this.count = count;
  11. this.size = size;
  12. }
  13. @:keep public function toString() {
  14. return t + "(" + count + ")";
  15. }
  16. }
  17. @:hlNative("std")
  18. class Profile {
  19. /**
  20. Enable allocation tracking per thread. All threads are enabled by default.
  21. **/
  22. public static var enable(get, set) : Bool;
  23. public static function getData( sortBySize = false ) {
  24. var old = enable;
  25. enable = false;
  26. track_lock(true);
  27. var maxDepth = 0;
  28. var count = track_count(maxDepth);
  29. var arr = new hl.NativeArray<Symbol>(maxDepth);
  30. var out = [];
  31. for( i in 0...count ) {
  32. var t : hl.Type = null, count = 0, size = 0;
  33. track_entry(i, t, count, size, arr);
  34. if( count == 0 ) continue;
  35. var a = new Allocation(t, count, size);
  36. a.stack = [for( a in arr ) resolveSymbol(a)];
  37. out.push(a);
  38. }
  39. if( sortBySize )
  40. out.sort(function(a1, a2) return a2.size - a1.size);
  41. else
  42. out.sort(function(a1, a2) return a2.count - a1.count);
  43. track_lock(false);
  44. enable = old;
  45. return out;
  46. }
  47. public static function dump( fileName = "alloc.dump", sortBySize = false ) {
  48. var old = enable;
  49. enable = false;
  50. var f = sys.io.File.write(fileName);
  51. var data = getData(sortBySize);
  52. var count = 0, size = 0;
  53. for( o in data ) {
  54. count += o.count;
  55. size += o.size;
  56. }
  57. f.writeString(count +" total allocs (" + size+" bytes)\n");
  58. for( o in data ) {
  59. f.writeString(o.count+" "+o.t + " (" + o.size + " bytes)\n");
  60. for( s in o.stack )
  61. f.writeString("\t" + s + "\n");
  62. }
  63. f.close();
  64. enable = old;
  65. }
  66. /**
  67. Reset accumulated tracked data.
  68. **/
  69. @:hlNative("std","track_reset") public static function reset() {
  70. }
  71. /**
  72. Start tracking. Enabled by default.
  73. **/
  74. @:hlNative("std","track_init") public static function start() {
  75. }
  76. /**
  77. Stop tracking for all threads.
  78. **/
  79. @:hlNative("std","track_stop") public static function stop() {
  80. }
  81. static var BUFSIZE = 512;
  82. static var buf = new hl.Bytes(BUFSIZE*2);
  83. static function resolveSymbol( s : Symbol ) {
  84. var size = BUFSIZE;
  85. var bytes = resolve_symbol(s, buf, size);
  86. if( bytes == null ) return "<???>";
  87. return @:privateAccess String.fromUCS2(bytes.sub(0,(size+1)*2));
  88. }
  89. static function get_enable() return track_enabled();
  90. static function set_enable(v) {
  91. track_enable(v);
  92. return v;
  93. }
  94. static function resolve_symbol( s : Symbol, buf : hl.Bytes, bufSize : hl.Ref<Int> ) : hl.Bytes { return null; }
  95. static function track_count( maxDepth : hl.Ref<Int> ) : Int { return 0; }
  96. static function track_entry( id : Int, type : hl.Ref<hl.Type>, count : hl.Ref<Int>, size : hl.Ref<Int>, stack : NativeArray<Symbol> ) : Void {}
  97. static function track_enable(b:Bool) : Void {}
  98. static function track_lock(b:Bool) : Void {}
  99. static function track_enabled() : Bool { return false; }
  100. static function __init__() { start(); track_enable(true); }
  101. }