Skip to content

Commit

Permalink
8300977: Retire java.io.ExpiringCache
Browse files Browse the repository at this point in the history
Reviewed-by: alanb, jpai
  • Loading branch information
minborg committed Mar 28, 2023
1 parent c90699e commit 927e674
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 434 deletions.
125 changes: 0 additions & 125 deletions src/java.base/share/classes/java/io/ExpiringCache.java

This file was deleted.

16 changes: 1 addition & 15 deletions src/java.base/share/classes/java/io/FileSystem.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
Expand Down Expand Up @@ -243,18 +243,4 @@ public abstract boolean createFileExclusively(String pathname)
*/
public abstract int hashCode(File f);

// Flags for enabling/disabling performance optimizations for file
// name canonicalization
static final boolean useCanonCaches;
static final boolean useCanonPrefixCache;

private static boolean getBooleanProperty(String prop, boolean defaultVal) {
String value = System.getProperty(prop);
return (value != null) ? Boolean.parseBoolean(value) : defaultVal;
}

static {
useCanonCaches = getBooleanProperty("sun.io.useCanonCaches", false);
useCanonPrefixCache = useCanonCaches && getBooleanProperty("sun.io.useCanonPrefixCache", false);
}
}
6 changes: 4 additions & 2 deletions src/java.base/unix/classes/java/io/DefaultFileSystem.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 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
Expand Down Expand Up @@ -29,7 +29,9 @@
*
* @since 1.8
*/
class DefaultFileSystem {
final class DefaultFileSystem {

private DefaultFileSystem() {}

/**
* Return the FileSystem object for Unix-based platform.
Expand Down
147 changes: 9 additions & 138 deletions src/java.base/unix/classes/java/io/UnixFileSystem.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 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
Expand Down Expand Up @@ -30,24 +30,19 @@
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;

class UnixFileSystem extends FileSystem {
final class UnixFileSystem extends FileSystem {

private final char slash;
private final char colon;
private final String javaHome;
private final String userDir;

public UnixFileSystem() {
UnixFileSystem() {
Properties props = GetPropertyAction.privilegedGetProperties();
slash = props.getProperty("file.separator").charAt(0);
colon = props.getProperty("path.separator").charAt(0);
javaHome = StaticProperty.javaHome();
userDir = StaticProperty.userDir();
cache = useCanonCaches ? new ExpiringCache() : null;
javaHomePrefixCache = useCanonPrefixCache ? new ExpiringCache() : null;
}


/* -- Normalization and construction -- */

@Override
Expand Down Expand Up @@ -142,7 +137,7 @@ public boolean isAbsolute(File f) {

@Override
public boolean isInvalid(File f) {
return f.getPath().indexOf('\u0000') < 0 ? false : true;
return f.getPath().indexOf('\u0000') >= 0;
}

@Override
Expand All @@ -156,117 +151,16 @@ public String resolve(File f) {
return resolve(userDir, f.getPath());
}

// Caches for canonicalization results to improve startup performance.
// The first cache handles repeated canonicalizations of the same path
// name. The prefix cache handles repeated canonicalizations within the
// same directory, and must not create results differing from the true
// canonicalization algorithm in canonicalize_md.c. For this reason the
// prefix cache is conservative and is not used for complex path names.
private final ExpiringCache cache;
// On Unix symlinks can jump anywhere in the file system, so we only
// treat prefixes in java.home as trusted and cacheable in the
// canonicalization algorithm
private final ExpiringCache javaHomePrefixCache;

@Override
public String canonicalize(String path) throws IOException {
if (!useCanonCaches) {
long comp = Blocker.begin();
try {
return canonicalize0(path);
} finally {
Blocker.end(comp);
}
} else {
String res = cache.get(path);
if (res == null) {
String dir = null;
String resDir;
if (useCanonPrefixCache) {
// Note that this can cause symlinks that should
// be resolved to a destination directory to be
// resolved to the directory they're contained in
dir = parentOrNull(path);
if (dir != null) {
resDir = javaHomePrefixCache.get(dir);
if (resDir != null) {
// Hit only in prefix cache; full path is canonical
String filename = path.substring(1 + dir.length());
res = resDir + slash + filename;
cache.put(dir + slash + filename, res);
}
}
}
if (res == null) {
long comp = Blocker.begin();
try {
res = canonicalize0(path);
} finally {
Blocker.end(comp);
}
cache.put(path, res);
if (useCanonPrefixCache &&
dir != null && dir.startsWith(javaHome)) {
resDir = parentOrNull(res);
// Note that we don't allow a resolved symlink
// to elsewhere in java.home to pollute the
// prefix cache (java.home prefix cache could
// just as easily be a set at this point)
if (resDir != null && resDir.equals(dir)) {
File f = new File(res);
if (f.exists() && !f.isDirectory()) {
javaHomePrefixCache.put(dir, resDir);
}
}
}
}
}
return res;
long comp = Blocker.begin();
try {
return canonicalize0(path);
} finally {
Blocker.end(comp);
}
}
private native String canonicalize0(String path) throws IOException;
// Best-effort attempt to get parent of this path; used for
// optimization of filename canonicalization. This must return null for
// any cases where the code in canonicalize_md.c would throw an
// exception or otherwise deal with non-simple pathnames like handling
// of "." and "..". It may conservatively return null in other
// situations as well. Returning null will cause the underlying
// (expensive) canonicalization routine to be called.
static String parentOrNull(String path) {
if (path == null) return null;
char sep = File.separatorChar;
int last = path.length() - 1;
int idx = last;
int adjacentDots = 0;
int nonDotCount = 0;
while (idx > 0) {
char c = path.charAt(idx);
if (c == '.') {
if (++adjacentDots >= 2) {
// Punt on pathnames containing . and ..
return null;
}
} else if (c == sep) {
if (adjacentDots == 1 && nonDotCount == 0) {
// Punt on pathnames containing . and ..
return null;
}
if (idx == 0 ||
idx >= last - 1 ||
path.charAt(idx - 1) == sep) {
// Punt on pathnames containing adjacent slashes
// toward the end
return null;
}
return path.substring(0, idx);
} else {
++nonDotCount;
adjacentDots = 0;
}
--idx;
}
return null;
}

/* -- Attribute accessors -- */

Expand Down Expand Up @@ -362,17 +256,6 @@ public boolean createFileExclusively(String path) throws IOException {

@Override
public boolean delete(File f) {
// Keep canonicalization caches in sync after file deletion
// and renaming operations. Could be more clever than this
// (i.e., only remove/update affected entries) but probably
// not worth it since these entries expire after 30 seconds
// anyway.
if (useCanonCaches) {
cache.clear();
}
if (useCanonPrefixCache) {
javaHomePrefixCache.clear();
}
long comp = Blocker.begin();
try {
return delete0(f);
Expand Down Expand Up @@ -406,17 +289,6 @@ public boolean createDirectory(File f) {

@Override
public boolean rename(File f1, File f2) {
// Keep canonicalization caches in sync after file deletion
// and renaming operations. Could be more clever than this
// (i.e., only remove/update affected entries) but probably
// not worth it since these entries expire after 30 seconds
// anyway.
if (useCanonCaches) {
cache.clear();
}
if (useCanonPrefixCache) {
javaHomePrefixCache.clear();
}
long comp = Blocker.begin();
try {
return rename0(f1, f2);
Expand Down Expand Up @@ -500,7 +372,6 @@ public int hashCode(File f) {
return f.getPath().hashCode() ^ 1234321;
}


private static native void initIDs();

static {
Expand Down
6 changes: 4 additions & 2 deletions src/java.base/windows/classes/java/io/DefaultFileSystem.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 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
Expand Down Expand Up @@ -29,7 +29,9 @@
*
* @since 1.8
*/
class DefaultFileSystem {
final class DefaultFileSystem {

private DefaultFileSystem() {}

/**
* Return the FileSystem object for Windows platform.
Expand Down

1 comment on commit 927e674

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.