This makes it so that when you pass dx --target-api=N, where N is an
API level representing Honeycomb or earlier, dx will not emit any of
the new extended opcodes.
N is currently baked into the code as 12 or larger being
post-Honeycomb, but it is subject to change if there are more revs of
the API under the Honeycomb umbrella (which wouldn't be surprising).
Bug:
4094709
Change-Id: Iaf5177f179b22586bcf806ecb53de20b6e989777
* the last in its chain
*/
public static Dop getNextOrNull(Dop opcode, DexOptions options) {
- int nextOpcode = opcode.getNextOpcode();
+ for (;;) {
+ int nextOpcode = opcode.getNextOpcode();
- if (nextOpcode == Opcodes.NO_NEXT) {
- return null;
- }
+ if (nextOpcode == Opcodes.NO_NEXT) {
+ return null;
+ }
+
+ opcode = get(nextOpcode);
- return get(nextOpcode);
+ if (!options.enableExtendedOpcodes && Opcodes.isExtended(nextOpcode)) {
+ /*
+ * Continuing rather than just returning null here
+ * protects against the possibility that an
+ * instruction fitting chain might list non-extended
+ * opcodes after extended ones.
+ */
+ continue;
+ }
+
+ return opcode;
+ }
}
/**
}
/**
+ * Gets whether ({@code true}) or not ({@code false}) the given opcode value
+ * is an "extended" opcode. Extended opcodes require a full 16-bit code unit
+ * to represent (without leaving space for an argument byte).
+ *
+ * @param opcode the opcode value
+ * @return {@code true} iff the opcode is an "extended" opcode
+ */
+ public static boolean isExtended(int opcode) {
+ return (opcode >= 0x00ff);
+ }
+
+ /**
* Gets the opcode out of an opcode unit, the latter of which may also
* include one or more argument values.
+ *
+ * @param opcodeUnit the opcode-containing code unit
+ * @return the extracted opcode
*/
public static int extractOpcodeFromUnit(int opcodeUnit) {
/*
--- /dev/null
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * 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.
+ */
+
+public class Blort
+{
+ private int field0 = 0;
+ private int field1 = 1;
+ private int field2 = 2;
+ private int field3 = 3;
+ private int field4 = 4;
+ private int field5 = 5;
+ private int field6 = 6;
+ private int field7 = 7;
+ private int field8 = 8;
+ private int field9 = 9;
+
+ public void test() {
+ int v0 = field0;
+ int v1 = field1;
+ int v2 = field2;
+ int v3 = field3;
+ int v4 = field4;
+ int v5 = field5;
+ int v6 = field6;
+ int v7 = field7;
+ int v8 = field8;
+ int v9 = field9;
+ int v10 = field0;
+ int v11 = field1;
+ int v12 = field2;
+ int v13 = field3;
+ int v14 = field4;
+ int v15 = field5;
+ int v16 = field6;
+ int v17 = field7;
+ int v18 = field8;
+ int v19 = field9;
+
+ sink(v0);
+ sink(v1);
+ sink(v2);
+ sink(v3);
+ sink(v4);
+ sink(v5);
+ sink(v6);
+ sink(v7);
+ sink(v8);
+ sink(v9);
+ sink(v10);
+ sink(v11);
+ sink(v12);
+ sink(v13);
+ sink(v14);
+ sink(v15);
+ sink(v16);
+ sink(v17);
+ sink(v18);
+ sink(v19);
+ }
+
+ private static void sink(int arg) {
+ // This space intentionally left blank.
+ }
+}
--- /dev/null
+This is a test of the dx option --target-api, which is supposed to
+disable the emission of extended-opcode instructions when the target
+API is for Honeycomb or earlier.
--- /dev/null
+#!/bin/bash
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# 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.
+
+# This test checks to see that without --target-api=11, the result of
+# dx contains at least one "iget/jumbo" opcode (one example of an
+# extended opcode); and that with that option no such opcode is
+# produced.
+
+$JAVAC -d . *.java
+
+count=`dx --debug --dex --no-optimize --positions=none --no-locals \
+ --dump-method=Blort.test Blort.class | grep "iget/jumbo" | wc -l`
+if [ "$count" = "0" ]; then
+ echo "No iget/jumbo emitted without --target-api"
+fi
+
+count=`dx --debug --dex --no-optimize --positions=none --no-locals \
+ --target-api=11 \
+ --dump-method=Blort.test Blort.class | grep "iget/jumbo" | wc -l`
+if [ "$count" != "0" ]; then
+ echo "Found $count iget/jumbo emitted with --target-api=11"
+fi
+
+echo "Done"