Clean up InstanceOf/CheckCast.

Avoid read barriers for boot image class InstanceOf. Boot
image classes are non-moveable, so comparing them against
from-space and to-space reference yields the same result.

Change the notion of a "fatal" type check slow path to mean
that the runtime call shall not return by normal path, i.e.
"fatal" now includes certainly throwing in a try-block. This
avoids unnecessary code to restore registers and jump back.
For boot image classes the CheckCast comparisons do not need
read barriers (for the same reason as for InstanceOf), so we
shall not have any false negatives and can treat the check's
slow paths as final in the same cases as in non-CC configs.

Boot image size for aosp_taimen-userdebug in AOSP master:
  - before:
    arm boot*.oat: 37075460
    arm64 boot*.oat: 43431768
  - after:
    arm boot*.oat: 36894292 (-177KiB, -0.5%)
    arm64 boot*.oat: 43201256 (-225KiB, -0.5%)

Also remove some obsolete helpers from CodeGenerator.

Test: Additional test in 603-checker-instanceof.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Test: Pixel 2 XL boots.
Test: testrunner.py --target --optimizing
Bug: 12687968
Change-Id: Ib1381084e46a10e70320dcc618f0502ad725f0b8
diff --git a/test/603-checker-instanceof/src/Main.java b/test/603-checker-instanceof/src/Main.java
index ddf4b92..1487969 100644
--- a/test/603-checker-instanceof/src/Main.java
+++ b/test/603-checker-instanceof/src/Main.java
@@ -22,12 +22,17 @@
 
 public class Main {
 
-  /// CHECK-START:    void Main.main(java.lang.String[]) builder (after)
+  public static void main(String[] args) {
+    test1();
+    test2();
+  }
+
+  /// CHECK-START:    void Main.test1() builder (after)
   /// CHECK:          BoundType  klass:SuperClass can_be_null:false exact:false
 
-  /// CHECK-START:    void Main.main(java.lang.String[]) builder (after)
+  /// CHECK-START:    void Main.test1() builder (after)
   /// CHECK-NOT:      BoundType  klass:SuperClass can_be_null:false exact:true
-  public static void main(String[] args) {
+  public static void test1() {
     Object obj = new ChildClass();
 
     // We need a fixed point iteration to hit the bogus type update
@@ -45,4 +50,33 @@
       }
     }
   }
+
+  /// CHECK-START-X86: boolean Main.$noinline$instanceOfString(java.lang.Object) disassembly (after)
+  /// CHECK:          InstanceOf check_kind:exact_check
+  /// CHECK-NOT:      {{.*fs:.*}}
+
+  /// CHECK-START-X86_64: boolean Main.$noinline$instanceOfString(java.lang.Object) disassembly (after)
+  /// CHECK:          InstanceOf check_kind:exact_check
+  /// CHECK-NOT:      {{.*gs:.*}}
+
+  /// CHECK-START-{ARM,ARM64}: boolean Main.$noinline$instanceOfString(java.lang.Object) disassembly (after)
+  /// CHECK:          InstanceOf check_kind:exact_check
+  // For ARM and ARM64, the marking register (r8 and x20, respectively) can be used in
+  // non-CC configs for any other purpose, so we'd need a config-specific checker test.
+  // TODO: Add the checks when we support config-specific tests.
+  public static boolean $noinline$instanceOfString(Object o) {
+    // String is a final class, so `instanceof String` should use exact check.
+    // String is in the boot image, so we should avoid read barriers. The presence
+    // of the read barrier can be checked in the architecture-specific disassembly.
+    return o instanceof String;
+  }
+
+  public static void test2() {
+    if ($noinline$instanceOfString(new Object())) {
+      throw new Error();
+    }
+    if (!$noinline$instanceOfString(new String())) {
+      throw new Error();
+    }
+  }
 }