Skip to content

Commit 113d783

Browse files
committed
add FFM.Critical to annotate a function as critical (direct access to Java Heap)
1 parent 0c62ae0 commit 113d783

4 files changed

Lines changed: 94 additions & 2 deletions

File tree

src/javaforce/ffm/Critical.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package javaforce.ffm;
2+
3+
/** JNI2FFM annotation.
4+
*
5+
* Indicates native function is critical.
6+
*
7+
* See Linker.Option.critical()
8+
*
9+
* @author pquiring
10+
*/
11+
12+
import java.lang.annotation.ElementType;
13+
import java.lang.annotation.Retention;
14+
import java.lang.annotation.RetentionPolicy;
15+
import java.lang.annotation.Target;
16+
17+
@Retention(RetentionPolicy.SOURCE)
18+
@Target(ElementType.METHOD)
19+
public @interface Critical {}

src/javaforce/ffm/FFM.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,34 @@ public MethodHandle getFunctionPtr(String name, FunctionDescriptor fd) {
190190
}
191191
}
192192

193+
/** Get native MethodHandle for specified function name with FunctionDescriptor where the symbol is a function pointer. */
194+
public MethodHandle getFunctionPtrCritical(String name, FunctionDescriptor fd) {
195+
if (debug) JFLog.log("FFM:getFunctionPtr:" + name);
196+
try {
197+
MemorySegment addr = lookup.findOrThrow(name);
198+
if (addr == null || addr.address() == 0) {
199+
JFLog.log("FFM:FunctionPtr not found(1):" + name + "=" + addr);
200+
return null;
201+
}
202+
//symbols have zero length, need to reinterpret as a pointer
203+
addr = addr.reinterpret(ADDRESS_SIZE);
204+
if (addr == null || addr.address() == 0) {
205+
JFLog.log("FFM:FunctionPtr not found(2):" + name + "=" + addr);
206+
return null;
207+
}
208+
//now get the contents of the pointer
209+
addr = addr.get(ADDRESS, 0);
210+
if (addr == null || addr.address() == 0) {
211+
JFLog.log("FFM:FunctionPtr not found(3):" + name + "=" + addr);
212+
return null;
213+
}
214+
return linker.downcallHandle(addr, fd, Linker.Option.critical(true));
215+
} catch (Exception e) {
216+
JFLog.logTrace("FFM:FunctionPtr not found(e):" + name);
217+
return null;
218+
}
219+
}
220+
193221
//upcall helpers
194222

195223
private static ValueLayout classToValueLayout(Class<?> cls) {
@@ -333,6 +361,44 @@ public static MemorySegment toMemory(Arena arena, MemorySegment[] ptrs) {
333361
return array;
334362
}
335363

364+
//array helpers (critical)
365+
366+
/** Create native array from float[] */
367+
public static MemorySegment toMemory(float[] m) {
368+
if (m == null) return MemorySegment.NULL;
369+
return MemorySegment.ofArray(m);
370+
}
371+
372+
/** Create native array from double[] */
373+
public static MemorySegment toMemory(double[] m) {
374+
if (m == null) return MemorySegment.NULL;
375+
return MemorySegment.ofArray(m);
376+
}
377+
378+
/** Create native array from long[] */
379+
public static MemorySegment toMemory(long[] m) {
380+
if (m == null) return MemorySegment.NULL;
381+
return MemorySegment.ofArray(m);
382+
}
383+
384+
/** Create native array from int[] */
385+
public static MemorySegment toMemory(int[] m) {
386+
if (m == null) return MemorySegment.NULL;
387+
return MemorySegment.ofArray(m);
388+
}
389+
390+
/** Create native array from short[] */
391+
public static MemorySegment toMemory(short[] m) {
392+
if (m == null) return MemorySegment.NULL;
393+
return MemorySegment.ofArray(m);
394+
}
395+
396+
/** Create native array from byte[] */
397+
public static MemorySegment toMemory(byte[] m) {
398+
if (m == null) return MemorySegment.NULL;
399+
return MemorySegment.ofArray(m);
400+
}
401+
336402
private static final long JAVA_LONG_SIZE = JAVA_LONG.byteSize();
337403
private static final long JAVA_INT_SIZE = JAVA_INT.byteSize();
338404
private static final long JAVA_SHORT_SIZE = JAVA_SHORT.byteSize();

src/javaforce/ffm/JNI2FFM.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public static void main(String[] args) {
6161

6262
boolean flag_nofreestring = false;
6363
boolean flag_nocopyback = false;
64+
boolean flag_critical = false;
6465

6566
try {
6667

@@ -117,6 +118,10 @@ public static void main(String[] args) {
117118
flag_nocopyback = true;
118119
continue;
119120
}
121+
if (ln.equals("@Critical")) {
122+
flag_critical = true;
123+
continue;
124+
}
120125
if (!ln.startsWith("public native")) continue;
121126
//public native void glActiveTexture(int i1);
122127
ln = ln.substring(14, ln.length() - 1);
@@ -177,7 +182,7 @@ public static void main(String[] args) {
177182
method.append(func_name);
178183
method.append(".invokeExact(");
179184

180-
ctor2.append(" " + func_name + " = ffm.getFunctionPtr(\"_" + func_name + "\", ffm.getFunctionDesciptor");
185+
ctor2.append(" " + func_name + " = ffm.getFunctionPtr" + (flag_critical ? "Critical": "") + "(\"_" + func_name + "\", ffm.getFunctionDesciptor");
181186
boolean first = true;
182187
boolean first_ctor = true;
183188
if (isRetVoid) {
@@ -228,7 +233,7 @@ public static void main(String[] args) {
228233
if (isArray) {
229234
array_names.add(arg_name);
230235
String segment_name = "_array_" + arg_name;
231-
arrays.append("MemorySegment " + segment_name + " = FFM.toMemory(arena, " + arg_name + ");");
236+
arrays.append("MemorySegment " + segment_name + " = FFM.toMemory(" + (flag_critical ? "" : "arena, ") + arg_name + ");");
232237
method.append(segment_name);
233238
arena_needed = true;
234239
} else {
@@ -306,6 +311,7 @@ public static void main(String[] args) {
306311
}
307312
flag_nofreestring = false;
308313
flag_nocopyback = false;
314+
flag_critical = false;
309315
}
310316
ctor.append(" return true;\n");
311317
ctor.append(" }\n");

src/javaforce/jni/MediaJNI.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77

88
import javaforce.api.*;
9+
import javaforce.ffm.*;
910
import javaforce.media.*;
1011

1112
public class MediaJNI implements MediaAPI {

0 commit comments

Comments
 (0)