Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions substratevm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ This changelog summarizes major changes to GraalVM Native Image.

## Version 23.1.0
* (GR-35746) Lower the default aligned chunk size from 1 MB to 512 KB for the serial and epsilon GCs, reducing memory usage and image size in many cases.
* (GR-45014) Support JFR on Windows.
* (GR-45015) Support the heap dumping infrastructure on Windows.

## Version 23.0.0
* (GR-40187) Report invalid use of SVM specific classes on image class- or module-path as error. As a temporary workaround, `-H:+AllowDeprecatedBuilderClassesOnImageClasspath` allows turning the error into a warning.
Expand Down
63 changes: 58 additions & 5 deletions substratevm/mx.substratevm/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,11 +646,6 @@
"subDir": "src",
"native": "static_lib",
"os_arch": {
"solaris": {
"<others>": {
"ignore": "solaris is not supported",
},
},
"windows": {
"<others>": {
"cflags": ["-Zi", "-O2", "-D_LITTLE_ENDIAN", "-DJDK_VER=<jdk_ver>"],
Expand Down Expand Up @@ -704,6 +699,60 @@
"jacoco" : "exclude",
},

"com.oracle.svm.native.darwin.iohelper": {
"subDir": "src",
"native": "static_lib",
"os_arch": {
"darwin": {
"<others>": {
"cflags": ["-ObjC", "-fPIC", "-O1", "-D_LITTLE_ENDIAN", "-ffunction-sections", "-fdata-sections", "-fvisibility=hidden", "-D_FORTIFY_SOURCE=0"],
},
},
"<others>": {
"<others>": {
"ignore": "only needed on darwin",
},
},
},
"jacoco" : "exclude",
},

"com.oracle.svm.native.linux.iohelper": {
"subDir": "src",
"native": "static_lib",
"os_arch" : {
"linux": {
"<others>" : {
"cflags": ["-g", "-gdwarf-4", "-fPIC", "-O2", "-ffunction-sections", "-fdata-sections", "-fvisibility=hidden", "-D_FORTIFY_SOURCE=0", "-D_GNU_SOURCE"],
},
},
"<others>": {
"<others>": {
"ignore": "only needed on linux",
},
},
},
"jacoco" : "exclude",
},

"com.oracle.svm.native.windows.iohelper": {
"subDir": "src",
"native": "static_lib",
"os_arch": {
"windows": {
"amd64" : {
"cflags": ["-MD", "-Zi", "-O2"],
},
},
"<others>": {
"<others>": {
"ignore": "only needed on windows",
},
},
},
"jacoco" : "exclude",
},

"com.oracle.svm.native.jvm.posix": {
"subDir": "src",
"native": "static_lib",
Expand Down Expand Up @@ -1477,6 +1526,10 @@
"dependency:com.oracle.svm.native.darwin/*",
"dependency:com.oracle.svm.native.jvm.posix/*",
"dependency:com.oracle.svm.native.jvm.windows/*",
"dependency:com.oracle.svm.native.linux.iohelper/*",
"dependency:com.oracle.svm.native.darwin.iohelper/*",
"dependency:com.oracle.svm.native.windows.iohelper/*",

],
},
"description" : "SubstrateVM image builder native components",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordFactory;

import com.oracle.svm.core.IOHelper;
import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
Expand Down Expand Up @@ -70,7 +71,7 @@ public RawFileDescriptor open(File file, FileAccessMode mode) {
private static RawFileDescriptor open0(String path, int flags) {
int permissions = PosixStat.S_IRUSR() | PosixStat.S_IWUSR();
try (CTypeConversion.CCharPointerHolder cPath = CTypeConversion.toCString(path)) {
return WordFactory.signed(Fcntl.NoTransitions.open(cPath.get(), flags, permissions));
return WordFactory.signed(IOHelper.openFile(cPath.get(), flags, permissions));
}
}

Expand Down Expand Up @@ -107,9 +108,10 @@ public long position(RawFileDescriptor fd) {
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@Override
public boolean seek(RawFileDescriptor fd, long position) {
assert position >= 0;
int posixFd = getPosixFileDescriptor(fd);
SignedWord newPos = Unistd.NoTransitions.lseek(posixFd, WordFactory.signed(position), Unistd.SEEK_SET());
return position == newPos.rawValue();
SignedWord actualPosition = Unistd.NoTransitions.lseek(posixFd, WordFactory.signed(position), Unistd.SEEK_SET());
return position == actualPosition.rawValue();
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import com.oracle.svm.core.headers.LibC;
import com.oracle.svm.core.thread.VMThreads;
import com.oracle.svm.core.windows.headers.FileAPI;
import com.oracle.svm.core.windows.headers.WinBase.HANDLE;

public class WindowsLogHandler implements LogHandler {

Expand Down Expand Up @@ -60,7 +61,7 @@ public void fatalError() {
LibC.abort();
}

private static int getOutputFile() {
private static HANDLE getOutputFile() {
// [TODO] Change to use FileDescriptor.err once FileDescriptor class is functional
return FileAPI.GetStdHandle(FileAPI.STD_ERROR_HANDLE());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,6 @@ static WordBase osThreadStartRoutine(WindowsThreadStartData data) {
*/
@Platforms(Platform.WINDOWS.class)
class WindowsParker extends Parker {
private static final long MAX_DWORD = (1L << 32) - 1;

/**
* An opaque handle for an event object from the operating system. Event objects have explicit
* set and reset operations. They can be waited on until they become set or a timeout occurs,
Expand Down Expand Up @@ -249,7 +247,7 @@ protected void park(boolean isAbsolute, long time) {
/* There was already a notification pending. */
SynchAPI.ResetEvent(eventHandle);
} else {
status = SynchAPI.WaitForSingleObject(eventHandle, toDword(millis));
status = SynchAPI.WaitForSingleObject(eventHandle, WindowsUtils.toDwordOrMaxValue(millis));
SynchAPI.ResetEvent(eventHandle);
}
assert status == SynchAPI.WAIT_OBJECT_0() || status == SynchAPI.WAIT_TIMEOUT();
Expand All @@ -258,15 +256,6 @@ protected void park(boolean isAbsolute, long time) {
}
}

/* DWORD is an unsigned 32-bit value. */
private static int toDword(long value) {
assert value >= 0;
if (value > MAX_DWORD) {
return (int) MAX_DWORD;
}
return (int) value;
}

@Override
protected void unpark() {
StackOverflowCheck.singleton().makeYellowZoneAvailable();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/*
* Copyright (c) 2021, 2021, 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.windows;

import java.io.File;
import java.nio.ByteOrder;

import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.nativeimage.c.type.CTypeConversion;
import org.graalvm.word.Pointer;
import org.graalvm.word.UnsignedWord;
import org.graalvm.word.WordFactory;

import com.oracle.svm.core.IOHelper;
import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
import com.oracle.svm.core.feature.InternalFeature;
import com.oracle.svm.core.os.AbstractRawFileOperationSupport;
import com.oracle.svm.core.os.AbstractRawFileOperationSupport.RawFileOperationSupportHolder;
import com.oracle.svm.core.util.VMError;
import com.oracle.svm.core.windows.headers.IO;

public class WindowsRawFileOperationSupport extends AbstractRawFileOperationSupport {
@Platforms(Platform.HOSTED_ONLY.class)
public WindowsRawFileOperationSupport(boolean useNativeByteOrder) {
super(useNativeByteOrder);
}

@Override
public RawFileDescriptor create(File file, FileCreationMode creationMode, FileAccessMode accessMode) {
String path = file.getPath();
int flags = parseMode(creationMode) | parseMode(accessMode);
return open0(path, flags);
}

@Override
public RawFileDescriptor open(File file, FileAccessMode mode) {
String path = file.getPath();
int flags = parseMode(mode);
return open0(path, flags);
}

private static RawFileDescriptor open0(String path, int flags) {
try (CTypeConversion.CCharPointerHolder cPath = CTypeConversion.toCString(path)) {
return WordFactory.signed(IOHelper.openFile(cPath.get(), flags, IO._S_IREAD() | IO._S_IWRITE()));
}
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@Override
public boolean isValid(RawFileDescriptor fd) {
int windowsFd = getWindowsFileDescriptor(fd);
/* > 0 to ensure the default value 0 is invalid on all platforms */
return windowsFd > 0;
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@Override
public boolean close(RawFileDescriptor fd) {
int windowsFd = getWindowsFileDescriptor(fd);
int result = IO.NoTransitions._close(windowsFd);
return result == 0;
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@Override
public long size(RawFileDescriptor fd) {
int windowsFd = getWindowsFileDescriptor(fd);
return IO.NoTransitions._filelengthi64(windowsFd);
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@Override
public long position(RawFileDescriptor fd) {
int windowsFd = getWindowsFileDescriptor(fd);
return IO.NoTransitions._lseeki64(windowsFd, 0L, IO.SEEK_CUR());
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@Override
public boolean seek(RawFileDescriptor fd, long position) {
assert position >= 0;
int windowsFd = getWindowsFileDescriptor(fd);
long actualPosition = IO.NoTransitions._lseeki64(windowsFd, position, IO.SEEK_SET());
return position == actualPosition;
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@Override
public boolean write(RawFileDescriptor fd, Pointer data, UnsignedWord size) {
int windowsFd = getWindowsFileDescriptor(fd);

Pointer pos = data;
UnsignedWord remaining = size;
while (remaining.notEqual(0)) {
int uBytesToWrite = WindowsUtils.toUnsignedIntOrMaxValue(remaining);
int ret = IO.NoTransitions._write(windowsFd, pos, uBytesToWrite);
if (ret == -1) {
return false;
}

UnsignedWord writtenBytes = WindowsUtils.unsignedIntToUnsignedWord(ret);
pos = pos.add(writtenBytes);
remaining = remaining.subtract(writtenBytes);
}
return true;
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
@Override
public long read(RawFileDescriptor fd, Pointer buffer, UnsignedWord bufferSize) {
int windowsFd = getWindowsFileDescriptor(fd);
int uMaxBytes = WindowsUtils.toUnsignedIntOrMaxValue(bufferSize);
int readBytes = IO.NoTransitions._read(windowsFd, buffer, uMaxBytes);
if (readBytes == -1) {
return -1L;
}
return WindowsUtils.unsignedIntToLong(readBytes);
}

@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
private static int getWindowsFileDescriptor(RawFileDescriptor fd) {
int result = (int) fd.rawValue();
assert result == fd.rawValue();
return result;
}

private static int parseMode(FileCreationMode mode) {
return switch (mode) {
case CREATE -> IO._O_CREAT() | IO._O_EXCL();
case CREATE_OR_REPLACE -> IO._O_CREAT() | IO._O_TRUNC();
default -> throw VMError.shouldNotReachHere();
};
}

private static int parseMode(FileAccessMode mode) {
return switch (mode) {
case READ -> IO._O_RDONLY();
case READ_WRITE -> IO._O_RDWR();
case WRITE -> IO._O_WRONLY();
default -> throw VMError.shouldNotReachHere();
};
}
}

@AutomaticallyRegisteredFeature
class WindowsRawFileOperationFeature implements InternalFeature {
@Override
public void afterRegistration(AfterRegistrationAccess access) {
ByteOrder nativeByteOrder = ByteOrder.nativeOrder();
assert nativeByteOrder == ByteOrder.LITTLE_ENDIAN || nativeByteOrder == ByteOrder.BIG_ENDIAN;

WindowsRawFileOperationSupport littleEndian = new WindowsRawFileOperationSupport(ByteOrder.LITTLE_ENDIAN == nativeByteOrder);
WindowsRawFileOperationSupport bigEndian = new WindowsRawFileOperationSupport(ByteOrder.BIG_ENDIAN == nativeByteOrder);
WindowsRawFileOperationSupport nativeOrder = nativeByteOrder == ByteOrder.LITTLE_ENDIAN ? littleEndian : bigEndian;

ImageSingletons.add(RawFileOperationSupportHolder.class, new RawFileOperationSupportHolder(littleEndian, bigEndian, nativeOrder));
}
}
Loading