# Avoiding Vendor- and Version-Specific VM Bugs

DevFeed: [Avoiding Vendor- and Version-Specific VM Bugs](<https://devfeed.tech/articles/avoiding-vendor-and-version-specific-vm-bugs-20919.md>)

Original publisher: [Read original article](<https://jakewharton.com/avoiding-vendor-and-version-specific-vm-bugs/>)

Published: 2018-12-04T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Android](<https://devfeed.tech/topics/android.md>), [R8](<https://devfeed.tech/topics/r8.md>), [Java](<https://devfeed.tech/topics/java.md>), [Code](<https://devfeed.tech/topics/code.md>), [cpu](<https://devfeed.tech/topics/cpu.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [code](<https://devfeed.tech/tags/code.md>), [java](<https://devfeed.tech/tags/java.md>), [r8](<https://devfeed.tech/tags/r8.md>), [tool](<https://devfeed.tech/tags/tool.md>), [xor](<https://devfeed.tech/tags/xor.md>)

## AI overview

This article examines vendor-specific and version-specific virtual machine bugs discovered while building and deploying D8. It explains how D8 converts stack-based Java bytecode into register-based Dalvik bytecode for Android, using Java's bitwise not operation as an example. The conversion uses an exclusive-or with -1 rather than a dedicated bitwise-not instruction, in part because of compatibility considerations involving the older tool.

## Source excerpt

Note: This post is part of a series on D8 and R8, Android's new dexer and optimizer, respectively. For an intro to D8 read "Android's Java 8 support". The first two posts (1, 2) in this series explored how D8 is responsible for desugaring new Java language features to work on all versions of Android. Desugaring is the more interesting feature to demonstrate, but it's secondary functionality of D8. The primary responsibility is converting the stack-based Java bytecode into register-based Dalvik bytecode so that it can run on Android's VM. At this point in Android's tenure it'd be reasonable to think that this conversion (called dexing) is a solved problem. During the process of building and rolling out D8, however, interesting vendor-specific and version-specific bugs in different VMs were uncovered which this post is going to explore. Not A Not D8 takes compiled Java bytecode and produces equivalent functionality using Dalvik bytecode. We can see this with a simple example that uses Java's bitwise not operator. class Not { static void print(int value) { System.out.println(~value); } } Compiling and dumping the class file shows the bytecodes that are used to implement this feature. $ javac *.java $ javap -c *.class class Not { static void print(int); Code: 0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 3: iload_0 4: iconst_m1 5: ixor 6: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 9: return } Bytecode index 3, 4, and 5 load the argument value onto the stack, load the constant -1, and perform a bitwise exclusive-or. If your bitwise skills are a little rusty, -1 is represented as all 1s and an exclusive-or sets a bit if and only if one of the two bits is set. 00010100 (value) xor 11111111 (-1) = 11101011 By performing an exclusive-or on a number whose bits are all set to 1, we are left with a number whose bits are the opposite of the original yielding the bitwise not. Running this through D8 shows the operation is implemented similar