Skip to content

Commit

Permalink
Add @RetainedLocalRef to volatile value field references to res…
Browse files Browse the repository at this point in the history
…olve potential memory issues in a J2ObjC context.

RELNOTES=n/a
PiperOrigin-RevId: 683652108
  • Loading branch information
java-team-github-bot authored and Google Java Core Libraries committed Oct 8, 2024
1 parent ed33d3d commit 4d7c71e
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.ForOverride;
import com.google.j2objc.annotations.ReflectionSupport;
import com.google.j2objc.annotations.RetainedLocalRef;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedActionException;
Expand Down Expand Up @@ -442,7 +443,7 @@ public V get(long timeout, TimeUnit unit)
if (Thread.interrupted()) {
throw new InterruptedException();
}
Object localValue = value;
@RetainedLocalRef Object localValue = value;
if (localValue != null & !(localValue instanceof SetFuture)) {
return getDoneValue(localValue);
}
Expand Down Expand Up @@ -550,7 +551,7 @@ public V get() throws InterruptedException, ExecutionException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
Object localValue = value;
@RetainedLocalRef Object localValue = value;
if (localValue != null & !(localValue instanceof SetFuture)) {
return getDoneValue(localValue);
}
Expand Down Expand Up @@ -609,13 +610,13 @@ private V getDoneValue(Object obj) throws ExecutionException {

@Override
public boolean isDone() {
final Object localValue = value;
@RetainedLocalRef Object localValue = value;
return localValue != null & !(localValue instanceof SetFuture);
}

@Override
public boolean isCancelled() {
final Object localValue = value;
@RetainedLocalRef Object localValue = value;
return localValue instanceof Cancellation;
}

Expand All @@ -638,7 +639,7 @@ public boolean isCancelled() {
@CanIgnoreReturnValue
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
Object localValue = value;
@RetainedLocalRef Object localValue = value;
boolean rValue = false;
if (localValue == null | localValue instanceof SetFuture) {
// Try to delay allocating the exception. At this point we may still lose the CAS, but it is
Expand Down Expand Up @@ -724,7 +725,7 @@ protected void interruptTask() {}
* @since 14.0
*/
protected final boolean wasInterrupted() {
final Object localValue = value;
@RetainedLocalRef Object localValue = value;
return (localValue instanceof Cancellation) && ((Cancellation) localValue).wasInterrupted;
}

Expand Down Expand Up @@ -846,7 +847,7 @@ protected boolean setException(Throwable throwable) {
@CanIgnoreReturnValue
protected boolean setFuture(ListenableFuture<? extends V> future) {
checkNotNull(future);
Object localValue = value;
@RetainedLocalRef Object localValue = value;
if (localValue == null) {
if (future.isDone()) {
Object value = getFutureValue(future);
Expand Down Expand Up @@ -1109,9 +1110,9 @@ protected void afterDone() {}
@CheckForNull
protected final Throwable tryInternalFastPathGetFailure() {
if (this instanceof Trusted) {
Object obj = value;
if (obj instanceof Failure) {
return ((Failure) obj).exception;
@RetainedLocalRef Object localValue = value;
if (localValue instanceof Failure) {
return ((Failure) localValue).exception;
}
}
return null;
Expand Down Expand Up @@ -1204,7 +1205,7 @@ private void addPendingString(StringBuilder builder) {

builder.append("PENDING");

Object localValue = value;
@RetainedLocalRef Object localValue = value;
if (localValue instanceof SetFuture) {
builder.append(", setFuture=[");
appendUserObject(builder, ((SetFuture) localValue).future);
Expand Down
23 changes: 12 additions & 11 deletions guava/src/com/google/common/util/concurrent/AbstractFuture.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.ForOverride;
import com.google.j2objc.annotations.ReflectionSupport;
import com.google.j2objc.annotations.RetainedLocalRef;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedActionException;
Expand Down Expand Up @@ -442,7 +443,7 @@ public V get(long timeout, TimeUnit unit)
if (Thread.interrupted()) {
throw new InterruptedException();
}
Object localValue = value;
@RetainedLocalRef Object localValue = value;
if (localValue != null & !(localValue instanceof SetFuture)) {
return getDoneValue(localValue);
}
Expand Down Expand Up @@ -550,7 +551,7 @@ public V get() throws InterruptedException, ExecutionException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
Object localValue = value;
@RetainedLocalRef Object localValue = value;
if (localValue != null & !(localValue instanceof SetFuture)) {
return getDoneValue(localValue);
}
Expand Down Expand Up @@ -609,13 +610,13 @@ private V getDoneValue(Object obj) throws ExecutionException {

@Override
public boolean isDone() {
final Object localValue = value;
@RetainedLocalRef Object localValue = value;
return localValue != null & !(localValue instanceof SetFuture);
}

@Override
public boolean isCancelled() {
final Object localValue = value;
@RetainedLocalRef Object localValue = value;
return localValue instanceof Cancellation;
}

Expand All @@ -638,7 +639,7 @@ public boolean isCancelled() {
@CanIgnoreReturnValue
@Override
public boolean cancel(boolean mayInterruptIfRunning) {
Object localValue = value;
@RetainedLocalRef Object localValue = value;
boolean rValue = false;
if (localValue == null | localValue instanceof SetFuture) {
// Try to delay allocating the exception. At this point we may still lose the CAS, but it is
Expand Down Expand Up @@ -724,7 +725,7 @@ protected void interruptTask() {}
* @since 14.0
*/
protected final boolean wasInterrupted() {
final Object localValue = value;
@RetainedLocalRef Object localValue = value;
return (localValue instanceof Cancellation) && ((Cancellation) localValue).wasInterrupted;
}

Expand Down Expand Up @@ -846,7 +847,7 @@ protected boolean setException(Throwable throwable) {
@CanIgnoreReturnValue
protected boolean setFuture(ListenableFuture<? extends V> future) {
checkNotNull(future);
Object localValue = value;
@RetainedLocalRef Object localValue = value;
if (localValue == null) {
if (future.isDone()) {
Object value = getFutureValue(future);
Expand Down Expand Up @@ -1109,9 +1110,9 @@ protected void afterDone() {}
@CheckForNull
protected final Throwable tryInternalFastPathGetFailure() {
if (this instanceof Trusted) {
Object obj = value;
if (obj instanceof Failure) {
return ((Failure) obj).exception;
@RetainedLocalRef Object localValue = value;
if (localValue instanceof Failure) {
return ((Failure) localValue).exception;
}
}
return null;
Expand Down Expand Up @@ -1204,7 +1205,7 @@ private void addPendingString(StringBuilder builder) {

builder.append("PENDING");

Object localValue = value;
@RetainedLocalRef Object localValue = value;
if (localValue instanceof SetFuture) {
builder.append(", setFuture=[");
appendUserObject(builder, ((SetFuture) localValue).future);
Expand Down

0 comments on commit 4d7c71e

Please sign in to comment.