diff options
author | 2015-08-10 16:46:25 +0000 | |
---|---|---|
committer | 2015-08-11 07:51:54 +0000 | |
commit | 12b39567bf3743b99dc1d943b772f2cd57124e8e (patch) | |
tree | 667d62c226e53e18ade10c5a6d0a6260c4e7d6c4 /src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java | |
parent | 1b5c327ea2d897b344ecb1cb897bcb8eee0a5774 (diff) |
Add comments about subtle benign race in PathFragment#hashCode.
--
MOS_MIGRATED_REVID=100285918
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java b/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java index d14f781703..e8fdf36510 100644 --- a/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java +++ b/src/main/java/com/google/devtools/build/lib/vfs/PathFragment.java @@ -641,6 +641,22 @@ public final class PathFragment implements Comparable<PathFragment>, Serializabl @Override public int hashCode() { + // We use the hash code caching strategy employed by java.lang.String. There are three subtle + // things going on here: + // + // (1) We use a value of 0 to indicate that the hash code hasn't been computed and cached yet. + // Yes, this means that if the hash code is really 0 then we will "recompute" it each time. But + // this isn't a problem in practice since a hash code of 0 is rare. + // + // (2) Since we have no synchronization, multiple threads can race here thinking there are the + // first one to compute and cache the hash code. + // + // (3) Moreover, since 'hashCode' is non-volatile, the cached hash code value written from one + // thread may not be visible by another. + // + // All three of these issues are benign from a correctness perspective; in the end we have no + // overhead from synchronization, at the cost of potentially computing the hash code more than + // once. int h = hashCode; if (h == 0) { h = isAbsolute ? 1 : 0; |