Skip to content

Commit de96721

Browse files
author
Elia Trachsel
committed
IO and additional FileSystem substitutions:
- DirectoryStream implementation by setting a host Iterator and Stream as hidden host reference then proxying all methods to the native world where we retrieve the host object and do the semantics of the function. - FileDisptacherImpl now has a TruffleDispatcher as a field to avoid code duplication. And generally the substitutions in the dispatcher classes just link against the appropriate methods in TruffleIO. - ReadV and WriteV implementation by retrieving the underlying direct bytebuffers of the native struct. - Refactoring of TruffleIO: Now all different readBytes and writeBytes go to one single method respectively where the error handling and return value translation is done. There we now also handle the unavailable flag correctly.
1 parent cb878ca commit de96721

20 files changed

+698
-200
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package sun.nio.ch;
24+
25+
import java.nio.channels.spi.AsynchronousChannelProvider;
26+
27+
public final class DefaultAsynchronousChannelProvider {
28+
29+
/**
30+
* Prevent instantiation.
31+
*/
32+
private DefaultAsynchronousChannelProvider() {
33+
}
34+
35+
/**
36+
* Returns the default AsynchronousChannelProvider.
37+
*/
38+
public static AsynchronousChannelProvider create() {
39+
return new DummyAsynchronousChannelProvider();
40+
}
41+
42+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package sun.nio.ch;
24+
25+
import java.io.IOException;
26+
import java.nio.channels.AsynchronousChannelGroup;
27+
import java.nio.channels.AsynchronousServerSocketChannel;
28+
import java.nio.channels.AsynchronousSocketChannel;
29+
import java.nio.channels.spi.AsynchronousChannelProvider;
30+
import java.util.concurrent.ExecutorService;
31+
import java.util.concurrent.ThreadFactory;
32+
33+
public class DummyAsynchronousChannelProvider extends AsynchronousChannelProvider {
34+
@Override
35+
public AsynchronousChannelGroup openAsynchronousChannelGroup(int nThreads, ThreadFactory threadFactory) throws IOException {
36+
return null;
37+
}
38+
39+
@Override
40+
public AsynchronousChannelGroup openAsynchronousChannelGroup(ExecutorService executor, int initialSize) throws IOException {
41+
return null;
42+
}
43+
44+
@Override
45+
public AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(AsynchronousChannelGroup group) throws IOException {
46+
return null;
47+
}
48+
49+
@Override
50+
public AsynchronousSocketChannel openAsynchronousSocketChannel(AsynchronousChannelGroup group) throws IOException {
51+
return null;
52+
}
53+
}

espresso/src/com.oracle.truffle.espresso.io/src/sun/nio/ch/FileDispatcherImpl.java

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@
3737
* This file must be compatible with 21+
3838
*/
3939
final class FileDispatcherImpl extends sun.nio.ch.FileDispatcher {
40-
40+
// to avoid code duplication of NativeDispatcher operations
41+
private final TruffleDispatcher truffleDispatcher = new TruffleDispatcher();
4142
static {
4243
sun.nio.ch.IOUtil.load();
4344
}
@@ -105,27 +106,27 @@ int setDirectIO(FileDescriptor fd, String path) {
105106

106107
@Override
107108
int read(FileDescriptor fd, long address, int len) throws IOException {
108-
return read0(fd, address, len);
109+
return truffleDispatcher.read(fd, address, len);
109110
}
110111

111112
@Override
112113
long readv(FileDescriptor fd, long address, int len) throws IOException {
113-
return readv0(fd, address, len);
114+
return truffleDispatcher.readv(fd, address, len);
114115
}
115116

116117
@Override
117118
int write(FileDescriptor fd, long address, int len) throws IOException {
118-
return write0(fd, address, len);
119+
return truffleDispatcher.write(fd, address, len);
119120
}
120121

121122
@Override
122123
long writev(FileDescriptor fd, long address, int len) throws IOException {
123-
return writev0(fd, address, len);
124+
return truffleDispatcher.writev(fd, address, len);
124125
}
125126

126127
@Override
127128
void close(FileDescriptor fd) throws IOException {
128-
close0(fd);
129+
truffleDispatcher.close(fd);
129130
}
130131

131132
@Override
@@ -212,16 +213,6 @@ boolean isOther(FileDescriptor fd) throws IOException {
212213

213214
private static native long size0(FileDescriptor fd) throws IOException;
214215

215-
private static native int read0(FileDescriptor fd, long address, int len) throws IOException;
216-
217-
private static native int readv0(FileDescriptor fd, long address, int len) throws IOException;
218-
219-
private static native int write0(FileDescriptor fd, long address, int len) throws IOException;
220-
221-
private static native int writev0(FileDescriptor fd, long address, int len) throws IOException;
222-
223-
private static native void close0(FileDescriptor fd) throws IOException;
224-
225216
private static native int pread0(FileDescriptor fd, long address, int len, long position) throws IOException;
226217

227218
private static native int pwrite0(FileDescriptor fd, long address, int len, long position) throws IOException;
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package sun.nio.ch;
24+
25+
class SocketDispatcher extends TruffleDispatcher {
26+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
package sun.nio.ch;
24+
25+
import java.io.FileDescriptor;
26+
import java.io.IOException;
27+
28+
class TruffleDispatcher extends NativeDispatcher {
29+
@Override
30+
int read(FileDescriptor fd, long address, int len) throws IOException {
31+
return read0(fd, address, len);
32+
}
33+
34+
@Override
35+
long readv(FileDescriptor fd, long address, int len) throws IOException {
36+
return readv0(fd, address, len);
37+
}
38+
39+
@Override
40+
int write(FileDescriptor fd, long address, int len) throws IOException {
41+
return write0(fd, address, len);
42+
}
43+
44+
@Override
45+
long writev(FileDescriptor fd, long address, int len) throws IOException {
46+
return writev0(fd, address, len);
47+
}
48+
49+
@Override
50+
void close(FileDescriptor fd) throws IOException {
51+
close0(fd);
52+
}
53+
54+
private static native int read0(FileDescriptor fd, long address, int len) throws IOException;
55+
56+
private static native long readv0(FileDescriptor fd, long address, int len) throws IOException;
57+
58+
private static native int write0(FileDescriptor fd, long address, int len) throws IOException;
59+
60+
private static native long writev0(FileDescriptor fd, long address, int len) throws IOException;
61+
62+
private static native void close0(FileDescriptor fd) throws IOException;
63+
64+
}

espresso/src/com.oracle.truffle.espresso.io/src/sun/nio/fs/TruffleFileSystemProvider.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
* This file must be compatible with 21+.
5353
*/
5454
class TruffleFileSystemProvider extends FileSystemProvider {
55-
5655
static {
5756
// ensure 'nio' is loaded. Also loads 'net' as a side-effect.
5857
sun.nio.ch.IOUtil.load();

espresso/src/com.oracle.truffle.espresso.io/src/sun/nio/fs/TruffleFilteredDirectoryStream.java

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,19 @@
3131
import java.util.Objects;
3232

3333
/**
34-
* This file must be compatible with 21+.
34+
* DirectoryStream implementation by setting a host iterator and stream as hidden host reference
35+
* then proxying all methods to the native world where we retrieve the host object and do the
36+
* semantics of the function. Note this file must be compatible with 21+.
3537
*/
3638
final class TruffleFilteredDirectoryStream implements DirectoryStream<Path> {
3739
private final TrufflePath truffleDir;
38-
private final DirectoryStream<Object> stream;
40+
private final DirectoryStream<String> stream;
3941
private final DirectoryStream.Filter<? super Path> filter;
4042

4143
/**
42-
* Thin wrapper for a foreign (host) {@code Iterator<Object>}, cannot have any fields.
44+
* Thin wrapper for a foreign (host) {@code Iterator<String>}, cannot have any fields.
4345
*/
44-
private static final class ForeignIterator implements Iterator<Object> {
46+
private static final class ForeignIterator implements Iterator<String> {
4547

4648
private ForeignIterator() {
4749
// only foreign wrappers allowed
@@ -53,15 +55,15 @@ public boolean hasNext() {
5355
}
5456

5557
@Override
56-
public Object next() {
58+
public String next() {
5759
return next0(this);
5860
}
5961
}
6062

6163
/**
6264
* Thin wrapper for a foreign (host) DirectoryStream, cannot have any fields.
6365
*/
64-
private static final class ForeignDirectoryStream implements DirectoryStream<Object> {
66+
private static final class ForeignDirectoryStream implements DirectoryStream<String> {
6567

6668
private ForeignDirectoryStream() {
6769
// only foreign wrappers
@@ -73,19 +75,19 @@ public void close() throws IOException {
7375
}
7476

7577
@Override
76-
public Iterator<Object> iterator() {
77-
return iterator0(this, ForeignIterator.class);
78+
public Iterator<String> iterator() {
79+
return iterator0(this);
7880
}
7981
}
8082

8183
static DirectoryStream<Path> create(TrufflePath truffleDir, Filter<? super Path> filter) throws IOException {
8284
if (!Files.isDirectory(truffleDir)) {
8385
throw new NotDirectoryException(truffleDir.toString());
8486
}
85-
return new TruffleFilteredDirectoryStream(truffleDir, directoryStream0(truffleDir, ForeignDirectoryStream.class), filter);
87+
return new TruffleFilteredDirectoryStream(truffleDir, directoryStream0(truffleDir), filter);
8688
}
8789

88-
private TruffleFilteredDirectoryStream(TrufflePath dir, DirectoryStream<Object> stream, Filter<? super Path> filter) {
90+
private TruffleFilteredDirectoryStream(TrufflePath dir, DirectoryStream<String> stream, Filter<? super Path> filter) {
8991
this.truffleDir = Objects.requireNonNull(dir);
9092
this.filter = Objects.requireNonNull(filter);
9193
this.stream = Objects.requireNonNull(stream);
@@ -94,7 +96,7 @@ private TruffleFilteredDirectoryStream(TrufflePath dir, DirectoryStream<Object>
9496

9597
@Override
9698
public Iterator<Path> iterator() {
97-
return MapFilterIterator.mapThenFilter(stream.iterator(), tf -> toTrufflePath0(tf, truffleDir.getTruffleFileSystem()),
99+
return MapFilterIterator.mapThenFilter(stream.iterator(), tf -> new TrufflePath((TruffleFileSystem) truffleDir.getFileSystem(), truffleDir.resolve(tf).toString()),
98100
path -> {
99101
try {
100102
return filter.accept(path);
@@ -116,17 +118,15 @@ private static <T extends Throwable> RuntimeException sneakyThrow(Throwable ex)
116118

117119
// region native methods
118120

119-
private static native DirectoryStream<Object> directoryStream0(TrufflePath dir, Class<ForeignDirectoryStream> directoryStreamClass) throws IOException;
121+
private static native DirectoryStream<String> directoryStream0(TrufflePath dir) throws IOException;
120122

121-
private static native boolean hasNext0(Iterator<Object> iterator);
123+
private static native boolean hasNext0(Iterator<String> iterator);
122124

123-
private static native Object next0(Iterator<Object> iterator);
125+
private static native String next0(Iterator<String> iterator);
124126

125-
private static native void close0(DirectoryStream<Object> directoryStream) throws IOException;
127+
private static native void close0(DirectoryStream<String> directoryStream) throws IOException;
126128

127-
private static native Iterator<Object> iterator0(DirectoryStream<Object> directoryStream, Class<ForeignIterator> iteratorClass);
128-
129-
private static native TrufflePath toTrufflePath0(Object truffleFile, TruffleFileSystem truffleFileSystem);
129+
private static native Iterator<String> iterator0(DirectoryStream<String> directoryStream);
130130

131131
// endregion native methods
132132
}

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/descriptors/EspressoSymbols.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ public static void ensureInitialized() {
185185
public static final Symbol<Type> sun_nio_ch_IOStatus = SYMBOLS.putType("Lsun/nio/ch/IOStatus;");
186186
public static final Symbol<Type> java_net_spi_InetAddressResolver$LookupPolicy = SYMBOLS.putType("Ljava/net/spi/InetAddressResolver$LookupPolicy;");
187187
public static final Symbol<Type> sun_nio_ch_Net = SYMBOLS.putType("Lsun/nio/ch/Net;");
188+
// libnio
189+
public static final Symbol<Type> sun_nio_fs_TruffleFilteredDirectoryStream$ForeignDirectoryStream = SYMBOLS.putType("Lsun/nio/fs/TruffleFilteredDirectoryStream$ForeignDirectoryStream;");
190+
public static final Symbol<Type> sun_nio_fs_TruffleFilteredDirectoryStream$ForeignIterator = SYMBOLS.putType("Lsun/nio/fs/TruffleFilteredDirectoryStream$ForeignIterator;");
188191
// URL class loader
189192
public static final Symbol<Type> java_net_URLClassLoader = SYMBOLS.putType("Ljava/net/URLClassLoader;");
190193
public static final Symbol<Type> java_net_URL = SYMBOLS.putType("Ljava/net/URL;");

0 commit comments

Comments
 (0)