aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Miller-Cushon <cushon@google.com>2023-09-06 12:25:02 -0700
committergoogle-java-format Team <google-java-format-dev+copybara@google.com>2023-09-06 12:25:33 -0700
commit9f2cd6827d016a3b55b7f9f39e054a69b0deb168 (patch)
tree295fb3e9b2264d6dcf311c08bbea5a90d6e00bba
parent28b199c54957bb10d203bb5d7a0e3ed82603f5e8 (diff)
downloadgoogle-java-format-9f2cd6827d016a3b55b7f9f39e054a69b0deb168.tar.gz
Make google-java-format friendlier to TSAN
This code does deliberate racy initialization of some memoized values, and there is a static final instance of the `Space` subclass that ends up being shared across multiple threads. Tested: sponge/1777b644-2dd8-420b-ad06-b4f17c893d8f PiperOrigin-RevId: 563181626
-rw-r--r--core/src/main/java/com/google/googlejavaformat/Doc.java29
1 files changed, 8 insertions, 21 deletions
diff --git a/core/src/main/java/com/google/googlejavaformat/Doc.java b/core/src/main/java/com/google/googlejavaformat/Doc.java
index d638ddb..e755bc6 100644
--- a/core/src/main/java/com/google/googlejavaformat/Doc.java
+++ b/core/src/main/java/com/google/googlejavaformat/Doc.java
@@ -19,6 +19,7 @@ import static com.google.googlejavaformat.CommentsHelper.reformatParameterCommen
import static java.lang.Math.max;
import com.google.common.base.MoreObjects;
+import com.google.common.base.Suppliers;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.Iterators;
import com.google.common.collect.Range;
@@ -26,6 +27,7 @@ import com.google.googlejavaformat.Output.BreakTag;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
+import java.util.function.Supplier;
/**
* {@link com.google.googlejavaformat.java.JavaInputAstVisitor JavaInputAstVisitor} outputs a
@@ -102,16 +104,13 @@ public abstract class Doc {
private static final DiscreteDomain<Integer> INTEGERS = DiscreteDomain.integers();
// Memoized width; Float.POSITIVE_INFINITY if contains forced breaks.
- private boolean widthComputed = false;
- private float width = 0.0F;
+ private final Supplier<Float> width = Suppliers.memoize(this::computeWidth);
// Memoized flat; not defined (and never computed) if contains forced breaks.
- private boolean flatComputed = false;
- private String flat = "";
+ private final Supplier<String> flat = Suppliers.memoize(this::computeFlat);
// Memoized Range.
- private boolean rangeComputed = false;
- private Range<Integer> range = EMPTY_RANGE;
+ private final Supplier<Range<Integer>> range = Suppliers.memoize(this::computeRange);
/**
* Return the width of a {@code Doc}, or {@code Float.POSITIVE_INFINITY} if it must be broken.
@@ -119,11 +118,7 @@ public abstract class Doc {
* @return the width
*/
final float getWidth() {
- if (!widthComputed) {
- width = computeWidth();
- widthComputed = true;
- }
- return width;
+ return width.get();
}
/**
@@ -133,11 +128,7 @@ public abstract class Doc {
* @return the flat-string value
*/
final String getFlat() {
- if (!flatComputed) {
- flat = computeFlat();
- flatComputed = true;
- }
- return flat;
+ return flat.get();
}
/**
@@ -146,11 +137,7 @@ public abstract class Doc {
* @return the {@code Doc}'s {@link Range}
*/
final Range<Integer> range() {
- if (!rangeComputed) {
- range = computeRange();
- rangeComputed = true;
- }
- return range;
+ return range.get();
}
/**