mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8331876: JFR: Move file read and write events to java.base
Reviewed-by: mgronlun, alanb
This commit is contained in:
parent
f608918df3
commit
4a20691e9b
20 changed files with 551 additions and 662 deletions
|
@ -28,6 +28,7 @@ package java.io;
|
|||
import java.nio.channels.FileChannel;
|
||||
import java.util.Arrays;
|
||||
import jdk.internal.util.ArraysSupport;
|
||||
import jdk.internal.event.FileReadEvent;
|
||||
import sun.nio.ch.FileChannelImpl;
|
||||
|
||||
/**
|
||||
|
@ -59,6 +60,12 @@ public class FileInputStream extends InputStream
|
|||
{
|
||||
private static final int DEFAULT_BUFFER_SIZE = 8192;
|
||||
|
||||
/**
|
||||
* Flag set by jdk.internal.event.JFRTracing to indicate if
|
||||
* file reads should be traced by JFR.
|
||||
*/
|
||||
private static boolean jfrTracing;
|
||||
|
||||
/* File Descriptor - handle to the open file */
|
||||
private final FileDescriptor fd;
|
||||
|
||||
|
@ -222,11 +229,36 @@ public class FileInputStream extends InputStream
|
|||
*/
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (jfrTracing && FileReadEvent.enabled()) {
|
||||
return traceRead0();
|
||||
}
|
||||
return read0();
|
||||
}
|
||||
|
||||
private native int read0() throws IOException;
|
||||
|
||||
private int traceRead0() throws IOException {
|
||||
int result = 0;
|
||||
boolean endOfFile = false;
|
||||
long bytesRead = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileReadEvent.timestamp();
|
||||
result = read0();
|
||||
if (result < 0) {
|
||||
endOfFile = true;
|
||||
} else {
|
||||
bytesRead = 1;
|
||||
}
|
||||
} finally {
|
||||
long duration = FileReadEvent.timestamp() - start;
|
||||
if (FileReadEvent.shouldCommit(duration)) {
|
||||
FileReadEvent.commit(start, duration, path, bytesRead, endOfFile);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a subarray as a sequence of bytes.
|
||||
* @param b the data to be written
|
||||
|
@ -236,6 +268,25 @@ public class FileInputStream extends InputStream
|
|||
*/
|
||||
private native int readBytes(byte[] b, int off, int len) throws IOException;
|
||||
|
||||
private int traceReadBytes(byte b[], int off, int len) throws IOException {
|
||||
int bytesRead = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileReadEvent.timestamp();
|
||||
bytesRead = readBytes(b, off, len);
|
||||
} finally {
|
||||
long duration = FileReadEvent.timestamp() - start;
|
||||
if (FileReadEvent.shouldCommit(duration)) {
|
||||
if (bytesRead < 0) {
|
||||
FileReadEvent.commit(start, duration, path, 0L, true);
|
||||
} else {
|
||||
FileReadEvent.commit(start, duration, path, bytesRead, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to {@code b.length} bytes of data from this input
|
||||
* stream into an array of bytes. This method blocks until some input
|
||||
|
@ -249,6 +300,9 @@ public class FileInputStream extends InputStream
|
|||
*/
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
if (jfrTracing && FileReadEvent.enabled()) {
|
||||
return traceReadBytes(b, 0, b.length);
|
||||
}
|
||||
return readBytes(b, 0, b.length);
|
||||
}
|
||||
|
||||
|
@ -268,6 +322,9 @@ public class FileInputStream extends InputStream
|
|||
*/
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
if (jfrTracing && FileReadEvent.enabled()) {
|
||||
return traceReadBytes(b, off, len);
|
||||
}
|
||||
return readBytes(b, off, len);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ package java.io;
|
|||
import java.nio.channels.FileChannel;
|
||||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.access.JavaIOFileDescriptorAccess;
|
||||
import jdk.internal.event.FileWriteEvent;
|
||||
import sun.nio.ch.FileChannelImpl;
|
||||
|
||||
|
||||
|
@ -68,6 +69,12 @@ public class FileOutputStream extends OutputStream
|
|||
private static final JavaIOFileDescriptorAccess FD_ACCESS =
|
||||
SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
/**
|
||||
* Flag set by jdk.internal.event.JFRTracing to indicate if
|
||||
* file writes should be traced by JFR.
|
||||
*/
|
||||
private static boolean jfrTracing;
|
||||
|
||||
/**
|
||||
* The system dependent file descriptor.
|
||||
*/
|
||||
|
@ -297,6 +304,21 @@ public class FileOutputStream extends OutputStream
|
|||
*/
|
||||
private native void write(int b, boolean append) throws IOException;
|
||||
|
||||
private void traceWrite(int b, boolean append) throws IOException {
|
||||
long bytesWritten = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileWriteEvent.timestamp();
|
||||
write(b, append);
|
||||
bytesWritten = 1;
|
||||
} finally {
|
||||
long duration = FileWriteEvent.timestamp() - start;
|
||||
if (FileWriteEvent.shouldCommit(duration)) {
|
||||
FileWriteEvent.commit(start, duration, path, bytesWritten);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the specified byte to this file output stream. Implements
|
||||
* the {@code write} method of {@code OutputStream}.
|
||||
|
@ -307,6 +329,10 @@ public class FileOutputStream extends OutputStream
|
|||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
boolean append = FD_ACCESS.getAppend(fd);
|
||||
if (jfrTracing && FileWriteEvent.enabled()) {
|
||||
traceWrite(b, append);
|
||||
return;
|
||||
}
|
||||
write(b, append);
|
||||
}
|
||||
|
||||
|
@ -322,6 +348,21 @@ public class FileOutputStream extends OutputStream
|
|||
private native void writeBytes(byte[] b, int off, int len, boolean append)
|
||||
throws IOException;
|
||||
|
||||
private void traceWriteBytes(byte b[], int off, int len, boolean append) throws IOException {
|
||||
long bytesWritten = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileWriteEvent.timestamp();
|
||||
writeBytes(b, off, len, append);
|
||||
bytesWritten = len;
|
||||
} finally {
|
||||
long duration = FileWriteEvent.timestamp() - start;
|
||||
if (FileWriteEvent.shouldCommit(duration)) {
|
||||
FileWriteEvent.commit(start, duration, path, bytesWritten);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes {@code b.length} bytes from the specified byte array
|
||||
* to this file output stream.
|
||||
|
@ -332,6 +373,10 @@ public class FileOutputStream extends OutputStream
|
|||
@Override
|
||||
public void write(byte[] b) throws IOException {
|
||||
boolean append = FD_ACCESS.getAppend(fd);
|
||||
if (jfrTracing && FileWriteEvent.enabled()) {
|
||||
traceWriteBytes(b, 0, b.length, append);
|
||||
return;
|
||||
}
|
||||
writeBytes(b, 0, b.length, append);
|
||||
}
|
||||
|
||||
|
@ -348,6 +393,10 @@ public class FileOutputStream extends OutputStream
|
|||
@Override
|
||||
public void write(byte[] b, int off, int len) throws IOException {
|
||||
boolean append = FD_ACCESS.getAppend(fd);
|
||||
if (jfrTracing && FileWriteEvent.enabled()) {
|
||||
traceWriteBytes(b, off, len, append);
|
||||
return;
|
||||
}
|
||||
writeBytes(b, off, len, append);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ import jdk.internal.access.JavaIORandomAccessFileAccess;
|
|||
import jdk.internal.access.SharedSecrets;
|
||||
import jdk.internal.misc.Blocker;
|
||||
import jdk.internal.util.ByteArray;
|
||||
import jdk.internal.event.FileReadEvent;
|
||||
import jdk.internal.event.FileWriteEvent;
|
||||
import sun.nio.ch.FileChannelImpl;
|
||||
|
||||
|
||||
|
@ -68,6 +70,12 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
private static final int O_DSYNC = 8;
|
||||
private static final int O_TEMPORARY = 16;
|
||||
|
||||
/**
|
||||
* Flag set by jdk.internal.event.JFRTracing to indicate if
|
||||
* file reads and writes should be traced by JFR.
|
||||
*/
|
||||
private static boolean jfrTracing;
|
||||
|
||||
private final FileDescriptor fd;
|
||||
|
||||
private final boolean rw;
|
||||
|
@ -376,11 +384,36 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
* end-of-file has been reached.
|
||||
*/
|
||||
public int read() throws IOException {
|
||||
if (jfrTracing && FileReadEvent.enabled()) {
|
||||
return traceRead0();
|
||||
}
|
||||
return read0();
|
||||
}
|
||||
|
||||
private native int read0() throws IOException;
|
||||
|
||||
private int traceRead0() throws IOException {
|
||||
int result = 0;
|
||||
long bytesRead = 0;
|
||||
boolean endOfFile = false;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileReadEvent.timestamp();
|
||||
result = read0();
|
||||
if (result < 0) {
|
||||
endOfFile = true;
|
||||
} else {
|
||||
bytesRead = 1;
|
||||
}
|
||||
} finally {
|
||||
long duration = FileReadEvent.timestamp() - start;
|
||||
if (FileReadEvent.shouldCommit(duration)) {
|
||||
FileReadEvent.commit(start, duration, path, bytesRead, endOfFile);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a sub array as a sequence of bytes.
|
||||
* @param b the buffer into which the data is read.
|
||||
|
@ -389,11 +422,33 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
* @throws IOException If an I/O error has occurred.
|
||||
*/
|
||||
private int readBytes(byte[] b, int off, int len) throws IOException {
|
||||
if (jfrTracing && FileReadEvent.enabled()) {
|
||||
return traceReadBytes0(b, off, len);
|
||||
}
|
||||
return readBytes0(b, off, len);
|
||||
}
|
||||
|
||||
private native int readBytes0(byte[] b, int off, int len) throws IOException;
|
||||
|
||||
private int traceReadBytes0(byte b[], int off, int len) throws IOException {
|
||||
int bytesRead = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileReadEvent.timestamp();
|
||||
bytesRead = readBytes0(b, off, len);
|
||||
} finally {
|
||||
long duration = FileReadEvent.timestamp() - start;
|
||||
if (FileReadEvent.shouldCommit(duration)) {
|
||||
if (bytesRead < 0) {
|
||||
FileReadEvent.commit(start, duration, path, 0L, true);
|
||||
} else {
|
||||
FileReadEvent.commit(start, duration, path, bytesRead, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads up to {@code len} bytes of data from this file into an
|
||||
* array of bytes. This method blocks until at least one byte of input
|
||||
|
@ -537,6 +592,14 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
* @throws IOException if an I/O error occurs.
|
||||
*/
|
||||
public void write(int b) throws IOException {
|
||||
if (jfrTracing && FileWriteEvent.enabled()) {
|
||||
traceImplWrite(b);
|
||||
return;
|
||||
}
|
||||
implWrite(b);
|
||||
}
|
||||
|
||||
private void implWrite(int b) throws IOException {
|
||||
boolean attempted = Blocker.begin(sync);
|
||||
try {
|
||||
write0(b);
|
||||
|
@ -545,6 +608,21 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
}
|
||||
}
|
||||
|
||||
private void traceImplWrite(int b) throws IOException {
|
||||
long bytesWritten = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileWriteEvent.timestamp();
|
||||
implWrite(b);
|
||||
bytesWritten = 1;
|
||||
} finally {
|
||||
long duration = FileWriteEvent.timestamp() - start;
|
||||
if (FileWriteEvent.shouldCommit(duration)) {
|
||||
FileWriteEvent.commit(start, duration, path, bytesWritten);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private native void write0(int b) throws IOException;
|
||||
|
||||
/**
|
||||
|
@ -556,6 +634,14 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
* @throws IOException If an I/O error has occurred.
|
||||
*/
|
||||
private void writeBytes(byte[] b, int off, int len) throws IOException {
|
||||
if (jfrTracing && FileWriteEvent.enabled()) {
|
||||
traceImplWriteBytes(b, off, len);
|
||||
return;
|
||||
}
|
||||
implWriteBytes(b, off, len);
|
||||
}
|
||||
|
||||
private void implWriteBytes(byte[] b, int off, int len) throws IOException {
|
||||
boolean attempted = Blocker.begin(sync);
|
||||
try {
|
||||
writeBytes0(b, off, len);
|
||||
|
@ -564,6 +650,21 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable {
|
|||
}
|
||||
}
|
||||
|
||||
private void traceImplWriteBytes(byte b[], int off, int len) throws IOException {
|
||||
long bytesWritten = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileWriteEvent.timestamp();
|
||||
implWriteBytes(b, off, len);
|
||||
bytesWritten = len;
|
||||
} finally {
|
||||
long duration = FileWriteEvent.timestamp() - start;
|
||||
if (FileWriteEvent.shouldCommit(duration)) {
|
||||
FileWriteEvent.commit(start, duration, path, bytesWritten);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private native void writeBytes0(byte[] b, int off, int len) throws IOException;
|
||||
|
||||
/**
|
||||
|
|
|
@ -120,7 +120,8 @@ public class Throwable implements Serializable {
|
|||
private static final long serialVersionUID = -3042686055658047285L;
|
||||
|
||||
/**
|
||||
* Flag that determines if exceptions should be traced by JFR
|
||||
* Flag set by jdk.internal.event.JFRTracing to indicate if
|
||||
* exceptions should be traced by JFR.
|
||||
*/
|
||||
static volatile boolean jfrTracing;
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2024, 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.internal.event;
|
||||
|
||||
/**
|
||||
* Event recording file reads.
|
||||
*/
|
||||
public final class FileReadEvent extends Event {
|
||||
|
||||
// The order of these fields must be the same as the parameters in
|
||||
// commit(..., String, long, boolean)
|
||||
public String path;
|
||||
public long bytesRead;
|
||||
public boolean endOfFile;
|
||||
|
||||
public static boolean enabled() {
|
||||
// Generated by JFR
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long timestamp() {
|
||||
// Generated by JFR
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public static boolean shouldCommit(long duration) {
|
||||
// Generated by JFR
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void commit(long start, long duration, String path, long bytesRead, boolean endOfFile) {
|
||||
// Generated by JFR
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.internal.event;
|
||||
|
||||
/**
|
||||
* Event recording file writes.
|
||||
*/
|
||||
public final class FileWriteEvent extends Event {
|
||||
|
||||
// The order of these fields must be the same as the parameters in
|
||||
// commit(..., String, long)
|
||||
public String path;
|
||||
public long bytesWritten;
|
||||
|
||||
public static boolean enabled() {
|
||||
// Generated by JFR
|
||||
return false;
|
||||
}
|
||||
|
||||
public static long timestamp() {
|
||||
// Generated by JFR
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public static boolean shouldCommit(long duration) {
|
||||
// Generated by JFR
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void commit(long start, long duration, String path, long bytesWritten) {
|
||||
// Generated by JFR
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2024, 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.internal.event;
|
||||
|
||||
import sun.nio.ch.FileChannelImpl;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.lang.Throwable;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Helper class to enable JFR tracing.
|
||||
*/
|
||||
public final class JFRTracing {
|
||||
|
||||
public static void enable() throws NoSuchFieldException, IllegalAccessException {
|
||||
enable(Throwable.class);
|
||||
enable(FileInputStream.class);
|
||||
enable(FileOutputStream.class);
|
||||
enable(FileChannelImpl.class);
|
||||
enable(RandomAccessFile.class);
|
||||
}
|
||||
|
||||
private static void enable(Class<?> clazz) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field field = clazz.getDeclaredField("jfrTracing");
|
||||
field.setAccessible(true);
|
||||
field.setBoolean(null, true);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2024, 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
|
||||
|
@ -24,7 +24,6 @@
|
|||
*/
|
||||
package jdk.internal.event;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
|
@ -34,12 +33,6 @@ public final class ThrowableTracer {
|
|||
|
||||
private static final AtomicLong numThrowables = new AtomicLong();
|
||||
|
||||
public static void enable() throws NoSuchFieldException, IllegalAccessException {
|
||||
Field field = Throwable.class.getDeclaredField("jfrTracing");
|
||||
field.setAccessible(true);
|
||||
field.setBoolean(null, true);
|
||||
}
|
||||
|
||||
public static void traceError(Class<?> clazz, String message) {
|
||||
if (OutOfMemoryError.class.isAssignableFrom(clazz)) {
|
||||
return;
|
||||
|
|
|
@ -60,7 +60,8 @@ import jdk.internal.misc.VM;
|
|||
import jdk.internal.misc.VM.BufferPool;
|
||||
import jdk.internal.ref.Cleaner;
|
||||
import jdk.internal.ref.CleanerFactory;
|
||||
|
||||
import jdk.internal.event.FileReadEvent;
|
||||
import jdk.internal.event.FileWriteEvent;
|
||||
import jdk.internal.access.foreign.UnmapperProxy;
|
||||
|
||||
public class FileChannelImpl
|
||||
|
@ -73,6 +74,10 @@ public class FileChannelImpl
|
|||
// Used to make native read and write calls
|
||||
private static final FileDispatcher nd = new FileDispatcherImpl();
|
||||
|
||||
// Flag set by jdk.internal.event.JFRTracing to indicate if
|
||||
// file reads and writes should be traced by JFR.
|
||||
private static boolean jfrTracing;
|
||||
|
||||
// File descriptor
|
||||
private final FileDescriptor fd;
|
||||
|
||||
|
@ -220,6 +225,13 @@ public class FileChannelImpl
|
|||
|
||||
@Override
|
||||
public int read(ByteBuffer dst) throws IOException {
|
||||
if (jfrTracing && FileReadEvent.enabled()) {
|
||||
return traceImplRead(dst);
|
||||
}
|
||||
return implRead(dst);
|
||||
}
|
||||
|
||||
private int implRead(ByteBuffer dst) throws IOException {
|
||||
ensureOpen();
|
||||
if (!readable)
|
||||
throw new NonReadableChannelException();
|
||||
|
@ -250,8 +262,34 @@ public class FileChannelImpl
|
|||
}
|
||||
}
|
||||
|
||||
private int traceImplRead(ByteBuffer dst) throws IOException {
|
||||
int bytesRead = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileReadEvent.timestamp();
|
||||
bytesRead = implRead(dst);
|
||||
} finally {
|
||||
long duration = FileReadEvent.timestamp() - start;
|
||||
if (FileReadEvent.shouldCommit(duration)) {
|
||||
if (bytesRead < 0) {
|
||||
FileReadEvent.commit(start, duration, path, 0L, true);
|
||||
} else {
|
||||
FileReadEvent.commit(start, duration, path, bytesRead, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long read(ByteBuffer[] dsts, int offset, int length)
|
||||
public long read(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
||||
if (jfrTracing && FileReadEvent.enabled()) {
|
||||
return traceImplRead(dsts, offset, length);
|
||||
}
|
||||
return implRead(dsts, offset, length);
|
||||
}
|
||||
|
||||
private long implRead(ByteBuffer[] dsts, int offset, int length)
|
||||
throws IOException
|
||||
{
|
||||
Objects.checkFromIndexSize(offset, length, dsts.length);
|
||||
|
@ -286,8 +324,34 @@ public class FileChannelImpl
|
|||
}
|
||||
}
|
||||
|
||||
private long traceImplRead(ByteBuffer[] dsts, int offset, int length) throws IOException {
|
||||
long bytesRead = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileReadEvent.timestamp();
|
||||
bytesRead = implRead(dsts, offset, length);
|
||||
} finally {
|
||||
long duration = FileReadEvent.timestamp() - start;
|
||||
if (FileReadEvent.shouldCommit(duration)) {
|
||||
if (bytesRead < 0) {
|
||||
FileReadEvent.commit(start, duration, path, 0L, true);
|
||||
} else {
|
||||
FileReadEvent.commit(start, duration, path, bytesRead, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
if (jfrTracing && FileWriteEvent.enabled()) {
|
||||
return traceImplWrite(src);
|
||||
}
|
||||
return implWrite(src);
|
||||
}
|
||||
|
||||
private int implWrite(ByteBuffer src) throws IOException {
|
||||
ensureOpen();
|
||||
if (!writable)
|
||||
throw new NonWritableChannelException();
|
||||
|
@ -319,10 +383,31 @@ public class FileChannelImpl
|
|||
}
|
||||
}
|
||||
|
||||
private int traceImplWrite(ByteBuffer src) throws IOException {
|
||||
int bytesWritten = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileWriteEvent.timestamp();
|
||||
bytesWritten = implWrite(src);
|
||||
} finally {
|
||||
long duration = FileWriteEvent.timestamp() - start;
|
||||
if (FileWriteEvent.shouldCommit(duration)) {
|
||||
long bytes = bytesWritten > 0 ? bytesWritten : 0;
|
||||
FileWriteEvent.commit(start, duration, path, bytes);
|
||||
}
|
||||
}
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long write(ByteBuffer[] srcs, int offset, int length)
|
||||
throws IOException
|
||||
{
|
||||
public long write(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
||||
if (jfrTracing && FileWriteEvent.enabled()) {
|
||||
return traceImplWrite(srcs, offset, length);
|
||||
}
|
||||
return implWrite(srcs, offset, length);
|
||||
}
|
||||
|
||||
private long implWrite(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
||||
Objects.checkFromIndexSize(offset, length, srcs.length);
|
||||
ensureOpen();
|
||||
if (!writable)
|
||||
|
@ -354,6 +439,21 @@ public class FileChannelImpl
|
|||
}
|
||||
}
|
||||
|
||||
private long traceImplWrite(ByteBuffer[] srcs, int offset, int length) throws IOException {
|
||||
long bytesWritten = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileWriteEvent.timestamp();
|
||||
bytesWritten = implWrite(srcs, offset, length);
|
||||
} finally {
|
||||
long duration = FileWriteEvent.timestamp() - start;
|
||||
if (FileWriteEvent.shouldCommit(duration)) {
|
||||
long bytes = bytesWritten > 0 ? bytesWritten : 0;
|
||||
FileWriteEvent.commit(start, duration, path, bytes);
|
||||
}
|
||||
}
|
||||
return bytesWritten;
|
||||
}
|
||||
// -- Other operations --
|
||||
|
||||
@Override
|
||||
|
@ -1028,6 +1128,13 @@ public class FileChannelImpl
|
|||
|
||||
@Override
|
||||
public int read(ByteBuffer dst, long position) throws IOException {
|
||||
if (jfrTracing && FileReadEvent.enabled()) {
|
||||
return traceImplRead(dst, position);
|
||||
}
|
||||
return implRead(dst, position);
|
||||
}
|
||||
|
||||
private int implRead(ByteBuffer dst, long position) throws IOException {
|
||||
if (dst == null)
|
||||
throw new NullPointerException();
|
||||
if (position < 0)
|
||||
|
@ -1046,6 +1153,25 @@ public class FileChannelImpl
|
|||
}
|
||||
}
|
||||
|
||||
private int traceImplRead(ByteBuffer dst, long position) throws IOException {
|
||||
int bytesRead = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileReadEvent.timestamp();
|
||||
bytesRead = implRead(dst, position);
|
||||
} finally {
|
||||
long duration = FileReadEvent.timestamp() - start;
|
||||
if (FileReadEvent.shouldCommit(duration)) {
|
||||
if (bytesRead < 0) {
|
||||
FileReadEvent.commit(start, duration, path, 0L, true);
|
||||
} else {
|
||||
FileReadEvent.commit(start, duration, path, bytesRead, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
private int readInternal(ByteBuffer dst, long position) throws IOException {
|
||||
assert !nd.needsPositionLock() || Thread.holdsLock(positionLock);
|
||||
int n = 0;
|
||||
|
@ -1074,6 +1200,13 @@ public class FileChannelImpl
|
|||
|
||||
@Override
|
||||
public int write(ByteBuffer src, long position) throws IOException {
|
||||
if (jfrTracing && FileReadEvent.enabled()) {
|
||||
return traceImplWrite(src, position);
|
||||
}
|
||||
return implWrite(src, position);
|
||||
}
|
||||
|
||||
private int implWrite(ByteBuffer src, long position) throws IOException {
|
||||
if (src == null)
|
||||
throw new NullPointerException();
|
||||
if (position < 0)
|
||||
|
@ -1092,6 +1225,22 @@ public class FileChannelImpl
|
|||
}
|
||||
}
|
||||
|
||||
private int traceImplWrite(ByteBuffer src, long position) throws IOException {
|
||||
int bytesWritten = 0;
|
||||
long start = 0;
|
||||
try {
|
||||
start = FileWriteEvent.timestamp();
|
||||
bytesWritten = implWrite(src, position);
|
||||
} finally {
|
||||
long duration = FileWriteEvent.timestamp() - start;
|
||||
if (FileWriteEvent.shouldCommit(duration)) {
|
||||
long bytes = bytesWritten > 0 ? bytesWritten : 0;
|
||||
FileWriteEvent.commit(start, duration, path, bytes);
|
||||
}
|
||||
}
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
private int writeInternal(ByteBuffer src, long position) throws IOException {
|
||||
assert !nd.needsPositionLock() || Thread.holdsLock(positionLock);
|
||||
int n = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue