aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/tools/android
diff options
context:
space:
mode:
authorGravatar Chengnian Sun <cnsun@google.com>2017-03-23 19:48:14 +0000
committerGravatar Yue Gan <yueg@google.com>2017-03-24 12:17:53 +0000
commit7bb3ba00d231399a4ffcbf2b22753eed1e249a30 (patch)
treec80e0591b341cef1968f0d900e97e83501a75cf6 /src/tools/android
parent18203b85c03b1ac35a7871c9a9d1794cc659a111 (diff)
rewrite Long.compare(long, long) to JVM instruction lcmp, so that devices with
API level below 19 can still use Long.compare(long, long) RELNOTES: n/a -- PiperOrigin-RevId: 151040972 MOS_MIGRATED_REVID=151040972
Diffstat (limited to 'src/tools/android')
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java24
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java58
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java (renamed from src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodInliner.java)7
3 files changed, 80 insertions, 9 deletions
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java b/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
index 1711f57a99..7be39052bd 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/Desugar.java
@@ -101,6 +101,14 @@ class Desugar {
public boolean onlyDesugarJavac9ForLint;
@Option(
+ name = "rewrite_calls_to_long_compare",
+ defaultValue = "true",
+ help = "rewrite calls to Long.compare(long, long) to the JVM instruction lcmp",
+ category = "misc"
+ )
+ public boolean enableRewritingOfLongCompare;
+
+ @Option(
name = "output",
allowMultiple = true,
defaultValue = "",
@@ -264,7 +272,10 @@ class Desugar {
}
if (!allowCallsToObjectsNonNull) {
- visitor = new ObjectsRequireNonNullMethodInliner(visitor);
+ visitor = new ObjectsRequireNonNullMethodRewriter(visitor);
+ }
+ if (options.enableRewritingOfLongCompare) {
+ visitor = new LongCompareMethodRewriter(visitor);
}
reader.accept(visitor, 0);
@@ -313,7 +324,10 @@ class Desugar {
if (!allowCallsToObjectsNonNull) {
// Not sure whether there will be implicit null check emitted by javac, so we rerun
// the inliner again
- visitor = new ObjectsRequireNonNullMethodInliner(visitor);
+ visitor = new ObjectsRequireNonNullMethodRewriter(visitor);
+ }
+ if (options.enableRewritingOfLongCompare) {
+ visitor = new LongCompareMethodRewriter(visitor);
}
reader.accept(visitor, 0);
String filename =
@@ -321,10 +335,10 @@ class Desugar {
outputFileProvider.write(filename, writer.toByteArray());
}
}
-
- Map<Path, LambdaInfo> leftBehind = lambdas.drain();
- checkState(leftBehind.isEmpty(), "Didn't process %s", leftBehind);
}
+
+ Map<Path, LambdaInfo> leftBehind = lambdas.drain();
+ checkState(leftBehind.isEmpty(), "Didn't process %s", leftBehind);
}
}
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java
new file mode 100644
index 0000000000..23d7a0d0b1
--- /dev/null
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/LongCompareMethodRewriter.java
@@ -0,0 +1,58 @@
+// Copyright 2017 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.android.desugar;
+
+import static org.objectweb.asm.Opcodes.ASM5;
+import static org.objectweb.asm.Opcodes.INVOKESTATIC;
+import static org.objectweb.asm.Opcodes.LCMP;
+
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ * This class rewrites any call to Long.compare with the JVM instruction lcmp that is semantically
+ * equivalent to Long.compare.
+ */
+public class LongCompareMethodRewriter extends ClassVisitor {
+
+ public LongCompareMethodRewriter(ClassVisitor cv) {
+ super(ASM5, cv);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ int access, String name, String desc, String signature, String[] exceptions) {
+ MethodVisitor visitor = super.cv.visitMethod(access, name, desc, signature, exceptions);
+ return visitor == null ? visitor : new LongCompareMethodVisitor(visitor);
+ }
+
+ private static class LongCompareMethodVisitor extends MethodVisitor {
+
+ public LongCompareMethodVisitor(MethodVisitor visitor) {
+ super(ASM5, visitor);
+ }
+
+ @Override
+ public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
+ if (opcode != INVOKESTATIC
+ || !owner.equals("java/lang/Long")
+ || !name.equals("compare")
+ || !desc.equals("(JJ)I")) {
+ super.visitMethodInsn(opcode, owner, name, desc, itf);
+ return;
+ }
+ super.visitInsn(LCMP);
+ }
+ }
+}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodInliner.java b/src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java
index e56cfe1d1b..5ce0bee6a1 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodInliner.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/ObjectsRequireNonNullMethodRewriter.java
@@ -25,12 +25,11 @@ import org.objectweb.asm.MethodVisitor;
/**
* This class desugars any call to Objects.requireNonNull(Object o), Objects.requireNonNull(Object
* o, String msg), and Objects.requireNonNull(Object o, Supplier msg), by replacing the call with
- * o.getClass(). Note that currently we discard the message, as inlining the message involves
- * changes to the control flow graph, which further requires re-computation of the stack map frames.
+ * o.getClass().
*/
-public class ObjectsRequireNonNullMethodInliner extends ClassVisitor {
+public class ObjectsRequireNonNullMethodRewriter extends ClassVisitor {
- public ObjectsRequireNonNullMethodInliner(ClassVisitor cv) {
+ public ObjectsRequireNonNullMethodRewriter(ClassVisitor cv) {
super(ASM5, cv);
}