Skip to content

Commit 5891509

Browse files
committed
8259947: (fs) Optimize UnixPath.encode implementation
Reviewed-by: chegar, shade, alanb
1 parent 69f90b5 commit 5891509

File tree

6 files changed

+64
-67
lines changed

6 files changed

+64
-67
lines changed

src/java.base/macosx/classes/sun/nio/fs/BsdNativeDispatcher.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,6 @@
2525

2626
package sun.nio.fs;
2727

28-
import java.security.AccessController;
29-
import java.security.PrivilegedAction;
30-
3128
/**
3229
* Bsd specific system calls.
3330
*/

src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,6 @@
2525

2626
package sun.nio.fs;
2727

28-
import java.nio.file.*;
29-
import java.io.IOException;
30-
import java.util.*;
3128
import java.util.regex.Pattern;
3229

3330
import static sun.nio.fs.MacOSXNativeDispatcher.*;
@@ -47,14 +44,18 @@ Pattern compilePathMatchPattern(String expr) {
4744
return Pattern.compile(expr, Pattern.CANON_EQ) ;
4845
}
4946

50-
char[] normalizeNativePath(char[] path) {
51-
for (char c : path) {
47+
@Override
48+
String normalizeNativePath(String path) {
49+
for (int i = 0; i < path.length(); i++) {
50+
char c = path.charAt(i);
5251
if (c > 0x80)
53-
return normalizepath(path, kCFStringNormalizationFormD);
52+
return new String(normalizepath(path.toCharArray(),
53+
kCFStringNormalizationFormD));
5454
}
5555
return path;
5656
}
5757

58+
@Override
5859
String normalizeJavaPath(String path) {
5960
for (int i = 0; i < path.length(); i++) {
6061
if (path.charAt(i) > 0x80)

src/java.base/macosx/classes/sun/nio/fs/MacOSXNativeDispatcher.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,6 @@
2525

2626
package sun.nio.fs;
2727

28-
import java.security.AccessController;
29-
import java.security.PrivilegedAction;
30-
3128
/**
3229
* MacOSX specific system calls.
3330
*/

src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -343,7 +343,7 @@ Pattern compilePathMatchPattern(String expr) {
343343
// Override if the platform uses different Unicode normalization form
344344
// for native file path. For example on MacOSX, the native path is stored
345345
// in Unicode NFD form.
346-
char[] normalizeNativePath(char[] path) {
346+
String normalizeNativePath(String path) {
347347
return path;
348348
}
349349

src/java.base/unix/classes/sun/nio/fs/UnixPath.java

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,26 +25,25 @@
2525

2626
package sun.nio.fs;
2727

28-
import java.nio.*;
2928
import java.nio.file.*;
3029
import java.nio.charset.*;
3130
import java.io.*;
3231
import java.net.URI;
3332
import java.util.*;
34-
import java.lang.ref.SoftReference;
33+
34+
import jdk.internal.access.JavaLangAccess;
35+
import jdk.internal.access.SharedSecrets;
3536

3637
import static sun.nio.fs.UnixNativeDispatcher.*;
3738
import static sun.nio.fs.UnixConstants.*;
3839

3940
/**
40-
* Solaris/Linux implementation of java.nio.file.Path
41+
* Linux/Mac implementation of java.nio.file.Path
4142
*/
42-
4343
class UnixPath implements Path {
44-
private static ThreadLocal<SoftReference<CharsetEncoder>> encoder =
45-
new ThreadLocal<SoftReference<CharsetEncoder>>();
4644

47-
// FIXME - eliminate this reference to reduce space
45+
private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
46+
4847
private final UnixFileSystem fs;
4948

5049
// internal representation
@@ -115,43 +114,13 @@ private static String normalize(String input, int len, int off) {
115114

116115
// encodes the given path-string into a sequence of bytes
117116
private static byte[] encode(UnixFileSystem fs, String input) {
118-
SoftReference<CharsetEncoder> ref = encoder.get();
119-
CharsetEncoder ce = (ref != null) ? ref.get() : null;
120-
if (ce == null) {
121-
ce = Util.jnuEncoding().newEncoder()
122-
.onMalformedInput(CodingErrorAction.REPORT)
123-
.onUnmappableCharacter(CodingErrorAction.REPORT);
124-
encoder.set(new SoftReference<>(ce));
125-
}
126-
127-
char[] ca = fs.normalizeNativePath(input.toCharArray());
128-
129-
// size output buffer for worse-case size
130-
byte[] ba = new byte[(int)(ca.length * (double)ce.maxBytesPerChar())];
131-
132-
// encode
133-
ByteBuffer bb = ByteBuffer.wrap(ba);
134-
CharBuffer cb = CharBuffer.wrap(ca);
135-
ce.reset();
136-
CoderResult cr = ce.encode(cb, bb, true);
137-
boolean error;
138-
if (!cr.isUnderflow()) {
139-
error = true;
140-
} else {
141-
cr = ce.flush(bb);
142-
error = !cr.isUnderflow();
143-
}
144-
if (error) {
117+
input = fs.normalizeNativePath(input);
118+
try {
119+
return JLA.getBytesNoRepl(input, Util.jnuEncoding());
120+
} catch (CharacterCodingException cce) {
145121
throw new InvalidPathException(input,
146122
"Malformed input or input contains unmappable characters");
147123
}
148-
149-
// trim result to actual length if required
150-
int len = bb.position();
151-
if (len != ba.length)
152-
ba = Arrays.copyOf(ba, len);
153-
154-
return ba;
155124
}
156125

157126
// package-private

test/micro/org/openjdk/bench/java/io/FileOpen.java

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -27,24 +27,24 @@
2727

2828
import java.io.File;
2929
import java.io.IOException;
30-
import java.nio.file.Files;
30+
import java.nio.file.Path;
3131
import java.util.concurrent.TimeUnit;
3232

3333
/**
34-
* Tests the overheads of I/O API.
34+
* Tests the overheads of creating File objects, and converting such objects to Paths.
3535
*/
3636
@BenchmarkMode(Mode.AverageTime)
37-
@OutputTimeUnit(TimeUnit.MICROSECONDS)
37+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
3838
@State(Scope.Thread)
3939
@Warmup(time=2, iterations=5)
4040
@Measurement(time=3, iterations=5)
4141
@Fork(value=2, jvmArgs="-Xmx1g")
4242
public class FileOpen {
4343

44-
public String normalFile = "/test/dir/file/name.txt";
45-
public String root = "/";
46-
public String trailingSlash = "/test/dir/file/name.txt/";
47-
public String notNormalizedFile = "/test/dir/file//name.txt";
44+
private String normalFile = "/test/dir/file/name.txt";
45+
private String root = "/";
46+
private String trailingSlash = "/test/dir/file/name.txt/";
47+
private String notNormalizedFile = "/test/dir/file//name.txt";
4848

4949
public File tmp;
5050

@@ -68,6 +68,11 @@ public File normalized() {
6868
return new File(normalFile);
6969
}
7070

71+
@Benchmark
72+
public File root() {
73+
return new File(root);
74+
}
75+
7176
@Benchmark
7277
public File trailingSlash() {
7378
return new File(trailingSlash);
@@ -85,4 +90,32 @@ public boolean booleanAttributes() {
8590
&& tmp.isDirectory()
8691
&& tmp.isFile();
8792
}
93+
94+
@Benchmark
95+
public void mixToPath(Blackhole bh) {
96+
bh.consume(new File(normalFile).toPath());
97+
bh.consume(new File(root).toPath());
98+
bh.consume(new File(trailingSlash).toPath());
99+
bh.consume(new File(notNormalizedFile).toPath());
100+
}
101+
102+
@Benchmark
103+
public Path normalizedToPath() {
104+
return new File(normalFile).toPath();
105+
}
106+
107+
@Benchmark
108+
public Path rootToPath() {
109+
return new File(root).toPath();
110+
}
111+
112+
@Benchmark
113+
public Path trailingSlashToPath() {
114+
return new File(trailingSlash).toPath();
115+
}
116+
117+
@Benchmark
118+
public Path notNormalizedToPath() {
119+
return new File(notNormalizedFile).toPath();
120+
}
88121
}

0 commit comments

Comments
 (0)