diff --git a/common.json b/common.json index 3da1bfc1ddf8..feda5f3154b8 100644 --- a/common.json +++ b/common.json @@ -8,7 +8,7 @@ "COMMENT.jdks": "When adding or removing JDKs keep in sync with JDKs in ci/common.jsonnet", "jdks": { - "galahad-jdk": {"name": "jpg-jdk", "version": "25", "build_id": "jdk-25+26-3156", "platformspecific": true, "extrabundles": ["static-libs"]}, + "galahad-jdk": {"name": "jpg-jdk", "version": "25", "build_id": "jdk-25+26-3319", "platformspecific": true, "extrabundles": ["static-libs"]}, "oraclejdk17": {"name": "jpg-jdk", "version": "17.0.7", "build_id": "jdk-17.0.7+8", "platformspecific": true, "extrabundles": ["static-libs"]}, "labsjdk-ce-17": {"name": "labsjdk", "version": "ce-17.0.7+4-jvmci-23.1-b02", "platformspecific": true }, @@ -45,13 +45,13 @@ "oraclejdk24": {"name": "jpg-jdk", "version": "24", "build_id": "jdk-24.0.1+9", "platformspecific": true, "extrabundles": ["static-libs"]}, - "oraclejdk-latest": {"name": "jpg-jdk", "version": "25", "build_id": "jdk-25+25", "platformspecific": true, "extrabundles": ["static-libs"]}, - "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-25+25-jvmci-b01", "platformspecific": true }, - "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-25+25-jvmci-b01-debug", "platformspecific": true }, - "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-25+25-jvmci-b01-sulong", "platformspecific": true }, - "labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-25+25-jvmci-b01", "platformspecific": true }, - "labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-25+25-jvmci-b01-debug", "platformspecific": true }, - "labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-25+25-jvmci-b01-sulong", "platformspecific": true } + "oraclejdk-latest": {"name": "jpg-jdk", "version": "25", "build_id": "jdk-25+26", "platformspecific": true, "extrabundles": ["static-libs"]}, + "labsjdk-ce-latest": {"name": "labsjdk", "version": "ce-25+26-jvmci-b01", "platformspecific": true }, + "labsjdk-ce-latestDebug": {"name": "labsjdk", "version": "ce-25+26-jvmci-b01-debug", "platformspecific": true }, + "labsjdk-ce-latest-llvm": {"name": "labsjdk", "version": "ce-25+26-jvmci-b01-sulong", "platformspecific": true }, + "labsjdk-ee-latest": {"name": "labsjdk", "version": "ee-25+26-jvmci-b01", "platformspecific": true }, + "labsjdk-ee-latestDebug": {"name": "labsjdk", "version": "ee-25+26-jvmci-b01-debug", "platformspecific": true }, + "labsjdk-ee-latest-llvm": {"name": "labsjdk", "version": "ee-25+26-jvmci-b01-sulong", "platformspecific": true } }, "eclipse": { diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/replacements/test/MathCbrtTest.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/replacements/test/MathCbrtTest.java new file mode 100644 index 000000000000..0c9594542a2d --- /dev/null +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/replacements/test/MathCbrtTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2025, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.graal.compiler.replacements.test; + +import org.junit.Test; + +import jdk.graal.compiler.jtt.JTTTest; + +public class MathCbrtTest extends JTTTest { + + public double cbrt(double d) { + return Math.cbrt(d); + } + + @Test + public void testCbrt() { + for (double d = -3.0d; d <= 3.0D; d += 0.01D) { + test("cbrt", d); + } + + double[] inputs = {Math.PI / 2, Math.PI, -1.0D, Double.MAX_VALUE, Double.MIN_VALUE, Double.NaN, Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY, + Double.longBitsToDouble(0x7fffffffffffffffL), Double.longBitsToDouble(0xffffffffffffffffL)}; + for (double d : inputs) { + test("cbrt", d); + } + } +} diff --git a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/replacements/test/StandardMethodSubstitutionsTest.java b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/replacements/test/StandardMethodSubstitutionsTest.java index abb68113bda6..2b9ff75f2d9f 100644 --- a/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/replacements/test/StandardMethodSubstitutionsTest.java +++ b/compiler/src/jdk.graal.compiler.test/src/jdk/graal/compiler/replacements/test/StandardMethodSubstitutionsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -53,6 +53,7 @@ public class StandardMethodSubstitutionsTest extends MethodSubstitutionTest { public void testMathSubstitutions() { assertInGraph(assertNotInGraph(testGraph("mathAbs"), IfNode.class), AbsNode.class); // Java double value = 34567.891D; + testGraph("mathCos"); testGraph("mathLog"); testGraph("mathLog10"); @@ -60,10 +61,13 @@ public void testMathSubstitutions() { testGraph("mathSqrt"); testGraph("mathTan"); testGraph("mathAll"); - if (getReplacements().hasSubstitution(getResolvedJavaMethod(Math.class, "tanh"), getInitialOptions())) { testGraph("mathTanh"); } + if (getReplacements().hasSubstitution(getResolvedJavaMethod(Math.class, "cbrt"), getInitialOptions())) { + testGraph("mathCbrt"); + } + testGraph("mathCbrt"); test("mathCos", value); test("mathLog", value); @@ -72,6 +76,7 @@ public void testMathSubstitutions() { test("mathSqrt", value); test("mathTan", value); test("mathTanh", value); + test("mathCbrt", value); test("mathAll", value); } @@ -141,6 +146,10 @@ public static double mathTanh(double value) { return Math.tanh(value); } + public static double mathCbrt(double value) { + return Math.cbrt(value); + } + public static double mathAll(double value) { return Math.sqrt(value) + Math.log(value) + Math.log10(value) + Math.sin(value) + Math.cos(value) + Math.tan(value); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/amd64/AMD64Assembler.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/amd64/AMD64Assembler.java index befb46e90cfd..2d6acfb472c0 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/amd64/AMD64Assembler.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/amd64/AMD64Assembler.java @@ -5036,6 +5036,10 @@ public final void incq(AMD64Address dst) { AMD64MOp.INC.emit(this, OperandSize.QWORD, dst); } + public final void movapd(Register dst, AMD64Address src) { + SSEOp.MOVAPD.emit(this, OperandSize.PD, dst, src); + } + public final void movapd(Register dst, Register src) { SSEOp.MOVAPD.emit(this, OperandSize.PD, dst, src); } @@ -5299,6 +5303,10 @@ public final void orl(Register dst, int imm32) { AMD64BinaryArithmetic.OR.getMIOpcode(OperandSize.DWORD, isByte(imm32)).emit(this, OperandSize.DWORD, dst, imm32); } + public final void orpd(Register dst, Register src) { + SSEOp.OR.emit(this, OperandSize.PD, dst, src); + } + public final void orq(Register dst, Register src) { AMD64BinaryArithmetic.OR.rmOp.emit(this, OperandSize.QWORD, dst, src); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java index c826df98f008..df33b5b53816 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/amd64/AMD64ArithmeticLIRGenerator.java @@ -135,6 +135,7 @@ import jdk.graal.compiler.lir.amd64.AMD64CountTrailingZerosOp; import jdk.graal.compiler.lir.amd64.AMD64FloatToHalfFloatOp; import jdk.graal.compiler.lir.amd64.AMD64HalfFloatToFloatOp; +import jdk.graal.compiler.lir.amd64.AMD64MathCbrtOp; import jdk.graal.compiler.lir.amd64.AMD64MathCopySignOp; import jdk.graal.compiler.lir.amd64.AMD64MathCosOp; import jdk.graal.compiler.lir.amd64.AMD64MathExpOp; @@ -1311,6 +1312,11 @@ public Value emitMathExp(Value input) { return new AMD64MathExpOp().emitLIRWrapper(getLIRGen(), input); } + @Override + public Value emitMathCbrt(Value input) { + return new AMD64MathCbrtOp().emitLIRWrapper(getLIRGen(), input); + } + @Override public Value emitMathPow(Value x, Value y) { return new AMD64MathPowOp().emitLIRWrapper(getLIRGen(), x, y); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java index 991f7e7496d1..24f529a66095 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/GraalHotSpotVMConfig.java @@ -682,6 +682,7 @@ private long getZGCAddressField(String name) { public final long arithmeticLogAddress = getFieldValue("CompilerToVM::Data::dlog", Long.class, "address"); public final long arithmeticLog10Address = getFieldValue("CompilerToVM::Data::dlog10", Long.class, "address"); public final long arithmeticPowAddress = getFieldValue("CompilerToVM::Data::dpow", Long.class, "address"); + public final long arithmeticCbrtAddress = getFieldValue("CompilerToVM::Data::dcbrt", Long.class, "address"); public final long fremAddress = getAddress("SharedRuntime::frem"); public final long dremAddress = getAddress("SharedRuntime::drem"); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java index 4e0cfe180f2c..96cdfc3ad1a1 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/JVMCIVersionCheck.java @@ -55,8 +55,8 @@ public final class JVMCIVersionCheck { */ private static final Map> JVMCI_MIN_VERSIONS = Map.of( "25", Map.of( - "Oracle Corporation", createLabsJDKVersion("25+25", 1), - DEFAULT_VENDOR_ENTRY, createLabsJDKVersion("25+25", 1))); + "Oracle Corporation", createLabsJDKVersion("25+26", 1), + DEFAULT_VENDOR_ENTRY, createLabsJDKVersion("25+26", 1))); private static final int NA = 0; /** * Minimum Java release supported by Graal. diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetResolvedJavaMethod.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetResolvedJavaMethod.java index 140abd0b5a7c..0baf22212ca9 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetResolvedJavaMethod.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetResolvedJavaMethod.java @@ -115,6 +115,11 @@ public boolean isDefault() { throw new UnsupportedOperationException(); } + @Override + public boolean isDeclared() { + throw new UnsupportedOperationException(); + } + @Override public boolean isClassInitializer() { throw new UnsupportedOperationException(); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetResolvedJavaType.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetResolvedJavaType.java index f33cf65bf669..be9d32a8c2fd 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetResolvedJavaType.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/SnippetResolvedJavaType.java @@ -26,6 +26,7 @@ import java.lang.annotation.Annotation; import java.util.Arrays; +import java.util.List; import java.util.Objects; import jdk.graal.compiler.core.common.LibGraalSupport; @@ -318,6 +319,11 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { return methods.clone(); } + @Override + public List getAllMethods(boolean forceLink) { + throw new UnsupportedOperationException(); + } + @Override public ResolvedJavaMethod getClassInitializer() { throw new UnsupportedOperationException(); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java index d36e373c9a5f..03ea6b157f54 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64HotSpotForeignCallsProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -33,6 +33,7 @@ import static jdk.graal.compiler.hotspot.HotSpotForeignCallLinkage.RegisterEffect.DESTROYS_ALL_CALLER_SAVE_REGISTERS; import static jdk.graal.compiler.hotspot.meta.HotSpotForeignCallDescriptor.Transition.LEAF; import static jdk.graal.compiler.replacements.nodes.BinaryMathIntrinsicNode.BinaryOperation.POW; +import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.CBRT; import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.COS; import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.EXP; import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG; @@ -110,6 +111,7 @@ protected void registerMathStubs(GraalHotSpotVMConfig hotSpotVMConfig, HotSpotPr link(new AMD64MathStub(LOG, options, providers, registerStubCall(LOG.foreignCallSignature, LEAF, NO_SIDE_EFFECT, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS))); link(new AMD64MathStub(LOG10, options, providers, registerStubCall(LOG10.foreignCallSignature, LEAF, NO_SIDE_EFFECT, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS))); link(new AMD64MathStub(POW, options, providers, registerStubCall(POW.foreignCallSignature, LEAF, NO_SIDE_EFFECT, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS))); + link(new AMD64MathStub(CBRT, options, providers, registerStubCall(CBRT.foreignCallSignature, LEAF, NO_SIDE_EFFECT, COMPUTES_REGISTERS_KILLED, NO_LOCATIONS))); } else { super.registerMathStubs(hotSpotVMConfig, providers, options); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64MathStub.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64MathStub.java index b819a30855e5..4c70633a354b 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64MathStub.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/amd64/AMD64MathStub.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2025, 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 @@ -49,24 +49,16 @@ public AMD64MathStub(BinaryOperation operation, OptionValues options, HotSpotPro } private static String snippetName(UnaryOperation operation) { - switch (operation) { - case SIN: - return "sin"; - case COS: - return "cos"; - case TAN: - return "tan"; - case TANH: - return "tanh"; - case EXP: - return "exp"; - case LOG: - return "log"; - case LOG10: - return "log10"; - default: - throw GraalError.shouldNotReachHere("Unknown operation " + operation); // ExcludeFromJacocoGeneratedReport - } + return switch (operation) { + case SIN -> "sin"; + case COS -> "cos"; + case TAN -> "tan"; + case TANH -> "tanh"; + case EXP -> "exp"; + case LOG -> "log"; + case LOG10 -> "log10"; + case CBRT -> "cbrt"; + }; } private static String snippetName(BinaryOperation operation) { @@ -115,4 +107,9 @@ private static double exp(double value) { private static double pow(double value1, double value2) { return BinaryMathIntrinsicNode.compute(value1, value2, BinaryOperation.POW); } + + @Snippet + private static double cbrt(double value) { + return UnaryMathIntrinsicNode.compute(value, UnaryOperation.CBRT); + } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java index 59ceb0ace38d..f8cc456c57dc 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/HotSpotHostForeignCallsProvider.java @@ -103,6 +103,7 @@ import static jdk.graal.compiler.hotspot.stubs.UnwindExceptionToCallerStub.EXCEPTION_HANDLER_FOR_RETURN_ADDRESS; import static jdk.graal.compiler.nodes.java.ForeignCallDescriptors.REGISTER_FINALIZER; import static jdk.graal.compiler.replacements.nodes.BinaryMathIntrinsicNode.BinaryOperation.POW; +import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.CBRT; import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.COS; import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.EXP; import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG; @@ -706,6 +707,9 @@ protected void registerMathStubs(GraalHotSpotVMConfig hotSpotVMConfig, HotSpotPr if (hotSpotVMConfig.arithmeticTanhAddress != 0L) { registerForeignCall(createDescriptor(TANH.foreignCallSignature, LEAF, NO_SIDE_EFFECT, NO_LOCATIONS), hotSpotVMConfig.arithmeticTanhAddress, NativeCall); } + if (hotSpotVMConfig.arithmeticCbrtAddress != 0L) { + registerForeignCall(createDescriptor(CBRT.foreignCallSignature, LEAF, NO_SIDE_EFFECT, NO_LOCATIONS), hotSpotVMConfig.arithmeticCbrtAddress, NativeCall); + } } private void registerSnippetStubs(HotSpotProviders providers, OptionValues options) { diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/UnimplementedGraalIntrinsics.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/UnimplementedGraalIntrinsics.java index 96b3dba0c226..4d37d78ee974 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/UnimplementedGraalIntrinsics.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/meta/UnimplementedGraalIntrinsics.java @@ -154,6 +154,8 @@ public UnimplementedGraalIntrinsics(Architecture arch) { // HotSpot runtime does not implement C2Compiler::is_intrinsic_supported for the // following intrinsics properly add(ignore, + // JDK-8355644 + "java/lang/Math.cbrt(D)D", // JDK-8338694 "java/lang/Math.tanh(D)D", // JDK-8309130 diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/amd64/AMD64MathCbrtOp.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/amd64/AMD64MathCbrtOp.java new file mode 100644 index 000000000000..70c5b5a35c24 --- /dev/null +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/amd64/AMD64MathCbrtOp.java @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, Intel Corporation. All rights reserved. + * Intel Math Library (LIBM) Source Code + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.graal.compiler.lir.amd64; + +import static jdk.graal.compiler.lir.amd64.AMD64LIRHelper.pointerConstant; +import static jdk.graal.compiler.lir.amd64.AMD64LIRHelper.recordExternalAddress; +import static jdk.vm.ci.amd64.AMD64.r8; +import static jdk.vm.ci.amd64.AMD64.r9; +import static jdk.vm.ci.amd64.AMD64.rax; +import static jdk.vm.ci.amd64.AMD64.rcx; +import static jdk.vm.ci.amd64.AMD64.rdx; +import static jdk.vm.ci.amd64.AMD64.rsp; +import static jdk.vm.ci.amd64.AMD64.xmm0; +import static jdk.vm.ci.amd64.AMD64.xmm1; +import static jdk.vm.ci.amd64.AMD64.xmm2; +import static jdk.vm.ci.amd64.AMD64.xmm3; +import static jdk.vm.ci.amd64.AMD64.xmm4; +import static jdk.vm.ci.amd64.AMD64.xmm5; +import static jdk.vm.ci.amd64.AMD64.xmm6; +import static jdk.vm.ci.amd64.AMD64.xmm7; + +import jdk.graal.compiler.asm.Label; +import jdk.graal.compiler.asm.amd64.AMD64Address; +import jdk.graal.compiler.asm.amd64.AMD64Assembler.ConditionFlag; +import jdk.graal.compiler.asm.amd64.AMD64MacroAssembler; +import jdk.graal.compiler.core.common.Stride; +import jdk.graal.compiler.lir.LIRInstructionClass; +import jdk.graal.compiler.lir.SyncPort; +import jdk.graal.compiler.lir.asm.ArrayDataPointerConstant; +import jdk.graal.compiler.lir.asm.CompilationResultBuilder; + +/** + *
+ *                     ALGORITHM DESCRIPTION
+ *                     ---------------------
+ *
+ * x=2^{3*k+j} * 1.b1 b2 ... b5 b6 ... b52
+ * Let r=(x*2^{-3k-j} - 1.b1 b2 ... b5 1)* rcp[b1 b2 ..b5],
+ * where rcp[b1 b2 .. b5]=1/(1.b1 b2 b3 b4 b5 1) in double precision
+ * cbrt(2^j * 1. b1 b2 .. b5 1) is approximated as T[j][b1..b5]+D[j][b1..b5]
+ * (T stores the high 53 bits, D stores the low order bits)
+ * Result=2^k*T+(2^k*T*r)*P+2^k*D
+ * where P=p1+p2*r+..+p8*r^7
+ *
+ * Special cases:
+ *  cbrt(NaN) = quiet NaN
+ *  cbrt(+/-INF) = +/-INF
+ *  cbrt(+/-0) = +/-0
+ * 
+ */ +// @formatter:off +@SyncPort(from = "https://github.com/openjdk/jdk/blob/83cb0c6de5988de526545d0926c2c6ef60efc1c7/src/hotspot/cpu/x86/stubGenerator_x86_64_cbrt.cpp#L30-L364", + sha1 = "1cf43819053aac54cbe343f9b8a8bfcc3e3dd6c8") +// @formatter:on +public final class AMD64MathCbrtOp extends AMD64MathIntrinsicUnaryOp { + + public static final LIRInstructionClass TYPE = LIRInstructionClass.create(AMD64MathCbrtOp.class); + + public AMD64MathCbrtOp() { + super(TYPE, /* GPR */ rax, rcx, rdx, r8, r9, + /* XMM */ xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7); + } + + private static ArrayDataPointerConstant sigMask = pointerConstant(16, new int[]{ + 0x00000000, 0x000fc000 + }); + + private static ArrayDataPointerConstant expMask = pointerConstant(16, new int[]{ + 0x00000000, 0xbff00000 + }); + + private static ArrayDataPointerConstant expMsk2 = pointerConstant(16, new int[]{ + 0x00000000, 0xbff04000 + }); + + private static ArrayDataPointerConstant expMsk3 = pointerConstant(16, new int[]{ + 0xffffffff, 0x000fffff + }); + + private static ArrayDataPointerConstant scale63 = pointerConstant(16, new int[]{ + 0x00000000, 0x43e00000 + }); + + private static ArrayDataPointerConstant zeron = pointerConstant(16, new int[]{ + 0x00000000, 0x80000000 + }); + + private static ArrayDataPointerConstant inf = pointerConstant(16, new int[]{ + 0x00000000, 0x7ff00000 + }); + + private static ArrayDataPointerConstant negInf = pointerConstant(16, new int[]{ + 0x00000000, 0xfff00000 + }); + + private static ArrayDataPointerConstant coeffTable = pointerConstant(16, new int[]{ + 0x5c9cc8e7, 0xbf9036de, 0xd2b3183b, 0xbfa511e8, + }); + + private static ArrayDataPointerConstant coeffTable16 = pointerConstant(16, new int[]{ + 0x6221a247, 0xbf98090d, 0x1c71c71c, 0xbfbc71c7, + }); + + private static ArrayDataPointerConstant coeffTable32 = pointerConstant(16, new int[]{ + 0xd588f115, 0x3f93750a, 0x3c0ca458, 0x3faf9add + }); + + private static ArrayDataPointerConstant coeffTable48 = pointerConstant(16, new int[]{ + 0x3506ac12, 0x3f9ee711, 0x55555555, 0x3fd55555 + }); + + private static ArrayDataPointerConstant rcpTable = pointerConstant(16, new int[]{ + 0x1f81f820, 0xbfef81f8, 0xabf0b767, 0xbfee9131, 0x76b981db, 0xbfedae60, + 0x89039b0b, 0xbfecd856, 0x0381c0e0, 0xbfec0e07, 0xb4e81b4f, 0xbfeb4e81, + 0x606a63be, 0xbfea98ef, 0x951033d9, 0xbfe9ec8e, 0xfcd6e9e0, 0xbfe948b0, + 0x0f6bf3aa, 0xbfe8acb9, 0x18181818, 0xbfe81818, 0x8178a4c8, 0xbfe78a4c, + 0x5c0b8170, 0xbfe702e0, 0x16816817, 0xbfe68168, 0x60581606, 0xbfe60581, + 0x308158ed, 0xbfe58ed2, 0xeae2f815, 0xbfe51d07, 0xa052bf5b, 0xbfe4afd6, + 0x6562d9fb, 0xbfe446f8, 0xbce4a902, 0xbfe3e22c, 0x13813814, 0xbfe38138, + 0x4a2b10bf, 0xbfe323e3, 0x4d812ca0, 0xbfe2c9fb, 0xb8812735, 0xbfe27350, + 0x8121fb78, 0xbfe21fb7, 0xada2811d, 0xbfe1cf06, 0x11811812, 0xbfe18118, + 0x1135c811, 0xbfe135c8, 0x6be69c90, 0xbfe0ecf5, 0x0a6810a7, 0xbfe0a681, + 0xd2f1a9fc, 0xbfe0624d, 0x81020408, 0xbfe02040 + }); + + private static ArrayDataPointerConstant cbrtTable = pointerConstant(16, new int[]{ + 0x221d4c97, 0x3ff01539, 0x771a2e33, 0x3ff03f06, 0xe629d671, 0x3ff06800, + 0x8731deb2, 0x3ff09032, 0xb1bd64ac, 0x3ff0b7a4, 0x1024fb87, 0x3ff0de60, + 0xb0597000, 0x3ff1046c, 0x12a9ba9b, 0x3ff129d2, 0x36cdaf38, 0x3ff14e97, + 0xa772f507, 0x3ff172c2, 0x848001d3, 0x3ff1965a, 0x8c38c55d, 0x3ff1b964, + 0x236a0c45, 0x3ff1dbe6, 0x5cbb1f9f, 0x3ff1fde4, 0xff409042, 0x3ff21f63, + 0x8c6746e5, 0x3ff24069, 0x454bb99b, 0x3ff260f9, 0x2f8e7073, 0x3ff28117, + 0x19b4b6d0, 0x3ff2a0c7, 0x9f2263ec, 0x3ff2c00c, 0x2bb7fb78, 0x3ff2deeb, + 0xff1efbbc, 0x3ff2fd65, 0x2fccf6a2, 0x3ff31b80, 0xadc50708, 0x3ff3393c, + 0x451e4c2a, 0x3ff3569e, 0xa0554cde, 0x3ff373a7, 0x4a6d76ce, 0x3ff3905b, + 0xb0e756b6, 0x3ff3acbb, 0x258fa340, 0x3ff3c8cb, 0xe02ac0ce, 0x3ff3e48b, + 0x00000000, 0x3ff40000, 0x8d47800e, 0x3ff41b29, 0x4b34d9b2, 0x3ff44360, + 0x20906571, 0x3ff4780b, 0x3ee06706, 0x3ff4abac, 0x5da66b8d, 0x3ff4de50, + 0x420a5c07, 0x3ff51003, 0xd6fd11c1, 0x3ff540cf, 0x4260716b, 0x3ff570c0, + 0xf7a45f38, 0x3ff59fdd, 0xc83539df, 0x3ff5ce31, 0xf20966a4, 0x3ff5fbc3, + 0x2c8f1b70, 0x3ff6289c, 0xb4316dcf, 0x3ff654c1, 0x54a34e44, 0x3ff6803b, + 0x72182659, 0x3ff6ab0f, 0x118c08bc, 0x3ff6d544, 0xe0388d4a, 0x3ff6fede, + 0x3a4f645e, 0x3ff727e5, 0x31104114, 0x3ff7505c, 0x904cd549, 0x3ff77848, + 0xe36b2534, 0x3ff79fae, 0x79f4605b, 0x3ff7c693, 0x6bbca391, 0x3ff7ecfa, + 0x9cae7eb9, 0x3ff812e7, 0xc043c71d, 0x3ff8385e, 0x5cb41b9d, 0x3ff85d63, + 0xcde083db, 0x3ff881f8, 0x4802b8a8, 0x3ff8a622, 0xda25e5e4, 0x3ff8c9e2, + 0x706e1010, 0x3ff8ed3d, 0xd632b6df, 0x3ff91034, 0xb7f0cf2d, 0x3ff932cb, + 0xa517bf3a, 0x3ff95504, 0x34f8bb19, 0x3ff987af, 0x8337b317, 0x3ff9ca0a, + 0x09cc13d5, 0x3ffa0b17, 0xce6419ed, 0x3ffa4ae4, 0xa5567031, 0x3ffa8982, + 0x500ab570, 0x3ffac6fe, 0x97a15a17, 0x3ffb0364, 0x64671755, 0x3ffb3ec1, + 0xd288c46f, 0x3ffb791f, 0x44693be4, 0x3ffbb28a, 0x72eb6e31, 0x3ffbeb0a, + 0x7bf5f697, 0x3ffc22a9, 0xef6af983, 0x3ffc596f, 0xdac655a3, 0x3ffc8f65, + 0xd38ce8d9, 0x3ffcc492, 0x00b19367, 0x3ffcf8fe, 0x230f8709, 0x3ffd2cae, + 0x9d15208f, 0x3ffd5fa9, 0x79b6e505, 0x3ffd91f6, 0x72bf2302, 0x3ffdc39a, + 0xf68c1570, 0x3ffdf49a, 0x2d4c23b8, 0x3ffe24fd, 0xfdc5ec73, 0x3ffe54c5, + 0x11b81dbb, 0x3ffe83fa, 0xd9dbaf25, 0x3ffeb29d, 0x9191d374, 0x3ffee0b5, + 0x4245e4bf, 0x3fff0e45, 0xc68a9dd3, 0x3fff3b50, 0xccf922dc, 0x3fff67db, + 0xdad7a4a6, 0x3fff93e9, 0x4e8cc9cb, 0x3fffbf7e, 0x61e47cd3, 0x3fffea9c + }); + + private static ArrayDataPointerConstant dTable = pointerConstant(16, new int[]{ + 0xf173d5fa, 0x3c76ee36, 0x45055704, 0x3c95b62d, 0x51ee3f07, 0x3ca2545b, + 0xa7706e18, 0x3c9c65f4, 0xdf1025a1, 0x3c63b83f, 0xb8dec2c5, 0x3ca67428, + 0x03e33ea6, 0x3ca1823d, 0xa06e6c52, 0x3ca241d3, 0xefa7e815, 0x3ca8b4e1, + 0x4e754fd0, 0x3cadeac4, 0x3d7c04c0, 0x3c71cc82, 0xc264f127, 0x3c953dc9, + 0x34d5c5a7, 0x3c93b5f7, 0xb9a7b902, 0x3c7366a3, 0x6433dd6c, 0x3caac888, + 0x4f401711, 0x3c987a4c, 0x1bbe943f, 0x3c9fab9f, 0xfd6ac93c, 0x3ca0c4b5, + 0x766f1035, 0x3ca90835, 0x2ce13c95, 0x3ca09fd9, 0x8418c8d8, 0x3cadc143, + 0xff474261, 0x3c8dc87d, 0x5cd783d3, 0x3c8f8872, 0xe7d0c8aa, 0x3caec35d, + 0xdba49538, 0x3ca3943b, 0x2b203947, 0x3ca92195, 0xafe6f86c, 0x3c59f556, + 0x3195a5f9, 0x3caadc99, 0x3d770e65, 0x3ca41943, 0xa36b97ea, 0x3ca76b6e, + 0xaaaaaaab, 0x3bd46aaa, 0xfee9d063, 0x3c637d40, 0xf514c24e, 0x3c89f356, + 0x670030e9, 0x3c953f22, 0xa173c1cf, 0x3caea671, 0x3fbcc1dd, 0x3c841d58, + 0x29b9b818, 0x3c9648f0, 0xad202ab4, 0x3ca1a66d, 0xf2d6b269, 0x3ca7b07b, + 0x017dc4ad, 0x3c836a36, 0xd6b16f60, 0x3c8b726b, 0xc2bc701d, 0x3cabfe18, + 0x1dfe451f, 0x3c7e799d, 0x7e7b5452, 0x3caddf5a, 0xea15c5e5, 0x3c734d90, + 0xa6558f7b, 0x3c8f4cbb, 0x4f4d361a, 0x3c9d473a, 0xf06b5ecf, 0x3c87e2d6, + 0xdc49b5f3, 0x3ca5f6f5, 0x0f5a41f1, 0x3ca16024, 0xc062c2bc, 0x3ca3586c, + 0x0df45d94, 0x3ca0c6a9, 0xeef4e10b, 0x3ca2703c, 0x74215c62, 0x3ca99f3e, + 0x286f88d2, 0x3cafa5ef, 0xb7d00b1f, 0x3c99239e, 0x8ff8e50c, 0x3cabc642, + 0x0a756b50, 0x3ca33971, 0xbe93d5dc, 0x3c389058, 0x7b752d97, 0x3c8e08ee, + 0x0fff0a3f, 0x3c9a2fed, 0x37eac5df, 0x3ca42034, 0x6c4969df, 0x3ca35668, + 0xf5860fa5, 0x3ca082ae, 0x99b322b6, 0x3c62cf11, 0x933e42d8, 0x3c7ac44e, + 0x0761e377, 0x3c975f68, 0x4b704cc9, 0x3c7c5adf, 0xcb8394dc, 0x3ca0f9ae, + 0x3e08f0f9, 0x3c9158c1, 0xcfa3f556, 0x3c9c7516, 0xf6cb01cd, 0x3c91d9c1, + 0xe811c1da, 0x3c9da58f, 0xea9036db, 0x3c2dcd9d, 0xb18fab04, 0x3c8015a8, + 0x92316223, 0x3cad4c55, 0xbe291e10, 0x3c8c6a0d, 0xfc9476ab, 0x3c8c615d, + 0x9b9bca75, 0x3cace0d7, 0x7ecc4726, 0x3ca4614a, 0x312152ee, 0x3cacd427, + 0x811960ca, 0x3cac1ba1, 0xa557fd24, 0x3c6514ca, 0xf5cdf826, 0x3ca712cc, + 0x75cdbea6, 0x3c9d93a5, 0xf3f3450c, 0x3ca90aaf, 0x071ba369, 0x3c85382f, + 0xcf26ae90, 0x3ca87e97, 0x75933097, 0x3c86da5c, 0x309c2b19, 0x3ca61791, + 0x90d5990b, 0x3ca44210, 0xf22ac222, 0x3c9a5f49, 0x0411eef9, 0x3cac502e, + 0x839809ae, 0x3c93d12a, 0x468a4418, 0x3ca46c91, 0x088afcdb, 0x3c9f1c33 + }); + + @Override + public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { + // Registers: + // input: xmm0 + // scratch: xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7 + // rax, rdx, rcx + Label l2TAGPACKET001 = new Label(); + Label l2TAGPACKET101 = new Label(); + Label l2TAGPACKET201 = new Label(); + Label l2TAGPACKET301 = new Label(); + Label l2TAGPACKET401 = new Label(); + Label l2TAGPACKET501 = new Label(); + Label l2TAGPACKET601 = new Label(); + Label lB11 = new Label(); + Label lB12 = new Label(); + Label lB14 = new Label(); + + masm.bind(lB11); + masm.subq(rsp, 24); + masm.movsd(new AMD64Address(rsp), xmm0); + + masm.bind(lB12); + masm.movq(xmm7, xmm0); + masm.movl(rdx, 0x7ff00); + masm.movsd(xmm5, recordExternalAddress(crb, expMsk3)); + masm.movsd(xmm3, recordExternalAddress(crb, expMsk2)); + masm.psrlq(xmm7, 44); + masm.pextrw(rcx, xmm7, 0); + masm.movdl(rax, xmm7); + masm.movsd(xmm1, recordExternalAddress(crb, expMask)); + masm.movsd(xmm2, recordExternalAddress(crb, sigMask)); + masm.andl(rcx, 0xf8); + masm.leaq(r8, recordExternalAddress(crb, rcpTable)); + masm.movsd(xmm4, new AMD64Address(rcx, r8, Stride.S1)); + masm.movq(r9, rax); + masm.andl(rdx, rax); + // Branch only if |x| is denormalized + masm.cmplAndJcc(rdx, 0, ConditionFlag.Equal, l2TAGPACKET001, false); + // Branch only if |x| is INF or NaN + masm.cmplAndJcc(rdx, 0x7ff00, ConditionFlag.Equal, l2TAGPACKET101, false); + masm.shrl(rdx, 8); + masm.shrq(r9, 8); + masm.andpd(xmm2, xmm0); + masm.andpd(xmm0, xmm5); + masm.orpd(xmm3, xmm2); + masm.orpd(xmm1, xmm0); + masm.movapd(xmm5, recordExternalAddress(crb, coeffTable)); + masm.movl(rax, 0x1556); + masm.movapd(xmm6, recordExternalAddress(crb, coeffTable16)); + masm.mull(rdx); + masm.movq(rdx, r9); + masm.andq(r9, 0x7ff); + masm.shrl(rax, 14); + masm.andl(rdx, 0x800); + masm.subq(r9, rax); + masm.subq(r9, rax); + masm.subq(r9, rax); + masm.shlq(r9, 8); + masm.addl(rax, 0x2aa); + masm.orl(rax, rdx); + masm.movdl(xmm7, rax); + masm.addq(rcx, r9); + masm.psllq(xmm7, 52); + + masm.bind(l2TAGPACKET201); + masm.movapd(xmm2, recordExternalAddress(crb, coeffTable32)); + masm.movapd(xmm0, recordExternalAddress(crb, coeffTable48)); + masm.subsd(xmm1, xmm3); + masm.movq(xmm3, xmm7); + masm.leaq(r8, recordExternalAddress(crb, cbrtTable)); + masm.mulsd(xmm7, new AMD64Address(rcx, r8, Stride.S1)); + masm.mulsd(xmm1, xmm4); + masm.leaq(r8, recordExternalAddress(crb, dTable)); + masm.mulsd(xmm3, new AMD64Address(rcx, r8, Stride.S1)); + masm.movapd(xmm4, xmm1); + masm.unpcklpd(xmm1, xmm1); + masm.mulpd(xmm5, xmm1); + masm.mulpd(xmm6, xmm1); + masm.mulpd(xmm1, xmm1); + masm.addpd(xmm2, xmm5); + masm.addpd(xmm0, xmm6); + masm.mulpd(xmm2, xmm1); + masm.mulpd(xmm1, xmm1); + masm.mulsd(xmm4, xmm7); + masm.addpd(xmm0, xmm2); + masm.mulsd(xmm1, xmm0); + masm.unpckhpd(xmm0, xmm0); + masm.addsd(xmm0, xmm1); + masm.mulsd(xmm0, xmm4); + masm.addsd(xmm0, xmm3); + masm.addsd(xmm0, xmm7); + masm.jmp(lB14); + + masm.bind(l2TAGPACKET001); + masm.mulsd(xmm0, recordExternalAddress(crb, scale63)); + masm.movq(xmm7, xmm0); + masm.movl(rdx, 0x7ff00); + masm.psrlq(xmm7, 44); + masm.pextrw(rcx, xmm7, 0); + masm.movdl(rax, xmm7); + masm.andl(rcx, 0xf8); + masm.leaq(r8, recordExternalAddress(crb, rcpTable)); + masm.movsd(xmm4, new AMD64Address(rcx, r8, Stride.S1)); + masm.movq(r9, rax); + masm.andl(rdx, rax); + masm.shrl(rdx, 8); + masm.shrq(r9, 8); + // Branch only if |x| is zero + masm.cmplAndJcc(rdx, 0, ConditionFlag.Equal, l2TAGPACKET301, false); + masm.andpd(xmm2, xmm0); + masm.andpd(xmm0, xmm5); + masm.orpd(xmm3, xmm2); + masm.orpd(xmm1, xmm0); + masm.movapd(xmm5, recordExternalAddress(crb, coeffTable)); + masm.movl(rax, 0x1556); + masm.movapd(xmm6, recordExternalAddress(crb, coeffTable16)); + masm.mull(rdx); + masm.movq(rdx, r9); + masm.andq(r9, 0x7ff); + masm.shrl(rax, 14); + masm.andl(rdx, 0x800); + masm.subq(r9, rax); + masm.subq(r9, rax); + masm.subq(r9, rax); + masm.shlq(r9, 8); + masm.addl(rax, 0x295); + masm.orl(rax, rdx); + masm.movdl(xmm7, rax); + masm.addq(rcx, r9); + masm.psllq(xmm7, 52); + masm.jmp(l2TAGPACKET201); + + masm.bind(l2TAGPACKET301); + // Branch only if x is negative zero + masm.cmpqAndJcc(r9, 0, ConditionFlag.NotEqual, l2TAGPACKET401, false); + masm.xorpd(xmm0, xmm0); + masm.jmp(lB14); + + masm.bind(l2TAGPACKET401); + masm.movsd(xmm0, recordExternalAddress(crb, zeron)); + masm.jmp(lB14); + + masm.bind(l2TAGPACKET101); + masm.movl(rax, new AMD64Address(rsp, 4)); + masm.movl(rdx, new AMD64Address(rsp)); + masm.movl(rcx, rax); + masm.andl(rcx, 0x7fffffff); + // Branch only if |x| is NaN + masm.cmplAndJcc(rcx, 0x7ff00000, ConditionFlag.Above, l2TAGPACKET501, false); + // Branch only if |x| is NaN + masm.cmplAndJcc(rdx, 0, ConditionFlag.NotEqual, l2TAGPACKET501, false); + // Branch only if x is negative INF + masm.cmplAndJcc(rax, 0x7ff00000, ConditionFlag.NotEqual, l2TAGPACKET601, false); + masm.movsd(xmm0, recordExternalAddress(crb, inf)); + masm.jmp(lB14); + + masm.bind(l2TAGPACKET601); + masm.movsd(xmm0, recordExternalAddress(crb, negInf)); + masm.jmp(lB14); + + masm.bind(l2TAGPACKET501); + masm.movsd(xmm0, new AMD64Address(rsp)); + masm.addsd(xmm0, xmm0); + masm.movq(new AMD64Address(rsp, 8), xmm0); + + masm.bind(lB14); + masm.addq(rsp, 24); + } +} diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/gen/ArithmeticLIRGeneratorTool.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/gen/ArithmeticLIRGeneratorTool.java index 5612910057fe..dd21e5d7d1af 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/gen/ArithmeticLIRGeneratorTool.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/gen/ArithmeticLIRGeneratorTool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2025, 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 @@ -174,6 +174,11 @@ default Value emitMathExp(Value input) { throw GraalError.unimplemented("No specialized implementation available"); // ExcludeFromJacocoGeneratedReport } + @SuppressWarnings("unused") + default Value emitMathCbrt(Value input) { + throw GraalError.unimplemented("No specialized implementation available"); // ExcludeFromJacocoGeneratedReport + } + @SuppressWarnings("unused") default Value emitMathPow(Value x, Value y) { throw GraalError.unimplemented("No specialized implementation available"); // ExcludeFromJacocoGeneratedReport diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/schedule/SchedulePhase.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/schedule/SchedulePhase.java index 6fe8409e6422..ae787b152c58 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/schedule/SchedulePhase.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/phases/schedule/SchedulePhase.java @@ -735,16 +735,12 @@ protected static boolean isImplicitNullOpportunity(Node currentNode, HIRBlock bl if (!supportsImplicitNullChecks) { return false; } - if (currentNode instanceof FloatingReadNode) { - FloatingReadNode floatingReadNode = (FloatingReadNode) currentNode; + if (currentNode instanceof FloatingReadNode floatingReadNode) { Node pred = block.getBeginNode().predecessor(); - if (pred instanceof IfNode) { - IfNode ifNode = (IfNode) pred; - if (ifNode.condition() instanceof IsNullNode && ifNode.getTrueSuccessorProbability() == 0.0) { - IsNullNode isNullNode = (IsNullNode) ifNode.condition(); - if (getUnproxifiedUncompressed(floatingReadNode.getAddress().getBase()) == getUnproxifiedUncompressed(isNullNode.getValue())) { - return true; - } + if (pred instanceof IfNode ifNode) { + if (ifNode.condition() instanceof IsNullNode isNullNode && ifNode.getTrueSuccessorProbability() == 0.0) { + ValueNode base = floatingReadNode.getAddress().getBase(); + return base != null && getUnproxifiedUncompressed(base) == getUnproxifiedUncompressed(isNullNode.getValue()); } } } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java index c61c69ec0139..31603eb87b32 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java @@ -25,6 +25,7 @@ package jdk.graal.compiler.replacements.amd64; import static jdk.graal.compiler.nodes.calc.FloatTypeTestNode.FloatTypeTestOp.IS_INFINITE; +import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.CBRT; import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.COS; import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.EXP; import static jdk.graal.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG; @@ -189,6 +190,7 @@ private static void registerMathPlugins(InvocationPlugins plugins, AMD64 arch, R registerUnaryMath(r, "cos", COS); registerUnaryMath(r, "tan", TAN); registerUnaryMath(r, "tanh", TANH); + registerUnaryMath(r, "cbrt", CBRT); registerFMA(r, arch); registerMinMax(r, arch); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/classfile/ClassfileConstantPool.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/classfile/ClassfileConstantPool.java index eef8e0457ec2..557521ebdcc9 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/classfile/ClassfileConstantPool.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/classfile/ClassfileConstantPool.java @@ -29,6 +29,7 @@ import java.io.DataInputStream; import java.io.IOException; +import java.util.List; import jdk.graal.compiler.core.common.LibGraalSupport; import jdk.graal.compiler.debug.GraalError; @@ -37,7 +38,6 @@ import jdk.graal.compiler.replacements.classfile.ClassfileConstant.FieldRef; import jdk.graal.compiler.replacements.classfile.ClassfileConstant.Primitive; import jdk.graal.compiler.replacements.classfile.ClassfileConstant.Utf8; - import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaField; @@ -181,6 +181,11 @@ public JavaMethod lookupMethod(int index, int opcode, ResolvedJavaMethod caller) return result; } + @Override + public List lookupBootstrapMethodInvocations(boolean invokeDynamic) { + throw GraalError.unimplementedOverride(); // ExcludeFromJacocoGeneratedReport + } + @Override public JavaType lookupType(int index, int opcode) { return get(ClassRef.class, index).resolve(this); diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/UnaryMathIntrinsicNode.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/UnaryMathIntrinsicNode.java index 908af0a1c64a..385464b54ea6 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/UnaryMathIntrinsicNode.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/replacements/nodes/UnaryMathIntrinsicNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2025, 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 @@ -33,7 +33,6 @@ import jdk.graal.compiler.core.common.type.Stamp; import jdk.graal.compiler.core.common.type.StampFactory; import jdk.graal.compiler.debug.Assertions; -import jdk.graal.compiler.debug.GraalError; import jdk.graal.compiler.graph.NodeClass; import jdk.graal.compiler.lir.gen.ArithmeticLIRGeneratorTool; import jdk.graal.compiler.nodeinfo.NodeInfo; @@ -52,7 +51,7 @@ public final class UnaryMathIntrinsicNode extends UnaryNode implements ArithmeticLIRLowerable, Lowerable { public static final NodeClass TYPE = NodeClass.create(UnaryMathIntrinsicNode.class); - protected final UnaryOperation operation; + private final UnaryOperation operation; public enum UnaryOperation { LOG(new ForeignCallSignature("arithmeticLog", double.class, double.class)), @@ -61,7 +60,8 @@ public enum UnaryOperation { COS(new ForeignCallSignature("arithmeticCos", double.class, double.class)), TAN(new ForeignCallSignature("arithmeticTan", double.class, double.class)), TANH(new ForeignCallSignature("arithmeticTanh", double.class, double.class)), - EXP(new ForeignCallSignature("arithmeticExp", double.class, double.class)); + EXP(new ForeignCallSignature("arithmeticExp", double.class, double.class)), + CBRT(new ForeignCallSignature("arithmeticCbrt", double.class, double.class)); public final ForeignCallSignature foreignCallSignature; @@ -70,32 +70,23 @@ public enum UnaryOperation { } public static double compute(UnaryOperation op, double value) { - switch (op) { - case LOG: - return Math.log(value); - case LOG10: - return Math.log10(value); - case EXP: - return Math.exp(value); - case SIN: - return Math.sin(value); - case COS: - return Math.cos(value); - case TAN: - return Math.tan(value); - case TANH: - return Math.tanh(value); - default: - throw new GraalError("unknown op %s", op); - } + return switch (op) { + case LOG -> Math.log(value); + case LOG10 -> Math.log10(value); + case EXP -> Math.exp(value); + case SIN -> Math.sin(value); + case COS -> Math.cos(value); + case TAN -> Math.tan(value); + case TANH -> Math.tanh(value); + case CBRT -> Math.cbrt(value); + }; } public static Stamp computeStamp(UnaryOperation op, Stamp valueStamp) { if (valueStamp.isEmpty()) { return StampFactory.forKind(JavaKind.Double).empty(); } - if (valueStamp instanceof FloatStamp) { - FloatStamp floatStamp = (FloatStamp) valueStamp; + if (valueStamp instanceof FloatStamp floatStamp) { switch (op) { case TANH: case COS: @@ -118,13 +109,13 @@ public static Stamp computeStamp(UnaryOperation op, Stamp valueStamp) { boolean nonNaN = floatStamp.lowerBound() >= 0.0 && floatStamp.isNonNaN(); return StampFactory.forFloat(JavaKind.Double, lowerBound, upperBound, nonNaN); } + case CBRT: case EXP: { - double lowerBound = Math.exp(floatStamp.lowerBound()); - double upperBound = Math.exp(floatStamp.upperBound()); + double lowerBound = compute(op, floatStamp.lowerBound()); + double upperBound = compute(op, floatStamp.upperBound()); boolean nonNaN = floatStamp.isNonNaN(); return StampFactory.forFloat(JavaKind.Double, lowerBound, upperBound, nonNaN); } - } } return StampFactory.forKind(JavaKind.Double); @@ -144,7 +135,7 @@ public static ValueNode create(ValueNode value, UnaryOperation op) { return new UnaryMathIntrinsicNode(value, op); } - protected static ValueNode tryConstantFold(ValueNode value, UnaryOperation op) { + private static ValueNode tryConstantFold(ValueNode value, UnaryOperation op) { if (value.isConstant()) { return ConstantNode.forDouble(UnaryOperation.compute(op, value.asJavaConstant().asDouble())); } @@ -167,32 +158,16 @@ public Stamp foldStamp(Stamp valueStamp) { public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) { // We can only reach here in the math stubs Value input = nodeValueMap.operand(getValue()); - Value result; - switch (getOperation()) { - case LOG: - result = gen.emitMathLog(input, false); - break; - case LOG10: - result = gen.emitMathLog(input, true); - break; - case EXP: - result = gen.emitMathExp(input); - break; - case SIN: - result = gen.emitMathSin(input); - break; - case COS: - result = gen.emitMathCos(input); - break; - case TAN: - result = gen.emitMathTan(input); - break; - case TANH: - result = gen.emitMathTanh(input); - break; - default: - throw GraalError.shouldNotReachHereUnexpectedValue(getOperation()); // ExcludeFromJacocoGeneratedReport - } + Value result = switch (getOperation()) { + case LOG -> gen.emitMathLog(input, false); + case LOG10 -> gen.emitMathLog(input, true); + case EXP -> gen.emitMathExp(input); + case SIN -> gen.emitMathSin(input); + case COS -> gen.emitMathCos(input); + case TAN -> gen.emitMathTan(input); + case TANH -> gen.emitMathTanh(input); + case CBRT -> gen.emitMathCbrt(input); + }; nodeValueMap.setResult(this, result); } diff --git a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/KnownTruffleTypes.java b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/KnownTruffleTypes.java index 47c307754777..b7a92208c0b6 100644 --- a/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/KnownTruffleTypes.java +++ b/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/truffle/KnownTruffleTypes.java @@ -221,7 +221,7 @@ private static ResolvedJavaField getThrowableJFRTracingField(MetaAccessProvider ResolvedJavaType throwableType = metaAccess.lookupJavaType(Throwable.class); for (ResolvedJavaField staticField : throwableType.getStaticFields()) { if (staticField.getName().equals("jfrTracing") && - staticField.getType().equals(metaAccess.lookupJavaType(boolean.class)) && staticField.isVolatile()) { + staticField.getType().equals(metaAccess.lookupJavaType(boolean.class))) { return staticField; } } diff --git a/docs/reference-manual/native-image/BuildOptions.md b/docs/reference-manual/native-image/BuildOptions.md index bff02f0429bd..d12f23bf3bcd 100644 --- a/docs/reference-manual/native-image/BuildOptions.md +++ b/docs/reference-manual/native-image/BuildOptions.md @@ -163,6 +163,7 @@ The following system properties are automatically copied into the generated exec | native.encoding | Specifies the host environment's character encoding | | org.graalvm.nativeimage.kind | Specifies if the image is built as a shared library or executable | | path.separator | Path separator | +| stdin.encoding | Specifies the encoding for `System.in` | | stdout.encoding | Specifies the encoding for `System.out` and `System.err` | | sun.jnu.encoding | Specifies encoding when parsing values passed via the commandline | diff --git a/espresso/mx.espresso/suite.py b/espresso/mx.espresso/suite.py index 63a794f2e05c..87bf394fa06e 100644 --- a/espresso/mx.espresso/suite.py +++ b/espresso/mx.espresso/suite.py @@ -606,7 +606,7 @@ "layout": { "bin/": [ "dependency:espresso:espresso", - "dependency:ESPRESSO_JVM_STANDALONE_JAVA_LINKS/bin/*", + "dependency:espresso:ESPRESSO_JVM_STANDALONE_JAVA_LINKS/bin/*", ], "./": [{ "source_type": "dependency", diff --git a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoBootstrapMethodInvocation.java b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoBootstrapMethodInvocation.java index 83af985b8de5..10ab8828314a 100644 --- a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoBootstrapMethodInvocation.java +++ b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoBootstrapMethodInvocation.java @@ -27,6 +27,7 @@ import java.util.List; import java.util.StringJoiner; +import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.JavaConstant; @@ -74,6 +75,16 @@ public List getStaticArguments() { return staticArguments; } + @Override + public void resolve() { + throw JVMCIError.unimplemented(); + } + + @Override + public JavaConstant lookup() { + throw JVMCIError.unimplemented(); + } + @Override public String toString() { StringJoiner joiner = new StringJoiner(", ", "[", "]"); diff --git a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoConstantPool.java b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoConstantPool.java index be395e1b8553..5af95c736eda 100644 --- a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoConstantPool.java +++ b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoConstantPool.java @@ -25,7 +25,9 @@ import static com.oracle.truffle.espresso.jvmci.EspressoJVMCIRuntime.runtime; import java.lang.invoke.MethodHandle; +import java.util.List; +import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaField; @@ -112,6 +114,11 @@ public JavaMethod lookupMethod(int cpi, int opcode, ResolvedJavaMethod caller) { @Override public native EspressoBootstrapMethodInvocation lookupBootstrapMethodInvocation(int cpi, int opcode); + @Override + public List lookupBootstrapMethodInvocations(boolean invokeDynamic) { + throw JVMCIError.unimplemented(); + } + @Override public native JavaType lookupType(int cpi, int opcode); diff --git a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedArrayType.java b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedArrayType.java index eb57e2be6657..902180043d73 100644 --- a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedArrayType.java +++ b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedArrayType.java @@ -26,6 +26,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Modifier; +import java.util.Collections; +import java.util.List; import java.util.Objects; import jdk.vm.ci.common.JVMCIError; @@ -285,6 +287,11 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { return NO_METHODS; } + @Override + public List getAllMethods(boolean forceLink) { + return Collections.emptyList(); + } + @Override public ResolvedJavaMethod getClassInitializer() { return null; diff --git a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedInstanceType.java b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedInstanceType.java index 0bdf3089b98b..e0b47634c82a 100644 --- a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedInstanceType.java +++ b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedInstanceType.java @@ -37,6 +37,7 @@ import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.Comparator; +import java.util.List; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.Assumptions; @@ -482,6 +483,14 @@ public EspressoResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { private native EspressoResolvedJavaMethod[] getDeclaredMethods0(); + @Override + public List getAllMethods(boolean forceLink) { + if (forceLink) { + link(); + } + throw JVMCIError.unimplemented(); + } + @Override public native EspressoResolvedJavaMethod getClassInitializer(); diff --git a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedJavaMethod.java b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedJavaMethod.java index 2414bf114ab8..1229ebaf1ffc 100644 --- a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedJavaMethod.java +++ b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedJavaMethod.java @@ -146,6 +146,11 @@ public boolean isDefault() { return ((getModifiers() & mask) == Modifier.PUBLIC) && getDeclaringClass().isInterface(); } + @Override + public boolean isDeclared() { + throw JVMCIError.unimplemented(); + } + @Override public boolean isClassInitializer() { return isStatic() && "".equals(getName()); diff --git a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedPrimitiveType.java b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedPrimitiveType.java index 850217a970e4..d59152482785 100644 --- a/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedPrimitiveType.java +++ b/espresso/src/com.oracle.truffle.espresso.jvmci/src/com/oracle/truffle/espresso/jvmci/meta/EspressoResolvedPrimitiveType.java @@ -26,6 +26,8 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Modifier; +import java.util.Collections; +import java.util.List; import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.meta.Assumptions; @@ -248,6 +250,11 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { return NO_METHODS; } + @Override + public List getAllMethods(boolean forceLink) { + return Collections.emptyList(); + } + @Override public ResolvedJavaMethod getClassInitializer() { return null; diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedConstantPool.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedConstantPool.java index f0c6282a9823..a3c65a6b2136 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedConstantPool.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/infrastructure/WrappedConstantPool.java @@ -185,6 +185,11 @@ public BootstrapMethodInvocation lookupBootstrapMethodInvocation(int cpi, int op return null; } + @Override + public List lookupBootstrapMethodInvocations(boolean invokeDynamic) { + return wrapped.lookupBootstrapMethodInvocations(invokeDynamic).stream().map(WrappedBootstrapMethodInvocation::new).collect(Collectors.toUnmodifiableList()); + } + public class WrappedBootstrapMethodInvocation implements BootstrapMethodInvocation { private final BootstrapMethodInvocation wrapped; @@ -217,5 +222,15 @@ public JavaConstant getType() { public List getStaticArguments() { return wrapped.getStaticArguments().stream().map(WrappedConstantPool.this::lookupConstant).collect(Collectors.toList()); } + + @Override + public void resolve() { + wrapped.resolve(); + } + + @Override + public JavaConstant lookup() { + return lookupConstant(wrapped.lookup()); + } } } diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java index 5f6d80dfcd08..47c9dd63ecdc 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisMethod.java @@ -817,6 +817,11 @@ public boolean isBridge() { return wrapped.isBridge(); } + @Override + public boolean isDeclared() { + return wrapped.isDeclared(); + } + @Override public boolean isClassInitializer() { return wrapped.isClassInitializer(); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java index baea022b094e..3993bdabdc04 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/AnalysisType.java @@ -1337,6 +1337,14 @@ public AnalysisMethod[] getDeclaredMethods(boolean forceLink) { return result; } + @Override + public List getAllMethods(boolean forceLink) { + /* + * Not needed on SubstrateVM for now. + */ + throw GraalError.unimplementedOverride(); // ExcludeFromJacocoGeneratedReport + } + @Override public ResolvedJavaMethod[] getDeclaredConstructors() { return getDeclaredConstructors(true); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerMethod.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerMethod.java index 77257e280599..2d32cc0189ab 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerMethod.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerMethod.java @@ -146,6 +146,11 @@ public boolean isDefault() { throw unimplemented(); } + @Override + public boolean isDeclared() { + throw unimplemented(); + } + @Override public boolean isClassInitializer() { throw unimplemented(); diff --git a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerType.java b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerType.java index c7d7abf489a3..af487cc728b3 100644 --- a/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerType.java +++ b/substratevm/src/com.oracle.graal.pointsto/src/com/oracle/graal/pointsto/meta/BaseLayerType.java @@ -25,6 +25,7 @@ package com.oracle.graal.pointsto.meta; import java.lang.annotation.Annotation; +import java.util.List; import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider; import com.oracle.graal.pointsto.util.AnalysisError; @@ -250,6 +251,11 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { return new ResolvedJavaMethod[0]; } + @Override + public List getAllMethods(boolean forceLink) { + throw AnalysisError.shouldNotReachHere("This type is incomplete and should not be used."); + } + @Override public ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses) { return includeSuperclasses ? instanceFieldsWithSuper : instanceFields; diff --git a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AdaptiveCollectionPolicy.java b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AdaptiveCollectionPolicy.java index 022ed2f46a0a..9d83e35ef955 100644 --- a/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AdaptiveCollectionPolicy.java +++ b/substratevm/src/com.oracle.svm.core.genscavenge/src/com/oracle/svm/core/genscavenge/AdaptiveCollectionPolicy.java @@ -51,7 +51,7 @@ @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+20/src/hotspot/share/gc/parallel/psAdaptiveSizePolicy.cpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+25/src/hotspot/share/gc/parallel/psParallelCompact.cpp#L964-L1181") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+25/src/hotspot/share/gc/parallel/psScavenge.cpp#L319-L635") -@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+20/src/hotspot/share/gc/shared/gc_globals.hpp#L303-L407") +@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+26/src/hotspot/share/gc/shared/gc_globals.hpp#L303-L407") class AdaptiveCollectionPolicy extends AbstractCollectionPolicy { /* diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/container/ContainerLibrary.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/container/ContainerLibrary.java index 51c99745ce8c..ed94d74945f2 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/container/ContainerLibrary.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/container/ContainerLibrary.java @@ -60,14 +60,14 @@ @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/linux/cgroupV2Subsystem_linux.hpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/linux/osContainer_linux.cpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/linux/osContainer_linux.hpp") -@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+24/src/hotspot/os/linux/os_linux.cpp") +@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+26/src/hotspot/os/linux/os_linux.cpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/linux/os_linux.hpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/linux/os_linux.inline.hpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/include/jvm_md.h") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+25/src/hotspot/os/posix/os_posix.cpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+25/src/hotspot/os/posix/os_posix.hpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/os/posix/os_posix.inline.hpp") -@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+22/src/hotspot/share/memory/allocation.hpp") +@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+26/src/hotspot/share/memory/allocation.hpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+21/src/hotspot/share/memory/allocation.inline.hpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/share/memory/allStatic.hpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/share/nmt/memTag.hpp") @@ -84,8 +84,8 @@ @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+23/src/hotspot/share/utilities/ostream.hpp") // The following annotations are for files in `src/svm`, which are completely customized for SVM @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/share/logging/log.hpp") -@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+23/src/hotspot/share/memory/allocation.cpp") -@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+25/src/hotspot/share/runtime/globals.hpp") +@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+26/src/hotspot/share/memory/allocation.cpp") +@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+26/src/hotspot/share/runtime/globals.hpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+21/src/hotspot/share/utilities/debug.cpp") @BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+18/src/hotspot/share/utilities/debug.hpp") public class ContainerLibrary { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JNIRegistrationUtil.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JNIRegistrationUtil.java index 26090951f48e..9cea5420d02d 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JNIRegistrationUtil.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/JNIRegistrationUtil.java @@ -38,6 +38,7 @@ import org.graalvm.nativeimage.hosted.Feature.DuringAnalysisAccess; import org.graalvm.nativeimage.hosted.Feature.FeatureAccess; import org.graalvm.nativeimage.hosted.RuntimeJNIAccess; +import org.graalvm.nativeimage.hosted.RuntimeReflection; import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport; import com.oracle.svm.core.util.ConcurrentIdentityHashMap; @@ -109,6 +110,9 @@ protected static void registerForThrowNew(FeatureAccess access, String... except for (String exceptionClassName : exceptionClassNames) { RuntimeJNIAccess.register(clazz(access, exceptionClassName)); RuntimeJNIAccess.register(constructor(access, exceptionClassName, String.class)); + + RuntimeReflection.register(clazz(access, exceptionClassName)); + RuntimeReflection.register(constructor(access, exceptionClassName, String.class)); } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java index 2fdb8f43c691..d1e1d3ab3010 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/SystemPropertiesSupport.java @@ -92,6 +92,7 @@ public abstract class SystemPropertiesSupport implements RuntimeSystemProperties "native.encoding", "stdout.encoding", "stderr.encoding", + "stdin.encoding", }; /** System properties that are computed at run time on first access. */ diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_jdk_internal_util_Exceptions.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_jdk_internal_util_Exceptions.java new file mode 100644 index 000000000000..714eace404a1 --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_jdk_internal_util_Exceptions.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025, 2025, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.svm.core.jdk; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; + +@TargetClass(jdk.internal.util.Exceptions.class) +@SuppressWarnings({"unused", "FieldCanBeLocal"}) +final class Target_jdk_internal_util_Exceptions { + + /** + * Setup is eagerly called in {@code com.oracle.svm.hosted.jdk.JDKInitializationFeature}. + */ + @Substitute + public static void setup() { + // do nothing + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/Target_jdk_jfr_internal_settings_Throttler.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/Target_jdk_jfr_internal_settings_Throttler.java new file mode 100644 index 000000000000..deaa61673500 --- /dev/null +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/Target_jdk_jfr_internal_settings_Throttler.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2025, 2025, 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.svm.core.jfr; + +import java.util.Random; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.Inject; +import com.oracle.svm.core.annotate.InjectAccessors; +import com.oracle.svm.core.annotate.RecomputeFieldValue; +import com.oracle.svm.core.annotate.TargetClass; + +import jdk.graal.compiler.nodes.extended.MembarNode; + +@TargetClass(className = "jdk.jfr.internal.settings.Throttler") +public final class Target_jdk_jfr_internal_settings_Throttler { + @Alias // + @InjectAccessors(ThrottlerRandomAccessor.class) // + private Random randomGenerator; + + @Inject // + @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) // + Random injectedRandomGenerator; +} + +final class ThrottlerRandomAccessor { + @SuppressWarnings("unused") + static Random get(Target_jdk_jfr_internal_settings_Throttler receiver) { + Random value = receiver.injectedRandomGenerator; + if (value != null) { + return value; + } + return initializeRandom(receiver); + } + + private static synchronized Random initializeRandom(Target_jdk_jfr_internal_settings_Throttler receiver) { + Random value = receiver.injectedRandomGenerator; + if (value != null) { + return value; + } + + value = new Random(); + /* Ensure that other threads see a fully initialized Random object once published below. */ + MembarNode.memoryBarrier(MembarNode.FenceKind.STORE_STORE); + + receiver.injectedRandomGenerator = value; + return value; + } + + @SuppressWarnings("unused") + static synchronized void set(Target_jdk_jfr_internal_settings_Throttler receiver, Random value) { + receiver.injectedRandomGenerator = value; + } +} diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/logging/JfrLogTag.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/logging/JfrLogTag.java index dcdd2e47864a..e788cffb26f2 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/logging/JfrLogTag.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/logging/JfrLogTag.java @@ -25,14 +25,14 @@ */ package com.oracle.svm.core.jfr.logging; -import com.oracle.svm.core.util.BasedOnJDKFile; +import com.oracle.svm.core.util.BasedOnJDKClass; /** * This enum contains all log tags that are in at least one {@link jdk.jfr.internal.LogTag}. This * class is necessary because {@link jdk.jfr.internal.LogTag} is an enum of log tag sets, and does * not provide the individual log tags. */ -@BasedOnJDKFile("https://github.com/openjdk/jdk/blob/jdk-25+25/src/jdk.jfr/share/classes/jdk/jfr/internal/LogTag.java") +@BasedOnJDKClass(className = "jdk.jfr.internal.LogTag") enum JfrLogTag { JFR, SYSTEM, @@ -46,5 +46,6 @@ enum JfrLogTag { PERIODIC, SAMPLING, DCMD, - START + START, + METHODTRACE } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SharedMethod.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SharedMethod.java index fae25501180d..d3975e747a78 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SharedMethod.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SharedMethod.java @@ -83,4 +83,11 @@ public interface SharedMethod extends ResolvedJavaMethod { /** Always call this method indirectly, even if it is normally called directly. */ boolean forceIndirectCall(); + + /** + * Override to fix JVMCI incompatibility issues (caused by "JDK-8357987: [JVMCI] Add support for + * retrieving all methods of a ResolvedJavaType"). + */ + @Override + boolean isDeclared(); } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SharedType.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SharedType.java index 4df6354d76e4..d15e901a2464 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SharedType.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/meta/SharedType.java @@ -34,6 +34,8 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; +import java.util.List; + /** * The type interface which is both used in the hosted and substrate worlds. */ @@ -100,4 +102,12 @@ default AssumptionResult findUniqueConcreteMethod(ResolvedJa } return null; } + + @Override + default List getAllMethods(boolean forceLink) { + /* + * Not needed on SubstrateVM for now. + */ + throw VMError.intentionallyUnimplemented(); // ExcludeFromJacocoGeneratedReport + } } diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/snippets/SnippetRuntime.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/snippets/SnippetRuntime.java index f3f6713ef613..0eca9dab356f 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/snippets/SnippetRuntime.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/snippets/SnippetRuntime.java @@ -62,9 +62,10 @@ public class SnippetRuntime { private static final SubstrateForeignCallDescriptor ARITHMETIC_LOG10 = findForeignJdkCall(UnaryOperation.LOG10.foreignCallSignature.getName(), Math.class, "log10", NO_SIDE_EFFECT, true, true); private static final SubstrateForeignCallDescriptor ARITHMETIC_EXP = findForeignJdkCall(UnaryOperation.EXP.foreignCallSignature.getName(), Math.class, "exp", NO_SIDE_EFFECT, true, true); private static final SubstrateForeignCallDescriptor ARITHMETIC_POW = findForeignJdkCall(BinaryOperation.POW.foreignCallSignature.getName(), Math.class, "pow", NO_SIDE_EFFECT, true, true); + private static final SubstrateForeignCallDescriptor ARITHMETIC_CBRT = findForeignJdkCall(UnaryOperation.CBRT.foreignCallSignature.getName(), Math.class, "cbrt", NO_SIDE_EFFECT, true, true); private static final SubstrateForeignCallDescriptor[] FOREIGN_CALLS = new SubstrateForeignCallDescriptor[]{UNSUPPORTED_FEATURE, REGISTER_FINALIZER, ARITHMETIC_SIN, ARITHMETIC_COS, ARITHMETIC_TAN, - ARITHMETIC_TANH, ARITHMETIC_LOG, ARITHMETIC_LOG10, ARITHMETIC_EXP, ARITHMETIC_POW}; + ARITHMETIC_TANH, ARITHMETIC_LOG, ARITHMETIC_LOG10, ARITHMETIC_EXP, ARITHMETIC_POW, ARITHMETIC_CBRT}; public static void registerForeignCalls(SubstrateForeignCallsProvider foreignCalls) { foreignCalls.register(FOREIGN_CALLS); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaThreads.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaThreads.java index c717508bb9f1..9f267832d5f9 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaThreads.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/JavaThreads.java @@ -335,58 +335,6 @@ public static void dispatchUncaughtException(Thread thread, Throwable throwable) } } - /** - * Thread instance initialization. - * - * This method is a copy of the implementation of the JDK 8 method - * - * Thread.init(ThreadGroup g, Runnable target, String name, long stackSize) - * - * and the JDK 11 constructor - * - * Thread(ThreadGroup g, Runnable target, String name, long stackSize, - * AccessControlContext acc, boolean inheritThreadLocals) - * - * with these unsupported features removed: - *
    - *
  • No security manager: using the ContextClassLoader of the parent.
  • - *
- */ - static void initializeNewThread( - Target_java_lang_Thread tjlt, - ThreadGroup groupArg, - Runnable target, - String name, - long stackSize, - boolean inheritThreadLocals) { - if (name == null) { - throw new NullPointerException("The name cannot be null"); - } - tjlt.name = name; - - final Thread parent = Thread.currentThread(); - final ThreadGroup group = ((groupArg != null) ? groupArg : parent.getThreadGroup()); - - int priority; - boolean daemon; - if (JavaThreads.toTarget(parent) == tjlt) { - priority = Thread.NORM_PRIORITY; - daemon = false; - } else { - priority = parent.getPriority(); - daemon = parent.isDaemon(); - } - - initThreadFields(tjlt, group, target, stackSize, priority, daemon); - - PlatformThreads.setThreadStatus(fromTarget(tjlt), ThreadStatus.NEW); - - initNewThreadLocalsAndLoader(tjlt, inheritThreadLocals, parent); - - /* Set thread ID */ - tjlt.tid = nextThreadID(); - } - static void initThreadFields(Target_java_lang_Thread tjlt, ThreadGroup group, Runnable target, long stackSize, int priority, boolean daemon) { assert tjlt.holder == null; tjlt.holder = new Target_java_lang_Thread_FieldHolder(group, target, stackSize, priority, daemon); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java index cedc61ce33b7..b74307ef7e21 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/Target_java_lang_Thread.java @@ -90,9 +90,6 @@ public final class Target_java_lang_Thread { @Alias// volatile String name; - @Alias// - Target_java_lang_ThreadLocal_ThreadLocalMap threadLocals = null; - @Alias// Target_java_lang_ThreadLocal_ThreadLocalMap inheritableThreadLocals = null; @@ -212,9 +209,30 @@ private Target_java_lang_Thread( /* Injected Target_java_lang_Thread instance field initialization. */ this.threadData = new ThreadData(); - String nameLocal = (name != null) ? name : genThreadName(); + this.name = (name != null) ? name : genThreadName(); boolean inheritThreadLocals = (characteristics & NO_INHERIT_THREAD_LOCALS) == 0; - JavaThreads.initializeNewThread(this, g, target, nameLocal, stackSize, inheritThreadLocals); + + final Thread parent = Thread.currentThread(); + final ThreadGroup group = ((g != null) ? g : parent.getThreadGroup()); + + int priority; + boolean daemon; + if (JavaThreads.toTarget(parent) == this) { + priority = Thread.NORM_PRIORITY; + daemon = false; + } else { + priority = parent.getPriority(); + daemon = parent.isDaemon(); + } + + JavaThreads.initThreadFields(this, group, target, stackSize, priority, daemon); + + PlatformThreads.setThreadStatus(JavaThreads.fromTarget(this), ThreadStatus.NEW); + + JavaThreads.initNewThreadLocalsAndLoader(this, inheritThreadLocals, parent); + + /* Set thread ID */ + tid = JavaThreads.nextThreadID(); this.scopedValueBindings = NEW_THREAD_BINDINGS; } diff --git a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateMethod.java b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateMethod.java index faff3535fd0d..c2ca2d57ea3b 100644 --- a/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateMethod.java +++ b/substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/meta/SubstrateMethod.java @@ -348,6 +348,11 @@ public int getModifiers() { return modifiers; } + @Override + public boolean isDeclared() { + throw shouldNotReachHereAtRuntime(); // ExcludeFromJacocoGeneratedReport + } + @Override public boolean isClassInitializer() { assert !("".equals(name) && isStatic()) : "class initializers are executed during native image generation and are never in the native image"; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionMethod.java index 844c96319083..225558af0ebb 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionMethod.java @@ -169,6 +169,11 @@ public boolean isDefault() { return original.isDefault(); } + @Override + public boolean isDeclared() { + return original.isDeclared(); + } + @Override public boolean isClassInitializer() { return original.isClassInitializer(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionType.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionType.java index 500565a306ff..20adad53717f 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionType.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/CustomSubstitutionType.java @@ -26,6 +26,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; +import java.util.List; import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider; import com.oracle.svm.core.util.VMError; @@ -259,6 +260,11 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { return original.getDeclaredMethods(forceLink); } + @Override + public List getAllMethods(boolean forceLink) { + return original.getAllMethods(forceLink); + } + @Override public ResolvedJavaMethod getClassInitializer() { return original.getClassInitializer(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/NonBytecodeMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/NonBytecodeMethod.java index 92b78635064d..9316b94ba121 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/NonBytecodeMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/NonBytecodeMethod.java @@ -149,6 +149,11 @@ public boolean isDefault() { return false; } + @Override + public boolean isDeclared() { + throw VMError.intentionallyUnimplemented(); // ExcludeFromJacocoGeneratedReport + } + @Override public boolean isClassInitializer() { return false; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationFeature.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationFeature.java index 86dfa00e9f2d..686d6e10c1e8 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationFeature.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JDKInitializationFeature.java @@ -276,6 +276,11 @@ public void afterRegistration(AfterRegistrationAccess access) { rci.initializeAtRunTime("jdk.internal.markdown.MarkdownTransformer", "Contains a static field with a DocTreeScanner which is initialized at run time"); + /* Ensure "enhanced exception messages" are initialized (JDK 25+26, JDK-8348986). */ + var exceptionsClass = ReflectionUtil.lookupClass("jdk.internal.util.Exceptions"); + var exceptionsSetup = ReflectionUtil.lookupMethod(exceptionsClass, "setup"); + ReflectionUtil.invokeMethod(exceptionsSetup, null); + /* * The local class Holder in FallbackLinker#getInstance fails the build time initialization * starting JDK 22. There is no way to obtain a list of local classes using reflection. They diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNet.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNet.java index 4d468be6b12c..94aefa5e434b 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNet.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/jdk/JNIRegistrationJavaNet.java @@ -120,6 +120,9 @@ static void registerInitInetAddressIDs(DuringAnalysisAccess a) { RuntimeJNIAccess.register(constructor(a, "java.net.Inet6Address")); RuntimeJNIAccess.register(fields(a, "java.net.Inet6Address", "holder6")); RuntimeJNIAccess.register(fields(a, "java.net.Inet6Address$Inet6AddressHolder", "ipaddress", "scope_id", "scope_id_set", "scope_ifname")); + + /* Used by getEnhancedExceptionsAllowed() in net_util.c (JDK-8348986) */ + RuntimeJNIAccess.register(fields(a, "jdk.internal.util.Exceptions", "enhancedNonSocketExceptionText")); } private static void registerNetworkInterfaceInit(DuringAnalysisAccess a) { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedMethod.java index 42e570bfc9a5..83e2b56e7ad7 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/HostedMethod.java @@ -462,6 +462,11 @@ public boolean isBridge() { return wrapped.isBridge(); } + @Override + public boolean isDeclared() { + return wrapped.isDeclared(); + } + @Override public boolean isClassInitializer() { return wrapped.isClassInitializer(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotatedMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotatedMethod.java index b47ba688a2b0..3822edfbbabc 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotatedMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/AnnotatedMethod.java @@ -149,6 +149,11 @@ public boolean isBridge() { return original.isBridge(); } + @Override + public boolean isDeclared() { + return original.isClassInitializer(); + } + @Override public boolean isClassInitializer() { return original.isClassInitializer(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/InjectedFieldsType.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/InjectedFieldsType.java index 700dcfcd0a15..a35ee51a9d62 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/InjectedFieldsType.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/InjectedFieldsType.java @@ -26,6 +26,7 @@ import java.lang.reflect.AnnotatedElement; import java.util.Arrays; +import java.util.List; import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider; import com.oracle.svm.core.annotate.Inject; @@ -262,6 +263,12 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { return original.getDeclaredMethods(forceLink); } + @Override + public List getAllMethods(boolean forceLink) { + VMError.guarantee(forceLink == false, "only use getAllMethods without forcing to link, because linking can throw LinkageError"); + return original.getAllMethods(forceLink); + } + @Override public ResolvedJavaMethod getClassInitializer() { return original.getClassInitializer(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/PolymorphicSignatureWrapperMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/PolymorphicSignatureWrapperMethod.java index 51dfc32641c1..5093ade0e0e4 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/PolymorphicSignatureWrapperMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/PolymorphicSignatureWrapperMethod.java @@ -243,6 +243,11 @@ public boolean isDefault() { return false; } + @Override + public boolean isDeclared() { + throw VMError.intentionallyUnimplemented(); // ExcludeFromJacocoGeneratedReport + } + @Override public boolean isClassInitializer() { return false; diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionMethod.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionMethod.java index 453b069634d7..505227a3ab3a 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionMethod.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionMethod.java @@ -177,6 +177,11 @@ public boolean isBridge() { return annotated.isBridge(); } + @Override + public boolean isDeclared() { + return original.isDeclared(); + } + @Override public boolean isClassInitializer() { return original.isClassInitializer(); diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionType.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionType.java index b01803c1cb9a..5e3802a996c3 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionType.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionType.java @@ -27,6 +27,7 @@ import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Modifier; import java.util.Arrays; +import java.util.List; import com.oracle.graal.pointsto.infrastructure.OriginalClassProvider; import com.oracle.svm.core.annotate.Substitute; @@ -300,6 +301,12 @@ public ResolvedJavaMethod[] getDeclaredMethods(boolean forceLink) { return annotated.getDeclaredMethods(forceLink); } + @Override + public List getAllMethods(boolean forceLink) { + VMError.guarantee(forceLink == false, "only use getAllMethods without forcing to link, because linking can throw LinkageError"); + return annotated.getAllMethods(forceLink); + } + @Override public ResolvedJavaMethod getClassInitializer() { return annotated.getClassInitializer(); diff --git a/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterConstantPool.java b/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterConstantPool.java index 3b3fd16a8268..c059236e00a1 100644 --- a/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterConstantPool.java +++ b/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterConstantPool.java @@ -41,6 +41,8 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.Signature; +import java.util.List; + public final class InterpreterConstantPool implements ConstantPool { private final InterpreterResolvedObjectType holder; @@ -89,6 +91,11 @@ public JavaMethod lookupMethod(int cpi, int opcode, ResolvedJavaMethod caller) { throw VMError.intentionallyUnimplemented(); } + @Override + public List lookupBootstrapMethodInvocations(boolean invokeDynamic) { + throw VMError.intentionallyUnimplemented(); + } + @Override public JavaType lookupType(int cpi, int opcode) { return (JavaType) at(cpi); diff --git a/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaMethod.java b/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaMethod.java index d1e5f94718d8..99e5d72e63e2 100644 --- a/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaMethod.java +++ b/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaMethod.java @@ -262,6 +262,11 @@ public int getMaxStackSize() { return maxStackSize; } + @Override + public boolean isDeclared() { + throw VMError.intentionallyUnimplemented(); + } + @Override public boolean isClassInitializer() { return "".equals(getName()) && isStatic(); diff --git a/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaType.java b/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaType.java index 2f65c3ee0e5d..cbd43dfa7791 100644 --- a/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaType.java +++ b/substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/InterpreterResolvedJavaType.java @@ -26,6 +26,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Modifier; +import java.util.List; import org.graalvm.nativeimage.Platform; import org.graalvm.nativeimage.Platforms; @@ -265,6 +266,11 @@ public ResolvedJavaMethod[] getDeclaredMethods() { return NO_METHODS; } + @Override + public List getAllMethods(boolean forceLink) { + throw VMError.intentionallyUnimplemented(); + } + @Override public final ResolvedJavaMethod getClassInitializer() { throw VMError.intentionallyUnimplemented(); diff --git a/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/WasmImports.java b/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/WasmImports.java index a3c6a4136f87..befd0374e052 100644 --- a/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/WasmImports.java +++ b/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/WasmImports.java @@ -65,6 +65,7 @@ public class WasmImports { public static final ImportDescriptor.Function F64Tanh = new ImportDescriptor.Function(MODULE_COMPAT, "f64tanh", TypeUse.forUnary(f64, f64), "Math.tanh"); public static final ImportDescriptor.Function F64Exp = new ImportDescriptor.Function(MODULE_COMPAT, "f64exp", TypeUse.forUnary(f64, f64), "Math.exp"); public static final ImportDescriptor.Function F64Pow = new ImportDescriptor.Function(MODULE_COMPAT, "f64pow", TypeUse.forBinary(f64, f64, f64), "Math.pow"); + public static final ImportDescriptor.Function F64Cbrt = new ImportDescriptor.Function(MODULE_COMPAT, "f64cbrt", TypeUse.forBinary(f64, f64, f64), "Math.cbrt"); /** * Signature: {@code printBytes(fd, bytePtr, numBytes)}. diff --git a/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/codegen/WebImageWasmNodeLowerer.java b/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/codegen/WebImageWasmNodeLowerer.java index c1d93995090b..e2e263cd0149 100644 --- a/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/codegen/WebImageWasmNodeLowerer.java +++ b/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/codegen/WebImageWasmNodeLowerer.java @@ -942,6 +942,7 @@ private Instruction lowerUnaryMathIntrinsic(UnaryMathIntrinsicNode node) { case TAN -> WasmImports.F64Tan; case TANH -> WasmImports.F64Tanh; case EXP -> WasmImports.F64Exp; + case CBRT -> WasmImports.F64Cbrt; }; return new Call(masm.idFactory.forFunctionImport(imported), lowerExpression(node.getValue())); diff --git a/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/codegen/runtime/wasm-bootstrap.js b/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/codegen/runtime/wasm-bootstrap.js index 54f6020fdf90..51b697f45a24 100644 --- a/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/codegen/runtime/wasm-bootstrap.js +++ b/web-image/src/com.oracle.svm.hosted.webimage/src/com/oracle/svm/hosted/webimage/wasm/codegen/runtime/wasm-bootstrap.js @@ -43,6 +43,7 @@ wasmImports.compat = { f64tanh: Math.tanh, f64exp: Math.exp, f64pow: Math.pow, + f64cbrt: Math.cbrt, f32rem: (x, y) => x % y, };