From: Phil Race Date: Mon, 23 Mar 2026 17:15:07 +0000 (+0000) Subject: [PATCH] 8378615: FFM Bound up call stub keeps JNI Global Ref to bound parameter X-Git-Tag: archive/raspbian/25.0.5_7ea-1+rpi1~4 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=d2fd9c2affb1021c41214a8960585b988dea0a50;p=openjdk-25.git [PATCH] 8378615: FFM Bound up call stub keeps JNI Global Ref to bound parameter From c6a20173a37ec56f3264d5a312543bdfc40ce3d2 Mon Sep 17 00:00:00 2001 Bug: https://bugs.openjdk.org/browse/JDK-8378615 Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/openjdk-25/+bug/2155650 Origin: upstream, https://github.com/openjdk/jdk/commit/c6a20173a37ec56f3264d5a312543bdfc40ce3d2 Reviewed-by: jdv, psadhukhan Reviewed-by: jdv, psadhukhan Gbp-Pq: Name jdk-8378615.diff --- diff --git a/src/java.desktop/share/classes/sun/font/HBShaper.java b/src/java.desktop/share/classes/sun/font/HBShaper.java index 3caa9f2bc..5b88e0af1 100644 --- a/src/java.desktop/share/classes/sun/font/HBShaper.java +++ b/src/java.desktop/share/classes/sun/font/HBShaper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -138,6 +138,7 @@ public class HBShaper { private static final MemorySegment get_h_advance_stub; private static final MemorySegment get_v_advance_stub; private static final MemorySegment get_contour_pt_stub; + private static final MemorySegment get_table_data_fn_stub; private static final MemorySegment store_layout_results_stub; @@ -220,6 +221,12 @@ public class HBShaper { jdk_hb_shape_handle = tmp4; Arena garena = Arena.global(); // creating stubs that exist until VM exit. + + get_table_data_fn_stub = getUpcallStub(garena, + "getFontTableData", // method name + JAVA_INT, // return type + JAVA_INT, ADDRESS); // arg types + FunctionDescriptor get_var_glyph_fd = getFunctionDescriptor(JAVA_INT, // return type ADDRESS, ADDRESS, JAVA_INT, JAVA_INT, ADDRESS, ADDRESS); // arg types MethodHandle get_var_glyph_mh = @@ -314,15 +321,9 @@ public class HBShaper { clusterHandle = getVarHandle(GlyphInfoLayout, "cluster"); } - - /* - * This is expensive but it is done just once per font. - * The unbound stub could be cached but the savings would - * be very low in the only case it is used. - */ @SuppressWarnings("restricted") - private static MemorySegment getBoundUpcallStub - (Arena arena, Class clazz, Object bindArg, String mName, + private static MemorySegment getUpcallStub + (Arena arena, String mName, MemoryLayout retType, MemoryLayout... argTypes) { try { @@ -331,10 +332,8 @@ public class HBShaper { FunctionDescriptor.ofVoid(argTypes) : FunctionDescriptor.of(retType, argTypes); MethodType mType = nativeDescriptor.toMethodType(); - mType = mType.insertParameterTypes(0, clazz); MethodHandle mh = MH_LOOKUP.findStatic(HBShaper.class, mName, mType); - MethodHandle bound_handle = mh.bindTo(bindArg); - return LINKER.upcallStub(bound_handle, nativeDescriptor, arena); + return LINKER.upcallStub(mh, nativeDescriptor, arena); } catch (IllegalAccessException | NoSuchMethodException e) { return null; } @@ -493,15 +492,16 @@ public class HBShaper { }); } - private static int getFontTableData(Font2D font2D, - int tag, - MemorySegment data_ptr_out) { + private static int getFontTableData(int tag, MemorySegment data_ptr_out) { /* * On return, the data_out_ptr will point to memory allocated by native malloc, * so it will be freed by the caller using native free - when it is * done with it. */ + + Font2D font2D = scopedVars.get().font(); + @SuppressWarnings("restricted") MemorySegment data_ptr = data_ptr_out.reinterpret(ADDRESS.byteSize()); if (tag == 0) { @@ -552,10 +552,6 @@ public class HBShaper { private static class FaceRef implements DisposerRecord { private Font2D font2D; private MemorySegment face; - // get_table_data_fn uses an Arena managed by GC, - // so we need to keep a reference to it here until - // this FaceRef is collected. - private MemorySegment get_table_data_fn; private FaceRef(Font2D font) { this.font2D = font; @@ -574,16 +570,7 @@ public class HBShaper { private void createFace() { try { - get_table_data_fn = getBoundUpcallStub(Arena.ofAuto(), - Font2D.class, - font2D, // bind arg - "getFontTableData", // method name - JAVA_INT, // return type - JAVA_INT, ADDRESS); // arg types - if (get_table_data_fn == null) { - return; - } - face = (MemorySegment)create_face_handle.invokeExact(get_table_data_fn); + face = (MemorySegment)create_face_handle.invokeExact(get_table_data_fn_stub); } catch (Throwable t) { } }