From: Not Zed Date: Sat, 25 Jan 2020 03:07:54 +0000 (+1030) Subject: Added some gc debugging / helpers. X-Git-Url: https://code.zedzone.au/cvs?a=commitdiff_plain;h=284263b5e3a54dfcfc6904b2de04cc00cd8cc146;p=zcl Added some gc debugging / helpers. --- diff --git a/nbproject/project.properties b/nbproject/project.properties index faa0316..c05dc39 100644 --- a/nbproject/project.properties +++ b/nbproject/project.properties @@ -81,7 +81,7 @@ run.classpath= # Space-separated list of JVM arguments used when running the project. # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. # To set system properties for unit tests define test-sys-prop.name=value: -run.jvmargs=-Djava.library.path=../nativez/bin/notzed.nativez/linux-amd64/lib:bin/notzed.zcl/linux-amd64/lib +run.jvmargs=--add-exports jdk.incubator.foreign/jdk.incubator.foreign.unsafe=notzed.zcl run.modulepath=\ ${javac.modulepath}:\ ${build.modules.dir} diff --git a/src/notzed.zcl.fxdemo/classes/fxdemo/fract/Mandelbrot.java b/src/notzed.zcl.fxdemo/classes/fxdemo/fract/Mandelbrot.java index 4a2cb1c..f5bd01c 100644 --- a/src/notzed.zcl.fxdemo/classes/fxdemo/fract/Mandelbrot.java +++ b/src/notzed.zcl.fxdemo/classes/fxdemo/fract/Mandelbrot.java @@ -36,8 +36,10 @@ import javafx.stage.Stage; import javafx.util.Duration; import java.nio.ByteBuffer; import au.notzed.zcl.CLMemory; +import au.notzed.zcl.CLObject; import java.io.IOException; import java.io.InputStream; +import java.util.concurrent.TimeUnit; import java.util.stream.Stream; import javafx.geometry.Rectangle2D; import javafx.stage.Screen; @@ -59,6 +61,9 @@ public class Mandelbrot extends Application { return t; }); + Timeline tofps; + Transition spin; + Zoom zoom; long nframes; long lframes; @@ -112,7 +117,7 @@ public class Mandelbrot extends Application { case "target": if (v.equals("list")) { System.out.println("Available targets:"); - for (Target t : targets) { + for (Target t: targets) { System.out.print("\t"); System.out.println(t.name); } @@ -148,8 +153,8 @@ public class Mandelbrot extends Application { case "size": if (v.equals("full")) { Rectangle2D size = Screen.getPrimary().getBounds(); - width = (int) size.getWidth(); - height = (int) size.getHeight(); + width = (int)size.getWidth(); + height = (int)size.getHeight(); fullscreen = true; } else { String coords[] = v.split(","); @@ -208,7 +213,7 @@ public class Mandelbrot extends Application { buffer = CLMemory.alloc(width * height * 4); - Timeline tofps = new Timeline(new KeyFrame(Duration.seconds(0.1), (ActionEvent event) -> { + tofps = new Timeline(new KeyFrame(Duration.seconds(0.1), (ActionEvent event) -> { fps.setText(String.format("fps %4d maxiter %d", (nframes - lframes) * 10, lastiter)); lframes = nframes; })); @@ -216,7 +221,7 @@ public class Mandelbrot extends Application { tofps.play(); if (delta != 0.0) { - Transition spin = new Transition(rate) { + spin = new Transition(rate) { { setCycleDuration(Duration.seconds(360 / (Math.abs(delta)))); } @@ -233,7 +238,7 @@ public class Mandelbrot extends Application { arg = Math.toRadians(90); } - Zoom zoom = synchronous ? new Zoom() : new Zoom(rate); + zoom = synchronous ? new Zoom() : new Zoom(rate); zoom.setInterpolator(Interpolator.EASE_BOTH); zoom.setAutoReverse(true); zoom.setCycleCount(Timeline.INDEFINITE); @@ -242,7 +247,18 @@ public class Mandelbrot extends Application { @Override public void stop() throws Exception { + // weird, one needs to explitly stop animations? + zoom.stop(); + tofps.stop(); + if (spin != null) + spin.stop(); + CLObject.debugDumpReachable("Running objects at exit"); + queue.shutdown(); + queue.awaitTermination(5, TimeUnit.SECONDS); calc.release(); + System.gc(); + Thread.sleep(1000); + CLObject.debugDumpReachable("Post release"); } class Zoom extends Transition { @@ -259,7 +275,7 @@ public class Mandelbrot extends Application { @Override protected void interpolate(double frac) { double scale = alpha / Math.exp(frac * beta); - int depth = (int) (-Math.log(scale) * gamma); + int depth = (int)(-Math.log(scale) * gamma); recalc(target, isdouble, scale, arg, depth); } @@ -304,4 +320,8 @@ public class Mandelbrot extends Application { .setPixels(0, 0, width, height, PixelFormat.getByteBgraInstance(), buffer, width * 4); } } + + public static void main(String[] args) { + launch(args); + } } diff --git a/src/notzed.zcl/classes/api/Callback.java b/src/notzed.zcl/classes/api/Callback.java index 936ae55..e688f56 100644 --- a/src/notzed.zcl/classes/api/Callback.java +++ b/src/notzed.zcl/classes/api/Callback.java @@ -35,6 +35,11 @@ public class Callback extends Native implements AutoCloseable { this.func = func; } + @Override + public String toString() { + return func == null ? "Callback.NULL" : func.toString(); + } + /* * A callback that resolve to MemoryAddress.NULL. * This can be released safely any number of times. diff --git a/src/notzed.zcl/classes/api/Memory.java b/src/notzed.zcl/classes/api/Memory.java index 8107d6c..a1d008e 100644 --- a/src/notzed.zcl/classes/api/Memory.java +++ b/src/notzed.zcl/classes/api/Memory.java @@ -87,6 +87,7 @@ public class Memory { final MemorySegment stack; final MemoryAddress base; long sp; + Thread origin; Stack(MemoryAddress p, long size) { super(p); @@ -94,6 +95,12 @@ public class Memory { stack = ForeignUnsafe.ofNativeUnchecked(addr(), size); base = stack.baseAddress(); sp = size; + + origin = Thread.currentThread(); + } + + public String toString() { + return "api.Memory$Stack thread=" + origin.toString(); } private static void release(MemoryAddress p) { diff --git a/src/notzed.zcl/classes/api/Native.java b/src/notzed.zcl/classes/api/Native.java index f8a4dc7..5518b26 100644 --- a/src/notzed.zcl/classes/api/Native.java +++ b/src/notzed.zcl/classes/api/Native.java @@ -36,10 +36,16 @@ import java.lang.System.Logger.Level; /** * Base class for all native objects. - * + * * Handles instantiation and provides helper functions for native access. - * + * * Work in progress. + * + * For better safety the 'p' field should be the CHandle, and addr() would + * call get(). Otherwise one must not release ANY object which might ever + * be used again - including any objects returned by the getInfo(). However ... + * it's a trade-off and it's a lot of code to change. + * */ public class Native { @@ -671,22 +677,32 @@ public class Native { T o; boolean step = false; - if (dolog) - log().log(Level.DEBUG, () -> String.format(" resolv $%016x %s", Memory.toLong(p), create)); + //if (dolog) + // log().log(Level.DEBUG, () -> String.format(" resolv $%016x %s", Memory.toLong(p), create)); - // ??? who the fuck knows if this will work - if (p.offset() == 0) + if (Memory.toLong(p) == 0) return null; // Instantiation needs to be synchronized for obvious reasons. synchronized (map) { CHandle h = (CHandle) map.get(p); + String fmt; + if (h == null || (o = (T)(h.get())) == null) { o = create.apply(p); + + fmt = h == null ? " create $%016x %s" : " replac $%016x %s"; + h = new CHandle(o, references, p); map.put(h); step = true; + } else { + fmt = " exists $%016x %s"; + } + { + T x = o; + log().log(Level.DEBUG, () -> String.format(fmt, Memory.toLong(p), x.getClass().getName())); } } @@ -721,13 +737,15 @@ public class Native { WeakReference ref; synchronized (map) { - ref = map.remove(p); + //ref = map.remove(p); + ref = map.get(p); } if (ref != null) { if (dolog) log().log(Level.DEBUG, () -> String.format(" force $%016x %s", Memory.toLong(p), getClass().getName())); + ref.clear(); ref.enqueue(); } } @@ -850,6 +868,23 @@ public class Native { } } + public static void debugDumpReachable(String title) { + synchronized (map) { + System.out.println(title); + for (CHandle h: map.table) { + while (h != null) { + Native o = h.get(); + System.out.printf(" $%016x: %s %-40s %s\n", + Memory.toLong(h.p), + o == null ? "dead" : "live", + h.jtype.getName(), + o); + h = h.next; + } + } + } + } + /** * Lightweight pointer hashtable. *

diff --git a/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java b/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java index 2151e7d..9b11165 100644 --- a/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java +++ b/src/notzed.zcl/classes/au/notzed/zcl/CLPlatform.java @@ -56,11 +56,7 @@ public class CLPlatform extends CLObject { private static void release(MemoryAddress p) { // noop - } - - @Override - public void release() { - // noop + System.out.println("** release clplatform"); } @Override @@ -94,7 +90,7 @@ public class CLPlatform extends CLObject { res = (int)clGetPlatformIDs.invokeExact(0, MemoryAddress.NULL, lenp); if (res != 0) throw new CLRuntimeException(res); - + len = Native.getInt(lenp); list = frame.alloca(8 * len); @@ -201,16 +197,16 @@ public class CLPlatform extends CLObject { /** * Get the platform api versiom. - * + * * This may be compared to the version constants * {@link #VERSION_1_0}, {@link #VERSION_1_1}, and so on. - * + * * @return platform api version. */ public int getAPIVersion() { return apiVersion; } - + /** * get CL_PLATFORM_PROFILE. *