Merge "Make moves from argument registers block moves to argument registers"
diff --git a/build.gradle b/build.gradle
index 5f33458..6afc31a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -704,7 +704,8 @@
 
 def baseR8CommandLine(args = []) {
     // Execute r8 commands against a stable r8 with relocated dependencies.
-    return ["java", "-ea", "-jar", r8WithRelocatedDeps.outputs.files[0]] + args
+    return [org.gradle.internal.jvm.Jvm.current().getJavaExecutable(),
+            "-ea", "-jar", r8WithRelocatedDeps.outputs.files[0]] + args
 }
 
 def r8CfCommandLine(input, output, pgconf, args = [], libs = []) {
diff --git a/src/main/java/com/android/tools/r8/graph/AccessFlags.java b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
index 63c1cde..9716eea 100644
--- a/src/main/java/com/android/tools/r8/graph/AccessFlags.java
+++ b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
@@ -65,7 +65,7 @@
 
   public abstract int getAsDexAccessFlags();
 
-  public final int getOriginalCfAccessFlags() {
+  public final int getOriginalAccessFlags() {
     return originalFlags;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
index 2578384..b13e356 100644
--- a/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
+++ b/src/main/java/com/android/tools/r8/ir/code/CheckCast.java
@@ -29,17 +29,9 @@
   // so that the source and destination are assigned the same register.
   public CheckCast(Value dest, Value value, DexType type) {
     super(dest, value);
-    if (value.isNeverNull()) {
-      dest.markNeverNull();
-    }
     this.type = type;
   }
 
-  @Override
-  boolean computeNeverNull() {
-    return object().isNeverNull();
-  }
-
   public DexType getType() {
     return type;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
index f8b40dd..1ef3414 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstClass.java
@@ -26,7 +26,6 @@
 
   public ConstClass(Value dest, DexType clazz) {
     super(dest);
-    dest.markNeverNull();
     this.clazz = clazz;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java b/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java
index c48740d..ebc61d0 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstMethodHandle.java
@@ -23,7 +23,6 @@
 
   public ConstMethodHandle(Value dest, DexMethodHandle methodHandle) {
     super(dest);
-    dest.markNeverNull();
     this.methodHandle = methodHandle;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java b/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java
index dd2b4ac..47aa1c4 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstMethodType.java
@@ -21,7 +21,6 @@
 
   public ConstMethodType(Value dest, DexProto methodType) {
     super(dest);
-    dest.markNeverNull();
     this.methodType = methodType;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstString.java b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
index 48cc0ba..356b73d 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstString.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstString.java
@@ -26,7 +26,6 @@
 
   public ConstString(Value dest, DexString value, ThrowingInfo throwingInfo) {
     super(dest);
-    dest.markNeverNull();
     this.value = value;
     this.throwingInfo = throwingInfo;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java b/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java
index 0f00350..e4e0e10 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DexItemBasedConstString.java
@@ -35,7 +35,6 @@
       ThrowingInfo throwingInfo,
       ClassNameComputationInfo classNameComputationInfo) {
     super(dest);
-    dest.markNeverNull();
     this.item = item;
     this.classNameComputationInfo = classNameComputationInfo;
     this.throwingInfo = throwingInfo;
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 5d72f77..0d8826b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -681,9 +681,6 @@
   public boolean verifyNoImpreciseOrBottomTypes() {
     Predicate<Value> verifyValue =
         v -> {
-          assert !v.isNeverNull()
-              || (v.getTypeLattice().isReference()
-                  && v.getTypeLattice().nullability().isDefinitelyNotNull());
           assert v.getTypeLattice().isPreciseType();
           assert !v.getTypeLattice().isFineGrainedType();
           // For now we assume no bottom types on IR values. We may want to reconsider this for
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index 21f0836..a12490e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -74,12 +74,6 @@
     this.position = position;
   }
 
-  boolean computeNeverNull() {
-    // By default just return the flag from the out value since it never changes.
-    assert outValue != null;
-    return outValue.isNeverNull();
-  }
-
   public String getPositionAsString() {
     return position == null ? "???" : position.toString();
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Move.java b/src/main/java/com/android/tools/r8/ir/code/Move.java
index 823b5ca..8892a52 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Move.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Move.java
@@ -21,16 +21,6 @@
 
   public Move(Value dest, Value src) {
     super(dest, src);
-    // CodeRewriter.removeOrReplaceByDebugLocalWrite() might add a Move to a dest that is already
-    // marked never-null. Avoid tripping assertion in markNeverNull() in that case.
-    if (src.isNeverNull() && dest.canBeNull()) {
-      dest.markNeverNull();
-    }
-  }
-
-  @Override
-  boolean computeNeverNull() {
-    return src().isNeverNull();
   }
 
   public Value dest() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/MoveException.java b/src/main/java/com/android/tools/r8/ir/code/MoveException.java
index e89778e..a82bfa1 100644
--- a/src/main/java/com/android/tools/r8/ir/code/MoveException.java
+++ b/src/main/java/com/android/tools/r8/ir/code/MoveException.java
@@ -26,7 +26,6 @@
     super(dest);
     this.exceptionType = exceptionType;
     this.options = options;
-    dest.markNeverNull();
   }
 
   public Value dest() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java b/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
index 5ce2193..fb4d23b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewArrayEmpty.java
@@ -25,7 +25,6 @@
 
   public NewArrayEmpty(Value dest, Value size, DexType type) {
     super(dest, size);
-    dest.markNeverNull();
     this.type = type;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
index 4de219e..3d7c81b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NewInstance.java
@@ -28,7 +28,6 @@
 
   public NewInstance(DexType clazz, Value dest) {
     super(dest);
-    dest.markNeverNull();
     assert clazz != null;
     this.clazz = clazz;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/NonNull.java b/src/main/java/com/android/tools/r8/ir/code/NonNull.java
index f124849..6b016b7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NonNull.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NonNull.java
@@ -21,7 +21,6 @@
   public NonNull(Value dest, Value src, Instruction origin) {
     super(dest, src);
     assert !src.isNeverNull();
-    dest.markNeverNull();
     this.origin = origin;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/code/Phi.java b/src/main/java/com/android/tools/r8/ir/code/Phi.java
index 9b5f919..812f928 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Phi.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Phi.java
@@ -126,7 +126,6 @@
       appendOperand(operand);
     }
     removeTrivialPhi(builder);
-    recomputeNeverNull();
   }
 
   public void addOperands(List<Value> operands) {
@@ -147,7 +146,6 @@
     if (removeTrivialPhi) {
       removeTrivialPhi();
     }
-    recomputeNeverNull();
   }
 
   @Override
@@ -157,14 +155,6 @@
     }
   }
 
-  // Implementation assumes that canBeNull may change to neverNull, but
-  // not other way around. This will need to be revised later.
-  void recomputeNeverNull() {
-    if (canBeNull() && operands.stream().allMatch(Value::isNeverNull)) {
-      markNeverNull();
-    }
-  }
-
   private void throwUndefinedValueError() {
     throw new CompilationError(
         "Undefined value encountered during compilation. "
@@ -187,10 +177,7 @@
 
   public void removeOperand(int index) {
     operands.get(index).removePhiUser(this);
-    Value value = operands.remove(index);
-    if (value.canBeNull()) {
-      recomputeNeverNull();
-    }
+    operands.remove(index);
   }
 
   public void removeOperandsByIndex(List<Integer> operandsToRemove) {
@@ -206,7 +193,6 @@
       current = i + 1;
     }
     operands.addAll(copy.subList(current, copy.size()));
-    recomputeNeverNull();
   }
 
   public void replaceOperandAt(int predIndex, Value newValue) {
@@ -214,9 +200,6 @@
     operands.set(predIndex, newValue);
     newValue.addPhiUser(this);
     current.removePhiUser(this);
-    if (current.canBeNull() && newValue.isNeverNull()) {
-      recomputeNeverNull();
-    }
   }
 
   void replaceOperand(Value current, Value newValue) {
@@ -226,9 +209,6 @@
         newValue.addPhiUser(this);
       }
     }
-    if (current.canBeNull() && newValue.isNeverNull()) {
-      recomputeNeverNull();
-    }
   }
 
   public boolean isTrivialPhi() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index 8b558ab..88fd645 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -207,8 +207,6 @@
   private Value previousConsecutive = null;
   private LiveIntervals liveIntervals;
   private int needsRegister = -1;
-  // TODO(b/72693244): deprecate once typeLattice is landed.
-  private boolean neverNull = false;
   private boolean isThis = false;
   private boolean isArgument = false;
   private boolean knownToBeBoolean = false;
@@ -762,33 +760,18 @@
     return null;
   }
 
-  public void markNeverNull() {
-    assert !neverNull;
-    neverNull = true;
-
-    // Propagate never null flag change.
-    for (Instruction user : users) {
-      Value value = user.outValue;
-      if (value != null && value.canBeNull() && user.computeNeverNull()) {
-        value.markNeverNull();
-      }
-    }
-    for (Phi phi : phiUsers) {
-      phi.recomputeNeverNull();
-    }
-  }
-
   /**
    * Returns whether this value is known to never be <code>null</code>.
    */
   public boolean isNeverNull() {
-    return neverNull
-        || (definition != null && definition.isNonNull())
-        || (typeLattice.isReference() && typeLattice.nullability().isDefinitelyNotNull());
+    assert typeLattice.isReference();
+    return (definition != null && definition.isNonNull())
+        || typeLattice.nullability().isDefinitelyNotNull();
   }
 
   public boolean canBeNull() {
-    return !neverNull;
+    assert typeLattice.isReference();
+    return typeLattice.nullability().isNullable();
   }
 
   public void markAsArgument() {
@@ -819,13 +802,10 @@
     return false;
   }
 
-  public void markAsThis(boolean receiverCanBeNull) {
+  public void markAsThis() {
     assert isArgument;
     assert !isThis;
     isThis = true;
-    if (!receiverCanBeNull) {
-      markNeverNull();
-    }
   }
 
   /**
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index 3f355c1..0f09bbc 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -885,7 +885,7 @@
         TypeLatticeElement.fromDexType(method.method.getHolder(), nullability, appInfo);
     Value value = writeRegister(register, receiver, ThrowingInfo.NO_THROW, local);
     addInstruction(new Argument(value));
-    value.markAsThis(receiverCouldBeNull);
+    value.markAsThis();
   }
 
   public void addNonThisArgument(int register, TypeLatticeElement typeLattice) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index da61535..34556ad 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -1004,14 +1004,14 @@
       return;
     }
     Value returnValue = firstExit.returnValue();
-    boolean isNeverNull = returnValue.isNeverNull();
+    boolean isNeverNull = returnValue.getTypeLattice().isReference() && returnValue.isNeverNull();
     for (int i = 1; i < normalExits.size(); i++) {
       Return exit = normalExits.get(i).exit().asReturn();
       Value value = exit.returnValue();
       if (value != returnValue) {
         returnValue = null;
       }
-      isNeverNull = isNeverNull && value.isNeverNull();
+      isNeverNull &= value.getTypeLattice().isReference() && value.isNeverNull();
     }
     if (returnValue != null) {
       if (returnValue.isArgument()) {
@@ -3225,10 +3225,10 @@
           }
         } else if (theIf.isZeroTest() && !inValues.get(0).isConstNumber()
             && (theIf.getType() == Type.EQ || theIf.getType() == Type.NE)) {
-          if (inValues.get(0).isNeverNull()) {
+          TypeLatticeElement l = inValues.get(0).getTypeLattice();
+          if (l.isReference() && inValues.get(0).isNeverNull()) {
             simplifyIfWithKnownCondition(code, block, theIf, 1);
           } else {
-            TypeLatticeElement l = inValues.get(0).getTypeLattice();
             if (!l.isPrimitive() && !l.isNullable()) {
               simplifyIfWithKnownCondition(code, block, theIf, 1);
             }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
index d7faa6d..93c8add 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/DefaultInliningOracle.java
@@ -274,7 +274,8 @@
       }
       for (int index = 0; index < arguments.size(); index++) {
         Value argument = arguments.get(index);
-        if ((argument.isArgument() || argument.isNeverNull())
+        if ((argument.isArgument()
+            || (argument.getTypeLattice().isReference() && argument.isNeverNull()))
             && hints.get(index)) {
           // 5-4 instructions per parameter check are expected to be removed.
           instructionLimit += 4;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
index 5d33d52..ab88150 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberValuePropagation.java
@@ -215,11 +215,11 @@
     if (target == null) {
       return;
     }
-    if (target.getOptimizationInfo().neverReturnsNull() && current.outValue().canBeNull()) {
+    if (target.getOptimizationInfo().neverReturnsNull()
+        && current.outValue().getTypeLattice().isReference()
+        && current.outValue().canBeNull()) {
       Value knownToBeNonNullValue = current.outValue();
-      knownToBeNonNullValue.markNeverNull();
       TypeLatticeElement typeLattice = knownToBeNonNullValue.getTypeLattice();
-      assert typeLattice.isNullable() && typeLattice.isReference();
       knownToBeNonNullValue.narrowing(appView.appInfo(), typeLattice.asNonNullable());
       affectedValues.addAll(knownToBeNonNullValue.affectedValues());
     }
@@ -307,10 +307,9 @@
           if (info != null
               && ((TrivialClassInitializer) info).field == field
               && !appView.appInfo().isPinned(field)
+              && outValue.getTypeLattice().isReference()
               && outValue.canBeNull()) {
-            outValue.markNeverNull();
             TypeLatticeElement typeLattice = outValue.getTypeLattice();
-            assert typeLattice.isNullable() && typeLattice.isReference();
             outValue.narrowing(appView.appInfo(), typeLattice.asNonNullable());
             affectedValues.addAll(outValue.affectedValues());
           }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java b/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
index dd84122..9a0a550 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/NonNullTracker.java
@@ -340,14 +340,14 @@
   private boolean isNonNullCandidate(Value knownToBeNonNullValue) {
     TypeLatticeElement typeLattice = knownToBeNonNullValue.getTypeLattice();
     return
-        // redundant
-        !knownToBeNonNullValue.isNeverNull()
+        // e.g., v <- non-null INT ?!
+        typeLattice.isReference()
         // v <- non-null NULL ?!
         && !typeLattice.isNullType()
         // v <- non-null known-to-be-non-null // redundant
         && typeLattice.isNullable()
-        // e.g., v <- non-null INT ?!
-        && typeLattice.isReference();
+        // redundant
+        && !knownToBeNonNullValue.isNeverNull();
   }
 
   public void computeNonNullParamOnNormalExits(OptimizationFeedback feedback, IRCode code) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java
index 234bcc6..4b8290e 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java
@@ -150,10 +150,11 @@
         if (lambda.staticFields().length != 1) {
           throw new LambdaStructureError("has static initializer, but no singleton field");
         }
-        checkAccessFlags("unexpected static initializer access flags",
-            method.accessFlags, CLASS_INITIALIZER_FLAGS);
+        checkAccessFlags(
+            "unexpected static initializer access flags",
+            method.accessFlags.getOriginalAccessFlags(),
+            CLASS_INITIALIZER_FLAGS);
         checkDirectMethodAnnotations(method);
-
       } else if (method.isStatic()) {
         throw new LambdaStructureError(
             "unexpected static method: " + method.method.toSourceString());
@@ -206,8 +207,14 @@
   @SafeVarargs
   static <T extends AccessFlags> void checkAccessFlags(
       String message, T actual, T... expected) throws LambdaStructureError {
+    checkAccessFlags(message, actual.materialize(), expected);
+  }
+
+  @SafeVarargs
+  static <T extends AccessFlags> void checkAccessFlags(String message, int actual, T... expected)
+      throws LambdaStructureError {
     for (T flag : expected) {
-      if (flag.materialize() == actual.materialize()) {
+      if (actual == flag.materialize()) {
         return;
       }
     }
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
index 8f51777..50d63e5 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
@@ -192,7 +192,7 @@
                   receiver, Nullability.definitelyNotNull(), builder.getAppInfo()),
               NO_THROW);
       builder.add(new Argument(receiverValue));
-      receiverValue.markAsThis(false);
+      receiverValue.markAsThis();
     }
 
     // Fill in the Argument instructions in the argument block.
diff --git a/src/main/java/com/android/tools/r8/optimize/ClassAndMemberPublicizer.java b/src/main/java/com/android/tools/r8/optimize/ClassAndMemberPublicizer.java
index f080071..229471e 100644
--- a/src/main/java/com/android/tools/r8/optimize/ClassAndMemberPublicizer.java
+++ b/src/main/java/com/android/tools/r8/optimize/ClassAndMemberPublicizer.java
@@ -93,18 +93,7 @@
     if (accessFlags.isPublic()) {
       return false;
     }
-
-    if (appView.dexItemFactory().isClassConstructor(encodedMethod.method)) {
-      return false;
-    }
-
-    if (!accessFlags.isPrivate()) {
-      accessFlags.promoteToPublic();
-      return false;
-    }
-    assert accessFlags.isPrivate();
-
-    if (appView.dexItemFactory().isConstructor(encodedMethod.method)) {
+    if (!accessFlags.isPrivate() || appView.dexItemFactory().isConstructor(encodedMethod.method)) {
       accessFlags.promoteToPublic();
       return false;
     }
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardAccessFlags.java b/src/main/java/com/android/tools/r8/shaking/ProguardAccessFlags.java
index 8522f1f..e857165 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardAccessFlags.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardAccessFlags.java
@@ -58,15 +58,15 @@
   }
 
   public boolean containsAll(AccessFlags other) {
-    return containsAll(other.getOriginalCfAccessFlags());
+    return containsAll(other.getOriginalAccessFlags());
   }
 
   public boolean containsNone(AccessFlags other) {
-    return containsNone(other.getOriginalCfAccessFlags());
+    return containsNone(other.getOriginalAccessFlags());
   }
 
   public void setFlags(AccessFlags other) {
-    this.flags = other.getOriginalCfAccessFlags();
+    this.flags = other.getOriginalAccessFlags();
   }
 
   public void setPublic() {
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/InnerEnumValuesTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/InnerEnumValuesTest.java
new file mode 100644
index 0000000..6c8a9be
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/applymapping/InnerEnumValuesTest.java
@@ -0,0 +1,68 @@
+// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8.naming.applymapping;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.naming.applymapping.Outer.InnerEnum;
+import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.StringUtils;
+import java.nio.file.Path;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class InnerEnumValuesTest extends TestBase {
+  private static Class<?> MAIN = TestApp.class;
+  private static String EXPECTED_OUTPUT = StringUtils.lines("state_X", "state_Y");
+
+  private static Path mappingFile;
+
+  @Before
+  public void setup() throws Exception {
+    // Mapping file that describes that inner enum has been renamed.
+    mappingFile = temp.newFile("mapping.txt").toPath();
+    FileUtils.writeTextFile(
+        mappingFile,
+        StringUtils.lines(
+            Outer.class.getTypeName() + " -> " + "x.y.z:",
+            "    void <init>() -> <init>",
+            InnerEnum.class.getTypeName() + " -> " + "x.y.z$ie:",
+            "    " + InnerEnum.class.getTypeName() + " STATE_A -> state_X",
+            "    " + InnerEnum.class.getTypeName() + " STATE_B -> state_Y",
+            "    " + InnerEnum.class.getTypeName() + "[] $VALUES -> XY",
+            "    void <clinit>() -> <clinit>",
+            "    void <init>(java.lang.String,int) -> <init>",
+            "    " + InnerEnum.class.getTypeName() + " valueOf(java.lang.String) -> valueOf",
+            "    " + InnerEnum.class.getTypeName() + "[] values() -> values"));
+  }
+
+  @Ignore("b/124177369")
+  @Test
+  public void b124177369() throws Exception {
+    testForR8(Backend.DEX)
+        .addProgramClassesAndInnerClasses(Outer.class)
+        .addProgramClasses(MAIN)
+        .addKeepMainRule(MAIN)
+        .addKeepRules("-dontoptimize")
+        .addKeepRules("-applymapping " + mappingFile.toAbsolutePath())
+        .compile()
+        .run(MAIN)
+        .assertSuccessWithOutput(EXPECTED_OUTPUT);
+  }
+}
+
+class Outer {
+  public enum InnerEnum {
+    STATE_A,
+    STATE_B
+  }
+}
+
+class TestApp {
+  public static void main(String[] args) {
+    for (InnerEnum i : InnerEnum.values()) {
+      System.out.println(i);
+    }
+  }
+}
diff --git a/third_party/android_sdk.tar.gz.sha1 b/third_party/android_sdk.tar.gz.sha1
new file mode 100644
index 0000000..ebc2c1d
--- /dev/null
+++ b/third_party/android_sdk.tar.gz.sha1
@@ -0,0 +1 @@
+fdbcfa08e6a1772bc9569bf706819a95a15bc3a0
\ No newline at end of file
diff --git a/tools/apk_masseur.py b/tools/apk_masseur.py
index 4b13a32..0edd032 100755
--- a/tools/apk_masseur.py
+++ b/tools/apk_masseur.py
@@ -88,7 +88,7 @@
   aligned_apk = os.path.join(temp, 'aligned.apk')
   zipalign_path = (
       'zipalign' if 'build_tools' in os.environ.get('PATH')
-      else os.path.join(utils.ANDROID_BUILD_TOOLS, 'zipalign'))
+      else os.path.join(utils.getAndroidBuildTools(), 'zipalign'))
   cmd = [
     zipalign_path,
     '-f',
diff --git a/tools/apk_utils.py b/tools/apk_utils.py
index 41c80c2..86f1fe8 100644
--- a/tools/apk_utils.py
+++ b/tools/apk_utils.py
@@ -26,7 +26,7 @@
 def sign_with_apksigner(
     unsigned_apk, signed_apk, keystore, password='android', quiet=False):
   cmd = [
-    os.path.join(utils.ANDROID_BUILD_TOOLS, 'apksigner'),
+    os.path.join(utils.getAndroidBuildTools(), 'apksigner'),
     'sign',
     '-v',
     '--ks', keystore,
diff --git a/tools/download_all_benchmark_dependencies.py b/tools/download_all_benchmark_dependencies.py
index 43ec0ab..2717c45 100755
--- a/tools/download_all_benchmark_dependencies.py
+++ b/tools/download_all_benchmark_dependencies.py
@@ -13,9 +13,8 @@
 
 def Main():
   gradle.RunGradle(BUILD_TARGETS)
-  # Download opensource_apps and place in build.
   utils.DownloadFromX20(utils.OPENSOURCE_APPS_SHA_FILE)
-
+  utils.DownloadFromX20(utils.ANDROID_SDK + '.tar.gz.sha1')
 
 if __name__ == '__main__':
   sys.exit(Main())
diff --git a/tools/golem.py b/tools/golem.py
index a535133..6552145 100755
--- a/tools/golem.py
+++ b/tools/golem.py
@@ -9,6 +9,7 @@
 
 LINKED_THIRD_PARTY_DIRECTORIES = [
     'android_jar',
+    'android_sdk',
     'benchmarks',
     'framework',
     'gmail',
diff --git a/tools/gradle.py b/tools/gradle.py
index 8a3502d..6a9bd16 100755
--- a/tools/gradle.py
+++ b/tools/gradle.py
@@ -31,7 +31,9 @@
   return parser.parse_known_args()
 
 def GetJavaEnv(env):
-  return dict(env if env else os.environ, JAVA_HOME = jdk.GetJdkHome())
+  java_env = dict(env if env else os.environ, JAVA_HOME = jdk.GetJdkHome())
+  java_env['PATH'] = java_env['PATH'] + os.pathsep + os.path.join(jdk.GetJdkHome(), 'bin')
+  return java_env
 
 def PrintCmd(s):
   if type(s) is list:
diff --git a/tools/run_on_as_app.py b/tools/run_on_as_app.py
index 998c9ef..fef337a 100755
--- a/tools/run_on_as_app.py
+++ b/tools/run_on_as_app.py
@@ -185,7 +185,7 @@
     cmd = [jdk.GetJavaExecutable(), '-ea', '-jar', r8_jar, 'extractmarker', apk]
   elif os.path.isfile(r8lib_jar):
     cmd = [jdk.GetJavaExecutable(), '-ea', '-cp', r8lib_jar,
-        'com.android.tools.r8.SwissArmyKnife', 'extractmarker', apk]
+        'com.android.tools.r8.ExtractMarker', apk]
   else:
     script = os.path.join(utils.TOOLS_DIR, 'extractmarker.py')
     cmd = ['python', script, apk]
@@ -452,7 +452,7 @@
       app, config, checkout_dir, proguard_config_dest)
 
   env = {}
-  env['ANDROID_HOME'] = utils.ANDROID_HOME
+  env['ANDROID_HOME'] = utils.getAndroidHome()
   env['JAVA_OPTS'] = '-ea:com.android.tools.r8...'
 
   releaseTarget = config.get('releaseTarget')
@@ -774,6 +774,9 @@
     if os.path.exists(WORKING_DIR):
       shutil.rmtree(WORKING_DIR)
     shutil.copytree(utils.OPENSOURCE_APPS_FOLDER, WORKING_DIR)
+    os.environ[utils.ANDROID_HOME_ENVIROMENT_NAME] = os.path.join(
+        utils.ANDROID_SDK)
+    os.environ[utils.ANDROID_TOOLS_VERSION_ENVIRONMENT_NAME] = '28.0.3'
 
   if not os.path.exists(WORKING_DIR):
     os.makedirs(WORKING_DIR)
diff --git a/tools/utils.py b/tools/utils.py
index f2df0ed..12535be 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -21,6 +21,7 @@
 TOOLS_DIR = defines.TOOLS_DIR
 REPO_ROOT = defines.REPO_ROOT
 THIRD_PARTY = defines.THIRD_PARTY
+ANDROID_SDK = os.path.join(THIRD_PARTY, 'android_sdk')
 MEMORY_USE_TMP_FILE = 'memory_use.tmp'
 DEX_SEGMENTS_RESULT_PATTERN = re.compile('- ([^:]+): ([0-9]+)')
 BUILD = os.path.join(REPO_ROOT, 'build')
@@ -69,13 +70,17 @@
     'third_party/opensource_apps.tar.gz.sha1')
 OPENSOURCE_APPS_FOLDER = os.path.join(REPO_ROOT, 'third_party/opensource_apps/')
 
-
-# Common environment setup.
+ANDROID_HOME_ENVIROMENT_NAME = "ANDROID_HOME"
+ANDROID_TOOLS_VERSION_ENVIRONMENT_NAME = "ANDROID_TOOLS_VERSION"
 USER_HOME = os.path.expanduser('~')
-ANDROID_HOME = os.path.join(USER_HOME, 'Android', 'Sdk')
-ANDROID_BUILD_TOOLS_VERSION = '28.0.3'
-ANDROID_BUILD_TOOLS = os.path.join(
-    ANDROID_HOME, 'build-tools', ANDROID_BUILD_TOOLS_VERSION)
+
+def getAndroidHome():
+  return os.environ.get(
+      ANDROID_HOME_ENVIROMENT_NAME, os.path.join(USER_HOME, 'Android', 'Sdk'))
+
+def getAndroidBuildTools():
+  version = os.environ.get(ANDROID_TOOLS_VERSION_ENVIRONMENT_NAME, '28.0.3')
+  return os.path.join(getAndroidHome(), 'build-tools', version)
 
 def Print(s, quiet=False):
   if quiet:
@@ -270,10 +275,9 @@
   PrintCmd(cmd)
   subprocess.check_call(cmd)
 
-def create_archive(name):
-  return create_archive(name, [name])
-
-def create_archive(name, sources):
+def create_archive(name, sources=None):
+  if not sources:
+    sources = [name]
   tarname = '%s.tar.gz' % name
   with tarfile.open(tarname, 'w:gz') as tar:
     for source in sources: