Block.hx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. abstract Pointer(Int) {
  2. public inline function isNull() {
  3. return this == 0;
  4. }
  5. public inline function offset( i : Int ) : Pointer {
  6. return cast (this + i);
  7. }
  8. public inline function sub( p : Pointer ) : Int {
  9. return this - cast(p);
  10. }
  11. public inline function pageAddress() : Pointer {
  12. return cast (this & ~0xFFFF);
  13. }
  14. public inline function toString() {
  15. return "0x"+StringTools.hex(this, 8);
  16. }
  17. public inline function shift( k : Int ) : Int {
  18. return this >>> k;
  19. }
  20. }
  21. @:enum abstract PageKind(Int) {
  22. var PDynamic = 0;
  23. var PRaw = 1;
  24. var PNoPtr = 2;
  25. var PFinalizer = 3;
  26. }
  27. class Page {
  28. var memory : Memory;
  29. public var addr : Pointer;
  30. public var kind : PageKind;
  31. public var size : Int;
  32. public var blockSize : Int;
  33. public var firstBlock : Int;
  34. public var maxBlocks : Int;
  35. public var nextBlock : Int;
  36. public var dataPosition : Int;
  37. public var bmp : haxe.io.Bytes;
  38. public var sizes : haxe.io.Bytes;
  39. public function new(m) {
  40. memory = m;
  41. }
  42. public inline function memHasPtr() {
  43. return kind == PDynamic || kind == PRaw;
  44. }
  45. public function isLiveBlock( bid : Int ) {
  46. if( sizes != null && sizes.get(bid) == 0 ) return false;
  47. return (bmp.get(bid >> 3) & (1 << (bid & 7))) != 0;
  48. }
  49. public function getBlockSize( bid : Int ) {
  50. return sizes == null ? 1 : sizes.get(bid);
  51. }
  52. public function goto( bid : Int ) {
  53. memory.memoryDump.seek(dataPosition + bid * blockSize, SeekBegin);
  54. }
  55. public function getPointer( bid : Int ) {
  56. return addr.offset(bid * blockSize);
  57. }
  58. }
  59. class Stack {
  60. public var base : Pointer;
  61. public var contents : Array<Pointer>;
  62. public function new() {
  63. }
  64. }
  65. enum BlockTypeKind {
  66. KHeader;
  67. KRoot;
  68. KAbstractData;
  69. KDynObjData;
  70. KInferred( t : TType, k : BlockTypeKind );
  71. }
  72. class Block {
  73. public var page : Page;
  74. public var bid : Int;
  75. public var owner : Block;
  76. public var type(default, set) : TType;
  77. public var typeKind : BlockTypeKind;
  78. public var depth : Int = -1;
  79. public var subs : Array<Block>; // can be null
  80. public var parents : Array<Block>; // if multiple owners
  81. public function new() {
  82. }
  83. public inline function getPointer() {
  84. return page.getPointer(bid);
  85. }
  86. public inline function getMemSize() {
  87. return page.getBlockSize(bid) * page.blockSize;
  88. }
  89. function set_type( t : TType ) {
  90. if( t != null && t.t == HF64 && page.kind != PNoPtr )
  91. throw "!";
  92. return type = t;
  93. }
  94. public function addParent(b:Block) {
  95. if( owner == null ) {
  96. owner = b;
  97. } else {
  98. if( parents == null ) parents = [owner];
  99. parents.push(b);
  100. }
  101. if( b.subs == null ) b.subs = [];
  102. b.subs.push(this);
  103. }
  104. public function getParents() {
  105. return parents != null ? parents : owner == null ? [] : [owner];
  106. }
  107. public function markDepth() {
  108. var d = depth + 1;
  109. var all = subs;
  110. while( all.length > 0 ) {
  111. var out = [];
  112. for( b in all ) {
  113. if( b.depth < 0 || b.depth > d ) {
  114. b.depth = d;
  115. if( b.subs != null ) for( s in b.subs ) out.push(s);
  116. }
  117. }
  118. all = out;
  119. d++;
  120. }
  121. }
  122. public function finalize() {
  123. if( parents == null ) return;
  124. inline function getPriority(b:Block) {
  125. var d = -b.depth * 5;
  126. if( b.type == null ) return d-2;
  127. if( !b.type.hasPtr ) return d-1; // false positive
  128. return switch( b.type.t ) {
  129. case HFun(_): d;
  130. case HVirtual(_): d+1;
  131. default: d+2;
  132. }
  133. }
  134. parents.sort(function(p1, p2) return getPriority(p2) - getPriority(p1));
  135. owner = parents[0];
  136. }
  137. function removeParent( p : Block ) {
  138. if( parents != null ) {
  139. parents.remove(p);
  140. if( parents.length == 0 ) parents = null;
  141. }
  142. if( owner == p )
  143. owner = parents == null ? null : parents[0];
  144. }
  145. public function removeChildren() {
  146. if( subs != null ) {
  147. for( s in subs )
  148. s.removeParent(this);
  149. subs = null;
  150. }
  151. }
  152. }