OpenJDK / jdk / jdk
changeset 59277:ab5848d09175
8244936: Reduce JNI overhead of accessing FileDescriptor
Reviewed-by: rriggs, alanb
author | redestad |
---|---|
date | Wed, 13 May 2020 22:25:14 +0200 |
parents | 0312e36e1daf |
children | 26a4100f7102 |
files | src/java.base/share/native/libjava/FileInputStream.c src/java.base/share/native/libjava/RandomAccessFile.c src/java.base/share/native/libjava/io_util.c src/java.base/unix/native/libjava/io_util_md.c src/java.base/unix/native/libjava/io_util_md.h src/java.base/windows/native/libjava/io_util_md.c src/java.base/windows/native/libjava/io_util_md.h test/micro/org/openjdk/bench/java/io/RandomAccessRead.java |
diffstat | 8 files changed, 66 insertions(+), 45 deletions(-) [+] |
line wrap: on
line diff
--- a/src/java.base/share/native/libjava/FileInputStream.c Wed May 13 20:19:09 2020 +0200 +++ b/src/java.base/share/native/libjava/FileInputStream.c Wed May 13 22:25:14 2020 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, 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 @@ -76,7 +76,7 @@ Java_java_io_FileInputStream_skip0(JNIEnv *env, jobject this, jlong toSkip) { jlong cur = jlong_zero; jlong end = jlong_zero; - FD fd = GET_FD(this, fis_fd); + FD fd = getFD(env, this, fis_fd); if (fd == -1) { JNU_ThrowIOException (env, "Stream Closed"); return 0; @@ -92,7 +92,7 @@ JNIEXPORT jint JNICALL Java_java_io_FileInputStream_available0(JNIEnv *env, jobject this) { jlong ret; - FD fd = GET_FD(this, fis_fd); + FD fd = getFD(env, this, fis_fd); if (fd == -1) { JNU_ThrowIOException (env, "Stream Closed"); return 0;
--- a/src/java.base/share/native/libjava/RandomAccessFile.c Wed May 13 20:19:09 2020 +0200 +++ b/src/java.base/share/native/libjava/RandomAccessFile.c Wed May 13 22:25:14 2020 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2020, 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 @@ -94,7 +94,7 @@ FD fd; jlong ret; - fd = GET_FD(this, raf_fd); + fd = getFD(env, this, raf_fd); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); return -1; @@ -111,7 +111,7 @@ FD fd; jlong length = jlong_zero; - fd = GET_FD(this, raf_fd); + fd = getFD(env, this, raf_fd); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); return -1; @@ -128,7 +128,7 @@ FD fd; - fd = GET_FD(this, raf_fd); + fd = getFD(env, this, raf_fd); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); return; @@ -147,7 +147,7 @@ FD fd; jlong cur; - fd = GET_FD(this, raf_fd); + fd = getFD(env, this, raf_fd); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); return;
--- a/src/java.base/share/native/libjava/io_util.c Wed May 13 20:19:09 2020 +0200 +++ b/src/java.base/share/native/libjava/io_util.c Wed May 13 22:25:14 2020 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2020, 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 @@ -39,7 +39,7 @@ readSingle(JNIEnv *env, jobject this, jfieldID fid) { jint nread; char ret; - FD fd = GET_FD(this, fid); + FD fd = getFD(env, this, fid); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); return -1; @@ -101,7 +101,7 @@ buf = stackBuf; } - fd = GET_FD(this, fid); + fd = getFD(env, this, fid); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); nread = -1; @@ -127,7 +127,7 @@ // Discard the 24 high-order bits of byte. See OutputStream#write(int) char c = (char) byte; jint n; - FD fd = GET_FD(this, fid); + FD fd = getFD(env, this, fid); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); return; @@ -178,7 +178,7 @@ if (!(*env)->ExceptionOccurred(env)) { off = 0; while (len > 0) { - fd = GET_FD(this, fid); + fd = getFD(env, this, fid); if (fd == -1) { JNU_ThrowIOException(env, "Stream Closed"); break;
--- a/src/java.base/unix/native/libjava/io_util_md.c Wed May 13 20:19:09 2020 +0200 +++ b/src/java.base/unix/native/libjava/io_util_md.c Wed May 13 22:25:14 2020 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, 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 @@ -92,6 +92,14 @@ return fd; } +FD getFD(JNIEnv *env, jobject obj, jfieldID fid) { + jobject fdo = (*env)->GetObjectField(env, obj, fid); + if (fdo == NULL) { + return -1; + } + return (*env)->GetIntField(env, fdo, IO_fd_fdID); +} + void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) { @@ -108,10 +116,10 @@ if (fd != -1) { jobject fdobj; jboolean append; - SET_FD(this, fd, fid); - fdobj = (*env)->GetObjectField(env, this, fid); if (fdobj != NULL) { + // Set FD + (*env)->SetIntField(env, fdobj, IO_fd_fdID, fd); append = (flags & O_APPEND) == 0 ? JNI_FALSE : JNI_TRUE; (*env)->SetBooleanField(env, fdobj, IO_append_fdID, append); }
--- a/src/java.base/unix/native/libjava/io_util_md.h Wed May 13 20:19:09 2020 +0200 +++ b/src/java.base/unix/native/libjava/io_util_md.h Wed May 13 22:25:14 2020 +0200 @@ -43,20 +43,12 @@ FD handleOpen(const char *path, int oflag, int mode); /* - * Macros to set/get fd from the java.io.FileDescriptor. These - * macros rely on having an appropriately defined 'this' object - * within the scope in which they're used. - * If GetObjectField returns null, SET_FD will stop and GET_FD - * will simply return -1 to avoid crashing VM. + * Functions to get fd from the java.io.FileDescriptor field + * of an object. These functions rely on having an appropriately + * defined object with a FileDescriptor object at the fid offset. + * If the FD object is null, return -1 to avoid crashing VM. */ - -#define SET_FD(this, fd, fid) \ - if ((*env)->GetObjectField(env, (this), (fid)) != NULL) \ - (*env)->SetIntField(env, (*env)->GetObjectField(env, (this), (fid)),IO_fd_fdID, (fd)) - -#define GET_FD(this, fid) \ - (*env)->GetObjectField(env, (this), (fid)) == NULL ? \ - -1 : (*env)->GetIntField(env, (*env)->GetObjectField(env, (this), (fid)), IO_fd_fdID) +FD getFD(JNIEnv *env, jobject cur, jfieldID fid); /* * Macros to set/get fd when inside java.io.FileDescriptor
--- a/src/java.base/windows/native/libjava/io_util_md.c Wed May 13 20:19:09 2020 +0200 +++ b/src/java.base/windows/native/libjava/io_util_md.c Wed May 13 22:25:14 2020 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2020, 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 @@ -259,6 +259,14 @@ return (jlong) h; } +FD getFD(JNIEnv *env, jobject obj, jfieldID fid) { + jobject fdo = (*env)->GetObjectField(env, obj, fid); + if (fdo == NULL) { + return -1; + } + return (*env)->GetLongField(env, fdo, IO_handle_fdID); +} + void fileOpen(JNIEnv *env, jobject this, jstring path, jfieldID fid, int flags) { @@ -266,10 +274,10 @@ if (h >= 0) { jobject fdobj; jboolean append; - SET_FD(this, h, fid); - fdobj = (*env)->GetObjectField(env, this, fid); if (fdobj != NULL) { + // Set FD + (*env)->SetLongField(env, fdobj, IO_handle_fdID, h); append = (flags & O_APPEND) == 0 ? JNI_FALSE : JNI_TRUE; (*env)->SetBooleanField(env, fdobj, IO_append_fdID, append); }
--- a/src/java.base/windows/native/libjava/io_util_md.h Wed May 13 20:19:09 2020 +0200 +++ b/src/java.base/windows/native/libjava/io_util_md.h Wed May 13 22:25:14 2020 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2020, 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 @@ -59,17 +59,12 @@ FD winFileHandleOpen(JNIEnv *env, jstring path, int flags); /* - * Macros to set/get fd from the java.io.FileDescriptor. - * If GetObjectField returns null, SET_FD will stop and GET_FD - * will simply return -1 to avoid crashing VM. + * Function to get fd from the java.io.FileDescriptor field of an + * object. These functions rely on having an appropriately + * defined object with a FileDescriptor object at the fid offset. + * If the FD object is null, return -1 to avoid crashing VM. */ -#define SET_FD(this, fd, fid) \ - if ((*env)->GetObjectField(env, (this), (fid)) != NULL) \ - (*env)->SetLongField(env, (*env)->GetObjectField(env, (this), (fid)), IO_handle_fdID, (fd)) - -#define GET_FD(this, fid) \ - ((*env)->GetObjectField(env, (this), (fid)) == NULL) ? \ - -1 : (*env)->GetLongField(env, (*env)->GetObjectField(env, (this), (fid)), IO_handle_fdID) +FD getFD(JNIEnv *env, jobject cur, jfieldID fid); /* * Macros to set/get fd when inside java.io.FileDescriptor
--- a/test/micro/org/openjdk/bench/java/io/RandomAccessRead.java Wed May 13 20:19:09 2020 +0200 +++ b/test/micro/org/openjdk/bench/java/io/RandomAccessRead.java Wed May 13 22:25:14 2020 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2020, 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 @@ -51,11 +51,15 @@ @Param("1000000") private int fileSize; + @Param("8192") + private int buffer; + private RandomAccessFile raf; private long offset; private int deltaIndex; private int[] deltas; private File f; + private byte[] buf; @Setup(Level.Trial) public void beforeRun() throws IOException { @@ -66,6 +70,7 @@ } } deltas = new int[]{1, 2, 3, 5, 7, 11, 13, 17, 19, 23}; + buf = new byte[buffer]; } @TearDown(Level.Trial) @@ -86,6 +91,20 @@ } @Benchmark + public int testBuffer() throws IOException { + offset = offset + deltas[deltaIndex]; + if (offset >= fileSize) { + offset = 0; + } + deltaIndex++; + if (deltaIndex >= deltas.length) { + deltaIndex = 0; + } + raf.seek(offset); + return raf.read(buf); + } + + @Benchmark public int test() throws IOException { offset = offset + deltas[deltaIndex]; if (offset >= fileSize) { @@ -98,5 +117,4 @@ raf.seek(offset); return raf.read(); } - }