Răsfoiți Sursa

hl memory tracking api

Nicolas Cannasse 8 ani în urmă
părinte
comite
e926a3a5e4
2 a modificat fișierele cu 77 adăugiri și 28 ștergeri
  1. 1 28
      std/hl/Gc.hx
  2. 76 0
      std/hl/Profile.hx

+ 1 - 28
std/hl/Gc.hx

@@ -31,7 +31,7 @@ enum GcFlag {
 	**/
 	DumpMem;
 	/**
-		Enable block tracking (see Gc.track API)
+		Enable allocation tracking
 	**/
 	Track;
 }
@@ -46,31 +46,6 @@ class Gc {
 		return { totalAllocated : tot, allocationCount : count, currentMemory : mem };
 	}
 
-	/**
-		Start tracking an object field change.
-		The check will be performed every allocation and the callback function triggered everytime
-		a change has been performed since last check. The callback parameter is true if the object was collected.
-		It is necessary to enable the Track flag in Gc.flags
-	**/
-	public static function track( obj : Dynamic, field : String, callb : Dynamic -> Bytes -> Void ) {
-		var oval = if( Reflect.isFunction(obj) ) Api.getClosureValue(obj) else obj;
-		var fid = if( ~/^[0-9]+$/.match(field) ) Std.parseInt(field) else @:privateAccess field.bytes.hash();
-		if( !_track(oval, fid, callb) )
-			throw "Could not track "+obj+"."+field;
-	}
-
-	public static function untrack( obj : Dynamic ) {
-		var oval = if( Reflect.isFunction(obj) ) Api.getClosureValue(obj) else obj;
-		return _untrack(oval);
-	}
-
-	@:hlNative("std", "gc_untrack_all") public static function untrackAll() : Void {
-	}
-
-	@:hlNative("std", "gc_track_count") public static function trackCount() : Int {
-		return 0;
-	}
-
 	/**
 		Dump whole memory into target filename for analysis.
 	**/
@@ -92,8 +67,6 @@ class Gc {
 	@:hlNative("std", "gc_enable") public static function enable( b : Bool ) : Void {}
 	@:hlNative("std", "gc_major") public static function major() : Void {}
 	@:hlNative("std", "gc_stats") static function _stats( totalAllocated : hl.Ref<Float>, allocationCount : hl.Ref<Float>, currentMemory : hl.Ref<Float> ) : Void {}
-	@:hlNative("std", "gc_track") static function _track( obj : Dynamic, fid : Int, callb : Dynamic -> Bytes -> Void ) : Bool { return false; }
-	@:hlNative("std", "gc_untrack") static function _untrack( obj : Dynamic ) : Bool { return false; }
 
 	@:hlNative("std", "gc_get_flags") static function _get_flags() : Int { return 0; }
 	@:hlNative("std", "gc_set_flags") static function _set_flags( v : Int ) {}

+ 76 - 0
std/hl/Profile.hx

@@ -0,0 +1,76 @@
+package hl;
+
+typedef Symbol = hl.Abstract<"hl_symbol">;
+
+class Allocation {
+	public var t : hl.Type;
+	public var count : Int;
+	public var size : Int;
+	public var stack : Array<String>;
+	public function new(t, count, size) {
+		this.t = t;
+		this.count = count;
+		this.size = size;
+	}
+}
+
+@:hlNative("std")
+class Profile {
+
+	public static var enable(get, set) : Bool;
+
+	public static function getData() {
+		var old = enable;
+		enable = false;
+		var maxDepth = 0;
+		var count = track_count(maxDepth);
+		var arr = new hl.NativeArray<Symbol>(maxDepth);
+		var out = [];
+		for( i in 0...count ) {
+			var t : hl.Type = null, count = 0, size = 0;
+			track_entry(i, t, count, size, arr);
+			if( count == 0 ) continue;
+			var a = new Allocation(t, count, size);
+			a.stack = [for( a in arr ) resolveSymbol(a)];
+			out.push(a);
+		}
+		out.sort(function(a1, a2) return a2.count - a1.count);
+		enable = old;
+		return out;
+	}
+
+	public static function dump( fileName = "alloc.dump" ) {
+		var d = getData();
+		var f = sys.io.File.write(fileName);
+		for( o in getData() ) {
+			f.writeString(o.count+" "+o.t + " (" + o.size + " bytes)\n");
+			for( s in o.stack )
+				f.writeString("\t" + s + "\n");
+		}
+		f.close();
+	}
+
+	static var BUFSIZE = 512;
+	static var buf = new hl.Bytes(BUFSIZE*2);
+	static function resolveSymbol( s : Symbol ) {
+		var size = BUFSIZE;
+		var bytes = resolve_symbol(s, buf, size);
+		if( bytes == null ) return "<???>";
+		return @:privateAccess String.fromUCS2(bytes.sub(0,(size+1)*2));
+	}
+
+	static function get_enable() return Gc.flags.has(Track);
+	static function set_enable(v) {
+		var flags = Gc.flags;
+		if( v ) flags.set(Track) else flags.unset(Track);
+		Gc.flags = flags;
+		return v;
+	}
+
+	static function resolve_symbol( s : Symbol, buf : hl.Bytes, bufSize : hl.Ref<Int> ) : hl.Bytes { return null; }
+	static function track_count( maxDepth : hl.Ref<Int> ) : Int { return 0; }
+	static function track_entry( id : Int, type : hl.Ref<hl.Type>, count : hl.Ref<Int>, size : hl.Ref<Int>, stack : NativeArray<Symbol> ) : Void {}
+	static function track_init() : Void {}
+	static function __init__() track_init();
+
+}