Skip to content

Commit 73baadc

Browse files
mcimadamoreJornVerneeminborg
committed
8295044: Implementation of Foreign Function and Memory API (Second Preview)
Co-authored-by: Jorn Vernee <jvernee@openjdk.org> Co-authored-by: Per Minborg <pminborg@openjdk.org> Co-authored-by: Maurizio Cimadamore <mcimadamore@openjdk.org> Reviewed-by: jvernee, pminborg, psandoz, alanb, sundar
1 parent bd38188 commit 73baadc

File tree

252 files changed

+9209
-7877
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

252 files changed

+9209
-7877
lines changed

src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -210,23 +210,7 @@ void DowncallStubGenerator::generate() {
210210
__ blr(_abi._target_addr_reg);
211211
// this call is assumed not to have killed rthread
212212

213-
if (!_needs_return_buffer) {
214-
// Unpack native results.
215-
switch (_ret_bt) {
216-
case T_BOOLEAN: __ c2bool(r0); break;
217-
case T_CHAR : __ ubfx(r0, r0, 0, 16); break;
218-
case T_BYTE : __ sbfx(r0, r0, 0, 8); break;
219-
case T_SHORT : __ sbfx(r0, r0, 0, 16); break;
220-
case T_INT : __ sbfx(r0, r0, 0, 32); break;
221-
case T_DOUBLE :
222-
case T_FLOAT :
223-
// Result is in v0 we'll save as needed
224-
break;
225-
case T_VOID: break;
226-
case T_LONG: break;
227-
default : ShouldNotReachHere();
228-
}
229-
} else {
213+
if (_needs_return_buffer) {
230214
assert(ret_buf_addr_sp_offset != -1, "no return buffer addr spill");
231215
__ ldr(tmp1, Address(sp, ret_buf_addr_sp_offset));
232216
int offset = 0;

src/hotspot/cpu/x86/downcallLinker_x86_64.cpp

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -211,24 +211,7 @@ void DowncallStubGenerator::generate() {
211211
__ call(_abi._target_addr_reg);
212212
// this call is assumed not to have killed r15_thread
213213

214-
if (!_needs_return_buffer) {
215-
// FIXME: this assumes we return in rax/xmm0, which might not be the case
216-
// Unpack native results.
217-
switch (_ret_bt) {
218-
case T_BOOLEAN: __ c2bool(rax); break;
219-
case T_CHAR : __ movzwl(rax, rax); break;
220-
case T_BYTE : __ sign_extend_byte (rax); break;
221-
case T_SHORT : __ sign_extend_short(rax); break;
222-
case T_INT : /* nothing to do */ break;
223-
case T_DOUBLE :
224-
case T_FLOAT :
225-
// Result is in xmm0 we'll save as needed
226-
break;
227-
case T_VOID: break;
228-
case T_LONG: break;
229-
default : ShouldNotReachHere();
230-
}
231-
} else {
214+
if (_needs_return_buffer) {
232215
assert(ret_buf_addr_rsp_offset != -1, "no return buffer addr spill");
233216
__ movptr(rscratch1, Address(rsp, ret_buf_addr_rsp_offset));
234217
int offset = 0;

src/hotspot/share/ci/ciField.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ static bool trust_final_non_static_fields(ciInstanceKlass* holder) {
225225
// Even if general trusting is disabled, trust system-built closures in these packages.
226226
if (holder->is_in_package("java/lang/invoke") || holder->is_in_package("sun/invoke") ||
227227
holder->is_in_package("java/lang/reflect") || holder->is_in_package("jdk/internal/reflect") ||
228-
holder->is_in_package("jdk/internal/foreign") || holder->is_in_package("java/lang/foreign") ||
228+
holder->is_in_package("jdk/internal/foreign/layout") || holder->is_in_package("jdk/internal/foreign") ||
229229
holder->is_in_package("jdk/internal/vm/vector") || holder->is_in_package("jdk/incubator/vector") ||
230230
holder->is_in_package("java/lang"))
231231
return true;

src/java.base/share/classes/java/lang/Module.java

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@
5252
import java.util.stream.Collectors;
5353
import java.util.stream.Stream;
5454

55+
import jdk.internal.javac.PreviewFeature;
5556
import jdk.internal.loader.BuiltinClassLoader;
5657
import jdk.internal.loader.BootLoader;
5758
import jdk.internal.loader.ClassLoaders;
5859
import jdk.internal.misc.CDS;
60+
import jdk.internal.module.ModuleBootstrap;
5961
import jdk.internal.module.ModuleLoaderMap;
6062
import jdk.internal.module.ServicesCatalog;
6163
import jdk.internal.module.Resources;
@@ -256,25 +258,77 @@ public ModuleLayer getLayer() {
256258
/**
257259
* Update this module to allow access to restricted methods.
258260
*/
259-
Module implAddEnableNativeAccess() {
261+
synchronized Module implAddEnableNativeAccess() {
260262
enableNativeAccess = true;
261263
return this;
262264
}
263265

264266
/**
265-
* Update all unnamed modules to allow access to restricted methods.
267+
* Returns {@code true} if this module can access
268+
* <a href="foreign/package-summary.html#restricted"><em>restricted</em></a> methods.
269+
*
270+
* @since 20
271+
*
272+
* @return {@code true} if this module can access <em>restricted</em> methods.
266273
*/
267-
static void implAddEnableNativeAccessAllUnnamed() {
268-
ALL_UNNAMED_MODULE.enableNativeAccess = true;
274+
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
275+
public boolean isNativeAccessEnabled() {
276+
Module target = moduleForNativeAccess();
277+
synchronized(target) {
278+
return target.enableNativeAccess;
279+
}
269280
}
270281

282+
// Returns the Module object that holds the enableNativeAccess
283+
// flag for this module.
284+
private Module moduleForNativeAccess() {
285+
return isNamed() ? this : ALL_UNNAMED_MODULE;
286+
}
287+
288+
// This is invoked from Reflection.ensureNativeAccess
289+
void ensureNativeAccess(Class<?> owner, String methodName) {
290+
// The target module whose enableNativeAccess flag is ensured
291+
Module target = moduleForNativeAccess();
292+
// racy read of the enable native access flag
293+
boolean isNativeAccessEnabled = target.enableNativeAccess;
294+
if (!isNativeAccessEnabled) {
295+
synchronized (target) {
296+
// safe read of the enableNativeAccess of the target module
297+
isNativeAccessEnabled = target.enableNativeAccess;
298+
299+
// check again with the safely read flag
300+
if (isNativeAccessEnabled) {
301+
// another thread beat us to it - nothing to do
302+
return;
303+
} else if (ModuleBootstrap.hasEnableNativeAccessFlag()) {
304+
throw new IllegalCallerException("Illegal native access from: " + this);
305+
} else {
306+
// warn and set flag, so that only one warning is reported per module
307+
String cls = owner.getName();
308+
String mtd = cls + "::" + methodName;
309+
String mod = isNamed() ? "module " + getName() : "the unnamed module";
310+
String modflag = isNamed() ? getName() : "ALL-UNNAMED";
311+
System.err.printf("""
312+
WARNING: A restricted method in %s has been called
313+
WARNING: %s has been called by %s
314+
WARNING: Use --enable-native-access=%s to avoid a warning for this module
315+
%n""", cls, mtd, mod, modflag);
316+
317+
// set the flag
318+
target.enableNativeAccess = true;
319+
}
320+
}
321+
}
322+
}
323+
324+
271325
/**
272-
* Returns true if module m can access restricted methods.
326+
* Update all unnamed modules to allow access to restricted methods.
273327
*/
274-
boolean implIsEnableNativeAccess() {
275-
return isNamed() ?
276-
enableNativeAccess :
277-
ALL_UNNAMED_MODULE.enableNativeAccess;
328+
static void implAddEnableNativeAccessToAllUnnamed() {
329+
synchronized (ALL_UNNAMED_MODULE) {
330+
ALL_UNNAMED_MODULE.enableNativeAccess = true;
331+
}
278332
}
279333

280334
// --

src/java.base/share/classes/java/lang/ModuleLayer.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,17 @@
4444
import java.util.stream.Collectors;
4545
import java.util.stream.Stream;
4646

47+
import jdk.internal.javac.PreviewFeature;
4748
import jdk.internal.loader.ClassLoaderValue;
4849
import jdk.internal.loader.Loader;
4950
import jdk.internal.loader.LoaderPool;
5051
import jdk.internal.module.ServicesCatalog;
5152
import jdk.internal.misc.CDS;
53+
import jdk.internal.reflect.CallerSensitive;
54+
import jdk.internal.reflect.Reflection;
5255
import jdk.internal.vm.annotation.Stable;
5356
import sun.security.util.SecurityConstants;
5457

55-
5658
/**
5759
* A layer of modules in the Java virtual machine.
5860
*
@@ -297,6 +299,39 @@ public Controller addOpens(Module source, String pn, Module target) {
297299
source.implAddOpens(pn, target);
298300
return this;
299301
}
302+
303+
/**
304+
* Enables native access for a module in the layer if the caller's module
305+
* has native access.
306+
*
307+
* <p> This method is <a href="foreign/package-summary.html#restricted"><em>restricted</em></a>.
308+
* Restricted methods are unsafe, and, if used incorrectly, their use might crash
309+
* the JVM or, worse, silently result in memory corruption. Thus, clients should refrain
310+
* from depending on restricted methods, and use safe and supported functionalities,
311+
* where possible.
312+
*
313+
* @param target
314+
* The module to update
315+
*
316+
* @return This controller
317+
*
318+
* @throws IllegalArgumentException
319+
* If {@code target} is not in the module layer
320+
*
321+
* @throws IllegalCallerException
322+
* If the caller is in a module that does not have native access enabled
323+
*
324+
* @since 20
325+
*/
326+
@PreviewFeature(feature=PreviewFeature.Feature.FOREIGN)
327+
@CallerSensitive
328+
public Controller enableNativeAccess(Module target) {
329+
ensureInLayer(target);
330+
Reflection.ensureNativeAccess(Reflection.getCallerClass(), Module.class,
331+
"enableNativeAccess");
332+
target.implAddEnableNativeAccess();
333+
return this;
334+
}
300335
}
301336

302337

src/java.base/share/classes/java/lang/System.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2437,11 +2437,11 @@ public boolean isReflectivelyOpened(Module m, String pn, Module other) {
24372437
public Module addEnableNativeAccess(Module m) {
24382438
return m.implAddEnableNativeAccess();
24392439
}
2440-
public void addEnableNativeAccessAllUnnamed() {
2441-
Module.implAddEnableNativeAccessAllUnnamed();
2440+
public void addEnableNativeAccessToAllUnnamed() {
2441+
Module.implAddEnableNativeAccessToAllUnnamed();
24422442
}
2443-
public boolean isEnableNativeAccess(Module m) {
2444-
return m.implIsEnableNativeAccess();
2443+
public void ensureNativeAccess(Module m, Class<?> owner, String methodName) {
2444+
m.ensureNativeAccess(owner, methodName);
24452445
}
24462446
public ServicesCatalog getServicesCatalog(ModuleLayer layer) {
24472447
return layer.getServicesCatalog();

0 commit comments

Comments
 (0)