From df509b1b162b96ce79f88dcc8cce61036fca9e1e Mon Sep 17 00:00:00 2001
From: Michael Skells <mike.skells1@gmail.com>
Date: Thu, 21 Jun 2018 11:10:55 -0700
Subject: [PATCH] 8199124: (fs) Reduce allocation for file system methods that
 are invoked with no open options

Reviewed-by: alanb
---
 .../nio/channels/AsynchronousFileChannel.java    | 11 ++++++++---
 .../classes/java/nio/channels/FileChannel.java   | 11 ++++++++---
 .../share/classes/java/nio/file/Files.java       | 16 +++++++++++-----
 .../java/nio/file/spi/FileSystemProvider.java    | 14 +++++++++-----
 4 files changed, 36 insertions(+), 16 deletions(-)

diff --git a/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java b/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java
index 26d2313f5f8..17f6ff076a9 100644
--- a/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java
+++ b/src/java.base/share/classes/java/nio/channels/AsynchronousFileChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, 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
@@ -301,8 +301,13 @@ public abstract class AsynchronousFileChannel
     public static AsynchronousFileChannel open(Path file, OpenOption... options)
         throws IOException
     {
-        Set<OpenOption> set = new HashSet<>(options.length);
-        Collections.addAll(set, options);
+        Set<OpenOption> set;
+        if (options.length == 0) {
+            set = Collections.emptySet();
+        } else {
+            set = new HashSet<>();
+            Collections.addAll(set, options);
+        }
         return open(file, set, null, NO_ATTRIBUTES);
     }
 
diff --git a/src/java.base/share/classes/java/nio/channels/FileChannel.java b/src/java.base/share/classes/java/nio/channels/FileChannel.java
index 4463e5a5d82..055cbfc7dad 100644
--- a/src/java.base/share/classes/java/nio/channels/FileChannel.java
+++ b/src/java.base/share/classes/java/nio/channels/FileChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2018, 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
@@ -335,8 +335,13 @@ public abstract class FileChannel
     public static FileChannel open(Path path, OpenOption... options)
         throws IOException
     {
-        Set<OpenOption> set = new HashSet<>(options.length);
-        Collections.addAll(set, options);
+        Set<OpenOption> set;
+        if (options.length == 0) {
+            set = Collections.emptySet();
+        } else {
+            set = new HashSet<>();
+            Collections.addAll(set, options);
+        }
         return open(path, set, NO_ATTRIBUTES);
     }
 
diff --git a/src/java.base/share/classes/java/nio/file/Files.java b/src/java.base/share/classes/java/nio/file/Files.java
index 348e0555dd5..82fad22b200 100644
--- a/src/java.base/share/classes/java/nio/file/Files.java
+++ b/src/java.base/share/classes/java/nio/file/Files.java
@@ -410,8 +410,13 @@ public final class Files {
     public static SeekableByteChannel newByteChannel(Path path, OpenOption... options)
         throws IOException
     {
-        Set<OpenOption> set = new HashSet<>(options.length);
-        Collections.addAll(set, options);
+        Set<OpenOption> set;
+        if (options.length == 0) {
+            set = Collections.emptySet();
+        } else {
+            set = new HashSet<>();
+            Collections.addAll(set, options);
+        }
         return newByteChannel(path, set);
     }
 
@@ -599,6 +604,9 @@ public final class Files {
 
     // -- Creation and deletion --
 
+    private static final Set<OpenOption> DEFAULT_CREATE_OPTIONS =
+        Set.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
+
     /**
      * Creates a new and empty file, failing if the file already exists. The
      * check for the existence of the file and the creation of the new file if
@@ -635,9 +643,7 @@ public final class Files {
     public static Path createFile(Path path, FileAttribute<?>... attrs)
         throws IOException
     {
-        EnumSet<StandardOpenOption> options =
-            EnumSet.<StandardOpenOption>of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
-        newByteChannel(path, options, attrs).close();
+        newByteChannel(path, DEFAULT_CREATE_OPTIONS, attrs).close();
         return path;
     }
 
diff --git a/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java b/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java
index 0af9162a768..08717711137 100644
--- a/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java
+++ b/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2018, 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
@@ -384,6 +384,10 @@ public abstract class FileSystemProvider {
         return Channels.newInputStream(Files.newByteChannel(path, options));
     }
 
+    private static final Set<OpenOption> DEFAULT_OPEN_OPTIONS =
+        Set.of(StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING,
+            StandardOpenOption.WRITE);
+
     /**
      * Opens or creates a file, returning an output stream that may be used to
      * write bytes to the file. This method works in exactly the manner
@@ -419,18 +423,18 @@ public abstract class FileSystemProvider {
         throws IOException
     {
         int len = options.length;
-        Set<OpenOption> opts = new HashSet<>(len + 3);
+        Set<OpenOption> opts ;
         if (len == 0) {
-            opts.add(StandardOpenOption.CREATE);
-            opts.add(StandardOpenOption.TRUNCATE_EXISTING);
+            opts = DEFAULT_OPEN_OPTIONS;
         } else {
+            opts = new HashSet<>();
             for (OpenOption opt: options) {
                 if (opt == StandardOpenOption.READ)
                     throw new IllegalArgumentException("READ not allowed");
                 opts.add(opt);
             }
+            opts.add(StandardOpenOption.WRITE);
         }
-        opts.add(StandardOpenOption.WRITE);
         return Channels.newOutputStream(newByteChannel(path, opts));
     }