Răsfoiți Sursa

Memory profiler: remove duplicated memory, block and type files

lviguier 1 an în urmă
părinte
comite
55b97c881a
5 a modificat fișierele cu 21 adăugiri și 1549 ștergeri
  1. 1 0
      common.hxml
  2. 0 208
      hide/tools/memory/Block.hx
  3. 0 1135
      hide/tools/memory/Memory.hx
  4. 0 188
      hide/tools/memory/TType.hx
  5. 20 18
      hide/view/Profiler.hx

+ 1 - 0
common.hxml

@@ -5,6 +5,7 @@
 -lib castle
 -lib hx3compat
 -lib domkit
+-lib hashlink
 -D js-classic
 -D js-unflatten
 -D hscriptPos

+ 0 - 208
hide/tools/memory/Block.hx

@@ -1,208 +0,0 @@
-package hide.tools.memory;
-
-abstract Pointer(haxe.Int64) {
-
-	public var value(get,never) : haxe.Int64;
-
-	inline function get_value() return this;
-
-	inline function new(v) this = v;
-
-	public inline function isNull() {
-		return this == 0;
-	}
-	public inline function offset( i : Int ) : Pointer {
-		return cast (this + i);
-	}
-	public inline function sub( p : Pointer ) : Int {
-		return haxe.Int64.toInt(this - p.value);
-	}
-	public inline function toString() {
-		return "0x"+(this.high == 0 ? StringTools.hex(this.high, 8) : "")+StringTools.hex(this.low,8);
-	}
-	public inline function shift( k : Int ) : haxe.Int64 {
-		return haxe.Int64.shr(this,k);
-	}
-
-	public static var NULL(get,never) : Pointer;
-	inline static function get_NULL() return new Pointer(0);
-
-}
-
-enum abstract PageKind(Int) {
-	var PDynamic = 0;
-	var PRaw = 1;
-	var PNoPtr = 2;
-	var PFinalizer = 3;
-}
-
-class Page {
-	public var addr : Pointer;
-	public var kind : PageKind;
-	public var size : Int;
-	public var reserved : Int;
-	public var dataPosition : Int = -1;
-
-	public function new() {
-	}
-
-	public inline function memHasPtr() {
-		return kind == PDynamic || kind == PRaw;
-	}
-
-}
-
-class Stack {
-	public var base : Pointer;
-	public var contents : Array<Pointer>;
-	public function new() {
-	}
-}
-
-enum BlockTypeKind {
-	KHeader;
-	KRoot;
-	KAbstractData;
-	KDynObjData;
-	KInferred( t : TType, k : BlockTypeKind );
-}
-
-class BlockSub {
-	public var b : Block;
-	public var fid : Int;
-	public function new(b,fid) {
-		this.b = b;
-		this.fid = fid;
-	}
-}
-
-class Block {
-	public static var MARK_UID = 0;
-
-	public var page : Page;
-	public var addr : Pointer;
-	public var size : Int;
-	public var typePtr : Pointer;
-	public var owner : Block;
-	public var type(default, set) : TType;
-	public var typeKind : BlockTypeKind;
-
-	public var depth : Int = -1;
-	public var mark : Int = -1;
-
-	public var subs : Array<BlockSub>; // can be null
-	public var parents : Array<Block>; // if multiple owners
-
-	public function new() {
-	}
-
-	inline function set_type( t : TType ) {
-		return type = t;
-	}
-
-	public function addParent(b:Block,fid:Int=0) {
-		if( owner == null ) {
-			owner = b;
-		} else {
-			if( parents == null ) parents = [owner];
-			parents.push(b);
-		}
-		if( b.subs == null ) b.subs = [];
-		b.subs.push(new BlockSub(this,fid));
-	}
-
-	public function makeTID( prev : Block, withField : Bool ) {
-		if( type == null )
-			return 0;
-		if( withField )
-			for( s in subs )
-				if( s.b == prev )
-					return type.tid | (s.fid << 24);
-		return type.tid;
-	}
-
-	public function getParents() {
-		return parents != null ? parents : owner == null ? [] : [owner];
-	}
-
-	public function markDepth() {
-		var d = depth + 1;
-		var all = subs;
-		if( all == null ) return;
-		while( all.length > 0 ) {
-			var out = [];
-			for( b in all ) {
-				var b = b.b;
-				if( b.depth < 0 || b.depth > d ) {
-					b.depth = d;
-					if( b.subs != null ) for( s in b.subs ) out.push(s);
-				}
-			}
-			all = out;
-			d++;
-		}
-	}
-
-	public function finalize() {
-		if( parents == null ) return;
-
-		inline function getPriority(b:Block) {
-			var d = -b.depth * 5;
-			if( b.type == null ) return d-2;
-			if( !b.type.hasPtr ) return d-1; // false positive
-			return switch( b.type.t ) {
-			case HFun(_): d;
-			case HVirtual(_): d+1;
-			default: d+2;
-			}
-		}
-
-		parents.sort(function(p1, p2) return getPriority(p2) - getPriority(p1));
-		owner = parents[0];
-	}
-
-	function removeParent( p : Block ) {
-		if( parents != null ) {
-			parents.remove(p);
-			if( parents.length == 0 ) parents = null;
-		}
-		if( owner == p )
-			owner = parents == null ? null : parents[0];
-	}
-
-	public function removeChildren() {
-		if( subs != null ) {
-			for( s in subs )
-				s.b.removeParent(this);
-			subs = null;
-		}
-	}
-
-}
-
-@:generic
-class PointerMap<T> {
-
-	var lookup : Map<Int,Map<Int,T>>;
-
-	public function new() {
-		lookup = new Map();
-	}
-
-	public function set( p : Pointer, v : T ) {
-		var c = lookup.get(p.value.high);
-		if( c == null ) {
-			c = new Map();
-			lookup.set(p.value.high, c);
-		}
-		c.set(p.value.low, v);
-	}
-
-	public function get( p : Pointer ) : T {
-		if( p.isNull() ) return null;
-		var c = lookup.get(p.value.high);
-		if( c == null ) return null;
-		return c.get(p.value.low);
-	}
-
-}

+ 0 - 1135
hide/tools/memory/Memory.hx

@@ -1,1135 +0,0 @@
-package hide.tools.memory;
-
-import format.hl.Data;
-using format.hl.Tools;
-import hide.tools.memory.Block;
-
-typedef TypeValue = { tl : Array<Int>, count : Int, mem : Int }
-
-class Stats {
-	var mem : Memory;
-	var byT = new Map();
-	var allT = [];
-
-	public function new(mem) {
-		this.mem = mem;
-	}
-
-	public function add( t : TType, mem : Int ) {
-		return addPath([t == null ? 0 : t.tid], mem);
-	}
-
-	public inline function makeID( t : TType, field : Int ) {
-		return t.tid | (field << 24);
-	}
-
-	public function addPath( tl : Array<Int>, mem : Int ) {
-		var key = tl.join(" ");
-		var inf = byT.get(key);
-		if( inf == null ) {
-			inf = { tl : tl, count : 0, mem : 0 };
-			byT.set(key, inf);
-			allT.push(inf);
-		}
-		inf.count++;
-		inf.mem += mem;
-	}
-
-	public function print( withSum = false ) {
-		sort( @:privateAccess mem.sortByCount );
-		var totCount = 0;
-		var totMem = 0;
-		var max = @:privateAccess mem.maxLines;
-		if( max > 0 && allT.length > max ) {
-			mem.log("<ignore "+(allT.length - max)+" lines>");
-			allT = allT.slice(allT.length - max);
-		}
-		for( i in allT ) {
-			totCount += i.count;
-			totMem += i.mem;
-			var tpath = getPathStrings(mem, i.tl);
-			mem.log(Memory.withColor(i.count + " count, " + Memory.MB(i.mem) + " ", 33) + tpath.join(${Memory.withColor(' > ', 36)}));
-		}
-		if( withSum )
-			mem.log("Total: "+totCount+" count, "+Memory.MB(totMem));
-	}
-
-	public static function getTypeString(mem : Memory, id : Int){
-		var t = mem.types[id & 0xFFFFFF];
-		var tstr = t.toString();
-		var fid = id >>> 24;
-		if( fid > 0 ) {
-			var f = t.memFieldsNames[fid-1];
-			if( f != null ) tstr += "." + f;
-		}
-		return tstr;
-	}
-
-	public static function getPathStrings(mem : Memory, i : Array<Int>){
-		var tpath = [];
-		for( tid in i )
-			tpath.push(getTypeString(mem, tid));
-
-		return tpath;
-	}
-
-	public function sort( byCount = true , asc = true) {
-		if( byCount )
-			allT.sort(function(i1, i2) return asc ? i1.count - i2.count : i2.count - i1.count);
-		else
-			allT.sort(function(i1, i2) return asc ? i1.mem - i2.mem : i2.mem - i1.mem);
-	}
-}
-
-
-enum FieldsMode {
-	Full;
-	Parents;
-	None;
-}
-
-enum FilterMode {
-	None;
-	Intersect;	// Will display only blocks present in all memories
-	Unique;		// Will display only blocks not present in other memories
-}
-
-class Memory {
-
-	public static var readIntCpt = 0;
-	public static var readPointerCpt = 0;
-	public var memoryDump : sys.io.FileInput;
-	public var memoryDumpBytes : haxe.io.Bytes;
-	public var pos : Int;
-
-	public var is64 : Bool;
-	public var bool32 : Bool;
-	public var ptrBits : Int;
-
-	public var types : Array<TType>;
-
-	var otherMems : Array<Memory>;
-	var filterMode: FilterMode = None;
-
-	var memFile : String;
-
-	var privateData : Int;
-	var markData : Int;
-
-	var sortByCount : Bool;
-	var displayFields : FieldsMode = Full;
-	var displayProgress = true;
-
-	var code : format.hl.Data;
-	var pages : Array<Page>;
-	var roots : Array<Pointer>;
-	var stacks : Array<Stack>;
-	var typesPointers : Array<Pointer>;
-	var closuresPointers : Array<Pointer>;
-	var blocks : Array<Block>;
-	var filteredBlocks : Array<Block> = [];
-	var baseTypes : Array<{ t : HLType, p : Pointer }>;
-	var all : Block;
-
-	var toProcess : Array<Block>;
-	var tdynObj : TType;
-	var tdynObjData : TType;
-	var pointerBlock : PointerMap<Block>;
-	var pointerType : PointerMap<TType>;
-	var falseCandidates : Array<{ b : Block, f : Block, idx : Int }>;
-
-	var currentTypeIndex = 0;
-	var resolveCache : Map<String,TType> = new Map();
-	var maxLines : Int = 100;
-
-	function new() {
-	}
-
-	public function typeSize( t : HLType ) {
-		return switch( t ) {
-		case HVoid: 0;
-		case HUi8: 1;
-		case HUi16: 2;
-		case HI32, HF32: 4;
-		case HI64, HF64: 8;
-		case HBool:
-			return bool32 ? 4 : 1;
-		case HPacked(_), HAt(_):
-			throw "assert";
-		default:
-			return is64 ? 8 : 4;
-		}
-	}
-
-	public function getType( t : HLType, isNull = false ) : TType {
-		// this is quite slow, but we can't use a Map, maybe try a more per-type specific approach ?
-		for( t2 in types )
-			if( t == t2.t )
-				return t2;
-		if( isNull )
-			return null;
-		throw "Type not found " + t.toString();
-		return null;
-	}
-
-	function loadBytecode( arg : String ) {
-		if( code != null ) throw "Duplicate code";
-		code = new format.hl.Reader(false).read(new haxe.io.BytesInput(sys.io.File.getBytes(arg)));
-		log(arg + " code loaded");
-	}
-
-	// function readInt() {
-	// 	return memoryDump.readInt32();
-	// }
-
-	// inline function readPointer() : Pointer {
-	// 	var low = memoryDump.readInt32();
-	// 	var high = is64 ? memoryDump.readInt32() : 0;
-	// 	return cast haxe.Int64.make(high,low);
-	// }
-
-	inline function readPointer() : Pointer {
-		readPointerCpt++;
-		var low = readInt();
-		readIntCpt--;
-		var high = 0;
-		if (is64) {
-			high = readInt();
-			readIntCpt--;
-		}
-		return cast haxe.Int64.make(high,low);
-	}
-
-	function readInt() {
-		readIntCpt++;
-		var ch1 = memoryDumpBytes.get(pos);
-		var ch2 = memoryDumpBytes.get(pos + 1);
-		var ch3 = memoryDumpBytes.get(pos + 2);
-		var ch4 = memoryDumpBytes.get(pos + 3);
-		pos += 4;
-		return memoryDump.bigEndian ? ch4 | (ch3 << 8) | (ch2 << 16) | (ch1 << 24) : ch1 | (ch2 << 8) | (ch3 << 16) | (ch4 << 24);
-	}
-
-	public static function MB( v : Float ) {
-		if( v < 1000 )
-			return Std.int(v) + "B";
-		if( v < 1024 * 1000 )
-			return (Math.round(v * 10 / 1024) / 10)+"KB";
-		return (Math.round(v * 10 / (1024 * 1024)) / 10)+"MB";
-	}
-
-	function loadMemory( arg : String ) {
-		memFile = arg;
-
-		memoryDump = sys.io.File.read(arg);
-		memoryDumpBytes = sys.io.File.getBytes(arg);
-
-		pos = 0;
-		if( memoryDumpBytes.getString(pos, 3) != "HMD" )
-			throw "Invalid memory dump file";
-		pos += 3;
-
-		var version = memoryDumpBytes.get(pos) - "0".code;
-		pos += 1;
-
-		if( version != 1 )
-			throw "Unsupported format version "+version;
-
-		var flags = readInt();
-		is64 = (flags & 1) != 0;
-		bool32 = (flags & 2) != 0;
-		ptrBits = is64 ? 3 : 2;
-		var ptrSize = 1 << ptrBits;
-
-		privateData = readInt();
-		markData = readInt();
-
-		// load pages
-		var count = readInt();
-		pages = [];
-		blocks = [];
-		for( i in 0...count ) {
-			var addr = readPointer();
-			var p = new Page();
-			p.addr = addr;
-			p.kind = cast readInt();
-			p.size = readInt();
-			p.reserved = readInt();
-
-			var readPtr = !p.memHasPtr();
-			while( true ) {
-				var ptr = readPointer();
-				if( ptr.isNull() ) break;
-				var size = readInt();
-				var b = new Block();
-				b.page = p;
-				b.addr = ptr;
-				b.size = size;
-				b.typePtr = @:privateAccess new hide.tools.memory.Pointer(0);
-				b.owner = null;
-				b.typeKind = null;
-				b.subs = null;
-				b.parents = null;
-				if( readPtr && size >= ptrSize ) b.typePtr = readPointer();
-				blocks.push(b);
-			}
-
-			if( p.memHasPtr() ) {
-				p.dataPosition = pos;
-				this.pos += p.size;
-			}
-
-			pages.push(p);
-		}
-
-		// load roots
-		roots = [for( i in 0...readInt() ) readPointer()];
-
-		// load stacks
-		stacks = [];
-		for( i in 0...readInt() ) {
-			var s = new Stack();
-			s.base = readPointer();
-			s.contents = [for( i in 0...readInt() ) readPointer()];
-			stacks.push(s);
-		}
-
-		// load types
-
-		baseTypes = [];
-		while( true ) {
-			var tid = readInt();
-			if( tid < 0 ) break;
-			var ptr = readPointer();
-			baseTypes.push({ t : Type.createEnumIndex(HLType, tid), p : ptr });
-		}
-
-		typesPointers = [for( i in 0...readInt() ) readPointer()];
-		closuresPointers = [for( i in 0...readInt() ) readPointer()];
-	}
-
-	public function getStats() {
-		var pagesSize = 0, reserved = 0;
-		var used = 0, gc = 0;
-		var fUsed = 0;
-		for( p in pages ) {
-			pagesSize += p.size;
-			reserved += p.reserved;
-		}
-		for( b in blocks )
-			used += b.size;
-		for (b in filteredBlocks)
-			fUsed += b.size;
-
-		var strings = [];
-		var string = "--- " + memFile + " ---\n";
-		string += pages.length + " pages, " + MB(pagesSize) + " memory\n";
-		string += roots.length + " roots, "+ stacks.length + " stacks\n";
-		string += code.types.length + " types, " + closuresPointers.length + " closures\n";
-		string += blocks.length + " live blocks " + MB(used) + " used, " + MB(pagesSize - used - reserved) + " free, "+MB(privateData + markData)+" gc\n";
-		if (filterMode != None)
-			string += filteredBlocks.length + " blocks in filter " + MB(fUsed) + " used\n";
-
-		strings.push(string);
-		for (m in otherMems??[]) strings = strings.concat(m.getStats());
-
-		return strings;
-	}
-
-	public function getStatsObj() {
-		var pagesSize = 0, reserved = 0;
-		var used = 0, gc = 0;
-		var fUsed = 0;
-		for( p in pages ) {
-			pagesSize += p.size;
-			reserved += p.reserved;
-		}
-		for( b in blocks )
-			used += b.size;
-		for (b in filteredBlocks)
-			fUsed += b.size;
-
-		var objs = [];
-		var obj = {
-			memFile : memFile,
-			free: pagesSize - used - reserved,
-			used: used,
-			totalAllocated: pagesSize - reserved,
-			gc : privateData + markData,
-			pagesCount : pages.length,
-			pagesSize : pagesSize,
-			rootsCount : roots.length,
-			stackCount : stacks.length,
-			typesCount : code.types.length,
-			closuresCount : closuresPointers.length,
-			blockCount : blocks.length
-		};
-
-		objs.push(obj);
-		for (m in otherMems??[]) objs = objs.concat(m.getStatsObj());
-
-		return objs;
-	}
-
-	function printStats() {
-		var pagesSize = 0, reserved = 0;
-		var used = 0, gc = 0;
-		var fUsed = 0;
-		for( p in pages ) {
-			pagesSize += p.size;
-			reserved += p.reserved;
-		}
-		for( b in blocks )
-			used += b.size;
-		for (b in filteredBlocks)
-			fUsed += b.size;
-		log(withColor("--- " + memFile + " ---", 36));
-		log(pages.length + " pages, " + MB(pagesSize) + " memory");
-		log(roots.length + " roots, "+ stacks.length + " stacks");
-		log(code.types.length + " types, " + closuresPointers.length + " closures");
-		log(blocks.length + " live blocks " + MB(used) + " used, " + MB(pagesSize - used - reserved) + " free, "+MB(privateData + markData)+" gc");
-		if (filterMode != None)
-			log(filteredBlocks.length + " blocks in filter " + MB(fUsed) + " used");
-	}
-
-	function getTypeNull( t : TType ) {
-		if( t.nullWrap != null )
-			return t.nullWrap;
-		for( t2 in types )
-			switch( t2.t ) {
-			case HNull(base) if( base == t.t ):
-				t.nullWrap = t2;
-				return t2;
-			default:
-			}
-		var r = new TType(types.length, HNull(t.t));
-		t.nullWrap = r;
-		types.push(r);
-		return r;
-	}
-
-	function goto( b : Block ) {
-		var p = b.page.dataPosition;
-		if( p < 0 ) throw "assert";
-		pos = p + b.addr.sub(b.page.addr);
-		//memoryDump.seek(p + b.addr.sub(b.page.addr), SeekBegin);
-	}
-
-	function check() {
-		if( code == null ) throw "Missing .hl file";
-		if( memoryDump == null ) throw "Missing .dump file";
-		if( code.types.length != this.typesPointers.length ) throw "Types count mismatch";
-
-		pointerType = new PointerMap();
-		var cid = 0;
-		types = [for( i in 0...code.types.length ) new TType(i, code.types[i])];
-		for( i in 0...typesPointers.length ) {
-			pointerType.set(typesPointers[i], types[i]);
-			switch( code.types[i] ) {
-			case HFun(f):
-				var tid = types.length;
-				var args = f.args.copy();
-				var clparam = args.shift();
-				if( clparam == null ) {
-					cid++;
-					continue;
-				}
-				switch( clparam ) {
-				case HEnum(p) if( p.name == "" ):
-					p.name = '<closure$i context>';
-				default:
-				}
-				var ct = new TType(tid, HFun({ args : args, ret : f.ret }), clparam);
-				types.push(ct);
-				var pt = closuresPointers[cid++];
-				if( !pt.isNull() )
-					pointerType.set(pt, ct);
-			case HObj(o), HStruct(o):
-				if( o.tsuper != null ) {
-					var found = false;
-					for( j in 0...types.length )
-						if( types[j].t == o.tsuper ) {
-							types[i].parentClass = types[j];
-							found = true;
-							break;
-						}
-					if( !found ) throw "Missing parent class";
-				}
-			default:
-			}
-		}
-
-		for( b in baseTypes ) {
-			var t = getType(b.t, true);
-			if( t == null ) {
-				t = new TType(types.length, b.t);
-				types.push(t);
-			}
-			pointerType.set(b.p, t);
-		}
-
-		var progress = 0;
-		pointerBlock = new PointerMap();
-
-		var missingTypes = 0;
-		for( b in blocks ) {
-			progress++;
-			if( displayProgress && progress % 1000 == 0 )
-				Sys.print((Std.int((progress / blocks.length) * 1000.0) / 10) + "%  \r");
-			if( b.page.kind == PDynamic ) {
-				goto(b);
-				b.typePtr = readPointer();
-			}
-			b.type = pointerType.get(b.typePtr);
-			if( b.page.kind == PDynamic && b.type == null && b.typePtr != Pointer.NULL )
-				missingTypes++; // types that we don't have in our dump
-			b.typePtr = Pointer.NULL;
-			if( b.type != null ) {
-				switch( b.page.kind ) {
-				case PDynamic:
-				case PNoPtr:
-					if( b.type.hasPtr ) {
-						if( b.type.t.match(HEnum(_)) ) {
-							// most likely one of the constructor without pointer parameter
-						} else
-							b.type = null; // false positive
-					}
-				case PRaw, PFinalizer:
-					if( b.type.isDyn )
-						b.type = null; // false positive
-				}
-			}
-			if( b.type != null && !b.type.isDyn )
-				b.type = getTypeNull(b.type);
-			if( b.type != null )
-				b.typeKind = KHeader;
-			pointerBlock.set(b.addr, b);
-		}
-
-		//Sys.println(missingTypes+" blocks with unresolved type");
-
-		printStats();
-
-		// look in roots (higher ownership priority)
-		all = new Block();
-
-		var broot = new Block();
-		broot.type = new TType(types.length, HAbstract("roots"));
-		types.push(broot.type);
-		broot.depth = 0;
-		broot.addParent(all);
-
-		for( r in roots ) {
-			var b = pointerBlock.get(r);
-			if( b == null ) continue;
-			b.addParent(broot);
-			if( b.type == null )
-				b.typeKind = KRoot;
-		}
-
-		var tinvalid = new TType(types.length, HAbstract("invalid"));
-		types.push(tinvalid);
-		for( t in types )
-			t.buildTypes(this, tinvalid);
-
-		var tunknown = new TType(types.length, HAbstract("unknown"));
-		types.push(tunknown);
-
-		tdynObj = getType(HDynObj);
-		tdynObjData = new TType(types.length, HAbstract("dynobjdata"));
-		types.push(tdynObjData);
-
-		toProcess = blocks.copy();
-		falseCandidates = [];
-
-
-		while( toProcess.length > 0 )
-			buildHierarchy();
-
-		var i = hide.tools.memory.Memory.readIntCpt;
-		var v = hide.tools.memory.Memory.readPointerCpt;
-		trace(i + " // " + v);
-		// look in stacks (low priority of ownership)
-		var tstacks = new TType(types.length, HAbstract("stack"));
-		var bstacks = [];
-		types.push(tstacks);
-		for( s in stacks ) {
-			var bstack = new Block();
-			bstack.depth = 10000;
-			bstack.type = tstacks;
-			bstack.addParent(all);
-			bstacks.push(bstack);
-			for( r in s.contents ) {
-				var b = pointerBlock.get(r);
-				if( b != null )
-					b.addParent(bstack);
-			}
-		}
-
-		for( f in falseCandidates )
-			if( f.f.owner == null ) {
-				f.f.addParent(f.b);
-				f.b.type.falsePositive++;
-				f.b.type.falsePositiveIndexes[f.idx]++;
-			}
-
-		// precompute Arrays (no NativeArray intermediate)
-		function shortCircuit( native, haxe ) {
-			var tnat = resolveType(native, false);
-			var tarr = resolveType(haxe, false);
-			if( tnat == null || tarr == null ) return;
-			for( b in blocks ) {
-				if( b.type == tnat && b.owner != null && b.owner.type == tarr && b.subs != null ) {
-					for( s in b.subs )
-						s.b.addParent(b.owner);
-				}
-			}
-		}
-		shortCircuit("hl.NativeArray","Array<T>");
-		// disable for now, this generates unknowns and "Void" links
-		//shortCircuit("hl_bytes_map","Map<String,Dynamic>");
-		//shortCircuit("hl_int_map","Map<Int,Dynamic>");
-		//shortCircuit("hl_obj_map","Map<{},Dynamic>");
-
-		// assign depths
-
-		Sys.println("Computing depths...");
-		broot.markDepth();
-		for( b in bstacks ) b.markDepth();
-
-		var changed = -1;
-		while( changed != 0 ) {
-			changed = 0;
-			for( b in blocks ) {
-				var minD = -1;
-				if( b.parents == null ) {
-					if( b.owner != null && b.owner.depth >= 0 )
-						minD = b.owner.depth;
-				} else {
-					for( p in b.parents )
-						if( p.depth >= 0 && (minD < 0 || p.depth < minD) )
-							minD = p.depth;
-				}
-				if( minD >= 0 ) {
-					minD++;
-					if( b.depth < 0 || b.depth > minD ) {
-						b.depth = minD;
-						changed++;
-					}
-				}
-			}
-		}
-
-		for( b in blocks )
-			b.finalize();
-
-		var unk = 0, unkMem = 0, unRef = 0;
-		for( b in blocks ) {
-			if( b.owner == null ) {
-				unRef++;
-				if( unRef < 100 )
-					log("  "+b.addr.toString()+"["+b.size+"] is not referenced");
-				continue;
-			}
-
-			if( b.type != null )
-				continue;
-
-			var o = b.owner;
-			while( o != null && o.type == null )
-				o = o.owner;
-			if( o != null )
-				switch( o.type.t ) {
-				case HAbstract(_):
-					b.type = o.type; // data inside this
-					b.typeKind = KAbstractData;
-					continue;
-				default:
-				}
-
-			b.type = tunknown;
-		}
-
-		var falseCount = 0;
-		for( t in types )
-			falseCount += t.falsePositive;
-
-		log("Hierarchy built, "+falseCount+" false positives, "+unRef+" unreferenced");
-	}
-
-	function printFalsePositives( ?typeStr : String ) {
-		var falses = [for( t in types ) if( t.falsePositive > 0 && (typeStr == null || t.toString().indexOf(typeStr) >= 0) ) t];
-		falses.sort(function(t1, t2) return t1.falsePositive - t2.falsePositive);
-		for( f in falses )
-			log(f.falsePositive+" count " + f + " "+f.falsePositiveIndexes+"\n    "+[for( f in f.memFields ) f.t.toString()]);
-	}
-
-	function printUnknown() {
-		var byT = new Map();
-		for( b in blocks ) {
-			if( b.type != null ) continue;
-
-			var o = b;
-			while( o != null && o.type == null )
-				o = o.owner;
-
-			var t = o == null ? null : o.type;
-			var tid = t == null ? -1 : t.tid;
-			var inf = byT.get(tid);
-			if( inf == null ) {
-				inf = { t : t, count : 0, mem : 0 };
-				byT.set(tid, inf);
-			}
-			inf.count++;
-			inf.mem += b.size;
-		}
-		var all = [for( k in byT ) k];
-		all.sort(function(i1, i2) return i1.count - i2.count);
-		for( a in all )
-			log("Unknown "+a.count + " count, " + MB(a.mem)+" "+(a.t == null ? "" : a.t.toString()));
-	}
-
-	function buildHierarchy() {
-		var progress = 0;
-		var blocks = toProcess;
-		toProcess = [];
-
-		for( b in blocks )
-			b.removeChildren();
-
-		for( b in blocks ) {
-			progress++;
-			if( displayProgress && progress % 10000 == 0 )
-				Sys.print((Std.int(progress * 1000.0 / blocks.length) / 10) + "%  \r");
-
-			if( !b.page.memHasPtr() )
-				continue;
-
-			if( b.type != null && !b.type.hasPtr )
-				log("  Scanning "+b.type+" "+b.addr.toString());
-
-			goto(b);
-			var fields = null;
-			var start = 0;
-			var ptrTags = null;
-			var hasFieldNames = false;
-			if( b.type != null ) {
-				hasFieldNames = b.type.memFieldsNames != null;
-				fields = b.type.memFields;
-				ptrTags = b.type.ptrTags;
-				// enum
-				if( b.type.constructs != null ) {
-					readPointer(); // type
-					var index = readInt();
-					fields = b.type.constructs[index];
-					if( is64 ) readInt(); // skip, not a pointer anyway
-					start += 2;
-				}
-			}
-
-			for( i in start...(b.size >> ptrBits) ) {
-				var r = readPointer();
-
-				var bs = pointerBlock.get(r);
-				if( bs == null ) continue;
-				var ft = fields != null ? fields[i] : null;
-
-				if( ptrTags != null && ((ptrTags.get(i >> 3) >>> (i & 7)) & 1) == 0 && !b.type.t.match(HVirtual(_)) )
-					continue;
-
-				if( b.type == tdynObj && (i == 1 || i == 2 || i == 3) ) {
-					if( bs.typeKind != KHeader && (bs.typeKind != null || bs.type != null) )
-						trace(bs.typeKind, bs.type);
-					else {
-						bs.type = tdynObjData;
-						bs.typeKind = KDynObjData;
-					}
-				}
-
-				if( ft != null && !ft.t.isPtr() ) {
-					falseCandidates.push({ b : b, f:bs, idx : i });
-					continue;
-				}
-				bs.addParent(b,hasFieldNames ? (i+1) : 0);
-
-				if( bs.type == null && ft != null ) {
-					if( ft.t.match(HDyn | HObj(_)) ) {
-						// we can't infer with a polymorph type
-						continue;
-					}
-					bs.type = ft;
-					bs.typeKind = KInferred(b.type, b.typeKind);
-					if( bs.subs != null )
-						toProcess.push(bs);
-				}
-			}
-		}
-	}
-
-	function printByType() {
-		var ctx = new Stats(this);
-		for( b in filteredBlocks )
-			ctx.add(b.type, b.size);
-		ctx.print();
-	}
-
-	function resolveType( str, showError = true ) {
-		var t = resolveCache.get(str);
-		if( t != null )
-			return t;
-		for( i in currentTypeIndex...types.length ) {
-			var t = types[i];
-			var tstr = t.toString();
-			if (tstr != null) {
-				resolveCache.set(tstr, t);
-				currentTypeIndex = i + 1;
-				if( tstr == str )
-					return t;
-			}
-		}
-		if( showError )
-			log("Type not found '"+str+"'");
-		return null;
-	}
-
-	public function getLocate(tstr : String, up = 0) {
-		var ctx = new Stats(this);
-
-		var lt = resolveType(tstr);
-		if( lt == null ) return ctx;
-
-		inline function isVirtualField(t) { t >>>= 24; return t == 1 || t == 2; }
-
-		for( b in filteredBlocks )
-			if( b.type != null && b.type.match(lt) ) {
-				var tl = [];
-				var owner = b.owner;
-				// skip first virtual field
-				if( lt.t != HDynObj && owner != null && owner.type != null && owner.type.t.match(HVirtual(_)) && isVirtualField(owner.makeTID(b,true)) )
-					owner = owner.owner;
-
-				if( owner != null ) {
-					tl.push(owner.makeTID(b,displayFields == Full));
-					var k : Int = up;
-					while( owner.owner != null && k-- > 0 && owner.owner != all ) {
-						var tag = owner.owner.makeTID(owner,displayFields != None);
-						owner = owner.owner;
-						// remove recursive sequence
-						for( i => tag2 in tl )
-							if( tag2 == tag ) {
-								var seq = true;
-								for( n in 0...i ) {
-									if( tl[n] != tl[i+1+n] )
-										seq = false;
-								}
-								if( seq ) {
-									for( k in 0...i ) tl.shift();
-									tag = -1;
-									k += i + 1;
-								}
-								break;
-							}
-						// don't display virtual wrappers
-						if( displayFields != None && owner.type != null && isVirtualField(tag) && owner.type.t.match(HVirtual(_)) ) {
-							tag = -1;
-							k++;
-						}
-						if( tag != -1 )
-							tl.unshift(tag);
-					}
-				}
-				ctx.addPath(tl, b.size);
-			}
-
-		return ctx;
-	}
-
-	function locate( tstr : String, up = 0 ) {
-		var ctx = getLocate(tstr, up);
-		ctx.print();
-	}
-
-	function count( tstr : String, excludes : Array<String> ) {
-		var t = resolveType(tstr);
-		if( t == null ) return;
-		var texclude = [];
-		for( e in excludes ) {
-			var t = resolveType(e);
-			if( t == null ) return;
-			texclude.push(t);
-		}
-		var ctx = new Stats(this);
-		Block.MARK_UID++;
-		var mark = [];
-		for( b in filteredBlocks )
-			if( b.type == t )
-				visitRec(b,ctx,[],mark);
-		while( mark.length > 0 ) {
-			var b = mark.pop();
-			for( s in b.subs )
-				visitRec(s.b,ctx,texclude,mark);
-		}
-		ctx.print(true);
-	}
-
-	function visitRec( b : Block, ctx : Stats, exclude : Array<TType>, mark : Array<Block> ) {
-		if( b.mark == Block.MARK_UID ) return;
-		b.mark = Block.MARK_UID;
-		if( b.type != null ) for( t in exclude ) if( b.type.match(t) ) return;
-		ctx.addPath(b.type == null ? [] : [b.type.tid],b.size);
-		if( b.subs != null )
-			mark.push(b);
-	}
-
-	function parents( tstr : String, up = 0 ) {
-		var lt = null;
-		for( t in types )
-			if( t.t.toString() == tstr ) {
-				lt = t;
-				break;
-			}
-		if( lt == null ) {
-			log("Type not found");
-			return;
-		}
-
-		var ctx = new Stats(this);
-		for( b in filteredBlocks )
-			if( b.type == lt )
-				for( b in b.getParents() )
-					ctx.addPath([if( b.type == null ) 0 else b.type.tid], 0);
-		ctx.print();
-	}
-
-	function subs( tstr : String, down = 0 ) {
-		var lt = null;
-		for( t in types )
-			if( t.t.toString() == tstr ) {
-				lt = t;
-				break;
-			}
-		if( lt == null ) {
-			log("Type not found");
-			return;
-		}
-
-		var ctx = new Stats(this);
-		var mark = new Map();
-		for( b in filteredBlocks )
-			if( b.type == lt ) {
-				function addRec(tl:Array<Int>,b:Block, k:Int) {
-					if( k < 0 ) return;
-					if( mark.exists(b) )
-						return;
-					mark.set(b, true);
-					tl.push(b.type == null ? 0 : b.type.tid);
-					ctx.addPath(tl, b.size);
-					if( b.subs != null ) {
-							k--;
-						for( s in b.subs )
-							addRec(tl.copy(),s.b, k);
-					}
-				}
-				addRec([], b, down);
-			}
-		ctx.print();
-	}
-
-	public function setFilterMode(m: FilterMode) {
-		filterMode = m;
-		switch( m ) {
-		case None:
-			filteredBlocks = blocks.copy();
-		default:
-			filteredBlocks = [];
-			var progress = 0;
-			for( b in blocks ) {
-				progress++;
-				if( displayProgress && progress % 1000 == 0 )
-					Sys.print((Std.int((progress / blocks.length) * 1000.0) / 10) + "%  \r");
-				if( !isBlockIgnored(b, m) )
-					filteredBlocks.push(b);
-			}
-			if( displayProgress )
-				Sys.print("       \r");
-		}
-	}
-	public function isBlockIgnored(b: Block, m: FilterMode) {
-		switch( m ) {
-		case None:
-			return false;
-		case Intersect:
-			for( m in otherMems ) {
-				if( m.pointerBlock.get(b.addr ) == null )
-					return true;
-			}
-		case Unique:
-			for( m in otherMems ) {
-				if( m.pointerBlock.get(b.addr ) != null )
-					return true;
-			}
-		}
-		return false;
-	}
-
-	public function log(msg:String) {
-		Sys.println(msg);
-	}
-
-	static function parseArgs(str: String) {
-		str = StringTools.trim(str);
-		var i = 0;
-		var tok = "";
-		var args = [];
-		var escape = false;
-		while(i != str.length) {
-			var c = str.charAt(i++);
-			if(c == '"') {
-				escape = !escape;
-			}
-			else {
-				if(c == " " && !escape) {
-					if(tok.length > 0) args.push(tok);
-					tok = "";
-				}
-				else
-					tok += c;
-			}
-		}
-		if(tok.length > 0) args.push(tok);
-		return args;
-	}
-
-	static var useColor = false;
-	static function main() {
-		var m = new Memory();
-		var others: Array<Memory> = [];
-		var filterMode: FilterMode = None;
-
-		//hl.Gc.dumpMemory(); Sys.command("cp memory.hl test.hl");
-
-		var code = null, memory = null;
-		var args = Sys.args();
-		while( args.length > 0 ) {
-			var arg = args.shift();
-			if( StringTools.endsWith(arg, ".hl") ) {
-				code = arg;
-				m.loadBytecode(arg);
-				continue;
-			}
-			if( arg == "-c" || arg == "--color" ) {
-				useColor = true;
-				continue;
-			}
-			if( arg == "--args" ) {
-				m.displayProgress = false;
-				break;
-			}
-			if (memory == null) {
-				memory = arg;
-				m.loadMemory(arg);
-			} else {
-				var m2 = new Memory();
-				m2.loadMemory(arg);
-				others.push(m2);
-			}
-		}
-		if( code != null && memory == null ) {
-			var dir = new haxe.io.Path(code).dir;
-			if( dir == null ) dir = ".";
-			memory = dir+"/hlmemory.dump";
-			if( sys.FileSystem.exists(memory) ) m.loadMemory(memory);
-		}
-
-		m.check();
-		for (m2 in others) {
-			m2.code = m.code;
-			m2.check();
-		}
-		m.otherMems = [for (i in others) i];
-		m.setFilterMode(filterMode);
-
-		var stdin = Sys.stdin();
-		while( true ) {
-			Sys.print(withColor("> ", 31));
-			var args = parseArgs(args.length > 0 ? args.shift() : stdin.readLine());
-			var cmd = args.shift();
-			switch( cmd ) {
-			case "exit", "quit", "q":
-				break;
-			case "types":
-				m.printByType();
-			case "stats":
-				m.printStats();
-			case "false":
-				m.printFalsePositives(args.shift());
-			case "unknown":
-				m.printUnknown();
-			case "locate":
-				m.locate(args.shift(), Std.parseInt(args.shift()));
-			case "count":
-				m.count(args.shift(), args);
-			case "parents":
-				m.parents(args.shift());
-			case "subs":
-				m.subs(args.shift(), Std.parseInt(args.shift()));
-			case "sort":
-				switch( args.shift() ) {
-				case "mem":
-					m.sortByCount = false;
-				case "count":
-					m.sortByCount = true;
-				case mode:
-					Sys.println("Unknown sort mode " + mode);
-				}
-			case "fields":
-				switch( args.shift() ) {
-				case "full":
-					m.displayFields = Full;
-				case "none":
-					m.displayFields = None;
-				case "parents":
-					m.displayFields = Parents;
-				case mode:
-					Sys.println("Unknown fields mode " + mode);
-				}
-			case "filter":
-				switch( args.shift() ) {
-				case "none":
-					filterMode = None;
-				case "intersect":
-					filterMode = Intersect;
-				case "unique":
-					filterMode = Unique;
-				case mode:
-					Sys.println("Unknown filter mode " + mode);
-				}
-				m.setFilterMode(filterMode);
-			case "nextDump":
-				others.push(m);
-				m = others.shift();
-				m.otherMems = [for (i in others) i];
-				m.setFilterMode(filterMode);
-				var ostr = others.length > 0 ? (" (others are " + others.map(m -> m.memFile) + ")") : "";
-				Sys.println("Using dump " + m.memFile + ostr);
-			case "lines":
-				var v = args.shift();
-				if( v != null )
-					m.maxLines = Std.parseInt(v);
-				Sys.println(m.maxLines == 0 ? "Lines limit disabled" : m.maxLines + " maximum lines displayed");
-			case null:
-				Sys.println("");
-			default:
-				Sys.println("Unknown command " + cmd);
-			}
-		}
-	}
-
-	// A list of ansi colors is available at
-	// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797#8-16-colors
-	public static function withColor(str: String, ansiCol: Int) {
-		if (!useColor)
-			return str;
-		return "\x1B[" + ansiCol + "m" + str + "\x1B[0m";
-	}
-}

+ 0 - 188
hide/tools/memory/TType.hx

@@ -1,188 +0,0 @@
-package hide.tools.memory;
-
-import format.hl.Data;
-using format.hl.Tools;
-
-class TType {
-	public var tid : Int;
-	public var t : HLType;
-	public var closure : HLType;
-	public var bmp : haxe.io.Bytes;
-	public var hasPtr : Bool;
-	public var isDyn : Bool;
-
-	public var memFields : Array<TType>;
-	public var memFieldsNames : Array<String>;
-
-	public var constructs : Array<Array<TType>>;
-	public var nullWrap : TType;
-	public var ptrTags : haxe.io.Bytes;
-	public var parentClass : TType;
-
-	public var falsePositive = 0;
-	public var falsePositiveIndexes = [];
-
-	public function new(tid, t, ?cl) {
-		this.tid = tid;
-		this.t = t;
-		this.closure = cl;
-		isDyn = t.isDynamic();
-		switch( t ) {
-		case HFun(_):
-			hasPtr = cl != null && cl.isPtr();
-		default:
-			hasPtr = t.containsPointer();
-		}
-	}
-
-	public function match( t : TType ) {
-		if( t == this ) return true;
-		if( parentClass != null ) return parentClass.match(t);
-		return false;
-	}
-
-	function tagPtr( pos : Int ) {
-		var p = pos >> 3;
-		if( ptrTags == null || ptrTags.length <= p ) {
-			var nc = haxe.io.Bytes.alloc(p + 1);
-			if( ptrTags != null ) nc.blit(0, ptrTags, 0, ptrTags.length);
-			ptrTags = nc;
-		}
-		ptrTags.set(p, ptrTags.get(p) | (1 << (pos & 7)));
-	}
-
-	function appendField( m : Memory, pos : Int, name : String, t : HLType ) {
-		switch( t ) {
-		case HPacked({ v : HStruct(p) }):
-			var all = [p];
-			while( p.tsuper != null ) {
-				switch( p.tsuper ) {
-				case HStruct(p2):
-					p = p2;
-					all.unshift(p2);
-				default:
-					throw "assert";
-				}
-			}
-			for( p in all )
-				for( f in p.fields )
-					pos = appendField(m, pos, name+"."+f.name, f.t);
-		case HPacked(_):
-			throw "assert";
-		default:
-			var size = m.typeSize(t);
-			pos = align(pos, size);
-			memFields[pos >> m.ptrBits] = m.getType(t);
-			memFieldsNames[pos >> m.ptrBits] = name;
-			if( t.isPtr() ) tagPtr(pos >> m.ptrBits);
-			pos += size;
-		}
-		return pos;
-	}
-
-	public function buildTypes( m : Memory, tvoid : TType ) {
-		if( !hasPtr ) return;
-
-		// layout of data inside memory
-		inline function fill(fields:Array<TType>, pos:Int) {
-			if( m.is64 ) {
-				for( i in 0...pos >> m.ptrBits )
-					if( fields[i] == null )
-						fields[i] = tvoid;
-			} else {
-				// fill two slots for 64bit data
-				var i = pos >> m.ptrBits;
-				while( --i >= 0 )
-					if( fields[i] == null )
-						fields[i] = (fields[i-1] == null || fields[i-1].t != HF64) ? tvoid : fields[i-1];
-			}
-		}
-
-		switch( t ) {
-		case HObj(p), HStruct(p):
-			var protos = [p];
-			while( p.tsuper != null )
-				switch( p.tsuper ) {
-				case HObj(p2), HStruct(p2):
-					protos.unshift(p2);
-					p = p2;
-				default:
-				}
-
-			memFields = [];
-			memFieldsNames = [];
-
-			var pos = t.match(HStruct(_)) ? 0 : 1 << m.ptrBits; // type
-			for( p in protos )
-				for( f in p.fields )
-					pos = appendField(m, pos, f.name, f.t);
-			fill(memFields, pos);
-		case HEnum(e):
-			constructs = [];
-			for( c in e.constructs ) {
-				var pos = (1<<m.ptrBits) + 4; // type + index
-				var fields = [];
-				for( t in c.params ) {
-					var size = m.typeSize(t);
-					pos = align(pos, size);
-					fields[pos>>m.ptrBits] = m.getType(t);
-					if( t.isPtr() ) tagPtr(pos >> m.ptrBits);
-					pos += size;
-				}
-				fill(fields, pos);
-				constructs.push(fields);
-			}
-		case HVirtual(fl):
-			memFields = [
-				tvoid, // type
-				m.getType(HDyn), // obj
-				m.getType(HDyn), // next
-			];
-			memFieldsNames = [];
-			var pos = (fl.length + 3) << m.ptrBits;
-			tagPtr(1);
-			tagPtr(2);
-			for( f in fl ) {
-				var size = m.typeSize(f.t);
-				pos = align(pos, size);
-				memFields[pos >> m.ptrBits] = m.getType(f.t);
-				memFieldsNames[pos >> m.ptrBits] = f.name;
-				if( f.t.isPtr() ) tagPtr(pos >> m.ptrBits);
-				pos += size;
-			}
-
-			fill(memFields, pos);
-			// keep null our fields pointers since they might point to a DynObj data head
-			for( i in 0...fl.length )
-				memFields[i+3] = null;
-		case HNull(t):
-			if( m.is64 )
-				memFields = [tvoid, m.getType(t)];
-			else
-				memFields = [tvoid, tvoid, m.getType(t), tvoid];
-		case HFun(_):
-			memFields = [tvoid, tvoid, tvoid, m.getType(closure)];
-		default:
-		}
-	}
-
-	inline function align(pos, size) {
-		var d = pos & (size - 1);
-		if( d != 0 ) pos += size - d;
-		return pos;
-	}
-
-	public function toString() {
-		switch( t ) {
-		case HAbstract("roots"):
-			return Memory.withColor("roots", 32);
-		case HAbstract(p):
-			return p;
-		case HFun(_), HMethod(_):
-			return 'Function(${t.toString()})';
-		default:
-			return t.toString();
-		}
-	}
-
-}

+ 20 - 18
hide/view/Profiler.hx

@@ -41,8 +41,8 @@ class Profiler extends hide.ui.View<{}> {
 	var tabs : hide.comp.Tabs;
 	var view : cdb.DiffFile.ConfigView;
 
-	public var mainMemory : hide.tools.memory.Memory = null;
-	public var currentMemory : hide.tools.memory.Memory = null;
+	public var mainMemory : hlmem.Memory = null;
+	public var currentMemory : hlmem.Memory = null;
 	public var names(default, null) : Array<String> = [];
 
 	public var lines(default, null) : Array<LineData> = [];
@@ -196,6 +196,7 @@ class Profiler extends hide.ui.View<{}> {
 	}
 
 	function load() {
+		var mem : hlmem.Memory;
 		names = dumpPaths;
 
 		var result = loadAll();
@@ -206,15 +207,15 @@ class Profiler extends hide.ui.View<{}> {
 			if (names.length > 0) {
 				this.currentFilter = None;
 				displayTypes(sort, sortOrderAscending);
-				statsObj = mainMemory?.getStatsObj();
+				statsObj = mainMemory?.getStats();
 			}
 		}
 	}
 
-	function loadAll() @:privateAccess{
+	function loadAll() @:privateAccess {
 		if (names.length < 1) return null;
 		for (i in 0...names.length) {
-			var newMem = new hide.tools.memory.Memory();
+			var newMem = new hlmem.Memory();
 			try {
 				if (i == 0) { // setup main Memory
 					newMem.loadBytecode(hlPath);
@@ -255,7 +256,7 @@ class Profiler extends hide.ui.View<{}> {
 
 		lines = [];
 
-		var ctx = new hide.tools.memory.Memory.Stats(currentMemory);
+		var ctx = new hlmem.Memory.Stats(currentMemory);
 		for ( b in currentMemory.filteredBlocks)
 			ctx.add(b.type, b.size);
 
@@ -267,15 +268,16 @@ class Profiler extends hide.ui.View<{}> {
 	}
 
 	public function getNameString(tid : Array<Int>) {
-		var path = hide.tools.memory.Memory.Stats.getPathStrings(mainMemory, tid);
+		var path = hlmem.Memory.Stats.getPathStrings(mainMemory, tid);
 		return path[path.length-1];
 	}
 
 	public function getPathString(tid : Array<Int>) {
-		return hide.tools.memory.Memory.Stats.getPathStrings(currentMemory, tid).join(" > ");
+		return hlmem.Memory.Stats.getPathStrings(currentMemory, tid).join(" > ");
 	}
 
 	public function refresh() {
+		//var memo : memory.Memory;
 		refreshStats();
 		refreshFilters();
 		refreshHierarchicalView();
@@ -331,14 +333,14 @@ class Profiler extends hide.ui.View<{}> {
 			new Element('
 			<h4>Memory usage</h4>
 			<h5>${s.memFile}</h5>
-			<div class="outer-gauge"><div class="inner-gauge" title="${hide.tools.memory.Memory.MB(s.used)} used (${ 100 * s.used / s.totalAllocated}% of total)" style="width:${ 100 * s.used / s.totalAllocated}%;"></div></div>
+			<div class="outer-gauge"><div class="inner-gauge" title="${hlmem.Memory.MB(s.used)} used (${ 100 * s.used / s.totalAllocated}% of total)" style="width:${ 100 * s.used / s.totalAllocated}%;"></div></div>
 			<dl>
-				<dt>Allocated</dt><dd>${hide.tools.memory.Memory.MB(s.totalAllocated)}</dd>
-				<dt>Used</dt><dd>${hide.tools.memory.Memory.MB(s.used)}</dd>
-				<dt>Free</dt><dd>${hide.tools.memory.Memory.MB(s.free)}</dd>
-				<dt>GC</dt><dd>${hide.tools.memory.Memory.MB(s.gc)}</dd>
+				<dt>Allocated</dt><dd>${hlmem.Memory.MB(s.totalAllocated)}</dd>
+				<dt>Used</dt><dd>${hlmem.Memory.MB(s.used)}</dd>
+				<dt>Free</dt><dd>${hlmem.Memory.MB(s.free)}</dd>
+				<dt>GC</dt><dd>${hlmem.Memory.MB(s.gc)}</dd>
 				<dt>&nbsp</dt><dd></dd>
-				<dt>Pages</dt><dd>${s.pagesCount} (${hide.tools.memory.Memory.MB(s.pagesSize)})</dd>
+				<dt>Pages</dt><dd>${s.pagesCount} (${hlmem.Memory.MB(s.pagesSize)})</dd>
 				<dt>Roots</dt><dd>${s.rootsCount}</dd>
 				<dt>Stacks</dt><dd>${s.stackCount}</dd>
 				<dt>Types</dt><dd>${s.typesCount}</dd>
@@ -385,7 +387,7 @@ class Profiler extends hide.ui.View<{}> {
 		var datas = [];
 		if (str == "null" || locationData.exists(str)) return;
 
-		var ctx = currentMemory.getLocate(str, 30);
+		var ctx = @:privateAccess currentMemory.locate(str, 30);
 		ctx.sort();
 		for (i in ctx.allT)
 			datas.push({count : i.count, size : i.mem, tid : i.tl, name : null, state: Unique});
@@ -461,7 +463,7 @@ class Profiler extends hide.ui.View<{}> {
 		locationData.clear();
 
 		displayTypes(sort, sortOrderAscending);
-		statsObj = mainMemory?.getStatsObj();
+		statsObj = mainMemory?.getStats();
 
 		refreshHierarchicalView();
 	}
@@ -491,11 +493,11 @@ class ProfilerElement extends hide.comp.Component{
 		this.parent = parent;
 		this.depth = parent != null ? parent.depth + 1 : 0;
 
-		var name = path == null ? line.name : hide.tools.memory.Memory.Stats.getTypeString(profiler.currentMemory, path.v);
+		var name = path == null ? line.name : hlmem.Memory.Stats.getTypeString(profiler.currentMemory, path.v);
 		var count = path == null ? line.count : path.total.count;
 		var mem = path == null ? line.size : path.total.mem;
 
-		this.element = new Element('<tr tabindex="2"><td><div class="folder icon ico ico-caret-right"></div>${count}</td><td>${hide.tools.memory.Memory.MB(mem)}</td><td title="${name}">${name}</td><td><div title="Allocated ${mem} (${100 * mem / Reflect.getProperty(profiler.statsObj[0], "totalAllocated")}% of total)" class="outer-gauge"><div class="inner-gauge" style="width:${100 * mem / Reflect.getProperty(profiler.statsObj[0], "totalAllocated")}%;"></div></div></td></tr>');
+		this.element = new Element('<tr tabindex="2"><td><div class="folder icon ico ico-caret-right"></div>${count}</td><td>${hlmem.Memory.MB(mem)}</td><td title="${name}">${name}</td><td><div title="Allocated ${mem} (${100 * mem / Reflect.getProperty(profiler.statsObj[0], "totalAllocated")}% of total)" class="outer-gauge"><div class="inner-gauge" style="width:${100 * mem / Reflect.getProperty(profiler.statsObj[0], "totalAllocated")}%;"></div></div></td></tr>');
 		this.element.find('td').first().css({'padding-left':'${10 * depth}px'});
 
 		this.foldBtn = this.element.find('.folder');