Merge
authorvlivanov
Fri, 20 May 2016 18:05:09 +0300
changeset 38697 110bb528423b
parent 38303 1d0016127806 (current diff)
parent 38696 441abd3b3345 (diff)
child 38698 2f5f325d4e6d
Merge
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/SourceStackTrace.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/UnsafeUtil.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotOopMap.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProxified.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSymbol.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Stable.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/events/EmptyEventProvider.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/events/EventProvider.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/logging/package-info.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.inittimer/src/jdk/vm/ci/inittimer/InitTimer.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.inittimer/src/jdk/vm/ci/inittimer/SuppressFBWarnings.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JVMCIMetaAccessContext.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LIRKind.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTableImpl.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalImpl.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTableImpl.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocationIdentity.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/TrustedInterface.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java
hotspot/src/os/linux/vm/os_linux.cpp
hotspot/src/share/vm/classfile/classLoader.cpp
hotspot/src/share/vm/logging/logTagSet.cpp
hotspot/src/share/vm/runtime/thread.cpp
hotspot/src/share/vm/runtime/thread.hpp
hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.hotspot.HotSpotVMEventListener
hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.JVMCICompilerFactory
hotspot/test/compiler/jvmci/compilerToVM/ReadUncompressedOopTest.java
hotspot/test/compiler/jvmci/events/JvmciCreateMetaAccessContextTest.java
hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantArrayElementDataProvider.java
hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantFieldValueDataProvider.java
hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadStableFieldValueDataProvider.java
hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/LogicOperator.java
--- a/hotspot/.mx.jvmci/mx_jvmci.py	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/.mx.jvmci/mx_jvmci.py	Fri May 20 18:05:09 2016 +0300
@@ -144,42 +144,6 @@
     assert vm in _jdkJvmVariants
     return True
 
-class JvmciJDKDeployedDist(object):
-    def __init__(self, name, compilers=False):
-        self._name = name
-        self._compilers = compilers
-
-    def dist(self):
-        return mx.distribution(self._name)
-
-    def deploy(self, jdkDir):
-        mx.nyi('deploy', self)
-
-    def post_parse_cmd_line(self):
-        self.set_archiveparticipant()
-
-    def set_archiveparticipant(self):
-        dist = self.dist()
-        dist.set_archiveparticipant(JVMCIArchiveParticipant(dist))
-
-class ExtJDKDeployedDist(JvmciJDKDeployedDist):
-    def __init__(self, name):
-        JvmciJDKDeployedDist.__init__(self, name)
-
-"""
-The monolithic JVMCI distribution is deployed through use of -Xbootclasspath/p
-so that it's not necessary to run JDK make after editing JVMCI sources.
-The latter causes all JDK Java sources to be rebuilt since JVMCI is
-(currently) in java.base.
-"""
-_monolithicJvmci = JvmciJDKDeployedDist('JVMCI')
-
-"""
-List of distributions that are deployed on the boot class path.
-Note: In jvmci-8, they were deployed directly into the JDK directory.
-"""
-jdkDeployedDists = [_monolithicJvmci]
-
 def _makehelp():
     return subprocess.check_output([mx.gmake_cmd(), 'help'], cwd=_jdkSourceRoot)
 
@@ -194,7 +158,7 @@
         # JDK9 must be bootstrapped with a JDK8
         compliance = mx.JavaCompliance('8')
         jdk8 = mx.get_jdk(compliance.exactMatch, versionDescription=compliance.value)
-        cmd = ['sh', 'configure', '--with-debug-level=' + _vm.debugLevel, '--with-native-debug-symbols=none', '--disable-precompiled-headers',
+        cmd = ['sh', 'configure', '--with-debug-level=' + _vm.debugLevel, '--with-native-debug-symbols=external', '--disable-precompiled-headers',
                '--with-jvm-variants=' + _vm.jvmVariant, '--disable-warnings-as-errors', '--with-boot-jdk=' + jdk8.home]
         mx.run(cmd, cwd=_jdkSourceRoot)
     cmd = [mx.gmake_cmd(), 'CONF=' + _vm.debugLevel]
@@ -217,7 +181,10 @@
 
         # The OpenJDK build creates an empty cacerts file so copy one from
         # the default JDK (which is assumed to be an OracleJDK)
-        srcCerts = join(mx.get_jdk(tag='default').home, 'jre', 'lib', 'security', 'cacerts')
+        srcCerts = join(mx.get_jdk(tag='default').home, 'lib', 'security', 'cacerts')
+        if not exists(srcCerts):
+            # Might be building with JDK8 which has cacerts under jre/
+            srcCerts = join(mx.get_jdk(tag='default').home, 'jre', 'lib', 'security', 'cacerts')
         dstCerts = join(jdkImageDir, 'lib', 'security', 'cacerts')
         shutil.copyfile(srcCerts, dstCerts)
 
@@ -673,24 +640,6 @@
 
     run_vm(['-javaagent:' + joljar, '-cp', os.pathsep.join([mx.classpath(), joljar]), "org.openjdk.jol.MainObjectInternals"] + candidates)
 
-class JVMCIArchiveParticipant:
-    def __init__(self, dist):
-        self.dist = dist
-
-    def __opened__(self, arc, srcArc, services):
-        self.services = services
-        self.jvmciServices = services
-        self.arc = arc
-
-    def __add__(self, arcname, contents):
-        return False
-
-    def __addsrc__(self, arcname, contents):
-        return False
-
-    def __closing__(self):
-        pass
-
 def _get_openjdk_os():
     # See: common/autoconf/platform.m4
     os = mx.get_os()
@@ -744,10 +693,6 @@
     name = '{}_{}_{}'.format(os, arch, buildname)
     return join(_get_jdk_build_dir(debugLevel=debugLevel), 'hotspot', name)
 
-def add_bootclasspath_prepend(dep):
-    assert isinstance(dep, mx.ClasspathDependency)
-    _jvmci_bootclasspath_prepends.append(dep)
-
 class JVMCI9JDKConfig(mx.JDKConfig):
     def __init__(self, debugLevel):
         self.debugLevel = debugLevel
@@ -771,20 +716,6 @@
             cp = os.pathsep.join([e for e in cp.split(os.pathsep) if e not in excluded])
             args[cpIndex] = cp
 
-        jvmciModeArgs = _jvmciModes[_vm.jvmciMode]
-        if jvmciModeArgs:
-            bcpDeps = [jdkDist.dist() for jdkDist in jdkDeployedDists]
-            if bcpDeps:
-                args = ['-Xbootclasspath/p:' + os.pathsep.join([d.classpath_repr() for d in bcpDeps])] + args
-
-        # Set the default JVMCI compiler
-        for jdkDist in reversed(jdkDeployedDists):
-            assert isinstance(jdkDist, JvmciJDKDeployedDist), jdkDist
-            if jdkDist._compilers:
-                jvmciCompiler = jdkDist._compilers[-1]
-                args = ['-Djvmci.compiler=' + jvmciCompiler] + args
-                break
-
         if '-version' in args:
             ignoredArgs = args[args.index('-version') + 1:]
             if  len(ignoredArgs) > 0:
@@ -877,41 +808,3 @@
             mx.warn('Ignoring "--jvmci-mode" option as "--jdk" tag is not "' + _JVMCI_JDK_TAG + '"')
 
     _vm.update(jvmVariant, debugLevel, jvmciMode)
-
-    for jdkDist in jdkDeployedDists:
-        jdkDist.post_parse_cmd_line()
-
-def _update_JDK9_STUBS_library():
-    """
-    Sets the "path" and "sha1" attributes of the "JDK9_STUBS" library.
-    """
-    jdk9InternalLib = _suite.suiteDict['libraries']['JDK9_STUBS']
-    jarInputDir = join(_suite.get_output_root(), 'jdk9-stubs')
-    jarPath = join(_suite.get_output_root(), 'jdk9-stubs.jar')
-
-    stubs = [
-        ('jdk.internal.misc', 'VM', """package jdk.internal.misc;
-public class VM {
-    public static String getSavedProperty(String key) {
-        throw new InternalError("should not reach here");
-    }
-}
-""")
-    ]
-
-    if not exists(jarPath):
-        sourceFiles = []
-        for (package, className, source) in stubs:
-            sourceFile = join(jarInputDir, package.replace('.', os.sep), className + '.java')
-            mx.ensure_dir_exists(os.path.dirname(sourceFile))
-            with open(sourceFile, 'w') as fp:
-                fp.write(source)
-            sourceFiles.append(sourceFile)
-        jdk = mx.get_jdk(tag='default')
-        mx.run([jdk.javac, '-d', jarInputDir] + sourceFiles)
-        mx.run([jdk.jar, 'cf', jarPath, '.'], cwd=jarInputDir)
-
-    jdk9InternalLib['path'] = jarPath
-    jdk9InternalLib['sha1'] = mx.sha1OfFile(jarPath)
-
-_update_JDK9_STUBS_library()
--- a/hotspot/.mx.jvmci/suite.py	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/.mx.jvmci/suite.py	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 suite = {
-  "mxversion" : "5.6.16",
+  "mxversion" : "5.23.1",
   "name" : "jvmci",
   "url" : "http://openjdk.java.net/projects/graal",
   "developer" : {
@@ -36,13 +36,6 @@
       "urls" : ["http://central.maven.org/maven2/org/testng/testng/6.9.10/testng-6.9.10.jar"],
       "sha1" : "6feb3e964aeb7097aff30c372aac3ec0f8d87ede",
     },
-
-    # Stubs for classes introduced in JDK9 that allow compilation with a JDK8 javac and Eclipse.
-    # The "path" and "sha1" attributes are added when mx_jvmci is loaded
-    # (see mx_jvmci._update_JDK9_STUBS_library()).
-    "JDK9_STUBS" : {
-        "license" : "GPLv2-CPE",
-     },
   },
 
   "projects" : {
@@ -52,7 +45,7 @@
     "jdk.vm.ci.services" : {
       "subDir" : "src/jdk.vm.ci/share/classes",
       "sourceDirs" : ["src"],
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "API,JVMCI",
     },
 
@@ -62,7 +55,7 @@
       "subDir" : "src/jdk.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "API,JVMCI",
     },
 
@@ -70,7 +63,7 @@
       "subDir" : "src/jdk.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "API,JVMCI",
     },
 
@@ -79,7 +72,7 @@
       "sourceDirs" : ["src"],
       "dependencies" : ["jdk.vm.ci.meta"],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "API,JVMCI",
     },
 
@@ -94,7 +87,7 @@
         "jdk.vm.ci.hotspot",
       ],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "API,JVMCI",
     },
 
@@ -103,9 +96,10 @@
       "sourceDirs" : ["src"],
       "dependencies" : [
         "jdk.vm.ci.code",
+        "jdk.vm.ci.services",
       ],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "API,JVMCI",
     },
 
@@ -118,18 +112,10 @@
         "jdk.vm.ci.runtime",
       ],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "API,JVMCI",
     },
 
-    "jdk.vm.ci.inittimer" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
-      "sourceDirs" : ["src"],
-      "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
-      "workingSets" : "JVMCI",
-    },
-
     # ------------- JVMCI:HotSpot -------------
 
     "jdk.vm.ci.aarch64" : {
@@ -137,7 +123,7 @@
       "sourceDirs" : ["src"],
       "dependencies" : ["jdk.vm.ci.code"],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "JVMCI,AArch64",
     },
 
@@ -146,7 +132,7 @@
       "sourceDirs" : ["src"],
       "dependencies" : ["jdk.vm.ci.code"],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "JVMCI,AMD64",
     },
 
@@ -155,7 +141,7 @@
       "sourceDirs" : ["src"],
       "dependencies" : ["jdk.vm.ci.code"],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "JVMCI,SPARC",
     },
 
@@ -165,13 +151,15 @@
       "dependencies" : [
         "jdk.vm.ci.hotspotvmconfig",
         "jdk.vm.ci.common",
-        "jdk.vm.ci.inittimer",
         "jdk.vm.ci.runtime",
         "jdk.vm.ci.services",
-        "JDK9_STUBS",
+      ],
+      "imports" : [
+        "jdk.internal.misc",
+        "jdk.internal.org.objectweb.asm",
       ],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "JVMCI",
     },
 
@@ -183,7 +171,7 @@
         "jdk.vm.ci.hotspot",
       ],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "API,JVMCI",
     },
 
@@ -191,7 +179,7 @@
       "subDir" : "src/jdk.vm.ci/share/classes",
       "sourceDirs" : ["src"],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "JVMCI,HotSpot",
     },
 
@@ -203,7 +191,7 @@
         "jdk.vm.ci.hotspot",
       ],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "JVMCI,HotSpot,AArch64",
     },
 
@@ -215,7 +203,7 @@
         "jdk.vm.ci.hotspot",
       ],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "JVMCI,HotSpot,AMD64",
     },
 
@@ -227,7 +215,7 @@
         "jdk.vm.ci.hotspot",
       ],
       "checkstyle" : "jdk.vm.ci.services",
-      "javaCompliance" : "1.8",
+      "javaCompliance" : "9",
       "workingSets" : "JVMCI,HotSpot,SPARC",
     },
 
@@ -249,7 +237,6 @@
     "JVMCI_API" : {
       "subDir" : "src/jdk.vm.ci/share/classes",
       "dependencies" : [
-        "jdk.vm.ci.inittimer",
         "jdk.vm.ci.runtime",
         "jdk.vm.ci.common",
         "jdk.vm.ci.aarch64",
@@ -292,31 +279,5 @@
       ],
       "exclude" : ["mx:JUNIT"],
     },
-
-    # This exists to have a monolithic jvmci.jar file which simplifies
-    # using the -Xoverride option in JDK9.
-    "JVMCI" : {
-      "subDir" : "src/jdk.vm.ci/share/classes",
-      "overlaps" : [
-        "JVMCI_API",
-        "JVMCI_SERVICES",
-        "JVMCI_HOTSPOT",
-        "JVMCI_HOTSPOTVMCONFIG",
-      ],
-      "dependencies" : [
-        "jdk.vm.ci.services",
-        "jdk.vm.ci.inittimer",
-        "jdk.vm.ci.runtime",
-        "jdk.vm.ci.common",
-        "jdk.vm.ci.aarch64",
-        "jdk.vm.ci.amd64",
-        "jdk.vm.ci.sparc",
-        "jdk.vm.ci.hotspotvmconfig",
-        "jdk.vm.ci.hotspot.aarch64",
-        "jdk.vm.ci.hotspot.amd64",
-        "jdk.vm.ci.hotspot.sparc",
-      ],
-      "exclude" : ["JDK9_STUBS"]
-    },
   },
 }
--- a/hotspot/src/cpu/aarch64/vm/compiledIC_aarch64.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/cpu/aarch64/vm/compiledIC_aarch64.cpp	Fri May 20 18:05:09 2016 +0300
@@ -92,9 +92,11 @@
 #ifndef PRODUCT
   NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
 
-  assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),
+  // read the value once
+  volatile intptr_t data = method_holder->data();
+  assert(data == 0 || data == (intptr_t)callee(),
          "a) MT-unsafe modification of inline cache");
-  assert(method_holder->data() == 0 || jump->jump_destination() == entry,
+  assert(data == 0 || jump->jump_destination() == entry,
          "b) MT-unsafe modification of inline cache");
 #endif
   // Update stub.
--- a/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRAssembler_ppc.cpp	Fri May 20 18:05:09 2016 +0300
@@ -2563,15 +2563,21 @@
 
   if (is_64bit) {
     __ cmpxchgd(BOOL_RESULT, /*current_value=*/R0, cmp_value, new_value, addr,
-                MacroAssembler::MemBarFenceAfter,
+                MacroAssembler::MemBarNone,
                 MacroAssembler::cmpxchgx_hint_atomic_update(),
                 noreg, NULL, /*check without ldarx first*/true);
   } else {
     __ cmpxchgw(BOOL_RESULT, /*current_value=*/R0, cmp_value, new_value, addr,
-                MacroAssembler::MemBarFenceAfter,
+                MacroAssembler::MemBarNone,
                 MacroAssembler::cmpxchgx_hint_atomic_update(),
                 noreg, /*check without ldarx first*/true);
   }
+
+  if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ isync();
+  } else {
+    __ sync();
+  }
 }
 
 
--- a/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/c1_LIRGenerator_ppc.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1353,7 +1353,11 @@
     }
   }
 
-  __ membar();
+  if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+    __ membar_acquire();
+  } else {
+    __ membar();
+  }
 }
 
 
--- a/hotspot/src/cpu/ppc/vm/compiledIC_ppc.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/compiledIC_ppc.cpp	Fri May 20 18:05:09 2016 +0300
@@ -178,10 +178,15 @@
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + IC_pos_in_java_to_interp_stub);
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
 
-  assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),
+#ifdef ASSERT
+  // read the value once
+  volatile intptr_t data = method_holder->data();
+  volatile address destination = jump->jump_destination();
+  assert(data == 0 || data == (intptr_t)callee(),
          "a) MT-unsafe modification of inline cache");
-  assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry,
+  assert(destination == (address)-1 || destination == entry,
          "b) MT-unsafe modification of inline cache");
+#endif
 
   // Update stub.
   method_holder->set_data((intptr_t)callee());
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1404,7 +1404,7 @@
 void MacroAssembler::cmpxchgw(ConditionRegister flag, Register dest_current_value,
                               Register compare_value, Register exchange_value,
                               Register addr_base, int semantics, bool cmpxchgx_hint,
-                              Register int_flag_success, bool contention_hint) {
+                              Register int_flag_success, bool contention_hint, bool weak) {
   Label retry;
   Label failed;
   Label done;
@@ -1414,6 +1414,7 @@
   bool use_result_reg    = (int_flag_success != noreg);
   bool preset_result_reg = (int_flag_success != dest_current_value && int_flag_success != compare_value &&
                             int_flag_success != exchange_value && int_flag_success != addr_base);
+  assert(!weak || flag == CCR0, "weak only supported with CCR0");
 
   if (use_result_reg && preset_result_reg) {
     li(int_flag_success, 0); // preset (assume cas failed)
@@ -1445,10 +1446,12 @@
   // fall through    => (flag == eq), (dest_current_value == compare_value)
 
   stwcx_(exchange_value, addr_base);
-  if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
-    bne_predict_not_taken(CCR0, retry); // StXcx_ sets CCR0.
-  } else {
-    bne(                  CCR0, retry); // StXcx_ sets CCR0.
+  if (!weak || use_result_reg) {
+    if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
+      bne_predict_not_taken(CCR0, weak ? failed : retry); // StXcx_ sets CCR0.
+    } else {
+      bne(                  CCR0, weak ? failed : retry); // StXcx_ sets CCR0.
+    }
   }
   // fall through    => (flag == eq), (dest_current_value == compare_value), (swapped)
 
@@ -1498,7 +1501,7 @@
 void MacroAssembler::cmpxchgd(ConditionRegister flag,
                               Register dest_current_value, RegisterOrConstant compare_value, Register exchange_value,
                               Register addr_base, int semantics, bool cmpxchgx_hint,
-                              Register int_flag_success, Label* failed_ext, bool contention_hint) {
+                              Register int_flag_success, Label* failed_ext, bool contention_hint, bool weak) {
   Label retry;
   Label failed_int;
   Label& failed = (failed_ext != NULL) ? *failed_ext : failed_int;
@@ -1508,6 +1511,7 @@
   bool use_result_reg    = (int_flag_success!=noreg);
   bool preset_result_reg = (int_flag_success!=dest_current_value && int_flag_success!=compare_value.register_or_noreg() &&
                             int_flag_success!=exchange_value && int_flag_success!=addr_base);
+  assert(!weak || flag == CCR0, "weak only supported with CCR0");
   assert(int_flag_success == noreg || failed_ext == NULL, "cannot have both");
 
   if (use_result_reg && preset_result_reg) {
@@ -1538,10 +1542,12 @@
   }
 
   stdcx_(exchange_value, addr_base);
-  if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
-    bne_predict_not_taken(CCR0, retry); // stXcx_ sets CCR0
-  } else {
-    bne(                  CCR0, retry); // stXcx_ sets CCR0
+  if (!weak || use_result_reg || failed_ext) {
+    if (UseStaticBranchPredictionInCompareAndSwapPPC64) {
+      bne_predict_not_taken(CCR0, weak ? failed : retry); // stXcx_ sets CCR0
+    } else {
+      bne(                  CCR0, weak ? failed : retry); // stXcx_ sets CCR0
+    }
   }
 
   // result in register (must do this at the end because int_flag_success can be the same register as one above)
--- a/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.hpp	Fri May 20 18:05:09 2016 +0300
@@ -430,11 +430,11 @@
   void cmpxchgw(ConditionRegister flag,
                 Register dest_current_value, Register compare_value, Register exchange_value, Register addr_base,
                 int semantics, bool cmpxchgx_hint = false,
-                Register int_flag_success = noreg, bool contention_hint = false);
+                Register int_flag_success = noreg, bool contention_hint = false, bool weak = false);
   void cmpxchgd(ConditionRegister flag,
                 Register dest_current_value, RegisterOrConstant compare_value, Register exchange_value,
                 Register addr_base, int semantics, bool cmpxchgx_hint = false,
-                Register int_flag_success = noreg, Label* failed = NULL, bool contention_hint = false);
+                Register int_flag_success = noreg, Label* failed = NULL, bool contention_hint = false, bool weak = false);
 
   // interface method calling
   void lookup_interface_method(Register recv_klass,
--- a/hotspot/src/cpu/ppc/vm/ppc.ad	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/cpu/ppc/vm/ppc.ad	Fri May 20 18:05:09 2016 +0300
@@ -3083,7 +3083,11 @@
       __ bne(                  CCR0, Lretry);
     }
     if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
-    __ fence();
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      __ sync();
+    }
   %}
 
   enc_class enc_GetAndAddL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
@@ -3108,7 +3112,11 @@
       __ bne(                  CCR0, Lretry);
     }
     if (RegCollision) __ subf(Rres, Rsrc, Rtmp);
-    __ fence();
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      __ sync();
+    }
   %}
 
   enc_class enc_GetAndSetI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src) %{
@@ -3132,7 +3140,11 @@
       __ bne(                  CCR0, Lretry);
     }
     if (RegCollision) __ mr(Rres, Rtmp);
-    __ fence();
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      __ sync();
+    }
   %}
 
   enc_class enc_GetAndSetL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src) %{
@@ -3156,7 +3168,11 @@
       __ bne(                  CCR0, Lretry);
     }
     if (RegCollision) __ mr(Rres, Rtmp);
-    __ fence();
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      __ sync();
+    }
   %}
 
   // This enc_class is needed so that scheduler gets proper
@@ -7553,6 +7569,8 @@
 // (CompareAndSwap ...)" or "If (CmpI (CompareAndSwap ..))"  cannot be
 // matched.
 
+// Strong versions:
+
 instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
   match(Set res (CompareAndSwapI mem_ptr (Binary src1 src2)));
   effect(TEMP cr0);
@@ -7562,8 +7580,13 @@
     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
-                MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
                 $res$$Register, true);
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      __ sync();
+    }
   %}
   ins_pipe(pipe_class_default);
 %}
@@ -7577,8 +7600,13 @@
     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
-                MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
                 $res$$Register, true);
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      __ sync();
+    }
   %}
   ins_pipe(pipe_class_default);
 %}
@@ -7592,8 +7620,13 @@
     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
-                MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
                 $res$$Register, NULL, true);
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      __ sync();
+    }
   %}
   ins_pipe(pipe_class_default);
 %}
@@ -7607,11 +7640,311 @@
     // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
-                MacroAssembler::MemBarFenceAfter, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
                 $res$$Register, NULL, true);
-  %}
-  ins_pipe(pipe_class_default);
-%}
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      __ sync();
+    }
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Weak versions:
+
+instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+  effect(TEMP cr0);
+  format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone,
+                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (WeakCompareAndSwapI mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+  effect(TEMP cr0);
+  format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
+    // value is never passed to caller.
+    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
+                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+  effect(TEMP cr0);
+  format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone,
+                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (WeakCompareAndSwapN mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+  effect(TEMP cr0);
+  format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
+    // value is never passed to caller.
+    __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
+                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, true, /*weak*/ true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+  effect(TEMP cr0);
+  format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    // value is never passed to caller.
+    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone,
+                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (WeakCompareAndSwapL mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+  effect(TEMP cr0);
+  format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
+    // value is never passed to caller.
+    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
+                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+  effect(TEMP cr0);
+  format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone,
+                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (WeakCompareAndSwapP mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+  effect(TEMP cr0);
+  format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
+    // value is never passed to caller.
+    __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
+                MacroAssembler::cmpxchgx_hint_atomic_update(), $res$$Register, NULL, true, /*weak*/ true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// CompareAndExchange
+
+instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+  effect(TEMP_DEF res, TEMP cr0);
+  format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                noreg, true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src1, iRegIsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (CompareAndExchangeI mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+  effect(TEMP_DEF res, TEMP cr0);
+  format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                noreg, true);
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
+      __ sync();
+    }
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+  effect(TEMP_DEF res, TEMP cr0);
+  format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                noreg, true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iRegNsrc src1, iRegNsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (CompareAndExchangeN mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+  effect(TEMP_DEF res, TEMP cr0);
+  format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                noreg, true);
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
+      __ sync();
+    }
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+  effect(TEMP_DEF res, TEMP cr0);
+  format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                noreg, NULL, true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iRegLsrc src1, iRegLsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (CompareAndExchangeL mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+  effect(TEMP_DEF res, TEMP cr0);
+  format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                noreg, NULL, true);
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
+      __ sync();
+    }
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() != MemNode::acquire && ((CompareAndSwapNode*)n)->order() != MemNode::seqcst);
+  effect(TEMP_DEF res, TEMP cr0);
+  format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                noreg, NULL, true);
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iRegPsrc src1, iRegPsrc src2, flagsRegCR0 cr0) %{
+  match(Set res (CompareAndExchangeP mem_ptr (Binary src1 src2)));
+  predicate(((CompareAndSwapNode*)n)->order() == MemNode::acquire || ((CompareAndSwapNode*)n)->order() == MemNode::seqcst);
+  effect(TEMP_DEF res, TEMP cr0);
+  format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
+  // Variable size: instruction count smaller if regs are disjoint.
+  ins_encode %{
+    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
+    // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
+    __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
+                MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
+                noreg, NULL, true);
+    if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+      __ isync();
+    } else {
+      // isync would be sufficient in case of CompareAndExchangeAcquire, but we currently don't optimize for that.
+      __ sync();
+    }
+  %}
+  ins_pipe(pipe_class_default);
+%}
+
+// Special RMW
 
 instruct getAndAddI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc src, flagsRegCR0 cr0) %{
   match(Set res (GetAndAddI mem_ptr src));
--- a/hotspot/src/cpu/sparc/vm/compiledIC_sparc.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/compiledIC_sparc.cpp	Fri May 20 18:05:09 2016 +0300
@@ -101,10 +101,15 @@
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
 
-  assert(method_holder->data() == 0 || method_holder->data() == (intptr_t)callee(),
+#ifdef ASSERT
+  // read the value once
+  intptr_t data = method_holder->data();
+  address destination = jump->jump_destination();
+  assert(data == 0 || data == (intptr_t)callee(),
          "a) MT-unsafe modification of inline cache");
-  assert(jump->jump_destination() == (address)-1 || jump->jump_destination() == entry,
+  assert(destination == (address)-1 || destination == entry,
          "b) MT-unsafe modification of inline cache");
+#endif
 
   // Update stub.
   method_holder->set_data((intptr_t)callee());
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64Kind.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.aarch64/src/jdk/vm/ci/aarch64/AArch64Kind.java	Fri May 20 18:05:09 2016 +0300
@@ -45,12 +45,7 @@
     V128_DWORD(16, DWORD),
     V128_QWORD(16, QWORD),
     V128_SINGLE(16, SINGLE),
-    V128_DOUBLE(16, DOUBLE),
-
-    MASK8(1),
-    MASK16(2),
-    MASK32(4),
-    MASK64(8);
+    V128_DOUBLE(16, DOUBLE);
 
     private final int size;
     private final int vectorLength;
@@ -121,18 +116,6 @@
         }
     }
 
-    public boolean isMask() {
-        switch (this) {
-            case MASK8:
-            case MASK16:
-            case MASK32:
-            case MASK64:
-                return true;
-            default:
-                return false;
-        }
-    }
-
     public char getTypeChar() {
         switch (this) {
             case BYTE:
@@ -159,11 +142,6 @@
             case V128_SINGLE:
             case V128_DOUBLE:
                 return 'v';
-            case MASK8:
-            case MASK16:
-            case MASK32:
-            case MASK64:
-                return 'k';
             default:
                 return '-';
         }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/BytecodeFrame.java	Fri May 20 18:05:09 2016 +0300
@@ -98,6 +98,11 @@
      */
     public final boolean rethrowException;
 
+    /**
+     * Specifies if this object represents a frame state in the middle of executing a call. If
+     * true, the arguments to the call have been popped from the stack and the return value (for a
+     * non-void call) has not yet been pushed.
+     */
     public final boolean duringCall;
 
     /**
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CodeUtil.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -417,7 +417,7 @@
     /**
      * Create a calling convention from a {@link ResolvedJavaMethod}.
      */
-    public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method) {
+    public static CallingConvention getCallingConvention(CodeCacheProvider codeCache, CallingConvention.Type type, ResolvedJavaMethod method, ValueKindFactory<?> valueKindFactory) {
         Signature sig = method.getSignature();
         JavaType retType = sig.getReturnType(null);
         int sigCount = sig.getParameterCount(false);
@@ -434,6 +434,6 @@
         }
 
         RegisterConfig registerConfig = codeCache.getRegisterConfig();
-        return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget());
+        return registerConfig.getCallingConvention(type, retType, argTypes, valueKindFactory);
     }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequestResult.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompilationRequestResult.java	Fri May 20 18:05:09 2016 +0300
@@ -23,49 +23,15 @@
 package jdk.vm.ci.code;
 
 /**
- * Simple class to provide information about the result of a compile request.
+ * Provides information about the result of a {@link CompilationRequest}.
  */
-public final class CompilationRequestResult {
-
-    /**
-     * A user readable description of the failure.
-     */
-    private final String failureMessage;
-
-    /**
-     * Whether this is a transient failure where retrying would help.
-     */
-    private final boolean retry;
+public interface CompilationRequestResult {
 
     /**
-     * Number of bytecodes inlined into the compilation, exclusive of the bytecodes in the root
-     * method.
+     * Determines if the compilation was successful.
+     *
+     * @return a non-null object whose {@link Object#toString()} describes the failure or null if
+     *         compilation was successful
      */
-    private final int inlinedBytecodes;
-
-    private CompilationRequestResult(String failureMessage, boolean retry, int inlinedBytecodes) {
-        this.failureMessage = failureMessage;
-        this.retry = retry;
-        this.inlinedBytecodes = inlinedBytecodes;
-    }
-
-    public static CompilationRequestResult success(int inlinedBytecodes) {
-        return new CompilationRequestResult(null, true, inlinedBytecodes);
-    }
-
-    public static CompilationRequestResult failure(String failureMessage, boolean retry) {
-        return new CompilationRequestResult(failureMessage, retry, 0);
-    }
-
-    public String getFailureMessage() {
-        return failureMessage;
-    }
-
-    public boolean getRetry() {
-        return retry;
-    }
-
-    public int getInlinedBytecodes() {
-        return inlinedBytecodes;
-    }
+    Object getFailure();
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompiledCode.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/CompiledCode.java	Fri May 20 18:05:09 2016 +0300
@@ -23,7 +23,9 @@
 package jdk.vm.ci.code;
 
 /**
- * The output from compiling a method.
+ * Marker type for an object containing the output of a compiler in a form suitable for installing
+ * into a managed code heap. Since the details of a code heap are specific to each runtime, this
+ * interface does not specify any methods.
  */
 public interface CompiledCode {
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/MemoryBarriers.java	Fri May 20 18:05:09 2016 +0300
@@ -25,8 +25,8 @@
 /**
  * Constants and intrinsic definition for memory barriers.
  *
- * The documentation for each constant is taken from Doug Lea's <a
- * href="http://gee.cs.oswego.edu/dl/jmm/cookbook.html">The JSR-133 Cookbook for Compiler
+ * The documentation for each constant is taken from Doug Lea's
+ * <a href="http://gee.cs.oswego.edu/dl/jmm/cookbook.html">The JSR-133 Cookbook for Compiler
  * Writers</a>.
  * <p>
  * The {@code JMM_*} constants capture the memory barriers necessary to implement the Java Memory
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ReferenceMap.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ReferenceMap.java	Fri May 20 18:05:09 2016 +0300
@@ -22,5 +22,10 @@
  */
 package jdk.vm.ci.code;
 
+/**
+ * Marker type for an object containing information about where the object references are in machine
+ * state (e.g., registers or stack locations). This is typically associated with an execution point
+ * in compiled code.
+ */
 public abstract class ReferenceMap {
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/Register.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,7 @@
  */
 package jdk.vm.ci.code;
 
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.ValueKind;
 
 /**
  * Represents a target machine register.
@@ -38,16 +37,8 @@
     public static final Register None = new Register(-1, -1, "noreg", SPECIAL);
 
     /**
-     * Frame pointer of the current method. All spill slots and outgoing stack-based arguments are
-     * addressed relative to this register.
-     */
-    public static final Register Frame = new Register(-2, -2, "framereg", SPECIAL);
-
-    public static final Register CallerFrame = new Register(-3, -3, "callerframereg", SPECIAL);
-
-    /**
      * The identifier for this register that is unique across all the registers in a
-     * {@link Architecture}. A valid register has {@code number > 0}.
+     * {@link Architecture}. A valid register has {@code number >= 0}.
      */
     public final int number;
 
@@ -144,17 +135,17 @@
      * @param kind the specified kind
      * @return the {@link RegisterValue}
      */
-    public RegisterValue asValue(LIRKind kind) {
+    public RegisterValue asValue(ValueKind<?> kind) {
         return new RegisterValue(kind, this);
     }
 
     /**
      * Gets this register as a {@linkplain RegisterValue value} with no particular kind.
      *
-     * @return a {@link RegisterValue} with {@link JavaKind#Illegal} kind.
+     * @return a {@link RegisterValue} with {@link ValueKind#Illegal} kind.
      */
     public RegisterValue asValue() {
-        return asValue(LIRKind.Illegal);
+        return asValue(ValueKind.Illegal);
     }
 
     /**
@@ -166,38 +157,6 @@
         return number >= 0;
     }
 
-    /**
-     * Gets the maximum register {@linkplain #number number} in a given set of registers.
-     *
-     * @param registers the set of registers to process
-     * @return the maximum register number for any register in {@code registers}
-     */
-    public static int maxRegisterNumber(Register[] registers) {
-        int max = Integer.MIN_VALUE;
-        for (Register r : registers) {
-            if (r.number > max) {
-                max = r.number;
-            }
-        }
-        return max;
-    }
-
-    /**
-     * Gets the maximum register {@linkplain #encoding encoding} in a given set of registers.
-     *
-     * @param registers the set of registers to process
-     * @return the maximum register encoding for any register in {@code registers}
-     */
-    public static int maxRegisterEncoding(Register[] registers) {
-        int max = Integer.MIN_VALUE;
-        for (Register r : registers) {
-            if (r.encoding > max) {
-                max = r.encoding;
-            }
-        }
-        return max;
-    }
-
     @Override
     public String toString() {
         return name;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterConfig.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.ValueKind;
 
 /**
  * A register configuration binds roles and {@linkplain RegisterAttributes attributes} to physical
@@ -46,7 +47,8 @@
     }
 
     /**
-     * Gets the register to which {@link Register#Frame} and {@link Register#CallerFrame} are bound.
+     * Gets the register used as the frame pointer. Spill slots and outgoing stack-based arguments
+     * are addressed relative to this register.
      */
     Register getFrameRegister();
 
@@ -56,9 +58,9 @@
      * @param type the type of calling convention being requested
      * @param returnType the return type (can be null for methods returning {@code void})
      * @param parameterTypes the types of the arguments of the call
-     * @param target the target platform
+     * @param valueKindFactory the factory to create custom {@link ValueKind ValueKinds}
      */
-    CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target);
+    CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory);
 
     /**
      * Gets the ordered set of registers that are can be used to pass parameters according to a
@@ -106,14 +108,6 @@
     RegisterAttributes[] getAttributesMap();
 
     /**
-     * Gets the register corresponding to a runtime-defined role.
-     *
-     * @param id the identifier of a runtime-defined register role
-     * @return the register playing the role specified by {@code id}
-     */
-    Register getRegisterForRole(int id);
-
-    /**
      * Determines if all {@link #getAllocatableRegisters() allocatable} registers are
      * {@link #getCallerSaveRegisters() caller saved}.
      */
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/RegisterValue.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,23 +23,16 @@
 package jdk.vm.ci.code;
 
 import jdk.vm.ci.meta.AllocatableValue;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.ValueKind;
 
 /**
- * Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance
- * of {@link RegisterValue} for each ({@link Register}, {@link JavaKind}) pair. Use
- * {@link Register#asValue(LIRKind)} to retrieve the canonical {@link RegisterValue} instance for a
- * given (register,kind) pair.
+ * Denotes a register that stores a value of a fixed kind.
  */
 public final class RegisterValue extends AllocatableValue {
 
     private final Register reg;
 
-    /**
-     * Should only be called from {@link Register#Register} to ensure canonicalization.
-     */
-    protected RegisterValue(LIRKind kind, Register register) {
+    protected RegisterValue(ValueKind<?> kind, Register register) {
         super(kind);
         this.reg = register;
     }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/SourceStackTrace.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.code;
-
-/**
- * Class representing an exception with a stack trace of the currently processed position in the
- * compiled Java program instead of the stack trace of the compiler. The exception of the compiler
- * is saved as the cause of this exception.
- */
-public abstract class SourceStackTrace extends BailoutException {
-    private static final long serialVersionUID = 2144811793442316776L;
-
-    public static SourceStackTrace create(Throwable cause, String format, StackTraceElement[] elements) {
-        return new SourceStackTrace(cause, format) {
-
-            private static final long serialVersionUID = 6279381376051787907L;
-
-            @Override
-            public synchronized Throwable fillInStackTrace() {
-                assert elements != null;
-                setStackTrace(elements);
-                return this;
-            }
-        };
-    }
-
-    private SourceStackTrace(Throwable cause, String format) {
-        super(cause, format);
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/StackSlot.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 package jdk.vm.ci.code;
 
 import jdk.vm.ci.meta.AllocatableValue;
-import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.ValueKind;
 
 /**
  * Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an
@@ -43,16 +43,16 @@
      * @param addFrameSize Specifies if the offset is relative to the stack pointer, or the
      *            beginning of the frame (stack pointer + total frame size).
      */
-    public static StackSlot get(LIRKind kind, int offset, boolean addFrameSize) {
+    public static StackSlot get(ValueKind<?> kind, int offset, boolean addFrameSize) {
         assert addFrameSize || offset >= 0;
         return new StackSlot(kind, offset, addFrameSize);
     }
 
     /**
-     * Private constructor to enforce use of {@link #get(LIRKind, int, boolean)} so that a cache can
-     * be used.
+     * Private constructor to enforce use of {@link #get(ValueKind, int, boolean)} so that a cache
+     * can be used.
      */
-    private StackSlot(LIRKind kind, int offset, boolean addFrameSize) {
+    private StackSlot(ValueKind<?> kind, int offset, boolean addFrameSize) {
         super(kind);
         this.offset = offset;
         this.addFrameSize = addFrameSize;
@@ -99,7 +99,7 @@
     public StackSlot asOutArg() {
         assert offset >= 0;
         if (addFrameSize) {
-            return get(getLIRKind(), offset, false);
+            return get(getValueKind(), offset, false);
         }
         return this;
     }
@@ -110,7 +110,7 @@
     public StackSlot asInArg() {
         assert offset >= 0;
         if (!addFrameSize) {
-            return get(getLIRKind(), offset, true);
+            return get(getValueKind(), offset, true);
         }
         return this;
     }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/TargetDescription.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,8 @@
 package jdk.vm.ci.code;
 
 import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
+
 import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LIRKind;
-import jdk.vm.ci.meta.PlatformKind;
 
 /**
  * Represents the target machine for a compiler, including the CPU architecture, the size of
@@ -56,8 +55,8 @@
     public final JavaKind wordJavaKind;
 
     /**
-     * The stack alignment requirement of the platform. For example, from Appendix D of <a
-     * href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures
+     * The stack alignment requirement of the platform. For example, from Appendix D of
+     * <a href="http://www.intel.com/Assets/PDF/manual/248966.pdf">Intel 64 and IA-32 Architectures
      * Optimization Reference Manual</a>:
      *
      * <pre>
@@ -118,13 +117,4 @@
     public String toString() {
         return identityHashCodeString(this);
     }
-
-    public LIRKind getLIRKind(JavaKind javaKind) {
-        PlatformKind platformKind = arch.getPlatformKind(javaKind);
-        if (javaKind.isObject()) {
-            return LIRKind.reference(platformKind);
-        } else {
-            return LIRKind.value(platformKind);
-        }
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueKindFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.code;
+
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.ValueKind;
+
+/**
+ * Can be implemented by compilers to create custom {@link ValueKind} subclasses.
+ */
+public interface ValueKindFactory<K extends ValueKind<K>> {
+
+    K getValueKind(JavaKind javaKind);
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueUtil.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/ValueUtil.java	Fri May 20 18:05:09 2016 +0300
@@ -22,9 +22,6 @@
  */
 package jdk.vm.ci.code;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import jdk.vm.ci.meta.AllocatableValue;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaValue;
@@ -111,73 +108,4 @@
             return asRegister(value);
         }
     }
-
-    public static boolean sameRegister(Value v1, Value v2) {
-        return isRegister(v1) && isRegister(v2) && asRegister(v1).equals(asRegister(v2));
-    }
-
-    public static boolean sameRegister(Value v1, Value v2, Value v3) {
-        return sameRegister(v1, v2) && sameRegister(v1, v3);
-    }
-
-    /**
-     * Checks if all the provided values are different physical registers. The parameters can be
-     * either {@link Register registers}, {@link Value values} or arrays of them. All values that
-     * are not {@link RegisterValue registers} are ignored.
-     */
-    public static boolean differentRegisters(Object... values) {
-        List<Register> registers = collectRegisters(values, new ArrayList<Register>());
-        for (int i = 1; i < registers.size(); i++) {
-            Register r1 = registers.get(i);
-            for (int j = 0; j < i; j++) {
-                Register r2 = registers.get(j);
-                if (r1.equals(r2)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    private static List<Register> collectRegisters(Object[] values, List<Register> registers) {
-        for (Object o : values) {
-            if (o instanceof Register) {
-                registers.add((Register) o);
-            } else if (o instanceof Value) {
-                if (isRegister((Value) o)) {
-                    registers.add(asRegister((Value) o));
-                }
-            } else if (o instanceof Object[]) {
-                collectRegisters((Object[]) o, registers);
-            } else {
-                throw new IllegalArgumentException("Not a Register or Value: " + o);
-            }
-        }
-        return registers;
-    }
-
-    /**
-     * Subtract sets of registers (x - y).
-     *
-     * @param x a set of register to subtract from.
-     * @param y a set of registers to subtract.
-     * @return resulting set of registers (x - y).
-     */
-    public static Value[] subtractRegisters(Value[] x, Value[] y) {
-        ArrayList<Value> result = new ArrayList<>(x.length);
-        for (Value i : x) {
-            boolean append = true;
-            for (Value j : y) {
-                if (ValueUtil.sameRegister(i, j)) {
-                    append = false;
-                    break;
-                }
-            }
-            if (append) {
-                result.add(i);
-            }
-        }
-        Value[] resultArray = new Value[result.size()];
-        return result.toArray(resultArray);
-    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/package-info.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/package-info.java	Fri May 20 18:05:09 2016 +0300
@@ -21,10 +21,10 @@
  * questions.
  */
 /**
- * Package that defines the interface between a Java application that wants to install code and the runtime.
- * The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider} interface.
- * The method {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompiledCode, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
+ * Package that defines the interface between a Java application that wants to install code and the
+ * runtime. The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider}
+ * interface. The method
+ * {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompiledCode, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
  * can be used to install code.
  */
 package jdk.vm.ci.code;
-
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ConstantReference.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/ConstantReference.java	Fri May 20 18:05:09 2016 +0300
@@ -26,6 +26,10 @@
 
 import jdk.vm.ci.meta.VMConstant;
 
+/**
+ * Represents an embedded {@link VMConstant} in the code or data section that needs to be
+ * {@link DataPatch patched} by the VM (e.g. an embedded pointer to a Java object).
+ */
 public final class ConstantReference extends Reference {
 
     private final VMConstant constant;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataPatch.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataPatch.java	Fri May 20 18:05:09 2016 +0300
@@ -24,12 +24,12 @@
 
 import java.util.Objects;
 
-import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.VMConstant;
 
 /**
  * Represents a code site that references some data. The associated data can be either a
  * {@link DataSectionReference reference} to the data section, or it may be an inlined
- * {@link JavaConstant} that needs to be patched.
+ * {@link VMConstant} that needs to be patched.
  */
 public final class DataPatch extends Site {
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataSectionReference.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/DataSectionReference.java	Fri May 20 18:05:09 2016 +0300
@@ -22,6 +22,10 @@
  */
 package jdk.vm.ci.code.site;
 
+/**
+ * Represents a pointer to some location in the data section that should be {@link DataPatch
+ * patched} into the code.
+ */
 public final class DataSectionReference extends Reference {
 
     private boolean initialized;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/InfopointReason.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/InfopointReason.java	Fri May 20 18:05:09 2016 +0300
@@ -30,7 +30,6 @@
     SAFEPOINT,
     CALL,
     IMPLICIT_EXCEPTION,
-    METASPACE_ACCESS,
     METHOD_START,
     METHOD_END,
     BYTECODE_POSITION;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Mark.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/site/Mark.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,23 @@
 import java.util.Objects;
 
 /**
- * Represents a mark in the machine code that can be used by the runtime for its own purposes. A
- * mark can reference other marks.
+ * Associates arbitrary information with a position in machine code. For example, HotSpot specific
+ * code in a compiler backend may use this to denote the position of a safepoint, exception handler
+ * entry point, verified entry point etc.
  */
 public final class Mark extends Site {
 
+    /**
+     * An object denoting extra semantic information about the machine code position of this mark.
+     */
     public final Object id;
 
+    /**
+     * Creates a mark that associates {@code id} with the machine code position {@code pcOffset}.
+     *
+     * @param pcOffset
+     * @param id
+     */
     public Mark(int pcOffset, Object id) {
         super(pcOffset);
         this.id = id;
@@ -40,7 +50,7 @@
     @Override
     public String toString() {
         if (id == null) {
-            return String.format("%d[<mar>]", pcOffset);
+            return String.format("%d[<mark>]", pcOffset);
         } else if (id instanceof Integer) {
             return String.format("%d[<mark with id %s>]", pcOffset, Integer.toHexString((Integer) id));
         } else {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrame.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.code/src/jdk/vm/ci/code/stack/InspectedFrame.java	Fri May 20 18:05:09 2016 +0300
@@ -24,16 +24,19 @@
 
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
+/**
+ * Access to the object variables in a stack frame.
+ */
 public interface InspectedFrame {
 
     /**
-     * Returns the value of the local at the given index. Currently only works for object values.
-     * This value is a copy iff {@link #isVirtual(int)} is true.
+     * Returns the value of the object local at {@code index}. This value is a copy iff
+     * {@link #isVirtual(int)} is true.
      */
     Object getLocal(int index);
 
     /**
-     * Returns whether the local at the given index is a virtual object, and therefore the object
+     * Returns whether the local at {@code index} is a virtual object, and therefore the object
      * returned by {@link #getLocal(int)} is a copy.
      */
     boolean isVirtual(int index);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/InitTimer.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.common;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A facility for timing a step in the runtime initialization sequence. This is independent from all
+ * other JVMCI code so as to not perturb the initialization sequence. It is enabled by setting the
+ * {@code "jvmci.inittimer"} system property to {@code "true"}.
+ */
+public final class InitTimer implements AutoCloseable {
+    final String name;
+    final long start;
+
+    private InitTimer(String name) {
+        int n = nesting.getAndIncrement();
+        if (n == 0) {
+            initializingThread = Thread.currentThread();
+            System.out.println("INITIALIZING THREAD: " + initializingThread);
+        } else {
+            assert Thread.currentThread() == initializingThread : Thread.currentThread() + " != " + initializingThread;
+        }
+        this.name = name;
+        this.start = System.currentTimeMillis();
+        System.out.println("START: " + SPACES.substring(0, n * 2) + name);
+    }
+
+    @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "only the initializing thread accesses this field")
+    public void close() {
+        final long end = System.currentTimeMillis();
+        int n = nesting.decrementAndGet();
+        System.out.println(" DONE: " + SPACES.substring(0, n * 2) + name + " [" + (end - start) + " ms]");
+        if (n == 0) {
+            initializingThread = null;
+        }
+    }
+
+    public static InitTimer timer(String name) {
+        return ENABLED ? new InitTimer(name) : null;
+    }
+
+    public static InitTimer timer(String name, Object suffix) {
+        return ENABLED ? new InitTimer(name + suffix) : null;
+    }
+
+    /**
+     * Specifies if initialization timing is enabled. Note: This property cannot use
+     * {@code HotSpotJVMCIRuntime.Option} since that class is not visible from this package.
+     */
+    private static final boolean ENABLED = Boolean.getBoolean("jvmci.InitTimer");
+
+    public static final AtomicInteger nesting = ENABLED ? new AtomicInteger() : null;
+    public static final String SPACES = "                                            ";
+
+    /**
+     * Used to assert the invariant that all related initialization happens on the same thread.
+     */
+    public static Thread initializingThread;
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/JVMCIError.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/JVMCIError.java	Fri May 20 18:05:09 2016 +0300
@@ -31,7 +31,6 @@
 public class JVMCIError extends Error {
 
     private static final long serialVersionUID = 531632331813456233L;
-    private final ArrayList<String> context = new ArrayList<>();
 
     public static RuntimeException unimplemented() {
         throw new JVMCIError("unimplemented");
@@ -101,27 +100,6 @@
         super(cause);
     }
 
-    /**
-     * This constructor creates a {@link JVMCIError} and adds all the
-     * {@linkplain #addContext(String) context} of another {@link JVMCIError}.
-     *
-     * @param e the original {@link JVMCIError}
-     */
-    public JVMCIError(JVMCIError e) {
-        super(e);
-        context.addAll(e.context);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder str = new StringBuilder();
-        str.append(super.toString());
-        for (String s : context) {
-            str.append("\n\tat ").append(s);
-        }
-        return str.toString();
-    }
-
     private static String format(String msg, Object... args) {
         if (args != null) {
             // expand Iterable parameters into a list representation
@@ -137,13 +115,4 @@
         }
         return String.format(Locale.ENGLISH, msg, args);
     }
-
-    public JVMCIError addContext(String newContext) {
-        this.context.add(newContext);
-        return this;
-    }
-
-    public JVMCIError addContext(String name, Object obj) {
-        return addContext(format("%s: %s", name, obj));
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/SuppressFBWarnings.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.common;
+
+/**
+ * Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
+ */
+@interface SuppressFBWarnings {
+    /**
+     * The set of FindBugs
+     * <a href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
+     * suppressed in annotated element. The value can be a bug category, kind or pattern.
+     */
+    String[] value();
+
+    /**
+     * Reason why the warning is suppressed.
+     */
+    String justification();
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.common/src/jdk/vm/ci/common/UnsafeUtil.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.common;
-
-import jdk.internal.misc.Unsafe;
-
-/**
- * Utilities for operating on raw memory with {@link Unsafe}.
- */
-public class UnsafeUtil {
-
-    /**
-     * Copies the contents of a {@link String} to a native memory buffer as a {@code '\0'}
-     * terminated C string. The native memory buffer is allocated via
-     * {@link Unsafe#allocateMemory(long)}. The caller is responsible for releasing the buffer when
-     * it is no longer needed via {@link Unsafe#freeMemory(long)}.
-     *
-     * @return the native memory pointer of the C string created from {@code s}
-     */
-    public static long createCString(Unsafe unsafe, String s) {
-        return writeCString(unsafe, s, unsafe.allocateMemory(s.length() + 1));
-    }
-
-    /**
-     * Reads a {@code '\0'} terminated C string from native memory and converts it to a
-     * {@link String}.
-     *
-     * @return a Java string
-     */
-    public static String readCString(Unsafe unsafe, long address) {
-        if (address == 0) {
-            return null;
-        }
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0;; i++) {
-            char c = (char) unsafe.getByte(address + i);
-            if (c == 0) {
-                break;
-            }
-            sb.append(c);
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Writes the contents of a {@link String} to a native memory buffer as a {@code '\0'}
-     * terminated C string. The caller is responsible for ensuring the buffer is at least
-     * {@code s.length() + 1} bytes long. The caller is also responsible for releasing the buffer
-     * when it is no longer.
-     *
-     * @return the value of {@code buf}
-     */
-    public static long writeCString(Unsafe unsafe, String s, long buf) {
-        int size = s.length();
-        for (int i = 0; i < size; i++) {
-            unsafe.putByte(buf + i, (byte) s.charAt(i));
-        }
-        unsafe.putByte(buf + size, (byte) '\0');
-        return buf;
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotJVMCIBackendFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
  */
 package jdk.vm.ci.hotspot.aarch64;
 
-import static jdk.vm.ci.inittimer.InitTimer.timer;
+import static jdk.vm.ci.common.InitTimer.timer;
 
 import java.util.EnumSet;
 
@@ -31,6 +31,7 @@
 import jdk.vm.ci.code.RegisterConfig;
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.code.stack.StackIntrospection;
+import jdk.vm.ci.common.InitTimer;
 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
 import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
 import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
@@ -38,7 +39,6 @@
 import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
 import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
-import jdk.vm.ci.inittimer.InitTimer;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.runtime.JVMCIBackend;
 
@@ -68,7 +68,7 @@
     }
 
     protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
-        return new AArch64HotSpotRegisterConfig(target.arch, runtime.getConfig());
+        return new AArch64HotSpotRegisterConfig(target, runtime.getConfig());
     }
 
     protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
@@ -122,7 +122,8 @@
         }
     }
 
-    protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, StackIntrospection stackIntrospection) {
+    protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection,
+                    StackIntrospection stackIntrospection) {
         return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
     }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.aarch64/src/jdk/vm/ci/hotspot/aarch64/AArch64HotSpotRegisterConfig.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -64,19 +64,20 @@
 import jdk.vm.ci.code.RegisterConfig;
 import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.ValueKindFactory;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
 import jdk.vm.ci.meta.AllocatableValue;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
-import jdk.vm.ci.meta.LIRKind;
 import jdk.vm.ci.meta.PlatformKind;
 import jdk.vm.ci.meta.Value;
+import jdk.vm.ci.meta.ValueKind;
 
 public class AArch64HotSpotRegisterConfig implements RegisterConfig {
 
-    private final Architecture architecture;
+    private final TargetDescription target;
 
     private final Register[] allocatable;
 
@@ -104,7 +105,7 @@
     public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
         ArrayList<Register> list = new ArrayList<>();
         for (Register reg : registers) {
-            if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
+            if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
                 list.add(reg);
             }
         }
@@ -159,13 +160,13 @@
         return registers;
     }
 
-    public AArch64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
-        this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
+    public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
+        this(target, config, initAllocatable(target.arch, config.useCompressedOops));
         assert callerSaved.length >= allocatable.length;
     }
 
-    public AArch64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) {
-        this.architecture = architecture;
+    public AArch64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
+        this.target = target;
         this.maxFrameSize = config.maxFrameSize;
 
         this.allocatable = allocatable.clone();
@@ -195,19 +196,14 @@
     }
 
     @Override
-    public Register getRegisterForRole(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
+    public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
         HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
         if (type == HotSpotCallingConventionType.NativeCall) {
-            return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
+            return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
         }
         // On x64, parameter locations are the same whether viewed
         // from the caller or callee perspective
-        return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
+        return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
     }
 
     @Override
@@ -230,7 +226,8 @@
         }
     }
 
-    private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
+    private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
+                    ValueKindFactory<?> valueKindFactory) {
         AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
 
         int currentGeneral = 0;
@@ -250,14 +247,14 @@
                 case Object:
                     if (currentGeneral < generalParameterRegisters.length) {
                         Register register = generalParameterRegisters[currentGeneral++];
-                        locations[i] = register.asValue(target.getLIRKind(kind));
+                        locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
                     }
                     break;
                 case Float:
                 case Double:
                     if (currentSIMD < simdParameterRegisters.length) {
                         Register register = simdParameterRegisters[currentSIMD++];
-                        locations[i] = register.asValue(target.getLIRKind(kind));
+                        locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
                     }
                     break;
                 default:
@@ -265,14 +262,14 @@
             }
 
             if (locations[i] == null) {
-                LIRKind lirKind = target.getLIRKind(kind);
-                locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
-                currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
+                ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
+                locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out);
+                currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
             }
         }
 
         JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
-        AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(target.getLIRKind(returnKind.getStackKind()));
+        AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
         return new CallingConvention(currentStackOffset, returnLocation, locations);
     }
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotJVMCIBackendFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
  */
 package jdk.vm.ci.hotspot.amd64;
 
-import static jdk.vm.ci.inittimer.InitTimer.timer;
+import static jdk.vm.ci.common.InitTimer.timer;
 
 import java.util.EnumSet;
 
@@ -31,6 +31,7 @@
 import jdk.vm.ci.code.RegisterConfig;
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.code.stack.StackIntrospection;
+import jdk.vm.ci.common.InitTimer;
 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
 import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
 import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
@@ -38,7 +39,6 @@
 import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
 import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
-import jdk.vm.ci.inittimer.InitTimer;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.runtime.JVMCIBackend;
 
@@ -152,7 +152,7 @@
     }
 
     protected RegisterConfig createRegisterConfig(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target) {
-        return new AMD64HotSpotRegisterConfig(target.arch, runtime.getConfig());
+        return new AMD64HotSpotRegisterConfig(target, runtime.getConfig());
     }
 
     protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
@@ -206,7 +206,8 @@
         }
     }
 
-    protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, StackIntrospection stackIntrospection) {
+    protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection,
+                    StackIntrospection stackIntrospection) {
         return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
     }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.amd64/src/jdk/vm/ci/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -56,19 +56,20 @@
 import jdk.vm.ci.code.RegisterConfig;
 import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.ValueKindFactory;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
 import jdk.vm.ci.meta.AllocatableValue;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
-import jdk.vm.ci.meta.LIRKind;
 import jdk.vm.ci.meta.PlatformKind;
 import jdk.vm.ci.meta.Value;
+import jdk.vm.ci.meta.ValueKind;
 
 public class AMD64HotSpotRegisterConfig implements RegisterConfig {
 
-    private final Architecture architecture;
+    private final TargetDescription target;
 
     private final Register[] allocatable;
 
@@ -96,7 +97,7 @@
     public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
         ArrayList<Register> list = new ArrayList<>();
         for (Register reg : registers) {
-            if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
+            if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
                 list.add(reg);
             }
         }
@@ -145,13 +146,13 @@
         return registers;
     }
 
-    public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
-        this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
+    public AMD64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
+        this(target, config, initAllocatable(target.arch, config.useCompressedOops));
         assert callerSaved.length >= allocatable.length;
     }
 
-    public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config, Register[] allocatable) {
-        this.architecture = architecture;
+    public AMD64HotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config, Register[] allocatable) {
+        this.target = target;
         this.maxFrameSize = config.maxFrameSize;
 
         if (config.windowsOs) {
@@ -173,7 +174,7 @@
         callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
 
         allAllocatableAreCallerSaved = true;
-        attributesMap = RegisterAttributes.createMap(this, architecture.getRegisters());
+        attributesMap = RegisterAttributes.createMap(this, target.arch.getRegisters());
     }
 
     @Override
@@ -192,19 +193,14 @@
     }
 
     @Override
-    public Register getRegisterForRole(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
+    public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
         HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
         if (type == HotSpotCallingConventionType.NativeCall) {
-            return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
+            return callingConvention(nativeGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
         }
         // On x64, parameter locations are the same whether viewed
         // from the caller or callee perspective
-        return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, target);
+        return callingConvention(javaGeneralParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
     }
 
     @Override
@@ -227,7 +223,8 @@
         }
     }
 
-    private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
+    private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
+                    ValueKindFactory<?> valueKindFactory) {
         AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
 
         int currentGeneral = 0;
@@ -247,14 +244,14 @@
                 case Object:
                     if (currentGeneral < generalParameterRegisters.length) {
                         Register register = generalParameterRegisters[currentGeneral++];
-                        locations[i] = register.asValue(target.getLIRKind(kind));
+                        locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
                     }
                     break;
                 case Float:
                 case Double:
                     if (currentXMM < xmmParameterRegisters.length) {
                         Register register = xmmParameterRegisters[currentXMM++];
-                        locations[i] = register.asValue(target.getLIRKind(kind));
+                        locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
                     }
                     break;
                 default:
@@ -262,14 +259,14 @@
             }
 
             if (locations[i] == null) {
-                LIRKind lirKind = target.getLIRKind(kind);
-                locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
-                currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
+                ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
+                locations[i] = StackSlot.get(valueKind, currentStackOffset, !type.out);
+                currentStackOffset += Math.max(valueKind.getPlatformKind().getSizeInBytes(), target.wordSize);
             }
         }
 
         JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
-        AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(target.getLIRKind(returnKind.getStackKind()));
+        AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
         return new CallingConvention(currentStackOffset, returnLocation, locations);
     }
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotJVMCIBackendFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
  */
 package jdk.vm.ci.hotspot.sparc;
 
-import static jdk.vm.ci.inittimer.InitTimer.timer;
+import static jdk.vm.ci.common.InitTimer.timer;
 
 import java.util.EnumSet;
 
@@ -30,6 +30,7 @@
 import jdk.vm.ci.code.RegisterConfig;
 import jdk.vm.ci.code.TargetDescription;
 import jdk.vm.ci.code.stack.StackIntrospection;
+import jdk.vm.ci.common.InitTimer;
 import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
 import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
 import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
@@ -37,7 +38,6 @@
 import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
 import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
-import jdk.vm.ci.inittimer.InitTimer;
 import jdk.vm.ci.runtime.JVMCIBackend;
 import jdk.vm.ci.sparc.SPARC;
 import jdk.vm.ci.sparc.SPARC.CPUFeature;
@@ -146,7 +146,7 @@
         TargetDescription target = createTarget(runtime.getConfig());
 
         HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime);
-        RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target.arch, runtime.getConfig());
+        RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target, runtime.getConfig());
         HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target, regConfig);
         HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime);
         StackIntrospection stackIntrospection = new HotSpotStackIntrospection(runtime);
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot.sparc/src/jdk/vm/ci/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,19 +78,20 @@
 import jdk.vm.ci.code.RegisterConfig;
 import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.code.ValueKindFactory;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspot.HotSpotCallingConventionType;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
 import jdk.vm.ci.meta.AllocatableValue;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
-import jdk.vm.ci.meta.LIRKind;
 import jdk.vm.ci.meta.PlatformKind;
+import jdk.vm.ci.meta.ValueKind;
 import jdk.vm.ci.sparc.SPARC;
 
 public class SPARCHotSpotRegisterConfig implements RegisterConfig {
 
-    private final Architecture architecture;
+    private final TargetDescription target;
 
     private final Register[] allocatable;
 
@@ -110,7 +111,7 @@
     public Register[] filterAllocatableRegisters(PlatformKind kind, Register[] registers) {
         ArrayList<Register> list = new ArrayList<>();
         for (Register reg : registers) {
-            if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
+            if (target.arch.canStoreValue(reg.getRegisterCategory(), kind)) {
                 list.add(reg);
             }
         }
@@ -166,16 +167,16 @@
         return registers;
     }
 
-    public SPARCHotSpotRegisterConfig(Architecture arch, HotSpotVMConfig config) {
-        this(arch, initAllocatable(arch, config.useCompressedOops), config);
+    public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
+        this(target, initAllocatable(target.arch, config.useCompressedOops), config);
     }
 
-    public SPARCHotSpotRegisterConfig(Architecture arch, Register[] allocatable, HotSpotVMConfig config) {
-        this.architecture = arch;
+    public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable, HotSpotVMConfig config) {
+        this.target = target;
         this.allocatable = allocatable.clone();
         this.addNativeRegisterArgumentSlots = config.linuxOs;
         HashSet<Register> callerSaveSet = new HashSet<>();
-        Collections.addAll(callerSaveSet, arch.getAvailableValueRegisters());
+        Collections.addAll(callerSaveSet, target.arch.getAvailableValueRegisters());
         for (Register cs : calleeSaveRegisters) {
             callerSaveSet.remove(cs);
         }
@@ -198,18 +199,13 @@
     }
 
     @Override
-    public Register getRegisterForRole(int index) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target) {
+    public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, ValueKindFactory<?> valueKindFactory) {
         HotSpotCallingConventionType hotspotType = (HotSpotCallingConventionType) type;
         if (type == HotSpotCallingConventionType.JavaCall || type == HotSpotCallingConventionType.NativeCall) {
-            return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, hotspotType, target);
+            return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
         }
         if (type == HotSpotCallingConventionType.JavaCallee) {
-            return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, target);
+            return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, hotspotType, valueKindFactory);
         }
         throw JVMCIError.shouldNotReachHere();
     }
@@ -234,7 +230,8 @@
         }
     }
 
-    private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type, TargetDescription target) {
+    private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, HotSpotCallingConventionType type,
+                    ValueKindFactory<?> valueKindFactory) {
         AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
 
         int currentGeneral = 0;
@@ -254,7 +251,7 @@
                 case Object:
                     if (currentGeneral < generalParameterRegisters.length) {
                         Register register = generalParameterRegisters[currentGeneral++];
-                        locations[i] = register.asValue(target.getLIRKind(kind));
+                        locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
                     }
                     break;
                 case Double:
@@ -265,13 +262,13 @@
                         }
                         Register register = fpuDoubleParameterRegisters[currentFloating];
                         currentFloating += 2; // Only every second is a double register
-                        locations[i] = register.asValue(target.getLIRKind(kind));
+                        locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
                     }
                     break;
                 case Float:
                     if (currentFloating < fpuFloatParameterRegisters.length) {
                         Register register = fpuFloatParameterRegisters[currentFloating++];
-                        locations[i] = register.asValue(target.getLIRKind(kind));
+                        locations[i] = register.asValue(valueKindFactory.getValueKind(kind));
                     }
                     break;
                 default:
@@ -279,18 +276,18 @@
             }
 
             if (locations[i] == null) {
-                LIRKind lirKind = target.getLIRKind(kind);
+                ValueKind<?> valueKind = valueKindFactory.getValueKind(kind);
                 // Stack slot is always aligned to its size in bytes but minimum wordsize
-                int typeSize = lirKind.getPlatformKind().getSizeInBytes();
+                int typeSize = valueKind.getPlatformKind().getSizeInBytes();
                 currentStackOffset = roundUp(currentStackOffset, typeSize);
                 int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
-                locations[i] = StackSlot.get(lirKind, slotOffset, !type.out);
+                locations[i] = StackSlot.get(valueKind, slotOffset, !type.out);
                 currentStackOffset += typeSize;
             }
         }
 
         JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
-        AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
+        AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(valueKindFactory.getValueKind(returnKind.getStackKind()));
 
         int outArgSpillArea;
         if (type == HotSpotCallingConventionType.NativeCall && addNativeRegisterArgumentSlots) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Fri May 20 18:05:09 2016 +0300
@@ -23,8 +23,8 @@
 
 package jdk.vm.ci.hotspot;
 
+import static jdk.vm.ci.common.InitTimer.timer;
 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
-import static jdk.vm.ci.inittimer.InitTimer.timer;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
@@ -33,9 +33,9 @@
 import jdk.vm.ci.code.InstalledCode;
 import jdk.vm.ci.code.InvalidInstalledCodeException;
 import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.common.InitTimer;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspotvmconfig.HotSpotVMField;
-import jdk.vm.ci.inittimer.InitTimer;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
@@ -79,7 +79,7 @@
     native byte[] getBytecode(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Gets the number of entries in {@code method}'s exception handler table or 0 if it has not
+     * Gets the number of entries in {@code method}'s exception handler table or 0 if it has no
      * exception handler table.
      */
     native int getExceptionTableLength(HotSpotResolvedJavaMethodImpl method);
@@ -246,8 +246,8 @@
     native void resolveInvokeDynamicInPool(HotSpotConstantPool constantPool, int cpi);
 
     /**
-     * Ensures that the type referenced by the entry for a <a
-     * href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
+     * Ensures that the type referenced by the entry for a
+     * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
      * polymorphic</a> method at index {@code cpi} in {@code constantPool} is loaded and
      * initialized.
      *
@@ -315,6 +315,21 @@
      */
     native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, HotSpotSpeculationLog speculationLog);
 
+    /**
+     * Generates the VM metadata for some compiled code and copies them into {@code metaData}. This
+     * method does not install anything into the code cache.
+     *
+     * @param target the target where this code would be installed
+     * @param compiledCode the result of a compilation
+     * @param metaData the metadata is written to this object
+     * @return the outcome of the installation which will be one of
+     *         {@link HotSpotVMConfig#codeInstallResultOk},
+     *         {@link HotSpotVMConfig#codeInstallResultCacheFull},
+     *         {@link HotSpotVMConfig#codeInstallResultCodeTooLarge},
+     *         {@link HotSpotVMConfig#codeInstallResultDependenciesFailed} or
+     *         {@link HotSpotVMConfig#codeInstallResultDependenciesInvalid}.
+     * @throws JVMCIError if there is something wrong with the compiled code or the metadata
+     */
     public native int getMetadata(TargetDescription target, HotSpotCompiledCode compiledCode, HotSpotMetaData metaData);
 
     /**
@@ -423,20 +438,6 @@
     native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method);
 
     /**
-     * Reads an object pointer within a VM data structure. That is, any {@link HotSpotVMField} whose
-     * {@link HotSpotVMField#type() type} is {@code "oop"} (e.g.,
-     * {@code ArrayKlass::_component_mirror}, {@code Klass::_java_mirror},
-     * {@code JavaThread::_threadObj}).
-     *
-     * Note that {@link Unsafe#getObject(Object, long)} cannot be used for this since it does a
-     * {@code narrowOop} read if the VM is using compressed oops whereas oops within VM data
-     * structures are (currently) always uncompressed.
-     *
-     * @param address address of an oop field within a VM data structure
-     */
-    native Object readUncompressedOop(long address);
-
-    /**
      * Determines if {@code method} should not be inlined or compiled.
      */
     native void doNotInlineOrCompile(HotSpotResolvedJavaMethodImpl method);
@@ -480,11 +481,6 @@
     native String getSymbol(long metaspaceSymbol);
 
     /**
-     * Lookup a VMSymbol from a String.
-     */
-    native long lookupSymbol(String symbol);
-
-    /**
      * Looks for the next Java stack frame matching an entry in {@code methods}.
      *
      * @param frame the starting point of the search, where {@code null} refers to the topmost frame
@@ -494,10 +490,10 @@
     native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, ResolvedJavaMethod[] methods, int initialSkip);
 
     /**
-     * Materializes all virtual objects within {@code stackFrame} updates its locals.
+     * Materializes all virtual objects within {@code stackFrame} and updates its locals.
      *
      * @param invalidate if {@code true}, the compiled method for the stack frame will be
-     *            invalidated.
+     *            invalidated
      */
     native void materializeVirtualObjects(HotSpotStackFrameReference stackFrame, boolean invalidate);
 
@@ -514,7 +510,6 @@
     /**
      * Determines if debug info should also be emitted at non-safepoint locations.
      */
-
     native boolean shouldDebugNonSafepoints();
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompilationRequestResult.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.CompilationRequest;
+import jdk.vm.ci.code.CompilationRequestResult;
+
+/**
+ * HotSpot specific information about the result of a {@link CompilationRequest}.
+ */
+public final class HotSpotCompilationRequestResult implements CompilationRequestResult {
+
+    /**
+     * A user readable description of the failure.
+     *
+     * This field is read by the VM.
+     */
+    private final String failureMessage;
+
+    /**
+     * Whether this is a transient failure where retrying would help.
+     *
+     * This field is read by the VM.
+     */
+    private final boolean retry;
+
+    /**
+     * Number of bytecodes inlined into the compilation, exclusive of the bytecodes in the root
+     * method.
+     *
+     * This field is read by the VM.
+     */
+    private final int inlinedBytecodes;
+
+    private HotSpotCompilationRequestResult(String failureMessage, boolean retry, int inlinedBytecodes) {
+        this.failureMessage = failureMessage;
+        this.retry = retry;
+        this.inlinedBytecodes = inlinedBytecodes;
+    }
+
+    public Object getFailure() {
+        return failureMessage;
+    }
+
+    /**
+     * Creates a result representing a successful compilation.
+     *
+     * @param inlinedBytecodes number of bytecodes inlined into the compilation, exclusive of the
+     *            bytecodes in the root method
+     */
+    public static HotSpotCompilationRequestResult success(int inlinedBytecodes) {
+        return new HotSpotCompilationRequestResult(null, true, inlinedBytecodes);
+    }
+
+    /**
+     * Creates a result representing a failed compilation.
+     *
+     * @param failureMessage a description of the failure
+     * @param retry whether this is a transient failure where retrying may succeed
+     */
+    public static HotSpotCompilationRequestResult failure(String failureMessage, boolean retry) {
+        return new HotSpotCompilationRequestResult(failureMessage, retry, 0);
+    }
+
+    public String getFailureMessage() {
+        return failureMessage;
+    }
+
+    public boolean getRetry() {
+        return retry;
+    }
+
+    public int getInlinedBytecodes() {
+        return inlinedBytecodes;
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCompiledNmethod.java	Fri May 20 18:05:09 2016 +0300
@@ -25,7 +25,6 @@
 import jdk.vm.ci.code.StackSlot;
 import jdk.vm.ci.code.site.DataPatch;
 import jdk.vm.ci.code.site.Site;
-import jdk.vm.ci.inittimer.SuppressFBWarnings;
 import jdk.vm.ci.meta.Assumptions.Assumption;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantPool.java	Fri May 20 18:05:09 2016 +0300
@@ -42,7 +42,7 @@
 /**
  * Implementation of {@link ConstantPool} for HotSpot.
  */
-final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
+final class HotSpotConstantPool implements ConstantPool, MetaspaceWrapperObject {
 
     /**
      * Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -22,19 +22,15 @@
  */
 package jdk.vm.ci.hotspot;
 
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
-
 import java.lang.reflect.Array;
 import java.util.Objects;
 
+import jdk.internal.vm.annotation.Stable;
 import jdk.vm.ci.common.JVMCIError;
-import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.ConstantReflectionProvider;
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.MemoryAccessProvider;
 import jdk.vm.ci.meta.MethodHandleAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaField;
@@ -43,7 +39,7 @@
 /**
  * HotSpot implementation of {@link ConstantReflectionProvider}.
  */
-public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider, HotSpotProxified {
+public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider {
 
     protected final HotSpotJVMCIRuntimeProvider runtime;
     protected final HotSpotMethodHandleAccessProvider methodHandleAccess;
@@ -88,50 +84,6 @@
         return Array.getLength(arrayObject);
     }
 
-    public JavaConstant readConstantArrayElement(JavaConstant array, int index) {
-        if (array instanceof HotSpotObjectConstantImpl && ((HotSpotObjectConstantImpl) array).getStableDimension() > 0) {
-            JavaConstant element = readArrayElement(array, index);
-            if (element != null && (((HotSpotObjectConstantImpl) array).isDefaultStable() || !element.isDefaultForKind())) {
-                return element;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Try to convert {@code offset} into an an index into {@code array}.
-     *
-     * @return the computed index or -1 if the offset isn't within the array
-     */
-    private int indexForOffset(JavaConstant array, long offset) {
-        if (array.getJavaKind() != JavaKind.Object || array.isNull()) {
-            return -1;
-        }
-        Class<?> componentType = ((HotSpotObjectConstantImpl) array).object().getClass().getComponentType();
-        JavaKind kind = runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(componentType).getJavaKind();
-        int arraybase = getArrayBaseOffset(kind);
-        int scale = getArrayIndexScale(kind);
-        if (offset < arraybase) {
-            return -1;
-        }
-        long index = offset - arraybase;
-        if (index % scale != 0) {
-            return -1;
-        }
-        long result = index / scale;
-        if (result >= Integer.MAX_VALUE) {
-            return -1;
-        }
-        return (int) result;
-    }
-
-    public JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset) {
-        if (array instanceof HotSpotObjectConstantImpl && ((HotSpotObjectConstantImpl) array).getStableDimension() > 0) {
-            return readConstantArrayElement(array, indexForOffset(array, offset));
-        }
-        return null;
-    }
-
     @Override
     public JavaConstant readArrayElement(JavaConstant array, int index) {
         if (array == null || array.getJavaKind() != JavaKind.Object || array.isNull()) {
@@ -145,11 +97,7 @@
 
         if (a instanceof Object[]) {
             Object element = ((Object[]) a)[index];
-            if (((HotSpotObjectConstantImpl) array).getStableDimension() > 1) {
-                return HotSpotObjectConstantImpl.forStableArray(element, ((HotSpotObjectConstantImpl) array).getStableDimension() - 1, ((HotSpotObjectConstantImpl) array).isDefaultStable());
-            } else {
-                return HotSpotObjectConstantImpl.forObject(element);
-            }
+            return HotSpotObjectConstantImpl.forObject(element);
         } else {
             return JavaConstant.forBoxedPrimitive(Array.get(a, index));
         }
@@ -227,103 +175,8 @@
         return null;
     }
 
-    private static final String SystemClassName = "Ljava/lang/System;";
-
-    /**
-     * Determines if a static field is constant for the purpose of
-     * {@link #readConstantFieldValue(ResolvedJavaField, JavaConstant)}.
-     */
-    protected boolean isStaticFieldConstant(HotSpotResolvedJavaField staticField) {
-        if (staticField.isFinal() || (staticField.isStable() && runtime.getConfig().foldStableValues)) {
-            ResolvedJavaType holder = staticField.getDeclaringClass();
-            if (holder.isInitialized() && !holder.getName().equals(SystemClassName)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Determines if a value read from a {@code final} instance field is considered constant. The
-     * implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
-     * not the {@link JavaConstant#isDefaultForKind default value} for its kind or if
-     * {@link Option#TrustFinalDefaultFields} is true.
-     *
-     * @param value a value read from a {@code final} instance field
-     * @param receiverClass the {@link Object#getClass() class} of object from which the
-     *            {@code value} was read
-     */
-    protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
-        return !value.isDefaultForKind() || Option.TrustFinalDefaultFields.getBoolean();
-    }
-
-    /**
-     * Determines if a value read from a {@link Stable} instance field is considered constant. The
-     * implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
-     * not the {@link JavaConstant#isDefaultForKind default value} for its kind.
-     *
-     * @param value a value read from a {@link Stable} field
-     * @param receiverClass the {@link Object#getClass() class} of object from which the
-     *            {@code value} was read
-     */
-    protected boolean isStableInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
-        return !value.isDefaultForKind();
-    }
-
-    public JavaConstant readConstantFieldValue(ResolvedJavaField field, JavaConstant receiver) {
-        HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
-
-        if (hotspotField.isStatic()) {
-            if (isStaticFieldConstant(hotspotField)) {
-                JavaConstant value = readFieldValue(field, receiver);
-                if (hotspotField.isFinal() || !value.isDefaultForKind()) {
-                    return value;
-                }
-            }
-        } else {
-            /*
-             * for non-static final fields, we must assume that they are only initialized if they
-             * have a non-default value.
-             */
-            Object object = receiver.isNull() ? null : ((HotSpotObjectConstantImpl) receiver).object();
-
-            // Canonicalization may attempt to process an unsafe read before
-            // processing a guard (e.g. a null check or a type check) for this read
-            // so we need to check the object being read
-            if (object != null) {
-                if (hotspotField.isFinal()) {
-                    if (hotspotField.isInObject(object)) {
-                        JavaConstant value = readFieldValue(field, receiver);
-                        if (isFinalInstanceFieldValueConstant(value, object.getClass())) {
-                            return value;
-                        }
-                    }
-                } else if (hotspotField.isStable() && runtime.getConfig().foldStableValues) {
-                    if (hotspotField.isInObject(object)) {
-                        JavaConstant value = readFieldValue(field, receiver);
-                        if (isStableInstanceFieldValueConstant(value, object.getClass())) {
-                            return value;
-                        }
-                    }
-                }
-            }
-        }
-        return null;
-    }
-
     public JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver) {
         HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
-        if (!hotspotField.isStable()) {
-            return readNonStableFieldValue(field, receiver);
-        } else if (runtime.getConfig().foldStableValues) {
-            return readStableFieldValue(field, receiver, hotspotField.isDefaultStable());
-        } else {
-            return null;
-        }
-    }
-
-    private JavaConstant readNonStableFieldValue(ResolvedJavaField field, JavaConstant receiver) {
-        HotSpotResolvedJavaField hotspotField = (HotSpotResolvedJavaField) field;
         if (hotspotField.isStatic()) {
             HotSpotResolvedJavaType holder = (HotSpotResolvedJavaType) hotspotField.getDeclaringClass();
             if (holder.isInitialized()) {
@@ -337,27 +190,6 @@
         return null;
     }
 
-    public JavaConstant readStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefaultStable) {
-        JavaConstant fieldValue = readNonStableFieldValue(field, receiver);
-        if (fieldValue != null && fieldValue.isNonNull()) {
-            JavaType declaredType = field.getType();
-            if (declaredType.getComponentType() != null) {
-                int stableDimension = getArrayDimension(declaredType);
-                return HotSpotObjectConstantImpl.forStableArray(((HotSpotObjectConstantImpl) fieldValue).object(), stableDimension, isDefaultStable);
-            }
-        }
-        return fieldValue;
-    }
-
-    private static int getArrayDimension(JavaType type) {
-        int dimensions = 0;
-        JavaType componentType = type;
-        while ((componentType = componentType.getComponentType()) != null) {
-            dimensions++;
-        }
-        return dimensions;
-    }
-
     @Override
     public JavaConstant asJavaClass(ResolvedJavaType type) {
         return HotSpotObjectConstantImpl.forObject(((HotSpotResolvedJavaType) type).mirror());
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotInstalledCode.java	Fri May 20 18:05:09 2016 +0300
@@ -23,9 +23,9 @@
 package jdk.vm.ci.hotspot;
 
 import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
+
+import jdk.internal.misc.Unsafe;
 import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.inittimer.SuppressFBWarnings;
-import jdk.internal.misc.Unsafe;
 
 /**
  * Implementation of {@link InstalledCode} for HotSpot.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java	Fri May 20 18:05:09 2016 +0300
@@ -22,27 +22,30 @@
  */
 package jdk.vm.ci.hotspot;
 
+import java.lang.reflect.Module;
+
 import jdk.vm.ci.code.CompilationRequest;
-import jdk.vm.ci.code.CompilationRequestResult;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
 import jdk.vm.ci.runtime.JVMCICompiler;
-import jdk.vm.ci.runtime.JVMCICompilerFactory;
 import jdk.vm.ci.runtime.JVMCIRuntime;
+import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
 import jdk.vm.ci.services.Services;
 
 final class HotSpotJVMCICompilerConfig {
 
-    private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler {
+    private static class DummyCompilerFactory extends JVMCICompilerFactory implements JVMCICompiler {
 
-        public CompilationRequestResult compileMethod(CompilationRequest request) {
+        public HotSpotCompilationRequestResult compileMethod(CompilationRequest request) {
             throw new JVMCIError("no JVMCI compiler selected");
         }
 
+        @Override
         public String getCompilerName() {
             return "<none>";
         }
 
+        @Override
         public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
             return this;
         }
@@ -65,6 +68,9 @@
             if (compilerName != null) {
                 for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
                     if (f.getCompilerName().equals(compilerName)) {
+                        Module jvmciModule = JVMCICompilerFactory.class.getModule();
+                        Services.exportJVMCITo(f.getClass());
+                        f.onSelection();
                         factory = f;
                     }
                 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext.java	Fri May 20 18:05:09 2016 +0300
@@ -30,7 +30,6 @@
 import java.util.Map;
 import java.util.WeakHashMap;
 
-import jdk.vm.ci.meta.JVMCIMetaAccessContext;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
@@ -47,7 +46,7 @@
  * longer used.
  *
  */
-public class HotSpotJVMCIMetaAccessContext implements JVMCIMetaAccessContext {
+public class HotSpotJVMCIMetaAccessContext {
 
     /**
      * The set of currently live contexts used for tracking of live metadata. Examined from the VM
@@ -149,7 +148,11 @@
 
     private final Map<Class<?>, WeakReference<ResolvedJavaType>> typeMap = new WeakHashMap<>();
 
-    @Override
+    /**
+     * Gets the JVMCI mirror for a {@link Class} object.
+     *
+     * @return the {@link ResolvedJavaType} corresponding to {@code javaClass}
+     */
     public synchronized ResolvedJavaType fromClass(Class<?> javaClass) {
         WeakReference<ResolvedJavaType> typeRef = typeMap.get(javaClass);
         ResolvedJavaType type = typeRef != null ? typeRef.get() : null;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Fri May 20 18:05:09 2016 +0300
@@ -22,7 +22,7 @@
  */
 package jdk.vm.ci.hotspot;
 
-import static jdk.vm.ci.inittimer.InitTimer.timer;
+import static jdk.vm.ci.common.InitTimer.timer;
 
 import java.io.IOException;
 import java.io.OutputStream;
@@ -37,24 +37,23 @@
 import java.util.Objects;
 import java.util.TreeMap;
 
+import jdk.internal.misc.VM;
 import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.code.CompilationRequestResult;
 import jdk.vm.ci.code.CompiledCode;
 import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.common.InitTimer;
 import jdk.vm.ci.common.JVMCIError;
-import jdk.vm.ci.inittimer.InitTimer;
-import jdk.vm.ci.inittimer.SuppressFBWarnings;
-import jdk.vm.ci.meta.JVMCIMetaAccessContext;
+import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory;
+import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.runtime.JVMCI;
 import jdk.vm.ci.runtime.JVMCIBackend;
 import jdk.vm.ci.runtime.JVMCICompiler;
+import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
 import jdk.vm.ci.services.Services;
-import jdk.internal.misc.VM;
-
-//JaCoCo Exclude
 
 /**
  * HotSpot implementation of a JVMCI runtime.
@@ -66,7 +65,7 @@
  * {@link #runtime()}. This allows the initialization to funnel back through
  * {@link JVMCI#initialize()} without deadlocking.
  */
-public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified {
+public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider {
 
     @SuppressWarnings("try")
     static class DelayedInit {
@@ -92,14 +91,12 @@
      */
     public enum Option {
         Compiler(String.class, null, "Selects the system compiler."),
-        ImplicitStableValues(boolean.class, true, "Mark well-known stable fields as such."),
         // Note: The following one is not used (see InitTimer.ENABLED).
         InitTimer(boolean.class, false, "Specifies if initialization timing is enabled."),
         PrintConfig(boolean.class, false, "Prints all HotSpotVMConfig fields."),
         PrintFlags(boolean.class, false, "Prints all JVMCI flags and exits."),
         ShowFlags(boolean.class, false, "Prints all JVMCI flags and continues."),
-        TraceMethodDataFilter(String.class, null, ""),
-        TrustFinalDefaultFields(boolean.class, true, "Determines whether to treat final fields with default values as constant.");
+        TraceMethodDataFilter(String.class, null, "");
 
         /**
          * The prefix for system properties that are JVMCI options.
@@ -203,13 +200,25 @@
     protected final HotSpotVMConfig config;
     private final JVMCIBackend hostBackend;
 
+    private final JVMCICompilerFactory compilerFactory;
+    private final HotSpotJVMCICompilerFactory hsCompilerFactory;
     private volatile JVMCICompiler compiler;
-    protected final JVMCIMetaAccessContext metaAccessContext;
+    protected final HotSpotJVMCIMetaAccessContext metaAccessContext;
+
+    /**
+     * Stores the result of {@link HotSpotJVMCICompilerFactory#getCompilationLevelAdjustment} so
+     * that it can be read from the VM.
+     */
+    @SuppressWarnings("unused") private final int compilationLevelAdjustment;
 
     private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
 
     private final Iterable<HotSpotVMEventListener> vmEventListeners;
 
+    /**
+     * Stores the result of {@link HotSpotJVMCICompilerFactory#getTrivialPrefixes()} so that it can
+     * be read from the VM.
+     */
     @SuppressWarnings("unused") private final String[] trivialPrefixes;
 
     @SuppressWarnings("try")
@@ -233,17 +242,7 @@
 
         vmEventListeners = Services.load(HotSpotVMEventListener.class);
 
-        JVMCIMetaAccessContext context = null;
-        for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
-            context = vmEventListener.createMetaAccessContext(this);
-            if (context != null) {
-                break;
-            }
-        }
-        if (context == null) {
-            context = new HotSpotJVMCIMetaAccessContext();
-        }
-        metaAccessContext = context;
+        metaAccessContext = new HotSpotJVMCIMetaAccessContext();
 
         boolean printFlags = Option.PrintFlags.getBoolean();
         boolean showFlags = Option.ShowFlags.getBoolean();
@@ -258,7 +257,16 @@
             printConfig(config, compilerToVm);
         }
 
-        trivialPrefixes = HotSpotJVMCICompilerConfig.getCompilerFactory().getTrivialPrefixes();
+        compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
+        if (compilerFactory instanceof HotSpotJVMCICompilerFactory) {
+            hsCompilerFactory = (HotSpotJVMCICompilerFactory) compilerFactory;
+            trivialPrefixes = hsCompilerFactory.getTrivialPrefixes();
+            compilationLevelAdjustment = hsCompilerFactory.getCompilationLevelAdjustment(config);
+        } else {
+            hsCompilerFactory = null;
+            trivialPrefixes = null;
+            compilationLevelAdjustment = 0;
+        }
     }
 
     private JVMCIBackend registerBackend(JVMCIBackend backend) {
@@ -280,15 +288,11 @@
         return compilerToVm;
     }
 
-    public JVMCIMetaAccessContext getMetaAccessContext() {
-        return metaAccessContext;
-    }
-
     public JVMCICompiler getCompiler() {
         if (compiler == null) {
             synchronized (this) {
                 if (compiler == null) {
-                    compiler = HotSpotJVMCICompilerConfig.getCompilerFactory().createCompiler(this);
+                    compiler = compilerFactory.createCompiler(this);
                 }
             }
         }
@@ -331,10 +335,32 @@
      * Called from the VM.
      */
     @SuppressWarnings({"unused"})
-    private CompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
+    private int adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, int level) {
+        return hsCompilerFactory.adjustCompilationLevel(config, declaringClass, name, signature, isOsr, level);
+    }
+
+    /**
+     * Called from the VM.
+     */
+    @SuppressWarnings({"unused"})
+    private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
         CompilationRequestResult result = getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
         assert result != null : "compileMethod must always return something";
-        return result;
+        HotSpotCompilationRequestResult hsResult;
+        if (result instanceof HotSpotCompilationRequestResult) {
+            hsResult = (HotSpotCompilationRequestResult) result;
+        } else {
+            Object failure = result.getFailure();
+            if (failure != null) {
+                boolean retry = false; // Be conservative with unknown compiler
+                hsResult = HotSpotCompilationRequestResult.failure(failure.toString(), retry);
+            } else {
+                int inlinedBytecodes = -1;
+                hsResult = HotSpotCompilationRequestResult.success(inlinedBytecodes);
+            }
+        }
+
+        return hsResult;
     }
 
     /**
@@ -350,6 +376,18 @@
     }
 
     /**
+     * Notify on completion of a bootstrap.
+     *
+     * Called from the VM.
+     */
+    @SuppressWarnings({"unused"})
+    private void bootstrapFinished() throws Exception {
+        for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
+            vmEventListener.notifyBootstrapFinished();
+        }
+    }
+
+    /**
      * Notify on successful install into the CodeCache.
      *
      * @param hotSpotCodeCacheProvider
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntimeProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntimeProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -24,15 +24,12 @@
 
 import java.io.OutputStream;
 
+import jdk.internal.misc.Unsafe;
 import jdk.vm.ci.common.JVMCIError;
-import jdk.vm.ci.meta.JVMCIMetaAccessContext;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.runtime.JVMCIRuntime;
-import jdk.internal.misc.Unsafe;
-
-//JaCoCo Exclude
 
 /**
  * Configuration information for the HotSpot JVMCI runtime.
@@ -70,8 +67,6 @@
      */
     ResolvedJavaType fromClass(Class<?> clazz);
 
-    JVMCIMetaAccessContext getMetaAccessContext();
-
     /**
      * The offset from the origin of an array to the first element.
      *
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -39,6 +39,4 @@
     Constant readNarrowKlassPointerConstant(Constant base, long displacement, CompressEncoding encoding);
 
     Constant readMethodPointerConstant(Constant base, long displacement);
-
-    Constant readSymbolConstant(Constant base, long displacement);
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMemoryAccessProviderImpl.java	Fri May 20 18:05:09 2016 +0300
@@ -33,7 +33,7 @@
 /**
  * HotSpot implementation of {@link MemoryAccessProvider}.
  */
-class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
+class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider {
 
     protected final HotSpotJVMCIRuntimeProvider runtime;
 
@@ -135,7 +135,7 @@
         if (base == null) {
             assert !compressed;
             displacement += asRawPointer(baseConstant);
-            ret = runtime.getCompilerToVM().readUncompressedOop(displacement);
+            ret = UNSAFE.getUncompressedObject(displacement);
         } else {
             assert runtime.getConfig().useCompressedOops == compressed;
             ret = UNSAFE.getObject(base, displacement);
@@ -232,16 +232,4 @@
         HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
         return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false);
     }
-
-    @Override
-    public Constant readSymbolConstant(Constant base, long displacement) {
-        int bits = runtime.getConfig().symbolPointerSize * Byte.SIZE;
-        long pointer = readRawValue(base, displacement, bits);
-        if (pointer == 0) {
-            return JavaConstant.NULL_POINTER;
-        } else {
-            String symbol = runtime.getCompilerToVM().getSymbol(pointer);
-            return new HotSpotSymbol(symbol, pointer).asConstant();
-        }
-    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaAccessProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -52,7 +52,7 @@
 /**
  * HotSpot implementation of {@link MetaAccessProvider}.
  */
-public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotProxified {
+public class HotSpotMetaAccessProvider implements MetaAccessProvider {
 
     protected final HotSpotJVMCIRuntimeProvider runtime;
 
@@ -78,15 +78,6 @@
         return new HotSpotSignature(runtime, signature);
     }
 
-    public HotSpotSymbol lookupSymbol(String symbol) {
-        long pointer = runtime.getCompilerToVM().lookupSymbol(symbol);
-        if (pointer == 0) {
-            return null;
-        } else {
-            return new HotSpotSymbol(symbol, pointer);
-        }
-    }
-
     /**
      * {@link Field} object of {@link Method#slot}.
      */
@@ -152,7 +143,8 @@
         int actionValue = convertDeoptAction(action);
         int reasonValue = convertDeoptReason(reason);
         int debugValue = debugId & intMaskRight(config.deoptimizationDebugIdBits);
-        JavaConstant c = JavaConstant.forInt(~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift)));
+        JavaConstant c = JavaConstant.forInt(
+                        ~((debugValue << config.deoptimizationDebugIdShift) | (reasonValue << config.deoptimizationReasonShift) | (actionValue << config.deoptimizationActionShift)));
         assert c.asInt() < 0;
         return c;
     }
@@ -316,7 +308,6 @@
                 return 0;
             } else {
                 if (lookupJavaType.isArray()) {
-                    // TODO(tw): Add compressed pointer support.
                     int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object());
                     ResolvedJavaType elementType = lookupJavaType.getComponentType();
                     JavaKind elementKind = elementType.getJavaKind();
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaData.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaData.java	Fri May 20 18:05:09 2016 +0300
@@ -22,8 +22,9 @@
  */
 package jdk.vm.ci.hotspot;
 
-import jdk.vm.ci.inittimer.SuppressFBWarnings;
-
+/**
+ * Encapsulates the VM metadata generated by {@link CompilerToVM#getMetadata}.
+ */
 public class HotSpotMetaData {
     @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] pcDescBytes;
     @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] scopesDescBytes;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstant.java	Fri May 20 18:05:09 2016 +0300
@@ -29,6 +29,4 @@
     HotSpotResolvedObjectType asResolvedJavaType();
 
     HotSpotResolvedJavaMethod asResolvedJavaMethod();
-
-    HotSpotSymbol asSymbol();
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl.java	Fri May 20 18:05:09 2016 +0300
@@ -27,7 +27,7 @@
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.VMConstant;
 
-final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VMConstant, HotSpotProxified {
+final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VMConstant {
 
     static HotSpotMetaspaceConstantImpl forMetaspaceObject(MetaspaceWrapperObject metaspaceObject, boolean compressed) {
         return new HotSpotMetaspaceConstantImpl(metaspaceObject, compressed);
@@ -108,11 +108,4 @@
         }
         return null;
     }
-
-    public HotSpotSymbol asSymbol() {
-        if (metaspaceObject instanceof HotSpotSymbol) {
-            return (HotSpotSymbol) metaspaceObject;
-        }
-        return null;
-    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethod.java	Fri May 20 18:05:09 2016 +0300
@@ -32,7 +32,7 @@
 import jdk.vm.ci.meta.JavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
-abstract class HotSpotMethod implements JavaMethod, Formattable /* , JavaMethodContex */{
+abstract class HotSpotMethod implements JavaMethod, Formattable {
 
     public static String applyFormattingFlagsAndWidth(String s, int flags, int width) {
         if (flags == 0 && width < 0) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -33,7 +33,7 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
-public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider, HotSpotProxified {
+public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider {
 
     private final ConstantReflectionProvider constantReflection;
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotObjectConstantImpl.java	Fri May 20 18:05:09 2016 +0300
@@ -28,7 +28,6 @@
 import java.lang.invoke.ConstantCallSite;
 import java.lang.invoke.MethodHandle;
 
-import jdk.vm.ci.inittimer.SuppressFBWarnings;
 import jdk.vm.ci.meta.Assumptions;
 import jdk.vm.ci.meta.Constant;
 import jdk.vm.ci.meta.JavaConstant;
@@ -39,7 +38,7 @@
  * Represents a constant non-{@code null} object reference, within the compiler and across the
  * compiler/runtime interface.
  */
-final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotProxified {
+final class HotSpotObjectConstantImpl implements HotSpotObjectConstant {
 
     static JavaConstant forObject(Object object) {
         return forObject(object, false);
@@ -53,15 +52,6 @@
         }
     }
 
-    static JavaConstant forStableArray(Object object, int stableDimension, boolean isDefaultStable) {
-        if (object == null) {
-            return JavaConstant.NULL_POINTER;
-        } else {
-            assert object.getClass().isArray();
-            return new HotSpotObjectConstantImpl(object, false, stableDimension, isDefaultStable);
-        }
-    }
-
     public static JavaConstant forBoxedValue(JavaKind kind, Object value) {
         if (kind == JavaKind.Object) {
             return HotSpotObjectConstantImpl.forObject(value);
@@ -82,22 +72,11 @@
 
     private final Object object;
     private final boolean compressed;
-    private final byte stableDimension;
-    private final boolean isDefaultStable;
 
-    private HotSpotObjectConstantImpl(Object object, boolean compressed, int stableDimension, boolean isDefaultStable) {
+    private HotSpotObjectConstantImpl(Object object, boolean compressed) {
         this.object = object;
         this.compressed = compressed;
-        this.stableDimension = (byte) stableDimension;
-        this.isDefaultStable = isDefaultStable;
         assert object != null;
-        assert stableDimension == 0 || (object != null && object.getClass().isArray());
-        assert stableDimension >= 0 && stableDimension <= 255;
-        assert !isDefaultStable || stableDimension > 0;
-    }
-
-    private HotSpotObjectConstantImpl(Object object, boolean compressed) {
-        this(object, compressed, 0, false);
     }
 
     @Override
@@ -118,12 +97,12 @@
 
     public JavaConstant compress() {
         assert !compressed;
-        return new HotSpotObjectConstantImpl(object, true, stableDimension, isDefaultStable);
+        return new HotSpotObjectConstantImpl(object, true);
     }
 
     public JavaConstant uncompress() {
         assert compressed;
-        return new HotSpotObjectConstantImpl(object, false, stableDimension, isDefaultStable);
+        return new HotSpotObjectConstantImpl(object, false);
     }
 
     public HotSpotResolvedObjectType getType() {
@@ -248,7 +227,7 @@
             return true;
         } else if (o instanceof HotSpotObjectConstantImpl) {
             HotSpotObjectConstantImpl other = (HotSpotObjectConstantImpl) o;
-            return object == other.object && compressed == other.compressed && stableDimension == other.stableDimension && isDefaultStable == other.isDefaultStable;
+            return object == other.object && compressed == other.compressed;
         }
         return false;
     }
@@ -266,19 +245,4 @@
     public String toString() {
         return (compressed ? "NarrowOop" : getJavaKind().getJavaName()) + "[" + JavaKind.Object.format(object) + "]";
     }
-
-    /**
-     * Number of stable dimensions if this constant is a stable array.
-     */
-    public int getStableDimension() {
-        return stableDimension & 0xff;
-    }
-
-    /**
-     * Returns {@code true} if this is a stable array constant and its elements should be considered
-     * as stable regardless of whether they are default values.
-     */
-    public boolean isDefaultStable() {
-        return isDefaultStable;
-    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotOopMap.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot;
-
-import jdk.vm.ci.inittimer.SuppressFBWarnings;
-
-public class HotSpotOopMap {
-    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int offset;
-    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int count;
-    @SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] data;
-
-    public byte[] data() {
-        return data;
-    }
-
-    public int count() {
-        return count;
-    }
-
-    public int offset() {
-        return offset;
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProfilingInfo.java	Fri May 20 18:05:09 2016 +0300
@@ -28,10 +28,7 @@
 import jdk.vm.ci.meta.ProfilingInfo;
 import jdk.vm.ci.meta.TriState;
 
-public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxified {
-
-    // private static final DebugMetric metricInsufficentSpace =
-    // Debug.metric("InsufficientSpaceForProfilingData");
+public final class HotSpotProfilingInfo implements ProfilingInfo {
 
     private final HotSpotMethodData methodData;
     private final HotSpotResolvedJavaMethod method;
@@ -162,7 +159,6 @@
 
             if (!methodData.isWithin(currentPosition)) {
                 exceptionPossiblyNotRecorded = true;
-                // metricInsufficentSpace.increment();
             }
         }
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotProxified.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot;
-
-/**
- * Marker interface for classes whose values are proxied during replay compilation capture.
- */
-public interface HotSpotProxified {
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotReferenceMap.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotReferenceMap.java	Fri May 20 18:05:09 2016 +0300
@@ -53,7 +53,7 @@
         }
         if (obj instanceof HotSpotReferenceMap) {
             HotSpotReferenceMap that = (HotSpotReferenceMap) obj;
-            if (Arrays.equals(objects, that.objects)) {
+            if (sizeInBytes == that.sizeInBytes && maxRegisterSize == that.maxRegisterSize && Arrays.equals(objects, that.objects) && Arrays.equals(derivedBase, that.derivedBase)) {
                 return true;
             }
         }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaField.java	Fri May 20 18:05:09 2016 +0300
@@ -43,11 +43,4 @@
      * Determines if this field should be treated as a constant.
      */
     boolean isStable();
-
-    /**
-     * Determines if this field should be considered constant if it has the default value for its
-     * type (e.g, 0, null, etc.). The result of this method is undefined if this field is not
-     * {@linkplain #isStable() stable}.
-     */
-    boolean isDefaultStable();
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java	Fri May 20 18:05:09 2016 +0300
@@ -22,16 +22,15 @@
  */
 package jdk.vm.ci.hotspot;
 
-import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
 import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
 
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 
+import jdk.internal.vm.annotation.Stable;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
 import jdk.vm.ci.meta.JavaType;
-import jdk.vm.ci.meta.LocationIdentity;
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ModifiersProvider;
 import jdk.vm.ci.meta.ResolvedJavaField;
@@ -40,7 +39,7 @@
 /**
  * Represents a field in a HotSpot type.
  */
-class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
+class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField {
 
     private final HotSpotResolvedObjectTypeImpl holder;
     private final String name;
@@ -51,43 +50,6 @@
      * This value contains all flags as stored in the VM including internal ones.
      */
     private final int modifiers;
-    private final LocationIdentity locationIdentity = new FieldLocationIdentity(this);
-
-    public static class FieldLocationIdentity extends LocationIdentity {
-        HotSpotResolvedJavaField inner;
-
-        FieldLocationIdentity(HotSpotResolvedJavaFieldImpl inner) {
-            this.inner = inner;
-        }
-
-        @Override
-        public boolean isImmutable() {
-            return false;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof FieldLocationIdentity) {
-                FieldLocationIdentity fieldLocationIdentity = (FieldLocationIdentity) obj;
-                return inner.equals(fieldLocationIdentity.inner);
-
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            return inner.hashCode();
-        }
-
-        @Override
-        public String toString() {
-            return inner.getName();
-        }
-    }
 
     HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) {
         this.holder = holder;
@@ -190,14 +152,7 @@
      * @return true if field has {@link Stable} annotation, false otherwise
      */
     public boolean isStable() {
-        if ((config().jvmAccFieldStable & modifiers) != 0) {
-            return true;
-        }
-        assert getAnnotation(Stable.class) == null;
-        if (Option.ImplicitStableValues.getBoolean() && isImplicitStableField()) {
-            return true;
-        }
-        return false;
+        return (config().jvmAccFieldStable & modifiers) != 0;
     }
 
     @Override
@@ -210,6 +165,15 @@
     }
 
     @Override
+    public Annotation[] getDeclaredAnnotations() {
+        Field javaField = toJava();
+        if (javaField != null) {
+            return javaField.getDeclaredAnnotations();
+        }
+        return new Annotation[0];
+    }
+
+    @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
         Field javaField = toJava();
         if (javaField != null) {
@@ -234,69 +198,4 @@
             return null;
         }
     }
-
-    private boolean isArray() {
-        JavaType fieldType = getType();
-        return fieldType instanceof ResolvedJavaType && ((ResolvedJavaType) fieldType).isArray();
-    }
-
-    private boolean isImplicitStableField() {
-        if (isSyntheticEnumSwitchMap()) {
-            return true;
-        }
-        if (isWellKnownImplicitStableField()) {
-            return true;
-        }
-        return false;
-    }
-
-    public boolean isDefaultStable() {
-        assert this.isStable();
-        if (isSyntheticEnumSwitchMap()) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean isSyntheticEnumSwitchMap() {
-        if (isSynthetic() && isStatic() && isArray()) {
-            if (isFinal() && name.equals("$VALUES") || name.equals("ENUM$VALUES")) {
-                // generated int[] field for EnumClass::values()
-                return true;
-            } else if (name.startsWith("$SwitchMap$") || name.startsWith("$SWITCH_TABLE$")) {
-                // javac and ecj generate a static field in an inner class for a switch on an enum
-                // named $SwitchMap$p$k$g$EnumClass and $SWITCH_TABLE$p$k$g$EnumClass, respectively
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean isWellKnownImplicitStableField() {
-        return WellKnownImplicitStableField.test(this);
-    }
-
-    static class WellKnownImplicitStableField {
-        /**
-         * @return {@code true} if the field is a well-known stable field.
-         */
-        public static boolean test(HotSpotResolvedJavaField field) {
-            return field.equals(STRING_VALUE_FIELD);
-        }
-
-        private static final ResolvedJavaField STRING_VALUE_FIELD;
-
-        static {
-            try {
-                MetaAccessProvider metaAccess = runtime().getHostJVMCIBackend().getMetaAccess();
-                STRING_VALUE_FIELD = metaAccess.lookupJavaField(String.class.getDeclaredField("value"));
-            } catch (SecurityException | NoSuchFieldException e) {
-                throw new JVMCIError(e);
-            }
-        }
-    }
-
-    public LocationIdentity getLocationIdentity() {
-        return locationIdentity;
-    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java	Fri May 20 18:05:09 2016 +0300
@@ -46,11 +46,8 @@
 import jdk.vm.ci.meta.JavaMethod;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.LineNumberTable;
-import jdk.vm.ci.meta.LineNumberTableImpl;
 import jdk.vm.ci.meta.Local;
-import jdk.vm.ci.meta.LocalImpl;
 import jdk.vm.ci.meta.LocalVariableTable;
-import jdk.vm.ci.meta.LocalVariableTableImpl;
 import jdk.vm.ci.meta.ModifiersProvider;
 import jdk.vm.ci.meta.ProfilingInfo;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
@@ -62,7 +59,7 @@
 /**
  * Implementation of {@link JavaMethod} for resolved HotSpot methods.
  */
-final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
+final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, MetaspaceWrapperObject {
 
     /**
      * Reference to metaspace Method object.
@@ -472,7 +469,19 @@
     @Override
     public Annotation[] getAnnotations() {
         Executable javaMethod = toJava();
-        return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations();
+        if (javaMethod != null) {
+            return javaMethod.getAnnotations();
+        }
+        return new Annotation[0];
+    }
+
+    @Override
+    public Annotation[] getDeclaredAnnotations() {
+        Executable javaMethod = toJava();
+        if (javaMethod != null) {
+            return javaMethod.getDeclaredAnnotations();
+        }
+        return new Annotation[0];
     }
 
     @Override
@@ -559,7 +568,7 @@
             line[i] = (int) values[i * 2 + 1];
         }
 
-        return new LineNumberTableImpl(line, bci);
+        return new LineNumberTable(line, bci);
     }
 
     @Override
@@ -584,13 +593,13 @@
             String localName = getConstantPool().lookupUtf8(nameCpIndex);
             String localType = getConstantPool().lookupUtf8(typeCpIndex);
 
-            locals[i] = new LocalImpl(localName, runtime().lookupType(localType, holder, false), startBci, endBci, slot);
+            locals[i] = new Local(localName, runtime().lookupType(localType, holder, false), startBci, endBci, slot);
 
             // Go to the next LocalVariableTableElement
             localVariableTableElement += config.localVariableTableElementSize;
         }
 
-        return new LocalVariableTableImpl(locals);
+        return new LocalVariableTable(locals);
     }
 
     /**
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectType.java	Fri May 20 18:05:09 2016 +0300
@@ -28,7 +28,6 @@
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
-import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
@@ -60,8 +59,6 @@
 
     HotSpotResolvedObjectType findLeastCommonAncestor(ResolvedJavaType otherType);
 
-    HotSpotResolvedObjectType asExactType();
-
     default boolean isPrimitive() {
         return false;
     }
@@ -109,6 +106,4 @@
     HotSpotResolvedObjectType getEnclosingType();
 
     ResolvedJavaMethod getClassInitializer();
-
-    ResolvedJavaField createField(String name, JavaType type, long offset, int modifiers);
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl.java	Fri May 20 18:05:09 2016 +0300
@@ -52,12 +52,11 @@
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.TrustedInterface;
 
 /**
  * Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
  */
-final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
+final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, MetaspaceWrapperObject {
 
     /**
      * The Java class this type represents.
@@ -128,9 +127,9 @@
      */
     long getMetaspaceKlass() {
         if (HotSpotJVMCIRuntime.getHostWordKind() == JavaKind.Long) {
-            return UNSAFE.getLong(javaClass, (long) config().klassOffset);
+            return UNSAFE.getLong(javaClass, config().klassOffset);
         }
-        return UNSAFE.getInt(javaClass, (long) config().klassOffset) & 0xFFFFFFFFL;
+        return UNSAFE.getInt(javaClass, config().klassOffset) & 0xFFFFFFFFL;
     }
 
     public long getMetaspacePointer() {
@@ -167,9 +166,25 @@
 
     @Override
     public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
+        if (isLeaf()) {
+            // No assumptions are required.
+            return new AssumptionResult<>(this);
+        }
         HotSpotVMConfig config = config();
         if (isArray()) {
-            return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;
+            ResolvedJavaType elementalType = getElementalType();
+            AssumptionResult<ResolvedJavaType> elementType = elementalType.findLeafConcreteSubtype();
+            if (elementType != null && elementType.getResult().equals(elementalType)) {
+                /*
+                 * If the elementType is leaf then the array is leaf under the same assumptions but
+                 * only if the element type is exactly the leaf type. The element type can be
+                 * abstract even if there is only one implementor of the abstract type.
+                 */
+                AssumptionResult<ResolvedJavaType> result = new AssumptionResult<>(this);
+                result.add(elementType);
+                return result;
+            }
+            return null;
         } else if (isInterface()) {
             HotSpotResolvedObjectTypeImpl implementor = getSingleImplementor();
             /*
@@ -192,8 +207,7 @@
                 }
                 return null;
             }
-
-            return new AssumptionResult<>(implementor, new LeafType(implementor), new ConcreteSubtype(this, implementor));
+            return concreteSubtype(implementor);
         } else {
             HotSpotResolvedObjectTypeImpl type = this;
             while (type.isAbstract()) {
@@ -207,7 +221,7 @@
                 return null;
             }
             if (this.isAbstract()) {
-                return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type));
+                return concreteSubtype(type);
             } else {
                 assert this.equals(type);
                 return new AssumptionResult<>(type, new LeafType(type));
@@ -215,6 +229,14 @@
         }
     }
 
+    private AssumptionResult<ResolvedJavaType> concreteSubtype(HotSpotResolvedObjectTypeImpl type) {
+        if (type.isLeaf()) {
+            return new AssumptionResult<>(type, new ConcreteSubtype(this, type));
+        } else {
+            return new AssumptionResult<>(type, new LeafType(type), new ConcreteSubtype(this, type));
+        }
+    }
+
     /**
      * Returns if type {@code type} is a leaf class. This is the case if the
      * {@code Klass::_subklass} field of the underlying class is zero.
@@ -297,11 +319,6 @@
     }
 
     @Override
-    public HotSpotResolvedObjectType asExactType() {
-        return isLeaf() ? this : null;
-    }
-
-    @Override
     public AssumptionResult<Boolean> hasFinalizableSubclass() {
         assert !isArray();
         if (!compilerToVM().hasFinalizableSubclass(this)) {
@@ -470,7 +487,7 @@
         return result;
     }
 
-    public synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
+    synchronized HotSpotResolvedJavaField createField(String fieldName, JavaType type, long offset, int rawFlags) {
         HotSpotResolvedJavaField result = null;
 
         final int flags = rawFlags & ModifiersProvider.jvmFieldModifiers();
@@ -490,7 +507,12 @@
             fieldCache.put(id, result);
         } else {
             assert result.getName().equals(fieldName);
-            // assert result.getType().equals(type);
+            /*
+             * Comparing the types directly is too strict, because the type in the cache could be
+             * resolved while the incoming type is unresolved. The name comparison is sufficient
+             * because the type will always be resolved in the context of the holder.
+             */
+            assert result.getType().getName().equals(type.getName());
             assert result.offset() == offset;
             assert result.getModifiers() == flags;
         }
@@ -745,6 +767,11 @@
     }
 
     @Override
+    public Annotation[] getDeclaredAnnotations() {
+        return mirror().getDeclaredAnnotations();
+    }
+
+    @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
         return mirror().getAnnotation(annotationClass);
     }
@@ -879,11 +906,6 @@
     }
 
     @Override
-    public boolean isTrustedInterfaceType() {
-        return TrustedInterface.class.isAssignableFrom(mirror());
-    }
-
-    @Override
     public boolean isCloneableWithAllocation() {
         return (getAccessFlags() & config().jvmAccIsCloneableFast) != 0;
     }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
 /**
  * Implementation of {@link JavaType} for primitive HotSpot types.
  */
-public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType implements HotSpotProxified {
+public final class HotSpotResolvedPrimitiveType extends HotSpotResolvedJavaType {
 
     private final JavaKind kind;
 
@@ -55,7 +55,7 @@
      * @param kind the Kind to create the mirror for
      */
     public HotSpotResolvedPrimitiveType(JavaKind kind) {
-        super(String.valueOf(Character.toUpperCase(kind.getTypeChar())));
+        super(String.valueOf(kind.getTypeChar()));
         this.kind = kind;
         assert mirror().isPrimitive() : mirror() + " not a primitive type";
     }
@@ -84,11 +84,6 @@
     }
 
     @Override
-    public ResolvedJavaType asExactType() {
-        return this;
-    }
-
-    @Override
     public ResolvedJavaType getSuperclass() {
         return null;
     }
@@ -204,6 +199,11 @@
     }
 
     @Override
+    public Annotation[] getDeclaredAnnotations() {
+        return new Annotation[0];
+    }
+
+    @Override
     public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
         return null;
     }
@@ -264,11 +264,6 @@
     }
 
     @Override
-    public boolean isTrustedInterfaceType() {
-        return false;
-    }
-
-    @Override
     public boolean isCloneableWithAllocation() {
         return false;
     }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSentinelConstant.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.ValueKind;
 import jdk.vm.ci.meta.VMConstant;
 import jdk.vm.ci.meta.Value;
 
@@ -32,8 +32,8 @@
 
     private final JavaKind javaKind;
 
-    public HotSpotSentinelConstant(LIRKind lirKind, JavaKind javaKind) {
-        super(lirKind);
+    public HotSpotSentinelConstant(ValueKind<?> valueKind, JavaKind javaKind) {
+        super(valueKind);
         this.javaKind = javaKind;
     }
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSymbol.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot;
-
-import jdk.vm.ci.meta.Constant;
-
-/**
- * Class to access the C++ {@code vmSymbols} table.
- */
-public final class HotSpotSymbol implements MetaspaceWrapperObject {
-
-    private final String symbol;
-    private final long pointer;
-
-    HotSpotSymbol(String symbol, long pointer) {
-        this.symbol = symbol;
-        this.pointer = pointer;
-    }
-
-    public String getSymbol() {
-        return symbol;
-    }
-
-    public Constant asConstant() {
-        return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
-    }
-
-    @Override
-    public long getMetaspacePointer() {
-        return pointer;
-    }
-
-    @Override
-    public String toString() {
-        return "Symbol<" + symbol + ">";
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMConfig.java	Fri May 20 18:05:09 2016 +0300
@@ -22,7 +22,6 @@
  */
 package jdk.vm.ci.hotspot;
 
-import static jdk.vm.ci.common.UnsafeUtil.readCString;
 import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
 import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
 
@@ -31,6 +30,8 @@
 import java.util.HashMap;
 import java.util.Iterator;
 
+import jdk.internal.misc.Unsafe;
+import jdk.internal.vm.annotation.Stable;
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspotvmconfig.HotSpotVMAddress;
 import jdk.vm.ci.hotspotvmconfig.HotSpotVMConstant;
@@ -38,9 +39,6 @@
 import jdk.vm.ci.hotspotvmconfig.HotSpotVMField;
 import jdk.vm.ci.hotspotvmconfig.HotSpotVMFlag;
 import jdk.vm.ci.hotspotvmconfig.HotSpotVMType;
-import jdk.internal.misc.Unsafe;
-
-//JaCoCo Exclude
 
 /**
  * Used to access native configuration details.
@@ -109,6 +107,27 @@
     }
 
     /**
+     * Reads a {@code '\0'} terminated C string from native memory and converts it to a
+     * {@link String}.
+     *
+     * @return a Java string
+     */
+    private static String readCString(Unsafe unsafe, long address) {
+        if (address == 0) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0;; i++) {
+            char c = (char) unsafe.getByte(address + i);
+            if (c == 0) {
+                break;
+            }
+            sb.append(c);
+        }
+        return sb.toString();
+    }
+
+    /**
      * Initialize fields by reading their values from vmStructs.
      */
     private void initialize() {
@@ -1256,8 +1275,16 @@
     @HotSpotVMField(name = "nmethod::_verified_entry_point", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodEntryOffset;
     @HotSpotVMField(name = "nmethod::_comp_level", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodCompLevelOffset;
 
+    @HotSpotVMConstant(name = "CompLevel_none") @Stable public int compilationLevelNone;
+    @HotSpotVMConstant(name = "CompLevel_simple") @Stable public int compilationLevelSimple;
+    @HotSpotVMConstant(name = "CompLevel_limited_profile") @Stable public int compilationLevelLimitedProfile;
+    @HotSpotVMConstant(name = "CompLevel_full_profile") @Stable public int compilationLevelFullProfile;
     @HotSpotVMConstant(name = "CompLevel_full_optimization") @Stable public int compilationLevelFullOptimization;
 
+    @HotSpotVMConstant(name = "JVMCIRuntime::none") @Stable public int compLevelAdjustmentNone;
+    @HotSpotVMConstant(name = "JVMCIRuntime::by_holder") @Stable public int compLevelAdjustmentByHolder;
+    @HotSpotVMConstant(name = "JVMCIRuntime::by_full_signature") @Stable public int compLevelAdjustmentByFullSignature;
+
     @HotSpotVMConstant(name = "InvocationEntryBci") @Stable public int invocationEntryBci;
 
     @HotSpotVMField(name = "JVMCIEnv::_task", type = "CompileTask*", get = HotSpotVMField.Type.OFFSET) @Stable public int jvmciEnvTaskOffset;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot;
-
-import jdk.vm.ci.code.CompiledCode;
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.meta.JVMCIMetaAccessContext;
-import jdk.vm.ci.meta.ResolvedJavaType;
-
-public interface HotSpotVMEventListener {
-
-    /**
-     * Notifies this client that the VM is shutting down.
-     */
-    default void notifyShutdown() {
-    }
-
-    /**
-     * Notify on successful install into the code cache.
-     *
-     * @param hotSpotCodeCacheProvider
-     * @param installedCode
-     * @param compiledCode
-     */
-    default void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) {
-    }
-
-    /**
-     * Create a custom {@link JVMCIMetaAccessContext} to be used for managing the lifetime of loaded
-     * metadata. It a custom one isn't created then the default implementation will be a single
-     * context with globally shared instances of {@link ResolvedJavaType} that are never released.
-     *
-     * @param hotSpotJVMCIRuntime
-     * @return a custom context or null
-     */
-    default JVMCIMetaAccessContext createMetaAccessContext(HotSpotJVMCIRuntime hotSpotJVMCIRuntime) {
-        return null;
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/Stable.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.vm.ci.hotspot;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * This annotation functions as an alias for the jdk.internal.vm.annotation.Stable annotation within JVMCI
- * code. It is specially recognized during class file parsing in the same way as that annotation.
- */
-@Target(ElementType.FIELD)
-@Retention(RetentionPolicy.RUNTIME)
-public @interface Stable {
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/SuppressFBWarnings.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot;
+
+/**
+ * Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
+ */
+@interface SuppressFBWarnings {
+    /**
+     * The set of FindBugs
+     * <a href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
+     * suppressed in annotated element. The value can be a bug category, kind or pattern.
+     */
+    String[] value();
+
+    /**
+     * Reason why the warning is suppressed.
+     */
+    String justification();
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/events/EmptyEventProvider.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot.events;
-
-import jdk.vm.ci.common.JVMCIError;
-
-/**
- * An empty implementation for {@link EventProvider}. This implementation is used when no logging is
- * requested.
- */
-public final class EmptyEventProvider implements EventProvider {
-
-    public CompilationEvent newCompilationEvent() {
-        return new EmptyCompilationEvent();
-    }
-
-    public static class EmptyCompilationEvent implements CompilationEvent {
-        public void commit() {
-            throw JVMCIError.shouldNotReachHere();
-        }
-
-        public boolean shouldWrite() {
-            // Events of this class should never been written.
-            return false;
-        }
-
-        public void begin() {
-        }
-
-        public void end() {
-        }
-
-        public void setMethod(String method) {
-            throw JVMCIError.shouldNotReachHere();
-        }
-
-        public void setCompileId(int compileId) {
-            throw JVMCIError.shouldNotReachHere();
-        }
-
-        public void setCompileLevel(int compileLevel) {
-            throw JVMCIError.shouldNotReachHere();
-        }
-
-        public void setSucceeded(boolean succeeded) {
-            throw JVMCIError.shouldNotReachHere();
-        }
-
-        public void setIsOsr(boolean isOsr) {
-            throw JVMCIError.shouldNotReachHere();
-        }
-
-        public void setCodeSize(int codeSize) {
-            throw JVMCIError.shouldNotReachHere();
-        }
-
-        public void setInlinedBytes(int inlinedBytes) {
-            throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-    public CompilerFailureEvent newCompilerFailureEvent() {
-        return new EmptyCompilerFailureEvent();
-    }
-
-    public static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
-        public void commit() {
-            throw JVMCIError.shouldNotReachHere();
-        }
-
-        public boolean shouldWrite() {
-            // Events of this class should never been written.
-            return false;
-        }
-
-        public void setCompileId(int compileId) {
-            throw JVMCIError.shouldNotReachHere();
-        }
-
-        public void setMessage(String message) {
-            throw JVMCIError.shouldNotReachHere();
-        }
-    }
-
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/events/EventProvider.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.hotspot.events;
-
-/**
- * A provider that provides a specific implementation for events that can be logged in the compiler.
- */
-public interface EventProvider {
-
-    /**
-     * An instant event is an event that is not considered to have taken any time.
-     */
-    interface InstantEvent {
-        /**
-         * Commits the event.
-         */
-        void commit();
-
-        /**
-         * Determines if this particular event instance would be committed to the data stream right
-         * now if application called {@link #commit()}. This in turn depends on whether the event is
-         * enabled and possible other factors.
-         *
-         * @return if this event would be committed on a call to {@link #commit()}.
-         */
-        boolean shouldWrite();
-    }
-
-    /**
-     * Timed events describe an operation that somehow consumes time.
-     */
-    interface TimedEvent extends InstantEvent {
-        /**
-         * Starts the timing for this event.
-         */
-        void begin();
-
-        /**
-         * Ends the timing period for this event.
-         */
-        void end();
-    }
-
-    /**
-     * Creates a new {@link CompilationEvent}.
-     *
-     * @return a compilation event
-     */
-    CompilationEvent newCompilationEvent();
-
-    /**
-     * A compilation event.
-     */
-    interface CompilationEvent extends TimedEvent {
-        void setMethod(String method);
-
-        void setCompileId(int compileId);
-
-        void setCompileLevel(int compileLevel);
-
-        void setSucceeded(boolean succeeded);
-
-        void setIsOsr(boolean isOsr);
-
-        void setCodeSize(int codeSize);
-
-        void setInlinedBytes(int inlinedBytes);
-    }
-
-    /**
-     * Creates a new {@link CompilerFailureEvent}.
-     *
-     * @return a compiler failure event
-     */
-    CompilerFailureEvent newCompilerFailureEvent();
-
-    /**
-     * A compiler failure event.
-     */
-    interface CompilerFailureEvent extends InstantEvent {
-        void setCompileId(int compileId);
-
-        void setMessage(String message);
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/logging/package-info.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-/**
- * Logging framework for the HotSpot CRI implementation.
- */
-package jdk.vm.ci.hotspot.logging;
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EmptyEventProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot.services;
+
+/**
+ * An empty implementation for {@link EventProvider}. This implementation is used when no logging is
+ * requested.
+ */
+final class EmptyEventProvider extends EventProvider {
+
+    EmptyEventProvider() {
+        super(null);
+    }
+
+    static InternalError shouldNotReachHere() {
+        throw new InternalError("should not reach here");
+    }
+
+    @Override
+    public CompilationEvent newCompilationEvent() {
+        return new EmptyCompilationEvent();
+    }
+
+    static class EmptyCompilationEvent implements CompilationEvent {
+        public void commit() {
+            throw shouldNotReachHere();
+        }
+
+        public boolean shouldWrite() {
+            // Events of this class should never been written.
+            return false;
+        }
+
+        public void begin() {
+        }
+
+        public void end() {
+        }
+
+        public void setMethod(String method) {
+            throw shouldNotReachHere();
+        }
+
+        public void setCompileId(int compileId) {
+            throw shouldNotReachHere();
+        }
+
+        public void setCompileLevel(int compileLevel) {
+            throw shouldNotReachHere();
+        }
+
+        public void setSucceeded(boolean succeeded) {
+            throw shouldNotReachHere();
+        }
+
+        public void setIsOsr(boolean isOsr) {
+            throw shouldNotReachHere();
+        }
+
+        public void setCodeSize(int codeSize) {
+            throw shouldNotReachHere();
+        }
+
+        public void setInlinedBytes(int inlinedBytes) {
+            throw shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public CompilerFailureEvent newCompilerFailureEvent() {
+        return new EmptyCompilerFailureEvent();
+    }
+
+    static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
+        public void commit() {
+            throw shouldNotReachHere();
+        }
+
+        public boolean shouldWrite() {
+            // Events of this class should never been written.
+            return false;
+        }
+
+        public void setCompileId(int compileId) {
+            throw shouldNotReachHere();
+        }
+
+        public void setMessage(String message) {
+            throw shouldNotReachHere();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EventProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot.services;
+
+import jdk.vm.ci.hotspot.services.EmptyEventProvider.EmptyCompilationEvent;
+import jdk.vm.ci.hotspot.services.EmptyEventProvider.EmptyCompilerFailureEvent;
+import jdk.vm.ci.services.JVMCIPermission;
+
+/**
+ * Service-provider class for logging compiler related events.
+ */
+public abstract class EventProvider {
+
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new JVMCIPermission());
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    EventProvider(Void ignore) {
+    }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @throws SecurityException if a security manager has been installed and it denies
+     *             {@link JVMCIPermission}
+     */
+    protected EventProvider() {
+        this(checkPermission());
+    }
+
+    /**
+     * Creates and returns an empty implementation for {@link EventProvider}. This implementation
+     * can be used when no logging is requested.
+     */
+    public static EventProvider createEmptyEventProvider() {
+        return new EmptyEventProvider();
+    }
+
+    /**
+     * Creates and returns an empty implementation for {@link CompilationEvent}.
+     */
+    public static CompilationEvent createEmptyCompilationEvent() {
+        return new EmptyCompilationEvent();
+    }
+
+    /**
+     * Creates and returns an empty implementation for {@link CompilationEvent}.
+     */
+    public static CompilerFailureEvent createEmptyCompilerFailureEvent() {
+        return new EmptyCompilerFailureEvent();
+    }
+
+    /**
+     * An instant event is an event that is not considered to have taken any time.
+     */
+    public interface InstantEvent {
+        /**
+         * Commits the event.
+         */
+        void commit();
+
+        /**
+         * Determines if this particular event instance would be committed to the data stream right
+         * now if application called {@link #commit()}. This in turn depends on whether the event is
+         * enabled and possible other factors.
+         *
+         * @return if this event would be committed on a call to {@link #commit()}.
+         */
+        boolean shouldWrite();
+    }
+
+    /**
+     * Timed events describe an operation that somehow consumes time.
+     */
+    public interface TimedEvent extends InstantEvent {
+        /**
+         * Starts the timing for this event.
+         */
+        void begin();
+
+        /**
+         * Ends the timing period for this event.
+         */
+        void end();
+    }
+
+    /**
+     * Creates a new {@link CompilationEvent}.
+     *
+     * @return a compilation event
+     */
+    public abstract CompilationEvent newCompilationEvent();
+
+    /**
+     * A compilation event.
+     */
+    public interface CompilationEvent extends TimedEvent {
+        void setMethod(String method);
+
+        void setCompileId(int compileId);
+
+        void setCompileLevel(int compileLevel);
+
+        void setSucceeded(boolean succeeded);
+
+        void setIsOsr(boolean isOsr);
+
+        void setCodeSize(int codeSize);
+
+        void setInlinedBytes(int inlinedBytes);
+    }
+
+    /**
+     * Creates a new {@link CompilerFailureEvent}.
+     *
+     * @return a compiler failure event
+     */
+    public abstract CompilerFailureEvent newCompilerFailureEvent();
+
+    /**
+     * A compiler failure event.
+     */
+    public interface CompilerFailureEvent extends InstantEvent {
+        void setCompileId(int compileId);
+
+        void setMessage(String message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotJVMCICompilerFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot.services;
+
+import jdk.vm.ci.hotspot.HotSpotVMConfig;
+import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
+
+/**
+ * HotSpot extensions to {@link JVMCICompilerFactory}.
+ */
+public abstract class HotSpotJVMCICompilerFactory extends JVMCICompilerFactory {
+
+    /**
+     * Gets 0 or more prefixes identifying classes that should by compiled by C1 in simple mode
+     * (i.e., {@code CompLevel_simple}) when HotSpot is running with tiered compilation. The
+     * prefixes should be class or package names using "/" as the separator, e.g. "jdk/vm/ci".
+     *
+     * @return 0 or more Strings identifying packages that should by compiled by the first tier only
+     *         or null if no redirection to C1 should be performed.
+     */
+    public String[] getTrivialPrefixes() {
+        return null;
+    }
+
+    /**
+     * Determines if this object may want to adjust the compilation level for a method that is being
+     * scheduled by the VM for compilation. The legal return values and their meanings are:
+     * <ul>
+     * <li>0 - no adjustment</li>
+     * <li>1 - adjust based on declaring class of method</li>
+     * <li>2 - adjust based on declaring class, name and signature of method</li>
+     * </ul>
+     */
+    public int getCompilationLevelAdjustment(HotSpotVMConfig config) {
+        return config.compLevelAdjustmentNone;
+    }
+
+    /**
+     * Potentially modifies the compilation level currently selected by the VM compilation policy
+     * for a method.
+     *
+     * @param config object for reading HotSpot {@code CompLevel} enum values
+     * @param declaringClass the class in which the method is declared
+     * @param name the name of the method or {@code null} depending on the value that was returned
+     *            by {@link #getCompilationLevelAdjustment(HotSpotVMConfig)}
+     * @param signature the signature of the method or {@code null} depending on the value that was
+     *            returned by {@link #getCompilationLevelAdjustment(HotSpotVMConfig)}
+     * @param isOsr specifies if the compilation being scheduled in an OSR compilation
+     * @param level the compilation level currently selected by the VM compilation policy
+     * @return the compilation level to use for the compilation being scheduled (must be a valid
+     *         {@code CompLevel} enum value)
+     */
+    public int adjustCompilationLevel(HotSpotVMConfig config, Class<?> declaringClass, String name, String signature, boolean isOsr, int level) {
+        throw new InternalError("Should not reach here");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotVMEventListener.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.hotspot.services;
+
+import jdk.vm.ci.code.CompiledCode;
+import jdk.vm.ci.code.InstalledCode;
+import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
+import jdk.vm.ci.services.JVMCIPermission;
+
+/**
+ * Service-provider class for responding to VM events.
+ */
+public abstract class HotSpotVMEventListener {
+
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new JVMCIPermission());
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    HotSpotVMEventListener(Void ignore) {
+    }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @throws SecurityException if a security manager has been installed and it denies
+     *             {@link JVMCIPermission}
+     */
+    protected HotSpotVMEventListener() {
+        this(checkPermission());
+    }
+
+    /**
+     * Notifies this client that the VM is shutting down.
+     */
+    public void notifyShutdown() {
+    }
+
+    /**
+     * Notify on successful install into the code cache.
+     *
+     * @param hotSpotCodeCacheProvider
+     * @param installedCode
+     * @param compiledCode
+     */
+    public void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) {
+    }
+
+    /**
+     * Notify on completion of a bootstrap.
+     */
+    public void notifyBootstrapFinished() {
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.inittimer/src/jdk/vm/ci/inittimer/InitTimer.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.inittimer;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * A facility for timing a step in the runtime initialization sequence. This is independent from all
- * other JVMCI code so as to not perturb the initialization sequence. It is enabled by setting the
- * {@code "jvmci.inittimer"} system property to {@code "true"}.
- */
-public final class InitTimer implements AutoCloseable {
-    final String name;
-    final long start;
-
-    private InitTimer(String name) {
-        int n = nesting.getAndIncrement();
-        if (n == 0) {
-            initializingThread = Thread.currentThread();
-            System.out.println("INITIALIZING THREAD: " + initializingThread);
-        } else {
-            assert Thread.currentThread() == initializingThread : Thread.currentThread() + " != " + initializingThread;
-        }
-        this.name = name;
-        this.start = System.currentTimeMillis();
-        System.out.println("START: " + SPACES.substring(0, n * 2) + name);
-    }
-
-    @SuppressFBWarnings(value = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD", justification = "only the initializing thread accesses this field")
-    public void close() {
-        final long end = System.currentTimeMillis();
-        int n = nesting.decrementAndGet();
-        System.out.println(" DONE: " + SPACES.substring(0, n * 2) + name + " [" + (end - start) + " ms]");
-        if (n == 0) {
-            initializingThread = null;
-        }
-    }
-
-    public static InitTimer timer(String name) {
-        return ENABLED ? new InitTimer(name) : null;
-    }
-
-    public static InitTimer timer(String name, Object suffix) {
-        return ENABLED ? new InitTimer(name + suffix) : null;
-    }
-
-    /**
-     * Specifies if initialization timing is enabled. Note: This property cannot use
-     * {@code HotSpotJVMCIRuntime.Option} since that class is not visible from this package.
-     */
-    private static final boolean ENABLED = Boolean.getBoolean("jvmci.InitTimer");
-
-    public static final AtomicInteger nesting = ENABLED ? new AtomicInteger() : null;
-    public static final String SPACES = "                                            ";
-
-    /**
-     * Used to assert the invariant that all related initialization happens on the same thread.
-     */
-    public static Thread initializingThread;
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.inittimer/src/jdk/vm/ci/inittimer/SuppressFBWarnings.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.inittimer;
-
-/**
- * Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
- */
-public @interface SuppressFBWarnings {
-    /**
-     * The set of FindBugs <a
-     * href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
-     * suppressed in annotated element. The value can be a bug category, kind or pattern.
-     */
-    String[] value();
-
-    /**
-     * Reason why the warning is suppressed.
-     */
-    String justification();
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/AllocatableValue.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
 
     public static final AllocatableValue[] NONE = {};
 
-    public AllocatableValue(LIRKind lirKind) {
-        super(lirKind);
+    public AllocatableValue(ValueKind<?> kind) {
+        super(kind);
     }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Assumptions.java	Fri May 20 18:05:09 2016 +0300
@@ -44,7 +44,10 @@
 
     /**
      * A class for providing information that is only valid in association with a set of
-     * {@link Assumption}s.
+     * {@link Assumption}s. It is permissible for AssumptionResults to have no assumptions at all.
+     * For instance, if {@link ResolvedJavaType#isLeaf()} returns true for a type
+     * {@link ResolvedJavaType#findLeafConcreteSubtype()} can return an AssumptionResult with no
+     * assumptions since the leaf information is statically true.
      *
      * @param <T>
      */
@@ -187,6 +190,7 @@
         public final ResolvedJavaType context;
 
         public LeafType(ResolvedJavaType context) {
+            assert !context.isLeaf() : "assumption isn't required for leaf types";
             this.context = context;
         }
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantReflectionProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ConstantReflectionProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -56,39 +56,10 @@
     JavaConstant readArrayElement(JavaConstant array, int index);
 
     /**
-     * Reads a value from the given array at the given index if it is a stable array. Returns
-     * {@code null} if the constant is not a stable array, if it is a default value, if the index is
-     * out of bounds, or if the value is not available at this point.
-     */
-    JavaConstant readConstantArrayElement(JavaConstant array, int index);
-
-    /**
-     * Reads a value from the given array at the given offset if it is a stable array. The offset
-     * will be decoded relative to the platform addressing into an index into the array. Returns
-     * {@code null} if the constant is not a stable array, if it is a default value, if the offset
-     * is out of bounds, or if the value is not available at this point.
-     */
-    JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset);
-
-    /**
-     * Gets the constant value of this field. Note that a {@code static final} field may not be
-     * considered constant if its declaring class is not yet initialized or if it is a well known
-     * field that can be updated via other means (e.g., {@link System#setOut(java.io.PrintStream)}).
-     *
-     * @param receiver object from which this field's value is to be read. This value is ignored if
-     *            this field is static.
-     * @return the constant value of this field or {@code null} if this field is not considered
-     *         constant by the runtime
-     */
-    JavaConstant readConstantFieldValue(ResolvedJavaField field, JavaConstant receiver);
-
-    /**
      * Gets the current value of this field for a given object, if available.
      *
      * There is no guarantee that the same value will be returned by this method for a field unless
-     * the field is considered to be
-     * {@linkplain #readConstantFieldValue(ResolvedJavaField, JavaConstant) constant} by the
-     * runtime.
+     * the field is considered to be constant by the runtime.
      *
      * @param receiver object from which this field's value is to be read. This value is ignored if
      *            this field is static.
@@ -98,23 +69,6 @@
     JavaConstant readFieldValue(ResolvedJavaField field, JavaConstant receiver);
 
     /**
-     * Gets the current value of this field for a given object, if available. Like
-     * {@link #readFieldValue(ResolvedJavaField, JavaConstant)} but treats array fields as stable.
-     *
-     * There is no guarantee that the same value will be returned by this method for a field unless
-     * the field is considered to be
-     * {@linkplain #readConstantFieldValue(ResolvedJavaField, JavaConstant) constant} by the
-     * runtime.
-     *
-     * @param receiver object from which this field's value is to be read. This value is ignored if
-     *            this field is static.
-     * @param isDefaultStable if {@code true}, default values are considered stable
-     * @return the value of this field or {@code null} if the value is not available (e.g., because
-     *         the field holder is not yet initialized).
-     */
-    JavaConstant readStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefaultStable);
-
-    /**
      * Converts the given {@link JavaKind#isPrimitive() primitive} constant to a boxed
      * {@link JavaKind#Object object} constant, according to the Java boxing rules. Returns
      * {@code null} if the source is is not a primitive constant, or the boxed value is not
@@ -123,10 +77,10 @@
     JavaConstant boxPrimitive(JavaConstant source);
 
     /**
-     * Converts the given {@link JavaKind#Object object} constant to a
-     * {@link JavaKind#isPrimitive() primitive} constant, according to the Java unboxing rules.
-     * Returns {@code null} if the source is is not an object constant that can be unboxed, or the
-     * unboxed value is not available at this point.
+     * Converts the given {@link JavaKind#Object object} constant to a {@link JavaKind#isPrimitive()
+     * primitive} constant, according to the Java unboxing rules. Returns {@code null} if the source
+     * is is not an object constant that can be unboxed, or the unboxed value is not available at
+     * this point.
      */
     JavaConstant unboxPrimitive(JavaConstant source);
 
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JVMCIMetaAccessContext.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.meta;
-
-/**
- * A context in which the results looking up the {@link ResolvedJavaType} for a {@link Class} are
- * cached.
- */
-public interface JVMCIMetaAccessContext {
-
-    /**
-     * Gets the JVMCI mirror for a {@link Class} object.
-     *
-     * @return the {@link ResolvedJavaType} corresponding to {@code javaClass}
-     */
-
-    ResolvedJavaType fromClass(Class<?> clazz);
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaConstant.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaConstant.java	Fri May 20 18:05:09 2016 +0300
@@ -357,106 +357,4 @@
                 throw new IllegalArgumentException(kind.toString());
         }
     }
-
-    /**
-     * Returns the zero value for a given numeric kind.
-     */
-    static JavaConstant zero(JavaKind kind) {
-        switch (kind) {
-            case Boolean:
-                return FALSE;
-            case Byte:
-                return forByte((byte) 0);
-            case Char:
-                return forChar((char) 0);
-            case Double:
-                return DOUBLE_0;
-            case Float:
-                return FLOAT_0;
-            case Int:
-                return INT_0;
-            case Long:
-                return LONG_0;
-            case Short:
-                return forShort((short) 0);
-            default:
-                throw new IllegalArgumentException(kind.toString());
-        }
-    }
-
-    /**
-     * Returns the one value for a given numeric kind.
-     */
-    static JavaConstant one(JavaKind kind) {
-        switch (kind) {
-            case Boolean:
-                return TRUE;
-            case Byte:
-                return forByte((byte) 1);
-            case Char:
-                return forChar((char) 1);
-            case Double:
-                return DOUBLE_1;
-            case Float:
-                return FLOAT_1;
-            case Int:
-                return INT_1;
-            case Long:
-                return LONG_1;
-            case Short:
-                return forShort((short) 1);
-            default:
-                throw new IllegalArgumentException(kind.toString());
-        }
-    }
-
-    /**
-     * Adds two numeric constants.
-     */
-    static JavaConstant add(JavaConstant x, JavaConstant y) {
-        assert x.getJavaKind() == y.getJavaKind();
-        switch (x.getJavaKind()) {
-            case Byte:
-                return forByte((byte) (x.asInt() + y.asInt()));
-            case Char:
-                return forChar((char) (x.asInt() + y.asInt()));
-            case Double:
-                return forDouble(x.asDouble() + y.asDouble());
-            case Float:
-                return forFloat(x.asFloat() + y.asFloat());
-            case Int:
-                return forInt(x.asInt() + y.asInt());
-            case Long:
-                return forLong(x.asLong() + y.asLong());
-            case Short:
-                return forShort((short) (x.asInt() + y.asInt()));
-            default:
-                throw new IllegalArgumentException(x.getJavaKind().toString());
-        }
-    }
-
-    /**
-     * Multiplies two numeric constants.
-     */
-    static PrimitiveConstant mul(JavaConstant x, JavaConstant y) {
-        assert x.getJavaKind() == y.getJavaKind();
-        switch (x.getJavaKind()) {
-            case Byte:
-                return forByte((byte) (x.asInt() * y.asInt()));
-            case Char:
-                return forChar((char) (x.asInt() * y.asInt()));
-            case Double:
-                return forDouble(x.asDouble() * y.asDouble());
-            case Float:
-                return forFloat(x.asFloat() * y.asFloat());
-            case Int:
-                return forInt(x.asInt() * y.asInt());
-            case Long:
-                return forLong(x.asLong() * y.asLong());
-            case Short:
-                return forShort((short) (x.asInt() * y.asInt()));
-            default:
-                throw new IllegalArgumentException(x.getJavaKind().toString());
-        }
-    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaField.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaField.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
  * Represents a reference to a Java field, either resolved or unresolved fields. Fields, like
  * methods and types, are resolved through {@link ConstantPool constant pools}.
  */
-public interface JavaField extends TrustedInterface {
+public interface JavaField {
 
     /**
      * Returns the name of this field.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaKind.java	Fri May 20 18:05:09 2016 +0300
@@ -33,34 +33,34 @@
  */
 public enum JavaKind {
     /** The primitive boolean kind, represented as an int on the stack. */
-    Boolean('z', "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class),
+    Boolean('Z', "boolean", 1, true, java.lang.Boolean.TYPE, java.lang.Boolean.class),
 
     /** The primitive byte kind, represented as an int on the stack. */
-    Byte('b', "byte", 1, true, java.lang.Byte.TYPE, java.lang.Byte.class),
+    Byte('B', "byte", 1, true, java.lang.Byte.TYPE, java.lang.Byte.class),
 
     /** The primitive short kind, represented as an int on the stack. */
-    Short('s', "short", 1, true, java.lang.Short.TYPE, java.lang.Short.class),
+    Short('S', "short", 1, true, java.lang.Short.TYPE, java.lang.Short.class),
 
     /** The primitive char kind, represented as an int on the stack. */
-    Char('c', "char", 1, true, java.lang.Character.TYPE, java.lang.Character.class),
+    Char('C', "char", 1, true, java.lang.Character.TYPE, java.lang.Character.class),
 
     /** The primitive int kind, represented as an int on the stack. */
-    Int('i', "int", 1, true, java.lang.Integer.TYPE, java.lang.Integer.class),
+    Int('I', "int", 1, true, java.lang.Integer.TYPE, java.lang.Integer.class),
 
     /** The primitive float kind. */
-    Float('f', "float", 1, false, java.lang.Float.TYPE, java.lang.Float.class),
+    Float('F', "float", 1, false, java.lang.Float.TYPE, java.lang.Float.class),
 
     /** The primitive long kind. */
-    Long('j', "long", 2, false, java.lang.Long.TYPE, java.lang.Long.class),
+    Long('J', "long", 2, false, java.lang.Long.TYPE, java.lang.Long.class),
 
     /** The primitive double kind. */
-    Double('d', "double", 2, false, java.lang.Double.TYPE, java.lang.Double.class),
+    Double('D', "double", 2, false, java.lang.Double.TYPE, java.lang.Double.class),
 
     /** The Object kind, also used for arrays. */
-    Object('a', "Object", 1, false, null, null),
+    Object('A', "Object", 1, false, null, null),
 
-    /** The void float kind. */
-    Void('v', "void", 0, false, java.lang.Void.TYPE, java.lang.Void.class),
+    /** The void kind. */
+    Void('V', "void", 0, false, java.lang.Void.TYPE, java.lang.Void.class),
 
     /** The non-type. */
     Illegal('-', "illegal", 0, false, null, null);
@@ -98,7 +98,11 @@
     }
 
     /**
-     * Returns the name of the kind as a single character.
+     * Returns the name of the kind as a single upper case character. For the void and primitive
+     * kinds, this is the <i>FieldType</i> term in
+     * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.3.2-200">
+     * table 4.3-A</a> of the JVM Specification. For {@link #Object}, the character {@code 'A'} is
+     * returned and for {@link #Illegal}, {@code '-'} is returned.
      */
     public char getTypeChar() {
         return typeChar;
@@ -204,7 +208,7 @@
     /**
      * Returns the kind from the character describing a primitive or void.
      *
-     * @param ch the character
+     * @param ch the character for a void or primitive kind as returned by {@link #getTypeChar()}
      * @return the kind
      */
     public static JavaKind fromPrimitiveOrVoidTypeChar(char ch) {
@@ -369,9 +373,9 @@
     }
 
     /**
-     * The minimum value that can be represented as a value of this kind.
+     * Gets the minimum value that can be represented as a value of this kind.
      *
-     * @return the minimum value
+     * @return the minimum value represented as a {@code long}
      */
     public long getMinValue() {
         switch (this) {
@@ -387,15 +391,19 @@
                 return java.lang.Integer.MIN_VALUE;
             case Long:
                 return java.lang.Long.MIN_VALUE;
+            case Float:
+                return java.lang.Float.floatToRawIntBits(java.lang.Float.MIN_VALUE);
+            case Double:
+                return java.lang.Double.doubleToRawLongBits(java.lang.Double.MIN_VALUE);
             default:
                 throw new IllegalArgumentException("illegal call to minValue on " + this);
         }
     }
 
     /**
-     * The maximum value that can be represented as a value of this kind.
+     * Gets the maximum value that can be represented as a value of this kind.
      *
-     * @return the maximum value
+     * @return the maximum value represented as a {@code long}
      */
     public long getMaxValue() {
         switch (this) {
@@ -411,6 +419,10 @@
                 return java.lang.Integer.MAX_VALUE;
             case Long:
                 return java.lang.Long.MAX_VALUE;
+            case Float:
+                return java.lang.Float.floatToRawIntBits(java.lang.Float.MAX_VALUE);
+            case Double:
+                return java.lang.Double.doubleToRawLongBits(java.lang.Double.MAX_VALUE);
             default:
                 throw new IllegalArgumentException("illegal call to maxValue on " + this);
         }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethod.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaMethod.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
  * Represents a reference to a Java method, either resolved or unresolved. Methods, like fields and
  * types, are resolved through {@link ConstantPool constant pools}.
  */
-public interface JavaMethod extends TrustedInterface {
+public interface JavaMethod {
 
     /**
      * Returns the name of this method.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaType.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/JavaType.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
  * Represents a resolved or unresolved type. Types include primitives, objects, {@code void}, and
  * arrays thereof.
  */
-public interface JavaType extends TrustedInterface {
+public interface JavaType {
 
     /**
      * Returns the name of this type in internal form. The following are examples of strings
@@ -62,6 +62,15 @@
     }
 
     /**
+     * Checks whether this type is an array class.
+     *
+     * @return {@code true} if this type is an array class
+     */
+    default boolean isArray() {
+        return getComponentType() != null;
+    }
+
+    /**
      * For array types, gets the type of the components, or {@code null} if this is not an array
      * type. This method is analogous to {@link Class#getComponentType()}.
      */
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LIRKind.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,460 +0,0 @@
-/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.meta;
-
-import java.util.ArrayList;
-
-/**
- * Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
- * low level representation of the value, and a {@link #referenceMask} that describes the location
- * of object references in the value, and optionally a {@link #derivedReferenceBase}.
- *
- * <h2>Constructing {@link LIRKind} instances</h2>
- *
- * During LIR generation, every new {@link Value} should get a {@link LIRKind} of the correct
- * {@link PlatformKind} that also contains the correct reference information. {@linkplain LIRKind
- * LIRKinds} should be created as follows:
- *
- * <p>
- * If the result value is created from one or more input values, the {@link LIRKind} should be
- * created with {@link LIRKind#combine}(inputs). If the result has a different {@link PlatformKind}
- * than the inputs, {@link LIRKind#combine}(inputs).{@link #changeType}(resultKind) should be used.
- * <p>
- * If the result is an exact copy of one of the inputs, {@link Value#getLIRKind()} can be used. Note
- * that this is only correct for move-like operations, like conditional move or compare-and-swap.
- * For convert operations, {@link LIRKind#combine} should be used.
- * <p>
- * If it is known that the result will be a reference (e.g. pointer arithmetic where the end result
- * is a valid oop), {@link LIRKind#reference} should be used.
- * <p>
- * If it is known that the result will neither be a reference nor be derived from a reference,
- * {@link LIRKind#value} can be used. If the operation producing this value has inputs, this is very
- * likely wrong, and {@link LIRKind#combine} should be used instead.
- * <p>
- * If it is known that the result is derived from a reference in a way that the garbage collector
- * can not track, {@link LIRKind#unknownReference} can be used. In most cases,
- * {@link LIRKind#combine} should be used instead, since it is able to detect this automatically.
- */
-public final class LIRKind {
-
-    private enum IllegalKind implements PlatformKind {
-        ILLEGAL;
-
-        private final EnumKey<IllegalKind> key = new EnumKey<>(this);
-
-        public Key getKey() {
-            return key;
-        }
-
-        public int getSizeInBytes() {
-            return 0;
-        }
-
-        public int getVectorLength() {
-            return 0;
-        }
-
-        public char getTypeChar() {
-            return '-';
-        }
-    }
-
-    /**
-     * The non-type. This uses {@link #unknownReference}, so it can never be part of an oop map.
-     */
-    public static final LIRKind Illegal = unknownReference(IllegalKind.ILLEGAL);
-
-    private final PlatformKind platformKind;
-    private final int referenceMask;
-
-    private AllocatableValue derivedReferenceBase;
-
-    private static final int UNKNOWN_REFERENCE = -1;
-
-    private LIRKind(PlatformKind platformKind, int referenceMask, AllocatableValue derivedReferenceBase) {
-        this.platformKind = platformKind;
-        this.referenceMask = referenceMask;
-        this.derivedReferenceBase = derivedReferenceBase;
-
-        assert derivedReferenceBase == null || !derivedReferenceBase.getLIRKind().isDerivedReference() : "derived reference can't have another derived reference as base";
-    }
-
-    /**
-     * Create a {@link LIRKind} of type {@code platformKind} that contains a primitive value. Should
-     * be only used when it's guaranteed that the value is not even indirectly derived from a
-     * reference. Otherwise, {@link #combine(Value...)} should be used instead.
-     */
-    public static LIRKind value(PlatformKind platformKind) {
-        return new LIRKind(platformKind, 0, null);
-    }
-
-    /**
-     * Create a {@link LIRKind} of type {@code platformKind} that contains a single tracked oop
-     * reference.
-     */
-    public static LIRKind reference(PlatformKind platformKind) {
-        return derivedReference(platformKind, null);
-    }
-
-    /**
-     * Create a {@link LIRKind} of type {@code platformKind} that contains a derived reference.
-     */
-    public static LIRKind derivedReference(PlatformKind platformKind, AllocatableValue base) {
-        int length = platformKind.getVectorLength();
-        assert 0 < length && length < 32 : "vector of " + length + " references not supported";
-        return new LIRKind(platformKind, (1 << length) - 1, base);
-    }
-
-    /**
-     * Create a {@link LIRKind} of type {@code platformKind} that contains a value that is derived
-     * from a reference in a non-linear way. Values of this {@link LIRKind} can not be live at
-     * safepoints. In most cases, this should not be called directly. {@link #combine} should be
-     * used instead to automatically propagate this information.
-     */
-    public static LIRKind unknownReference(PlatformKind platformKind) {
-        return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
-    }
-
-    /**
-     * Create a derived reference.
-     *
-     * @param base An {@link AllocatableValue} containing the base pointer of the derived reference.
-     */
-    public LIRKind makeDerivedReference(AllocatableValue base) {
-        assert !isUnknownReference() && derivedReferenceBase == null;
-        if (Value.ILLEGAL.equals(base)) {
-            return makeUnknownReference();
-        } else {
-            if (isValue()) {
-                return derivedReference(platformKind, base);
-            } else {
-                return new LIRKind(platformKind, referenceMask, base);
-            }
-        }
-    }
-
-    /**
-     * Derive a new type from inputs. The result will have the {@link PlatformKind} of one of the
-     * inputs. If all inputs are values, the result is a value. Otherwise, the result is an unknown
-     * reference.
-     *
-     * This method should be used to construct the result {@link LIRKind} of any operation that
-     * modifies values (e.g. arithmetics).
-     */
-    public static LIRKind combine(Value... inputs) {
-        assert inputs.length > 0;
-        for (Value input : inputs) {
-            LIRKind kind = input.getLIRKind();
-            if (kind.isUnknownReference()) {
-                return kind;
-            } else if (!kind.isValue()) {
-                return kind.makeUnknownReference();
-            }
-        }
-
-        // all inputs are values, just return one of them
-        return inputs[0].getLIRKind();
-    }
-
-    /**
-     * Merge the types of the inputs. The result will have the {@link PlatformKind} of one of the
-     * inputs. If all inputs are values (references), the result is a value (reference). Otherwise,
-     * the result is an unknown reference.
-     *
-     * This method should be used to construct the result {@link LIRKind} of merge operation that
-     * does not modify values (e.g. phis).
-     */
-    public static LIRKind merge(Value... inputs) {
-        assert inputs.length > 0;
-        ArrayList<LIRKind> kinds = new ArrayList<>(inputs.length);
-        for (int i = 0; i < inputs.length; i++) {
-            kinds.add(inputs[i].getLIRKind());
-        }
-        return merge(kinds);
-    }
-
-    /**
-     * Helper method to construct derived reference kinds. Returns the base value of a reference or
-     * derived reference. For values it returns {@code null}, and for unknown references it returns
-     * {@link Value#ILLEGAL}.
-     */
-    public static AllocatableValue derivedBaseFromValue(AllocatableValue value) {
-        LIRKind kind = value.getLIRKind();
-        if (kind.isValue()) {
-            return null;
-        } else if (kind.isDerivedReference()) {
-            return kind.getDerivedReferenceBase();
-        } else if (kind.isUnknownReference()) {
-            return Value.ILLEGAL;
-        } else {
-            // kind is a reference
-            return value;
-        }
-    }
-
-    /**
-     * Helper method to construct derived reference kinds. If one of {@code base1} or {@code base2}
-     * are set, it creates a derived reference using it as the base. If both are set, the result is
-     * an unknown reference.
-     */
-    public static LIRKind combineDerived(LIRKind kind, AllocatableValue base1, AllocatableValue base2) {
-        if (base1 == null && base2 == null) {
-            return kind;
-        } else if (base1 == null) {
-            return kind.makeDerivedReference(base2);
-        } else if (base2 == null) {
-            return kind.makeDerivedReference(base1);
-        } else {
-            return kind.makeUnknownReference();
-        }
-    }
-
-    /**
-     * @see #merge(Value...)
-     */
-    public static LIRKind merge(Iterable<LIRKind> kinds) {
-        LIRKind mergeKind = null;
-
-        for (LIRKind kind : kinds) {
-
-            if (kind.isUnknownReference()) {
-                /**
-                 * Kind is an unknown reference, therefore the result can only be also an unknown
-                 * reference.
-                 */
-                mergeKind = kind;
-                break;
-            }
-            if (mergeKind == null) {
-                mergeKind = kind;
-                continue;
-            }
-
-            if (kind.isValue()) {
-                /* Kind is a value. */
-                if (mergeKind.referenceMask != 0) {
-                    /*
-                     * Inputs consists of values and references. Make the result an unknown
-                     * reference.
-                     */
-                    mergeKind = mergeKind.makeUnknownReference();
-                    break;
-                }
-                /* Check that other inputs are also values. */
-            } else {
-                /* Kind is a reference. */
-                if (mergeKind.referenceMask != kind.referenceMask) {
-                    /*
-                     * Reference maps do not match so the result can only be an unknown reference.
-                     */
-                    mergeKind = mergeKind.makeUnknownReference();
-                    break;
-                }
-            }
-
-        }
-        assert mergeKind != null && verifyMerge(mergeKind, kinds);
-
-        // all inputs are values or references, just return one of them
-        return mergeKind;
-    }
-
-    private static boolean verifyMerge(LIRKind mergeKind, Iterable<LIRKind> kinds) {
-        for (LIRKind kind : kinds) {
-            assert mergeKind == null || verifyMoveKinds(mergeKind, kind) : String.format("Input kinds do not match %s vs. %s", mergeKind, kind);
-        }
-        return true;
-    }
-
-    /**
-     * Create a new {@link LIRKind} with the same reference information and a new
-     * {@linkplain #getPlatformKind platform kind}. If the new kind is a longer vector than this,
-     * the new elements are marked as untracked values.
-     */
-    public LIRKind changeType(PlatformKind newPlatformKind) {
-        if (newPlatformKind == platformKind) {
-            return this;
-        } else if (isUnknownReference()) {
-            return unknownReference(newPlatformKind);
-        } else if (referenceMask == 0) {
-            // value type
-            return LIRKind.value(newPlatformKind);
-        } else {
-            // reference type
-            int newLength = Math.min(32, newPlatformKind.getVectorLength());
-            int newReferenceMask = referenceMask & (0xFFFFFFFF >>> (32 - newLength));
-            assert newReferenceMask != UNKNOWN_REFERENCE;
-            return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
-        }
-    }
-
-    /**
-     * Create a new {@link LIRKind} with a new {@linkplain #getPlatformKind platform kind}. If the
-     * new kind is longer than this, the reference positions are repeated to fill the vector.
-     */
-    public LIRKind repeat(PlatformKind newPlatformKind) {
-        if (isUnknownReference()) {
-            return unknownReference(newPlatformKind);
-        } else if (referenceMask == 0) {
-            // value type
-            return LIRKind.value(newPlatformKind);
-        } else {
-            // reference type
-            int oldLength = platformKind.getVectorLength();
-            int newLength = newPlatformKind.getVectorLength();
-            assert oldLength <= newLength && newLength < 32 && (newLength % oldLength) == 0;
-
-            // repeat reference mask to fill new kind
-            int newReferenceMask = 0;
-            for (int i = 0; i < newLength; i += platformKind.getVectorLength()) {
-                newReferenceMask |= referenceMask << i;
-            }
-
-            assert newReferenceMask != UNKNOWN_REFERENCE;
-            return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
-        }
-    }
-
-    /**
-     * Create a new {@link LIRKind} with the same type, but marked as containing an
-     * {@link LIRKind#unknownReference}.
-     */
-    public LIRKind makeUnknownReference() {
-        return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
-    }
-
-    /**
-     * Get the low level type that is used in code generation.
-     */
-    public PlatformKind getPlatformKind() {
-        return platformKind;
-    }
-
-    /**
-     * Check whether this value is a derived reference.
-     */
-    public boolean isDerivedReference() {
-        return getDerivedReferenceBase() != null;
-    }
-
-    /**
-     * Get the base value of a derived reference.
-     */
-    public AllocatableValue getDerivedReferenceBase() {
-        return derivedReferenceBase;
-    }
-
-    /**
-     * Change the base value of a derived reference. This must be called on derived references only.
-     */
-    public void setDerivedReferenceBase(AllocatableValue derivedReferenceBase) {
-        assert isDerivedReference();
-        this.derivedReferenceBase = derivedReferenceBase;
-    }
-
-    /**
-     * Check whether this value is derived from a reference in a non-linear way. If this returns
-     * {@code true}, this value must not be live at safepoints.
-     */
-    public boolean isUnknownReference() {
-        return referenceMask == UNKNOWN_REFERENCE;
-    }
-
-    public int getReferenceCount() {
-        assert !isUnknownReference();
-        return Integer.bitCount(referenceMask);
-    }
-
-    /**
-     * Check whether the {@code idx}th part of this value is a reference that must be tracked at
-     * safepoints.
-     *
-     * @param idx The index into the vector if this is a vector kind. Must be 0 if this is a scalar
-     *            kind.
-     */
-    public boolean isReference(int idx) {
-        assert 0 <= idx && idx < platformKind.getVectorLength() : "invalid index " + idx + " in " + this;
-        return !isUnknownReference() && (referenceMask & 1 << idx) != 0;
-    }
-
-    /**
-     * Check whether this kind is a value type that doesn't need to be tracked at safepoints.
-     */
-    public boolean isValue() {
-        return referenceMask == 0;
-    }
-
-    @Override
-    public String toString() {
-        if (isValue()) {
-            return platformKind.name();
-        } else if (isUnknownReference()) {
-            return platformKind.name() + "[*]";
-        } else {
-            StringBuilder ret = new StringBuilder();
-            ret.append(platformKind.name());
-            ret.append('[');
-            for (int i = 0; i < platformKind.getVectorLength(); i++) {
-                if (isReference(i)) {
-                    ret.append('.');
-                } else {
-                    ret.append(' ');
-                }
-            }
-            ret.append(']');
-            return ret.toString();
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((platformKind == null) ? 0 : platformKind.hashCode());
-        result = prime * result + referenceMask;
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof LIRKind)) {
-            return false;
-        }
-
-        LIRKind other = (LIRKind) obj;
-        return platformKind == other.platformKind && referenceMask == other.referenceMask;
-    }
-
-    public static boolean verifyMoveKinds(LIRKind dst, LIRKind src) {
-        if (src.equals(dst)) {
-            return true;
-        }
-        if (src.getPlatformKind().equals(dst.getPlatformKind())) {
-            return !src.isUnknownReference() || dst.isUnknownReference();
-        }
-        return false;
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTable.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTable.java	Fri May 20 18:05:09 2016 +0300
@@ -22,11 +22,30 @@
  */
 package jdk.vm.ci.meta;
 
-public interface LineNumberTable {
+public class LineNumberTable {
+
+    private final int[] lineNumbers;
+    private final int[] bci;
 
-    int[] getLineNumberEntries();
+    public LineNumberTable(int[] lineNumbers, int[] bci) {
+        this.lineNumbers = lineNumbers;
+        this.bci = bci;
+    }
+
+    public int[] getLineNumberEntries() {
+        return lineNumbers;
+    }
 
-    int[] getBciEntries();
+    public int[] getBciEntries() {
+        return bci;
+    }
 
-    int getLineNumber(int bci);
+    public int getLineNumber(int atBci) {
+        for (int i = 0; i < this.bci.length - 1; i++) {
+            if (this.bci[i] <= atBci && atBci < this.bci[i + 1]) {
+                return lineNumbers[i];
+            }
+        }
+        return lineNumbers[lineNumbers.length - 1];
+    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LineNumberTableImpl.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.meta;
-
-public class LineNumberTableImpl implements LineNumberTable {
-
-    private final int[] lineNumbers;
-    private final int[] bci;
-
-    public LineNumberTableImpl(int[] lineNumbers, int[] bci) {
-        this.lineNumbers = lineNumbers;
-        this.bci = bci;
-    }
-
-    @Override
-    public int[] getLineNumberEntries() {
-        return lineNumbers;
-    }
-
-    @Override
-    public int[] getBciEntries() {
-        return bci;
-    }
-
-    @Override
-    public int getLineNumber(@SuppressWarnings("hiding") int bci) {
-        for (int i = 0; i < this.bci.length - 1; i++) {
-            if (this.bci[i] <= bci && bci < this.bci[i + 1]) {
-                return lineNumbers[i];
-            }
-        }
-        return lineNumbers[lineNumbers.length - 1];
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Local.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Local.java	Fri May 20 18:05:09 2016 +0300
@@ -22,15 +22,58 @@
  */
 package jdk.vm.ci.meta;
 
-public interface Local {
+public class Local {
+
+    private final String name;
+    private final int startBci;
+    private final int endBci;
+    private final int slot;
+    private final JavaType type;
 
-    int getStartBCI();
+    public Local(String name, JavaType type, int startBci, int endBci, int slot) {
+        this.name = name;
+        this.startBci = startBci;
+        this.endBci = endBci;
+        this.slot = slot;
+        this.type = type;
+    }
 
-    int getEndBCI();
+    public int getStartBCI() {
+        return startBci;
+    }
+
+    public int getEndBCI() {
+        return endBci;
+    }
+
+    public String getName() {
+        return name;
+    }
 
-    int getSlot();
+    public JavaType getType() {
+        return type;
+    }
+
+    public int getSlot() {
+        return slot;
+    }
 
-    String getName();
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Local)) {
+            return false;
+        }
+        Local that = (Local) obj;
+        return this.name.equals(that.name) && this.startBci == that.startBci && this.endBci == that.endBci && this.slot == that.slot && this.type.equals(that.type);
+    }
 
-    JavaType getType();
+    @Override
+    public int hashCode() {
+        return super.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return "LocalImpl<name=" + name + ", type=" + type + ", startBci=" + startBci + ", endBci=" + endBci + ", slot=" + slot + ">";
+    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalImpl.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.meta;
-
-public class LocalImpl implements Local {
-
-    private final String name;
-    private final int startBci;
-    private final int endBci;
-    private final int slot;
-    private final JavaType type;
-
-    public LocalImpl(String name, JavaType type, int startBci, int endBci, int slot) {
-        this.name = name;
-        this.startBci = startBci;
-        this.endBci = endBci;
-        this.slot = slot;
-        this.type = type;
-    }
-
-    @Override
-    public int getStartBCI() {
-        return startBci;
-    }
-
-    @Override
-    public int getEndBCI() {
-        return endBci;
-    }
-
-    @Override
-    public String getName() {
-        return name;
-    }
-
-    @Override
-    public JavaType getType() {
-        return type;
-    }
-
-    @Override
-    public int getSlot() {
-        return slot;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (!(obj instanceof LocalImpl)) {
-            return false;
-        }
-        LocalImpl that = (LocalImpl) obj;
-        return this.name.equals(that.name) && this.startBci == that.startBci && this.endBci == that.endBci && this.slot == that.slot && this.type.equals(that.type);
-    }
-
-    @Override
-    public int hashCode() {
-        return super.hashCode();
-    }
-
-    @Override
-    public String toString() {
-        return "LocalImpl<name=" + name + ", type=" + type + ", startBci=" + startBci + ", endBci=" + endBci + ", slot=" + slot + ">";
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTable.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTable.java	Fri May 20 18:05:09 2016 +0300
@@ -22,11 +22,42 @@
  */
 package jdk.vm.ci.meta;
 
-public interface LocalVariableTable {
+import java.util.ArrayList;
+import java.util.List;
+
+public class LocalVariableTable {
 
-    Local[] getLocals();
+    private final Local[] locals;
+
+    public LocalVariableTable(Local[] locals) {
+        this.locals = locals;
+    }
 
-    Local[] getLocalsAt(int bci);
+    public Local getLocal(int slot, int bci) {
+        Local result = null;
+        for (Local local : locals) {
+            if (local.getSlot() == slot && local.getStartBCI() <= bci && local.getEndBCI() >= bci) {
+                if (result == null) {
+                    result = local;
+                } else {
+                    throw new IllegalStateException("Locals overlap!");
+                }
+            }
+        }
+        return result;
+    }
 
-    Local getLocal(int slot, int bci);
+    public Local[] getLocals() {
+        return locals;
+    }
+
+    public Local[] getLocalsAt(int bci) {
+        List<Local> result = new ArrayList<>();
+        for (Local l : locals) {
+            if (l.getStartBCI() <= bci && bci <= l.getEndBCI()) {
+                result.add(l);
+            }
+        }
+        return result.toArray(new Local[result.size()]);
+    }
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocalVariableTableImpl.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.meta;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class LocalVariableTableImpl implements LocalVariableTable {
-
-    private final Local[] locals;
-
-    public LocalVariableTableImpl(Local[] locals) {
-        this.locals = locals;
-    }
-
-    @Override
-    public Local getLocal(int slot, int bci) {
-        Local result = null;
-        for (Local local : locals) {
-            if (local.getSlot() == slot && local.getStartBCI() <= bci && local.getEndBCI() >= bci) {
-                if (result == null) {
-                    result = local;
-                } else {
-                    throw new IllegalStateException("Locals overlap!");
-                }
-            }
-        }
-        return result;
-    }
-
-    @Override
-    public Local[] getLocals() {
-        return locals;
-    }
-
-    @Override
-    public Local[] getLocalsAt(int bci) {
-        List<Local> result = new ArrayList<>();
-        for (Local l : locals) {
-            if (l.getStartBCI() <= bci && bci <= l.getEndBCI()) {
-                result.add(l);
-            }
-        }
-        return result.toArray(new Local[result.size()]);
-    }
-
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/LocationIdentity.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.meta;
-
-import java.util.IdentityHashMap;
-
-// JaCoCo Exclude
-
-/**
- * Marker interface for location identities. A different location identity of two memory accesses
- * guarantees that the two accesses do not interfere.
- *
- * Clients of {@link LocationIdentity} must use {@link #equals(Object)}, not {@code ==}, when
- * comparing two {@link LocationIdentity} values for equality. Likewise, they must not use
- * {@link IdentityHashMap}s with {@link LocationIdentity} values as keys.
- */
-public abstract class LocationIdentity {
-
-    private static final class AnyLocationIdentity extends LocationIdentity {
-        @Override
-        public boolean isImmutable() {
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "ANY_LOCATION";
-        }
-    }
-
-    public static final LocationIdentity ANY_LOCATION = new AnyLocationIdentity();
-
-    public static LocationIdentity any() {
-        return ANY_LOCATION;
-    }
-
-    /**
-     * Denotes a location is unchanging in all cases. Not that this is different than the Java
-     * notion of final which only requires definite assignment.
-     */
-    public abstract boolean isImmutable();
-
-    public final boolean isMutable() {
-        return !isImmutable();
-    }
-
-    public final boolean isAny() {
-        return this == ANY_LOCATION;
-    }
-
-    public final boolean isSingle() {
-        return this != ANY_LOCATION;
-    }
-
-    public final boolean overlaps(LocationIdentity other) {
-        return isAny() || other.isAny() || this.equals(other);
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MemoryAccessProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MemoryAccessProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -35,8 +35,8 @@
      * @param displacement the displacement within the object in bytes
      * @return the read value encapsulated in a {@link JavaConstant} object, or {@code null} if the
      *         value cannot be read.
-     * @throws IllegalArgumentException if {@code kind} is {@code null}, {@link JavaKind#Void} or
-     *             not {@linkplain JavaKind#isPrimitive() primitive} kind
+     * @throws IllegalArgumentException if {@code kind} is {@code null}, {@link JavaKind#Void}, not
+     *             {@link JavaKind#Object} or not {@linkplain JavaKind#isPrimitive() primitive} kind
      */
     JavaConstant readUnsafeConstant(JavaKind kind, JavaConstant base, long displacement) throws IllegalArgumentException;
 
@@ -59,7 +59,9 @@
      *
      * @param base the base address from which the value is read
      * @param displacement the displacement within the object in bytes
-     * @return the read value encapsulated in a {@link Constant} object
+     * @return the read value encapsulated in a {@link Constant} object or {@code null} if the
+     *         address computed from {@code base} and {@code displacement} does not denote a
+     *         location holding an {@code Object} value
      */
     JavaConstant readObjectConstant(Constant base, long displacement);
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -81,8 +81,8 @@
     long getMemorySize(JavaConstant constant);
 
     /**
-     * Parses a <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
+     * Parses a
+     * <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
      * descriptor</a> into a {@link Signature}. The behavior of this method is undefined if the
      * method descriptor is not well formed.
      */
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaUtil.java	Fri May 20 18:05:09 2016 +0300
@@ -22,132 +22,14 @@
  */
 package jdk.vm.ci.meta;
 
-import java.io.PrintStream;
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
 
 /**
  * Miscellaneous collection of utility methods used by {@code jdk.vm.ci.meta} and its clients.
  */
 public class MetaUtil {
 
-    private static class ClassInfo {
-        public long totalSize;
-        public long instanceCount;
-
-        @Override
-        public String toString() {
-            return "totalSize=" + totalSize + ", instanceCount=" + instanceCount;
-        }
-    }
-
-    /**
-     * Returns the number of bytes occupied by this constant value or constant object and
-     * recursively all values reachable from this value.
-     *
-     * @param constant the constant whose bytes should be measured
-     * @param printTopN print total size and instance count of the top n classes is desired
-     * @return the number of bytes occupied by this constant
-     */
-    public static long getMemorySizeRecursive(MetaAccessProvider access, ConstantReflectionProvider constantReflection, JavaConstant constant, PrintStream out, int printTopN) {
-        Set<JavaConstant> marked = new HashSet<>();
-        Deque<JavaConstant> stack = new ArrayDeque<>();
-        if (constant.getJavaKind() == JavaKind.Object && constant.isNonNull()) {
-            marked.add(constant);
-        }
-        final HashMap<ResolvedJavaType, ClassInfo> histogram = new HashMap<>();
-        stack.push(constant);
-        long sum = 0;
-        while (!stack.isEmpty()) {
-            JavaConstant c = stack.pop();
-            long memorySize = access.getMemorySize(constant);
-            sum += memorySize;
-            if (c.getJavaKind() == JavaKind.Object && c.isNonNull()) {
-                ResolvedJavaType clazz = access.lookupJavaType(c);
-                if (!histogram.containsKey(clazz)) {
-                    histogram.put(clazz, new ClassInfo());
-                }
-                ClassInfo info = histogram.get(clazz);
-                info.instanceCount++;
-                info.totalSize += memorySize;
-                ResolvedJavaType type = access.lookupJavaType(c);
-                if (type.isArray()) {
-                    if (!type.getComponentType().isPrimitive()) {
-                        int length = constantReflection.readArrayLength(c);
-                        for (int i = 0; i < length; i++) {
-                            JavaConstant value = constantReflection.readArrayElement(c, i);
-                            pushConstant(marked, stack, value);
-                        }
-                    }
-                } else {
-                    ResolvedJavaField[] instanceFields = type.getInstanceFields(true);
-                    for (ResolvedJavaField f : instanceFields) {
-                        if (f.getJavaKind() == JavaKind.Object) {
-                            JavaConstant value = constantReflection.readFieldValue(f, c);
-                            pushConstant(marked, stack, value);
-                        }
-                    }
-                }
-            }
-        }
-        ArrayList<ResolvedJavaType> clazzes = new ArrayList<>();
-        clazzes.addAll(histogram.keySet());
-        Collections.sort(clazzes, new Comparator<ResolvedJavaType>() {
-
-            @Override
-            public int compare(ResolvedJavaType o1, ResolvedJavaType o2) {
-                long l1 = histogram.get(o1).totalSize;
-                long l2 = histogram.get(o2).totalSize;
-                if (l1 > l2) {
-                    return -1;
-                } else if (l1 == l2) {
-                    return 0;
-                } else {
-                    return 1;
-                }
-            }
-        });
-
-        int z = 0;
-        for (ResolvedJavaType c : clazzes) {
-            if (z > printTopN) {
-                break;
-            }
-            out.println("Class " + c + ", " + histogram.get(c));
-            ++z;
-        }
-
-        return sum;
-    }
-
-    private static void pushConstant(Set<JavaConstant> marked, Deque<JavaConstant> stack, JavaConstant value) {
-        if (value.isNonNull()) {
-            if (!marked.contains(value)) {
-                marked.add(value);
-                stack.push(value);
-            }
-        }
-    }
-
-    /**
-     * Calls {@link JavaType#resolve(ResolvedJavaType)} on an array of types.
-     */
-    public static ResolvedJavaType[] resolveJavaTypes(JavaType[] types, ResolvedJavaType accessingClass) {
-        ResolvedJavaType[] result = new ResolvedJavaType[types.length];
-        for (int i = 0; i < result.length; i++) {
-            result[i] = types[i].resolve(accessingClass);
-        }
-        return result;
-    }
-
     /**
      * Extends the functionality of {@link Class#getSimpleName()} to include a non-empty string for
      * anonymous and local classes.
@@ -184,7 +66,17 @@
         return name.substring(index + 1);
     }
 
-    static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) {
+    /**
+     * Converts a type name in internal form to an external form.
+     *
+     * @param name the internal name to convert
+     * @param qualified whether the returned name should be qualified with the package name
+     * @param classForNameCompatible specifies if the returned name for array types should be in
+     *            {@link Class#forName(String)} format (e.g., {@code "[Ljava.lang.Object;"},
+     *            {@code "[[I"}) or in Java source code format (e.g., {@code "java.lang.Object[]"},
+     *            {@code "int[][]"} ).
+     */
+    public static String internalNameToJava(String name, boolean qualified, boolean classForNameCompatible) {
         switch (name.charAt(0)) {
             case 'L': {
                 String result = name.substring(1, name.length() - 1).replace('/', '.');
@@ -207,19 +99,6 @@
     }
 
     /**
-     * Turns an class name in internal format into a resolved Java type.
-     */
-    public static ResolvedJavaType classForName(String internal, MetaAccessProvider metaAccess, ClassLoader cl) {
-        JavaKind k = JavaKind.fromTypeString(internal);
-        try {
-            String n = internalNameToJava(internal, true, true);
-            return metaAccess.lookupJavaType(k.isPrimitive() ? k.toJavaClass() : Class.forName(n, true, cl));
-        } catch (ClassNotFoundException cnfe) {
-            throw new IllegalArgumentException("could not instantiate class described by " + internal, cnfe);
-        }
-    }
-
-    /**
      * Convenient shortcut for calling
      * {@link #appendLocation(StringBuilder, ResolvedJavaMethod, int)} without having to supply a
      * {@link StringBuilder} instance and convert the result to a string.
@@ -337,21 +216,6 @@
     }
 
     /**
-     * Prepends the String {@code indentation} to every line in String {@code lines}, including a
-     * possibly non-empty line following the final newline.
-     */
-    public static String indent(String lines, String indentation) {
-        if (lines.length() == 0) {
-            return lines;
-        }
-        final String newLine = "\n";
-        if (lines.endsWith(newLine)) {
-            return indentation + (lines.substring(0, lines.length() - 1)).replace(newLine, newLine + indentation) + newLine;
-        }
-        return indentation + lines.replace(newLine, newLine + indentation);
-    }
-
-    /**
      * Gets a string representation of an object based soley on its class and its
      * {@linkplain System#identityHashCode(Object) identity hash code}. This avoids and calls to
      * virtual methods on the object such as {@link Object#hashCode()}.
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PlatformKind.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/PlatformKind.java	Fri May 20 18:05:09 2016 +0300
@@ -42,7 +42,7 @@
 
         @Override
         public int hashCode() {
-            return e.ordinal() ^ e.name().hashCode();
+            return e.ordinal();
         }
 
         @Override
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaField.java	Fri May 20 18:05:09 2016 +0300
@@ -22,14 +22,14 @@
  */
 package jdk.vm.ci.meta;
 
-import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Modifier;
 
 /**
  * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved
  * through {@link ConstantPool constant pools}.
  */
-public interface ResolvedJavaField extends JavaField, ModifiersProvider {
+public interface ResolvedJavaField extends JavaField, ModifiersProvider, AnnotatedElement {
 
     /**
      * {@inheritDoc}
@@ -59,27 +59,4 @@
      * this field.
      */
     ResolvedJavaType getDeclaringClass();
-
-    /**
-     * Returns all annotations of this field. If no annotations are present, an array of length 0 is
-     * returned.
-     */
-    Annotation[] getAnnotations();
-
-    /**
-     * Returns the annotation for the specified type of this field, if such an annotation is
-     * present.
-     *
-     * @param annotationClass the Class object corresponding to the annotation type
-     * @return this element's annotation for the specified annotation type if present on this field,
-     *         else {@code null}
-     */
-    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
-
-    /**
-     * Returns an object representing the unique location identity of this resolved Java field.
-     *
-     * @return the location identity of the field
-     */
-    LocationIdentity getLocationIdentity();
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaMethod.java	Fri May 20 18:05:09 2016 +0300
@@ -24,6 +24,7 @@
 
 import java.lang.annotation.Annotation;
 import java.lang.invoke.MethodHandle;
+import java.lang.reflect.AnnotatedElement;
 import java.lang.reflect.Array;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -33,7 +34,7 @@
  * Represents a resolved Java method. Methods, like fields and types, are resolved through
  * {@link ConstantPool constant pools}.
  */
-public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider {
+public interface ResolvedJavaMethod extends JavaMethod, InvokeTarget, ModifiersProvider, AnnotatedElement {
 
     /**
      * Returns the bytecode of this method, if the method has code. The returned byte array does not
@@ -93,8 +94,8 @@
     }
 
     /**
-     * Checks that the method is a <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6">varargs</a>
+     * Checks that the method is a
+     * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6">varargs</a>
      * method.
      *
      * @return whether the method is a varargs method
@@ -104,8 +105,8 @@
     }
 
     /**
-     * Checks that the method is a <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6">bridge</a>
+     * Checks that the method is a
+     * <a href="http://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6">bridge</a>
      * method.
      *
      * @return whether the method is a bridge method
@@ -189,22 +190,6 @@
     ConstantPool getConstantPool();
 
     /**
-     * Returns all annotations of this method. If no annotations are present, an array of length 0
-     * is returned.
-     */
-    Annotation[] getAnnotations();
-
-    /**
-     * Returns the annotation for the specified type of this method, if such an annotation is
-     * present.
-     *
-     * @param annotationClass the Class object corresponding to the annotation type
-     * @return this element's annotation for the specified annotation type if present on this
-     *         method, else {@code null}
-     */
-    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
-
-    /**
      * Returns an array of arrays that represent the annotations on the formal parameters, in
      * declaration order, of this method.
      *
@@ -347,8 +332,8 @@
     SpeculationLog getSpeculationLog();
 
     /**
-     * Determines if the method identified by its holder and name is a <a
-     * href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
+     * Determines if the method identified by its holder and name is a
+     * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-2.html#jvms-2.9">signature
      * polymorphic</a> method.
      */
     static boolean isSignaturePolymorphic(JavaType holder, String name, MetaAccessProvider metaAccess) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ResolvedJavaType.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
  */
 package jdk.vm.ci.meta;
 
-import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
 
 import jdk.vm.ci.meta.Assumptions.AssumptionResult;
 
@@ -31,7 +31,7 @@
  * thereof. Types, like fields and methods, are resolved through {@link ConstantPool constant pools}
  * .
  */
-public interface ResolvedJavaType extends JavaType, ModifiersProvider {
+public interface ResolvedJavaType extends JavaType, ModifiersProvider, AnnotatedElement {
     /**
      * Checks whether this type has a finalizer method.
      *
@@ -62,13 +62,6 @@
     boolean isInstanceClass();
 
     /**
-     * Checks whether this type is an array class.
-     *
-     * @return {@code true} if this type is an array class
-     */
-    boolean isArray();
-
-    /**
      * Checks whether this type is primitive.
      *
      * @return {@code true} if this type is primitive
@@ -137,14 +130,6 @@
     boolean isInstance(JavaConstant obj);
 
     /**
-     * Returns this type if it is an exact type otherwise returns null. This type is exact if it is
-     * void, primitive, final, or an array of a final or primitive type.
-     *
-     * @return this type if it is exact; {@code null} otherwise
-     */
-    ResolvedJavaType asExactType();
-
-    /**
      * Gets the super class of this type. If this type represents either the {@code Object} class,
      * an interface, a primitive type, or void, then null is returned. If this object represents an
      * array class then the type object representing the {@code Object} class is returned.
@@ -276,30 +261,14 @@
     ResolvedJavaField[] getInstanceFields(boolean includeSuperclasses);
 
     /**
-     * Returns the static fields of this class, including
-     * {@linkplain ResolvedJavaField#isInternal() internal} fields. A zero-length array is returned
-     * for array and primitive types. The order of fields returned by this method is stable. That
-     * is, for a single JVM execution the same order is returned each time this method is called.
+     * Returns the static fields of this class, including {@linkplain ResolvedJavaField#isInternal()
+     * internal} fields. A zero-length array is returned for array and primitive types. The order of
+     * fields returned by this method is stable. That is, for a single JVM execution the same order
+     * is returned each time this method is called.
      */
     ResolvedJavaField[] getStaticFields();
 
     /**
-     * Returns all annotations of this class. If no annotations are present, an array of length 0 is
-     * returned.
-     */
-    Annotation[] getAnnotations();
-
-    /**
-     * Returns the annotation for the specified type of this class, if such an annotation is
-     * present.
-     *
-     * @param annotationClass the Class object corresponding to the annotation type
-     * @return this element's annotation for the specified annotation type if present on this class,
-     *         else {@code null}
-     */
-    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
-
-    /**
      * Returns the instance field of this class (or one of its super classes) at the given offset,
      * or {@code null} if there is no such field.
      *
@@ -345,12 +314,6 @@
      */
     ResolvedJavaMethod getClassInitializer();
 
-    /**
-     * Returns true if this type represents an interface and it should be trusted even in places
-     * where the JVM verifier would not give any guarantees other than {@link Object}.
-     */
-    boolean isTrustedInterfaceType();
-
     default ResolvedJavaMethod findMethod(String name, Signature signature) {
         for (ResolvedJavaMethod method : getDeclaredMethods()) {
             if (method.getName().equals(name) && method.getSignature().equals(signature)) {
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Signature.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Signature.java	Fri May 20 18:05:09 2016 +0300
@@ -84,8 +84,8 @@
     }
 
     /**
-     * Gets the <a
-     * href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
+     * Gets the
+     * <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
      * descriptor</a> corresponding to this signature. For example:
      *
      * <pre>
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/TrustedInterface.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.meta;
-
-/**
- * Interfaces extending this interface should be trusted by the compiler. See
- * {@link ResolvedJavaType#isTrustedInterfaceType()}.
- *
- */
-public interface TrustedInterface {
-
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/VMConstant.java	Fri May 20 18:05:09 2016 +0300
@@ -22,5 +22,8 @@
  */
 package jdk.vm.ci.meta;
 
+/**
+ * Represents a constant that needs to be patched at runtime by the VM.
+ */
 public interface VMConstant extends Constant {
 }
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/Value.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 
     private static final class IllegalValue extends AllocatableValue {
         private IllegalValue() {
-            super(LIRKind.Illegal);
+            super(ValueKind.Illegal);
         }
 
         @Override
@@ -49,15 +49,15 @@
         }
     }
 
-    private final LIRKind lirKind;
+    private final ValueKind<?> valueKind;
 
     /**
      * Initializes a new value of the specified kind.
      *
-     * @param lirKind the kind
+     * @param valueKind the kind
      */
-    protected Value(LIRKind lirKind) {
-        this.lirKind = lirKind;
+    protected Value(ValueKind<?> valueKind) {
+        this.valueKind = valueKind;
     }
 
     /**
@@ -68,27 +68,31 @@
         return "|" + getPlatformKind().getTypeChar();
     }
 
-    public final LIRKind getLIRKind() {
-        return lirKind;
+    public final ValueKind<?> getValueKind() {
+        return valueKind;
+    }
+
+    public final <K extends ValueKind<K>> K getValueKind(Class<K> cls) {
+        return cls.cast(valueKind);
     }
 
     /**
      * Returns the platform specific kind used to store this value.
      */
     public final PlatformKind getPlatformKind() {
-        return lirKind.getPlatformKind();
+        return valueKind.getPlatformKind();
     }
 
     @Override
     public int hashCode() {
-        return 41 + lirKind.hashCode();
+        return 41 + valueKind.hashCode();
     }
 
     @Override
     public boolean equals(Object obj) {
         if (obj instanceof Value) {
             Value that = (Value) obj;
-            return lirKind.equals(that.lirKind);
+            return valueKind.equals(that.valueKind);
         }
         return false;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/ValueKind.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.meta;
+
+/**
+ * Represents the type of {@link Value values}. This class can be extended by compilers to track
+ * additional information about values.
+ */
+public abstract class ValueKind<K extends ValueKind<K>> {
+
+    private enum IllegalKind implements PlatformKind {
+        ILLEGAL;
+
+        private final EnumKey<IllegalKind> key = new EnumKey<>(this);
+
+        public Key getKey() {
+            return key;
+        }
+
+        public int getSizeInBytes() {
+            return 0;
+        }
+
+        public int getVectorLength() {
+            return 0;
+        }
+
+        public char getTypeChar() {
+            return '-';
+        }
+    }
+
+    private static class IllegalValueKind extends ValueKind<IllegalValueKind> {
+
+        IllegalValueKind() {
+            super(IllegalKind.ILLEGAL);
+        }
+
+        @Override
+        public IllegalValueKind changeType(PlatformKind newPlatformKind) {
+            return this;
+        }
+    }
+
+    /**
+     * The non-type.
+     */
+    public static final ValueKind<?> Illegal = new IllegalValueKind();
+
+    private final PlatformKind platformKind;
+
+    public ValueKind(PlatformKind platformKind) {
+        this.platformKind = platformKind;
+    }
+
+    public final PlatformKind getPlatformKind() {
+        return platformKind;
+    }
+
+    /**
+     * Create a new {@link ValueKind} with a different {@link PlatformKind}. Subclasses must
+     * override this to preserve the additional information added by the compiler.
+     */
+    public abstract K changeType(PlatformKind newPlatformKind);
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/package-info.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/package-info.java	Fri May 20 18:05:09 2016 +0300
@@ -22,8 +22,8 @@
  */
 
 /**
- * Package that defines the interface between a runtime and a Java application that wants to access meta information. The runtime
- * provides an implementation of the {@link jdk.vm.ci.meta.MetaAccessProvider} interface.
+ * Package that defines the interface between a runtime and a Java application that wants to access
+ * meta information. The runtime provides an implementation of the
+ * {@link jdk.vm.ci.meta.MetaAccessProvider} interface.
  */
 package jdk.vm.ci.meta;
-
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.vm.ci.runtime;
-
-/**
- * Factory for a JVMCI compiler.
- */
-public interface JVMCICompilerFactory {
-
-    /**
-     * Get the name of this compiler.
-     */
-    String getCompilerName();
-
-    /**
-     * Create a new instance of the {@link JVMCICompiler}.
-     */
-    JVMCICompiler createCompiler(JVMCIRuntime runtime);
-
-    /**
-     * In a tiered system it might be advantageous for startup to keep the JVMCI compiler from
-     * compiling itself so provide a hook to request that certain packages are compiled only by an
-     * optimizing first tier. The prefixes should class or package names using / as the separator,
-     * i.e. jdk/vm/ci for instance.
-     *
-     * @return 0 or more Strings identifying packages that should by compiled by the first tier
-     *         only.
-     */
-    default String[] getTrivialPrefixes() {
-        return null;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.runtime.services;
+
+import jdk.vm.ci.runtime.JVMCICompiler;
+import jdk.vm.ci.runtime.JVMCIRuntime;
+import jdk.vm.ci.services.JVMCIPermission;
+
+/**
+ * Service-provider class for creating JVMCI compilers.
+ */
+public abstract class JVMCICompilerFactory {
+
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new JVMCIPermission());
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    private JVMCICompilerFactory(Void ignore) {
+    }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @throws SecurityException if a security manager has been installed and it denies
+     *             {@link JVMCIPermission}
+     */
+    protected JVMCICompilerFactory() {
+        this(checkPermission());
+    }
+
+    /**
+     * Get the name of this compiler. The name is used by JVMCI to determine which factory to use.
+     */
+    public abstract String getCompilerName();
+
+    /**
+     * Notifies this object that it has been selected to {@linkplain #createCompiler(JVMCIRuntime)
+     * create} a compiler and it should now perform any heavy weight initialization that it deferred
+     * during construction.
+     */
+    public void onSelection() {
+    }
+
+    /**
+     * Create a new instance of a {@link JVMCICompiler}.
+     */
+    public abstract JVMCICompiler createCompiler(JVMCIRuntime runtime);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIPermission.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.vm.ci.services;
+
+import java.security.BasicPermission;
+
+/**
+ * This class represents the permission to access JVMCI services.
+ */
+public class JVMCIPermission extends BasicPermission {
+
+    private static final long serialVersionUID = 6346818963934448226L;
+
+    public JVMCIPermission() {
+        super("jvmci");
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,7 @@
  */
 package jdk.vm.ci.services;
 
+import java.lang.reflect.Module;
 import java.util.Formatter;
 import java.util.Iterator;
 import java.util.ServiceConfigurationError;
@@ -36,10 +37,51 @@
     }
 
     /**
+     * Performs any required security checks and dynamic reconfiguration to allow the module of a
+     * given class to access the classes in the JVMCI module.
+     *
+     * Note: This API uses {@link Class} instead of {@link Module} to provide backwards
+     * compatibility for JVMCI clients compiled against a JDK release earlier than 9.
+     *
+     * @param requestor a class requesting access to the JVMCI module for its module
+     * @throws SecurityException if a security manager is present and it denies
+     *             {@link JVMCIPermission}
+     */
+    public static void exportJVMCITo(Class<?> requestor) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new JVMCIPermission());
+        }
+        Module jvmci = Services.class.getModule();
+        Module requestorModule = requestor.getModule();
+        if (jvmci != requestorModule) {
+            for (String pkg : jvmci.getPackages()) {
+                // Export all JVMCI packages dynamically instead
+                // of requiring a long list of -XaddExports
+                // options on the JVM command line.
+                if (!jvmci.isExported(pkg, requestorModule)) {
+                    jvmci.addExports(pkg, requestorModule);
+                }
+            }
+        }
+    }
+
+    /**
      * Gets an {@link Iterable} of the JVMCI providers available for a given service.
+     *
+     * @throws SecurityException if a security manager is present and it denies
+     *             {@link JVMCIPermission}
      */
     public static <S> Iterable<S> load(Class<S> service) {
-        return ServiceLoader.load(service);
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new JVMCIPermission());
+        }
+        Module jvmci = Services.class.getModule();
+        jvmci.addUses(service);
+
+        // Restrict JVMCI clients to be on the class path or module path
+        return ServiceLoader.load(service, ClassLoader.getSystemClassLoader());
     }
 
     /**
@@ -48,9 +90,18 @@
      * @param service the service whose provider is being requested
      * @param required specifies if an {@link InternalError} should be thrown if no provider of
      *            {@code service} is available
+     * @throws SecurityException if a security manager is present and it denies
+     *             {@link JVMCIPermission}
      */
     public static <S> S loadSingle(Class<S> service, boolean required) {
-        Iterable<S> providers = ServiceLoader.load(service);
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new JVMCIPermission());
+        }
+        Module jvmci = Services.class.getModule();
+        jvmci.addUses(service);
+        // Restrict JVMCI clients to be on the class path or module path
+        Iterable<S> providers = ServiceLoader.load(service, ClassLoader.getSystemClassLoader());
         S singleProvider = null;
         try {
             for (Iterator<S> it = providers.iterator(); it.hasNext();) {
--- a/hotspot/src/jdk.vm.ci/share/classes/module-info.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/jdk.vm.ci/share/classes/module-info.java	Fri May 20 18:05:09 2016 +0300
@@ -24,9 +24,13 @@
  */
 
 module jdk.vm.ci {
-    uses jdk.vm.ci.hotspot.HotSpotVMEventListener;
+    exports jdk.vm.ci.services;
+    exports jdk.vm.ci.runtime.services;
+    exports jdk.vm.ci.hotspot.services;
+
+    uses jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
     uses jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
-    uses jdk.vm.ci.runtime.JVMCICompilerFactory;
+    uses jdk.vm.ci.runtime.services.JVMCICompilerFactory;
 
     provides jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory with
         jdk.vm.ci.hotspot.aarch64.AArch64HotSpotJVMCIBackendFactory;
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1925,9 +1925,10 @@
     return false;
   }
 
-  char buf[32];
+  char buf[33];
   int bytes;
-  while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
+  buf[32] = '\0';
+  while ((bytes = ::read(fd, buf, sizeof(buf)-1)) > 0) {
     st->print_raw(buf, bytes);
   }
 
@@ -6045,8 +6046,8 @@
 
     if (core_pattern[0] == '|') {
       written = jio_snprintf(buffer, bufferSize,
-                        "\"%s\" (or dumping to %s/core.%d)",
-                                     &core_pattern[1], p, current_process_id());
+                             "\"%s\" (or dumping to %s/core.%d)",
+                             &core_pattern[1], p, current_process_id());
     } else {
       written = jio_snprintf(buffer, bufferSize, "%s/%s", p, core_pattern);
     }
@@ -6079,20 +6080,20 @@
   char *p = &buf[len];
 
   jio_snprintf(p, buflen-len,
-             "\n\n"
-             "Do you want to debug the problem?\n\n"
-             "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " UINTX_FORMAT " (" INTPTR_FORMAT ")\n"
-             "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
-             "Otherwise, press RETURN to abort...",
-             os::current_process_id(), os::current_process_id(),
-             os::current_thread_id(), os::current_thread_id());
+               "\n\n"
+               "Do you want to debug the problem?\n\n"
+               "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " UINTX_FORMAT " (" INTPTR_FORMAT ")\n"
+               "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
+               "Otherwise, press RETURN to abort...",
+               os::current_process_id(), os::current_process_id(),
+               os::current_thread_id(), os::current_thread_id());
 
   bool yes = os::message_box("Unexpected Error", buf);
 
   if (yes) {
     // yes, user asked VM to launch debugger
-    jio_snprintf(buf, sizeof(buf), "gdb /proc/%d/exe %d",
-                     os::current_process_id(), os::current_process_id());
+    jio_snprintf(buf, sizeof(char)*buflen, "gdb /proc/%d/exe %d",
+                 os::current_process_id(), os::current_process_id());
 
     os::fork_and_exec(buf);
     yes = false;
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp	Fri May 20 18:05:09 2016 +0300
@@ -825,7 +825,7 @@
 
   intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc);
   st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(sp));
-  print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t));
+  print_hex_dump(st, (address)sp, (address)(sp + 8), sizeof(intptr_t));
   st->cr();
 
   // Note: it may be unsafe to inspect memory near pc. For example, pc may
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/StringUtils.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.hotspot.igv.util;
+
+/**
+ *
+ * @author tkrodrig
+ */
+public class StringUtils {
+
+    public static String escapeHTML(String s) {
+        StringBuilder str = null;
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            switch (c) {
+                case '&':
+                case '<':
+                case '>':
+                case '"':
+                case '\'':
+                    if (str == null) {
+                        str = new StringBuilder();
+                        str.append(s, 0, i);
+                    }
+                    switch (c) {
+                        case '&':
+                            str.append("&amp;");
+                            break;
+                        case '<':
+                            str.append("&lt;");
+                            break;
+                        case '>':
+                            str.append("&gt;");
+                            break;
+                        case '"':
+                            str.append("&quot;");
+                            break;
+                        case '\'':
+                            str.append("&apos;");
+                            break;
+                        default:
+                            assert false;
+                    }
+                    break;
+                case '\u0000':
+                case '\u0001':
+                case '\u0002':
+                case '\u0003':
+                case '\u0004':
+                case '\u0005':
+                case '\u0006':
+                case '\u0007':
+                case '\u0008':
+                case '\u000b':
+                case '\u000c':
+                case '\u000e':
+                case '\u000f':
+                case '\u0010':
+                case '\u0011':
+                case '\u0012':
+                case '\u0013':
+                case '\u0014':
+                case '\u0015':
+                case '\u0016':
+                case '\u0017':
+                case '\u0018':
+                case '\u0019':
+                case '\u001a':
+                case '\u001b':
+                case '\u001c':
+                case '\u001d':
+                case '\u001e':
+                case '\u001f':
+                    if (str == null) {
+                        str = new StringBuilder();
+                        str.append(s, 0, i);
+                    }
+                    str.append("'0x").append(Integer.toHexString(c));
+                    break;
+                default:
+                    if (str != null) {
+                        str.append(c);
+                    }
+                    break;
+            }
+        }
+        if (str == null) {
+            return s;
+        } else {
+            return str.toString();
+        }
+    }
+
+}
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1499,7 +1499,8 @@
 // twice, we need to check that the operands are pointer-eequivalent in
 // the DFA during the labeling process.
 Predicate *InstructForm::build_predicate() {
-  char buf[1024], *s=buf;
+  const int buflen = 1024;
+  char buf[buflen], *s=buf;
   Dict names(cmpstr,hashstr,Form::arena);       // Map Names to counts
 
   MatchNode *mnode =
@@ -1508,12 +1509,12 @@
 
   uint first = 1;
   // Start with the predicate supplied in the .ad file.
-  if( _predicate ) {
-    if( first ) first=0;
-    strcpy(s,"("); s += strlen(s);
-    strcpy(s,_predicate->_pred);
+  if (_predicate) {
+    if (first) first = 0;
+    strcpy(s, "("); s += strlen(s);
+    strncpy(s, _predicate->_pred, buflen - strlen(s) - 1);
     s += strlen(s);
-    strcpy(s,")"); s += strlen(s);
+    strcpy(s, ")"); s += strlen(s);
   }
   for( DictI i(&names); i.test(); ++i ) {
     uintptr_t cnt = (uintptr_t)i._value;
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp	Fri May 20 18:05:09 2016 +0300
@@ -5521,7 +5521,8 @@
     }
   }
 
-  if (_block_pos[max_reg] <= interval_to || _block_pos[max_reg + 1] <= interval_to) {
+  if (max_reg != any_reg &&
+      (_block_pos[max_reg] <= interval_to || _block_pos[max_reg + 1] <= interval_to)) {
     *need_split = true;
   }
 
@@ -6497,8 +6498,9 @@
       if (_counters_sum[i] > 0 || _counters_max[i] >= 0) {
         tty->print("%25s: %8d", counter_name(i), _counters_sum[i]);
 
-        if (base_counter(i) != invalid_counter) {
-          tty->print("  (%5.1f%%) ", _counters_sum[i] * 100.0 / _counters_sum[base_counter(i)]);
+        LinearScanStatistic::Counter cntr = base_counter(i);
+        if (cntr != invalid_counter) {
+          tty->print("  (%5.1f%%) ", _counters_sum[i] * 100.0 / _counters_sum[cntr]);
         } else {
           tty->print("           ");
         }
--- a/hotspot/src/share/vm/ci/ciMethodBlocks.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciMethodBlocks.cpp	Fri May 20 18:05:09 2016 +0300
@@ -372,7 +372,7 @@
 
 void ciBlock::dump() {
   tty->print(" [%d .. %d), {", _start_bci, _limit_bci);
-  for (int i = 0; i < 8; i++) {
+  for (int i = 0; i < 7; i++) {
     if ((_flags & (1 << i)) != 0) {
       tty->print(" %s", flagnames[i]);
     }
--- a/hotspot/src/share/vm/ci/ciReplay.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp	Fri May 20 18:05:09 2016 +0300
@@ -823,7 +823,7 @@
         int value = atoi(string_value);
         java_mirror->short_field_put(fd.offset(), value);
       } else if (strcmp(field_signature, "Z") == 0) {
-        int value = atol(string_value);
+        int value = atoi(string_value);
         java_mirror->bool_field_put(fd.offset(), value);
       } else if (strcmp(field_signature, "J") == 0) {
         jlong value;
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1401,9 +1401,11 @@
 
   FieldAllocationType update(bool is_static, BasicType type) {
     FieldAllocationType atype = basic_type_to_atype(is_static, type);
-    // Make sure there is no overflow with injected fields.
-    assert(count[atype] < 0xFFFF, "More than 65535 fields");
-    count[atype]++;
+    if (atype != BAD_ALLOCATION_TYPE) {
+      // Make sure there is no overflow with injected fields.
+      assert(count[atype] < 0xFFFF, "More than 65535 fields");
+      count[atype]++;
+    }
     return atype;
   }
 };
@@ -2002,13 +2004,6 @@
       if (!privileged)              break;  // only allow in privileged code
       return _method_HotSpotIntrinsicCandidate;
     }
-#if INCLUDE_JVMCI
-    case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_vm_ci_hotspot_Stable_signature): {
-      if (_location != _in_field)   break;  // only allow for fields
-      if (!privileged)              break;  // only allow in privileged code
-      return _field_Stable;
-    }
-#endif
     case vmSymbols::VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_Stable_signature): {
       if (_location != _in_field)   break;  // only allow for fields
       if (!privileged)              break;  // only allow in privileged code
@@ -3335,8 +3330,9 @@
         }
       } else if (tag == vmSymbols::tag_bootstrap_methods() &&
                  _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
-        if (parsed_bootstrap_methods_attribute)
+        if (parsed_bootstrap_methods_attribute) {
           classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
+        }
         parsed_bootstrap_methods_attribute = true;
         parse_classfile_bootstrap_methods_attribute(cfs, cp, attribute_length, CHECK);
       } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) {
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1160,10 +1160,10 @@
     while ((index = strchr(name, '/')) != NULL) {
       *index = '.'; // replace '/' with '.' in package name
     }
-    const char* fmt = "Prohibited package name: %s";
-    size_t len = strlen(fmt) + strlen(name);
+    const char* msg_text = "Prohibited package name: ";
+    size_t len = strlen(msg_text) + strlen(name) + 1;
     char* message = NEW_RESOURCE_ARRAY(char, len);
-    jio_snprintf(message, len, fmt, name);
+    jio_snprintf(message, len, "%s%s", msg_text, name);
     Exceptions::_throw_msg(THREAD_AND_LOCATION,
       vmSymbols::java_lang_SecurityException(), message);
   }
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp	Fri May 20 18:05:09 2016 +0300
@@ -358,6 +358,7 @@
   template(nthreads_name,                             "nthreads")                                 \
   template(ngroups_name,                              "ngroups")                                  \
   template(shutdown_method_name,                      "shutdown")                                 \
+  template(bootstrapFinished_method_name,             "bootstrapFinished")                        \
   template(finalize_method_name,                      "finalize")                                 \
   template(reference_lock_name,                       "lock")                                     \
   template(reference_discovered_name,                 "discovered")                               \
--- a/hotspot/src/share/vm/code/debugInfoRec.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/code/debugInfoRec.cpp	Fri May 20 18:05:09 2016 +0300
@@ -37,9 +37,7 @@
   int  _offset; // location in the stream of this scope
   int  _length; // number of bytes in the stream
   int  _hash;   // hash of stream bytes (for quicker reuse)
-#if INCLUDE_JVMCI
   DebugInformationRecorder* _DIR;
-#endif
 
 public:
   int offset() { return _offset; }
@@ -57,9 +55,7 @@
   DIR_Chunk(int offset, int length, DebugInformationRecorder* dir) {
     _offset = offset;
     _length = length;
-#if INCLUDE_JVMCI
     _DIR = dir;
-#endif
     unsigned int hash = 0;
     address p = dir->stream()->buffer() + _offset;
     for (int i = 0; i < length; i++) {
@@ -87,7 +83,6 @@
     return NULL;
   }
 
-#if INCLUDE_JVMCI
   static int compare(DIR_Chunk* const & a, DIR_Chunk* const & b) {
     if (b->_hash > a->_hash) {
       return 1;
@@ -104,7 +99,6 @@
     address buf = a->_DIR->stream()->buffer();
     return memcmp(buf + b->_offset, buf + a->_offset, a->_length);
   }
-#endif
 };
 
 static inline bool compute_recording_non_safepoints() {
@@ -141,9 +135,6 @@
   _oop_recorder = oop_recorder;
 
   _all_chunks    = new GrowableArray<DIR_Chunk*>(300);
-#if !INCLUDE_JVMCI
-  _shared_chunks = new GrowableArray<DIR_Chunk*>(30);
-#endif
   _next_chunk = _next_chunk_limit = NULL;
 
   add_new_pc_offset(PcDesc::lower_offset_limit);  // sentinel record
@@ -265,14 +256,6 @@
 
 
 int DebugInformationRecorder::find_sharable_decode_offset(int stream_offset) {
-#if !INCLUDE_JVMCI
-  // Only pull this trick if non-safepoint recording
-  // is enabled, for now.
-  if (!recording_non_safepoints()) {
-    return serialized_null;
-  }
-#endif // INCLUDE_JVMCI
-
   NOT_PRODUCT(++dir_stats.chunks_queried);
   int stream_length = stream()->position() - stream_offset;
   assert(stream_offset != serialized_null, "should not be null");
@@ -280,7 +263,6 @@
 
   DIR_Chunk* ns = new(this) DIR_Chunk(stream_offset, stream_length, this);
 
-#if INCLUDE_JVMCI
   DIR_Chunk* match = _all_chunks->insert_sorted<DIR_Chunk::compare>(ns);
   if (match != ns) {
     // Found an existing chunk
@@ -292,35 +274,6 @@
     // Inserted this chunk, so nothing to do
     return serialized_null;
   }
-#else // INCLUDE_JVMCI
-  // Look in previously shared scopes first:
-  DIR_Chunk* ms = ns->find_match(_shared_chunks, 0, this);
-  if (ms != NULL) {
-    NOT_PRODUCT(++dir_stats.chunks_reshared);
-    assert(ns+1 == _next_chunk, "");
-    _next_chunk = ns;
-    return ms->offset();
-  }
-
-  // Look in recently encountered scopes next:
-  const int MAX_RECENT = 50;
-  int start_index = _all_chunks->length() - MAX_RECENT;
-  if (start_index < 0)  start_index = 0;
-  ms = ns->find_match(_all_chunks, start_index, this);
-  if (ms != NULL) {
-    NOT_PRODUCT(++dir_stats.chunks_shared);
-    // Searching in _all_chunks is limited to a window,
-    // but searching in _shared_chunks is unlimited.
-    _shared_chunks->append(ms);
-    assert(ns+1 == _next_chunk, "");
-    _next_chunk = ns;
-    return ms->offset();
-  }
-
-  // No match.  Add this guy to the list, in hopes of future shares.
-  _all_chunks->append(ns);
-  return serialized_null;
-#endif // INCLUDE_JVMCI
 }
 
 
--- a/hotspot/src/share/vm/code/debugInfoRec.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/code/debugInfoRec.hpp	Fri May 20 18:05:09 2016 +0300
@@ -167,9 +167,6 @@
 
   // Scopes that have been described so far.
   GrowableArray<DIR_Chunk*>* _all_chunks;
-#if !INCLUDE_JVMCI
-  GrowableArray<DIR_Chunk*>* _shared_chunks;
-#endif
   DIR_Chunk* _next_chunk;
   DIR_Chunk* _next_chunk_limit;
 
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Fri May 20 18:05:09 2016 +0300
@@ -2392,10 +2392,9 @@
 
 // Debugging output for failure
 void CompileBroker::print_last_compile() {
-  if ( _last_compile_level != CompLevel_none &&
-       compiler(_last_compile_level) != NULL &&
-       _last_method_compiled != NULL &&
-       _last_compile_type != no_compile) {
+  if (_last_compile_level != CompLevel_none &&
+      compiler(_last_compile_level) != NULL &&
+      _last_compile_type != no_compile) {
     if (_last_compile_type == osr_compile) {
       tty->print_cr("Last parse:  [osr]%d+++(%d) %s",
                     _osr_compilation_id, _last_compile_level, _last_method_compiled);
--- a/hotspot/src/share/vm/compiler/compileLog.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/compiler/compileLog.cpp	Fri May 20 18:05:09 2016 +0300
@@ -231,7 +231,8 @@
       // Copy any remaining data inside a quote:
       bool saw_slop = false;
       int end_cdata = 0;  // state machine [0..2] watching for too many "]]"
-      while ((nr = read(partial_fd, buf, buflen)) > 0) {
+      while ((nr = read(partial_fd, buf, buflen-1)) > 0) {
+        buf[buflen-1] = '\0';
         if (!saw_slop) {
           file->print_raw_cr("<fragment>");
           file->print_raw_cr("<![CDATA[");
--- a/hotspot/src/share/vm/compiler/compilerDirectives.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/compiler/compilerDirectives.cpp	Fri May 20 18:05:09 2016 +0300
@@ -204,7 +204,7 @@
   compilerdirectives_common_flags(init_defaults_definition)
   compilerdirectives_c2_flags(init_defaults_definition)
   compilerdirectives_c1_flags(init_defaults_definition)
-  memset(_modified, 0, sizeof _modified);
+  memset(_modified, 0, sizeof(_modified));
 
   // Canonicalize DisableIntrinsic to contain only ',' as a separator.
   this->DisableIntrinsicOption = canonicalize_disableintrinsic(DisableIntrinsic);
--- a/hotspot/src/share/vm/compiler/compilerDirectives.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/compiler/compilerDirectives.hpp	Fri May 20 18:05:09 2016 +0300
@@ -127,7 +127,7 @@
     number_of_flags
   } flags;
 
-  bool _modified[number_of_flags];
+  bool _modified[number_of_flags]; // Records what options where set by a directive
 
 #define flag_store_definition(name, type, dvalue, cc_flag) type name##Option;
   compilerdirectives_common_flags(flag_store_definition)
@@ -135,7 +135,7 @@
   compilerdirectives_c1_flags(flag_store_definition)
 
 // Casting to get the same function signature for all setters. Used from parser.
-#define set_function_definition(name, type, dvalue, cc_flag) void set_##name(void* value) { type val = *(type*)value; name##Option = val; _modified[name##Index] = 1; }
+#define set_function_definition(name, type, dvalue, cc_flag) void set_##name(void* value) { type val = *(type*)value; name##Option = val; _modified[name##Index] = true; }
   compilerdirectives_common_flags(set_function_definition)
   compilerdirectives_c2_flags(set_function_definition)
   compilerdirectives_c1_flags(set_function_definition)
@@ -149,7 +149,7 @@
 void print(outputStream* st) {
     print_inline(st);
     st->print("  ");
-#define print_function_definition(name, type, dvalue, cc_flag) print_##type(st, #name, this->name##Option, true);//(bool)_modified[name##Index]);
+#define print_function_definition(name, type, dvalue, cc_flag) print_##type(st, #name, this->name##Option, true);
     compilerdirectives_common_flags(print_function_definition)
     compilerdirectives_c2_flags(print_function_definition)
     compilerdirectives_c1_flags(print_function_definition)
--- a/hotspot/src/share/vm/compiler/directivesParser.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/compiler/directivesParser.cpp	Fri May 20 18:05:09 2016 +0300
@@ -151,8 +151,6 @@
     { "c2",     type_c2,     0, mask(type_directives), NULL, UnknownFlagType },
     { "match",  type_match,  1, mask(type_directives), NULL, UnknownFlagType },
     { "inline", type_inline, 1, mask(type_directives) | mask(type_c1) | mask(type_c2), NULL, UnknownFlagType },
-    { "enable", type_enable, 1, mask(type_directives) | mask(type_c1) | mask(type_c2), NULL, UnknownFlagType },
-    { "preset", type_preset, 0, mask(type_c1) | mask(type_c2), NULL, UnknownFlagType },
 
     // Global flags
     #define common_flag_key(name, type, dvalue, compiler) \
@@ -353,7 +351,7 @@
       if (!set_option_flag(t, v, option_key, current_directive->_c1_store)) {
         return false;
       }
-      if(!set_option_flag(t, v, option_key, current_directive->_c2_store)) {
+      if (!set_option_flag(t, v, option_key, current_directive->_c2_store)) {
         return false;
       }
     } else {
@@ -436,31 +434,6 @@
     }
     break;
 
-  case type_enable:
-    switch (enclosing_key->type) {
-    case type_c1:
-    case type_c2:
-    {
-      if (t != JSON_TRUE && t != JSON_FALSE) {
-        error(VALUE_ERROR, "Key of type %s enclosed in a %s key needs a true or false value", option_key->name, enclosing_key->name);
-        return false;
-      }
-      int val = (t == JSON_TRUE);
-      current_directiveset->set_Enable(&val);
-      break;
-    }
-
-    case type_directives:
-      error(VALUE_ERROR, "Enable keyword not available for generic directive");
-      return false;
-
-    default:
-      error(INTERNAL_ERROR, "Unexpected enclosing type for key %s: %s", option_key->name, enclosing_key->name);
-      ShouldNotReachHere();
-      return false;
-    }
-    break;
-
   default:
     break;
   }
@@ -730,19 +703,6 @@
     DirectivesParser::test(
       "[{c1:{c1:{c1:{c1:{c1:{c1:{c1:{}}}}}}}}]", false);
 
-  DirectivesParser::test(
-    "[" "\n"
-    "  {" "\n"
-    "    c1: true," "\n"
-    "    c2: true," "\n"
-    "    match: true," "\n"
-    "    inline: true," "\n"
-    "    enable: true," "\n"
-    "    c1: {" "\n"
-    "      preset: true," "\n"
-    "    }" "\n"
-    "  }" "\n"
-    "]" "\n", false);
 }
 
 void DirectivesParser_test() {
--- a/hotspot/src/share/vm/compiler/disassembler.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp	Fri May 20 18:05:09 2016 +0300
@@ -99,7 +99,7 @@
     const char* p = strrchr(buf, *os::file_separator());
     if (p != NULL) lib_offset = p - base + 1;
     p = strstr(p ? p : base, "jvm");
-    if (p != NULL)  jvm_offset = p - base;
+    if (p != NULL) jvm_offset = p - base;
   }
 #endif
   // Find the disassembler shared library.
@@ -113,13 +113,13 @@
     strcpy(&buf[jvm_offset], hsdis_library_name);
     strcat(&buf[jvm_offset], os::dll_file_extension());
     _library = os::dll_load(buf, ebuf, sizeof ebuf);
-    if (_library == NULL) {
+    if (_library == NULL && lib_offset >= 0) {
       // 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so
       strcpy(&buf[lib_offset], hsdis_library_name);
       strcat(&buf[lib_offset], os::dll_file_extension());
       _library = os::dll_load(buf, ebuf, sizeof ebuf);
     }
-    if (_library == NULL) {
+    if (_library == NULL && lib_offset > 0) {
       // 3. <home>/jre/lib/<arch>/hsdis-<arch>.so
       buf[lib_offset - 1] = '\0';
       const char* p = strrchr(buf, *os::file_separator());
--- a/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciCodeInstaller.cpp	Fri May 20 18:05:09 2016 +0300
@@ -181,8 +181,8 @@
   /*
    * This method needs to return a raw (untyped) pointer, since the value of a pointer to the base
    * class is in general not equal to the pointer of the subclass. When patching metaspace pointers,
-   * the compiler expects a direct pointer to the subclass (Klass*, Method* or Symbol*), not a
-   * pointer to the base class (Metadata* or MetaspaceObj*).
+   * the compiler expects a direct pointer to the subclass (Klass* or Method*), not a pointer to the
+   * base class (Metadata* or MetaspaceObj*).
    */
   oop obj = HotSpotMetaspaceConstantImpl::metaspaceObject(constant);
   if (obj->is_a(HotSpotResolvedObjectTypeImpl::klass())) {
@@ -197,11 +197,6 @@
     int index = _oop_recorder->find_index(method);
     TRACE_jvmci_3("metadata[%d of %d] = %s", index, _oop_recorder->metadata_count(), method->name()->as_C_string());
     return method;
-  } else if (obj->is_a(HotSpotSymbol::klass())) {
-    Symbol* symbol = (Symbol*) (address) HotSpotSymbol::pointer(obj);
-    assert(!HotSpotMetaspaceConstantImpl::compressed(constant), "unexpected compressed symbol pointer %s @ " INTPTR_FORMAT, symbol->as_C_string(), p2i(symbol));
-    TRACE_jvmci_3("symbol = %s", symbol->as_C_string());
-    return symbol;
   } else {
     JVMCI_ERROR_NULL("unexpected metadata reference for constant of type %s", obj->klass()->signature_name());
   }
@@ -224,9 +219,8 @@
 #endif
 
 Location::Type CodeInstaller::get_oop_type(Handle value) {
-  Handle lirKind = Value::lirKind(value);
-  Handle platformKind = LIRKind::platformKind(lirKind);
-  assert(LIRKind::referenceMask(lirKind) == 1, "unexpected referenceMask");
+  Handle valueKind = Value::valueKind(value);
+  Handle platformKind = ValueKind::platformKind(valueKind);
 
   if (platformKind == word_kind()) {
     return Location::oop;
@@ -501,7 +495,7 @@
     return result;
   }
 
-  _debug_recorder->pcs_size(); // ehm, create the sentinel record
+  _debug_recorder->pcs_size(); // create the sentinel record
 
   assert(_debug_recorder->pcs_length() >= 2, "must be at least 2");
 
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp	Fri May 20 18:05:09 2016 +0300
@@ -39,6 +39,7 @@
 
 JVMCICompiler::JVMCICompiler() : AbstractCompiler(jvmci) {
   _bootstrapping = false;
+  _bootstrap_compilation_request_handled = false;
   _methods_compiled = 0;
   assert(_instance == NULL, "only one instance allowed");
   _instance = this;
@@ -57,7 +58,7 @@
   CompilationPolicy::completed_vm_startup();
 }
 
-void JVMCICompiler::bootstrap() {
+void JVMCICompiler::bootstrap(TRAPS) {
   if (Arguments::mode() == Arguments::_int) {
     // Nothing to do in -Xint mode
     return;
@@ -68,7 +69,6 @@
   FlagSetting ctwOff(CompileTheWorld, false);
 #endif
 
-  JavaThread* THREAD = JavaThread::current();
   _bootstrapping = true;
   ResourceMark rm;
   HandleMark hm;
@@ -97,7 +97,7 @@
     do {
       os::sleep(THREAD, 100, true);
       qsize = CompileBroker::queue_size(CompLevel_full_optimization);
-    } while (first_round && qsize == 0);
+    } while (!_bootstrap_compilation_request_handled && first_round && qsize == 0);
     first_round = false;
     if (PrintBootstrap) {
       while (z < (_methods_compiled / 100)) {
@@ -111,6 +111,7 @@
     tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methods_compiled);
   }
   _bootstrapping = false;
+  JVMCIRuntime::bootstrap_finished(CHECK);
 }
 
 #define CHECK_ABORT THREAD); \
@@ -171,15 +172,15 @@
   } else {
     oop result_object = (oop) result.get_jobject();
     if (result_object != NULL) {
-      oop failure_message = CompilationRequestResult::failureMessage(result_object);
+      oop failure_message = HotSpotCompilationRequestResult::failureMessage(result_object);
       if (failure_message != NULL) {
         const char* failure_reason = java_lang_String::as_utf8_string(failure_message);
-        env->set_failure(failure_reason, CompilationRequestResult::retry(result_object) != 0);
+        env->set_failure(failure_reason, HotSpotCompilationRequestResult::retry(result_object) != 0);
       } else {
         if (env->task()->code() == NULL) {
           env->set_failure("no nmethod produced", true);
         } else {
-          env->task()->set_num_inlined_bytecodes(CompilationRequestResult::inlinedBytecodes(result_object));
+          env->task()->set_num_inlined_bytecodes(HotSpotCompilationRequestResult::inlinedBytecodes(result_object));
           Atomic::inc(&_methods_compiled);
         }
       }
@@ -187,6 +188,18 @@
       assert(false, "JVMCICompiler.compileMethod should always return non-null");
     }
   }
+  if (_bootstrapping) {
+    _bootstrap_compilation_request_handled = true;
+  }
+}
+
+CompLevel JVMCIRuntime::adjust_comp_level(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread) {
+  if (!thread->adjusting_comp_level()) {
+    thread->set_adjusting_comp_level(true);
+    level = adjust_comp_level_inner(method, is_osr, level, thread);
+    thread->set_adjusting_comp_level(false);
+  }
+  return level;
 }
 
 /**
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.hpp	Fri May 20 18:05:09 2016 +0300
@@ -33,6 +33,11 @@
   bool _bootstrapping;
 
   /**
+   * True if we have seen a bootstrap compilation request.
+   */
+  volatile bool _bootstrap_compilation_request_handled;
+
+  /**
    * Number of methods successfully compiled by a call to
    * JVMCICompiler::compile_method().
    */
@@ -68,7 +73,13 @@
   // Initialization
   virtual void initialize();
 
-  void bootstrap();
+  /**
+   * Initialize the compile queue with the methods in java.lang.Object and
+   * then wait until the queue is empty.
+   */
+  void bootstrap(TRAPS);
+
+  bool is_bootstrapping() const { return _bootstrapping; }
 
   // Compilation entry point for methods
   virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci, DirectiveSet* directive);
--- a/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Fri May 20 18:05:09 2016 +0300
@@ -781,13 +781,11 @@
   Handle compiled_code_handle = JNIHandles::resolve(compiled_code);
   Handle metadata_handle = JNIHandles::resolve(metadata);
 
-  HotSpotOopMap::klass()->initialize(thread);
-
   CodeMetadata code_metadata;
   CodeBlob *cb = NULL;
   CodeInstaller installer;
 
-  JVMCIEnv::CodeInstallResult result = installer.gather_metadata(target_handle, compiled_code_handle, code_metadata, CHECK_0); //cb, pc_descs, nr_pc_descs, scopes_descs, scopes_size, reloc_buffer);
+  JVMCIEnv::CodeInstallResult result = installer.gather_metadata(target_handle, compiled_code_handle, code_metadata, CHECK_0);
   if (result != JVMCIEnv::ok) {
     return result;
   }
@@ -1008,11 +1006,6 @@
   nmethod::invalidate_installed_code(installed_code_handle, CHECK);
 C2V_END
 
-C2V_VMENTRY(jobject, readUncompressedOop, (JNIEnv*, jobject, jlong addr))
-  oop ret = oopDesc::load_decode_heap_oop((oop*)(address)addr);
-  return JNIHandles::make_local(THREAD, ret);
-C2V_END
-
 C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv*, jobject))
   typeArrayOop arrayOop = oopFactory::new_longArray(JVMCICounterSize, CHECK_NULL);
   JavaThread::collect_counters(arrayOop);
@@ -1048,11 +1041,6 @@
   return JNIHandles::make_local(THREAD, sym());
 C2V_END
 
-C2V_VMENTRY(jlong, lookupSymbol, (JNIEnv*, jobject, jobject string))
-  Symbol* symbol = java_lang_String::as_symbol_or_null(JNIHandles::resolve(string));
-  return (jlong) symbol;
-C2V_END
-
 bool matches(jobjectArray methods, Method* method) {
   objArrayOop methods_oop = (objArrayOop) JNIHandles::resolve(methods);
 
@@ -1474,13 +1462,11 @@
   {CC "getLocalVariableTableLength",                  CC "(" HS_RESOLVED_METHOD ")I",                                                       FN_PTR(getLocalVariableTableLength)},
   {CC "reprofile",                                    CC "(" HS_RESOLVED_METHOD ")V",                                                       FN_PTR(reprofile)},
   {CC "invalidateInstalledCode",                      CC "(" INSTALLED_CODE ")V",                                                           FN_PTR(invalidateInstalledCode)},
-  {CC "readUncompressedOop",                          CC "(J)" OBJECT,                                                                      FN_PTR(readUncompressedOop)},
   {CC "collectCounters",                              CC "()[J",                                                                            FN_PTR(collectCounters)},
   {CC "allocateCompileId",                            CC "(" HS_RESOLVED_METHOD "I)I",                                                      FN_PTR(allocateCompileId)},
   {CC "isMature",                                     CC "(" METASPACE_METHOD_DATA ")Z",                                                    FN_PTR(isMature)},
   {CC "hasCompiledCodeForOSR",                        CC "(" HS_RESOLVED_METHOD "II)Z",                                                     FN_PTR(hasCompiledCodeForOSR)},
   {CC "getSymbol",                                    CC "(J)" STRING,                                                                      FN_PTR(getSymbol)},
-  {CC "lookupSymbol",                                 CC "(" STRING ")J",                                                                   FN_PTR(lookupSymbol)},
   {CC "getNextStackFrame",                            CC "(" HS_STACK_FRAME_REF "[" RESOLVED_METHOD "I)" HS_STACK_FRAME_REF,                FN_PTR(getNextStackFrame)},
   {CC "materializeVirtualObjects",                    CC "(" HS_STACK_FRAME_REF "Z)V",                                                      FN_PTR(materializeVirtualObjects)},
   {CC "shouldDebugNonSafepoints",                     CC "()Z",                                                                             FN_PTR(shouldDebugNonSafepoints)},
--- a/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciJavaClasses.hpp	Fri May 20 18:05:09 2016 +0300
@@ -33,7 +33,7 @@
   static void compute_offsets(TRAPS);
 };
 
-/* This macro defines the structure of the CompilationResult - classes.
+/* This macro defines the structure of the JVMCI classes accessed from VM code.
  * It will generate classes with accessors similar to javaClasses.hpp, but with specializations for oops, Handles and jni handles.
  *
  * The public interface of these classes will look like this:
@@ -64,9 +64,6 @@
   start_class(HotSpotResolvedJavaMethodImpl)                                                                                                                   \
     long_field(HotSpotResolvedJavaMethodImpl, metaspaceMethod)                                                                                                 \
   end_class                                                                                                                                                    \
-  start_class(HotSpotSymbol)                                                                                                                                   \
-    long_field(HotSpotSymbol, pointer)                                                                                                                         \
-  end_class                                                                                                                                                    \
   start_class(InstalledCode)                                                                                                                                   \
     long_field(InstalledCode, address)                                                                                                                         \
     long_field(InstalledCode, entryPoint)                                                                                                                      \
@@ -165,10 +162,10 @@
   start_class(site_Mark)                                                                                                                                       \
     oop_field(site_Mark, id, "Ljava/lang/Object;")                                                                                                             \
   end_class                                                                                                                                                    \
-  start_class(CompilationRequestResult)                                                                                                                        \
-    oop_field(CompilationRequestResult, failureMessage, "Ljava/lang/String;")                                                                                  \
-    boolean_field(CompilationRequestResult, retry)                                                                                                             \
-    int_field(CompilationRequestResult, inlinedBytecodes)                                                                                                      \
+  start_class(HotSpotCompilationRequestResult)                                                                                                                 \
+    oop_field(HotSpotCompilationRequestResult, failureMessage, "Ljava/lang/String;")                                                                           \
+    boolean_field(HotSpotCompilationRequestResult, retry)                                                                                                      \
+    int_field(HotSpotCompilationRequestResult, inlinedBytecodes)                                                                                               \
   end_class                                                                                                                                                    \
   start_class(DebugInfo)                                                                                                                                       \
     oop_field(DebugInfo, bytecodePosition, "Ljdk/vm/ci/code/BytecodePosition;")                                                                                \
@@ -219,7 +216,7 @@
     boolean_field(HotSpotObjectConstantImpl, compressed)                                                                                                       \
   end_class                                                                                                                                                    \
   start_class(HotSpotMetaspaceConstantImpl)                                                                                                                    \
-    oop_field(HotSpotMetaspaceConstantImpl, metaspaceObject, "Ljdk/vm/ci/hotspot/MetaspaceWrapperObject;")                                            \
+    oop_field(HotSpotMetaspaceConstantImpl, metaspaceObject, "Ljdk/vm/ci/hotspot/MetaspaceWrapperObject;")                                                     \
     boolean_field(HotSpotMetaspaceConstantImpl, compressed)                                                                                                    \
   end_class                                                                                                                                                    \
   start_class(HotSpotSentinelConstant)                                                                                                                         \
@@ -233,12 +230,11 @@
     static_oop_field(JavaKind, Int, "Ljdk/vm/ci/meta/JavaKind;");                                                                                              \
     static_oop_field(JavaKind, Long, "Ljdk/vm/ci/meta/JavaKind;");                                                                                             \
   end_class                                                                                                                                                    \
-  start_class(LIRKind)                                                                                                                                         \
-    oop_field(LIRKind, platformKind, "Ljdk/vm/ci/meta/PlatformKind;")                                                                                          \
-    int_field(LIRKind, referenceMask)                                                                                                                          \
+  start_class(ValueKind)                                                                                                                                       \
+    oop_field(ValueKind, platformKind, "Ljdk/vm/ci/meta/PlatformKind;")                                                                                        \
   end_class                                                                                                                                                    \
   start_class(Value)                                                                                                                                           \
-    oop_field(Value, lirKind, "Ljdk/vm/ci/meta/LIRKind;")                                                                                                      \
+    oop_field(Value, valueKind, "Ljdk/vm/ci/meta/ValueKind;")                                                                                                  \
     static_oop_field(Value, ILLEGAL, "Ljdk/vm/ci/meta/AllocatableValue;");                                                                                     \
   end_class                                                                                                                                                    \
   start_class(RegisterValue)                                                                                                                                   \
@@ -279,24 +275,20 @@
     objArrayOop_field(HotSpotStackFrameReference, locals, "[Ljava/lang/Object;")                                                                               \
     typeArrayOop_field(HotSpotStackFrameReference, localIsVirtual, "[Z")                                                                                       \
   end_class                                                                                                                                                    \
-  start_class(HotSpotMetaData) \
-    typeArrayOop_field(HotSpotMetaData, pcDescBytes, "[B") \
-    typeArrayOop_field(HotSpotMetaData, scopesDescBytes, "[B") \
-    typeArrayOop_field(HotSpotMetaData, relocBytes, "[B") \
-    typeArrayOop_field(HotSpotMetaData, exceptionBytes, "[B") \
-    typeArrayOop_field(HotSpotMetaData, oopMaps, "[B") \
-    objArrayOop_field(HotSpotMetaData, metadata, "[Ljava/lang/String;") \
-  end_class \
-  start_class(HotSpotOopMap) \
-    int_field(HotSpotOopMap, offset) \
-    int_field(HotSpotOopMap, count) \
-    typeArrayOop_field(HotSpotOopMap, data, "[B") \
+  start_class(HotSpotMetaData)                                                                                                                                 \
+    typeArrayOop_field(HotSpotMetaData, pcDescBytes, "[B")                                                                                                     \
+    typeArrayOop_field(HotSpotMetaData, scopesDescBytes, "[B")                                                                                                 \
+    typeArrayOop_field(HotSpotMetaData, relocBytes, "[B")                                                                                                      \
+    typeArrayOop_field(HotSpotMetaData, exceptionBytes, "[B")                                                                                                  \
+    typeArrayOop_field(HotSpotMetaData, oopMaps, "[B")                                                                                                         \
+    objArrayOop_field(HotSpotMetaData, metadata, "[Ljava/lang/String;")                                                                                        \
   end_class                                                                                                                                                    \
   start_class(HotSpotConstantPool)                                                                                                                             \
     long_field(HotSpotConstantPool, metaspaceConstantPool)                                                                                                     \
   end_class                                                                                                                                                    \
   start_class(HotSpotJVMCIRuntime)                                                                                                                             \
     objArrayOop_field(HotSpotJVMCIRuntime, trivialPrefixes, "[Ljava/lang/String;")                                                                             \
+    int_field(HotSpotJVMCIRuntime, compilationLevelAdjustment)                                                                                                 \
   end_class                                                                                                                                                    \
   /* end*/
 
@@ -309,7 +301,7 @@
         assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected, found %s", obj->klass()->external_name());                       \
         assert(offset != 0, "must be valid offset");                                                                                                           \
     }                                                                                                                                                          \
-    static void compute_offsets(TRAPS);                                                                                                                             \
+    static void compute_offsets(TRAPS);                                                                                                                        \
   public:                                                                                                                                                      \
     static InstanceKlass* klass() { return SystemDictionary::name##_klass(); }
 
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.cpp	Fri May 20 18:05:09 2016 +0300
@@ -54,6 +54,7 @@
 bool JVMCIRuntime::_well_known_classes_initialized = false;
 int JVMCIRuntime::_trivial_prefixes_count = 0;
 char** JVMCIRuntime::_trivial_prefixes = NULL;
+JVMCIRuntime::CompLevelAdjustment JVMCIRuntime::_comp_level_adjustment = JVMCIRuntime::none;
 bool JVMCIRuntime::_shutdown_called = false;
 
 BasicType JVMCIRuntime::kindToBasicType(Handle kind, TRAPS) {
@@ -62,15 +63,15 @@
   }
   jchar ch = JavaKind::typeChar(kind);
   switch(ch) {
-    case 'z': return T_BOOLEAN;
-    case 'b': return T_BYTE;
-    case 's': return T_SHORT;
-    case 'c': return T_CHAR;
-    case 'i': return T_INT;
-    case 'f': return T_FLOAT;
-    case 'j': return T_LONG;
-    case 'd': return T_DOUBLE;
-    case 'a': return T_OBJECT;
+    case 'Z': return T_BOOLEAN;
+    case 'B': return T_BYTE;
+    case 'S': return T_SHORT;
+    case 'C': return T_CHAR;
+    case 'I': return T_INT;
+    case 'F': return T_FLOAT;
+    case 'J': return T_LONG;
+    case 'D': return T_DOUBLE;
+    case 'A': return T_OBJECT;
     case '-': return T_ILLEGAL;
     default:
       JVMCI_ERROR_(T_ILLEGAL, "unexpected Kind: %c", ch);
@@ -573,14 +574,14 @@
   } uu;
   uu.l = value;
   switch (typeChar) {
-    case 'z': tty->print(value == 0 ? "false" : "true"); break;
-    case 'b': tty->print("%d", (jbyte) value); break;
-    case 'c': tty->print("%c", (jchar) value); break;
-    case 's': tty->print("%d", (jshort) value); break;
-    case 'i': tty->print("%d", (jint) value); break;
-    case 'f': tty->print("%f", uu.f); break;
-    case 'j': tty->print(JLONG_FORMAT, value); break;
-    case 'd': tty->print("%lf", uu.d); break;
+    case 'Z': tty->print(value == 0 ? "false" : "true"); break;
+    case 'B': tty->print("%d", (jbyte) value); break;
+    case 'C': tty->print("%c", (jchar) value); break;
+    case 'S': tty->print("%d", (jshort) value); break;
+    case 'I': tty->print("%d", (jint) value); break;
+    case 'F': tty->print("%f", uu.f); break;
+    case 'J': tty->print(JLONG_FORMAT, value); break;
+    case 'D': tty->print("%lf", uu.d); break;
     default: assert(false, "unknown typeChar"); break;
   }
   if (newline) {
@@ -666,6 +667,11 @@
       _trivial_prefixes = prefixes;
       _trivial_prefixes_count = trivial_prefixes->length();
     }
+    int adjustment = HotSpotJVMCIRuntime::compilationLevelAdjustment(result);
+    assert(adjustment >= JVMCIRuntime::none &&
+           adjustment <= JVMCIRuntime::by_full_signature,
+           "compilation level adjustment out of bounds");
+    _comp_level_adjustment = (CompLevelAdjustment) adjustment;
     _HotSpotJVMCIRuntime_initialized = true;
     _HotSpotJVMCIRuntime_instance = JNIHandles::make_global(result());
   }
@@ -803,6 +809,73 @@
   }
 }
 
+CompLevel JVMCIRuntime::adjust_comp_level_inner(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread) {
+  JVMCICompiler* compiler = JVMCICompiler::instance(thread);
+  if (compiler != NULL && compiler->is_bootstrapping()) {
+    return level;
+  }
+  if (!is_HotSpotJVMCIRuntime_initialized() || !_comp_level_adjustment) {
+    // JVMCI cannot participate in compilation scheduling until
+    // JVMCI is initialized and indicates it wants to participate.
+    return level;
+  }
+
+#define CHECK_RETURN THREAD); \
+if (HAS_PENDING_EXCEPTION) { \
+  Handle exception(THREAD, PENDING_EXCEPTION); \
+  CLEAR_PENDING_EXCEPTION; \
+\
+  java_lang_Throwable::java_printStackTrace(exception, THREAD); \
+  if (HAS_PENDING_EXCEPTION) { \
+    CLEAR_PENDING_EXCEPTION; \
+  } \
+  return level; \
+} \
+(void)(0
+
+
+  Thread* THREAD = thread;
+  HandleMark hm;
+  Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_RETURN);
+  Handle name;
+  Handle sig;
+  if (_comp_level_adjustment == JVMCIRuntime::by_full_signature) {
+    name = java_lang_String::create_from_symbol(method->name(), CHECK_RETURN);
+    sig = java_lang_String::create_from_symbol(method->signature(), CHECK_RETURN);
+  } else {
+    name = Handle();
+    sig = Handle();
+  }
+
+  JavaValue result(T_INT);
+  JavaCallArguments args;
+  args.push_oop(receiver);
+  args.push_oop(method->method_holder()->java_mirror());
+  args.push_oop(name());
+  args.push_oop(sig());
+  args.push_int(is_osr);
+  args.push_int(level);
+  JavaCalls::call_special(&result, receiver->klass(), vmSymbols::adjustCompilationLevel_name(),
+                          vmSymbols::adjustCompilationLevel_signature(), &args, CHECK_RETURN);
+
+  int comp_level = result.get_jint();
+  if (comp_level < CompLevel_none || comp_level > CompLevel_full_optimization) {
+    assert(false, "compilation level out of bounds");
+    return level;
+  }
+  return (CompLevel) comp_level;
+#undef CHECK_RETURN
+}
+
+void JVMCIRuntime::bootstrap_finished(TRAPS) {
+  HandleMark hm(THREAD);
+  Handle receiver = get_HotSpotJVMCIRuntime(CHECK);
+  JavaValue result(T_VOID);
+  JavaCallArguments args;
+  args.push_oop(receiver);
+  JavaCalls::call_special(&result, receiver->klass(), vmSymbols::bootstrapFinished_method_name(), vmSymbols::void_method_signature(), &args, CHECK);
+}
+
 bool JVMCIRuntime::treat_as_trivial(Method* method) {
   if (_HotSpotJVMCIRuntime_initialized) {
     for (int i = 0; i < _trivial_prefixes_count; i++) {
--- a/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/jvmciRuntime.hpp	Fri May 20 18:05:09 2016 +0300
@@ -66,6 +66,16 @@
 };
 
 class JVMCIRuntime: public AllStatic {
+ public:
+  // Constants describing whether JVMCI wants to be able to adjust the compilation
+  // level selected for a method by the VM compilation policy and if so, based on
+  // what information about the method being schedule for compilation.
+  enum CompLevelAdjustment {
+     none = 0,             // no adjustment
+     by_holder = 1,        // adjust based on declaring class of method
+     by_full_signature = 2 // adjust based on declaring class, name and signature of method
+  };
+
  private:
   static jobject _HotSpotJVMCIRuntime_instance;
   static bool _HotSpotJVMCIRuntime_initialized;
@@ -74,14 +84,11 @@
   static int _trivial_prefixes_count;
   static char** _trivial_prefixes;
 
+  static CompLevelAdjustment _comp_level_adjustment;
+
   static bool _shutdown_called;
 
-  /**
-   * Instantiates a service object, calls its default constructor and returns it.
-   *
-   * @param name the name of a class implementing jdk.vm.ci.service.Service
-   */
-  static Handle create_Service(const char* name, TRAPS);
+  static CompLevel adjust_comp_level_inner(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread);
 
  public:
   static bool is_HotSpotJVMCIRuntime_initialized() {
@@ -120,12 +127,26 @@
 
   static void shutdown(TRAPS);
 
+  static void bootstrap_finished(TRAPS);
+
   static bool shutdown_called() {
     return _shutdown_called;
   }
 
   static bool treat_as_trivial(Method* method);
 
+  /**
+   * Lets JVMCI modify the compilation level currently selected for a method by
+   * the VM compilation policy.
+   *
+   * @param method the method being scheduled for compilation
+   * @param is_osr specifies if the compilation is an OSR compilation
+   * @param level the compilation level currently selected by the VM compilation policy
+   * @param thread the current thread
+   * @return the compilation level to use for the compilation
+   */
+  static CompLevel adjust_comp_level(methodHandle method, bool is_osr, CompLevel level, JavaThread* thread);
+
   static BasicType kindToBasicType(Handle kind, TRAPS);
 
   // The following routines are all called from compiled JVMCI code
--- a/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Fri May 20 18:05:09 2016 +0300
@@ -44,12 +44,11 @@
   do_klass(HotSpotSentinelConstant_klass,                jdk_vm_ci_hotspot_HotSpotSentinelConstant,             Jvmci) \
   do_klass(HotSpotStackFrameReference_klass,             jdk_vm_ci_hotspot_HotSpotStackFrameReference,          Jvmci) \
   do_klass(HotSpotMetaData_klass,                        jdk_vm_ci_hotspot_HotSpotMetaData,                     Jvmci) \
-  do_klass(HotSpotOopMap_klass,                          jdk_vm_ci_hotspot_HotSpotOopMap,                       Jvmci) \
   do_klass(HotSpotConstantPool_klass,                    jdk_vm_ci_hotspot_HotSpotConstantPool,                 Jvmci) \
   do_klass(HotSpotJVMCIMetaAccessContext_klass,          jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext,       Jvmci) \
   do_klass(HotSpotJVMCIRuntime_klass,                    jdk_vm_ci_hotspot_HotSpotJVMCIRuntime,                 Jvmci) \
   do_klass(HotSpotSpeculationLog_klass,                  jdk_vm_ci_hotspot_HotSpotSpeculationLog,               Jvmci) \
-  do_klass(HotSpotSymbol_klass,                          jdk_vm_ci_hotspot_HotSpotSymbol,                       Jvmci) \
+  do_klass(HotSpotCompilationRequestResult_klass,        jdk_vm_ci_hotspot_HotSpotCompilationRequestResult,     Jvmci) \
   do_klass(Assumptions_ConcreteMethod_klass,             jdk_vm_ci_meta_Assumptions_ConcreteMethod,             Jvmci) \
   do_klass(Assumptions_NoFinalizableSubclass_klass,      jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass,      Jvmci) \
   do_klass(Assumptions_ConcreteSubtype_klass,            jdk_vm_ci_meta_Assumptions_ConcreteSubtype,            Jvmci) \
@@ -61,7 +60,6 @@
   do_klass(DebugInfo_klass,                              jdk_vm_ci_code_DebugInfo,                              Jvmci) \
   do_klass(RegisterSaveLayout_klass,                     jdk_vm_ci_code_RegisterSaveLayout,                     Jvmci) \
   do_klass(BytecodeFrame_klass,                          jdk_vm_ci_code_BytecodeFrame,                          Jvmci) \
-  do_klass(CompilationRequestResult_klass,               jdk_vm_ci_code_CompilationRequestResult,               Jvmci) \
   do_klass(InstalledCode_klass,                          jdk_vm_ci_code_InstalledCode,                          Jvmci) \
   do_klass(code_Location_klass,                          jdk_vm_ci_code_Location,                               Jvmci) \
   do_klass(code_Register_klass,                          jdk_vm_ci_code_Register,                               Jvmci) \
@@ -84,7 +82,7 @@
   do_klass(NullConstant_klass,                           jdk_vm_ci_meta_NullConstant,                           Jvmci) \
   do_klass(ExceptionHandler_klass,                       jdk_vm_ci_meta_ExceptionHandler,                       Jvmci) \
   do_klass(JavaKind_klass,                               jdk_vm_ci_meta_JavaKind,                               Jvmci) \
-  do_klass(LIRKind_klass,                                jdk_vm_ci_meta_LIRKind,                                Jvmci) \
+  do_klass(ValueKind_klass,                              jdk_vm_ci_meta_ValueKind,                              Jvmci) \
   do_klass(Value_klass,                                  jdk_vm_ci_meta_Value,                                  Jvmci)
 #endif
 
--- a/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/vmStructs_jvmci.cpp	Fri May 20 18:05:09 2016 +0300
@@ -308,6 +308,10 @@
   declare_preprocessor_constant("FIELDINFO_TAG_SIZE", FIELDINFO_TAG_SIZE) \
   declare_preprocessor_constant("STACK_BIAS", STACK_BIAS)                 \
                                                                           \
+  declare_constant(CompLevel_none)                                        \
+  declare_constant(CompLevel_simple)                                      \
+  declare_constant(CompLevel_limited_profile)                             \
+  declare_constant(CompLevel_full_profile)                                \
   declare_constant(CompLevel_full_optimization)                           \
   declare_constant(HeapWordSize)                                          \
   declare_constant(InvocationEntryBci)                                    \
@@ -464,6 +468,9 @@
   declare_constant(JVMCIEnv::dependencies_invalid)                        \
   declare_constant(JVMCIEnv::cache_full)                                  \
   declare_constant(JVMCIEnv::code_too_large)                              \
+  declare_constant(JVMCIRuntime::none)                                    \
+  declare_constant(JVMCIRuntime::by_holder)                               \
+  declare_constant(JVMCIRuntime::by_full_signature)                       \
                                                                           \
   declare_constant(Klass::_lh_neutral_value)                              \
   declare_constant(Klass::_lh_instance_slow_path_bit)                     \
--- a/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Fri May 20 18:05:09 2016 +0300
@@ -45,19 +45,18 @@
   template(jdk_vm_ci_hotspot_HotSpotSentinelConstant,             "jdk/vm/ci/hotspot/HotSpotSentinelConstant")             \
   template(jdk_vm_ci_hotspot_HotSpotStackFrameReference,          "jdk/vm/ci/hotspot/HotSpotStackFrameReference")          \
   template(jdk_vm_ci_hotspot_HotSpotMetaData,                     "jdk/vm/ci/hotspot/HotSpotMetaData")                     \
-  template(jdk_vm_ci_hotspot_HotSpotOopMap,                       "jdk/vm/ci/hotspot/HotSpotOopMap")                       \
   template(jdk_vm_ci_hotspot_HotSpotConstantPool,                 "jdk/vm/ci/hotspot/HotSpotConstantPool")                 \
   template(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext,       "jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext")       \
   template(jdk_vm_ci_hotspot_HotSpotJVMCIRuntime,                 "jdk/vm/ci/hotspot/HotSpotJVMCIRuntime")                 \
   template(jdk_vm_ci_hotspot_HotSpotSpeculationLog,               "jdk/vm/ci/hotspot/HotSpotSpeculationLog")               \
-  template(jdk_vm_ci_hotspot_HotSpotSymbol,                       "jdk/vm/ci/hotspot/HotSpotSymbol")                       \
+  template(jdk_vm_ci_hotspot_HotSpotCompilationRequestResult,     "jdk/vm/ci/hotspot/HotSpotCompilationRequestResult")     \
   template(jdk_vm_ci_meta_JavaConstant,                           "jdk/vm/ci/meta/JavaConstant")                           \
   template(jdk_vm_ci_meta_PrimitiveConstant,                      "jdk/vm/ci/meta/PrimitiveConstant")                      \
   template(jdk_vm_ci_meta_RawConstant,                            "jdk/vm/ci/meta/RawConstant")                            \
   template(jdk_vm_ci_meta_NullConstant,                           "jdk/vm/ci/meta/NullConstant")                           \
   template(jdk_vm_ci_meta_ExceptionHandler,                       "jdk/vm/ci/meta/ExceptionHandler")                       \
   template(jdk_vm_ci_meta_JavaKind,                               "jdk/vm/ci/meta/JavaKind")                               \
-  template(jdk_vm_ci_meta_LIRKind,                                "jdk/vm/ci/meta/LIRKind")                                \
+  template(jdk_vm_ci_meta_ValueKind,                              "jdk/vm/ci/meta/ValueKind")                              \
   template(jdk_vm_ci_meta_Value,                                  "jdk/vm/ci/meta/Value")                                  \
   template(jdk_vm_ci_meta_Assumptions_ConcreteSubtype,            "jdk/vm/ci/meta/Assumptions$ConcreteSubtype")            \
   template(jdk_vm_ci_meta_Assumptions_LeafType,                   "jdk/vm/ci/meta/Assumptions$LeafType")                   \
@@ -67,7 +66,6 @@
   template(jdk_vm_ci_code_Architecture,                           "jdk/vm/ci/code/Architecture")                           \
   template(jdk_vm_ci_code_BytecodeFrame,                          "jdk/vm/ci/code/BytecodeFrame")                          \
   template(jdk_vm_ci_code_BytecodePosition,                       "jdk/vm/ci/code/BytecodePosition")                       \
-  template(jdk_vm_ci_code_CompilationRequestResult,               "jdk/vm/ci/code/CompilationRequestResult")               \
   template(jdk_vm_ci_code_DebugInfo,                              "jdk/vm/ci/code/DebugInfo")                              \
   template(jdk_vm_ci_code_InstalledCode,                          "jdk/vm/ci/code/InstalledCode")                          \
   template(jdk_vm_ci_code_Location,                               "jdk/vm/ci/code/Location")                               \
@@ -89,13 +87,14 @@
   template(jdk_vm_ci_code_site_Site,                              "jdk/vm/ci/code/site/Site")                              \
   template(jdk_vm_ci_code_site_InfopointReason,                   "jdk/vm/ci/code/site/InfopointReason")                   \
   template(jdk_vm_ci_common_JVMCIError,                           "jdk/vm/ci/common/JVMCIError")                           \
+  template(adjustCompilationLevel_name,                           "adjustCompilationLevel")                                \
+  template(adjustCompilationLevel_signature,                      "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;ZI)I") \
   template(compileMethod_name,                                    "compileMethod")                                         \
-  template(compileMethod_signature,                               "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)Ljdk/vm/ci/code/CompilationRequestResult;") \
+  template(compileMethod_signature,                               "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)Ljdk/vm/ci/hotspot/HotSpotCompilationRequestResult;") \
   template(fromMetaspace_name,                                    "fromMetaspace")                                         \
   template(method_fromMetaspace_signature,                        "(J)Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;")      \
   template(constantPool_fromMetaspace_signature,                  "(J)Ljdk/vm/ci/hotspot/HotSpotConstantPool;")            \
-  template(klass_fromMetaspace_signature,                         "(Ljava/lang/Class;)Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;") \
-  template(jdk_vm_ci_hotspot_Stable_signature,                    "Ljdk/vm/ci/hotspot/Stable;")
+  template(klass_fromMetaspace_signature,                         "(Ljava/lang/Class;)Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;")
 #endif
 
 #endif // SHARE_VM_JVMCI_VMSYMBOLS_JVMCI_HPP
--- a/hotspot/src/share/vm/logging/logTagSet.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/logging/logTagSet.cpp	Fri May 20 18:05:09 2016 +0300
@@ -114,12 +114,18 @@
   va_copy(saved_args, args);
   size_t prefix_len = _write_prefix(buf, sizeof(buf));
   // Check that string fits in buffer; resize buffer if necessary
-  int ret = os::log_vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
+  int ret;
+  if (prefix_len < vwrite_buffer_size) {
+    ret = os::log_vsnprintf(buf + prefix_len, sizeof(buf) - prefix_len, fmt, args);
+  } else {
+    // Buffer too small. Just call printf to find out the length for realloc below.
+    ret = os::log_vsnprintf(buf, sizeof(buf), fmt, args);
+  }
   assert(ret >= 0, "Log message buffer issue");
   if ((size_t)ret >= sizeof(buf)) {
     size_t newbuf_len = prefix_len + ret + 1;
     char* newbuf = NEW_C_HEAP_ARRAY(char, newbuf_len, mtLogging);
-    memcpy(newbuf, buf, prefix_len);
+    prefix_len = _write_prefix(newbuf, newbuf_len);
     ret = os::log_vsnprintf(newbuf + prefix_len, newbuf_len - prefix_len, fmt, saved_args);
     assert(ret >= 0, "Log message buffer issue");
     log(level, newbuf);
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Fri May 20 18:05:09 2016 +0300
@@ -80,7 +80,8 @@
 
 ConstantPool::ConstantPool(Array<u1>* tags) :
   _tags(tags),
-  _length(tags->length()) {
+  _length(tags->length()),
+  _flags(0) {
 
     assert(_tags != NULL, "invariant");
     assert(tags->length() == _length, "invariant");
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1678,8 +1678,14 @@
   CellTypeState actual[5];
   assert(poplen < 5, "this must be less than length of actual vector");
 
-  // pop all arguments
-  for(int i = 0; i < poplen; i++) actual[i] = pop();
+  // Pop all arguments.
+  for (int i = 0; i < poplen; i++) {
+    actual[i] = pop();
+  }
+  // Field _state is uninitialized when calling push.
+  for (int i = poplen; i < 5; i++) {
+    actual[i] = CellTypeState::uninit;
+  }
 
   // put them back
   char push_ch = *out++;
--- a/hotspot/src/share/vm/opto/block.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/opto/block.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1430,7 +1430,7 @@
       if (n->num_preds() != 1) break;
 
       i++;
-      assert(n = _cfg.get_block(i), "expecting next block");
+      assert(n == _cfg.get_block(i), "expecting next block");
       tr->append(n);
       uf->map(n->_pre_order, tr->id());
       traces[n->_pre_order] = NULL;
--- a/hotspot/src/share/vm/opto/callnode.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Fri May 20 18:05:09 2016 +0300
@@ -256,6 +256,7 @@
 JVMState::JVMState(ciMethod* method, JVMState* caller) :
   _method(method) {
   assert(method != NULL, "must be valid call site");
+  _bci = InvocationEntryBci;
   _reexecute = Reexecute_Undefined;
   debug_only(_bci = -99);  // random garbage value
   debug_only(_map = (SafePointNode*)-1);
--- a/hotspot/src/share/vm/opto/escape.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/opto/escape.cpp	Fri May 20 18:05:09 2016 +0300
@@ -721,7 +721,8 @@
         break;
       }
 #endif
-      if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
+      if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN ||
+          opcode == Op_CompareAndExchangeN || opcode == Op_CompareAndExchangeP) {
         add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
       }
       if (adr_type->isa_oopptr() ||
--- a/hotspot/src/share/vm/opto/graphKit.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1079,7 +1079,7 @@
   case Bytecodes::_freturn:
   case Bytecodes::_dreturn:
   case Bytecodes::_areturn:
-    assert(rsize = -depth, "");
+    assert(rsize == -depth, "");
     inputs = rsize;
     break;
 
--- a/hotspot/src/share/vm/opto/library_call.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Fri May 20 18:05:09 2016 +0300
@@ -2697,6 +2697,7 @@
       assert(sig->type_at(0)->basic_type() == T_OBJECT, "get and set base is object");
       assert(sig->type_at(1)->basic_type() == T_LONG, "get and set offset is long");
       assert(sig->type_at(2)->basic_type() == type, "get and set must take expected type as new value/delta");
+      assert(access_kind == Volatile, "mo is not passed to intrinsic nodes in current implementation");
 #endif // ASSERT
         break;
       }
@@ -2822,8 +2823,14 @@
     case Acquire:
       break;
     case Release:
+      insert_mem_bar(Op_MemBarRelease);
+      break;
     case Volatile:
-      insert_mem_bar(Op_MemBarRelease);
+      if (support_IRIW_for_not_multiple_copy_atomic_cpu) {
+        insert_mem_bar(Op_MemBarVolatile);
+      } else {
+        insert_mem_bar(Op_MemBarRelease);
+      }
       break;
     default:
       ShouldNotReachHere();
@@ -3035,6 +3042,7 @@
     case Acquire:
     case Volatile:
       insert_mem_bar(Op_MemBarAcquire);
+      // !support_IRIW_for_not_multiple_copy_atomic_cpu handled in platform code
       break;
     default:
       ShouldNotReachHere();
--- a/hotspot/src/share/vm/opto/macroArrayCopy.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/opto/macroArrayCopy.cpp	Fri May 20 18:05:09 2016 +0300
@@ -503,46 +503,50 @@
     // further to JVM_ArrayCopy on the first per-oop check that fails.
     // (Actually, we don't move raw bits only; the GC requires card marks.)
 
-    // Get the klass* for both src and dest
-    Node* src_klass  = ac->in(ArrayCopyNode::SrcKlass);
-    Node* dest_klass = ac->in(ArrayCopyNode::DestKlass);
+    // We don't need a subtype check for validated copies and Object[].clone()
+    bool skip_subtype_check = ac->is_arraycopy_validated() || ac->is_copyof_validated() ||
+                              ac->is_copyofrange_validated() || ac->is_cloneoop();
+    if (!skip_subtype_check) {
+      // Get the klass* for both src and dest
+      Node* src_klass  = ac->in(ArrayCopyNode::SrcKlass);
+      Node* dest_klass = ac->in(ArrayCopyNode::DestKlass);
 
-    assert(src_klass != NULL && dest_klass != NULL, "should have klasses");
+      assert(src_klass != NULL && dest_klass != NULL, "should have klasses");
 
-    // Generate the subtype check.
-    // This might fold up statically, or then again it might not.
-    //
-    // Non-static example:  Copying List<String>.elements to a new String[].
-    // The backing store for a List<String> is always an Object[],
-    // but its elements are always type String, if the generic types
-    // are correct at the source level.
-    //
-    // Test S[] against D[], not S against D, because (probably)
-    // the secondary supertype cache is less busy for S[] than S.
-    // This usually only matters when D is an interface.
-    Node* not_subtype_ctrl = (ac->is_arraycopy_validated() || ac->is_copyof_validated() || ac->is_copyofrange_validated()) ? top() :
-      Phase::gen_subtype_check(src_klass, dest_klass, ctrl, mem, &_igvn);
-    // Plug failing path into checked_oop_disjoint_arraycopy
-    if (not_subtype_ctrl != top()) {
-      Node* local_ctrl = not_subtype_ctrl;
-      MergeMemNode* local_mem = MergeMemNode::make(mem);
-      transform_later(local_mem);
+      // Generate the subtype check.
+      // This might fold up statically, or then again it might not.
+      //
+      // Non-static example:  Copying List<String>.elements to a new String[].
+      // The backing store for a List<String> is always an Object[],
+      // but its elements are always type String, if the generic types
+      // are correct at the source level.
+      //
+      // Test S[] against D[], not S against D, because (probably)
+      // the secondary supertype cache is less busy for S[] than S.
+      // This usually only matters when D is an interface.
+      Node* not_subtype_ctrl = Phase::gen_subtype_check(src_klass, dest_klass, ctrl, mem, &_igvn);
+      // Plug failing path into checked_oop_disjoint_arraycopy
+      if (not_subtype_ctrl != top()) {
+        Node* local_ctrl = not_subtype_ctrl;
+        MergeMemNode* local_mem = MergeMemNode::make(mem);
+        transform_later(local_mem);
 
-      // (At this point we can assume disjoint_bases, since types differ.)
-      int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());
-      Node* p1 = basic_plus_adr(dest_klass, ek_offset);
-      Node* n1 = LoadKlassNode::make(_igvn, NULL, C->immutable_memory(), p1, TypeRawPtr::BOTTOM);
-      Node* dest_elem_klass = transform_later(n1);
-      Node* cv = generate_checkcast_arraycopy(&local_ctrl, &local_mem,
-                                              adr_type,
-                                              dest_elem_klass,
-                                              src, src_offset, dest, dest_offset,
-                                              ConvI2X(copy_length), dest_uninitialized);
-      if (cv == NULL)  cv = intcon(-1);  // failure (no stub available)
-      checked_control = local_ctrl;
-      checked_i_o     = *io;
-      checked_mem     = local_mem->memory_at(alias_idx);
-      checked_value   = cv;
+        // (At this point we can assume disjoint_bases, since types differ.)
+        int ek_offset = in_bytes(ObjArrayKlass::element_klass_offset());
+        Node* p1 = basic_plus_adr(dest_klass, ek_offset);
+        Node* n1 = LoadKlassNode::make(_igvn, NULL, C->immutable_memory(), p1, TypeRawPtr::BOTTOM);
+        Node* dest_elem_klass = transform_later(n1);
+        Node* cv = generate_checkcast_arraycopy(&local_ctrl, &local_mem,
+                                                adr_type,
+                                                dest_elem_klass,
+                                                src, src_offset, dest, dest_offset,
+                                                ConvI2X(copy_length), dest_uninitialized);
+        if (cv == NULL)  cv = intcon(-1);  // failure (no stub available)
+        checked_control = local_ctrl;
+        checked_i_o     = *io;
+        checked_mem     = local_mem->memory_at(alias_idx);
+        checked_value   = cv;
+      }
     }
     // At this point we know we do not need type checks on oop stores.
 
--- a/hotspot/src/share/vm/opto/matcher.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Fri May 20 18:05:09 2016 +0300
@@ -659,11 +659,14 @@
   uint reth_edge_cnt = TypeFunc::Parms+1;
   RegMask *reth_rms  = init_input_masks( reth_edge_cnt + soe_cnt, _return_addr_mask, c_frame_ptr_mask );
   // Rethrow takes exception oop only, but in the argument 0 slot.
-  reth_rms[TypeFunc::Parms] = mreg2regmask[find_receiver(false)];
+  OptoReg::Name reg = find_receiver(false);
+  if (reg >= 0) {
+    reth_rms[TypeFunc::Parms] = mreg2regmask[reg];
 #ifdef _LP64
-  // Need two slots for ptrs in 64-bit land
-  reth_rms[TypeFunc::Parms].Insert(OptoReg::add(OptoReg::Name(find_receiver(false)),1));
+    // Need two slots for ptrs in 64-bit land
+    reth_rms[TypeFunc::Parms].Insert(OptoReg::add(OptoReg::Name(reg), 1));
 #endif
+  }
 
   // Input RegMask array shared by all TailCalls
   uint tail_call_edge_cnt = TypeFunc::Parms+2;
--- a/hotspot/src/share/vm/opto/memnode.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Fri May 20 18:05:09 2016 +0300
@@ -502,7 +502,7 @@
       if (ac->is_clonebasic()) {
         intptr_t offset;
         AllocateNode* alloc = AllocateNode::Ideal_allocation(ac->in(ArrayCopyNode::Dest), phase, offset);
-        assert(alloc != NULL && alloc->initialization()->is_complete_with_arraycopy(), "broken allocation");
+        assert(alloc != NULL && (!ReduceBulkZeroing || alloc->initialization()->is_complete_with_arraycopy()), "broken allocation");
         if (alloc == ld_alloc) {
           return ac;
         }
--- a/hotspot/src/share/vm/prims/jni.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp	Fri May 20 18:05:09 2016 +0300
@@ -3988,7 +3988,11 @@
         if (BootstrapJVMCI) {
           JavaThread* THREAD = thread;
           JVMCICompiler* compiler = JVMCICompiler::instance(CATCH);
-          compiler->bootstrap();
+          compiler->bootstrap(THREAD);
+          if (HAS_PENDING_EXCEPTION) {
+            HandleMark hm;
+            vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
+          }
         }
       }
     }
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp	Fri May 20 18:05:09 2016 +0300
@@ -27,6 +27,9 @@
 #include "compiler/compileTask.hpp"
 #include "runtime/advancedThresholdPolicy.hpp"
 #include "runtime/simpleThresholdPolicy.inline.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 
 #ifdef TIERED
 // Print an event.
@@ -453,7 +456,7 @@
 }
 
 // Determine if a method should be compiled with a normal entry point at a different level.
-CompLevel AdvancedThresholdPolicy::call_event(Method* method, CompLevel cur_level) {
+CompLevel AdvancedThresholdPolicy::call_event(Method* method, CompLevel cur_level, JavaThread * thread) {
   CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(),
                              common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true));
   CompLevel next_level = common(&AdvancedThresholdPolicy::call_predicate, method, cur_level);
@@ -470,11 +473,16 @@
   } else {
     next_level = MAX2(osr_level, next_level);
   }
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler) {
+    next_level = JVMCIRuntime::adjust_comp_level(method, false, next_level, thread);
+  }
+#endif
   return next_level;
 }
 
 // Determine if we should do an OSR compilation of a given method.
-CompLevel AdvancedThresholdPolicy::loop_event(Method* method, CompLevel cur_level) {
+CompLevel AdvancedThresholdPolicy::loop_event(Method* method, CompLevel cur_level, JavaThread * thread) {
   CompLevel next_level = common(&AdvancedThresholdPolicy::loop_predicate, method, cur_level, true);
   if (cur_level == CompLevel_none) {
     // If there is a live OSR method that means that we deopted to the interpreter
@@ -484,6 +492,11 @@
       return osr_level;
     }
   }
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler) {
+    next_level = JVMCIRuntime::adjust_comp_level(method, true, next_level, thread);
+  }
+#endif
   return next_level;
 }
 
@@ -501,7 +514,7 @@
     create_mdo(mh, thread);
   }
   if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
-    CompLevel next_level = call_event(mh(), level);
+    CompLevel next_level = call_event(mh(), level, thread);
     if (next_level != level) {
       compile(mh, InvocationEntryBci, next_level, thread);
     }
@@ -521,7 +534,7 @@
   }
 
   if (is_compilation_enabled()) {
-    CompLevel next_osr_level = loop_event(imh(), level);
+    CompLevel next_osr_level = loop_event(imh(), level, thread);
     CompLevel max_osr_level = (CompLevel)imh->highest_osr_comp_level();
     // At the very least compile the OSR version
     if (!CompileBroker::compilation_is_in_queue(imh) && (next_osr_level != level)) {
@@ -534,7 +547,7 @@
     if (mh() != imh()) { // If there is an enclosing method
       guarantee(nm != NULL, "Should have nmethod here");
       cur_level = comp_level(mh());
-      next_level = call_event(mh(), cur_level);
+      next_level = call_event(mh(), cur_level, thread);
 
       if (max_osr_level == CompLevel_full_optimization) {
         // The inlinee OSRed to full opt, we need to modify the enclosing method to avoid deopts
@@ -569,7 +582,7 @@
       }
     } else {
       cur_level = comp_level(imh());
-      next_level = call_event(imh(), cur_level);
+      next_level = call_event(imh(), cur_level, thread);
       if (!CompileBroker::compilation_is_in_queue(imh) && (next_level != cur_level)) {
         compile(imh, InvocationEntryBci, next_level, thread);
       }
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.hpp	Fri May 20 18:05:09 2016 +0300
@@ -174,10 +174,10 @@
   // Transition functions.
   // call_event determines if a method should be compiled at a different
   // level with a regular invocation entry.
-  CompLevel call_event(Method* method, CompLevel cur_level);
+  CompLevel call_event(Method* method, CompLevel cur_level, JavaThread * thread);
   // loop_event checks if a method should be OSR compiled at a different
   // level.
-  CompLevel loop_event(Method* method, CompLevel cur_level);
+  CompLevel loop_event(Method* method, CompLevel cur_level, JavaThread * thread);
   // Has a method been long around?
   // We don't remove old methods from the compile queue even if they have
   // very low activity (see select_task()).
--- a/hotspot/src/share/vm/runtime/relocator.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/runtime/relocator.cpp	Fri May 20 18:05:09 2016 +0300
@@ -612,8 +612,8 @@
   // In case we have shrunken a tableswitch/lookupswitch statement, we store the last
   // bytes that get overwritten. We have to copy the bytes after the change_jumps method
   // has been called, since it is likely to update last offset in a tableswitch/lookupswitch
-  if (delta < 0) {
-    assert(delta>=-3, "we cannot overwrite more than 3 bytes");
+  assert(delta >= -3, "We cannot overwrite more than 3 bytes.");
+  if (delta < 0 && delta >= -3) {
     memcpy(_overwrite, addr_at(bci + ilen + delta), -delta);
   }
 
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp	Fri May 20 18:05:09 2016 +0300
@@ -29,6 +29,9 @@
 #include "runtime/simpleThresholdPolicy.hpp"
 #include "runtime/simpleThresholdPolicy.inline.hpp"
 #include "code/scopeDesc.hpp"
+#if INCLUDE_JVMCI
+#include "jvmci/jvmciRuntime.hpp"
+#endif
 
 
 void SimpleThresholdPolicy::print_counters(const char* prefix, methodHandle mh) {
@@ -354,7 +357,7 @@
 }
 
 // Determine if a method should be compiled with a normal entry point at a different level.
-CompLevel SimpleThresholdPolicy::call_event(Method* method,  CompLevel cur_level) {
+CompLevel SimpleThresholdPolicy::call_event(Method* method,  CompLevel cur_level, JavaThread* thread) {
   CompLevel osr_level = MIN2((CompLevel) method->highest_osr_comp_level(),
                              common(&SimpleThresholdPolicy::loop_predicate, method, cur_level));
   CompLevel next_level = common(&SimpleThresholdPolicy::call_predicate, method, cur_level);
@@ -371,12 +374,16 @@
   } else {
     next_level = MAX2(osr_level, next_level);
   }
-
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler) {
+    next_level = JVMCIRuntime::adjust_comp_level(method, false, next_level, thread);
+  }
+#endif
   return next_level;
 }
 
 // Determine if we should do an OSR compilation of a given method.
-CompLevel SimpleThresholdPolicy::loop_event(Method* method, CompLevel cur_level) {
+CompLevel SimpleThresholdPolicy::loop_event(Method* method, CompLevel cur_level, JavaThread* thread) {
   CompLevel next_level = common(&SimpleThresholdPolicy::loop_predicate, method, cur_level);
   if (cur_level == CompLevel_none) {
     // If there is a live OSR method that means that we deopted to the interpreter
@@ -386,6 +393,11 @@
       return osr_level;
     }
   }
+#if INCLUDE_JVMCI
+  if (UseJVMCICompiler) {
+    next_level = JVMCIRuntime::adjust_comp_level(method, true, next_level, thread);
+  }
+#endif
   return next_level;
 }
 
@@ -394,7 +406,7 @@
 void SimpleThresholdPolicy::method_invocation_event(const methodHandle& mh, const methodHandle& imh,
                                               CompLevel level, CompiledMethod* nm, JavaThread* thread) {
   if (is_compilation_enabled() && !CompileBroker::compilation_is_in_queue(mh)) {
-    CompLevel next_level = call_event(mh(), level);
+    CompLevel next_level = call_event(mh(), level, thread);
     if (next_level != level) {
       compile(mh, InvocationEntryBci, next_level, thread);
     }
@@ -410,8 +422,8 @@
     // Use loop event as an opportunity to also check there's been
     // enough calls.
     CompLevel cur_level = comp_level(mh());
-    CompLevel next_level = call_event(mh(), cur_level);
-    CompLevel next_osr_level = loop_event(mh(), level);
+    CompLevel next_level = call_event(mh(), cur_level, thread);
+    CompLevel next_osr_level = loop_event(mh(), level, thread);
 
     next_level = MAX2(next_level,
                       next_osr_level < CompLevel_full_optimization ? next_osr_level : cur_level);
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.hpp	Fri May 20 18:05:09 2016 +0300
@@ -51,10 +51,10 @@
   // Transition functions.
   // call_event determines if a method should be compiled at a different
   // level with a regular invocation entry.
-  CompLevel call_event(Method* method, CompLevel cur_level);
+  CompLevel call_event(Method* method, CompLevel cur_level, JavaThread* thread);
   // loop_event checks if a method should be OSR compiled at a different
   // level.
-  CompLevel loop_event(Method* method, CompLevel cur_level);
+  CompLevel loop_event(Method* method, CompLevel cur_level, JavaThread* thread);
   void print_counters(const char* prefix, methodHandle mh);
 protected:
   int c1_count() const     { return _c1_count; }
--- a/hotspot/src/share/vm/runtime/thread.cpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Fri May 20 18:05:09 2016 +0300
@@ -1450,6 +1450,7 @@
   _pending_deoptimization = -1;
   _pending_failed_speculation = NULL;
   _pending_transfer_to_interpreter = false;
+  _adjusting_comp_level = false;
   _jvmci._alternate_call_target = NULL;
   assert(_jvmci._implicit_exception_pc == NULL, "must be");
   if (JVMCICounterSize > 0) {
--- a/hotspot/src/share/vm/runtime/thread.hpp	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Fri May 20 18:05:09 2016 +0300
@@ -933,6 +933,9 @@
   // Specifies if the DeoptReason for the last uncommon trap was Reason_transfer_to_interpreter
   bool      _pending_transfer_to_interpreter;
 
+  // Guard for re-entrant call to JVMCIRuntime::adjust_comp_level
+  bool      _adjusting_comp_level;
+
   // An object that JVMCI compiled code can use to further describe and
   // uniquely identify the  speculative optimization guarded by the uncommon trap
   oop       _pending_failed_speculation;
@@ -1321,6 +1324,8 @@
 #if INCLUDE_JVMCI
   int  pending_deoptimization() const             { return _pending_deoptimization; }
   oop  pending_failed_speculation() const         { return _pending_failed_speculation; }
+  bool adjusting_comp_level() const               { return _adjusting_comp_level; }
+  void set_adjusting_comp_level(bool b)           { _adjusting_comp_level = b; }
   bool has_pending_monitorenter() const           { return _pending_monitorenter; }
   void set_pending_monitorenter(bool b)           { _pending_monitorenter = b; }
   void set_pending_deoptimization(int reason)     { _pending_deoptimization = reason; }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestObjectArrayClone.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8155643
+ * @summary Test Object.clone() intrinsic if ReduceInitialCardMarks is disabled.
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:CompileOnly=TestObjectArrayClone.test -XX:-ReduceInitialCardMarks TestObjectArrayClone
+ */
+public class TestObjectArrayClone {
+
+    public static TestObjectArrayClone[] test(TestObjectArrayClone[] arr) {
+        return arr.clone();
+    }
+
+    public static void main(String[] args) {
+        test(new TestObjectArrayClone[42]);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/arraycopy/TestReduceBulkZeroingDisabled.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8155241
+ * @summary Test arraycopy elimination with ReduceBulkZeroing disabled.
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:-ReduceBulkZeroing TestReduceBulkZeroingDisabled
+ */
+public class TestReduceBulkZeroingDisabled {
+
+    static public void main(String[] args) {
+        System.out.println("Passed");
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/intrinsics/string/TestStringIntrinsicRangeChecks.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8155608
+ * @summary Verifies that string intrinsics throw array out of bounds exceptions.
+ * @library /compiler/patches /testlibrary /test/lib /
+ * @build java.base/java.lang.Helper
+ * @build compiler.intrinsics.string.TestStringIntrinsicRangeChecks
+ * @run main compiler.intrinsics.string.TestStringIntrinsicRangeChecks
+ */
+package compiler.intrinsics.string;
+
+import java.lang.Helper;
+import java.lang.reflect.*;
+
+public class TestStringIntrinsicRangeChecks {
+    // Prepare test arrays
+    private static int SIZE = 16;
+    private static byte[] byteArray = new byte[SIZE];
+    private static char[] charArray = new char[SIZE];
+
+    public static void check(Method m, boolean shouldThrow, Object... args) throws Exception {
+        // Prepare error message
+        String message = m.getName() + "(";
+        for (int i = 0; i < args.length; ++i) {
+            message += args[i];
+            message += (i+1 < args.length) ? ", " : ")";
+        }
+
+        try {
+            m.invoke(null, args);
+        } catch (InvocationTargetException e) {
+            // Get actual exception
+            Throwable t = e.getTargetException();
+            if (!shouldThrow) {
+                throw new RuntimeException("Unexpected exception thrown for " + message, e);
+            }
+            if (t instanceof StringIndexOutOfBoundsException ||
+                t instanceof ArrayIndexOutOfBoundsException) {
+                // Expected exception. Make sure that the exception was not thrown in UTF16.putChar/getChar
+                // because the corresponding intrinsics are unchecked and the Java code should do all the checks.
+                StackTraceElement[] stack = t.getStackTrace();
+                if (stack.length != 0) {
+                    String methodName = stack[0].getMethodName();
+                    if (methodName.equals("putChar") || methodName.equals("getChar")) {
+                        throw new RuntimeException("Exception thrown in " + methodName + " for " + message, t);
+                    }
+                }
+            }
+            return;
+        }
+        if (shouldThrow) {
+            throw new RuntimeException("No exception thrown for " + message);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        // Get intrinsified String API methods
+        Method compressByte = Helper.class.getMethod("compressByte", byte[].class, int.class, int.class, int.class, int.class);
+        Method compressChar = Helper.class.getMethod("compressChar", char[].class, int.class, int.class, int.class, int.class);
+        Method inflateByte  = Helper.class.getMethod("inflateByte",  byte[].class, int.class, int.class, int.class, int.class);
+        Method inflateChar  = Helper.class.getMethod("inflateChar",  byte[].class, int.class, int.class, int.class, int.class);
+        Method toBytes      = Helper.class.getMethod("toBytes",      char[].class, int.class, int.class);
+        Method getChars     = Helper.class.getMethod("getChars",     byte[].class, int.class, int.class, int.class, int.class);
+
+        // Check different combinations of arguments (source/destination offset and length)
+        for (int srcOff = 0; srcOff < SIZE; ++srcOff) {
+            for (int dstOff = 0; dstOff < SIZE; ++dstOff) {
+                for (int len = 0; len < SIZE; ++len) {
+                    // Check for potential overlows in source or destination array
+                    boolean srcOverflow  = (srcOff + len) > SIZE;
+                    boolean srcOverflowB = (2*srcOff + 2*len) > SIZE;
+                    boolean dstOverflow  = (dstOff + len) > SIZE;
+                    boolean dstOverflowB = (2*dstOff + 2*len) > SIZE;
+                    boolean getCharsOver = (srcOff < len) && ((2*(len-1) >= SIZE) || ((dstOff + len - srcOff) > SIZE));
+                    // Check if an exception is thrown and bail out if result is inconsistent with above
+                    // assumptions (for example, an exception was not thrown although an overflow happened).
+                    check(compressByte, srcOverflowB || dstOverflow,  byteArray, srcOff, SIZE, dstOff, len);
+                    check(compressChar, srcOverflow  || dstOverflow,  charArray, srcOff, SIZE, dstOff, len);
+                    check(inflateByte,  srcOverflow  || dstOverflowB, byteArray, srcOff, SIZE, dstOff, len);
+                    check(inflateChar,  srcOverflow  || dstOverflow,  byteArray, srcOff, SIZE, dstOff, len);
+                    check(toBytes,      srcOverflow,                  charArray, srcOff, len);
+                    check(getChars,     getCharsOver,                 byteArray, srcOff, len, SIZE, dstOff);
+                }
+            }
+        }
+    }
+}
--- a/hotspot/test/compiler/jvmci/common/JVMCIHelpers.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/common/JVMCIHelpers.java	Fri May 20 18:05:09 2016 +0300
@@ -26,10 +26,10 @@
 import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.code.CompilationRequest;
 import jdk.vm.ci.code.CompilationRequestResult;
-import jdk.vm.ci.hotspot.HotSpotVMEventListener;
+import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.runtime.JVMCICompiler;
-import jdk.vm.ci.runtime.JVMCICompilerFactory;
+import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
 import jdk.vm.ci.runtime.JVMCIRuntime;
 
 /*
@@ -37,20 +37,26 @@
  */
 public class JVMCIHelpers {
 
-    public static class EmptyVMEventListener implements HotSpotVMEventListener {
+    public static class EmptyVMEventListener extends HotSpotVMEventListener {
         // just empty, using default interface methods
     }
 
+    public static class EmptyCompilationRequestResult implements CompilationRequestResult {
+        @Override
+        public Object getFailure() {
+            return "no compiler configured";
+        }
+    }
     public static class EmptyHotspotCompiler implements JVMCICompiler {
 
         @Override
         public CompilationRequestResult compileMethod(CompilationRequest request) {
             // do nothing
-            return CompilationRequestResult.failure("no compiler configured", true);
+            return new EmptyCompilationRequestResult();
         }
     }
 
-    public static class EmptyCompilerFactory implements JVMCICompilerFactory {
+    public static class EmptyCompilerFactory extends JVMCICompilerFactory {
 
         @Override
         public String getCompilerName() {
--- a/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/common/patches/jdk.vm.ci/jdk/vm/ci/hotspot/CompilerToVMHelper.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -207,10 +207,6 @@
         return CTVM.getLocalVariableTableStart((HotSpotResolvedJavaMethodImpl)method);
     }
 
-    public static Object readUncompressedOop(long address) {
-        return CTVM.readUncompressedOop(address);
-    }
-
     public static void doNotInlineOrCompile(HotSpotResolvedJavaMethod method) {
         CTVM.doNotInlineOrCompile((HotSpotResolvedJavaMethodImpl)method);
     }
--- a/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.hotspot.HotSpotVMEventListener	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-compiler.jvmci.common.JVMCIHelpers$EmptyVMEventListener
--- a/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.JVMCICompilerFactory	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
--- a/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/compilerToVM/MaterializeVirtualObjectTest.java	Fri May 20 18:05:09 2016 +0300
@@ -33,13 +33,12 @@
  *          jdk.vm.ci/jdk.vm.ci.hotspot
  *          jdk.vm.ci/jdk.vm.ci.code
  *          jdk.vm.ci/jdk.vm.ci.meta
- * @ignore 8139703
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest
  * @build sun.hotspot.WhiteBox
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:.
+ * @run main/othervm -Xmixed -Xbootclasspath/a:.
  *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
  *                   -XX:CompileCommand=exclude,*::check
@@ -47,7 +46,7 @@
  *                   -Xbatch
  *                   -Dcompiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate=false
  *                   compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest
- * @run main/othervm -Xbootclasspath/a:.
+ * @run main/othervm -Xmixed -Xbootclasspath/a:.
  *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
  *                   -XX:CompileCommand=exclude,*::check
@@ -67,24 +66,27 @@
 
 import compiler.jvmci.common.CTVMUtilities;
 import compiler.testlibrary.CompilerUtils;
+import compiler.whitebox.CompilerWhiteBoxTest;
 
 import sun.hotspot.WhiteBox;
 
 public class MaterializeVirtualObjectTest {
-    private static final WhiteBox WB = WhiteBox.getWhiteBox();
+    private static final WhiteBox WB;
     private static final Method METHOD;
     private static final ResolvedJavaMethod RESOLVED_METHOD;
-    private static final boolean INVALIDATE = Boolean.getBoolean(
-            "compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate");
+    private static final boolean INVALIDATE;
 
     static {
+        WB = WhiteBox.getWhiteBox();
         try {
             METHOD = MaterializeVirtualObjectTest.class.getDeclaredMethod(
-                    "testFrame", String.class, boolean.class);
+                    "testFrame", String.class, int.class);
         } catch (NoSuchMethodException e) {
             throw new Error("Can't get executable for test method", e);
         }
         RESOLVED_METHOD = CTVMUtilities.getResolvedMethod(METHOD);
+        INVALIDATE = Boolean.getBoolean(
+            "compiler.jvmci.compilerToVM.MaterializeVirtualObjectTest.invalidate");
     }
 
     public static void main(String[] args) {
@@ -106,26 +108,29 @@
         System.out.println(getName());
         Asserts.assertFalse(WB.isMethodCompiled(METHOD), getName()
                 + " : method unexpectedly compiled");
-        /* need to call testFrame at least once to be able to compile it, so
-           calling with materialize=false, because testFrame is not compiled */
-        testFrame("someString", /* materialize= */ false);
-        WB.enqueueMethodForCompilation(METHOD, 4);
+        /* need to trigger compilation by multiple method invocations
+           in order to have method profile data to be gathered */
+        boolean isTiered = WB.getBooleanVMFlag("TieredCompilation");
+        int COMPILE_THRESHOLD = isTiered ? CompilerWhiteBoxTest.THRESHOLD
+                : CompilerWhiteBoxTest.THRESHOLD * 2;
+        for (int i = 0; i < COMPILE_THRESHOLD; i++) {
+            testFrame("someString", i);
+        }
         Asserts.assertTrue(WB.isMethodCompiled(METHOD), getName()
                 + "Method unexpectedly not compiled");
-        // calling with materialize=true to materialize compiled testFrame
-        testFrame("someString", /* materialize= */ true);
+        testFrame("someString", CompilerWhiteBoxTest.THRESHOLD);
     }
 
-    private void testFrame(String str, boolean materialize) {
+    private void testFrame(String str, int iteration) {
         Helper helper = new Helper(str);
-        check(materialize);
+        check(iteration);
         Asserts.assertTrue((helper.string != null) && (this != null)
                 && (helper != null), getName() + " : some locals are null");
     }
 
-    private void check(boolean materialize) {
+    private void check(int iteration) {
         // Materialize virtual objects on last invocation
-        if (materialize) {
+        if (iteration == CompilerWhiteBoxTest.THRESHOLD) {
             HotSpotStackFrameReference hsFrame = CompilerToVMHelper
                     .getNextStackFrame(/* topmost frame */ null,
                             new ResolvedJavaMethod[]{
--- a/hotspot/test/compiler/jvmci/compilerToVM/ReadUncompressedOopTest.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8136421
- * @ignore 8155216
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
- * @library / /testlibrary /test/lib/
- * @library ../common/patches
- * @modules java.base/jdk.internal.misc
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
- * @build compiler.jvmci.compilerToVM.ReadUncompressedOopTest
- * @build sun.hotspot.WhiteBox
- * @run main ClassFileInstaller
- *     sun.hotspot.WhiteBox
- *     sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:.
- *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- *                   -XX:-UseCompressedOops
- *                   compiler.jvmci.compilerToVM.ReadUncompressedOopTest
- * @run main/othervm -Xbootclasspath/a:.
- *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
- *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- *                   -XX:+UseCompressedOops
- *                   compiler.jvmci.compilerToVM.ReadUncompressedOopTest
- */
-
-package compiler.jvmci.compilerToVM;
-
-import jdk.vm.ci.hotspot.CompilerToVMHelper;
-import jdk.test.lib.Asserts;
-import jdk.test.lib.Utils;
-import sun.hotspot.WhiteBox;
-import jdk.internal.misc.Unsafe;
-
-import java.lang.reflect.Field;
-
-public class ReadUncompressedOopTest {
-
-    public static void main(String args[])  {
-        new ReadUncompressedOopTest().runTest();
-    }
-
-    private void runTest()  {
-        long ptr = getPtr();
-        System.out.printf("calling readUncompressedOop(0x%x)%n", ptr);
-        Asserts.assertEQ(getClass(),
-                CompilerToVMHelper.readUncompressedOop(ptr),
-                String.format("unexpected class returned for 0x%x", ptr));
-    }
-
-    private static final Unsafe UNSAFE = Utils.getUnsafe();
-    private static final WhiteBox WB = WhiteBox.getWhiteBox();
-    private static final Class<?> CLASS = ReadUncompressedOopTest.class;
-    private static final long PTR = WB.getObjectAddress(CLASS);
-
-    private static long getPtr() {
-        Field field;
-        try {
-            field = CLASS.getDeclaredField("PTR");
-        } catch (NoSuchFieldException nsfe) {
-            throw new Error("TESTBUG : " + nsfe, nsfe);
-        }
-        Object base = UNSAFE.staticFieldBase(field);
-        return WB.getObjectAddress(base) + UNSAFE.staticFieldOffset(field);
-    }
-}
-
--- a/hotspot/test/compiler/jvmci/errors/TestInvalidDebugInfo.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/errors/TestInvalidDebugInfo.java	Fri May 20 18:05:09 2016 +0300
@@ -36,6 +36,7 @@
 
 package compiler.jvmci.errors;
 
+import jdk.vm.ci.code.Architecture;
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.code.DebugInfo;
 import jdk.vm.ci.code.Location;
@@ -53,9 +54,10 @@
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaValue;
-import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.PlatformKind;
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.meta.Value;
+import jdk.vm.ci.meta.ValueKind;
 
 import org.junit.Test;
 
@@ -67,6 +69,22 @@
     private static class UnknownJavaValue implements JavaValue {
     }
 
+    private static class TestValueKind extends ValueKind<TestValueKind> {
+
+        TestValueKind(Architecture arch, JavaKind kind) {
+            this(arch.getPlatformKind(kind));
+        }
+
+        TestValueKind(PlatformKind kind) {
+            super(kind);
+        }
+
+        @Override
+        public TestValueKind changeType(PlatformKind kind) {
+            return new TestValueKind(kind);
+        }
+    }
+
     private void test(JavaValue[] values, JavaKind[] slotKinds, int locals, int stack, int locks) {
         test(null, values, slotKinds, locals, stack, locks);
     }
@@ -146,7 +164,7 @@
 
     @Test(expected = JVMCIError.class)
     public void testUnexpectedTypeOnStack() {
-        LIRKind kind = codeCache.getTarget().getLIRKind(JavaKind.Int);
+        ValueKind<?> kind = new TestValueKind(codeCache.getTarget().arch, JavaKind.Int);
         StackSlot value = StackSlot.get(kind, 8, false);
         test(new JavaValue[]{value}, new JavaKind[]{JavaKind.Illegal}, 1, 0, 0);
     }
--- a/hotspot/test/compiler/jvmci/events/JvmciCreateMetaAccessContextTest.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8136421
- * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
- * @library / /testlibrary
- * @library ../common/patches
- * @modules java.base/jdk.internal.misc
- * @modules jdk.vm.ci/jdk.vm.ci.hotspot
- *          jdk.vm.ci/jdk.vm.ci.code
- *          jdk.vm.ci/jdk.vm.ci.meta
- *          jdk.vm.ci/jdk.vm.ci.runtime
- * @build jdk.vm.ci/jdk.vm.ci.hotspot.MetaAccessWrapper
- * @build compiler.jvmci.common.JVMCIHelpers
- *     compiler.jvmci.events.JvmciCreateMetaAccessContextTest
- * @run main jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
- * @run main jdk.test.lib.FileInstaller
- *     ./JvmciCreateMetaAccessContextTest.config
- *     ./META-INF/services/jdk.vm.ci.hotspot.HotSpotVMEventListener
- * @run main ClassFileInstaller
- *     compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
- *     compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
- *     compiler.jvmci.events.JvmciCreateMetaAccessContextTest
- *     jdk.test.lib.Asserts
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- *     -Xbootclasspath/a:.
- *     -Dcompiler.jvmci.events.JvmciCreateMetaAccessContextTest.providenull=true
- *     compiler.jvmci.events.JvmciCreateMetaAccessContextTest
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
- *     -Xbootclasspath/a:.
- *     -Dcompiler.jvmci.events.JvmciCreateMetaAccessContextTest.providenull=false
- *     compiler.jvmci.events.JvmciCreateMetaAccessContextTest
- */
-
-package compiler.jvmci.events;
-
-import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-import jdk.vm.ci.hotspot.HotSpotVMEventListener;
-import jdk.vm.ci.hotspot.MetaAccessWrapper;
-import jdk.vm.ci.meta.JVMCIMetaAccessContext;
-import jdk.test.lib.Asserts;
-
-public class JvmciCreateMetaAccessContextTest
-        implements HotSpotVMEventListener {
-    private static final boolean PROVIDE_NULL_CONTEXT = Boolean.getBoolean(
-            "compiler.jvmci.events.JvmciCreateMetaAccessContextTest"
-                    + ".providenull");
-    private static volatile int createMetaAccessContextCount = 0;
-    private static volatile String errorMessage = "";
-
-    public static void main(String args[]) {
-        if (createMetaAccessContextCount != 0) {
-            throw new Error("Unexpected createMetaAccessContextevents count"
-                    + " at test start");
-        }
-        JVMCIMetaAccessContext context;
-        context = HotSpotJVMCIRuntime.runtime().getMetaAccessContext();
-        Asserts.assertNotNull(context,
-                "JVMCIMetaAccessContext is null after 1st request");
-        Asserts.assertEQ(createMetaAccessContextCount, 1,
-                "Unexpected createMetaAccessContext events count after 1st"
-                        + " JVMCI runtime request");
-        context = HotSpotJVMCIRuntime.runtime().getMetaAccessContext();
-        Asserts.assertNotNull(context,
-                "JVMCIMetaAccessContext is null after 2nd request");
-        Asserts.assertEQ(createMetaAccessContextCount, 1,
-                "Unexpected createMetaAccessContext events count after 2nd"
-                        + " JVMCI runtime request");
-        Asserts.assertTrue(errorMessage.isEmpty(), errorMessage);
-        if (PROVIDE_NULL_CONTEXT) {
-            Asserts.assertFalse(context instanceof MetaAccessWrapper,
-                    "Got unexpected context: " + context.getClass());
-        } else {
-            Asserts.assertTrue(context instanceof MetaAccessWrapper,
-                    "Got unexpected context: " + context.getClass());
-        }
-    }
-
-    @Override
-    public JVMCIMetaAccessContext createMetaAccessContext(HotSpotJVMCIRuntime
-            hotSpotJVMCIRuntime) {
-        createMetaAccessContextCount++;
-        if (hotSpotJVMCIRuntime == null) {
-            errorMessage += " HotSpotJVMCIRuntime is null.";
-        }
-        if (PROVIDE_NULL_CONTEXT) {
-            return null;
-        }
-        return new MetaAccessWrapper();
-    }
-}
--- a/hotspot/test/compiler/jvmci/events/JvmciShutdownEventListener.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventListener.java	Fri May 20 18:05:09 2016 +0300
@@ -24,9 +24,9 @@
 package compiler.jvmci.events;
 
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-import jdk.vm.ci.hotspot.HotSpotVMEventListener;
+import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
 
-public class JvmciShutdownEventListener implements HotSpotVMEventListener {
+public class JvmciShutdownEventListener extends HotSpotVMEventListener {
     public static final String MESSAGE = "Shutdown notified";
     public static final String GOT_INTERNAL_ERROR = "Got internal error";
 
--- a/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java	Fri May 20 18:05:09 2016 +0300
@@ -36,7 +36,7 @@
  *        compiler.jvmci.events.JvmciShutdownEventTest
  * @run main jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
  * @run main jdk.test.lib.FileInstaller ./JvmciShutdownEventTest.config
- *     ./META-INF/services/jdk.vm.ci.hotspot.HotSpotVMEventListener
+ *     ./META-INF/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener
  * @run main ClassFileInstaller
  *     compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
  *     compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/DataPatchTest.java	Fri May 20 18:05:09 2016 +0300
@@ -42,7 +42,6 @@
 import jdk.vm.ci.code.site.DataSectionReference;
 import jdk.vm.ci.hotspot.HotSpotConstant;
 import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
-import jdk.vm.ci.hotspot.HotSpotSymbol;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
 import jdk.vm.ci.meta.ResolvedJavaType;
 
@@ -158,32 +157,4 @@
             asm.emitPointerRet(ret);
         });
     }
-
-    public static long getConstSymbol(HotSpotMetaAccessProvider meta) {
-        HotSpotSymbol symbol = meta.lookupSymbol("java/lang/Object");
-        return symbol.getMetaspacePointer();
-    }
-
-    private void testSymbol(TestCompiler compiler) {
-        test(compiler, getMethod("getConstSymbol", HotSpotMetaAccessProvider.class), (HotSpotMetaAccessProvider) metaAccess);
-    }
-
-    @Test
-    public void testInlineSymbol() {
-        testSymbol(asm -> {
-            HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object");
-            Register ret = asm.emitLoadPointer((HotSpotConstant) symbol.asConstant());
-            asm.emitPointerRet(ret);
-        });
-    }
-
-    @Test
-    public void testSymbolInDataSection() {
-        testSymbol(asm -> {
-            HotSpotSymbol symbol = ((HotSpotMetaAccessProvider) metaAccess).lookupSymbol("java/lang/Object");
-            DataSectionReference ref = asm.emitDataItem((HotSpotConstant) symbol.asConstant());
-            Register ret = asm.emitLoadPointer(ref);
-            asm.emitPointerRet(ret);
-        });
-    }
 }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/SimpleDebugInfoTest.java	Fri May 20 18:05:09 2016 +0300
@@ -82,7 +82,7 @@
     public void testRegInt() {
         DebugInfoCompiler compiler = (asm, values) -> {
             Register reg = asm.emitLoadInt(42);
-            values[0] = reg.asValue(target.getLIRKind(JavaKind.Int));
+            values[0] = reg.asValue(asm.getValueKind(JavaKind.Int));
             return null;
         };
         testIntOnStack(compiler);
@@ -131,7 +131,7 @@
     public void testRegFloat() {
         DebugInfoCompiler compiler = (asm, values) -> {
             Register reg = asm.emitLoadFloat(42.0f);
-            values[0] = reg.asValue(target.getLIRKind(JavaKind.Float));
+            values[0] = reg.asValue(asm.getValueKind(JavaKind.Float));
             return null;
         };
         testFloatOnStack(compiler);
@@ -181,7 +181,7 @@
     public void testRegLong() {
         DebugInfoCompiler compiler = (asm, values) -> {
             Register reg = asm.emitLoadLong(42);
-            values[0] = reg.asValue(target.getLIRKind(JavaKind.Long));
+            values[0] = reg.asValue(asm.getValueKind(JavaKind.Long));
             values[1] = Value.ILLEGAL;
             return null;
         };
@@ -234,7 +234,7 @@
         ResolvedJavaType type = metaAccess.lookupJavaType(objectOnStack());
         DebugInfoCompiler compiler = (asm, values) -> {
             Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.asJavaClass(type));
-            values[0] = reg.asValue(target.getLIRKind(JavaKind.Object));
+            values[0] = reg.asValue(asm.getValueKind(JavaKind.Object));
             return null;
         };
         testObjectOnStack(compiler);
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/TestAssembler.java	Fri May 20 18:05:09 2016 +0300
@@ -48,9 +48,10 @@
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
 import jdk.vm.ci.meta.Assumptions.Assumption;
 import jdk.vm.ci.meta.InvokeTarget;
-import jdk.vm.ci.meta.LIRKind;
+import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.PlatformKind;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ValueKind;
 import jdk.vm.ci.meta.VMConstant;
 
 /**
@@ -173,7 +174,7 @@
      */
     public abstract void emitTrap(DebugInfo info);
 
-    public final LIRKind narrowOopKind;
+    public final ValueKind<?> narrowOopKind;
 
     protected final Buffer code;
     protected final Buffer data;
@@ -191,8 +192,20 @@
 
     private StackSlot deoptRescue;
 
+    private static class TestValueKind extends ValueKind<TestValueKind> {
+
+        TestValueKind(PlatformKind kind) {
+            super(kind);
+        }
+
+        @Override
+        public TestValueKind changeType(PlatformKind kind) {
+            return new TestValueKind(kind);
+        }
+    }
+
     protected TestAssembler(CodeCacheProvider codeCache, int initialFrameSize, int stackAlignment, PlatformKind narrowOopKind, Register... registers) {
-        this.narrowOopKind = LIRKind.reference(narrowOopKind);
+        this.narrowOopKind = new TestValueKind(narrowOopKind);
 
         this.code = new Buffer();
         this.data = new Buffer();
@@ -209,12 +222,16 @@
         this.curStackSlot = initialFrameSize;
     }
 
+    public ValueKind<?> getValueKind(JavaKind kind) {
+        return new TestValueKind(codeCache.getTarget().arch.getPlatformKind(kind));
+    }
+
     protected Register newRegister() {
         return registers[nextRegister++];
     }
 
-    protected StackSlot newStackSlot(LIRKind kind) {
-        curStackSlot += kind.getPlatformKind().getSizeInBytes();
+    protected StackSlot newStackSlot(PlatformKind kind) {
+        curStackSlot += kind.getSizeInBytes();
         if (curStackSlot > frameSize) {
             int newFrameSize = curStackSlot;
             if (newFrameSize % stackAlignment != 0) {
@@ -223,7 +240,7 @@
             emitGrowStack(newFrameSize - frameSize);
             frameSize = newFrameSize;
         }
-        return StackSlot.get(kind, -curStackSlot, true);
+        return StackSlot.get(new TestValueKind(kind), -curStackSlot, true);
     }
 
     protected void setDeoptRescueSlot(StackSlot deoptRescue) {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/VirtualObjectDebugInfoTest.java	Fri May 20 18:05:09 2016 +0300
@@ -136,7 +136,7 @@
             } else if (template.arrayField[i] instanceof String) {
                 String value = (String) template.arrayField[i];
                 Register reg = asm.emitLoadPointer((HotSpotConstant) constantReflection.forString(value));
-                arrayContent[i] = reg.asValue(target.getLIRKind(JavaKind.Object));
+                arrayContent[i] = reg.asValue(asm.getValueKind(JavaKind.Object));
             } else {
                 Assert.fail("unexpected value");
             }
@@ -159,7 +159,7 @@
                     break;
                 case Float: // template.floatField
                     Register fReg = asm.emitLoadFloat(template.floatField);
-                    retContent[i] = fReg.asValue(target.getLIRKind(JavaKind.Float));
+                    retContent[i] = fReg.asValue(asm.getValueKind(JavaKind.Float));
                     break;
                 case Object: // template.arrayField
                     retContent[i] = array;
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/amd64/AMD64TestAssembler.java	Fri May 20 18:05:09 2016 +0300
@@ -37,7 +37,6 @@
 import jdk.vm.ci.hotspot.HotSpotForeignCallTarget;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
 import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LIRKind;
 import jdk.vm.ci.meta.VMConstant;
 
 public class AMD64TestAssembler extends TestAssembler {
@@ -64,7 +63,7 @@
         emitFatNop();
         code.emitByte(0x50 | AMD64.rbp.encoding);  // PUSH rbp
         emitMove(true, AMD64.rbp, AMD64.rsp);      // MOV rbp, rsp
-        setDeoptRescueSlot(newStackSlot(LIRKind.value(AMD64Kind.QWORD)));
+        setDeoptRescueSlot(newStackSlot(AMD64Kind.QWORD));
     }
 
     @Override
@@ -193,7 +192,7 @@
 
     @Override
     public StackSlot emitIntToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.DWORD));
+        StackSlot ret = newStackSlot(AMD64Kind.DWORD);
         // MOV r/m32,r32
         emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
         return ret;
@@ -201,7 +200,7 @@
 
     @Override
     public StackSlot emitLongToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.QWORD));
+        StackSlot ret = newStackSlot(AMD64Kind.QWORD);
         // MOV r/m64,r64
         emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
         return ret;
@@ -209,7 +208,7 @@
 
     @Override
     public StackSlot emitFloatToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(AMD64Kind.SINGLE));
+        StackSlot ret = newStackSlot(AMD64Kind.SINGLE);
         emitREX(false, a.encoding, 0, 0);
         code.emitByte(0xF3);
         code.emitByte(0x0F);
@@ -221,7 +220,7 @@
 
     @Override
     public StackSlot emitPointerToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.reference(AMD64Kind.QWORD));
+        StackSlot ret = newStackSlot(AMD64Kind.QWORD);
         // MOV r/m64,r64
         emitModRMMemory(true, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
         return ret;
@@ -229,7 +228,7 @@
 
     @Override
     public StackSlot emitNarrowPointerToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.reference(AMD64Kind.DWORD));
+        StackSlot ret = newStackSlot(AMD64Kind.DWORD);
         // MOV r/m32,r32
         emitModRMMemory(false, 0x89, a.encoding, AMD64.rbp.encoding, ret.getRawOffset() + 16);
         return ret;
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.code.test/src/jdk/vm/ci/code/test/sparc/SPARCTestAssembler.java	Fri May 20 18:05:09 2016 +0300
@@ -37,7 +37,6 @@
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
 import jdk.vm.ci.hotspot.HotSpotVMConfig;
 import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.LIRKind;
 import jdk.vm.ci.meta.VMConstant;
 import jdk.vm.ci.sparc.SPARC;
 import jdk.vm.ci.sparc.SPARCKind;
@@ -70,7 +69,7 @@
     public void emitPrologue() {
         // SAVE sp, -128, sp
         emitOp3(0b10, SPARC.sp, 0b111100, SPARC.sp, -SPARC.REGISTER_SAFE_AREA_SIZE);
-        setDeoptRescueSlot(newStackSlot(LIRKind.value(SPARCKind.XWORD)));
+        setDeoptRescueSlot(newStackSlot(SPARCKind.XWORD));
     }
 
     @Override
@@ -194,7 +193,7 @@
 
     @Override
     public StackSlot emitIntToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.WORD));
+        StackSlot ret = newStackSlot(SPARCKind.WORD);
         // STW a, [fp+offset]
         emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
         return ret;
@@ -202,7 +201,7 @@
 
     @Override
     public StackSlot emitLongToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.XWORD));
+        StackSlot ret = newStackSlot(SPARCKind.XWORD);
         // STX a, [fp+offset]
         emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
         return ret;
@@ -210,7 +209,7 @@
 
     @Override
     public StackSlot emitFloatToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.value(SPARCKind.SINGLE));
+        StackSlot ret = newStackSlot(SPARCKind.SINGLE);
         // STF a, [fp+offset]
         emitOp3(0b11, a, 0b100100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
         return ret;
@@ -218,7 +217,7 @@
 
     @Override
     public StackSlot emitPointerToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.XWORD));
+        StackSlot ret = newStackSlot(SPARCKind.XWORD);
         // STX a, [fp+offset]
         emitOp3(0b11, a, 0b001110, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
         return ret;
@@ -226,7 +225,7 @@
 
     @Override
     public StackSlot emitNarrowPointerToStack(Register a) {
-        StackSlot ret = newStackSlot(LIRKind.reference(SPARCKind.WORD));
+        StackSlot ret = newStackSlot(SPARCKind.WORD);
         // STW a, [fp+offset]
         emitOp3(0b11, a, 0b000100, SPARC.fp, ret.getRawOffset() + SPARC.STACK_BIAS);
         return ret;
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/AsJavaTypeDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/AsJavaTypeDataProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -34,26 +34,26 @@
     @DataProvider(name = "asJavaTypeDataProvider")
     public static Object[][] asJavaTypeDataProvider() {
         return new Object[][]{
-                {CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.class),
-                        "jdk.vm.ci.hotspot.test.DummyClass"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(boolean.class), "boolean"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(byte.class), "byte"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(short.class), "short"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(char.class), "char"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(int.class), "int"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(long.class), "long"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(float.class), "float"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(double.class), "double"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(Object.class), "java.lang.Object"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(boolean[].class), "boolean[]"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(boolean[][].class), "boolean[][]"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(Object[].class), "java.lang.Object[]"},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(Object[][].class), "java.lang.Object[][]"},
-                {JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField), null},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), null},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE), null},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues), null},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues), null},
-                {JavaConstant.NULL_POINTER, null}, {null, null}};
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.class),
+                                        "jdk.vm.ci.hotspot.test.DummyClass"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(boolean.class), "boolean"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(byte.class), "byte"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(short.class), "short"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(char.class), "char"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(int.class), "int"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(long.class), "long"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(float.class), "float"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(double.class), "double"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(Object.class), "java.lang.Object"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(boolean[].class), "boolean[]"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(boolean[][].class), "boolean[][]"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(Object[].class), "java.lang.Object[]"},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(Object[][].class), "java.lang.Object[][]"},
+                        {JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField), null},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), null},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE), null},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues), null},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues), null},
+                        {JavaConstant.NULL_POINTER, null}, {null, null}};
     }
 }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/BoxPrimitiveDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/BoxPrimitiveDataProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -37,30 +37,30 @@
         LinkedList<Object[]> cfgSet = new LinkedList<>();
         // Boolean testing
         cfgSet.add(
-                new Object[]{JavaConstant.forBoolean(true), CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) true)});
+                        new Object[]{JavaConstant.forBoolean(true), CONSTANT_REFLECTION_PROVIDER.forObject(true)});
         cfgSet.add(new Object[]{JavaConstant.forBoolean(false),
-                CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) false)});
+                        CONSTANT_REFLECTION_PROVIDER.forObject(false)});
         // Boxed boolean testing (returns null)
-        cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) true), null});
-        cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) false), null});
+        cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(true), null});
+        cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(false), null});
         for (byte number : new byte[]{-128, 0, 1, 127}) {
             // Integer primitives testing
             cfgSet.add(new Object[]{JavaConstant.forByte(number),
-                    CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number))});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number))});
             cfgSet.add(new Object[]{JavaConstant.forShort(number),
-                    CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number))});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number))});
             cfgSet.add(new Object[]{JavaConstant.forInt(number),
-                    CONSTANT_REFLECTION_PROVIDER.forObject(Integer.valueOf(number))});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(Integer.valueOf(number))});
             cfgSet.add(new Object[]{JavaConstant.forLong(number),
-                    CONSTANT_REFLECTION_PROVIDER.forObject(Long.valueOf(number))});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(Long.valueOf(number))});
             if (number >= 0) {
                 cfgSet.add(new Object[]{JavaConstant.forChar((char) number),
-                        CONSTANT_REFLECTION_PROVIDER.forObject(Character.valueOf((char) number))});
+                                CONSTANT_REFLECTION_PROVIDER.forObject(Character.valueOf((char) number))});
             }
             // Float and Double variables are not cached,
             // so the tested method returns "null" on them
-            cfgSet.add(new Object[]{JavaConstant.forFloat((float) number), null});
-            cfgSet.add(new Object[]{JavaConstant.forDouble((double) number), null});
+            cfgSet.add(new Object[]{JavaConstant.forFloat(number), null});
+            cfgSet.add(new Object[]{JavaConstant.forDouble(number), null});
             // Boxed primitives testing (return null)
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number)), null});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number)), null});
@@ -78,7 +78,7 @@
         // Non-primitives testing
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), null});
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues),
-                null});
+                        null});
         // Null testing
         cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, null});
         cfgSet.add(new Object[]{null, null});
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ConstantEqualsDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ConstantEqualsDataProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -39,53 +39,53 @@
         HashMap<Object, Constant> constMap = new HashMap<>();
         constMap.put(DUMMY_CLASS_INSTANCE.booleanField, JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField));
         constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultBooleanField,
-                JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.stableDefaultBooleanField));
+                        JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.stableDefaultBooleanField));
         constMap.put(DUMMY_CLASS_INSTANCE.byteField, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField));
         constMap.put(DUMMY_CLASS_INSTANCE.finalByteField, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.finalByteField));
         constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultByteField,
-                JavaConstant.forByte(DUMMY_CLASS_INSTANCE.stableDefaultByteField));
+                        JavaConstant.forByte(DUMMY_CLASS_INSTANCE.stableDefaultByteField));
         constMap.put(DUMMY_CLASS_INSTANCE.shortField, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField));
         constMap.put(DUMMY_CLASS_INSTANCE.finalShortField, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.finalShortField));
         constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultShortField,
-                JavaConstant.forShort(DUMMY_CLASS_INSTANCE.stableDefaultShortField));
+                        JavaConstant.forShort(DUMMY_CLASS_INSTANCE.stableDefaultShortField));
         constMap.put(DUMMY_CLASS_INSTANCE.intField, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField));
         constMap.put(DUMMY_CLASS_INSTANCE.finalIntField, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.finalIntField));
         constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultIntField,
-                JavaConstant.forInt(DUMMY_CLASS_INSTANCE.stableDefaultIntField));
+                        JavaConstant.forInt(DUMMY_CLASS_INSTANCE.stableDefaultIntField));
         constMap.put(DUMMY_CLASS_INSTANCE.longField, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField));
         constMap.put(DUMMY_CLASS_INSTANCE.finalLongField, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.finalLongField));
         constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultLongField,
-                JavaConstant.forLong(DUMMY_CLASS_INSTANCE.stableDefaultLongField));
+                        JavaConstant.forLong(DUMMY_CLASS_INSTANCE.stableDefaultLongField));
         constMap.put(DUMMY_CLASS_INSTANCE.doubleField, JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField));
         constMap.put(DUMMY_CLASS_INSTANCE.finalDoubleField,
-                JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.finalDoubleField));
+                        JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.finalDoubleField));
         constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultDoubleField,
-                JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.stableDefaultDoubleField));
+                        JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.stableDefaultDoubleField));
         constMap.put(DUMMY_CLASS_INSTANCE.floatField, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField));
         constMap.put(DUMMY_CLASS_INSTANCE.finalFloatField, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.finalFloatField));
         constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultFloatField,
-                JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.stableDefaultFloatField));
+                        JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.stableDefaultFloatField));
         constMap.put(DUMMY_CLASS_INSTANCE.charField, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField));
         constMap.put(DUMMY_CLASS_INSTANCE.finalCharField, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.finalCharField));
         constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultCharField,
-                JavaConstant.forChar(DUMMY_CLASS_INSTANCE.stableDefaultCharField));
+                        JavaConstant.forChar(DUMMY_CLASS_INSTANCE.stableDefaultCharField));
         constMap.put(DUMMY_CLASS_INSTANCE.stringField,
-                CONSTANT_REFLECTION_PROVIDER.forString(DUMMY_CLASS_INSTANCE.stringField));
+                        CONSTANT_REFLECTION_PROVIDER.forString(DUMMY_CLASS_INSTANCE.stringField));
         constMap.put(DUMMY_CLASS_INSTANCE.stringField2,
-                CONSTANT_REFLECTION_PROVIDER.forString(DUMMY_CLASS_INSTANCE.stringField2));
+                        CONSTANT_REFLECTION_PROVIDER.forString(DUMMY_CLASS_INSTANCE.stringField2));
         constMap.put(DUMMY_CLASS_INSTANCE.objectField,
-                CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField));
         constMap.put(DUMMY_CLASS_INSTANCE.finalObjectField,
-                CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.finalObjectField));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.finalObjectField));
         constMap.put(DUMMY_CLASS_INSTANCE.stableDefaultObjectField,
-                CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.stableDefaultObjectField));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.stableDefaultObjectField));
         constMap.put(null, null);
         constMap.put(JavaConstant.NULL_POINTER, JavaConstant.NULL_POINTER);
         LinkedList<Object[]> cfgSet = new LinkedList<>();
         constMap.entrySet().stream().forEach((obj1) -> {
             constMap.entrySet().stream().forEach((obj2) -> {
                 cfgSet.add(new Object[]{obj1.getValue(), obj2.getValue(),
-                        Objects.equals(obj1.getKey(), obj2.getKey())});
+                                Objects.equals(obj1.getKey(), obj2.getKey())});
             });
         });
         return cfgSet.toArray(new Object[0][0]);
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForObjectDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForObjectDataProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -29,27 +29,27 @@
     @DataProvider(name = "forObjectDataProvider")
     public static Object[][] forObjectDataProvider() {
         return new Object[][]{
-                {TestHelper.DUMMY_CLASS_INSTANCE.objectField,
-                        "Object[Object@" + TestHelper.DUMMY_CLASS_INSTANCE.objectField.hashCode() + "]"},
-                {TestHelper.DUMMY_CLASS_INSTANCE.stringField,
-                        "Object[String:\"" + TestHelper.DUMMY_CLASS_INSTANCE.stringField + "\"]"},
-                {TestHelper.DUMMY_CLASS_INSTANCE.booleanField,
-                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.booleanField + "]"},
-                {TestHelper.DUMMY_CLASS_INSTANCE.byteField,
-                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.byteField + "]"},
-                {TestHelper.DUMMY_CLASS_INSTANCE.charField,
-                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.charField + "]"},
-                {TestHelper.DUMMY_CLASS_INSTANCE.shortField,
-                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.shortField + "]"},
-                {TestHelper.DUMMY_CLASS_INSTANCE.intField,
-                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.intField + "]"},
-                {TestHelper.DUMMY_CLASS_INSTANCE.longField,
-                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.longField + "]"},
-                {TestHelper.DUMMY_CLASS_INSTANCE.floatField,
-                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.floatField + "]"},
-                {TestHelper.DUMMY_CLASS_INSTANCE.doubleField,
-                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.doubleField + "]"},
-                {new Object[0], "Object[Object[" + 0 + "]{}]"}, {new Object[1], "Object[Object[" + 1 + "]{null}]"},
-                {null, "Object[null]"}};
+                        {TestHelper.DUMMY_CLASS_INSTANCE.objectField,
+                                        "Object[Object@" + TestHelper.DUMMY_CLASS_INSTANCE.objectField.hashCode() + "]"},
+                        {TestHelper.DUMMY_CLASS_INSTANCE.stringField,
+                                        "Object[String:\"" + TestHelper.DUMMY_CLASS_INSTANCE.stringField + "\"]"},
+                        {TestHelper.DUMMY_CLASS_INSTANCE.booleanField,
+                                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.booleanField + "]"},
+                        {TestHelper.DUMMY_CLASS_INSTANCE.byteField,
+                                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.byteField + "]"},
+                        {TestHelper.DUMMY_CLASS_INSTANCE.charField,
+                                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.charField + "]"},
+                        {TestHelper.DUMMY_CLASS_INSTANCE.shortField,
+                                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.shortField + "]"},
+                        {TestHelper.DUMMY_CLASS_INSTANCE.intField,
+                                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.intField + "]"},
+                        {TestHelper.DUMMY_CLASS_INSTANCE.longField,
+                                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.longField + "]"},
+                        {TestHelper.DUMMY_CLASS_INSTANCE.floatField,
+                                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.floatField + "]"},
+                        {TestHelper.DUMMY_CLASS_INSTANCE.doubleField,
+                                        "Object[" + TestHelper.DUMMY_CLASS_INSTANCE.doubleField + "]"},
+                        {new Object[0], "Object[Object[" + 0 + "]{}]"}, {new Object[1], "Object[Object[" + 1 + "]{null}]"},
+                        {null, "Object[null]"}};
     }
 }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForStringDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ForStringDataProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -31,8 +31,8 @@
     @DataProvider(name = "forStringDataProvider")
     public static Object[][] forStringDataProvider() {
         return new Object[][]{
-                {DUMMY_CLASS_INSTANCE.stringField, "Object[String:\"" + DUMMY_CLASS_INSTANCE.stringField + "\"]"},
-                {DUMMY_CLASS_INSTANCE.stringEmptyField, "Object[String:\"\"]"},
-                {null, "Object[null]"}};
+                        {DUMMY_CLASS_INSTANCE.stringField, "Object[String:\"" + DUMMY_CLASS_INSTANCE.stringField + "\"]"},
+                        {DUMMY_CLASS_INSTANCE.stringEmptyField, "Object[String:\"\"]"},
+                        {null, "Object[null]"}};
     }
 }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/HotSpotConstantReflectionProviderTest.java	Fri May 20 18:05:09 2016 +0300
@@ -58,7 +58,7 @@
     public void testForObject(Object obj, String expected) {
         JavaConstant jConst = TestHelper.CONSTANT_REFLECTION_PROVIDER.forObject(obj);
         Assert.assertNotNull(jConst,
-                             "An instance of JavaConstant returned by" + " \"forObject\" method should not be null");
+                        "An instance of JavaConstant returned by" + " \"forObject\" method should not be null");
         Assert.assertEquals(jConst.toString(), expected, "Unexpected result:");
     }
 
@@ -66,131 +66,46 @@
     public void testForString(String string, String expected) {
         JavaConstant jConst = CONSTANT_REFLECTION_PROVIDER.forString(string);
         Assert.assertNotNull(jConst,
-                             "An instance of JavaConstant returned by" + " \"forString\" method should not be null");
+                        "An instance of JavaConstant returned by" + " \"forString\" method should not be null");
         Assert.assertEquals(jConst.toString(), expected, "Unexpected result:");
     }
 
     @Test(dataProvider = "constantEqualsDataProvider", dataProviderClass = ConstantEqualsDataProvider.class)
     public void testConstantEquals(Constant const1, Constant const2, Boolean expected) {
         Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.constantEquals(const1, const2), expected,
-                            "Unexpected result:");
+                        "Unexpected result:");
     }
 
     @Test(dataProvider = "readArrayLengthDataProvider", dataProviderClass = ReadArrayLengthDataProvider.class)
     public void testReadArrayLength(JavaConstant array, Integer expected) {
         Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.readArrayLength(array), expected,
-                            "Unexpected result:");
+                        "Unexpected result:");
     }
 
     @Test(dataProvider = "readArrayElementDataProvider", dataProviderClass = ReadArrayElementDataProvider.class)
     public void testReadArrayElement(JavaConstant array, int index, Object expected) {
         Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.readArrayElement(array, index), expected,
-                            "Unexpected result:");
+                        "Unexpected result:");
     }
 
     @Test(dataProvider = "readFieldValueDataProvider", dataProviderClass = ReadFieldValueDataProvider.class)
     public void testReadFieldValue(ResolvedJavaField field, JavaConstant receiver, JavaConstant expected) {
         JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.readFieldValue(field, receiver);
         Assert.assertEquals(actual == null ? "null" : actual.toString(),
-                            expected == null ? "null" : expected.toString(), "Unexpected result:");
-    }
-
-    @Test(dataProvider = "readFieldValueNegativeDataProvider",
-            dataProviderClass = ReadFieldValueDataProvider.class,
-            expectedExceptions = {NullPointerException.class})
-    public void testNegativeReadFieldValue(ResolvedJavaField field, JavaConstant receiver) {
-        CONSTANT_REFLECTION_PROVIDER.readFieldValue(field, receiver);
-    }
-
-    @Test(dataProvider = "readStableFieldValueDataProvider",
-            dataProviderClass = ReadStableFieldValueDataProvider.class)
-    public void testReadStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefStab,
-                                         JavaConstant expected) {
-        Assert.assertEquals(
-                CONSTANT_REFLECTION_PROVIDER.readStableFieldValue(field, receiver, isDefStab),
-                expected,
-                "Unexpected result:");
+                        expected == null ? "null" : expected.toString(), "Unexpected result:");
     }
 
-    @Test(dataProvider = "readStableFieldValueArrayDataProvider",
-            dataProviderClass = ReadStableFieldValueDataProvider.class)
-    public void testReadStableFieldValueForArray(ResolvedJavaField field, JavaConstant receiver, boolean isDefStab,
-                                                 int arrayDim, JavaConstant expected) {
-        JavaConstant result = CONSTANT_REFLECTION_PROVIDER.readStableFieldValue(field, receiver,
-                                                                                isDefStab);
-        boolean resultDefStab = false;
-        int resultStableDim = -1;
-        try {
-            Class<?> hotSpotObjectConstantImplClass = Class.forName(
-                    "jdk.vm.ci.hotspot.HotSpotObjectConstantImpl");
-            Method getStableDimensionMethod = hotSpotObjectConstantImplClass.getDeclaredMethod(
-                    "getStableDimension");
-            Method isDefaultStableMethod = hotSpotObjectConstantImplClass.getDeclaredMethod(
-                    "isDefaultStable");
-            getStableDimensionMethod.setAccessible(true);
-            isDefaultStableMethod.setAccessible(true);
-            resultDefStab = (boolean) isDefaultStableMethod.invoke(result);
-            resultStableDim = (int) getStableDimensionMethod.invoke(result);
-        } catch (ReflectiveOperationException e) {
-            throw new Error("Unexpected error: " + e, e);
-        }
-        Assert.assertEquals(resultDefStab, isDefStab,
-                            "Wrong default stable value for " + result.toString());
-        Assert.assertEquals(resultStableDim, arrayDim,
-                            "Wrong array dimension for " + result.toString());
-        Assert.assertEquals(result.toString(), expected.toString(), "Unexpected result:");
-    }
-
-    @Test(dataProvider = "readStableFieldValueNegativeDataProvider",
-            dataProviderClass = ReadStableFieldValueDataProvider.class,
-            expectedExceptions = {NullPointerException.class})
-    public void testNegativeReadStableFieldValue(ResolvedJavaField field, JavaConstant receiver, boolean isDefStab) {
-        CONSTANT_REFLECTION_PROVIDER.readStableFieldValue(field, receiver, isDefStab);
-    }
-
-    @Test(dataProvider = "readConstantFieldValueDataProvider",
-            dataProviderClass = ReadConstantFieldValueDataProvider.class)
-    public void testReadConstantFieldValue(ResolvedJavaField field, JavaConstant receiver, JavaConstant expected,
-                                           String testInfo) {
-        String msg = String.format("Unexpected result for %s. Field is stable = %s.", testInfo,
-                                   ((HotSpotResolvedJavaField) field).isStable());
-        Assert.assertEquals(CONSTANT_REFLECTION_PROVIDER.readConstantFieldValue(field, receiver),
-                            expected, msg);
-    }
-
-    @Test(dataProvider = "readConstantFieldValueNegativeDataProvider",
-            dataProviderClass = ReadConstantFieldValueDataProvider.class,
-            expectedExceptions = {NullPointerException.class})
-    public void testNegativeReadConstantFieldValue(ResolvedJavaField field, JavaConstant receiver) {
-        CONSTANT_REFLECTION_PROVIDER.readConstantFieldValue(field, receiver);
-    }
-
-    @Test(dataProvider = "readConstantArrayElementDataProvider",
-            dataProviderClass = ReadConstantArrayElementDataProvider.class)
-    public void testReadConstantArrayElement(JavaConstant array, int index, JavaConstant expected, String testInfo) {
-        JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.readConstantArrayElement(array, index);
-        Assert.assertEquals(actual == null ? "null" : actual.toString(),
-                            expected == null ? "null" : expected.toString(),
-                            String.format("Unexpected result while testing %s:", testInfo));
-    }
-
-    @Test(dataProvider = "readConstantArrayElementForOffsetDataProvider",
-            dataProviderClass = ReadConstantArrayElementDataProvider.class)
-    public void testReadConstantArrayElementForOffset(JavaConstant array, long offset, JavaConstant expected,
-                                                      String testInfo) {
-        JavaConstant actual = CONSTANT_REFLECTION_PROVIDER.readConstantArrayElementForOffset(array,
-                                                                                             offset);
-        Assert.assertEquals(actual == null ? "null" : actual.toString(),
-                            expected == null ? "null" : expected.toString(),
-                            String.format("Unexpected result while testing %s:", testInfo));
+    @Test(dataProvider = "readFieldValueNegativeDataProvider", dataProviderClass = ReadFieldValueDataProvider.class, expectedExceptions = {NullPointerException.class})
+    public void testNegativeReadFieldValue(ResolvedJavaField field, JavaConstant receiver) {
+        CONSTANT_REFLECTION_PROVIDER.readFieldValue(field, receiver);
     }
 
     @Test(dataProvider = "asJavaTypeDataProvider", dataProviderClass = AsJavaTypeDataProvider.class)
     public void testAsJavaType(JavaConstant constant, String expected) {
         ResolvedJavaType actual = CONSTANT_REFLECTION_PROVIDER.asJavaType(constant);
         Assert.assertEquals(actual == null ? "null" : actual.toJavaName(),
-                            expected == null ? "null" : expected,
-                            "Unexpected result, wrong type returned:");
+                        expected == null ? "null" : expected,
+                        "Unexpected result, wrong type returned:");
     }
 
     @Test(dataProvider = "boxPrimitiveDataProvider", dataProviderClass = BoxPrimitiveDataProvider.class)
@@ -221,6 +136,6 @@
     public void testGetMethodHandleAccess() {
         MethodHandleAccessProvider actual = CONSTANT_REFLECTION_PROVIDER.getMethodHandleAccess();
         Assert.assertNotNull(actual,
-                             "Returned MethodHandleAccessProvider instance should not be null");
+                        "Returned MethodHandleAccessProvider instance should not be null");
     }
 }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/IsEmbeddableDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/IsEmbeddableDataProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -33,14 +33,14 @@
     @DataProvider(name = "isEmbeddableDataProvider")
     public static Object[][] isEmbeddableDataProvider() {
         return new Object[][]{{JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField), true},
-                {JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField), true},
-                {JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField), true},
-                {JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField), true},
-                {JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField), true},
-                {JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField), true},
-                {JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField), true},
-                {JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField), true},
-                {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), true},
-                {JavaConstant.NULL_POINTER, true}, {null, true}};
+                        {JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField), true},
+                        {JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField), true},
+                        {JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField), true},
+                        {JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField), true},
+                        {JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField), true},
+                        {JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField), true},
+                        {JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField), true},
+                        {CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField), true},
+                        {JavaConstant.NULL_POINTER, true}, {null, true}};
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderData.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.vm.ci.hotspot.test;
+
+import java.lang.reflect.Field;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.runtime.JVMCI;
+import org.testng.annotations.DataProvider;
+import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
+import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
+import jdk.vm.ci.meta.Constant;
+import jdk.internal.misc.Unsafe;
+
+public class MemoryAccessProviderData {
+    private static final Unsafe UNSAFE = getUnsafe();
+    private static final HotSpotConstantReflectionProvider CONSTANT_REFLECTION = (HotSpotConstantReflectionProvider) JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection();
+    private static final TestClass TEST_OBJECT = new TestClass();
+    private static final JavaConstant TEST_CONSTANT = CONSTANT_REFLECTION.forObject(TEST_OBJECT);
+    private static final JavaConstant TEST_CLASS_CONSTANT = CONSTANT_REFLECTION.forObject(TestClass.class);
+
+    private static Unsafe getUnsafe() {
+        try {
+            Field f = Unsafe.class.getDeclaredField("theUnsafe");
+            f.setAccessible(true);
+            return (Unsafe) f.get(null);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new RuntimeException("Unable to get Unsafe instance.", e);
+        }
+    }
+
+    @DataProvider(name = "positiveObject")
+    public static Object[][] getPositiveObjectJavaKind() {
+        HotSpotJVMCIRuntimeProvider runtime = (HotSpotJVMCIRuntimeProvider) JVMCI.getRuntime();
+        int offset = runtime.getConfig().classMirrorOffset;
+        Constant wrappedKlassPointer = ((HotSpotResolvedObjectType) runtime.fromClass(TestClass.class)).klass();
+        return new Object[][]{new Object[]{JavaKind.Object, wrappedKlassPointer, (long) offset, TEST_CLASS_CONSTANT, 0}};
+    }
+
+    @DataProvider(name = "positivePrimitive")
+    public static Object[][] getPositivePrimitiveJavaKinds() {
+        Field booleanField;
+        Field byteField;
+        Field shortField;
+        Field intField;
+        Field longField;
+        Field floatField;
+        Field doubleField;
+        Field charField;
+        try {
+            booleanField = MemoryAccessProviderData.TestClass.class.getDeclaredField("booleanField");
+            byteField = MemoryAccessProviderData.TestClass.class.getDeclaredField("byteField");
+            shortField = MemoryAccessProviderData.TestClass.class.getDeclaredField("shortField");
+            intField = MemoryAccessProviderData.TestClass.class.getDeclaredField("intField");
+            longField = MemoryAccessProviderData.TestClass.class.getDeclaredField("longField");
+            floatField = MemoryAccessProviderData.TestClass.class.getDeclaredField("floatField");
+            doubleField = MemoryAccessProviderData.TestClass.class.getDeclaredField("doubleField");
+            charField = MemoryAccessProviderData.TestClass.class.getDeclaredField("charField");
+        } catch (NoSuchFieldException e) {
+            throw new Error("TESTBUG: can't find test field " + e, e);
+        }
+        long booleanFieldOffset = UNSAFE.objectFieldOffset(booleanField);
+        long byteFieldOffset = UNSAFE.objectFieldOffset(byteField);
+        long shortFieldOffset = UNSAFE.objectFieldOffset(shortField);
+        long intFieldOffset = UNSAFE.objectFieldOffset(intField);
+        long longFieldOffset = UNSAFE.objectFieldOffset(longField);
+        long floatFieldOffset = UNSAFE.objectFieldOffset(floatField);
+        long doubleFieldOffset = UNSAFE.objectFieldOffset(doubleField);
+        long charFieldOffset = UNSAFE.objectFieldOffset(charField);
+        return new Object[][]{
+                        new Object[]{JavaKind.Boolean, TEST_CONSTANT, booleanFieldOffset,
+                                        JavaConstant.forBoolean(TEST_OBJECT.booleanField), 8},
+                        new Object[]{JavaKind.Byte, TEST_CONSTANT, byteFieldOffset,
+                                        JavaConstant.forByte(TEST_OBJECT.byteField), 8},
+                        new Object[]{JavaKind.Short, TEST_CONSTANT, shortFieldOffset,
+                                        JavaConstant.forShort(TEST_OBJECT.shortField), 16},
+                        new Object[]{JavaKind.Int, TEST_CONSTANT, intFieldOffset,
+                                        JavaConstant.forInt(TEST_OBJECT.intField), 32},
+                        new Object[]{JavaKind.Long, TEST_CONSTANT, longFieldOffset,
+                                        JavaConstant.forLong(TEST_OBJECT.longField), 64},
+                        new Object[]{JavaKind.Float, TEST_CONSTANT, floatFieldOffset,
+                                        JavaConstant.forFloat(TEST_OBJECT.floatField), 32},
+                        new Object[]{JavaKind.Double, TEST_CONSTANT, doubleFieldOffset,
+                                        JavaConstant.forDouble(TEST_OBJECT.doubleField), 64},
+                        new Object[]{JavaKind.Char, TEST_CONSTANT, charFieldOffset,
+                                        JavaConstant.forChar(TEST_OBJECT.charField), 16}};
+    }
+
+    @DataProvider(name = "negative")
+    public static Object[][] getNegativeJavaKinds() {
+        return new Object[][]{
+                        new Object[]{JavaKind.Void, JavaConstant.NULL_POINTER},
+                        new Object[]{JavaKind.Illegal, JavaConstant.INT_1}};
+    }
+
+    private static class TestClass {
+        public final boolean booleanField = true;
+        public final byte byteField = 2;
+        public final short shortField = 3;
+        public final int intField = 4;
+        public final long longField = 5L;
+        public final double doubleField = 6.0d;
+        public final float floatField = 7.0f;
+        public final char charField = 'a';
+        public final String stringField = "abc";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MemoryAccessProviderTest.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8152341
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
+ * @library /testlibrary /test/lib /compiler/jvmci/jdk.vm.ci.hotspot.test/src
+ * @modules jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.common
+ *          jdk.vm.ci/jdk.vm.ci.runtime
+ *          jdk.vm.ci/jdk.vm.ci.hotspot
+ *          java.base/jdk.internal.misc
+ * @run testng/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      jdk.vm.ci.hotspot.test.MemoryAccessProviderTest
+ */
+
+package jdk.vm.ci.hotspot.test;
+
+import jdk.vm.ci.meta.Constant;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.MemoryAccessProvider;
+import jdk.vm.ci.runtime.JVMCI;
+
+public class MemoryAccessProviderTest {
+    private static final MemoryAccessProvider PROVIDER = JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection().getMemoryAccessProvider();
+
+    @Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class)
+    public void testPositiveReadUnsafeConstant(JavaKind kind, JavaConstant base, Long offset, Object expected, int bitsCount) {
+        Assert.assertEquals(PROVIDER.readUnsafeConstant(kind, base, offset), expected, "Failed to read constant");
+    }
+
+    @Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
+    public void testReadUnsafeConstantNullBase(JavaKind kind, JavaConstant base, Long offset, Object expected, int bitsCount) {
+        PROVIDER.readUnsafeConstant(kind, null, offset);
+    }
+
+    @Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
+    public void testNegativeReadUnsafeConstantNullKind(JavaKind kind, JavaConstant base, Long offset, Object expected, int bitsCount) {
+        Assert.assertNull(PROVIDER.readUnsafeConstant(null, base, offset), "Expected null return");
+    }
+
+    @Test(dataProvider = "negative", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
+    public void testNegativeReadUnsafeConstant(JavaKind kind, JavaConstant base) {
+        PROVIDER.readUnsafeConstant(kind, base, 0L);
+    }
+
+    @Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class)
+    public void testPositiveReadPrimitiveConstant(JavaKind kind, Constant base, Long offset, Object expected, int bitsCount) {
+        Assert.assertEquals(PROVIDER.readPrimitiveConstant(kind, base, offset, bitsCount), expected, "Failed to read constant");
+    }
+
+    @Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
+    public void testReadPrimitiveConstantNullBase(JavaKind kind, Constant base, Long offset, Object expected, int bitsCount) {
+        Assert.assertNull(PROVIDER.readPrimitiveConstant(kind, null, offset, bitsCount), "Unexpected value for null base");
+    }
+
+    @Test(dataProvider = "negative", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
+    public void testNegativeReadPrimitiveConstant(JavaKind kind, Constant base) {
+        PROVIDER.readPrimitiveConstant(kind, base, 0L, kind == null ? 0 : kind.getBitCount());
+    }
+
+    @Test(dataProvider = "positiveObject", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
+    public void testObjectReadPrimitiveConstant(JavaKind kind, Constant base, Long offset, Object expected, int bitsCount) {
+        PROVIDER.readPrimitiveConstant(kind, base, 0L, bitsCount);
+    }
+
+    @Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class, expectedExceptions = {IllegalArgumentException.class})
+    public void testReadPrimitiveConstantLessBits(JavaKind kind, Constant base, Long offset, Object expected, int bitsCount) {
+        PROVIDER.readPrimitiveConstant(kind, base, offset, bitsCount - 1);
+    }
+
+    @Test(dataProvider = "positiveObject", dataProviderClass = MemoryAccessProviderData.class)
+    public void testPositiveReadObjectConstant(JavaKind kind, Constant base, Long offset, Object expected, int bitsCount) {
+        Assert.assertEquals(PROVIDER.readObjectConstant(base, offset), expected, "Unexpected result");
+    }
+
+    @Test(dataProvider = "positiveObject", dataProviderClass = MemoryAccessProviderData.class)
+    public void testNegativeReadObjectConstantNullBase(JavaKind kind, Constant base, Long offset, Object expected, int bitsCount) {
+        Assert.assertNull(PROVIDER.readObjectConstant(null, offset), "Unexpected return");
+    }
+
+    @Test(dataProvider = "positiveObject", dataProviderClass = MemoryAccessProviderData.class)
+    public void testNegativeReadObjectConstantWrongOffset(JavaKind kind, Constant base, Long offset, Object expected, int bitsCount) {
+        Assert.assertNull(PROVIDER.readObjectConstant(base, offset + 1), "Expected null");
+    }
+
+    @Test(dataProvider = "positivePrimitive", dataProviderClass = MemoryAccessProviderData.class)
+    public void testNegativeReadObjectConstantPrimitiveBase(JavaKind kind, Constant base, Long offset, Object expected, int bitsCount) {
+        Assert.assertNull(PROVIDER.readObjectConstant(base, offset), "Expected null");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderData.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.vm.ci.hotspot.test;
+
+import java.io.File;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Paths;
+import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.MethodHandleAccessProvider;
+import jdk.vm.ci.runtime.JVMCI;
+import org.testng.annotations.DataProvider;
+
+public class MethodHandleAccessProviderData implements TestInterface {
+    private static final MetaAccessProvider META_ACCESS = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
+    private static final HotSpotConstantReflectionProvider CONSTANT_REFLECTION = (HotSpotConstantReflectionProvider) JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection();
+    // see DirectMethodHandle.java to check invoke* method names assignment
+    private static final String IVIRTUAL_RESOLVED_NAME = "invokeVirtual";
+    private static final String ISTATIC_RESOLVED_NAME = "invokeStatic";
+    private static final String ISPECIAL_RESOLVED_NAME = "invokeSpecial";
+    private static final String ISTATICINIT_RESOLVED_NAME = "invokeStaticInit";
+    private static final String IINTERFACE_RESOLVED_NAME = "invokeInterface";
+    private static final String INEWSPECIAL_RESOLVED_NAME = "newInvokeSpecial";
+
+    @DataProvider(name = "intrinsicsPositive")
+    public static Object[][] getIntrinsicsDataPositive() {
+        Object[][] result;
+        try {
+            result = new Object[][]{
+                            new Object[]{
+                                            META_ACCESS.lookupJavaMethod(MethodHandle.class.getDeclaredMethod("invokeBasic", Object[].class)),
+                                            MethodHandleAccessProvider.IntrinsicMethod.INVOKE_BASIC},
+                            new Object[]{
+                                            META_ACCESS.lookupJavaMethod(MethodHandle.class.getDeclaredMethod("linkToInterface", Object[].class)),
+                                            MethodHandleAccessProvider.IntrinsicMethod.LINK_TO_INTERFACE},
+                            new Object[]{
+                                            META_ACCESS.lookupJavaMethod(MethodHandle.class.getDeclaredMethod("linkToStatic", Object[].class)),
+                                            MethodHandleAccessProvider.IntrinsicMethod.LINK_TO_STATIC},
+                            new Object[]{
+                                            META_ACCESS.lookupJavaMethod(MethodHandle.class.getDeclaredMethod("linkToVirtual", Object[].class)),
+                                            MethodHandleAccessProvider.IntrinsicMethod.LINK_TO_VIRTUAL},
+                            new Object[]{
+                                            META_ACCESS.lookupJavaMethod(MethodHandle.class.getDeclaredMethod("linkToSpecial", Object[].class)),
+                                            MethodHandleAccessProvider.IntrinsicMethod.LINK_TO_SPECIAL}};
+        } catch (NoSuchMethodException e) {
+            throw new Error("TESTBUG: can't find method: " + e, e);
+        }
+        return result;
+    }
+
+    @DataProvider(name = "intrinsicsNegative")
+    public static Object[][] getIntrinsicsDataNegative() {
+        Object[][] result;
+        try {
+            result = new Object[][]{new Object[]{META_ACCESS.lookupJavaMethod(MethodHandle.class.getDeclaredMethod("invokeWithArguments", Object[].class))}};
+        } catch (NoSuchMethodException e) {
+            throw new Error("TESTBUG: can't find method: " + e, e);
+        }
+        return result;
+    }
+
+    @DataProvider(name = "invokeBasicNegative1")
+    public static Object[][] getInvokeBasicDataNegative1() {
+        Object[][] result;
+        JavaConstant wrongObject = CONSTANT_REFLECTION.forObject("42");
+        // 2nd parameter is force bytecode generation = true/false
+        result = new Object[][]{
+                        new Object[]{wrongObject, true},
+                        new Object[]{wrongObject, false},
+                        new Object[]{JavaConstant.NULL_POINTER, true},
+                        new Object[]{JavaConstant.NULL_POINTER, false}};
+        return result;
+    }
+
+    @DataProvider(name = "invokeBasicNegative2")
+    public static Object[][] getInvokeBasicDataNegative2() {
+        Object[][] result;
+        // 2nd parameter is force bytecode generation = true/false
+        result = new Object[][]{
+                        new Object[]{null, true},
+                        new Object[]{null, false}};
+        return result;
+    }
+
+    @DataProvider(name = "invokeBasicPositive")
+    public static Object[][] getInvokeBasicDataPositive() {
+        Object[][] result;
+        MethodHandle mhIVirtual;
+        MethodHandle mhIStatic;
+        MethodHandle mhISpecial;
+        MethodHandle mhIStaticInit;
+        MethodHandle mhINewSpecial;
+        MethodHandle mhIInterface;
+        MethodHandles.Lookup lookup = MethodHandles.lookup();
+        MethodType voidRet = MethodType.methodType(void.class);
+        Class<?> self = MethodHandleAccessProviderData.class;
+        // let's get a separate, thus, not initialized class
+        ClassLoader current = self.getClassLoader();
+        String[] cpaths = System.getProperty("java.class.path").split(File.pathSeparator);
+        URL[] urls = new URL[cpaths.length];
+        try {
+            for (int i = 0; i < cpaths.length; i++) {
+                urls[i] = Paths.get(cpaths[i]).toUri().toURL();
+            }
+        } catch (MalformedURLException e) {
+            throw new Error("Can't parse classpath url: " + e, e);
+        }
+        Class<?> clone;
+        try {
+            clone = new ParentLastURLClassLoader(urls, current).loadClass(self.getName());
+        } catch (ClassNotFoundException e) {
+            throw new Error("TESTBUG: can't find class: " + e, e);
+        }
+        try {
+            mhIVirtual = lookup.findVirtual(self, "publicMethod", voidRet);
+            mhIStatic = lookup.findStatic(self, "staticMethod", voidRet);
+            mhISpecial = lookup.findSpecial(self, "privateMethod", voidRet, self);
+            mhIStaticInit = lookup.findStatic(clone, "staticMethod", voidRet);
+            mhINewSpecial = lookup.findConstructor(self, voidRet);
+            mhIInterface = lookup.findVirtual(TestInterface.class, "interfaceMethod", voidRet);
+        } catch (NoSuchMethodException | IllegalAccessException e) {
+            throw new Error("TESTBUG: lookup failed: " + e, e);
+        }
+        JavaConstant jcIVirtual = CONSTANT_REFLECTION.forObject(mhIVirtual);
+        JavaConstant jcIStatic = CONSTANT_REFLECTION.forObject(mhIStatic);
+        JavaConstant jcISpecial = CONSTANT_REFLECTION.forObject(mhISpecial);
+        JavaConstant jcIStaticInit = CONSTANT_REFLECTION.forObject(mhIStaticInit);
+        JavaConstant jcINewSpecial = CONSTANT_REFLECTION.forObject(mhINewSpecial);
+        JavaConstant jcIInterface = CONSTANT_REFLECTION.forObject(mhIInterface);
+        // 2nd parameter is force bytecode generation = true/false
+        result = new Object[][]{
+                        new Object[]{jcIVirtual, true, IVIRTUAL_RESOLVED_NAME},
+                        new Object[]{jcIVirtual, false, IVIRTUAL_RESOLVED_NAME},
+                        new Object[]{jcIStatic, true, ISTATIC_RESOLVED_NAME},
+                        new Object[]{jcIStatic, false, ISTATIC_RESOLVED_NAME},
+                        new Object[]{jcISpecial, true, ISPECIAL_RESOLVED_NAME},
+                        new Object[]{jcISpecial, false, ISPECIAL_RESOLVED_NAME},
+                        new Object[]{jcIStaticInit, true, ISTATICINIT_RESOLVED_NAME},
+                        new Object[]{jcIStaticInit, false, ISTATICINIT_RESOLVED_NAME},
+                        new Object[]{jcINewSpecial, false, INEWSPECIAL_RESOLVED_NAME},
+                        new Object[]{jcINewSpecial, true, INEWSPECIAL_RESOLVED_NAME},
+                        new Object[]{jcIInterface, false, IINTERFACE_RESOLVED_NAME},
+                        new Object[]{jcIInterface, true, IINTERFACE_RESOLVED_NAME}};
+        return result;
+    }
+
+    // can't use nested classes for storing these test methods. see JDK-8010319
+    private void privateMethod() {
+        // empty
+    }
+
+    public static void staticMethod() {
+        // empty
+    }
+
+    public void publicMethod() {
+        // empty
+    }
+
+    @Override
+    public void interfaceMethod() {
+        // empty
+    }
+}
+
+interface TestInterface {
+    void interfaceMethod();
+}
+
+class ParentLastURLClassLoader extends URLClassLoader {
+
+    ParentLastURLClassLoader(URL[] urls, ClassLoader parent) {
+        super(urls, parent);
+    }
+
+    @Override
+    public Class<?> loadClass(String name) throws ClassNotFoundException {
+        try {
+            Class<?> c = findClass(name);
+            if (c != null) {
+                return c;
+            }
+        } catch (ClassNotFoundException e) {
+            // ignore
+        }
+        return super.loadClass(name);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/MethodHandleAccessProviderTest.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8152343
+ * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
+ * @library /testlibrary /test/lib /compiler/jvmci/jdk.vm.ci.hotspot.test/src
+ * @modules jdk.vm.ci/jdk.vm.ci.meta
+ *          jdk.vm.ci/jdk.vm.ci.runtime
+ *          jdk.vm.ci/jdk.vm.ci.hotspot
+ * @run testng/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
+ *      jdk.vm.ci.hotspot.test.MethodHandleAccessProviderTest
+ */
+
+package jdk.vm.ci.hotspot.test;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Method;
+import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
+import jdk.vm.ci.meta.MethodHandleAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.runtime.JVMCI;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.MethodHandleAccessProvider.IntrinsicMethod;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+public class MethodHandleAccessProviderTest {
+    private static final HotSpotConstantReflectionProvider CONSTANT_REFLECTION = (HotSpotConstantReflectionProvider) JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection();
+    private static final MethodHandleAccessProvider PROVIDER = CONSTANT_REFLECTION.getMethodHandleAccess();
+    private static final MetaAccessProvider META_ACCESS = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
+
+    @Test(dataProvider = "intrinsicsPositive", dataProviderClass = MethodHandleAccessProviderData.class)
+    public void testLookupMethodHandleIntrinsic(ResolvedJavaMethod mtd, IntrinsicMethod expected) {
+        Assert.assertEquals(expected, PROVIDER.lookupMethodHandleIntrinsic(mtd), "Unexpected intrinsic returned for " + mtd);
+    }
+
+    @Test(dataProvider = "intrinsicsNegative", dataProviderClass = MethodHandleAccessProviderData.class)
+    public void testLookupMethodHandleIntrinsicNegative(ResolvedJavaMethod mtd) {
+        Assert.assertNull(PROVIDER.lookupMethodHandleIntrinsic(mtd), "Expected null return for " + mtd);
+    }
+
+    @Test(expectedExceptions = {NullPointerException.class})
+    public void testLookupMethodHandleIntrinsicNull() {
+        PROVIDER.lookupMethodHandleIntrinsic(null);
+    }
+
+    @Test(dataProvider = "invokeBasicPositive", dataProviderClass = MethodHandleAccessProviderData.class)
+    public void testResolveInvokeBasicTarget(JavaConstant javaConstantMethodHandle, boolean force, String expected) {
+        ResolvedJavaMethod mtd = PROVIDER.resolveInvokeBasicTarget(javaConstantMethodHandle, force);
+        Assert.assertTrue(mtd.getName().startsWith(expected), "Unexpected method resolved: " + mtd);
+    }
+
+    @Test(dataProvider = "invokeBasicNegative1", dataProviderClass = MethodHandleAccessProviderData.class)
+    public void testResolveInvokeBasicTargetNegative1(JavaConstant javaConstantMethodHandle, boolean force) {
+        Assert.assertNull(PROVIDER.resolveInvokeBasicTarget(javaConstantMethodHandle, force),
+                        "Expected null return for " + javaConstantMethodHandle + " with force=" + force);
+    }
+
+    @Test(dataProvider = "invokeBasicNegative2", dataProviderClass = MethodHandleAccessProviderData.class, expectedExceptions = {NullPointerException.class})
+    public void testResolveInvokeBasicTargetNegative2(JavaConstant javaConstantMethodHandle, boolean force) {
+        PROVIDER.resolveInvokeBasicTarget(javaConstantMethodHandle, force);
+    }
+
+    @Test
+    public void testResolveLinkToTarget() {
+        Method self;
+        try {
+            self = getClass().getDeclaredMethod("testResolveLinkToTarget");
+        } catch (NoSuchMethodException e) {
+            throw new Error("TESTBUG: can't find method: " + e, e);
+        }
+        MethodHandle mh;
+        try {
+            mh = MethodHandles.lookup().unreflect(self);
+        } catch (IllegalAccessException e) {
+            throw new Error("TESTBUG: can't get MHandle: " + e, e);
+        }
+        Method internalMemberNameMethod;
+        try {
+            internalMemberNameMethod = mh.getClass().getDeclaredMethod("internalMemberName");
+        } catch (NoSuchMethodException e) {
+            throw new Error("TESTBUG: can't find method: " + e, e);
+        }
+        internalMemberNameMethod.setAccessible(true);
+        Object memberName;
+        try {
+            memberName = internalMemberNameMethod.invoke(mh);
+        } catch (ReflectiveOperationException e) {
+            throw new Error("TESTBUG: can't invoke internalMemberName method", e);
+        }
+        JavaConstant jcMemberName = CONSTANT_REFLECTION.forObject(memberName);
+        ResolvedJavaMethod mtd = PROVIDER.resolveLinkToTarget(jcMemberName);
+        Assert.assertEquals(mtd, META_ACCESS.lookupJavaMethod(self), "Got unexpected method: " + mtd);
+    }
+
+    @Test(expectedExceptions = {NullPointerException.class})
+    public void testResolveLinkToTargetNegativeNull() {
+        PROVIDER.resolveLinkToTarget(null);
+    }
+
+    @Test
+    public void testResolveLinkToTargetNegativeNullConstant() {
+        Assert.assertNull(PROVIDER.resolveLinkToTarget(JavaConstant.NULL_POINTER), "Expected null return");
+    }
+
+    @Test(expectedExceptions = {IllegalArgumentException.class})
+    public void testResolveLinkToTargetNegativeWrongConstant() {
+        PROVIDER.resolveLinkToTarget(CONSTANT_REFLECTION.forObject("42"));
+    }
+}
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayElementDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadArrayElementDataProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -42,50 +42,50 @@
         LinkedList<Object[]> cfgSet = new LinkedList<>();
         for (int i : new int[]{0, 1}) {
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayWithValues),
-                    i, JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanArrayWithValues[i])});
+                            i, JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanArrayWithValues[i])});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayWithValues),
-                    i, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteArrayWithValues[i])});
+                            i, JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteArrayWithValues[i])});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayWithValues),
-                    i, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortArrayWithValues[i])});
+                            i, JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortArrayWithValues[i])});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayWithValues),
-                    i, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charArrayWithValues[i])});
+                            i, JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charArrayWithValues[i])});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayWithValues),
-                    i, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intArrayWithValues[i])});
+                            i, JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intArrayWithValues[i])});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayWithValues),
-                    i, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longArrayWithValues[i])});
+                            i, JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longArrayWithValues[i])});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayWithValues),
-                    i, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatArrayWithValues[i])});
+                            i, JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatArrayWithValues[i])});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayWithValues),
-                    i, JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleArrayWithValues[i])});
+                            i, JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleArrayWithValues[i])});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayWithValues),
-                    i, CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayWithValues[i])});
+                            i, CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayWithValues[i])});
             cfgSet.add(new Object[]{
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues), i,
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues[i])});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues), i,
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues[i])});
             cfgSet.add(new Object[]{
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues), i,
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues[i])});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues), i,
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues[i])});
             cfgSet.add(new Object[]{
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues), i,
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues[i])});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues), i,
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues[i])});
             cfgSet.add(new Object[]{
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayArrayWithValues), i,
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayArrayWithValues[i])});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayArrayWithValues), i,
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.charArrayArrayWithValues[i])});
             cfgSet.add(new Object[]{
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayArrayWithValues), i,
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayArrayWithValues[i])});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayArrayWithValues), i,
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.intArrayArrayWithValues[i])});
             cfgSet.add(new Object[]{
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayArrayWithValues), i,
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayArrayWithValues[i])});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayArrayWithValues), i,
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.longArrayArrayWithValues[i])});
             cfgSet.add(new Object[]{
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues), i,
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues[i])});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues), i,
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues[i])});
             cfgSet.add(new Object[]{
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues), i,
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues[i])});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues), i,
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues[i])});
             cfgSet.add(new Object[]{
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues), i,
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues[i])});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues), i,
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues[i])});
         }
         Stream.concat(ARRAYS_MAP.values().stream(), ARRAY_ARRAYS_MAP.values().stream()).forEach((array) -> {
             for (int i : new int[]{-1, 2}) {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantArrayElementDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,290 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.vm.ci.hotspot.test;
-
-import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER;
-import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT;
-import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE;
-import static jdk.vm.ci.hotspot.test.TestHelper.getResolvedJavaField;
-import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAYS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAY_ARRAYS_MAP;
-
-import java.lang.reflect.Field;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Stream;
-
-import jdk.vm.ci.meta.JavaConstant;
-import org.testng.annotations.DataProvider;
-import jdk.internal.misc.Unsafe;
-import jdk.vm.ci.meta.ResolvedJavaField;
-
-public class ReadConstantArrayElementDataProvider {
-
-    // Non-stable array fields names mapped to their base offsets and index scale
-    private static final List<ArrayFieldParams> NON_STABLE_ARRAY_NAMES
-            = new LinkedList<>();
-
-    static {
-        NON_STABLE_ARRAY_NAMES.add(
-                new ArrayFieldParams("booleanArrayWithValues", Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
-                             Unsafe.ARRAY_BOOLEAN_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("byteArrayWithValues",
-                                                Unsafe.ARRAY_BYTE_BASE_OFFSET,
-                                                Unsafe.ARRAY_BYTE_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("shortArrayWithValues",
-                                                Unsafe.ARRAY_SHORT_BASE_OFFSET,
-                                                Unsafe.ARRAY_SHORT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("charArrayWithValues",
-                                                Unsafe.ARRAY_CHAR_BASE_OFFSET,
-                                                Unsafe.ARRAY_CHAR_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("intArrayWithValues",
-                                                Unsafe.ARRAY_INT_BASE_OFFSET,
-                                                Unsafe.ARRAY_INT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("longArrayWithValues",
-                                                Unsafe.ARRAY_LONG_BASE_OFFSET,
-                                                Unsafe.ARRAY_LONG_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("floatArrayWithValues",
-                                                Unsafe.ARRAY_FLOAT_BASE_OFFSET,
-                                                Unsafe.ARRAY_FLOAT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("doubleArrayWithValues",
-                                                Unsafe.ARRAY_DOUBLE_BASE_OFFSET,
-                                                Unsafe.ARRAY_DOUBLE_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("objectArrayWithValues",
-                                                Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
-                                                Unsafe.ARRAY_BOOLEAN_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("booleanArrayArrayWithValues",
-                                                Unsafe.ARRAY_OBJECT_BASE_OFFSET,
-                                                Unsafe.ARRAY_OBJECT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("byteArrayArrayWithValues",
-                                                Unsafe.ARRAY_OBJECT_BASE_OFFSET,
-                                                Unsafe.ARRAY_OBJECT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("shortArrayArrayWithValues",
-                                                Unsafe.ARRAY_OBJECT_BASE_OFFSET,
-                                                Unsafe.ARRAY_OBJECT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("charArrayArrayWithValues",
-                                                Unsafe.ARRAY_OBJECT_BASE_OFFSET,
-                                                Unsafe.ARRAY_OBJECT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("intArrayArrayWithValues",
-                                                Unsafe.ARRAY_OBJECT_BASE_OFFSET,
-                                                Unsafe.ARRAY_OBJECT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("longArrayArrayWithValues",
-                                                Unsafe.ARRAY_OBJECT_BASE_OFFSET,
-                                                Unsafe.ARRAY_OBJECT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("floatArrayArrayWithValues",
-                                                Unsafe.ARRAY_OBJECT_BASE_OFFSET,
-                                                Unsafe.ARRAY_OBJECT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("doubleArrayArrayWithValues",
-                                                Unsafe.ARRAY_OBJECT_BASE_OFFSET,
-                                                Unsafe.ARRAY_OBJECT_INDEX_SCALE));
-        NON_STABLE_ARRAY_NAMES.add(new ArrayFieldParams("objectArrayArrayWithValues",
-                                                Unsafe.ARRAY_OBJECT_BASE_OFFSET,
-                                                Unsafe.ARRAY_OBJECT_INDEX_SCALE));
-    }
-
-    // Stable array fields names mapped to their base offsets and index scale
-    private static final List<ArrayFieldParams> STABLE_ARRAY_NAMES
-            = new LinkedList<>();
-
-    static {
-        NON_STABLE_ARRAY_NAMES.stream().forEach((entry) -> {
-            String nsFieldName = entry.name;
-            char firstChar = nsFieldName.charAt(0);
-            char newFirstChar = Character.toUpperCase(firstChar);
-            String sFieldName = nsFieldName.replaceFirst("" + firstChar,
-                                                         "" + newFirstChar);
-            sFieldName = "stable" + sFieldName;
-            STABLE_ARRAY_NAMES.add(new ArrayFieldParams(sFieldName, entry.offsetBase, entry.scale));
-        });
-    }
-
-    @DataProvider(name = "readConstantArrayElementDataProvider")
-    public static Object[][] readConstantArrayElementDataProvider() {
-        LinkedList<Object[]> cfgSet = new LinkedList<>();
-        for (int i : new int[]{0, 1}) {
-            NON_STABLE_ARRAY_NAMES.stream().forEach((entry) -> {
-                String fieldName = entry.name;
-                cfgSet.add(new Object[]{
-                        readFieldValue(fieldName),
-                        i,
-                        null,
-                        "array field \"" + fieldName + "\" for index " + i});
-            });
-            STABLE_ARRAY_NAMES.stream().forEach((entry) -> {
-                String fieldName = entry.name;
-                cfgSet.add(new Object[]{
-                        readFieldValue(fieldName),
-                        i,
-                        i == 0 ? getJavaConstant(fieldName) : null,
-                        "array field \"" + fieldName + "\" for index " + i});
-            });
-        }
-        Stream<Map.Entry<ResolvedJavaField, JavaConstant>> arraysStream1
-                = Stream.concat(ARRAYS_MAP.entrySet().stream(),
-                                ARRAY_ARRAYS_MAP.entrySet().stream());
-        Stream<Map.Entry<ResolvedJavaField, JavaConstant>> arraysStream2
-                = Stream.concat(STABLE_ARRAYS_MAP.entrySet().stream(),
-                                STABLE_ARRAY_ARRAYS_MAP.entrySet().stream());
-        Stream.concat(arraysStream1, arraysStream2).forEach((array) -> {
-            for (int i : new int[]{-1, 2}) {
-                cfgSet.add(new Object[]{
-                        array.getValue(),
-                        i,
-                        null,
-                        "array field \"" + array.getKey() + "\" for index " + i});
-            }
-        });
-        cfgSet.add(new Object[]{null, 0, null, "null"});
-        cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, 0, null, "JavaConstant.NULL_POINTER"});
-        INSTANCE_FIELDS_MAP.values().forEach((constant) -> {
-            cfgSet.add(new Object[]{constant, 0, null, "non-stable non-array field"});
-        });
-        INSTANCE_STABLE_FIELDS_MAP.values().forEach((constant) -> {
-            cfgSet.add(new Object[]{constant, 0, null, "stable non-array field"});
-        });
-        return cfgSet.toArray(new Object[0][0]);
-    }
-
-    @DataProvider(name = "readConstantArrayElementForOffsetDataProvider")
-    public static Object[][] readConstantArrayElementForOffsetDataProvider() {
-        LinkedList<Object[]> cfgSet = new LinkedList<>();
-        // Testing non-stable arrays. Result should be null in all cases
-        for (double i : new double[]{-1, 0, 0.5, 1, 1.5, 2}) {
-            NON_STABLE_ARRAY_NAMES.stream().forEach(entry -> {
-                String fieldName = entry.name;
-                long offset = (long) (entry.offsetBase + i * entry.scale);
-                cfgSet.add(new Object[]{
-                        readFieldValue(fieldName),
-                        offset,
-                        null,
-                        "array field \"" + fieldName + "\" for offset " + offset});
-            });
-        }
-        // Testing stable arrays. Result should be null in all cases except "offset = base + 0"
-        for (double i : new double[]{-1, 0.5, 1, 1.5, 2}) {
-            STABLE_ARRAY_NAMES.stream().forEach(entry -> {
-                String fieldName = entry.name;
-                long offset = (long) Math.ceil(entry.offsetBase + i * entry.scale);
-                cfgSet.add(new Object[]{
-                        readFieldValue(fieldName),
-                        offset,
-                        null,
-                        "array field \"" + fieldName + "\" for offset " + offset});
-            });
-        }
-        // Testing stable arrays "offset = base + 0". Result should be non-null
-        STABLE_ARRAY_NAMES.stream().forEach(entry -> {
-            String fieldName = entry.name;
-            long offset = (long) entry.offsetBase;
-            cfgSet.add(new Object[]{
-                    readFieldValue(fieldName),
-                    offset,
-                    getJavaConstant(fieldName),
-                    "array field \"" + fieldName + "\" for offset " + offset});
-        });
-        // Testing null as array
-        cfgSet.add(new Object[]{null, 0, null, "null"});
-        // Testing JavaConstant.NULL_POINTER as array
-        cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, 0, null, "JavaConstant.NULL_POINTER"});
-        // Testing non-stable non-array fields
-        INSTANCE_FIELDS_MAP.values().forEach((constant) -> {
-            cfgSet.add(new Object[]{constant, 0, null, "non-stable non-array field"});
-        });
-        // Testing stable non-array fields
-        INSTANCE_STABLE_FIELDS_MAP.values().forEach((constant) -> {
-            cfgSet.add(new Object[]{constant, 0, null, "stable non-array field"});
-        });
-        return cfgSet.toArray(new Object[0][0]);
-    }
-
-    private static JavaConstant readFieldValue(String fieldName) {
-        return CONSTANT_REFLECTION_PROVIDER.readFieldValue(getResolvedJavaField(DummyClass.class, fieldName),
-                                                           DUMMY_CLASS_CONSTANT);
-    }
-
-    private static JavaConstant getJavaConstant(String fieldName) {
-        Class<DummyClass> dummyClass = DummyClass.class;
-        Field arrayField;
-        try {
-            arrayField = dummyClass.getDeclaredField(fieldName);
-        } catch (NoSuchFieldException ex) {
-            throw new Error("Test bug: wrong field name " + ex, ex);
-        } catch (SecurityException ex) {
-            throw new Error("Unexpected error: " + ex, ex);
-        }
-        arrayField.setAccessible(true);
-        Class<?> componentType = arrayField.getType().getComponentType();
-        if (componentType == null) {
-            throw new Error("Test error: field is not an array");
-        }
-        Object value;
-        try {
-            value = arrayField.get(DUMMY_CLASS_INSTANCE);
-        } catch (IllegalArgumentException | IllegalAccessException ex) {
-            throw new Error("Unexpected error: " + ex, ex);
-        }
-        if (componentType == boolean.class) {
-            return JavaConstant.forBoolean(((boolean[]) value)[0]);
-        }
-        if (componentType == byte.class) {
-            return JavaConstant.forByte(((byte[]) value)[0]);
-        }
-        if (componentType == short.class) {
-            return JavaConstant.forShort(((short[]) value)[0]);
-        }
-        if (componentType == char.class) {
-            return JavaConstant.forChar(((char[]) value)[0]);
-        }
-        if (componentType == int.class) {
-            return JavaConstant.forInt(((int[]) value)[0]);
-        }
-        if (componentType == long.class) {
-            return JavaConstant.forLong(((long[]) value)[0]);
-        }
-        if (componentType == float.class) {
-            return JavaConstant.forFloat(((float[]) value)[0]);
-        }
-        if (componentType == double.class) {
-            return JavaConstant.forDouble(((double[]) value)[0]);
-        }
-        return CONSTANT_REFLECTION_PROVIDER.forObject(((Object[]) value)[0]);
-    }
-
-    private static class ArrayFieldParams {
-        public final String name;
-        public final int offsetBase;
-        public final int scale;
-
-       ArrayFieldParams(String name, int offsetBase, int scale) {
-           this.name = name;
-           this.offsetBase = offsetBase;
-           this.scale = scale;
-       }
-    }
-}
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadConstantFieldValueDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.vm.ci.hotspot.test;
-
-import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT;
-import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FINAL_DEFAULT_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FINAL_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_DEFAULT_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FINAL_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_DEFAULT_FIELDS_MAP;
-
-import java.util.LinkedList;
-import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-import jdk.vm.ci.meta.JavaConstant;
-import org.testng.annotations.DataProvider;
-
-
-public class ReadConstantFieldValueDataProvider {
-
-    @DataProvider(name = "readConstantFieldValueDataProvider")
-    public static Object[][] readConstantFieldValueDataProvider() {
-        LinkedList<Object[]> cfgSet = new LinkedList<>();
-        // Testing static final fields
-        STATIC_FINAL_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            cfgSet.add(new Object[]{field.getKey(), null, field.getValue(), "static final field"});
-        });
-        // Testing static stable fields
-        STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            cfgSet.add(new Object[]{field.getKey(), null, field.getValue(), "static stable field"});
-        });
-        // Testing instance final non-default fields
-        INSTANCE_FINAL_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            cfgSet.add(new Object[]{field.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    field.getValue(),
-                    "instance final field"});
-        });
-        // Testing instance final default fields.
-        boolean trustDefFinal = HotSpotJVMCIRuntime.Option.TrustFinalDefaultFields.getBoolean();
-        INSTANCE_FINAL_DEFAULT_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            JavaConstant expected = trustDefFinal ? field.getValue() : null;
-            cfgSet.add(new Object[]{field.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    expected,
-                    "instance final default field"});
-        });
-        // Testing instance stable non-default fields
-        INSTANCE_STABLE_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            cfgSet.add(new Object[]{field.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    field.getValue(),
-                    "instance stable field"});
-        });
-        // Testing instance stable default fields
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            cfgSet.add(new Object[]{field.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    null,
-                    "instance stable default field"});
-        });
-        // Testing regular instance fields
-        INSTANCE_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            cfgSet.add(new Object[]{field.getKey(), DUMMY_CLASS_CONSTANT, null, "instance field"});
-        });
-        // Testing regular static fields
-        STATIC_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            cfgSet.add(new Object[]{field.getKey(), null, null, "static field"});
-        });
-        // Testing static stable fields
-        STATIC_STABLE_DEFAULT_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            cfgSet.add(new Object[]{field.getKey(), null, null, "static stable default field"});
-        });
-        return cfgSet.toArray(new Object[0][0]);
-    }
-
-    @DataProvider(name = "readConstantFieldValueNegativeDataProvider")
-    public static Object[][] readConstantFieldValueNegativeDataProvider() {
-        LinkedList<Object[]> cfgSet = new LinkedList<>();
-        // Testing instance fields with null as receiver
-        INSTANCE_FIELDS_MAP.entrySet().stream().forEach((field) -> {
-            cfgSet.add(new Object[]{field.getKey(), null});
-        });
-        // Testing null as a field argument
-        cfgSet.add(new Object[]{null, null});
-        return cfgSet.toArray(new Object[0][0]);
-    }
-}
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadFieldValueDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadFieldValueDataProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -39,7 +39,6 @@
 import jdk.vm.ci.meta.JavaConstant;
 import org.testng.annotations.DataProvider;
 
-
 public class ReadFieldValueDataProvider {
 
     @DataProvider(name = "readFieldValueDataProvider")
@@ -48,8 +47,8 @@
         // Testing instance non-stable fields
         INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> {
             cfgSet.add(new Object[]{instanceField.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    instanceField.getValue()});
+                            DUMMY_CLASS_CONSTANT,
+                            instanceField.getValue()});
         });
         // Testing static non-stable fields with null as receiver
         STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> {
@@ -58,14 +57,14 @@
         // Testing static non-stable fields with JavaConstant.NULL_POINTER as receiver
         STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> {
             cfgSet.add(new Object[]{staticField.getKey(),
-                    JavaConstant.NULL_POINTER,
-                    staticField.getValue()});
+                            JavaConstant.NULL_POINTER,
+                            staticField.getValue()});
         });
         // Testing instance stable fields
         INSTANCE_STABLE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> {
             cfgSet.add(new Object[]{instanceField.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    instanceField.getValue()});
+                            DUMMY_CLASS_CONSTANT,
+                            instanceField.getValue()});
         });
         // Testing static stable fields with null as receiver
         STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> {
@@ -74,32 +73,32 @@
         // Testing static stable fields with JavaConstant.NULL_POINTER as receiver
         STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> {
             cfgSet.add(new Object[]{staticField.getKey(),
-                    JavaConstant.NULL_POINTER,
-                    staticField.getValue()});
+                            JavaConstant.NULL_POINTER,
+                            staticField.getValue()});
         });
         // Testing instance non-stable array fields
         ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> {
             cfgSet.add(new Object[]{instanceField.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    instanceField.getValue()});
+                            DUMMY_CLASS_CONSTANT,
+                            instanceField.getValue()});
         });
         // Testing instance stable array fields
         STABLE_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> {
             cfgSet.add(new Object[]{instanceField.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    instanceField.getValue()});
+                            DUMMY_CLASS_CONSTANT,
+                            instanceField.getValue()});
         });
         // Testing instance non-stable array-of-array fields
         ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> {
             cfgSet.add(new Object[]{instanceField.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    instanceField.getValue()});
+                            DUMMY_CLASS_CONSTANT,
+                            instanceField.getValue()});
         });
         // Testing instance stable array-of-array fields
         STABLE_ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> {
             cfgSet.add(new Object[]{instanceField.getKey(),
-                    DUMMY_CLASS_CONSTANT,
-                    instanceField.getValue()});
+                            DUMMY_CLASS_CONSTANT,
+                            instanceField.getValue()});
         });
         // Testing instance fields with JavaConstant.NULL_POINTER as receiver
         INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> {
@@ -108,8 +107,8 @@
         // Testing instance fields with an object that does not have the field
         INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> {
             cfgSet.add(new Object[]{instanceField.getKey(),
-                    CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField),
-                    null});
+                            CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField),
+                            null});
         });
         return cfgSet.toArray(new Object[0][0]);
     }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/ReadStableFieldValueDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.vm.ci.hotspot.test;
-
-import static jdk.vm.ci.hotspot.test.TestHelper.ARRAYS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.ARRAY_ARRAYS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.CONSTANT_REFLECTION_PROVIDER;
-import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_CONSTANT;
-import static jdk.vm.ci.hotspot.test.TestHelper.DUMMY_CLASS_INSTANCE;
-import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAYS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.STABLE_ARRAY_ARRAYS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_STABLE_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.INSTANCE_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_FIELDS_MAP;
-import static jdk.vm.ci.hotspot.test.TestHelper.STATIC_STABLE_FIELDS_MAP;
-
-import java.util.LinkedList;
-import jdk.vm.ci.meta.JavaConstant;
-import org.testng.annotations.DataProvider;
-
-public class ReadStableFieldValueDataProvider {
-
-    @DataProvider(name = "readStableFieldValueDataProvider")
-    public static Object[][] readStableFieldValueDataProvider() {
-        LinkedList<Object[]> cfgSet = new LinkedList<>();
-        for (boolean isDefStab : new boolean[]{true, false}) {
-            // Testing instance non-stable fields
-            INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> {
-                cfgSet.add(new Object[]{instanceField.getKey(),
-                        DUMMY_CLASS_CONSTANT,
-                        isDefStab,
-                        instanceField.getValue()});
-            });
-            // Testing static non-stable fields with null as receiver
-            STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> {
-                cfgSet.add(new Object[]{staticField.getKey(),
-                        null,
-                        isDefStab,
-                        staticField.getValue()});
-            });
-            // Testing static non-stable fields with JavaConstant.NULL_POINTER as receiver
-            STATIC_FIELDS_MAP.entrySet().stream().forEach((staticField) -> {
-                cfgSet.add(new Object[]{staticField.getKey(),
-                        JavaConstant.NULL_POINTER,
-                        isDefStab,
-                        staticField.getValue()});
-            });
-            // Testing instance stable fields
-            INSTANCE_STABLE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> {
-                cfgSet.add(new Object[]{instanceField.getKey(),
-                        DUMMY_CLASS_CONSTANT,
-                        isDefStab,
-                        instanceField.getValue()});
-            });
-            // Testing static stable fields with null as receiver
-            STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> {
-                cfgSet.add(new Object[]{staticField.getKey(),
-                        null,
-                        isDefStab,
-                        staticField.getValue()});
-            });
-            // Testing static stable fields with JavaConstant.NULL_POINTER as receiver
-            STATIC_STABLE_FIELDS_MAP.entrySet().stream().forEach((staticField) -> {
-                cfgSet.add(new Object[]{staticField.getKey(),
-                        JavaConstant.NULL_POINTER,
-                        isDefStab,
-                        staticField.getValue()});
-            });
-            // Testing instance fields with JavaConstant.NULL_POINTER as receiver
-            INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> {
-                cfgSet.add(new Object[]{instanceField.getKey(),
-                        JavaConstant.NULL_POINTER,
-                        isDefStab,
-                        null});
-            });
-            // Testing instance fields with an object that does not have the field
-            INSTANCE_FIELDS_MAP.entrySet().stream().forEach((instanceField) -> {
-                cfgSet.add(new Object[]{instanceField.getKey(),
-                        CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE.objectField),
-                        isDefStab,
-                        null});
-            });
-        }
-        return cfgSet.toArray(new Object[0][0]);
-    }
-
-    @DataProvider(name = "readStableFieldValueArrayDataProvider")
-    public static Object[][] readStableFieldValueArrayDataProvider() {
-        LinkedList<Object[]> cfgSet = new LinkedList<>();
-        for (boolean isDefStab : new boolean[]{true, false}) {
-            // Testing instance non-stable array fields
-            ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> {
-                cfgSet.add(new Object[]{instanceField.getKey(),
-                        DUMMY_CLASS_CONSTANT,
-                        isDefStab,
-                        TestHelper.ARRAY_DIMENSION,
-                        instanceField.getValue()});
-            });
-            // Testing instance stable array fields
-            STABLE_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> {
-                cfgSet.add(new Object[]{instanceField.getKey(),
-                        DUMMY_CLASS_CONSTANT,
-                        isDefStab,
-                        TestHelper.ARRAY_DIMENSION,
-                        instanceField.getValue()});
-            });
-            // Testing instance non-stable array-of-array fields
-            ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> {
-                cfgSet.add(new Object[]{instanceField.getKey(),
-                        DUMMY_CLASS_CONSTANT,
-                        isDefStab,
-                        TestHelper.ARRAY_OF_ARRAYS_DIMENSION,
-                        instanceField.getValue()});
-            });
-            // Testing instance stable array-of-array fields
-            STABLE_ARRAY_ARRAYS_MAP.entrySet().stream().forEach((instanceField) -> {
-                cfgSet.add(new Object[]{instanceField.getKey(),
-                        DUMMY_CLASS_CONSTANT,
-                        isDefStab,
-                        TestHelper.ARRAY_OF_ARRAYS_DIMENSION,
-                        instanceField.getValue()});
-            });
-        }
-        return cfgSet.toArray(new Object[0][0]);
-    }
-
-    @DataProvider(name = "readStableFieldValueNegativeDataProvider")
-    public static Object[][] readStableFieldValueNegativeDataProvider() {
-        LinkedList<Object[]> cfgSet = new LinkedList<>();
-        for (boolean isDefStab : new boolean[]{true, false}) {
-            // Testing instance fields with null as receiver
-            INSTANCE_FIELDS_MAP.keySet().stream().forEach((instanceField) -> {
-                cfgSet.add(new Object[]{instanceField, null, isDefStab});
-            });
-            // Testing null as a field argument
-            cfgSet.add(new Object[]{null, null, isDefStab});
-        }
-        return cfgSet.toArray(new Object[0][0]);
-    }
-}
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHelper.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/TestHelper.java	Fri May 20 18:05:09 2016 +0300
@@ -35,298 +35,247 @@
 public class TestHelper {
 
     public static final DummyClass DUMMY_CLASS_INSTANCE = new DummyClass();
-    public static final HotSpotConstantReflectionProvider CONSTANT_REFLECTION_PROVIDER
-            = (HotSpotConstantReflectionProvider) JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection();
-    public static final JavaConstant DUMMY_CLASS_CONSTANT
-            = CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE);
+    public static final HotSpotConstantReflectionProvider CONSTANT_REFLECTION_PROVIDER = (HotSpotConstantReflectionProvider) JVMCI.getRuntime().getHostJVMCIBackend().getConstantReflection();
+    public static final JavaConstant DUMMY_CLASS_CONSTANT = CONSTANT_REFLECTION_PROVIDER.forObject(DUMMY_CLASS_INSTANCE);
 
-    public static final Map<ResolvedJavaField, JavaConstant> INSTANCE_FIELDS_MAP
-            = new HashMap<>();
+    public static final Map<ResolvedJavaField, JavaConstant> INSTANCE_FIELDS_MAP = new HashMap<>();
 
     static {
         INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "booleanField"),
-                                JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField));
+                        JavaConstant.forBoolean(DUMMY_CLASS_INSTANCE.booleanField));
         INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "byteField"),
-                                JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField));
+                        JavaConstant.forByte(DUMMY_CLASS_INSTANCE.byteField));
         INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "shortField"),
-                                JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField));
+                        JavaConstant.forShort(DUMMY_CLASS_INSTANCE.shortField));
         INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "charField"),
-                                JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField));
+                        JavaConstant.forChar(DUMMY_CLASS_INSTANCE.charField));
         INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "intField"),
-                                JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField));
+                        JavaConstant.forInt(DUMMY_CLASS_INSTANCE.intField));
         INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "longField"),
-                                JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField));
+                        JavaConstant.forLong(DUMMY_CLASS_INSTANCE.longField));
         INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "floatField"),
-                                JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField));
+                        JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.floatField));
         INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "doubleField"),
-                                JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField));
+                        JavaConstant.forDouble(DUMMY_CLASS_INSTANCE.doubleField));
         INSTANCE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "objectField"),
-                                CONSTANT_REFLECTION_PROVIDER.forObject(
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
                                         DUMMY_CLASS_INSTANCE.objectField));
     }
 
-    public static final Map<ResolvedJavaField, JavaConstant> INSTANCE_FINAL_FIELDS_MAP
-            = new HashMap<>();
+    public static final Map<ResolvedJavaField, JavaConstant> INSTANCE_FINAL_FIELDS_MAP = new HashMap<>();
 
     static {
         INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalBooleanField"),
-                                      JavaConstant.forBoolean(
-                                              DUMMY_CLASS_INSTANCE.finalBooleanField));
+                        JavaConstant.forBoolean(
+                                        DUMMY_CLASS_INSTANCE.finalBooleanField));
         INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalByteField"),
-                                      JavaConstant.forByte(DUMMY_CLASS_INSTANCE.finalByteField));
+                        JavaConstant.forByte(DUMMY_CLASS_INSTANCE.finalByteField));
         INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalShortField"),
-                                      JavaConstant.forShort(DUMMY_CLASS_INSTANCE.finalShortField));
+                        JavaConstant.forShort(DUMMY_CLASS_INSTANCE.finalShortField));
         INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalCharField"),
-                                      JavaConstant.forChar(DUMMY_CLASS_INSTANCE.finalCharField));
+                        JavaConstant.forChar(DUMMY_CLASS_INSTANCE.finalCharField));
         INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalIntField"),
-                                      JavaConstant.forInt(DUMMY_CLASS_INSTANCE.finalIntField));
+                        JavaConstant.forInt(DUMMY_CLASS_INSTANCE.finalIntField));
         INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalLongField"),
-                                      JavaConstant.forLong(DUMMY_CLASS_INSTANCE.finalLongField));
+                        JavaConstant.forLong(DUMMY_CLASS_INSTANCE.finalLongField));
         INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalFloatField"),
-                                      JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.finalFloatField));
+                        JavaConstant.forFloat(DUMMY_CLASS_INSTANCE.finalFloatField));
         INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalDoubleField"),
-                                      JavaConstant.forDouble(
-                                              DUMMY_CLASS_INSTANCE.finalDoubleField));
+                        JavaConstant.forDouble(
+                                        DUMMY_CLASS_INSTANCE.finalDoubleField));
         INSTANCE_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "finalObjectField"),
-                                      CONSTANT_REFLECTION_PROVIDER.forObject(
-                                              DUMMY_CLASS_INSTANCE.finalObjectField));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.finalObjectField));
     }
 
-    public static final Map<ResolvedJavaField, JavaConstant> INSTANCE_FINAL_DEFAULT_FIELDS_MAP
-            = new HashMap<>();
+    public static final Map<ResolvedJavaField, JavaConstant> INSTANCE_FINAL_DEFAULT_FIELDS_MAP = new HashMap<>();
 
     static {
         INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                   "finalDefaultBooleanField"),
-                                              JavaConstant.forBoolean(
-                                                      DUMMY_CLASS_INSTANCE.finalDefaultBooleanField));
+                        "finalDefaultBooleanField"),
+                        JavaConstant.forBoolean(
+                                        DUMMY_CLASS_INSTANCE.finalDefaultBooleanField));
         INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                   "finalDefaultByteField"),
-                                              JavaConstant.forByte(
-                                                      DUMMY_CLASS_INSTANCE.finalDefaultByteField));
+                        "finalDefaultByteField"),
+                        JavaConstant.forByte(
+                                        DUMMY_CLASS_INSTANCE.finalDefaultByteField));
         INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                   "finalDefaultShortField"),
-                                              JavaConstant.forShort(
-                                                      DUMMY_CLASS_INSTANCE.finalDefaultShortField));
+                        "finalDefaultShortField"),
+                        JavaConstant.forShort(
+                                        DUMMY_CLASS_INSTANCE.finalDefaultShortField));
         INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                   "finalDefaultCharField"),
-                                              JavaConstant.forChar(
-                                                      DUMMY_CLASS_INSTANCE.finalDefaultCharField));
+                        "finalDefaultCharField"),
+                        JavaConstant.forChar(
+                                        DUMMY_CLASS_INSTANCE.finalDefaultCharField));
         INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                   "finalDefaultIntField"),
-                                              JavaConstant.forInt(
-                                                      DUMMY_CLASS_INSTANCE.finalDefaultIntField));
+                        "finalDefaultIntField"),
+                        JavaConstant.forInt(
+                                        DUMMY_CLASS_INSTANCE.finalDefaultIntField));
         INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                   "finalDefaultLongField"),
-                                              JavaConstant.forLong(
-                                                      DUMMY_CLASS_INSTANCE.finalDefaultLongField));
+                        "finalDefaultLongField"),
+                        JavaConstant.forLong(
+                                        DUMMY_CLASS_INSTANCE.finalDefaultLongField));
         INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                   "finalDefaultFloatField"),
-                                              JavaConstant.forFloat(
-                                                      DUMMY_CLASS_INSTANCE.finalDefaultFloatField));
+                        "finalDefaultFloatField"),
+                        JavaConstant.forFloat(
+                                        DUMMY_CLASS_INSTANCE.finalDefaultFloatField));
         INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                   "finalDefaultDoubleField"),
-                                              JavaConstant.forDouble(
-                                                      DUMMY_CLASS_INSTANCE.finalDefaultDoubleField));
+                        "finalDefaultDoubleField"),
+                        JavaConstant.forDouble(
+                                        DUMMY_CLASS_INSTANCE.finalDefaultDoubleField));
         INSTANCE_FINAL_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                   "finalDefaultObjectField"),
-                                              CONSTANT_REFLECTION_PROVIDER.forObject(
-                                                      DUMMY_CLASS_INSTANCE.finalDefaultObjectField));
+                        "finalDefaultObjectField"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.finalDefaultObjectField));
     }
 
-    public static final Map<ResolvedJavaField, JavaConstant> INSTANCE_STABLE_FIELDS_MAP
-            = new HashMap<>();
+    public static final Map<ResolvedJavaField, JavaConstant> INSTANCE_STABLE_FIELDS_MAP = new HashMap<>();
 
     static {
         INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableBooleanField"),
-                                       JavaConstant.forBoolean(
-                                               DUMMY_CLASS_INSTANCE.stableBooleanField));
+                        JavaConstant.forBoolean(
+                                        DUMMY_CLASS_INSTANCE.stableBooleanField));
         INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableByteField"),
-                                       JavaConstant.forByte(DUMMY_CLASS_INSTANCE.stableByteField));
+                        JavaConstant.forByte(DUMMY_CLASS_INSTANCE.stableByteField));
         INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableShortField"),
-                                       JavaConstant.forShort(
-                                               DUMMY_CLASS_INSTANCE.stableShortField));
+                        JavaConstant.forShort(
+                                        DUMMY_CLASS_INSTANCE.stableShortField));
         INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableCharField"),
-                                       JavaConstant.forChar(DUMMY_CLASS_INSTANCE.stableCharField));
+                        JavaConstant.forChar(DUMMY_CLASS_INSTANCE.stableCharField));
         INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableIntField"),
-                                       JavaConstant.forInt(DUMMY_CLASS_INSTANCE.stableIntField));
+                        JavaConstant.forInt(DUMMY_CLASS_INSTANCE.stableIntField));
         INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableLongField"),
-                                       JavaConstant.forLong(DUMMY_CLASS_INSTANCE.stableLongField));
+                        JavaConstant.forLong(DUMMY_CLASS_INSTANCE.stableLongField));
         INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableFloatField"),
-                                       JavaConstant.forFloat(
-                                               DUMMY_CLASS_INSTANCE.stableFloatField));
+                        JavaConstant.forFloat(
+                                        DUMMY_CLASS_INSTANCE.stableFloatField));
         INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableDoubleField"),
-                                       JavaConstant.forDouble(
-                                               DUMMY_CLASS_INSTANCE.stableDoubleField));
+                        JavaConstant.forDouble(
+                                        DUMMY_CLASS_INSTANCE.stableDoubleField));
         INSTANCE_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "stableObjectField"),
-                                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                                               DUMMY_CLASS_INSTANCE.stableObjectField));
-    }
-
-    public static final Map<ResolvedJavaField, JavaConstant> INSTANCE_STABLE_DEFAULT_FIELDS_MAP
-            = new HashMap<>();
-
-    static {
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                    "stableDefaultBooleanField"),
-                                               JavaConstant.forBoolean(
-                                                       DUMMY_CLASS_INSTANCE.stableDefaultBooleanField));
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                    "stableDefaultByteField"),
-                                               JavaConstant.forByte(
-                                                       DUMMY_CLASS_INSTANCE.stableDefaultByteField));
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                    "stableDefaultShortField"),
-                                               JavaConstant.forShort(
-                                                       DUMMY_CLASS_INSTANCE.stableDefaultShortField));
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                    "stableDefaultCharField"),
-                                               JavaConstant.forChar(
-                                                       DUMMY_CLASS_INSTANCE.stableDefaultCharField));
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                    "stableDefaultIntField"),
-                                               JavaConstant.forInt(
-                                                       DUMMY_CLASS_INSTANCE.stableDefaultIntField));
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                    "stableDefaultLongField"),
-                                               JavaConstant.forLong(
-                                                       DUMMY_CLASS_INSTANCE.stableDefaultLongField));
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                    "stableDefaultFloatField"),
-                                               JavaConstant.forFloat(
-                                                       DUMMY_CLASS_INSTANCE.stableDefaultFloatField));
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                    "stableDefaultDoubleField"),
-                                               JavaConstant.forDouble(
-                                                       DUMMY_CLASS_INSTANCE.stableDefaultDoubleField));
-        INSTANCE_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                    "stableDefaultObjectField"),
-                                               CONSTANT_REFLECTION_PROVIDER.forObject(
-                                                       DUMMY_CLASS_INSTANCE.stableDefaultObjectField));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableObjectField));
     }
 
     public static final Map<ResolvedJavaField, JavaConstant> STATIC_FIELDS_MAP = new HashMap<>();
 
     static {
         STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticBooleanField"),
-                              JavaConstant.forBoolean(DummyClass.staticBooleanField));
+                        JavaConstant.forBoolean(DummyClass.staticBooleanField));
         STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticByteField"),
-                              JavaConstant.forByte(DummyClass.staticByteField));
+                        JavaConstant.forByte(DummyClass.staticByteField));
         STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticShortField"),
-                              JavaConstant.forShort(DummyClass.staticShortField));
+                        JavaConstant.forShort(DummyClass.staticShortField));
         STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticCharField"),
-                              JavaConstant.forChar(DummyClass.staticCharField));
+                        JavaConstant.forChar(DummyClass.staticCharField));
         STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticIntField"),
-                              JavaConstant.forInt(DummyClass.staticIntField));
+                        JavaConstant.forInt(DummyClass.staticIntField));
         STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticLongField"),
-                              JavaConstant.forLong(DummyClass.staticLongField));
+                        JavaConstant.forLong(DummyClass.staticLongField));
         STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFloatField"),
-                              JavaConstant.forFloat(DummyClass.staticFloatField));
+                        JavaConstant.forFloat(DummyClass.staticFloatField));
         STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticDoubleField"),
-                              JavaConstant.forDouble(DummyClass.staticDoubleField));
+                        JavaConstant.forDouble(DummyClass.staticDoubleField));
         STATIC_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticObjectField"),
-                              CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticObjectField));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticObjectField));
     }
 
-    public static final Map<ResolvedJavaField, JavaConstant> STATIC_FINAL_FIELDS_MAP
-            = new HashMap<>();
+    public static final Map<ResolvedJavaField, JavaConstant> STATIC_FINAL_FIELDS_MAP = new HashMap<>();
 
     static {
         STATIC_FINAL_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticFinalBooleanField"),
-                JavaConstant.forBoolean(DummyClass.staticFinalBooleanField));
+                        getResolvedJavaField(DummyClass.class, "staticFinalBooleanField"),
+                        JavaConstant.forBoolean(DummyClass.staticFinalBooleanField));
         STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalByteField"),
-                                    JavaConstant.forByte(DummyClass.staticFinalByteField));
+                        JavaConstant.forByte(DummyClass.staticFinalByteField));
         STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalShortField"),
-                                    JavaConstant.forShort(DummyClass.staticFinalShortField));
+                        JavaConstant.forShort(DummyClass.staticFinalShortField));
         STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalCharField"),
-                                    JavaConstant.forChar(DummyClass.staticFinalCharField));
+                        JavaConstant.forChar(DummyClass.staticFinalCharField));
         STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalIntField"),
-                                    JavaConstant.forInt(DummyClass.staticFinalIntField));
+                        JavaConstant.forInt(DummyClass.staticFinalIntField));
         STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalLongField"),
-                                    JavaConstant.forLong(DummyClass.staticFinalLongField));
+                        JavaConstant.forLong(DummyClass.staticFinalLongField));
         STATIC_FINAL_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticFinalFloatField"),
-                                    JavaConstant.forFloat(DummyClass.staticFinalFloatField));
+                        JavaConstant.forFloat(DummyClass.staticFinalFloatField));
         STATIC_FINAL_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticFinalDoubleField"),
-                JavaConstant.forDouble(DummyClass.staticFinalDoubleField));
+                        getResolvedJavaField(DummyClass.class, "staticFinalDoubleField"),
+                        JavaConstant.forDouble(DummyClass.staticFinalDoubleField));
         STATIC_FINAL_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticFinalObjectField"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticFinalObjectField));
+                        getResolvedJavaField(DummyClass.class, "staticFinalObjectField"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticFinalObjectField));
     }
 
-    public static final Map<ResolvedJavaField, JavaConstant> STATIC_STABLE_FIELDS_MAP
-            = new HashMap<>();
+    public static final Map<ResolvedJavaField, JavaConstant> STATIC_STABLE_FIELDS_MAP = new HashMap<>();
 
     static {
         STATIC_STABLE_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticStableBooleanField"),
-                JavaConstant.forBoolean(DummyClass.staticStableBooleanField));
+                        getResolvedJavaField(DummyClass.class, "staticStableBooleanField"),
+                        JavaConstant.forBoolean(DummyClass.staticStableBooleanField));
         STATIC_STABLE_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticStableByteField"),
-                JavaConstant.forByte(DummyClass.staticStableByteField));
+                        getResolvedJavaField(DummyClass.class, "staticStableByteField"),
+                        JavaConstant.forByte(DummyClass.staticStableByteField));
         STATIC_STABLE_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticStableShortField"),
-                JavaConstant.forShort(DummyClass.staticStableShortField));
+                        getResolvedJavaField(DummyClass.class, "staticStableShortField"),
+                        JavaConstant.forShort(DummyClass.staticStableShortField));
         STATIC_STABLE_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticStableCharField"),
-                JavaConstant.forChar(DummyClass.staticStableCharField));
+                        getResolvedJavaField(DummyClass.class, "staticStableCharField"),
+                        JavaConstant.forChar(DummyClass.staticStableCharField));
         STATIC_STABLE_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class, "staticStableIntField"),
-                                     JavaConstant.forInt(DummyClass.staticStableIntField));
+                        JavaConstant.forInt(DummyClass.staticStableIntField));
         STATIC_STABLE_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticStableLongField"),
-                JavaConstant.forLong(DummyClass.staticStableLongField));
+                        getResolvedJavaField(DummyClass.class, "staticStableLongField"),
+                        JavaConstant.forLong(DummyClass.staticStableLongField));
         STATIC_STABLE_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticStableFloatField"),
-                JavaConstant.forFloat(DummyClass.staticStableFloatField));
+                        getResolvedJavaField(DummyClass.class, "staticStableFloatField"),
+                        JavaConstant.forFloat(DummyClass.staticStableFloatField));
         STATIC_STABLE_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticStableDoubleField"),
-                JavaConstant.forDouble(DummyClass.staticStableDoubleField));
+                        getResolvedJavaField(DummyClass.class, "staticStableDoubleField"),
+                        JavaConstant.forDouble(DummyClass.staticStableDoubleField));
         STATIC_STABLE_FIELDS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "staticStableObjectField"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticStableObjectField));
+                        getResolvedJavaField(DummyClass.class, "staticStableObjectField"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(DummyClass.staticStableObjectField));
     }
 
-    public static final Map<ResolvedJavaField, JavaConstant> STATIC_STABLE_DEFAULT_FIELDS_MAP
-            = new HashMap<>();
+    public static final Map<ResolvedJavaField, JavaConstant> STATIC_STABLE_DEFAULT_FIELDS_MAP = new HashMap<>();
 
     static {
         STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                  "staticStableDefaultBooleanField"),
-                                             JavaConstant.forBoolean(
-                                                     DummyClass.staticStableDefaultBooleanField));
+                        "staticStableDefaultBooleanField"),
+                        JavaConstant.forBoolean(
+                                        DummyClass.staticStableDefaultBooleanField));
         STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                  "staticStableDefaultByteField"),
-                                             JavaConstant.forByte(
-                                                     DummyClass.staticStableDefaultByteField));
+                        "staticStableDefaultByteField"),
+                        JavaConstant.forByte(
+                                        DummyClass.staticStableDefaultByteField));
         STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                  "staticStableDefaultShortField"),
-                                             JavaConstant.forShort(
-                                                     DummyClass.staticStableDefaultShortField));
+                        "staticStableDefaultShortField"),
+                        JavaConstant.forShort(
+                                        DummyClass.staticStableDefaultShortField));
         STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                  "staticStableDefaultCharField"),
-                                             JavaConstant.forChar(
-                                                     DummyClass.staticStableDefaultCharField));
+                        "staticStableDefaultCharField"),
+                        JavaConstant.forChar(
+                                        DummyClass.staticStableDefaultCharField));
         STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                  "staticStableDefaultIntField"),
-                                             JavaConstant.forInt(
-                                                     DummyClass.staticStableDefaultIntField));
+                        "staticStableDefaultIntField"),
+                        JavaConstant.forInt(
+                                        DummyClass.staticStableDefaultIntField));
         STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                  "staticStableDefaultLongField"),
-                                             JavaConstant.forLong(
-                                                     DummyClass.staticStableDefaultLongField));
+                        "staticStableDefaultLongField"),
+                        JavaConstant.forLong(
+                                        DummyClass.staticStableDefaultLongField));
         STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                  "staticStableDefaultFloatField"),
-                                             JavaConstant.forFloat(
-                                                     DummyClass.staticStableDefaultFloatField));
+                        "staticStableDefaultFloatField"),
+                        JavaConstant.forFloat(
+                                        DummyClass.staticStableDefaultFloatField));
         STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                  "staticStableDefaultDoubleField"),
-                                             JavaConstant.forDouble(
-                                                     DummyClass.staticStableDefaultDoubleField));
+                        "staticStableDefaultDoubleField"),
+                        JavaConstant.forDouble(
+                                        DummyClass.staticStableDefaultDoubleField));
         STATIC_STABLE_DEFAULT_FIELDS_MAP.put(getResolvedJavaField(DummyClass.class,
-                                                                  "staticStableDefaultObjectField"),
-                                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                                     DummyClass.staticStableDefaultObjectField));
+                        "staticStableDefaultObjectField"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DummyClass.staticStableDefaultObjectField));
     }
 
     public static final int ARRAY_DIMENSION = 1;
@@ -336,138 +285,138 @@
 
     static {
         ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "booleanArrayWithValues"),
-                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                               DUMMY_CLASS_INSTANCE.booleanArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.booleanArrayWithValues));
         ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "byteArrayWithValues"),
-                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                               DUMMY_CLASS_INSTANCE.byteArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.byteArrayWithValues));
         ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "shortArrayWithValues"),
-                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                               DUMMY_CLASS_INSTANCE.shortArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.shortArrayWithValues));
         ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "charArrayWithValues"),
-                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                               DUMMY_CLASS_INSTANCE.charArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.charArrayWithValues));
         ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "intArrayWithValues"),
-                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                               DUMMY_CLASS_INSTANCE.intArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.intArrayWithValues));
         ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "longArrayWithValues"),
-                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                               DUMMY_CLASS_INSTANCE.longArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.longArrayWithValues));
         ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "floatArrayWithValues"),
-                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                               DUMMY_CLASS_INSTANCE.floatArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.floatArrayWithValues));
         ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "doubleArrayWithValues"),
-                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                               DUMMY_CLASS_INSTANCE.doubleArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.doubleArrayWithValues));
         ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "objectArrayWithValues"),
-                       CONSTANT_REFLECTION_PROVIDER.forObject(
-                               DUMMY_CLASS_INSTANCE.objectArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.objectArrayWithValues));
     }
 
     public static final Map<ResolvedJavaField, JavaConstant> STABLE_ARRAYS_MAP = new HashMap<>();
 
     static {
         STABLE_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableBooleanArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableBooleanArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableBooleanArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableBooleanArrayWithValues));
         STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableByteArrayWithValues"),
-                              CONSTANT_REFLECTION_PROVIDER.forObject(
-                                      DUMMY_CLASS_INSTANCE.stableByteArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableByteArrayWithValues));
         STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableShortArrayWithValues"),
-                              CONSTANT_REFLECTION_PROVIDER.forObject(
-                                      DUMMY_CLASS_INSTANCE.stableShortArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableShortArrayWithValues));
         STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableCharArrayWithValues"),
-                              CONSTANT_REFLECTION_PROVIDER.forObject(
-                                      DUMMY_CLASS_INSTANCE.stableCharArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableCharArrayWithValues));
         STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableIntArrayWithValues"),
-                              CONSTANT_REFLECTION_PROVIDER.forObject(
-                                      DUMMY_CLASS_INSTANCE.stableIntArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableIntArrayWithValues));
         STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableLongArrayWithValues"),
-                              CONSTANT_REFLECTION_PROVIDER.forObject(
-                                      DUMMY_CLASS_INSTANCE.stableLongArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableLongArrayWithValues));
         STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableFloatArrayWithValues"),
-                              CONSTANT_REFLECTION_PROVIDER.forObject(
-                                      DUMMY_CLASS_INSTANCE.stableFloatArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableFloatArrayWithValues));
         STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableDoubleArrayWithValues"),
-                              CONSTANT_REFLECTION_PROVIDER.forObject(
-                                      DUMMY_CLASS_INSTANCE.stableDoubleArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableDoubleArrayWithValues));
         STABLE_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "stableObjectArrayWithValues"),
-                              CONSTANT_REFLECTION_PROVIDER.forObject(
-                                      DUMMY_CLASS_INSTANCE.stableObjectArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableObjectArrayWithValues));
     }
 
     public static final Map<ResolvedJavaField, JavaConstant> ARRAY_ARRAYS_MAP = new HashMap<>();
 
     static {
         ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "booleanArrayArrayWithValues"),
-                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                     DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.booleanArrayArrayWithValues));
         ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "byteArrayArrayWithValues"),
-                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                     DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.byteArrayArrayWithValues));
         ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "shortArrayArrayWithValues"),
-                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                     DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.shortArrayArrayWithValues));
         ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "charArrayArrayWithValues"),
-                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                     DUMMY_CLASS_INSTANCE.charArrayArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.charArrayArrayWithValues));
         ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "intArrayArrayWithValues"),
-                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                     DUMMY_CLASS_INSTANCE.intArrayArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.intArrayArrayWithValues));
         ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "longArrayArrayWithValues"),
-                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                     DUMMY_CLASS_INSTANCE.longArrayArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.longArrayArrayWithValues));
         ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "floatArrayArrayWithValues"),
-                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                     DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.floatArrayArrayWithValues));
         ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "doubleArrayArrayWithValues"),
-                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                     DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.doubleArrayArrayWithValues));
         ARRAY_ARRAYS_MAP.put(getResolvedJavaField(DummyClass.class, "objectArrayArrayWithValues"),
-                             CONSTANT_REFLECTION_PROVIDER.forObject(
-                                     DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues));
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.objectArrayArrayWithValues));
     }
 
     public static final Map<ResolvedJavaField, JavaConstant> STABLE_ARRAY_ARRAYS_MAP = new HashMap<>();
 
     static {
         STABLE_ARRAY_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableBooleanArrayArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableBooleanArrayArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableBooleanArrayArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableBooleanArrayArrayWithValues));
         STABLE_ARRAY_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableByteArrayArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableByteArrayArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableByteArrayArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableByteArrayArrayWithValues));
         STABLE_ARRAY_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableShortArrayArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableShortArrayArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableShortArrayArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableShortArrayArrayWithValues));
         STABLE_ARRAY_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableCharArrayArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableCharArrayArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableCharArrayArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableCharArrayArrayWithValues));
         STABLE_ARRAY_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableIntArrayArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableIntArrayArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableIntArrayArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableIntArrayArrayWithValues));
         STABLE_ARRAY_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableLongArrayArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableLongArrayArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableLongArrayArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableLongArrayArrayWithValues));
         STABLE_ARRAY_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableFloatArrayArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableFloatArrayArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableFloatArrayArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableFloatArrayArrayWithValues));
         STABLE_ARRAY_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableDoubleArrayArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableDoubleArrayArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableDoubleArrayArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableDoubleArrayArrayWithValues));
         STABLE_ARRAY_ARRAYS_MAP.put(
-                getResolvedJavaField(DummyClass.class, "stableObjectArrayArrayWithValues"),
-                CONSTANT_REFLECTION_PROVIDER.forObject(
-                        DUMMY_CLASS_INSTANCE.stableObjectArrayArrayWithValues));
+                        getResolvedJavaField(DummyClass.class, "stableObjectArrayArrayWithValues"),
+                        CONSTANT_REFLECTION_PROVIDER.forObject(
+                                        DUMMY_CLASS_INSTANCE.stableObjectArrayArrayWithValues));
     }
 
     public static ResolvedJavaField getResolvedJavaField(Class<?> clazz, String fieldName) {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/UnboxPrimitiveDataProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.hotspot.test/src/jdk/vm/ci/hotspot/test/UnboxPrimitiveDataProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -38,32 +38,32 @@
         LinkedList<Object[]> cfgSet = new LinkedList<>();
         // Testing boolean
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(
-                (Boolean) true), JavaConstant.forBoolean(true)});
+                        true), JavaConstant.forBoolean(true)});
         cfgSet.add(new Object[]{JavaConstant.forBoolean(true), null});
-        cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject((Boolean) false),
-                JavaConstant.forBoolean(false)});
+        cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(false),
+                        JavaConstant.forBoolean(false)});
         cfgSet.add(new Object[]{JavaConstant.forBoolean(false), null});
         for (byte number : new byte[]{-128, 0, 1, 127}) {
             // Testing boxed primitives
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Byte.valueOf(number)),
-                    JavaConstant.forByte(number)});
+                            JavaConstant.forByte(number)});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Short.valueOf(number)),
-                    JavaConstant.forShort(number)});
+                            JavaConstant.forShort(number)});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Integer.valueOf(number)),
-                    JavaConstant.forInt(number)});
+                            JavaConstant.forInt(number)});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Long.valueOf(number)),
-                    JavaConstant.forLong(number)});
+                            JavaConstant.forLong(number)});
             if (number >= 0) {
                 cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(
-                        Character.valueOf((char) number)),
-                        JavaConstant.forChar((char) number)});
+                                Character.valueOf((char) number)),
+                                JavaConstant.forChar((char) number)});
             }
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(
-                    Float.valueOf(number * 1.1f)),
-                    JavaConstant.forFloat(number * 1.1f)});
+                            Float.valueOf(number * 1.1f)),
+                            JavaConstant.forFloat(number * 1.1f)});
             cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(
-                    Double.valueOf(number * 1.1)),
-                    JavaConstant.forDouble(number * 1.1)});
+                            Double.valueOf(number * 1.1)),
+                            JavaConstant.forDouble(number * 1.1)});
             // Testing non-boxed primitives (should result in returning of "null")
             cfgSet.add(new Object[]{JavaConstant.forByte(number), null});
             cfgSet.add(new Object[]{JavaConstant.forShort(number), null});
@@ -75,23 +75,23 @@
         }
         // Testing boxed primitives with max values
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Short.MAX_VALUE),
-                JavaConstant.forShort(Short.MAX_VALUE)});
+                        JavaConstant.forShort(Short.MAX_VALUE)});
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Integer.MAX_VALUE),
-                JavaConstant.forInt(Integer.MAX_VALUE)});
+                        JavaConstant.forInt(Integer.MAX_VALUE)});
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Long.MAX_VALUE),
-                JavaConstant.forLong(Long.MAX_VALUE)});
+                        JavaConstant.forLong(Long.MAX_VALUE)});
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Character.MAX_VALUE),
-                JavaConstant.forChar(Character.MAX_VALUE)});
+                        JavaConstant.forChar(Character.MAX_VALUE)});
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Float.MAX_VALUE),
-                JavaConstant.forFloat(Float.MAX_VALUE)});
+                        JavaConstant.forFloat(Float.MAX_VALUE)});
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(Double.MAX_VALUE),
-                JavaConstant.forDouble(Double.MAX_VALUE)});
+                        JavaConstant.forDouble(Double.MAX_VALUE)});
         // Non-primitives testing
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(
-                DUMMY_CLASS_INSTANCE.objectField), null});
+                        DUMMY_CLASS_INSTANCE.objectField), null});
         cfgSet.add(new Object[]{CONSTANT_REFLECTION_PROVIDER.forObject(
-                DUMMY_CLASS_INSTANCE.booleanArrayWithValues),
-                null});
+                        DUMMY_CLASS_INSTANCE.booleanArrayWithValues),
+                        null});
         // Null testing
         cfgSet.add(new Object[]{JavaConstant.NULL_POINTER, null});
         cfgSet.add(new Object[]{null, null});
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantTest.java	Fri May 20 18:05:09 2016 +0300
@@ -34,12 +34,11 @@
 // * @compile ConstantTest.java FieldUniverse.java TypeUniverse.java TestMetaAccessProvider.java
 package jdk.vm.ci.runtime.test;
 
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.JavaKind;
-
 import org.junit.Assert;
 import org.junit.Test;
 
+import jdk.vm.ci.meta.JavaConstant;
+
 public class ConstantTest extends FieldUniverse {
 
     @Test
@@ -52,30 +51,4 @@
     public void testNullIsNull() {
         Assert.assertTrue(JavaConstant.NULL_POINTER.isNull());
     }
-
-    @Test
-    public void testOne() {
-        for (JavaKind kind : JavaKind.values()) {
-            if (kind.isNumericInteger() || kind.isNumericFloat()) {
-                Assert.assertTrue(JavaConstant.one(kind).getJavaKind() == kind);
-            }
-        }
-        Assert.assertEquals(1, JavaConstant.one(JavaKind.Int).asInt());
-        Assert.assertEquals(1L, JavaConstant.one(JavaKind.Long).asLong());
-        Assert.assertEquals(1, JavaConstant.one(JavaKind.Byte).asInt());
-        Assert.assertEquals(1, JavaConstant.one(JavaKind.Short).asInt());
-        Assert.assertEquals(1, JavaConstant.one(JavaKind.Char).asInt());
-        Assert.assertTrue(1F == JavaConstant.one(JavaKind.Float).asFloat());
-        Assert.assertTrue(1D == JavaConstant.one(JavaKind.Double).asDouble());
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testIllegalOne() {
-        JavaConstant.one(JavaKind.Illegal);
-    }
-
-    @Test(expected = IllegalArgumentException.class)
-    public void testVoidOne() {
-        JavaConstant.one(JavaKind.Void);
-    }
 }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java	Fri May 20 18:05:09 2016 +0300
@@ -37,10 +37,13 @@
 import static jdk.vm.ci.meta.MetaUtil.toInternalName;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import jdk.vm.ci.meta.DeoptimizationAction;
+import jdk.vm.ci.meta.DeoptimizationReason;
 
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.JavaKind;
@@ -48,6 +51,7 @@
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
 
 import org.junit.Test;
 
@@ -55,6 +59,16 @@
  * Tests for {@link MetaAccessProvider}.
  */
 public class TestMetaAccessProvider extends TypeUniverse {
+    private static final DeoptimizationAction DEOPT_ACTION = DeoptimizationAction.InvalidateRecompile;
+    private static final DeoptimizationReason DEOPT_REASON = DeoptimizationReason.Aliasing;
+    private static final int INT_23BITS_SET = 0x7FFFFF;
+    private static final int[] DEBUG_IDS = new int[]{0, 1, 42, INT_23BITS_SET};
+    private static final int[] VALID_ENCODED_VALUES = new int[]{
+                    metaAccess.encodeDeoptActionAndReason(DEOPT_ACTION, DEOPT_REASON, DEBUG_IDS[0]).asInt(),
+                    metaAccess.encodeDeoptActionAndReason(DEOPT_ACTION, DEOPT_REASON, DEBUG_IDS[1]).asInt(),
+                    metaAccess.encodeDeoptActionAndReason(DEOPT_ACTION, DEOPT_REASON, DEBUG_IDS[2]).asInt(),
+                    metaAccess.encodeDeoptActionAndReason(DEOPT_ACTION, DEOPT_REASON, DEBUG_IDS[3]).asInt()
+    };
 
     @Test
     public void lookupJavaTypeTest() {
@@ -70,6 +84,37 @@
         }
     }
 
+    @Test(expected = IllegalArgumentException.class)
+    public void lookupJavaTypeNegativeTest() {
+        metaAccess.lookupJavaType((Class<?>) null);
+    }
+
+    @Test
+    public void lookupJavaTypesTest() {
+        ResolvedJavaType[] result = metaAccess.lookupJavaTypes(classes.toArray(new Class<?>[classes.size()]));
+        int counter = 0;
+        for (Class<?> aClass : classes) {
+            assertEquals("Unexpected javaType: " + result[counter] + " while expecting of class: " + aClass, result[counter].toClassName(), aClass.getName());
+            counter++;
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void lookupJavaTypesNegative1Test() {
+        assertNull("Expected null", metaAccess.lookupJavaTypes(null));
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void lookupJavaTypesNegative2Test() {
+        ResolvedJavaType[] result = metaAccess.lookupJavaTypes(new Class<?>[]{null, null, null});
+        for (ResolvedJavaType aType : result) {
+            assertNull("Expected null javaType", aType);
+        }
+        result = metaAccess.lookupJavaTypes(new Class<?>[]{String.class, String.class});
+        assertEquals("Results not equals", result[0].getClass(), result[1].getClass());
+        assertEquals("Result is not String.class", result[0].getClass(), String.class);
+    }
+
     @Test
     public void lookupJavaMethodTest() {
         for (Class<?> c : classes) {
@@ -81,6 +126,11 @@
         }
     }
 
+    @Test(expected = NullPointerException.class)
+    public void lookupJavaMethodNegativeTest() {
+        metaAccess.lookupJavaMethod(null);
+    }
+
     @Test
     public void lookupJavaFieldTest() {
         for (Class<?> c : classes) {
@@ -106,4 +156,107 @@
             }
         }
     }
+
+    @Test(expected = NullPointerException.class)
+    public void lookupJavaTypeConstantNegativeTest() {
+        metaAccess.lookupJavaType((JavaConstant) null);
+    }
+
+    @Test
+    public void getMemorySizeTest() {
+        for (ConstantValue cv : constants()) {
+            JavaConstant c = cv.value;
+            long memSize = metaAccess.getMemorySize(c);
+            if (c.isNull()) {
+                assertEquals("Expected size = 0 for null", memSize, 0L);
+            } else {
+                assertTrue("Expected size != 0 for " + cv, memSize != 0L);
+            }
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void getMemorySizeNegativeTest() {
+        metaAccess.getMemorySize(null);
+    }
+
+    @Test
+    public void parseMethodDescriptorTest() {
+        for (String retType : new String[]{"V", "Z", "Ljava/lang/String;"}) {
+            for (String paramTypes : new String[]{"", "B",
+                            "Ljava/lang/String;", "JLjava/lang/String;",
+                            "Ljava/lang/String;F",
+                            "[Ljava/lang/String;ZBCDFIJLS[ILjava/lang/Object;"}) {
+                String signature = "(" + paramTypes + ")" + retType;
+                Signature result = metaAccess.parseMethodDescriptor(signature);
+                assertEquals("Expected signatures to be equal", result.toMethodDescriptor(), signature);
+            }
+        }
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void parseMethodDescriptorNegativeNullTest() {
+        metaAccess.parseMethodDescriptor(null);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void encodeDeoptActionAndReasonNegative1Test() {
+        metaAccess.encodeDeoptActionAndReason(null, DeoptimizationReason.Aliasing, 0);
+
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void encodeDeoptActionAndReasonNegative2Test() {
+        metaAccess.encodeDeoptActionAndReason(DeoptimizationAction.InvalidateRecompile, null, 0);
+    }
+
+    @Test
+    public void decodeDeoptReasonTest() {
+        for (int encoded : VALID_ENCODED_VALUES) {
+            JavaConstant value = JavaConstant.forInt(encoded);
+            DeoptimizationReason reason = metaAccess.decodeDeoptReason(value);
+            assertEquals("Expected equal reasons", reason, DEOPT_REASON);
+        }
+    }
+
+    @Test
+    public void decodeDeoptReasonNegative1Test() {
+        int encoded = 42;
+        JavaConstant value = JavaConstant.forInt(encoded);
+        metaAccess.decodeDeoptReason(value);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void decodeDeoptReasonNegative2Test() {
+        metaAccess.decodeDeoptReason(null);
+    }
+
+    @Test
+    public void decodeDeoptActionTest() {
+        for (int encoded : VALID_ENCODED_VALUES) {
+            JavaConstant value = JavaConstant.forInt(encoded);
+            DeoptimizationAction action = metaAccess.decodeDeoptAction(value);
+            assertEquals("Expected equal actions", action, DEOPT_ACTION);
+        }
+    }
+
+    @Test
+    public void decodeDeoptActionNegative1Test() {
+        int encoded = 123456789;
+        JavaConstant value = JavaConstant.forInt(encoded);
+        metaAccess.decodeDeoptAction(value);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void decodeDeoptActionNegative2Test() {
+        metaAccess.decodeDeoptAction(null);
+    }
+
+    @Test
+    public void decodeDebugIdTest() {
+        for (int i = 0; i < VALID_ENCODED_VALUES.length; i++) {
+            JavaConstant value = JavaConstant.forInt(VALID_ENCODED_VALUES[i]);
+            assertEquals("Unexpected debugId", metaAccess.decodeDebugId(value), DEBUG_IDS[i]);
+        }
+    }
 }
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaField.java	Fri May 20 18:05:09 2016 +0300
@@ -37,7 +37,6 @@
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.lang.annotation.Annotation;
@@ -45,12 +44,9 @@
 import java.lang.reflect.Method;
 import java.util.Arrays;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.LocationIdentity;
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
@@ -103,43 +99,6 @@
         }
     }
 
-    @Test
-    public void getLocationIdentityTest() {
-        for (Map.Entry<Field, ResolvedJavaField> e : fields.entrySet()) {
-            LocationIdentity identity = e.getValue().getLocationIdentity();
-            assertTrue(identity != null);
-        }
-    }
-
-    static class ReadConstantValueTestConstants {
-        String stringField = "field";
-        final String constantStringField = "constantField";
-
-        static final Object CONST1 = new ReadConstantValueTestConstants();
-        static final Object CONST2 = null;
-        static final Object CONST3 = new String();
-    }
-
-    @Test
-    public void readConstantValueTest() throws NoSuchFieldException {
-        ResolvedJavaField field = metaAccess.lookupJavaField(ReadConstantValueTestConstants.class.getDeclaredField("stringField"));
-        List<ConstantValue> receiverConstants = readConstants(ReadConstantValueTestConstants.class);
-        for (ConstantValue receiver : receiverConstants) {
-            JavaConstant value = constantReflection.readConstantFieldValue(field, receiver.value);
-            assertNull(value);
-        }
-
-        ResolvedJavaField constField = metaAccess.lookupJavaField(ReadConstantValueTestConstants.class.getDeclaredField("constantStringField"));
-        for (ConstantValue receiver : receiverConstants) {
-            JavaConstant value = constantReflection.readConstantFieldValue(constField, receiver.value);
-            if (value != null) {
-                Object expected = "constantField";
-                String actual = ((ReadConstantValueTestConstants) receiver.boxed).constantStringField;
-                assertTrue(actual + " != " + expected, actual == expected);
-            }
-        }
-    }
-
     private Method findTestMethod(Method apiMethod) {
         String testName = apiMethod.getName() + "Test";
         for (Method m : getClass().getDeclaredMethods()) {
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -68,7 +68,6 @@
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.TrustedInterface;
 
 import org.junit.Test;
 
@@ -184,34 +183,6 @@
         }
     }
 
-    private static Class<?> asExactClass(Class<?> c) {
-        if (c.isArray()) {
-            if (asExactClass(c.getComponentType()) != null) {
-                return c;
-            }
-        } else {
-            if (c.isPrimitive() || Modifier.isFinal(c.getModifiers())) {
-                return c;
-            }
-        }
-        return null;
-    }
-
-    @Test
-    public void asExactTypeTest() {
-        for (Class<?> c : classes) {
-            ResolvedJavaType type = metaAccess.lookupJavaType(c);
-            ResolvedJavaType exactType = type.asExactType();
-            Class<?> expected = asExactClass(c);
-            if (expected == null) {
-                assertTrue("exact(" + c.getName() + ") != null", exactType == null);
-            } else {
-                assertNotNull(exactType);
-                assertTrue(exactType.equals(metaAccess.lookupJavaType(expected)));
-            }
-        }
-    }
-
     @Test
     public void getSuperclassTest() {
         for (Class<?> c : classes) {
@@ -329,6 +300,7 @@
             } else {
                 assertTrue(leafConcreteSubtype.getResult().equals(expected));
             }
+            assertTrue(!type.isLeaf() || leafConcreteSubtype.isAssumptionFree());
         }
 
         if (!type.isArray()) {
@@ -373,8 +345,10 @@
 
         ResolvedJavaType a1a = metaAccess.lookupJavaType(Abstract1[].class);
         checkConcreteSubtype(a1a, null);
+        ResolvedJavaType i1a = metaAccess.lookupJavaType(Interface1[].class);
+        checkConcreteSubtype(i1a, null);
         ResolvedJavaType c1a = metaAccess.lookupJavaType(Concrete1[].class);
-        checkConcreteSubtype(c1a, null);
+        checkConcreteSubtype(c1a, c1a);
         ResolvedJavaType f1a = metaAccess.lookupJavaType(Final1[].class);
         checkConcreteSubtype(f1a, f1a);
 
@@ -842,16 +816,6 @@
     }
 
     @Test
-    public void isTrustedInterfaceTypeTest() {
-        for (Class<?> c : classes) {
-            ResolvedJavaType type = metaAccess.lookupJavaType(c);
-            if (TrustedInterface.class.isAssignableFrom(c)) {
-                assertTrue(type.isTrustedInterfaceType());
-            }
-        }
-    }
-
-    @Test
     public void isLeafTest() {
         for (Class<?> c : classes) {
             ResolvedJavaType type = metaAccess.lookupJavaType(c);
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TypeUniverse.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,15 +52,12 @@
 import jdk.vm.ci.meta.MetaAccessProvider;
 import jdk.vm.ci.meta.ResolvedJavaField;
 import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.TrustedInterface;
 import jdk.vm.ci.runtime.JVMCI;
 
 import org.junit.Test;
 
 import jdk.internal.misc.Unsafe;
 
-//JaCoCo Exclude
-
 /**
  * Context for type related tests.
  */
@@ -116,8 +113,8 @@
                         byte[].class, short[].class, char[].class, int[].class, float[].class, long[].class, double[].class, Object[].class, Class[].class, List[].class, boolean[][].class,
                         byte[][].class, short[][].class, char[][].class, int[][].class, float[][].class, long[][].class, double[][].class, Object[][].class, Class[][].class, List[][].class,
                         ClassLoader.class, String.class, Serializable.class, Cloneable.class, Test.class, TestMetaAccessProvider.class, List.class, Collection.class, Map.class, Queue.class,
-                        HashMap.class, LinkedHashMap.class, IdentityHashMap.class, AbstractCollection.class, AbstractList.class, ArrayList.class, TrustedInterface.class, InnerClass.class,
-                        InnerStaticClass.class, InnerStaticFinalClass.class, PrivateInnerClass.class, ProtectedInnerClass.class};
+                        HashMap.class, LinkedHashMap.class, IdentityHashMap.class, AbstractCollection.class, AbstractList.class, ArrayList.class, InnerClass.class, InnerStaticClass.class,
+                        InnerStaticFinalClass.class, PrivateInnerClass.class, ProtectedInnerClass.class};
         for (Class<?> c : initialClasses) {
             addClass(c);
         }
@@ -184,7 +181,7 @@
                     if (boxed instanceof JavaConstant) {
                         res.add(new ConstantValue(javaField.format("%H.%n"), (JavaConstant) boxed, boxed));
                     } else {
-                        JavaConstant value = constantReflection.readConstantFieldValue(javaField, null);
+                        JavaConstant value = constantReflection.readFieldValue(javaField, null);
                         if (value != null) {
                             res.add(new ConstantValue(javaField.format("%H.%n"), value, boxed));
                             if (boxed instanceof Object[]) {
--- a/hotspot/test/compiler/patches/java.base/java/lang/Helper.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/compiler/patches/java.base/java/lang/Helper.java	Fri May 20 18:05:09 2016 +0300
@@ -29,8 +29,48 @@
  * A helper class to get access to package-private members
  */
 public class Helper {
-  @jdk.internal.vm.annotation.ForceInline
-  public static boolean StringCodingHasNegatives(byte[] ba, int off, int len) {
-    return StringCoding.hasNegatives(ba, off, len);
-  }
+    @jdk.internal.vm.annotation.ForceInline
+    public static boolean StringCodingHasNegatives(byte[] ba, int off, int len) {
+        return StringCoding.hasNegatives(ba, off, len);
+    }
+
+    @jdk.internal.vm.annotation.ForceInline
+    public static byte[] compressByte(byte[] src, int srcOff, int dstSize, int dstOff, int len) {
+        byte[] dst = new byte[dstSize];
+        StringUTF16.compress(src, srcOff, dst, dstOff, len);
+        return dst;
+    }
+
+    @jdk.internal.vm.annotation.ForceInline
+    public static byte[] compressChar(char[] src, int srcOff, int dstSize, int dstOff, int len) {
+        byte[] dst = new byte[dstSize];
+        StringUTF16.compress(src, srcOff, dst, dstOff, len);
+        return dst;
+    }
+
+    @jdk.internal.vm.annotation.ForceInline
+    public static byte[] inflateByte(byte[] src, int srcOff, int dstSize, int dstOff, int len) {
+        byte[] dst = new byte[dstSize];
+        StringLatin1.inflate(src, srcOff, dst, dstOff, len);
+        return dst;
+    }
+
+    @jdk.internal.vm.annotation.ForceInline
+    public static char[] inflateChar(byte[] src, int srcOff, int dstSize, int dstOff, int len) {
+        char[] dst = new char[dstSize];
+        StringLatin1.inflate(src, srcOff, dst, dstOff, len);
+        return dst;
+    }
+
+    @jdk.internal.vm.annotation.ForceInline
+    public static byte[] toBytes(char[] value, int off, int len) {
+        return StringUTF16.toBytes(value, off, len);
+    }
+
+    @jdk.internal.vm.annotation.ForceInline
+    public static char[] getChars(byte[] value, int srcBegin, int srcEnd, int dstSize, int dstBegin) {
+        char[] dst = new char[dstSize];
+        StringUTF16.getChars(value, srcBegin, srcEnd, dst, dstBegin);
+        return dst;
+    }
 }
--- a/hotspot/test/testlibrary/jittester/Makefile	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/Makefile	Fri May 20 18:05:09 2016 +0300
@@ -91,10 +91,10 @@
 	@echo 'Main-Class: jdk.test.lib.jittester.Automatic' >> $(MANIFEST)
 
 compile_testlib: INIT
-	$(JAVAC) -XDignore.symbol.file -Xlint $(TESTLIBRARY_SRC_FILES) -d $(CLASSES_DIR) -source 1.8
+	$(JAVAC) -XDignore.symbol.file -XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint $(TESTLIBRARY_SRC_FILES) -d $(CLASSES_DIR)
 
 COMPILE: INIT filelist compile_testlib
-	$(JAVAC) -cp $(CLASSES_DIR) -XDignore.symbol.file -Xlint -sourcepath $(SRC_DIR) -d $(CLASSES_DIR) -source 1.8 @filelist
+	$(JAVAC) -cp $(CLASSES_DIR) -XDignore.symbol.file -XaddExports:java.base/jdk.internal.misc=ALL-UNNAMED -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -Xlint -sourcepath $(SRC_DIR) -d $(CLASSES_DIR) @filelist
 
 filelist: $(SRC_FILES)
 		@rm -f $@
@@ -104,7 +104,7 @@
 	$(shell if [ ! -d $(CLASSES_DIR) ]; then mkdir -p $(CLASSES_DIR); fi)
 
 install: clean_testbase testgroup testroot copytestlibrary JAR cleantmp
-	$(JAVA) -jar $(DIST_JAR) $(APPLICATION_ARGS)
+	$(JAVA) -XaddExports:java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED -ea -jar $(DIST_JAR) $(APPLICATION_ARGS)
 
 clean_testbase:
 	@rm -rf $(TESTBASE_DIR)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java	Fri May 20 18:05:09 2016 +0300
@@ -23,125 +23,165 @@
 
 package jdk.test.lib.jittester;
 
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import jdk.test.lib.jittester.IRNode;
-import jdk.test.lib.jittester.ProductionParams;
-import jdk.test.lib.jittester.SymbolTable;
-import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.Pair;
 import jdk.test.lib.jittester.factories.IRNodeBuilder;
-import jdk.test.lib.jittester.TypesParser;
+import jdk.test.lib.jittester.jtreg.Printer;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.visitors.JavaCodeVisitor;
+import jdk.test.lib.jittester.utils.FixedTrees;
 import jdk.test.lib.jittester.utils.OptionResolver;
 import jdk.test.lib.jittester.utils.OptionResolver.Option;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.time.LocalTime;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
 public class Automatic {
-    public static final int minutesToWait = 3;
+    private static final int MINUTES_TO_WAIT = Integer.getInteger("jdk.test.lib.jittester", 3);
 
-    private static String makeTestCase(String name) {
+    static String getJtregHeader(String mainClass, boolean addCompile) {
+        String synopsis = "seed = '" + ProductionParams.seed.value() + "'"
+                + ", specificSeed = '" + PseudoRandom.getCurrentSeed() + "'";
+        StringBuilder header = new StringBuilder();
+        header.append("/*\n * @test\n * @summary ")
+                .append(synopsis)
+                .append(" \n* @library / ../\n");
+        if (addCompile) {
+            header.append("\n * @compile ")
+                    .append(mainClass)
+                    .append(".java\n");
+        }
+        header.append(" * @run build jdk.test.lib.jittester.jtreg.JitTesterDriver "
+                        + "jdk.test.lib.jittester.jtreg.Printer\n")
+                .append(" * @run driver jdk.test.lib.jittester.jtreg.JitTesterDriver ")
+                .append(mainClass)
+                .append("\n */\n\n");
+        if (ProductionParams.printHierarchy.value()) {
+            header.append("/*\n")
+                .append(Automatic.printHierarchy())
+                .append("*/\n");
+        }
+        return header.toString();
+    }
+
+    private static Pair<IRNode, IRNode> generateIRTree(String name) {
         SymbolTable.removeAll();
         TypeList.removeAll();
-        StringBuilder resultVis = new StringBuilder();
-        StringBuilder headerBuilder = new StringBuilder();
-        try {
-            IRNodeBuilder builder = new IRNodeBuilder()
-                    .setPrefix(name)
-                    .setName(name)
-                    .setLevel(0);
+
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setPrefix(name)
+                .setName(name)
+                .setLevel(0);
 
-            JavaCodeVisitor vis = new JavaCodeVisitor();
-            String synopsis = "seed = '" + ProductionParams.seed.value() + "'";
-            String pathPrefix = ProductionParams.testbaseDir.value()
-                    .replaceAll("([^/]+)", "..");
-            headerBuilder
-                    .append("/*\n")
-                    .append(" * @test\n")
-                    .append(" * @summary ")
-                        .append(synopsis)
-                        .append("\n")
-                    .append(" * @compile ")
-                        .append(name)
-                        .append(".java\n")
-                    .append(" * @run build jdk.test.lib.jittester.jtreg.JitTesterDriver\n")
-                    .append(" * @run driver jdk.test.lib.jittester.jtreg.JitTesterDriver ")
-                        .append(name)
-                        .append("\n")
-                    .append(" */\n\n");
-
-
-            if (!ProductionParams.disableClasses.value()) {
-                long comlexityLimit = (long) (ProductionParams.complexityLimit.value()
-                        * PseudoRandom.random());
-                IRNode privateClasses = builder.setComplexityLimit(comlexityLimit)
+        Long complexityLimit = ProductionParams.complexityLimit.value();
+        IRNode privateClasses = null;
+        if (!ProductionParams.disableClasses.value()) {
+            long privateClassComlexity = (long) (complexityLimit * PseudoRandom.random());
+            try {
+                privateClasses = builder.setComplexityLimit(privateClassComlexity)
                         .getClassDefinitionBlockFactory()
                         .produce();
-                if (privateClasses != null) {
-                    resultVis.append(privateClasses.accept(vis));
-                }
+            } catch (ProductionFailedException ex) {
+                ex.printStackTrace(System.out);
             }
-            long mainComplexityLimit = (long) (ProductionParams.complexityLimit.value()
-                    * PseudoRandom.random());
-            IRNode mainClass = builder.setComplexityLimit(mainComplexityLimit)
+        }
+        long mainClassComplexity = (long) (complexityLimit * PseudoRandom.random());
+        IRNode mainClass = null;
+        try {
+            mainClass = builder.setComplexityLimit(mainClassComplexity)
                     .getMainKlassFactory()
                     .produce();
-            resultVis.append(mainClass.accept(vis));
-
-            if (ProductionParams.printHierarchy.value()) {
-                headerBuilder
-                        .append("/*\n")
-                        .append(Automatic.printHierarchy())
-                        .append("*/\n");
-            }
-        } catch (Exception e) {
-            e.printStackTrace(System.out);
+            TypeKlass aClass = new TypeKlass(name);
+            mainClass.getChild(1).addChild(FixedTrees.generateMainOrExecuteMethod(aClass, true));
+            mainClass.getChild(1).addChild(FixedTrees.generateMainOrExecuteMethod(aClass, false));
+        } catch (ProductionFailedException ex) {
+            ex.printStackTrace(System.out);
         }
-        return headerBuilder.append(resultVis).toString();
+        return new Pair<>(mainClass, privateClasses);
     }
 
     private static void initializeTestGenerator(String[] params) {
         OptionResolver parser = new OptionResolver();
-        Option<String> propertyFileOpt = parser.addStringOption('p', "property-file", "",
-                "File to read properties from");
+        Option<String> propertyFileOpt = parser.addStringOption('p', "property-file",
+                "conf/default.properties", "File to read properties from");
         ProductionParams.register(parser);
         parser.parse(params, propertyFileOpt);
-        jdk.test.lib.jittester.utils.PseudoRandom.reset(ProductionParams.seed.value());
-        TypesParser.parseTypesAndMethods(ProductionParams.classesFile.value(), ProductionParams.excludeMethodsFile.value());
+        PseudoRandom.reset(ProductionParams.seed.value());
+        TypesParser.parseTypesAndMethods(ProductionParams.classesFile.value(),
+                ProductionParams.excludeMethodsFile.value());
+        if (ProductionParams.specificSeed.isSet()) {
+            PseudoRandom.setCurrentSeed(ProductionParams.specificSeed.value());
+        }
     }
 
     public static void main(String[] args) {
         initializeTestGenerator(args);
         int counter = 0;
         try {
-            String testbaseDir = ProductionParams.testbaseDir.value();
+            Path testbaseDir = Paths.get(ProductionParams.testbaseDir.value());
+            System.out.printf(" %13s | %8s | %8s | %8s |%n", "start time", "count", "generat",
+                              "running");
+            System.out.printf(" %13s | %8s | %8s | %8s |%n", "---", "---", "---","---");
+            String path = getJavaPath();
+            String javacPath = Paths.get(path, "javac").toString();
+            String javaPath = Paths.get(path, "java").toString();
+
+            // compile Printer class first. A common one for all tests
+            ensureExisting(testbaseDir);
+            ProcessBuilder pbPrinter = new ProcessBuilder(javacPath,
+                    Paths.get(testbaseDir.toString(), "jdk", "test", "lib", "jittester",
+                            "jtreg", "Printer.java").toString());
+            runProcess(pbPrinter, testbaseDir.resolve("Printer").toString());
             do {
                 double start = System.currentTimeMillis();
+                System.out.print("[" + LocalTime.now() + "] |");
                 String name = "Test_" + counter;
-                generateTestFile(name);
+                Pair<IRNode, IRNode> irTree = generateIRTree(name);
+                System.out.printf(" %8d |", counter);
                 double generationTime = System.currentTimeMillis() - start;
-                String path = getJavaPath();
-                ProcessBuilder pb = new ProcessBuilder(path + "javac", testbaseDir + "/" + name + ".java");
-                runProcess(pb, testbaseDir + "/" + name);
+                System.out.printf(" %8.0f |", generationTime);
+                if (!ProductionParams.disableJavacodeGeneration.value()) {
+                    JavaCodeGenerator generator = new JavaCodeGenerator();
+                    String javaFile = generator.apply(irTree.first, irTree.second);
+                    ProcessBuilder pb = new ProcessBuilder(javacPath, "-cp", testbaseDir.toString()
+                            + ":" + generator.getTestbase().toString(), javaFile);
+                    runProcess(pb, generator.getTestbase().resolve(name).toString());
+                    start = System.currentTimeMillis();
 
-                start = System.currentTimeMillis();
-                pb = new ProcessBuilder(path + "java", "-Xint", "-cp", testbaseDir, name);
-                name = name + ".gold";
-                runProcess(pb, testbaseDir + "/" + name);
+                    // Run compiled class files
+                    pb = new ProcessBuilder(javaPath, "-Xint", "-cp", testbaseDir.toString()
+                            + ":" + generator.getTestbase().toString(), name);
+                    String goldFile = name + ".gold";
+                    runProcess(pb, generator.getTestbase().resolve(goldFile).toString());
+                }
+
+                if (!ProductionParams.disableBytecodeGeneration.value()) {
+                    ByteCodeGenerator generator = new ByteCodeGenerator();
+                    generator.apply(irTree.first, irTree.second);
+                    generator.writeJtregBytecodeRunner(name);
+                    // Run generated bytecode
+                    ProcessBuilder pb = new ProcessBuilder(javaPath, "-Xint", "-Xverify", "-cp",
+                            testbaseDir.toString() + ":" + generator.getTestbase().toString(),
+                            name);
+                    String goldFile = name + ".gold";
+                    start = System.currentTimeMillis();
+                    runProcess(pb, generator.getTestbase().resolve(goldFile).toString());
+                }
+
                 double runningTime = System.currentTimeMillis() - start;
-                System.out.printf("%4d : generation time (ms) : %8.0f running time (ms) : %8.0f\n",
-                                  counter, generationTime, runningTime);
-                if (runningTime < TimeUnit.MINUTES.toMillis(minutesToWait))
-                ++counter;
+                System.out.printf(" %8.0f |%n", runningTime);
+                if (runningTime < TimeUnit.MINUTES.toMillis(MINUTES_TO_WAIT)) {
+                    ++counter;
+                }
             } while (counter < ProductionParams.numberOfTests.value());
         } catch (IOException | InterruptedException ex) {
-            Logger.getLogger(Automatic.class.getName()).log(Level.SEVERE, null, ex);
+            ex.printStackTrace();
         }
     }
 
@@ -156,65 +196,47 @@
         return "";
     }
 
-    private static void runProcess(ProcessBuilder pb, String name)
+    private static int runProcess(ProcessBuilder pb, String name)
             throws IOException, InterruptedException {
         pb.redirectError(new File(name + ".err"));
         pb.redirectOutput(new File(name + ".out"));
         Process process = pb.start();
-        if (process.waitFor(minutesToWait, TimeUnit.MINUTES)) {
+        if (process.waitFor(MINUTES_TO_WAIT, TimeUnit.MINUTES)) {
             try (FileWriter file = new FileWriter(name + ".exit")) {
                 file.write(Integer.toString(process.exitValue()));
             }
+            return process.exitValue();
         } else {
             process.destroyForcibly();
-        }
-        TimeUnit.MILLISECONDS.sleep(300);
-    }
-
-    private static void generateTestFile(String testName) {
-        String code = makeTestCase(testName);
-        String testbaseDir = ProductionParams.testbaseDir.value();
-        String fileName = testbaseDir + "/" + testName + ".java";
-        try (FileWriter file = new FileWriter(fileName)) {
-            file.write(code);
-            //file.close();
-        } catch (IOException ex) {
-            Logger.getLogger(Automatic.class.getName())
-                  .log(Level.SEVERE, " Cannot write to file " + fileName, ex);
+            return -1;
         }
     }
 
     private static String printHierarchy() {
-        String r = "CLASS HIERARCHY:\n";
-        for (Type t : TypeList.getAll()) {
-            if (t instanceof TypeKlass) {
-                TypeKlass k = (TypeKlass) t;
-                if (k.isAbstract()) {
-                    r += "abstract ";
-                }
-                if (k.isFinal()) {
-                    r += "final ";
-                }
-                if (k.isInterface()) {
-                    r += "interface ";
-                } else {
-                    r += "class ";
-                }
-                r += k.getName() + ": ";
-                HashSet<String> parents = k.getParentsNames();
-                if (parents != null) {
-                    Iterator<String> n = parents.iterator();
-                    int size = parents.size();
-                    for (int i = 0; n.hasNext() && i < size - 1; i++) {
-                        r += n.next() + ", ";
-                    }
-                    if (n.hasNext()) {
-                        r += n.next();
-                    }
-                }
-                r += "\n";
+        return TypeList.getAll().stream()
+                .filter(t -> t instanceof TypeKlass)
+                .map(t -> typeDescription((TypeKlass) t))
+                .collect(Collectors.joining("\n","CLASS HIERARCHY:\n", "\n"));
+    }
+
+    private static String typeDescription(TypeKlass type) {
+        StringBuilder result = new StringBuilder();
+        String parents = type.getParentsNames().stream().collect(Collectors.joining(","));
+        result.append(type.isAbstract() ? "abstract " : "")
+              .append(type.isFinal() ? "final " : "")
+              .append(type.isInterface() ? "interface " : "class ")
+              .append(type.getName())
+              .append(parents.isEmpty() ? "" : ": " + parents);
+        return result.toString();
+    }
+
+    static void ensureExisting(Path path) {
+        if (Files.notExists(path)) {
+            try {
+                Files.createDirectories(path);
+            } catch (IOException ex) {
+                ex.printStackTrace();
             }
         }
-        return r;
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/BinaryOperator.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/BinaryOperator.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,12 +26,8 @@
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class BinaryOperator extends Operator {
-    protected String operationCode;
-    protected Type resultType;
-
-    public BinaryOperator(OperatorKind opKind, IRNode leftOperand, IRNode rightOperand) {
-        super(opKind.priority);
-        operationCode = opKind.text;
+    public BinaryOperator(OperatorKind opKind, Type resultType, IRNode leftOperand, IRNode rightOperand) {
+        super(opKind, resultType);
         addChild(leftOperand);
         addChild(rightOperand);
     }
@@ -47,10 +43,6 @@
         }
     }
 
-    public String getOperationCode() {
-        return operationCode;
-    }
-
     @Override
     public<T> T accept(Visitor<T> v) {
         return v.visit(this);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Block.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Block.java	Fri May 20 18:05:09 2016 +0300
@@ -28,17 +28,12 @@
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class Block extends IRNode {
-    private final Type returnType;
 
-    public Block(TypeKlass klass, Type returnType, List<IRNode> content, int level) {
-        setKlass(klass);
+    public Block(TypeKlass owner, Type returnType, List<? extends IRNode> content, int level) {
+        super(returnType);
+        setOwner(owner);
         addChildren(content);
         this.level = level;
-        this.returnType = returnType;
-    }
-
-    public Type getReturnType() {
-        return returnType;
     }
 
     protected int size() {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Break.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Break.java	Fri May 20 18:05:09 2016 +0300
@@ -27,6 +27,10 @@
 
 public class Break extends IRNode {
 
+    public Break() {
+        super(TypeList.VOID);
+    }
+
     @Override
     public<T> T accept(Visitor<T> v) {
         return v.visit(this);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/BuiltInType.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/BuiltInType.java	Fri May 20 18:05:09 2016 +0300
@@ -27,9 +27,9 @@
 
     private static class BuiltInTypeCapacityHelper {
 
-        static String builtInTypes[] = {"boolean", "byte", "short", "char", "int", "long", "float", "double"};
+        private static final String builtInTypes[] = {"boolean", "byte", "short", "char", "int", "long", "float", "double"};
 
-        static private int getIndexFor(String typeName) {
+        private static int getIndexFor(String typeName) {
             for (int i = 0; i < builtInTypes.length; i++) {
                 if (typeName.compareTo(builtInTypes[i]) == 0) {
                     return i;
@@ -38,7 +38,7 @@
             return -1;
         }
 
-        static public int compare(String typeName1, String typeName2) {
+        public static int compare(String typeName1, String typeName2) {
             int i1 = getIndexFor(typeName1);
             int i2 = getIndexFor(typeName2);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ByteCodeGenerator.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.lib.jittester;
+
+import jdk.test.lib.jittester.visitors.ByteCodeVisitor;
+
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import java.util.function.BiFunction;
+
+/**
+ * Generates class files from bytecode
+ */
+class ByteCodeGenerator implements BiFunction<IRNode, IRNode, String> {
+    private final Path testbase = Paths.get(ProductionParams.testbaseDir.value(),
+            "bytecode_tests");
+
+    public void writeJtregBytecodeRunner(String name) {
+        try (FileWriter file = new FileWriter(testbase.resolve(name + ".java").toFile())) {
+            file.write(Automatic.getJtregHeader(name, false));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public String apply(IRNode mainClass, IRNode privateClasses) {
+        Automatic.ensureExisting(testbase);
+        try {
+            ByteCodeVisitor vis = new ByteCodeVisitor();
+            if (privateClasses != null) {
+                privateClasses.accept(vis);
+            }
+            mainClass.accept(vis);
+
+            Path mainClassPath = testbase.resolve(mainClass.getName() + ".class");
+            writeToClassFile(mainClassPath, vis.getByteCode(mainClass.getName()));
+            if (privateClasses != null) {
+                privateClasses.getChildren().forEach(c -> {
+                    String name = c.getName();
+                    Path classPath = testbase.resolve(name + ".class");
+                    writeToClassFile(classPath, vis.getByteCode(name));
+                });
+            }
+            return mainClassPath.toString();
+        } catch (Throwable t) {
+            Path errFile = testbase.resolve(mainClass.getName() + ".err");
+            try (PrintWriter pw = new PrintWriter(Files.newOutputStream(errFile,
+                    StandardOpenOption.CREATE_NEW))) {
+                t.printStackTrace(pw);
+            } catch (IOException e) {
+                t.printStackTrace();
+                throw new Error("can't write error to error file " + errFile, e);
+            }
+            return null;
+        }
+    }
+
+    public Path getTestbase() {
+        return testbase;
+    }
+
+    private void writeToClassFile(Path path, byte[] bytecode) {
+        try (FileOutputStream file = new FileOutputStream(path.toString())) {
+            file.write(bytecode);
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+    }
+}
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/CastOperator.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/CastOperator.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,9 @@
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class CastOperator extends Operator {
-    private final Type resultType;
 
     public CastOperator(Type resultType, IRNode casted) {
-        super(13);
-        this.resultType = resultType;
+        super(null, 13, resultType);
         addChild(casted);
     }
 
@@ -43,8 +41,4 @@
     public<T> T accept(Visitor<T> v) {
         return v.visit(this);
     }
-
-    public Type getResultType() {
-        return resultType;
-    }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/CatchBlock.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/CatchBlock.java	Fri May 20 18:05:09 2016 +0300
@@ -31,6 +31,7 @@
     public final List<Type> throwables;
 
     public CatchBlock(IRNode body, List<Type> throwables, int level) {
+        super(body.getResultType());
         this.level = level;
         this.throwables = Collections.unmodifiableList(throwables);
         addChild(body);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Continue.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Continue.java	Fri May 20 18:05:09 2016 +0300
@@ -27,6 +27,10 @@
 
 public class Continue extends IRNode {
 
+    public Continue() {
+        super(TypeList.VOID);
+    }
+
     @Override
     public<T> T accept(Visitor<T> v) {
         return v.visit(this);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Declaration.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Declaration.java	Fri May 20 18:05:09 2016 +0300
@@ -27,6 +27,7 @@
 
 public class Declaration extends IRNode {
     public Declaration(IRNode declarationExpr) {
+        super(declarationExpr.getResultType());
         addChild(declarationExpr);
     }
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/IRNode.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/IRNode.java	Fri May 20 18:05:09 2016 +0300
@@ -37,16 +37,26 @@
 public abstract class IRNode {
     private IRNode parent;
     private final List<IRNode> children = new ArrayList<>();
-    protected IRNode klass;
+    protected TypeKlass owner;
     protected int level;
+    private final Type resultType;
+
+    protected IRNode(Type resultType) {
+        this.resultType = resultType;
+    }
+
+    public Type getResultType() {
+        return resultType;
+    }
+
     //TODO
     //private boolean isCFDeviation;
 
     public abstract <T> T accept(Visitor<T> v);
 
-    public void setKlass(TypeKlass klass) {
-        this.klass = klass;
-        if (Objects.isNull(klass)) {
+    public void setOwner(TypeKlass owner) {
+        this.owner = owner;
+        if (Objects.isNull(owner)) {
             System.out.println(getClass().getName() + " null");
             for (StackTraceElement s : Thread.currentThread().getStackTrace()) {
                 System.out.println(s.toString());
@@ -55,20 +65,17 @@
     }
 
     public void addChild(IRNode child) {
-        children.add(child);
-        if (!Objects.isNull(child)) {
+        if (Objects.nonNull(child)) {
+            children.add(child);
             child.parent = this;
         }
     }
 
     public void addChildren(List<? extends IRNode> ch) {
-        if (!Objects.isNull(ch)) {
-            children.addAll(ch);
-            for (IRNode c : ch) {
-                if (!Objects.isNull(c)) {
-                    c.parent = this;
-                }
-            }
+        if (Objects.nonNull(ch)) {
+            ch.stream()
+                .filter(c -> c != null)
+                .forEach(this::addChild);
         }
     }
 
@@ -80,8 +87,8 @@
         return i < children.size() ? children.get(i) : null;
     }
 
-    public IRNode getKlass() {
-        return klass;
+    public TypeKlass getOwner() {
+        return owner;
     }
 
     public IRNode getParent() {
@@ -90,7 +97,7 @@
 
     public void setChild(int index, IRNode child) {
         children.set(index, child);
-        if (!Objects.isNull(child)) {
+        if (Objects.nonNull(child)) {
             child.parent = this;
         }
     }
@@ -145,7 +152,7 @@
 
     @Override
     public final String toString() {
-        throw new Error("Should be toJavaCode");
+        return getName();
     }
 
     public String getName() {
@@ -154,7 +161,7 @@
 
     public static long countDepth(Collection<IRNode> input) {
         return input.stream()
-                .filter(c -> !Objects.isNull(c))
+                .filter(Objects::nonNull)
                 .mapToLong(IRNode::countDepth)
                 .max().orElse(0L);
     }
@@ -166,7 +173,7 @@
     public List<IRNode> getStackableLeaves() {
         List<IRNode> result = new ArrayList<>();
         children.stream()
-                .filter(c -> !Objects.isNull(c))
+                .filter(Objects::nonNull)
                 .forEach(c -> {
                     if (countDepth() == c.level && (c instanceof Block)) {
                         result.add(c);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/If.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/If.java	Fri May 20 18:05:09 2016 +0300
@@ -30,9 +30,10 @@
         CONDITION,
         THEN,
         ELSE,
-    };
+    }
 
-    public If(IRNode condition, IRNode thenBlock, IRNode elseBlock, int level) {
+    public If(IRNode condition, Block thenBlock, Block elseBlock, int level) {
+        super(thenBlock.getResultType());
         this.level = level;
         resizeUpChildren(IfPart.values().length);
         setChild(IfPart.CONDITION.ordinal(), condition);
@@ -43,7 +44,7 @@
     @Override
     public long complexity() {
         IRNode condition = getChild(IfPart.CONDITION.ordinal());
-        IRNode thenBlock=  getChild(IfPart.THEN.ordinal());
+        IRNode thenBlock = getChild(IfPart.THEN.ordinal());
         IRNode elseBlock = getChild(IfPart.ELSE.ordinal());
         return (condition != null ? condition.complexity() : 0)
             + Math.max(thenBlock != null ? thenBlock.complexity() : 0,
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Initialization.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Initialization.java	Fri May 20 18:05:09 2016 +0300
@@ -26,20 +26,14 @@
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public abstract class Initialization extends IRNode {
-    protected VariableInfo variableInfo = new VariableInfo();
-
-    protected Initialization() {
-    }
+    private final VariableInfo variableInfo;
 
     protected Initialization(VariableInfo varInfo, IRNode initExpr) {
+        super(varInfo.type);
         variableInfo = varInfo;
         addChild(initExpr);
     }
 
-    public VariableInfo get() {
-        return variableInfo;
-    }
-
     @Override
     public long complexity() {
         return getChild(0).complexity() + 1;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/JavaCodeGenerator.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.lib.jittester;
+
+import jdk.test.lib.jittester.visitors.JavaCodeVisitor;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.function.BiFunction;
+
+/**
+ * Generates class files from java source code
+ */
+class JavaCodeGenerator implements BiFunction<IRNode, IRNode, String> {
+    private final Path testbase = Paths.get(ProductionParams.testbaseDir.value(), "java_tests");
+
+    private String generateJavaCode(IRNode mainClass, IRNode privateClasses) {
+        StringBuilder code = new StringBuilder();
+        JavaCodeVisitor vis = new JavaCodeVisitor();
+
+        code.append(Automatic.getJtregHeader(mainClass.getName(), true));
+        if (privateClasses != null) {
+            code.append(privateClasses.accept(vis));
+        }
+        code.append(mainClass.accept(vis));
+
+        return code.toString();
+    }
+
+    public Path getTestbase() {
+        return testbase;
+    }
+
+    @Override
+    public String apply(IRNode mainClass, IRNode privateClasses) {
+        String code = generateJavaCode(mainClass, privateClasses);
+        Automatic.ensureExisting(testbase);
+        Path fileName = testbase.resolve(mainClass.getName() + ".java");
+        try (FileWriter file = new FileWriter(fileName.toFile())) {
+            file.write(code);
+            return fileName.toString();
+        } catch (IOException ex) {
+            ex.printStackTrace();
+        }
+        return "";
+    }
+}
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Literal.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Literal.java	Fri May 20 18:05:09 2016 +0300
@@ -27,11 +27,10 @@
 
 public class Literal extends IRNode {
     public final Object value;
-    protected final Type resultType;
 
     public Literal(Object v, Type t) {
+        super(t);
         value = v;
-        resultType = t;
     }
 
     @Override
@@ -44,10 +43,6 @@
         return v.visit(this);
     }
 
-    public Type getResultType() {
-        return resultType;
-    }
-
     public Object getValue() {
         return value;
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/LocalVariable.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/LocalVariable.java	Fri May 20 18:05:09 2016 +0300
@@ -25,16 +25,9 @@
 
 import jdk.test.lib.jittester.visitors.Visitor;
 
-public class LocalVariable extends IRNode implements VariableBase {
-    private VariableInfo value = new VariableInfo();
-
+public class LocalVariable extends VariableBase {
     public LocalVariable(VariableInfo value) {
-        this.value = value;
-    }
-
-    @Override
-    public VariableInfo get() {
-        return value;
+        super(value);
     }
 
     @Override
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/LogicOperator.java	Sat May 14 15:34:30 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.test.lib.jittester;
-
-import jdk.test.lib.jittester.visitors.Visitor;
-
-public class LogicOperator extends IRNode {
-
-    protected LogicOperator() {
-    }
-
-    @Override
-    public<T> T accept(Visitor<T> v) {
-        return v.visit(this);
-    }
-}
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/NonStaticMemberVariable.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/NonStaticMemberVariable.java	Fri May 20 18:05:09 2016 +0300
@@ -25,20 +25,14 @@
 
 import jdk.test.lib.jittester.visitors.Visitor;
 
-public class NonStaticMemberVariable extends IRNode implements VariableBase {
-    private final VariableInfo value;
+public class NonStaticMemberVariable extends VariableBase {
 
     public NonStaticMemberVariable(IRNode object, VariableInfo value) {
-        this.value = value;
+        super(value);
         addChild(object);
     }
 
     @Override
-    public VariableInfo get() {
-        return value;
-    }
-
-    @Override
     public long complexity() {
         return getChild(0).complexity();
     }
@@ -47,8 +41,4 @@
     public<T> T accept(Visitor<T> v) {
         return v.visit(this);
     }
-
-    public VariableInfo getValue() {
-        return value;
-    }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Nothing.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Nothing.java	Fri May 20 18:05:09 2016 +0300
@@ -27,6 +27,10 @@
 
 public class Nothing extends IRNode {
 
+    public Nothing() {
+        super(TypeList.VOID);
+    }
+
     @Override
     public long complexity() {
         return 0;
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Operator.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Operator.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,18 +24,28 @@
 package jdk.test.lib.jittester;
 
 public abstract class Operator extends IRNode {
-    protected int operatorPriority;
+    protected final OperatorKind opKind;
+    private final int priority;
 
     public int getPriority() {
-        return operatorPriority;
+        return priority;
+    }
+
+    public OperatorKind getOperationKind() {
+        return opKind;
     }
 
     public enum Order {
         LEFT, RIGHT
-    };
+    }
 
-    // This constructor is called to construct an IR-tree node.
-    protected Operator(int operatorPriority) {
-        this.operatorPriority = operatorPriority;
+    protected Operator(OperatorKind opKind, Type resultType) {
+        this(opKind, opKind.priority, resultType);
+    }
+
+    protected Operator(OperatorKind opKind, int operatorPriority, Type resultType) {
+        super(resultType);
+        this.opKind = opKind;
+        this.priority = operatorPriority;
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/OperatorKind.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/OperatorKind.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,58 +25,96 @@
 
 // all unary and binary operator kinds
 public enum OperatorKind {
-    COMPOUND_ADD("+=",   1),
-    COMPOUND_SUB("-=",   1),
-    COMPOUND_MUL("*=",   1),
-    COMPOUND_DIV("-=",   1),
-    COMPOUND_MOD("%=",   1),
-    COMPOUND_AND("&=",   1),
-    COMPOUND_OR ("|=",   1),
-    COMPOUND_XOR("^=",   1),
-    COMPOUND_SHR(">>=",  1),
-    COMPOUND_SHL("<<=",  1),
-    COMPOUND_SAR(">>>=", 1),
-    ASSIGN      ("=",    1),
-    OR          ("||",   3),
-    BIT_OR      ("|",    5),
-    BIT_XOR     ("^",    6),
-    AND         ("&&",   7),
-    BIT_AND     ("&",    7),
-    EQ          ("==",   8),
-    NE          ("!=",   8),
-    GT          (">",    9),
-    LT          ("<",    9),
-    GE          (">=",   9),
-    LE          ("<=",   9),
-    SHR         (">>",  10),
-    SHL         ("<<",  10),
-    SAR         (">>>", 10),
-    ADD         ("+",   11),
-    STRADD      ("+",   11),
-    SUB         ("-",   11),
-    MUL         ("*",   12),
-    DIV         ("/",   12),
-    MOD         ("%",   12),
-    NOT         ("!",   14),
-    BIT_NOT     ("~",   14),
-    UNARY_PLUS  ("+",   14),
-    UNARY_MINUS ("-",   14),
-    PRE_DEC     ("--",  15, true),
-    POST_DEC    ("--",  15, false),
-    PRE_INC     ("++",  16, true),
-    POST_INC    ("++",  16, false),
+    /** a += b */
+    COMPOUND_ADD(1),
+    /** a -= b */
+    COMPOUND_SUB(1),
+    /** a *= b */
+    COMPOUND_MUL(1),
+    /** a /= b */
+    COMPOUND_DIV(1),
+    /** a %= b */
+    COMPOUND_MOD(1),
+    /** a &= b */
+    COMPOUND_AND(1),
+    /** a |= b */
+    COMPOUND_OR (1),
+    /** a ^= b */
+    COMPOUND_XOR(1),
+    /** a >>= b */
+    COMPOUND_SHR(1),
+    /** a <<= b */
+    COMPOUND_SHL(1),
+    /** a >>>= b */
+    COMPOUND_SAR(1),
+    /** a = b */
+    ASSIGN      (1),
+    /**  a || b */
+    OR          (3),
+    /** a | b */
+    BIT_OR      (5),
+    /** a ^ b */
+    BIT_XOR     (6),
+    /** a && b */
+    AND         (7),
+    /** a & b */
+    BIT_AND     (7),
+    /** a == b */
+    EQ          (8),
+    /** a != b */
+    NE          (8),
+    /** a > b */
+    GT          (9),
+    /** a < b */
+    LT          (9),
+    /** a >= b */
+    GE          (9),
+    /** a <= b */
+    LE          (9),
+    /** a >> b */
+    SHR         (10),
+    /** a << b */
+    SHL         (10),
+    /** a >>> b */
+    SAR         (10),
+    /** a + b */
+    ADD         (11),
+    /** a.toString() + b */
+    STRADD      (11),
+    /** a - b */
+    SUB         (11),
+    /** a * b */
+    MUL         (12),
+    /** a / b */
+    DIV         (12),
+    /** a % b */
+    MOD         (12),
+    /** !a */
+    NOT         (14),
+    /** ~a */
+    BIT_NOT     (14),
+    /** +a */
+    UNARY_PLUS  (14),
+    /** -a */
+    UNARY_MINUS (14),
+    /** --a */
+    PRE_DEC     (15, true),
+    /** a-- */
+    POST_DEC    (15, false),
+    /** ++a */
+    PRE_INC     (16, true),
+    /** a++ */
+    POST_INC    (16, false),
     ;
 
-    public final String text;
     public final int priority;
     public final boolean isPrefix; // used for unary operators
 
-    private OperatorKind(String text, int priority) {
-        this(text, priority, true);
+    private OperatorKind(int priority) {
+        this(priority, true);
     }
 
-    private OperatorKind(String text, int priority, boolean isPrefix) {
-        this.text = text;
+    private OperatorKind(int priority, boolean isPrefix) {
         this.priority = priority;
         this.isPrefix = isPrefix;
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/PrintVariables.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/PrintVariables.java	Fri May 20 18:05:09 2016 +0300
@@ -25,15 +25,16 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class PrintVariables extends IRNode {
-    private final String printerName;
     private final ArrayList<Symbol> vars;
 
-    public PrintVariables(String printerName, ArrayList<Symbol> vars, int level) {
-        this.printerName = printerName;
-        this.vars = vars;
+    public PrintVariables(TypeKlass owner, int level) {
+        super(TypeList.VOID);
+        this.owner = owner;
+        this.vars = SymbolTable.getAllCombined(owner, VariableInfo.class);
         this.level = level;
     }
 
@@ -45,8 +46,4 @@
     public List<Symbol> getVars() {
         return vars;
     }
-
-    public String getPrinterName() {
-        return printerName;
-    }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java	Fri May 20 18:05:09 2016 +0300
@@ -68,11 +68,14 @@
     public static Option<Boolean> disableNestedBlocks = null;
     public static Option<Boolean> disableArrays = null;
     public static Option<Boolean> enableFinalizers = null;
+    public static Option<Boolean> disableBytecodeGeneration = null;
+    public static Option<Boolean> disableJavacodeGeneration = null;
     // workaraound: to reduce chance throwing ArrayIndexOutOfBoundsException
     public static Option<Integer> chanceExpressionIndex = null;
     public static Option<String> testbaseDir = null;
     public static Option<Integer> numberOfTests = null;
     public static Option<String> seed = null;
+    public static Option<Long> specificSeed = null;
     public static Option<String> classesFile = null;
     public static Option<String> excludeMethodsFile = null;
 
@@ -117,11 +120,14 @@
         disableNestedBlocks = optionResolver.addBooleanOption("disable-nested-blocks", "Disable generation of nested blocks");
         disableArrays = optionResolver.addBooleanOption("disable-arrays", "Disable generation of arrays");
         enableFinalizers = optionResolver.addBooleanOption("enable-finalizers", "Enable finalizers (for stress testing)");
+        disableBytecodeGeneration = optionResolver.addBooleanOption("disable-bytecode-generation", "Disable generation of bytecode output");
+        disableJavacodeGeneration = optionResolver.addBooleanOption("disable-javacode-generation", "Disable generation of java source code output");
         chanceExpressionIndex = optionResolver.addIntegerOption("chance-expression-index", 0, "A non negative decimal integer used to restrict chane of generating expression in array index while creating or accessing by index");
         testbaseDir = optionResolver.addStringOption("testbase-dir", ".", "Testbase dir");
         numberOfTests = optionResolver.addIntegerOption('n', "number-of-tests", 0, "Number of test classes to generate");
         seed = optionResolver.addStringOption("seed", "", "Random seed");
-        classesFile = optionResolver.addStringOption('f', "classes-file", "", "File to read classes from");
-        excludeMethodsFile = optionResolver.addStringOption('r', "exclude-methods-file", "", "File to read excluded methods from");
+        specificSeed = optionResolver.addLongOption('z', "specificSeed", 0L, "A seed to be set for specific test generation(regular seed still needed for initialization)");
+        classesFile = optionResolver.addStringOption('f', "classes-file", "conf/classes.lst", "File to read classes from");
+        excludeMethodsFile = optionResolver.addStringOption('r', "exclude-methods-file", "conf/exclude.methods.lst", "File to read excluded methods from");
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Rule.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Rule.java	Fri May 20 18:05:09 2016 +0300
@@ -32,27 +32,26 @@
 /**
  * The Rule. A helper to perform production.
  */
-public class Rule extends Factory implements Comparable<Rule> {
-    private String name;
+public class Rule<T extends IRNode> extends Factory<T> implements Comparable<Rule<T>> {
+    private final String name;
+    private final TreeSet<RuleEntry> variants;
     private Integer limit = -1;
 
     @Override
-    public int compareTo(Rule rule) {
+    public int compareTo(Rule<T> rule) {
         return name.compareTo(rule.name);
     }
 
-    private TreeSet<RuleEntry> variants;
-
     public Rule(String name) {
         this.name = name;
         variants = new TreeSet<>();
     }
 
-    public void add(String ruleName, Factory factory) {
+    public void add(String ruleName, Factory<? extends T> factory) {
         add(ruleName, factory, 1.0);
     }
 
-    public void add(String ruleName, Factory factory, double weight) {
+    public void add(String ruleName, Factory<? extends T> factory, double weight) {
         variants.add(new RuleEntry(ruleName, factory, weight));
     }
 
@@ -61,7 +60,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public T produce() throws ProductionFailedException {
         if (!variants.isEmpty()) {
             // Begin production.
             LinkedList<RuleEntry> rulesList = new LinkedList<>(variants);
@@ -98,19 +97,19 @@
         throw new ProductionFailedException();
     }
 
-    private class RuleEntry extends Factory implements Comparable<RuleEntry> {
+    private class RuleEntry extends Factory<T> implements Comparable<RuleEntry> {
         private final double weight;
-        private final Factory factory;
+        private final Factory<? extends T> factory;
         private final String name;
 
-        private RuleEntry(String name, Factory factory, double weight) {
+        private RuleEntry(String name, Factory<? extends T> factory, double weight) {
             this.name = name;
             this.weight = weight;
             this.factory = factory;
         }
 
         @Override
-        public IRNode produce() throws ProductionFailedException {
+        public T produce() throws ProductionFailedException {
             return factory.produce();
         }
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Statement.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Statement.java	Fri May 20 18:05:09 2016 +0300
@@ -29,6 +29,7 @@
     private final boolean needSemicolon;
 
     public Statement(IRNode statementBody, boolean needSemicolon) {
+        super(statementBody.getResultType());
         this.needSemicolon = needSemicolon;
         addChild(statementBody);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/StaticMemberVariable.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/StaticMemberVariable.java	Fri May 20 18:05:09 2016 +0300
@@ -26,17 +26,11 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.visitors.Visitor;
 
-public class StaticMemberVariable extends IRNode implements VariableBase {
-    private final VariableInfo varInfo;
+public class StaticMemberVariable extends VariableBase {
 
     public StaticMemberVariable(TypeKlass owner, VariableInfo varInfo) {
-        setKlass(owner);
-        this.varInfo = varInfo;
-    }
-
-    @Override
-    public VariableInfo get() {
-        return varInfo;
+        super(varInfo);
+        setOwner(owner);
     }
 
     @Override
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Switch.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Switch.java	Fri May 20 18:05:09 2016 +0300
@@ -30,6 +30,7 @@
     private final int caseBlockIdx;
 
     public Switch(int level, List<IRNode> chldrn, int caseBlockIdx) {
+        super(chldrn.get(caseBlockIdx).getResultType());
         this.level = level;
         addChildren(chldrn);
         this.caseBlockIdx = caseBlockIdx;
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Symbol.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Symbol.java	Fri May 20 18:05:09 2016 +0300
@@ -29,7 +29,7 @@
 
     public String name;
     public Type type;
-    public TypeKlass klass;
+    public TypeKlass owner;
     public static final int NONE = 0x00;
     public static final int PRIVATE = 0x01;
     public static final int DEFAULT = 0x02;
@@ -47,16 +47,16 @@
         this.name = name;
     }
 
-    public Symbol(String name, TypeKlass klass, Type type, int flags) {
+    public Symbol(String name, TypeKlass owner, Type type, int flags) {
         this.name = name;
-        this.klass = klass;
+        this.owner = owner;
         this.type = type;
         this.flags = flags;
     }
 
     protected Symbol(Symbol value) {
         this.name = value.name;
-        this.klass = value.klass;
+        this.owner = value.owner;
         this.type = value.type;
         this.flags = value.flags;
     }
@@ -71,7 +71,7 @@
         }
         try {
             Symbol s = (Symbol) o;
-            return klass.equals(s.klass) && name.equals(s.name);
+            return owner.equals(s.owner) && name.equals(s.name);
         } catch (Exception e) {
             return false;
         }
@@ -110,4 +110,9 @@
     public Symbol deepCopy() {
         return new Symbol(this);
     }
+
+
+    public TypeKlass getOwner() {
+        return owner;
+    }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/SymbolTable.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/SymbolTable.java	Fri May 20 18:05:09 2016 +0300
@@ -28,6 +28,7 @@
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Stack;
+import java.util.stream.Collectors;
 import jdk.test.lib.jittester.types.TypeKlass;
 
 
@@ -42,9 +43,8 @@
 
         String classList = ProductionParams.addExternalSymbols.value();
         if (classList.equals("all")) {
-            for (Type type : TypeList.getReferenceTypes()) {
-                type.exportSymbols();
-            }
+            TypeList.getReferenceTypes()
+                    .forEach(Type::exportSymbols);
         } else {
             String[] splittedList = classList.split(",");
             for (Type type : TypeList.getReferenceTypes()) {
@@ -96,13 +96,9 @@
     public static Collection<Symbol> get(Type type, Class<?> classToCheck) {
         HashMap<Type, ArrayList<Symbol>> vars = SYMBOL_STACK.peek();
         if (vars.containsKey(type)) {
-            ArrayList<Symbol> result = new ArrayList<>();
-            for (Symbol symbol : vars.get(type)) {
-                if (classToCheck.isInstance(symbol)) {
-                    result.add(symbol);
-                }
-            }
-            return result;
+            return vars.get(type).stream()
+                .filter(classToCheck::isInstance)
+                .collect(Collectors.toList());
         }
         return new ArrayList<>();
     }
@@ -113,7 +109,7 @@
         if (vars.containsKey(type)) {
             ArrayList<Symbol> result = new ArrayList<>();
             for (Symbol symbol : vars.get(type)) {
-                if (classToCheck.isInstance(symbol) && typeKlass.equals(symbol.klass)) {
+                if (classToCheck.isInstance(symbol) && typeKlass.equals(symbol.owner)) {
                     result.add(symbol);
                 }
             }
@@ -150,7 +146,7 @@
         for (Type type : SYMBOL_STACK.peek().keySet()) {
             ArrayList<Symbol> symbolsOfType =  SYMBOL_STACK.peek().get(type);
             for (Symbol symbol : symbolsOfType) {
-                if (classToCheck.isInstance(symbol) && typeKlass.equals(symbol.klass)) {
+                if (classToCheck.isInstance(symbol) && typeKlass.equals(symbol.owner)) {
                     if (!result.containsKey(type)) {
                         result.put(type, new ArrayList<>());
                     }
@@ -193,7 +189,7 @@
         for (Type type : SYMBOL_STACK.peek().keySet()) {
             ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type);
             for (Symbol symbol : symbolsOfType) {
-                if (classToCheck.isInstance(symbol) && typeKlass.equals(symbol.klass)) {
+                if (classToCheck.isInstance(symbol) && typeKlass.equals(symbol.owner)) {
                     result.add(symbol);
                 }
             }
@@ -207,7 +203,7 @@
         for (Type t : SYMBOL_STACK.peek().keySet()) {
             ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(t);
             for (Symbol symbol : symbolsOfType) {
-                if (typeKlass.equals(symbol.klass)) {
+                if (typeKlass.equals(symbol.owner)) {
                     result.add(symbol);
                 }
             }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TernaryOperator.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TernaryOperator.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,12 +30,11 @@
         CONDITION,
         TRUE,
         FALSE,
-    };
+    }
     //protected Production conditionalExpression, leftExpression, rightExpression;
-    protected Type resultType;
 
     public TernaryOperator(IRNode condition, IRNode trueBranch, IRNode falseBranch) {
-        super(2);
+        super(null, 2, trueBranch.getResultType());
         resizeUpChildren(TernaryPart.values().length);
         setChild(TernaryPart.CONDITION.ordinal(), condition);
         setChild(TernaryPart.TRUE.ordinal(), trueBranch);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Throw.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Throw.java	Fri May 20 18:05:09 2016 +0300
@@ -27,6 +27,7 @@
 
 public class Throw extends IRNode {
     public Throw(IRNode throwable) {
+        super(throwable.getResultType());
         addChild(throwable);
     }
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TryCatchBlock.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TryCatchBlock.java	Fri May 20 18:05:09 2016 +0300
@@ -29,6 +29,7 @@
 
 public class TryCatchBlock extends IRNode {
     public TryCatchBlock(IRNode body, IRNode finallyBlock, List<CatchBlock> catchBlocks, int level) {
+        super(body.getResultType());
         this.level = level;
         addChild(body);
         addChild(finallyBlock);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Type.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Type.java	Fri May 20 18:05:09 2016 +0300
@@ -33,10 +33,16 @@
     private final String typeName;
 
     protected Type(String typeName) {
+        super(null);
         this.typeName = typeName;
     }
 
     @Override
+    public Type getResultType() {
+        return this;
+    }
+
+    @Override
     public boolean equals(Object t) {
         if (this == t) {
             return true;
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TypeList.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TypeList.java	Fri May 20 18:05:09 2016 +0300
@@ -27,19 +27,31 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.function.Predicate;
-import jdk.test.lib.jittester.types.TypeArray;
+
 import jdk.test.lib.jittester.types.TypeBoolean;
 import jdk.test.lib.jittester.types.TypeByte;
 import jdk.test.lib.jittester.types.TypeChar;
 import jdk.test.lib.jittester.types.TypeDouble;
 import jdk.test.lib.jittester.types.TypeFloat;
 import jdk.test.lib.jittester.types.TypeInt;
+import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.types.TypeLong;
 import jdk.test.lib.jittester.types.TypeShort;
 import jdk.test.lib.jittester.types.TypeVoid;
 
 public class TypeList {
-    private static final TypeVoid TYPE_VOID = new TypeVoid();
+    public static final TypeVoid VOID = new TypeVoid();
+    public static final TypeBoolean BOOLEAN = new TypeBoolean();
+    public static final TypeByte BYTE = new TypeByte();
+    public static final TypeChar CHAR = new TypeChar();
+    public static final TypeShort SHORT = new TypeShort();
+    public static final TypeInt INT = new TypeInt();
+    public static final TypeLong LONG = new TypeLong();
+    public static final TypeFloat FLOAT = new TypeFloat();
+    public static final TypeDouble DOUBLE = new TypeDouble();
+    public static final TypeKlass OBJECT = new TypeKlass("java.lang.Object");
+    public static final TypeKlass STRING = new TypeKlass("java.lang.String", TypeKlass.FINAL);
+
     private static final List<Type> TYPES = new ArrayList<>();
     private static final List<Type> BUILTIN_TYPES = new ArrayList<>();
     private static final List<Type> BUILTIN_INT_TYPES = new ArrayList<>();
@@ -47,14 +59,14 @@
     private static final List<Type> REFERENCE_TYPES = new ArrayList<>();
 
     static {
-        BUILTIN_INT_TYPES.add(new TypeBoolean());
-        BUILTIN_INT_TYPES.add(new TypeByte());
-        BUILTIN_INT_TYPES.add(new TypeChar());
-        BUILTIN_INT_TYPES.add(new TypeShort());
-        BUILTIN_INT_TYPES.add(new TypeInt());
-        BUILTIN_INT_TYPES.add(new TypeLong());
-        BUILTIN_FP_TYPES.add(new TypeFloat());
-        BUILTIN_FP_TYPES.add(new TypeDouble());
+        BUILTIN_INT_TYPES.add(BOOLEAN);
+        BUILTIN_INT_TYPES.add(BYTE);
+        BUILTIN_INT_TYPES.add(CHAR);
+        BUILTIN_INT_TYPES.add(SHORT);
+        BUILTIN_INT_TYPES.add(INT);
+        BUILTIN_INT_TYPES.add(LONG);
+        BUILTIN_FP_TYPES.add(FLOAT);
+        BUILTIN_FP_TYPES.add(DOUBLE);
 
         BUILTIN_TYPES.addAll(BUILTIN_INT_TYPES);
         BUILTIN_TYPES.addAll(BUILTIN_FP_TYPES);
@@ -62,13 +74,13 @@
         TYPES.addAll(BUILTIN_TYPES);
 
         if (!ProductionParams.disableArrays.value()) {
-            REFERENCE_TYPES.add(new TypeArray().produce());
             TYPES.addAll(REFERENCE_TYPES);
         }
-    }
 
-    public static TypeVoid getVoid() {
-        return TYPE_VOID;
+        STRING.addParent(OBJECT.getName());
+        STRING.setParent(OBJECT);
+        add(STRING);
+        add(OBJECT);
     }
 
     public static Collection<Type> getAll() {
@@ -100,14 +112,14 @@
     }
 
     public static boolean isBuiltIn(Type t) {
-        return isBuiltInInt(t) || isBuiltInFP(t);
+        return isBuiltInInt(t) || isBuiltInFP(t) || t.equals(VOID);
     }
 
     protected static boolean isIn(Type t) {
         return TYPES.contains(t);
     }
 
-    protected static boolean isReferenceType(Type t) {
+    public static boolean isReferenceType(Type t) {
         return REFERENCE_TYPES.contains(t);
     }
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TypesParser.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TypesParser.java	Fri May 20 18:05:09 2016 +0300
@@ -42,7 +42,6 @@
 import jdk.test.lib.jittester.functions.FunctionInfo;
 import jdk.test.lib.jittester.types.TypeArray;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeVoid;
 
 /**
  * Class used for parsing included classes file and excluded methods file
@@ -62,7 +61,7 @@
     public static void parseTypesAndMethods(String klassesFileName, String exMethodsFileName) {
         Asserts.assertNotNull(klassesFileName, "Classes input file name is null");
         Asserts.assertFalse(klassesFileName.isEmpty(), "Classes input file name is empty");
-        Set<Class<?>> klasses = parseKlasses(klassesFileName);
+        List<Class<?>> klasses = parseKlasses(klassesFileName);
         Set<Executable> methodsToExclude;
         if (exMethodsFileName != null && !exMethodsFileName.isEmpty()) {
             methodsToExclude = parseMethods(exMethodsFileName);
@@ -119,15 +118,18 @@
         }
         if (klass.isPrimitive()) {
             if (klass.equals(void.class)) {
-                type = new TypeVoid();
+                type = TypeList.VOID;
             } else {
                 type = TypeList.find(klass.getName());
             }
         } else {
             int flags = getKlassFlags(klass);
             if (klass.isArray()) {
-                TypeKlass elementType
-                        = new TypeKlass(klass.getCanonicalName().replaceAll("\\[\\]", ""), flags);
+                Class<?> elementKlass  = klass.getComponentType();
+                while (elementKlass.isArray()) {
+                    elementKlass = elementKlass.getComponentType();
+                }
+                Type elementType = getType(elementKlass);
                 int dim = getArrayClassDimension(klass);
                 type = new TypeArray(elementType, dim);
             } else {
@@ -138,10 +140,14 @@
                 type = new TypeKlass(canonicalName, flags);
             }
             Class<?> parentKlass = klass.getSuperclass();
+            TypeKlass typeKlass = (TypeKlass) type;
             if (parentKlass != null) {
                 TypeKlass parentTypeKlass = (TypeKlass) getType(parentKlass);
-                ((TypeKlass) type).addParent(parentTypeKlass.getName());
-                ((TypeKlass) type).setParent(parentTypeKlass);
+                typeKlass.addParent(parentTypeKlass.getName());
+                typeKlass.setParent(parentTypeKlass);
+            }
+            for (Class<?> iface : klass.getInterfaces()) {
+                typeKlass.addParent(getType(iface).getName());
             }
         }
         TYPE_CACHE.put(klass, type);
@@ -197,10 +203,10 @@
         return flags;
     }
 
-    private static Set<Class<?>> parseKlasses(String klassesFileName) {
+    private static List<Class<?>> parseKlasses(String klassesFileName) {
         Asserts.assertNotNull(klassesFileName, "Classes input file name is null");
         Asserts.assertFalse(klassesFileName.isEmpty(), "Classes input file name is empty");
-        Set<String> klassNamesSet = new HashSet<>();
+        List<String> klassNamesList = new ArrayList<>();
         Path klassesFilePath = (new File(klassesFileName)).toPath();
         try {
             Files.lines(klassesFilePath).forEach(line -> {
@@ -211,20 +217,20 @@
                 String msg = String.format("Format of the classes input file \"%s\" is incorrect,"
                         + " line \"%s\" has wrong format", klassesFileName, line);
                 Asserts.assertTrue(line.matches("\\w[\\w\\.$]*"), msg);
-                klassNamesSet.add(line.replaceAll(";", ""));
+                klassNamesList.add(line.replaceAll(";", ""));
             });
         } catch (IOException ex) {
             throw new Error("Error reading klasses file", ex);
         }
-        Set<Class<?>> klassesSet = new HashSet<>();
-        klassNamesSet.stream().forEach(klassName -> {
+        List<Class<?>> klassesList = new ArrayList<>();
+        klassNamesList.stream().forEach(klassName -> {
             try {
-                klassesSet.add(Class.forName(klassName));
+                klassesList.add(Class.forName(klassName));
             } catch (ClassNotFoundException ex) {
                 throw new Error("Unexpected exception while parsing klasses file", ex);
             }
         });
-        return klassesSet;
+        return klassesList;
     }
 
     private static Set<Executable> parseMethods(String methodsFileName) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/UnaryOperator.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/UnaryOperator.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,12 +26,8 @@
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class UnaryOperator extends Operator {
-    protected OperatorKind opKind;
-    protected Type resultType;
-
     public UnaryOperator(OperatorKind opKind, IRNode expression) {
-        super(opKind.priority);
-        this.opKind = opKind;
+        super(opKind, expression.getResultType());
         addChild(expression);
     }
 
@@ -49,8 +45,4 @@
     public boolean isPrefix() {
         return opKind.isPrefix;
     }
-
-    public String getOperatorText() {
-        return opKind.text;
-    }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableBase.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableBase.java	Fri May 20 18:05:09 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,14 @@
 
 package jdk.test.lib.jittester;
 
-public interface VariableBase {
+public abstract class VariableBase extends IRNode {
+    private final VariableInfo variableInfo;
+    protected VariableBase(VariableInfo variableInfo) {
+        super(variableInfo.type);
+        this.variableInfo = variableInfo;
+    }
 
-    VariableInfo get();
+    public VariableInfo getVariableInfo() {
+        return variableInfo;
+    }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableDeclaration.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableDeclaration.java	Fri May 20 18:05:09 2016 +0300
@@ -26,9 +26,10 @@
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class VariableDeclaration extends IRNode {
-    protected final VariableInfo variableInfo;
+    private final VariableInfo variableInfo;
 
     public VariableDeclaration(VariableInfo value) {
+        super(value.type);
         variableInfo = value;
     }
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableDeclarationBlock.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableDeclarationBlock.java	Fri May 20 18:05:09 2016 +0300
@@ -24,10 +24,12 @@
 package jdk.test.lib.jittester;
 
 import java.util.ArrayList;
+
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class VariableDeclarationBlock extends IRNode {
-    public VariableDeclarationBlock(ArrayList<IRNode> content, int level) {
+    public VariableDeclarationBlock(ArrayList<? extends Declaration> content, int level) {
+        super(TypeList.VOID);
         addChildren(content);
         this.level = level;
     }
@@ -40,10 +42,6 @@
                 .sum();
     }
 
-    protected int size() {
-        return getChildren() != null ? getChildren().size() : 0;
-    }
-
     @Override
     public<T> T accept(Visitor<T> v) {
         return v.visit(this);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableInfo.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableInfo.java	Fri May 20 18:05:09 2016 +0300
@@ -55,4 +55,8 @@
     public Symbol deepCopy() {
         return new VariableInfo(this);
     }
+
+    public boolean isLocal() {
+        return (flags & LOCAL) != 0;
+    }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/arrays/ArrayCreation.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/arrays/ArrayCreation.java	Fri May 20 18:05:09 2016 +0300
@@ -28,7 +28,6 @@
 import java.util.stream.Collectors;
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.Literal;
-import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.VariableDeclaration;
 import jdk.test.lib.jittester.types.TypeArray;
 import jdk.test.lib.jittester.visitors.Visitor;
@@ -39,6 +38,7 @@
     private final List<Byte> dims;
 
     public ArrayCreation(VariableDeclaration var, TypeArray array, ArrayList<IRNode> dimensionSizeExpressions) {
+        super(array);
         this.variable = var;
         this.array = array;
         addChildren(dimensionSizeExpressions);
@@ -55,8 +55,8 @@
         type.setDimentions(dims);
     }
 
-    public Type getArrayType() {
-        return array.type;
+    public TypeArray getArrayType() {
+        return array;
     }
 
     @Override
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/arrays/ArrayElement.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/arrays/ArrayElement.java	Fri May 20 18:05:09 2016 +0300
@@ -25,10 +25,12 @@
 
 import java.util.ArrayList;
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.types.TypeArray;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class ArrayElement extends IRNode {
     public ArrayElement(IRNode array, ArrayList<IRNode> dimensionExpressions) {
+        super(((TypeArray) array.getResultType()).type);
         addChild(array);
         addChildren(dimensionExpressions);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/arrays/ArrayExtraction.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/arrays/ArrayExtraction.java	Fri May 20 18:05:09 2016 +0300
@@ -40,6 +40,7 @@
 public class ArrayExtraction extends IRNode {
     private final List<Byte> dims;
     public ArrayExtraction(IRNode array, ArrayList<IRNode> dimensionExpressions) {
+        super(array.getResultType());
         addChild(array);
         addChildren(dimensionExpressions);
         if (array instanceof ArrayCreation) {
@@ -56,7 +57,7 @@
             }
         } else if (array instanceof LocalVariable) {
             LocalVariable loc = (LocalVariable) array;
-            TypeArray type = (TypeArray) loc.get().type;
+            TypeArray type = (TypeArray) loc.getVariableInfo().type;
             dims = type.getDims();
             for (int i = dimensionExpressions.size(); i < type.dimensions; ++i) {
                 dims.add(type.getDims().get(i));
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/ClassDefinitionBlock.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/ClassDefinitionBlock.java	Fri May 20 18:05:09 2016 +0300
@@ -25,10 +25,12 @@
 
 import java.util.ArrayList;
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class ClassDefinitionBlock extends IRNode {
     public ClassDefinitionBlock(ArrayList<IRNode> content, int level) {
+        super(TypeList.VOID);
         this.level = level;
         addChildren(content);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/Interface.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/Interface.java	Fri May 20 18:05:09 2016 +0300
@@ -24,6 +24,7 @@
 package jdk.test.lib.jittester.classes;
 
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.visitors.Visitor;
 
@@ -32,6 +33,7 @@
     private TypeKlass parent = null;
 
     public Interface(TypeKlass parent, String name, int level, IRNode functionDeclaraionBlock) {
+        super(TypeList.find(functionDeclaraionBlock.getOwner().getName()));
         this.parent = parent;
         this.name = name;
         this.level = level;
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/Klass.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/Klass.java	Fri May 20 18:05:09 2016 +0300
@@ -70,19 +70,21 @@
             IRNode functionDefinitions, IRNode abstractFunctionRedefinitions,
             IRNode overridenFunctionRedefitions, IRNode functionDeclarations,
             IRNode printVariablesBlock) {
+        super(thisKlass);
         this.thisKlass = thisKlass;
-        klass = thisKlass;
+        owner = thisKlass;
         this.parentKlass = parent;
         this.interfaces = interfaces;
         this.name = name;
         this.level = level;
-        addChild(variableDeclarations);
-        addChild(constructorDefinitions);
-        addChild(abstractFunctionRedefinitions);
-        addChild(overridenFunctionRedefitions);
-        addChild(functionDefinitions);
-        addChild(functionDeclarations);
-        addChild(printVariablesBlock);
+        resizeUpChildren(KlassPart.values().length);
+        setChild(KlassPart.DATA_MEMBERS.ordinal(), variableDeclarations);
+        setChild(KlassPart.CONSTRUCTORS.ordinal(), constructorDefinitions);
+        setChild(KlassPart.REDEFINED_FUNCTIONS.ordinal(), abstractFunctionRedefinitions);
+        setChild(KlassPart.OVERRIDEN_FUNCTIONS.ordinal(), overridenFunctionRedefitions);
+        setChild(KlassPart.MEMBER_FUNCTIONS.ordinal(), functionDefinitions);
+        setChild(KlassPart.MEMBER_FUNCTIONS_DECLARATIONS.ordinal(), functionDeclarations);
+        setChild(KlassPart.PRINT_VARIABLES.ordinal(), printVariablesBlock);
     }
 
     @Override
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/MainKlass.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/MainKlass.java	Fri May 20 18:05:09 2016 +0300
@@ -40,6 +40,7 @@
 
     public MainKlass(String name, TypeKlass thisKlass, IRNode variableDeclarations,
             IRNode functionDefinitions, IRNode testFunction, IRNode printVariables) {
+        super(thisKlass);
         addChild(variableDeclarations);
         addChild(functionDefinitions);
         addChild(testFunction);
@@ -64,4 +65,8 @@
     public String getName() {
         return name;
     }
+
+    public TypeKlass getThisKlass() {
+        return thisKlass;
+    }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArgumentDeclarationFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArgumentDeclarationFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -33,7 +33,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class ArgumentDeclarationFactory extends Factory {
+class ArgumentDeclarationFactory extends Factory<ArgumentDeclaration> {
     private final int argumentNumber;
     private final TypeKlass ownerClass;
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArithmeticOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArithmeticOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,15 +23,15 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Operator;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Rule;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class ArithmeticOperatorFactory extends Factory {
-    private final Rule rule;
+class ArithmeticOperatorFactory extends Factory<Operator> {
+    private final Rule<Operator> rule;
 
     ArithmeticOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
             Type resultType, boolean exceptionSafe, boolean noconsts) throws ProductionFailedException {
@@ -42,7 +42,7 @@
                 .setResultType(resultType)
                 .setExceptionSafe(exceptionSafe)
                 .setNoConsts(noconsts);
-        rule = new Rule("arithmetic");
+        rule = new Rule<>("arithmetic");
         rule.add("add", builder.setOperatorKind(OperatorKind.ADD).getBinaryOperatorFactory());
         rule.add("sub", builder.setOperatorKind(OperatorKind.SUB).getBinaryOperatorFactory());
         rule.add("mul", builder.setOperatorKind(OperatorKind.MUL).getBinaryOperatorFactory());
@@ -55,7 +55,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Operator produce() throws ProductionFailedException {
         return rule.produce();
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArrayCreationFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArrayCreationFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -29,15 +29,14 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.ProductionParams;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.VariableDeclaration;
 import jdk.test.lib.jittester.arrays.ArrayCreation;
 import jdk.test.lib.jittester.types.TypeArray;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeByte;
-import jdk.test.lib.jittester.types.TypeVoid;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class ArrayCreationFactory extends SafeFactory {
+class ArrayCreationFactory extends SafeFactory<ArrayCreation> {
     private final long complexityLimit;
     private final int operatorLimit;
     private final Type resultType;
@@ -56,16 +55,16 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected ArrayCreation sproduce() throws ProductionFailedException {
         if (resultType instanceof TypeArray) {
             TypeArray arrayResultType = (TypeArray) resultType;
-            if (arrayResultType.type.equals(new TypeVoid())) {
+            if (arrayResultType.type.equals(TypeList.VOID)) {
                 arrayResultType = arrayResultType.produce();
             }
             IRNodeBuilder builder = new IRNodeBuilder()
                     .setComplexityLimit(complexityLimit)
                     .setOwnerKlass(ownerClass)
-                    .setResultType(new TypeByte())
+                    .setResultType(TypeList.BYTE)
                     .setExceptionSafe(exceptionSafe)
                     .setNoConsts(noconsts);
             double chanceExpression = ProductionParams.chanceExpressionIndex.value() / 100;
@@ -77,14 +76,14 @@
                             .getExpressionFactory()
                             .produce());
                 } else {
-                    Literal dimension = (Literal)builder.getLiteralFactory().produce();
+                    Literal dimension = builder.getLiteralFactory().produce();
                     while (Integer.valueOf(dimension.getValue().toString()) < 1) {
-                        dimension = (Literal)builder.getLiteralFactory().produce();
+                        dimension = builder.getLiteralFactory().produce();
                     }
                     dims.add(dimension);
                 }
             }
-            VariableDeclaration var =  (VariableDeclaration) builder
+            VariableDeclaration var = builder
                     .setOwnerKlass(ownerClass)
                     .setResultType(arrayResultType)
                     .setIsLocal(true)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArrayElementFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArrayElementFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -29,15 +29,15 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.ProductionParams;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.arrays.ArrayCreation;
 import jdk.test.lib.jittester.arrays.ArrayElement;
 import jdk.test.lib.jittester.arrays.ArrayExtraction;
 import jdk.test.lib.jittester.types.TypeArray;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeByte;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class ArrayElementFactory extends SafeFactory {
+class ArrayElementFactory extends SafeFactory<ArrayElement> {
     private final long complexityLimit;
     private final int operatorLimit;
     private final Type resultType;
@@ -56,7 +56,7 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected ArrayElement sproduce() throws ProductionFailedException {
         if (resultType instanceof TypeArray) {
             throw new ProductionFailedException();
         }
@@ -76,10 +76,10 @@
                 .setResultType(new TypeArray(resultType, dimensionsCount))
                 .getExpressionFactory()
                 .produce();
-        ExpressionFactory expressionFactory = builder
+        Factory<IRNode> expressionFactory = builder
                 .setComplexityLimit(complexityPerDimension)
                 .setOperatorLimit(operatorLimitPerDimension)
-                .setResultType(new TypeByte())
+                .setResultType(TypeList.BYTE)
                 .getExpressionFactory();
         double chanceExpression = ProductionParams.chanceExpressionIndex.value() / 100.;
         ArrayList<IRNode> perDimensionExpressions = new ArrayList<>(dimensionsCount);
@@ -96,7 +96,7 @@
                     if (i < arrayExtraction.getDimsNumber())
                         dimLimit = arrayExtraction.getDim(i);
                 }
-                perDimensionExpressions.add(new Literal(PseudoRandom.randomNotNegative(dimLimit), new TypeByte()));
+                perDimensionExpressions.add(new Literal((byte)PseudoRandom.randomNotNegative(dimLimit), TypeList.BYTE));
             }
         }
         return new ArrayElement(arrayReturningExpression, perDimensionExpressions);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArrayExtractionFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArrayExtractionFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -29,14 +29,14 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.ProductionParams;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.arrays.ArrayCreation;
 import jdk.test.lib.jittester.arrays.ArrayExtraction;
 import jdk.test.lib.jittester.types.TypeArray;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeByte;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class ArrayExtractionFactory extends SafeFactory {
+class ArrayExtractionFactory extends SafeFactory<ArrayExtraction> {
     private final long complexityLimit;
     private final int operatorLimit;
     private final Type resultType;
@@ -55,7 +55,7 @@
     }
 
     @Override
-    public IRNode sproduce() throws ProductionFailedException {
+    public ArrayExtraction sproduce() throws ProductionFailedException {
         if (resultType instanceof TypeArray) {
             TypeArray arrayType = (TypeArray) resultType;
             int delta = PseudoRandom.randomNotZero(ProductionParams.dimensionsLimit.value()
@@ -79,7 +79,7 @@
                 double chanceExpression = ProductionParams.chanceExpressionIndex.value() / 100.;
                 for (int i = 0; i < delta; i++) {
                     if (PseudoRandom.randomBoolean(chanceExpression)) {
-                        perDimensionExpression.add(builder.setResultType(new TypeByte())
+                        perDimensionExpression.add(builder.setResultType(TypeList.BYTE)
                                 .setComplexityLimit(dimComplLimit)
                                 .setOperatorLimit(dimOpLimit)
                                 .getExpressionFactory()
@@ -94,7 +94,7 @@
                             if (i < arrayExtraction.getDimsNumber())
                                 dimLimit = arrayExtraction.getDim(i);
                         }
-                        perDimensionExpression.add(new Literal(PseudoRandom.randomNotNegative(dimLimit), new TypeByte()));
+                        perDimensionExpression.add(new Literal((byte)PseudoRandom.randomNotNegative(dimLimit), TypeList.BYTE));
                     }
                 }
                 return new ArrayExtraction(arrayReturningExpression, perDimensionExpression);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/AssignmentOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/AssignmentOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -24,7 +24,8 @@
 package jdk.test.lib.jittester.factories;
 
 import java.util.ArrayList;
-import jdk.test.lib.jittester.IRNode;
+
+import jdk.test.lib.jittester.Operator;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Rule;
@@ -34,7 +35,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class AssignmentOperatorFactory extends Factory {
+class AssignmentOperatorFactory extends Factory<Operator> {
     private final int operatorLimit;
     private final long complexityLimit;
     private final Type resultType;
@@ -42,8 +43,8 @@
     private final boolean noconsts;
     private final TypeKlass ownerClass;
 
-    private Rule fillRule(Type resultType) throws ProductionFailedException {
-        Rule rule = new Rule("assignment");
+    private Rule<Operator> fillRule(Type resultType) throws ProductionFailedException {
+        Rule<Operator> rule = new Rule<>("assignment");
         IRNodeBuilder builder = new IRNodeBuilder()
                 .setComplexityLimit(complexityLimit)
                 .setOperatorLimit(operatorLimit)
@@ -84,14 +85,14 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Operator produce() throws ProductionFailedException {
         if (resultType == null) { // if no result type is given - choose any.
             ArrayList<Type> allTypes = new ArrayList<>(TypeList.getAll());
             PseudoRandom.shuffle(allTypes);
             for (Type type : allTypes) {
                 SymbolTable.push();
                 try {
-                    IRNode result =  fillRule(type).produce();
+                    Operator result =  fillRule(type).produce();
                     SymbolTable.merge();
                     return result;
                 } catch (ProductionFailedException e) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/AssignmentOperatorImplFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/AssignmentOperatorImplFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -31,8 +31,8 @@
 import jdk.test.lib.jittester.Rule;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.VariableBase;
 import jdk.test.lib.jittester.utils.TypeUtil;
-import jdk.test.lib.jittester.VariableBase;
 import jdk.test.lib.jittester.VariableInfo;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
@@ -49,7 +49,7 @@
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         return new Pair<>(resultType, PseudoRandom.randomElement(
                 TypeUtil.getImplicitlyCastable(TypeList.getAll(), resultType)));
     }
@@ -68,23 +68,22 @@
                 .setOperatorLimit(leftOperatorLimit)
                 .setResultType(leftOperandType)
                 .setIsConstant(false);
-        Rule rule = new Rule("assignment");
+        Rule<VariableBase> rule = new Rule<>("assignment");
         rule.add("initialized_nonconst_var", builder.setIsInitialized(true).getVariableFactory());
         rule.add("uninitialized_nonconst_var", builder.setIsInitialized(false).getVariableFactory());
-        IRNode leftOperandValue = rule.produce();
+        VariableBase leftOperandValue = rule.produce();
         IRNode rightOperandValue = builder.setComplexityLimit(rightComplexityLimit)
                 .setOperatorLimit(rightOperatorLimit)
                 .setResultType(rightOperandType)
                 .getExpressionFactory()
                 .produce();
         try {
-            VariableBase v = (VariableBase) leftOperandValue;
-            if ((v.get().flags & VariableInfo.INITIALIZED) == 0) {
-                v.get().flags |= VariableInfo.INITIALIZED;
+            if ((leftOperandValue.getVariableInfo().flags & VariableInfo.INITIALIZED) == 0) {
+                leftOperandValue.getVariableInfo().flags |= VariableInfo.INITIALIZED;
             }
         } catch (Exception e) {
             throw new ProductionFailedException(e.getMessage());
         }
-        return new BinaryOperator(opKind, leftOperandValue, rightOperandValue);
+        return new BinaryOperator(opKind, resultType, leftOperandValue, rightOperandValue);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryArithmeticOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryArithmeticOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -30,7 +30,6 @@
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.utils.TypeUtil;
-import jdk.test.lib.jittester.types.TypeInt;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
@@ -47,18 +46,18 @@
         // arithmetic for built-in types less capacious than "int" is not supported.
         if (TypeList.isBuiltIn(resultType)) {
             BuiltInType builtInType = (BuiltInType) resultType;
-            return builtInType.equals(new TypeInt()) || builtInType.isMoreCapaciousThan(new TypeInt());
+            return builtInType.equals(TypeList.INT) || builtInType.isMoreCapaciousThan(TypeList.INT);
         } else {
             return false;
         }
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         Collection<Type> castableFromResultType = TypeUtil.getImplicitlyCastable(TypeList.getBuiltIn(), resultType);
         // built-in types less capacious than int are automatically casted to int in arithmetic.
         final Type leftType = PseudoRandom.randomElement(castableFromResultType);
-        final Type rightType = resultType.equals(new TypeInt()) ?
+        final Type rightType = resultType.equals(TypeList.INT) ?
                 PseudoRandom.randomElement(castableFromResultType) : resultType;
         //TODO: is there sense to swap them randomly as it was done in original code?
         return PseudoRandom.randomBoolean() ? new Pair<>(leftType, rightType) : new Pair<>(rightType, leftType);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryBitwiseOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryBitwiseOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -29,10 +29,7 @@
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.utils.TypeUtil;
-import jdk.test.lib.jittester.types.TypeBoolean;
-import jdk.test.lib.jittester.types.TypeInt;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeLong;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
 import java.util.Collection;
@@ -45,15 +42,15 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return resultType.equals(new TypeInt()) || resultType.equals(new TypeLong()) || resultType.equals(new TypeBoolean());
+        return resultType.equals(TypeList.INT) || resultType.equals(TypeList.LONG) || resultType.equals(TypeList.BOOLEAN);
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         Collection<Type> castableFromResult = TypeUtil.getImplicitlyCastable(TypeList.getBuiltIn(), resultType);
         // built-in types less capacious than int are automatically casted to int in arithmetic.
         final Type leftType = PseudoRandom.randomElement(castableFromResult);
-        final Type rightType = resultType.equals(new TypeInt()) ? PseudoRandom.randomElement(castableFromResult) : resultType;
+        final Type rightType = resultType.equals(TypeList.INT) ? PseudoRandom.randomElement(castableFromResult) : resultType;
         //TODO: is there sense to swap them randomly as it was done in original code?
         return PseudoRandom.randomBoolean() ? new Pair<>(leftType, rightType) : new Pair<>(rightType, leftType);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryComparisonOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryComparisonOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -28,7 +28,6 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
-import jdk.test.lib.jittester.types.TypeBoolean;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
@@ -43,13 +42,13 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return resultType.equals(new TypeBoolean());
+        return resultType.equals(TypeList.BOOLEAN);
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         final List<Type> builtInExceptBoolean = new ArrayList<>(TypeList.getBuiltIn());
-        builtInExceptBoolean.remove(new TypeBoolean());
+        builtInExceptBoolean.remove(TypeList.BOOLEAN);
         return new Pair<>(PseudoRandom.randomElement(builtInExceptBoolean),
                 PseudoRandom.randomElement(builtInExceptBoolean));
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryEqualityOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryEqualityOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -28,7 +28,6 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
-import jdk.test.lib.jittester.types.TypeBoolean;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
@@ -43,13 +42,13 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return resultType.equals(new TypeBoolean());
+        return resultType.equals(TypeList.BOOLEAN);
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         final List<Type> builtInExceptBoolean = new ArrayList<>(TypeList.getBuiltIn());
-        builtInExceptBoolean.remove(new TypeBoolean());
+        builtInExceptBoolean.remove(TypeList.BOOLEAN);
         return new Pair<>(PseudoRandom.randomElement(builtInExceptBoolean), PseudoRandom.randomElement(builtInExceptBoolean));
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryLogicOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryLogicOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -30,7 +30,7 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
 import jdk.test.lib.jittester.Type;
-import jdk.test.lib.jittester.types.TypeBoolean;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
@@ -42,11 +42,11 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return resultType.equals(new TypeBoolean());
+        return resultType.equals(TypeList.BOOLEAN);
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         return new Pair<>(resultType, resultType);
     }
 
@@ -81,6 +81,6 @@
         } finally {
             SymbolTable.pop();
         }
-        return new BinaryOperator(opKind, leftOperand, rightOperand);
+        return new BinaryOperator(opKind, resultType, leftOperand, rightOperand);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -33,7 +33,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-abstract class BinaryOperatorFactory extends OperatorFactory {
+abstract class BinaryOperatorFactory extends OperatorFactory<BinaryOperator> {
     protected final OperatorKind opKind;
     protected final Type resultType;
     protected final Type ownerClass;
@@ -48,7 +48,7 @@
 
     protected abstract boolean isApplicable(Type resultType);
 
-    protected abstract Pair<Type, Type> generateTypes() throws ProductionFailedException;
+    protected abstract Pair<Type, Type> generateTypes();
 
     protected BinaryOperator generateProduction(Type leftType, Type rightType) throws ProductionFailedException {
         int leftOpLimit = (int) (PseudoRandom.random() * (operatorLimit - 1));
@@ -72,11 +72,11 @@
                 .setResultType(rightType)
                 .getExpressionFactory()
                 .produce();
-        return new BinaryOperator(opKind, leftExpr, rightExpr);
+        return new BinaryOperator(opKind, resultType, leftExpr, rightExpr);
     }
 
     @Override
-    public final IRNode produce() throws ProductionFailedException {
+    public final BinaryOperator produce() throws ProductionFailedException {
         if (!isApplicable(resultType)) {
             //avoid implicit use of resultType.toString()
             throw new ProductionFailedException("Type " + resultType.getName() + " is not applicable by " + getClass().getName());
@@ -91,7 +91,7 @@
 
         try {
             SymbolTable.push();
-            IRNode p = generateProduction(types.first, types.second);
+            BinaryOperator p = generateProduction(types.first, types.second);
             SymbolTable.merge();
             return p;
         } catch (ProductionFailedException e) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryShiftOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryShiftOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -28,9 +28,7 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
-import jdk.test.lib.jittester.types.TypeInt;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeLong;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 import jdk.test.lib.jittester.utils.TypeUtil;
 
@@ -42,13 +40,13 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return resultType.equals(new TypeInt()) || resultType.equals(new TypeLong());
+        return resultType.equals(TypeList.INT) || resultType.equals(TypeList.LONG);
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
-        Type leftType = resultType.equals(new TypeInt()) ? PseudoRandom.randomElement(TypeUtil.getImplicitlyCastable(TypeList.getBuiltInInt(), resultType)) : resultType;
-        Type rightType = PseudoRandom.randomElement(TypeUtil.getImplicitlyCastable(TypeList.getBuiltInInt(), new TypeLong()));
+    protected Pair<Type, Type> generateTypes() {
+        Type leftType = resultType.equals(TypeList.INT) ? PseudoRandom.randomElement(TypeUtil.getImplicitlyCastable(TypeList.getBuiltInInt(), resultType)) : resultType;
+        Type rightType = PseudoRandom.randomElement(TypeUtil.getImplicitlyCastable(TypeList.getBuiltInInt(), TypeList.LONG));
         return new Pair<>(leftType, rightType);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryStringPlusFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryStringPlusFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -38,11 +38,11 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return resultType.equals(TypeList.find("java.lang.String"));
-        }
+        return resultType.equals(TypeList.STRING);
+    }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         return new Pair<>(resultType, resultType);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BitwiseInversionOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BitwiseInversionOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,7 +23,6 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
@@ -31,8 +30,6 @@
 import jdk.test.lib.jittester.utils.TypeUtil;
 import jdk.test.lib.jittester.UnaryOperator;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeInt;
-import jdk.test.lib.jittester.types.TypeLong;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
 class BitwiseInversionOperatorFactory extends UnaryOperatorFactory {
@@ -43,12 +40,12 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return resultType.equals(new TypeInt()) || resultType.equals(new TypeLong());
+        return resultType.equals(TypeList.INT) || resultType.equals(TypeList.LONG);
     }
 
     @Override
-    protected Type generateType() throws ProductionFailedException {
-        if (resultType.equals(new TypeInt())) {
+    protected Type generateType() {
+        if (resultType.equals(TypeList.INT)) {
             return PseudoRandom.randomElement(TypeUtil.getImplicitlyCastable(TypeList.getBuiltIn(), resultType));
         } else {
             return resultType;
@@ -56,7 +53,7 @@
     }
 
     @Override
-    protected IRNode generateProduction(Type resultType) throws ProductionFailedException {
+    protected UnaryOperator generateProduction(Type resultType) throws ProductionFailedException {
         return new UnaryOperator(opKind, new IRNodeBuilder().setComplexityLimit(complexityLimit - 1)
                 .setOperatorLimit(operatorLimit - 1)
                 .setOwnerKlass((TypeKlass) ownerClass)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BitwiseOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BitwiseOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,15 +23,15 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Operator;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Rule;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class BitwiseOperatorFactory extends Factory {
-    private final Rule rule;
+class BitwiseOperatorFactory extends Factory<Operator> {
+    private final Rule<Operator> rule;
 
     BitwiseOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
             Type resultType, boolean exceptionSafe, boolean noconsts) throws ProductionFailedException {
@@ -42,7 +42,7 @@
                 .setResultType(resultType)
                 .setExceptionSafe(exceptionSafe)
                 .setNoConsts(noconsts);
-        rule = new Rule("bitwise");
+        rule = new Rule<>("bitwise");
         rule.add("and", builder.setOperatorKind(OperatorKind.BIT_AND).getBinaryOperatorFactory());
         rule.add("or", builder.setOperatorKind(OperatorKind.BIT_OR).getBinaryOperatorFactory());
         rule.add("xor", builder.setOperatorKind(OperatorKind.BIT_XOR).getBinaryOperatorFactory());
@@ -53,7 +53,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Operator produce() throws ProductionFailedException {
         return rule.produce();
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BlockFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BlockFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -38,13 +38,12 @@
 import jdk.test.lib.jittester.loops.For;
 import jdk.test.lib.jittester.loops.While;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeVoid;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
 import java.util.ArrayList;
 import java.util.List;
 
-class BlockFactory extends Factory {
+class BlockFactory extends Factory<Block> {
     private final Type returnType;
     private final long complexityLimit;
     private final int statementLimit;
@@ -74,7 +73,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Block produce() throws ProductionFailedException {
         if (statementLimit > 0 && complexityLimit > 0) {
             List<IRNode> content = new ArrayList<>();
             int slimit = PseudoRandom.randomNotZero(statementLimit);
@@ -89,12 +88,12 @@
                     .setCanHaveContinues(canHaveContinues)
                     .setExceptionSafe(false)
                     .setNoConsts(false);
-            Rule rule;
+            Rule<IRNode> rule;
             SymbolTable.push();
             for (int i = 0; i < slimit && climit > 0; ) {
                 int subLimit = (int) (PseudoRandom.random() * (slimit - i - 1));
                 builder.setComplexityLimit((long) (PseudoRandom.random() * climit));
-                rule = new Rule("block");
+                rule = new Rule<>("block");
                 rule.add("statement", builder.getStatementFactory(), 5);
                 if (!ProductionParams.disableVarsInBlock.value()) {
                     rule.add("decl", builder.setIsLocal(true).getDeclarationFactory());
@@ -131,14 +130,14 @@
                 }
             }
             // Ok, if the block can end with break and continue. Generate the appropriate productions.
-            rule = new Rule("block_ending");
+            rule = new Rule<>("block_ending");
             if (canHaveBreaks && !subBlock) {
                 rule.add("break", builder.getBreakFactory());
             }
             if (canHaveContinues && !subBlock) {
                 rule.add("continue", builder.getContinueFactory());
             }
-            if (canHaveReturn && !subBlock && !returnType.equals(new TypeVoid())) {
+            if (canHaveReturn && !subBlock && !returnType.equals(TypeList.VOID)) {
                 rule.add("return", builder.setComplexityLimit(climit).getReturnFactory());
             }
             if (canHaveThrow && !subBlock) {
@@ -166,7 +165,7 @@
         throw new ProductionFailedException();
     }
 
-    private void addControlFlowDeviation(Rule rule, IRNodeBuilder builder) {
+    private void addControlFlowDeviation(Rule<IRNode> rule, IRNodeBuilder builder) {
         if (!ProductionParams.disableIf.value()) {
             rule.add("if", builder.getIfFactory());
         }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BreakFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BreakFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -24,12 +24,11 @@
 package jdk.test.lib.jittester.factories;
 
 import jdk.test.lib.jittester.Break;
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.ProductionFailedException;
 
-class BreakFactory extends Factory {
+class BreakFactory extends Factory<Break> {
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Break produce() throws ProductionFailedException {
         return new Break();
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CastOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CastOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -33,7 +33,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class CastOperatorFactory extends OperatorFactory {
+class CastOperatorFactory extends OperatorFactory<CastOperator> {
     private final Type resultType;
     private final Type ownerClass;
 
@@ -45,12 +45,12 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public CastOperator produce() throws ProductionFailedException {
         ArrayList<Type> argType = new ArrayList<>(TypeList.getAll());
         PseudoRandom.shuffle(argType);
         for (Type type : argType) {
             try {
-                ExpressionFactory expressionFactory = new IRNodeBuilder()
+                Factory<IRNode> expressionFactory = new IRNodeBuilder()
                         .setComplexityLimit(complexityLimit - 1)
                         .setOperatorLimit(operatorLimit - 1)
                         .setOwnerKlass((TypeKlass) ownerClass)
@@ -59,14 +59,11 @@
                         .setResultType(type)
                         .getExpressionFactory();
                 SymbolTable.push();
-                if (type.equals(resultType)) {
-                    IRNode expr = expressionFactory.produce();
-                    SymbolTable.merge();
-                    return expr;
-                } else if ((!exceptionSafe || exceptionSafe && !(type instanceof TypeKlass))
-                        && type.canExplicitlyCastTo(resultType)) {
+                if (type.equals(resultType) ||
+                        ((!exceptionSafe || exceptionSafe && !(type instanceof TypeKlass))
+                            && type.canExplicitlyCastTo(resultType))) {
                     // In safe mode we cannot explicitly cast an object, because it may throw.
-                    IRNode castOperator = new CastOperator(resultType, expressionFactory.produce());
+                    CastOperator castOperator = new CastOperator(resultType, expressionFactory.produce());
                     SymbolTable.merge();
                     return castOperator;
                 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ClassDefinitionBlockFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ClassDefinitionBlockFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -38,7 +38,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class ClassDefinitionBlockFactory extends Factory {
+class ClassDefinitionBlockFactory extends Factory<ClassDefinitionBlock> {
     private final String prefix;
     private final long complexityLimit;
     private final int classesLimit;
@@ -62,7 +62,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public ClassDefinitionBlock produce() throws ProductionFailedException {
         ArrayList<IRNode> content = new ArrayList<>();
         int limit = (int) Math.ceil(PseudoRandom.random() * classesLimit);
         if (limit > 0) {
@@ -74,9 +74,8 @@
                     .setComplexityLimit(classCompl);
             for (int i = 0; i < limit; i++) {
                 try {
-                    Rule rule = new Rule("class");
+                    Rule<IRNode> rule = new Rule<>("class");
                     rule.add("basic_class", builder.setName(prefix + "_Class_" + i)
-                            .setPrinterName(prefix + ".Printer")
                             .setMemberFunctionsLimit(memberFunctionsLimit)
                             .getKlassFactory());
                     if (!ProductionParams.disableInterfaces.value()) {
@@ -110,13 +109,12 @@
             IRNode randomChild = childs.get(0);
             List<IRNode> leaves = randomChild.getStackableLeaves();
             if (!leaves.isEmpty()) {
-                PseudoRandom.shuffle(leaves);
-                Block randomLeaf = (Block) leaves.get(0);
-                TypeKlass klass = (TypeKlass) randomChild.getKlass();
+                Block randomLeaf = (Block) leaves.get(PseudoRandom.randomNotNegative(leaves.size()));
+                TypeKlass owner = randomChild.getOwner();
                 int newLevel = randomLeaf.getLevel() + 1;
-                Type retType = randomLeaf.getReturnType();
+                Type retType = randomLeaf.getResultType();
                 IRNodeBuilder b = new IRNodeBuilder()
-                        .setOwnerKlass(klass)
+                        .setOwnerKlass(owner)
                         .setResultType(retType)
                         .setComplexityLimit(complexityLimit)
                         .setStatementLimit(statementLimit)
@@ -137,7 +135,7 @@
                 .filter(c -> c instanceof Klass && c.countDepth() > maxDepth)
                 .collect(Collectors.toList());
         for (IRNode ch : childs) {
-            List<IRNode> leaves = null;
+            List<IRNode> leaves;
             do {
                 long depth = Math.max(ch.countDepth(), maxDepth + 1);
                 leaves = ch.getDeviantBlocks(depth);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CompoundArithmeticAssignmentOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CompoundArithmeticAssignmentOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -30,8 +30,8 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.VariableBase;
 import jdk.test.lib.jittester.utils.TypeUtil;
-import jdk.test.lib.jittester.types.TypeBoolean;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
@@ -43,11 +43,11 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return TypeList.isBuiltIn(resultType) && !resultType.equals(new TypeBoolean());
+        return TypeList.isBuiltIn(resultType) && !resultType.equals(TypeList.BOOLEAN);
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         return new Pair<>(resultType, PseudoRandom.randomElement(
                 TypeUtil.getExplicitlyCastable(TypeList.getBuiltIn(), resultType)));
     }
@@ -66,13 +66,13 @@
                 .setResultType(rightType)
                 .getExpressionFactory()
                 .produce();
-        IRNode leftExpr = builder.setComplexityLimit(leftComplexityLimit)
+        VariableBase leftExpr = builder.setComplexityLimit(leftComplexityLimit)
                 .setOperatorLimit(leftOperatorLimit)
                 .setResultType(leftType)
                 .setIsConstant(false)
                 .setIsInitialized(true)
                 .getVariableFactory()
                 .produce();
-        return new BinaryOperator(opKind, leftExpr, rightExpr);
+        return new BinaryOperator(opKind, resultType, leftExpr, rightExpr);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CompoundBitwiseAssignmentOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CompoundBitwiseAssignmentOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -46,7 +46,7 @@
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         return new Pair<>(resultType, PseudoRandom.randomElement(TypeUtil.getExplicitlyCastable(TypeList.getBuiltInInt(), resultType)));
     }
 
@@ -71,6 +71,6 @@
                 .setResultType(rightType)
                 .getExpressionFactory()
                 .produce();
-        return new BinaryOperator(opKind, leftExpr, rightExpr);
+        return new BinaryOperator(opKind, resultType, leftExpr, rightExpr);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CompoundShiftAssignmentOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CompoundShiftAssignmentOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -32,7 +32,6 @@
 import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.utils.TypeUtil;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeBoolean;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
 class CompoundShiftAssignmentOperatorFactory extends BinaryOperatorFactory {
@@ -43,11 +42,11 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return TypeList.isBuiltInInt(resultType) && !resultType.equals(new TypeBoolean());
+        return TypeList.isBuiltInInt(resultType) && !resultType.equals(TypeList.BOOLEAN);
     }
 
     @Override
-    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+    protected Pair<Type, Type> generateTypes() {
         return new Pair<>(resultType, PseudoRandom.randomElement(
                 TypeUtil.getExplicitlyCastable(TypeList.getBuiltInInt(), resultType)));
     }
@@ -73,6 +72,6 @@
                 .setResultType(rightType)
                 .getExpressionFactory()
                 .produce();
-        return new BinaryOperator(opKind, leftExpr, rightExpr);
+        return new BinaryOperator(opKind, resultType, leftExpr, rightExpr);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ConstructorDefinitionBlockFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ConstructorDefinitionBlockFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -31,7 +31,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class ConstructorDefinitionBlockFactory extends Factory {
+class ConstructorDefinitionBlockFactory extends Factory<ConstructorDefinitionBlock> {
     private final long complexityLimit;
     private final int statementLimit;
     private final int operatorLimit;
@@ -53,7 +53,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public ConstructorDefinitionBlock produce() throws ProductionFailedException {
         IRNodeBuilder builder = new IRNodeBuilder()
                 .setOwnerKlass(ownerClass)
                 .setStatementLimit(statementLimit)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ConstructorDefinitionFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ConstructorDefinitionFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -28,15 +28,15 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Symbol;
 import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.VariableInfo;
 import jdk.test.lib.jittester.functions.ArgumentDeclaration;
 import jdk.test.lib.jittester.functions.ConstructorDefinition;
 import jdk.test.lib.jittester.functions.FunctionInfo;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeVoid;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class ConstructorDefinitionFactory extends Factory {
+class ConstructorDefinitionFactory extends Factory<ConstructorDefinition> {
     private final long complexityLimit;
     private final int statementLimit;
     private final int operatorLimit;
@@ -55,7 +55,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public ConstructorDefinition produce() throws ProductionFailedException {
         int argNumber = (int) (PseudoRandom.random() * memberFunctionsArgLimit);
         ArrayList<VariableInfo> argumentsInfo = new ArrayList<>(argNumber);
         ArrayList<ArgumentDeclaration> argumentsDeclaration = new ArrayList<>(argNumber);
@@ -90,7 +90,7 @@
             }
             long blockComplLimit = (long) (PseudoRandom.random() * complexityLimit);
             try {
-                body = builder.setResultType(new TypeVoid())
+                body = builder.setResultType(TypeList.VOID)
                         .setComplexityLimit(blockComplLimit)
                         .setStatementLimit(statementLimit)
                         .setOperatorLimit(operatorLimit)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ContinueFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ContinueFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -24,12 +24,11 @@
 package jdk.test.lib.jittester.factories;
 
 import jdk.test.lib.jittester.Continue;
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.ProductionFailedException;
 
-class ContinueFactory extends Factory {
+class ContinueFactory extends Factory<Continue> {
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Continue produce() throws ProductionFailedException {
         return new Continue();
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CounterInitializerFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CounterInitializerFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -24,20 +24,20 @@
 package jdk.test.lib.jittester.factories;
 
 import java.util.List;
+
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.LiteralInitializer;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.VariableInfo;
 import jdk.test.lib.jittester.utils.TypeUtil;
-import jdk.test.lib.jittester.VariableInfo;
 import jdk.test.lib.jittester.loops.CounterInitializer;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeInt;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class CounterInitializerFactory extends SafeFactory {
+class CounterInitializerFactory extends SafeFactory<CounterInitializer> {
     private final int counterValue;
     private final TypeKlass ownerClass;
 
@@ -47,9 +47,9 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
-        List<Type> types = TypeUtil.getMoreCapaciousThan(TypeList.getBuiltIn(), new TypeInt());
-        types.add(new TypeInt());
+    protected CounterInitializer sproduce() throws ProductionFailedException {
+        List<Type> types = TypeUtil.getMoreCapaciousThan(TypeList.getBuiltIn(), TypeList.INT);
+        types.add(TypeList.INT);
         final Type selectedType = PseudoRandom.randomElement(types);
         IRNode init = new LiteralInitializer(counterValue, selectedType);
         String resultName = "var_" + SymbolTable.getNextVariableNumber();
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CounterManipulatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CounterManipulatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -27,10 +27,11 @@
 import jdk.test.lib.jittester.LocalVariable;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.Statement;
 import jdk.test.lib.jittester.UnaryOperator;
 import jdk.test.lib.jittester.loops.CounterManipulator;
 
-class CounterManipulatorFactory extends Factory {
+class CounterManipulatorFactory extends Factory<CounterManipulator> {
     private final LocalVariable counter;
 
     CounterManipulatorFactory(LocalVariable counter) {
@@ -38,9 +39,9 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public CounterManipulator produce() throws ProductionFailedException {
         // We'll keep it simple for the time being..
         IRNode manipulator = new UnaryOperator(OperatorKind.POST_DEC, counter);
-        return new CounterManipulator(manipulator);
+        return new CounterManipulator(new Statement(manipulator, false));
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/DeclarationFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/DeclarationFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -31,7 +31,7 @@
 import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class DeclarationFactory extends Factory {
+class DeclarationFactory extends Factory<Declaration> {
     private final int operatorLimit;
     private final long complexityLimit;
     private final boolean isLocal;
@@ -48,29 +48,42 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
-        Rule rule = new Rule("declaration");
+    public Declaration produce() throws ProductionFailedException {
+        Rule<IRNode> rule = new Rule<>("declaration");
         IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(ownerClass)
-                .setResultType(TypeList.getVoid())
+                .setResultType(TypeList.VOID)
                 .setIsLocal(isLocal)
                 .setComplexityLimit(complexityLimit)
                 .setOperatorLimit(operatorLimit)
                 .setIsLocal(isLocal)
                 .setExceptionSafe(exceptionSafe);
-        rule.add("decl", builder.setIsStatic(false).getVariableDeclarationFactory());
-        rule.add("decl_and_init", builder.setIsConstant(false)
-                .setIsStatic(false).getVariableInitializationFactory());
+        rule.add("decl", builder
+                .setIsStatic(false)
+                .getVariableDeclarationFactory());
+        rule.add("decl_and_init", builder
+                .setIsConstant(false)
+                .setIsStatic(false)
+                .getVariableInitializationFactory());
         if (!ProductionParams.disableFinalVariables.value()) {
-            rule.add("const_decl_and_init", builder.setIsConstant(true)
-                    .setIsStatic(false).getVariableInitializationFactory());
+            rule.add("const_decl_and_init", builder
+                    .setIsConstant(true)
+                    .setIsStatic(false)
+                    .getVariableInitializationFactory());
         }
         if (!isLocal && !ProductionParams.disableStatic.value()) {
-            rule.add("static_decl", builder.setIsStatic(true).getVariableDeclarationFactory());
-            rule.add("static_decl_and_init", builder.setIsConstant(false)
-                    .setIsStatic(true).getVariableInitializationFactory());
+            rule.add("static_decl", builder
+                    .setIsConstant(false)
+                    .setIsStatic(true)
+                    .getVariableDeclarationFactory());
+            rule.add("static_decl_and_init", builder
+                    .setIsConstant(false)
+                    .setIsStatic(true)
+                    .getVariableInitializationFactory());
             if (!ProductionParams.disableFinalVariables.value()) {
-                rule.add("static_const_decl_and_init", builder.setIsConstant(true)
-                        .setIsStatic(true).getVariableInitializationFactory());
+                rule.add("static_const_decl_and_init", builder
+                        .setIsConstant(true)
+                        .setIsStatic(true)
+                        .getVariableInitializationFactory());
             }
         }
         return new Declaration(rule.produce());
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/DoWhileFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/DoWhileFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,21 +23,21 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
-import jdk.test.lib.jittester.Initialization;
+import jdk.test.lib.jittester.Block;
 import jdk.test.lib.jittester.Literal;
 import jdk.test.lib.jittester.LocalVariable;
-import jdk.test.lib.jittester.Nothing;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.loops.DoWhile;
 import jdk.test.lib.jittester.loops.Loop;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeInt;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class DoWhileFactory extends SafeFactory {
+import java.util.LinkedList;
+
+class DoWhileFactory extends SafeFactory<DoWhile> {
     private final Loop loop;
     private final long complexityLimit;
     private final int statementLimit;
@@ -62,7 +62,8 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected DoWhile sproduce() throws ProductionFailedException {
+        Block emptyBlock = new Block(ownerClass, returnType, new LinkedList<>(), level - 1);
         if (statementLimit > 0 && complexityLimit > 0) {
             long complexity = complexityLimit;
             // Loop header parameters
@@ -89,7 +90,7 @@
                     .setResultType(returnType)
                     .setOperatorLimit(operatorLimit);
             loop.initialization = builder.getCounterInitializerFactory(0).produce();
-            IRNode header;
+            Block header;
             try {
                 header = builder.setComplexityLimit(headerComplLimit)
                         .setStatementLimit(headerStatementLimit)
@@ -101,17 +102,17 @@
                         .getBlockFactory()
                         .produce();
             } catch (ProductionFailedException e) {
-                header = new Nothing();
+                header = emptyBlock;
             }
             // getChildren().set(DoWhile.DoWhilePart.HEADER.ordinal(), header);
-            LocalVariable counter = new LocalVariable(((Initialization) loop.initialization).get());
-            Literal limiter = new Literal(Integer.valueOf((int) thisLoopIterLimit), new TypeInt());
+            LocalVariable counter = new LocalVariable(loop.initialization.getVariableInfo());
+            Literal limiter = new Literal((int) thisLoopIterLimit, TypeList.INT);
             loop.condition = builder.setComplexityLimit(condComplLimit)
                     .setLocalVariable(counter)
                     .getLoopingConditionFactory(limiter)
                     .produce();
             SymbolTable.push();
-            IRNode body1;
+            Block body1;
             try {
                 body1 = builder.setComplexityLimit(body1ComplLimit)
                         .setStatementLimit(body1StatementLimit)
@@ -123,11 +124,11 @@
                         .getBlockFactory()
                         .produce();
             } catch (ProductionFailedException e) {
-                body1 = new Nothing();
+                body1 = emptyBlock;
             }
             // getChildren().set(DoWhile.DoWhilePart.BODY1.ordinal(), body1);
             loop.manipulator = builder.setLocalVariable(counter).getCounterManipulatorFactory().produce();
-            IRNode body2;
+            Block body2;
             try {
                 body2 = builder.setComplexityLimit(body2ComplLimit)
                         .setStatementLimit(body2StatementLimit)
@@ -139,7 +140,7 @@
                         .getBlockFactory()
                         .produce();
             } catch (ProductionFailedException e) {
-                body2 = new Nothing();
+                body2 = emptyBlock;
             }
             // getChildren().set(DoWhile.DoWhilePart.BODY2.ordinal(), body2);
             SymbolTable.pop();
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ExpressionFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ExpressionFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -29,11 +29,11 @@
 import jdk.test.lib.jittester.ProductionLimiter;
 import jdk.test.lib.jittester.ProductionParams;
 import jdk.test.lib.jittester.Rule;
-import jdk.test.lib.jittester.Type;;
+import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class ExpressionFactory extends SafeFactory {
-    private final Rule rule;
+class ExpressionFactory extends SafeFactory<IRNode> {
+    private final Rule<IRNode> rule;
 
     ExpressionFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass, Type resultType,
             boolean exceptionSafe, boolean noconsts) throws ProductionFailedException {
@@ -44,7 +44,7 @@
                 .setResultType(resultType)
                 .setExceptionSafe(exceptionSafe)
                 .setNoConsts(noconsts);
-        rule = new Rule("expression");
+        rule = new Rule<>("expression");
         if (!noconsts) {
             rule.add("literal", builder.getLiteralFactory());
             rule.add("constant", builder.setIsConstant(true)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/Factory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/Factory.java	Fri May 20 18:05:09 2016 +0300
@@ -26,6 +26,6 @@
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.ProductionFailedException;
 
-public abstract class Factory {
-    public abstract IRNode produce() throws ProductionFailedException;
+public abstract class Factory<T extends IRNode> {
+    public abstract T produce() throws ProductionFailedException;
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ForFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ForFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,22 +23,25 @@
 
 package jdk.test.lib.jittester.factories;
 
+import jdk.test.lib.jittester.Block;
 import jdk.test.lib.jittester.IRNode;
-import jdk.test.lib.jittester.Initialization;
 import jdk.test.lib.jittester.Literal;
 import jdk.test.lib.jittester.LocalVariable;
 import jdk.test.lib.jittester.Nothing;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Rule;
+import jdk.test.lib.jittester.Statement;
 import jdk.test.lib.jittester.SymbolTable;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.loops.For;
 import jdk.test.lib.jittester.loops.Loop;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeInt;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class ForFactory extends SafeFactory {
+import java.util.LinkedList;
+
+class ForFactory extends SafeFactory<For> {
     private final Loop loop;
     private final long complexityLimit;
     private final int statementLimit;
@@ -46,7 +49,6 @@
     private final TypeKlass ownerClass;
     private final Type returnType;
     private final int level;
-    private long thisLoopIterLimit = 0;
     private final boolean canHaveReturn;
 
     ForFactory(TypeKlass ownerClass, Type returnType, long complexityLimit, int statementLimit,
@@ -62,7 +64,8 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected For sproduce() throws ProductionFailedException {
+        Block emptyBlock = new Block(ownerClass, returnType, new LinkedList<>(), level - 1);
         if (statementLimit <= 0 || complexityLimit <= 0) {
             throw new ProductionFailedException();
         }
@@ -81,7 +84,7 @@
         long statement1ComplLimit = (long) (0.005 * complexity * PseudoRandom.random());
         complexity -= statement1ComplLimit;
         // Loop body parameters
-        thisLoopIterLimit = (long) (0.0001 * complexity * PseudoRandom.random());
+        long thisLoopIterLimit = (long) (0.0001 * complexity * PseudoRandom.random());
         if (thisLoopIterLimit > Integer.MAX_VALUE || thisLoopIterLimit == 0) {
             throw new ProductionFailedException();
         }
@@ -100,7 +103,7 @@
         int body3StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 4.0));
         // Production
         loop.initialization = builder.getCounterInitializerFactory(0).produce();
-        IRNode header;
+        Block header;
         try {
             header = builder.setComplexityLimit(headerComplLimit)
                     .setStatementLimit(headerStatementLimit)
@@ -112,12 +115,12 @@
                     .getBlockFactory()
                     .produce();
         } catch (ProductionFailedException e) {
-            header = new Nothing();
+            header = emptyBlock;
         }
         SymbolTable.push();
         IRNode statement1;
         try {
-            Rule rule = new Rule("statement1");
+            Rule<IRNode> rule = new Rule<>("statement1");
             builder.setComplexityLimit(statement1ComplLimit);
             rule.add("assignment", builder.getAssignmentOperatorFactory());
             rule.add("function", builder.getFunctionFactory(), 0.1);
@@ -129,20 +132,20 @@
         } catch (ProductionFailedException e) {
             statement1 = new Nothing();
         }
-        LocalVariable counter = new LocalVariable(((Initialization) loop.initialization).get());
-        Literal limiter = new Literal(Integer.valueOf((int) thisLoopIterLimit), new TypeInt());
+        LocalVariable counter = new LocalVariable(loop.initialization.getVariableInfo());
+        Literal limiter = new Literal((int) thisLoopIterLimit, TypeList.INT);
         loop.condition = builder.setComplexityLimit(condComplLimit)
                 .setLocalVariable(counter)
                 .getLoopingConditionFactory(limiter)
                 .produce();
         IRNode statement2;
         try {
-            statement2 =  builder.setComplexityLimit(statement2ComplLimit)
+            statement2 = builder.setComplexityLimit(statement2ComplLimit)
                     .getAssignmentOperatorFactory().produce();
         } catch (ProductionFailedException e) {
             statement2 = new Nothing();
         }
-        IRNode body1;
+        Block body1;
         try {
             body1 = builder.setComplexityLimit(body1ComplLimit)
                     .setStatementLimit(body1StatementLimit)
@@ -154,10 +157,10 @@
                     .getBlockFactory()
                     .produce();
         } catch (ProductionFailedException e) {
-            body1 = new Nothing();
+            body1 = emptyBlock;
         }
         loop.manipulator = builder.setLocalVariable(counter).getCounterManipulatorFactory().produce();
-        IRNode body2;
+        Block body2;
         try {
             body2 = builder.setComplexityLimit(body2ComplLimit)
                     .setStatementLimit(body2StatementLimit)
@@ -169,9 +172,9 @@
                     .getBlockFactory()
                     .produce();
         } catch (ProductionFailedException e) {
-            body2 = new Nothing();
+            body2 = emptyBlock;
         }
-        IRNode body3;
+        Block body3;
         try {
             body3 = builder.setComplexityLimit(body3ComplLimit)
                     .setStatementLimit(body3StatementLimit)
@@ -183,10 +186,13 @@
                     .getBlockFactory()
                     .produce();
         } catch (ProductionFailedException e) {
-            body3 = new Nothing();
+            body3 = emptyBlock;
         }
         SymbolTable.pop();
-        return new For(level, loop, thisLoopIterLimit, header, statement1, statement2, body1,
+        return new For(level, loop, thisLoopIterLimit, header,
+                new Statement(statement1, false),
+                new Statement(statement2, false),
+                body1,
                 body2, body3);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDeclarationBlockFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDeclarationBlockFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -31,7 +31,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class FunctionDeclarationBlockFactory extends Factory {
+class FunctionDeclarationBlockFactory extends Factory<FunctionDeclarationBlock> {
     private final int memberFunctionsLimit;
     private final int memberFunctionsArgLimit;
     private final int level;
@@ -46,7 +46,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public FunctionDeclarationBlock produce() throws ProductionFailedException {
         ArrayList<IRNode> content = new ArrayList<>();
         int memFunLimit = (int) (PseudoRandom.random() * memberFunctionsLimit);
         if (memFunLimit > 0) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDeclarationFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDeclarationFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -27,7 +27,6 @@
 import java.util.Collection;
 import java.util.List;
 
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Symbol;
 import jdk.test.lib.jittester.SymbolTable;
@@ -39,10 +38,9 @@
 import jdk.test.lib.jittester.functions.FunctionDefinition;
 import jdk.test.lib.jittester.functions.FunctionInfo;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeVoid;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class FunctionDeclarationFactory extends Factory {
+class FunctionDeclarationFactory extends Factory<FunctionDeclaration> {
     private final Type resultType;
     private final TypeKlass ownerClass;
     private final String name;
@@ -59,11 +57,11 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public FunctionDeclaration produce() throws ProductionFailedException {
         Type resType = resultType;
         if (resType == null) {
             List<Type> types = new ArrayList<>(TypeList.getAll());
-            types.add(new TypeVoid());
+            types.add(TypeList.VOID);
             resType = PseudoRandom.randomElement(types);
         }
         int argNumber = (int) (PseudoRandom.random() * memberFunctionsArgLimit);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDefinitionBlockFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDefinitionBlockFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -35,7 +35,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class FunctionDefinitionBlockFactory extends Factory {
+class FunctionDefinitionBlockFactory extends Factory<FunctionDefinitionBlock> {
     private final long complexityLimit;
     private final int statementLimit;
     private final int operatorLimit;
@@ -59,7 +59,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public FunctionDefinitionBlock produce() throws ProductionFailedException {
         ArrayList<IRNode> content = new ArrayList<>();
         int memFunLimit = (int) (PseudoRandom.random() * memberFunctionsLimit);
         if (memFunLimit > 0) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDefinitionFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDefinitionFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -28,6 +28,7 @@
 import java.util.List;
 
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Nothing;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Symbol;
 import jdk.test.lib.jittester.SymbolTable;
@@ -37,11 +38,11 @@
 import jdk.test.lib.jittester.functions.ArgumentDeclaration;
 import jdk.test.lib.jittester.functions.FunctionDefinition;
 import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.functions.Return;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeVoid;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class FunctionDefinitionFactory extends Factory {
+class FunctionDefinitionFactory extends Factory<FunctionDefinition> {
     private final Type resultType;
     private final String name;
     private final long complexityLimit;
@@ -67,11 +68,11 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public FunctionDefinition produce() throws ProductionFailedException {
         Type resType = resultType;
         if (resType == null) {
             List<Type> types = new ArrayList<>(TypeList.getAll());
-            types.add(new TypeVoid());
+            types.add(TypeList.VOID);
             resType = PseudoRandom.randomElement(types);
         }
         int argNumber = (int) (PseudoRandom.random() * memberFunctionsArgLimit);
@@ -86,7 +87,7 @@
         ArrayList<ArgumentDeclaration> argumentsDeclaration = new ArrayList<>(argNumber);
         SymbolTable.push();
         IRNode body;
-        IRNode returnNode;
+        Return returnNode;
         FunctionInfo functionInfo;
         try {
             IRNodeBuilder builder = new IRNodeBuilder().setArgumentType(ownerClass);
@@ -127,13 +128,13 @@
                     .setCanHaveReturn(true)
                     .getBlockFactory()
                     .produce();
-            if (!resType.equals(new TypeVoid())) {
+            if (!resType.equals(TypeList.VOID)) {
                 returnNode = builder.setComplexityLimit(complexityLimit - blockComplLimit)
                         .setExceptionSafe(false)
                         .getReturnFactory()
                         .produce();
             } else {
-                returnNode = null;
+                returnNode = new Return(new Nothing());
             }
         } finally {
             SymbolTable.pop();
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -37,7 +37,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class FunctionFactory extends SafeFactory {
+class FunctionFactory extends SafeFactory<Function> {
     private final FunctionInfo functionInfo;
     private final int operatorLimit;
     private final long complexityLimit;
@@ -55,7 +55,7 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected Function sproduce() throws ProductionFailedException {
         // Currently no function is exception-safe
         if (exceptionSafe) {
             throw new ProductionFailedException();
@@ -72,7 +72,7 @@
             for (Symbol function : allFunctions) {
                 FunctionInfo functionInfo = (FunctionInfo) function;
                 // Don't try to construct abstract classes.
-                if (functionInfo.isConstructor() && functionInfo.klass.isAbstract()) {
+                if (functionInfo.isConstructor() && functionInfo.owner.isAbstract()) {
                     continue;
                 }
                 // We don't call methods from the same class which are not final, because if we
@@ -94,7 +94,7 @@
 
                 // If it's a local call.. or it's a call using some variable to some object of some type in our hierarchy
                 boolean inHierarchy = false;
-                if (ownerClass.equals(functionInfo.klass) || (inHierarchy = klassHierarchy.contains(functionInfo.klass))) {
+                if (ownerClass.equals(functionInfo.owner) || (inHierarchy = klassHierarchy.contains(functionInfo.owner))) {
                     if ((functionInfo.flags & FunctionInfo.FINAL) == 0 && (functionInfo.flags & FunctionInfo.STATIC) == 0
                             && (functionInfo.flags & FunctionInfo.NONRECURSIVE) == 0) {
                         continue;
@@ -121,7 +121,7 @@
                             // If there are function with a same name and same number of args,
                             // then disable usage of foldable expressions in the args.
                             boolean noconsts = false;
-                            Collection<Symbol> allFuncsInKlass = SymbolTable.getAllCombined(functionInfo.klass,
+                            Collection<Symbol> allFuncsInKlass = SymbolTable.getAllCombined(functionInfo.owner,
                                     FunctionInfo.class);
                             for (Symbol s2 : allFuncsInKlass) {
                                 FunctionInfo i2 = (FunctionInfo) function;
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionRedefinitionBlockFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionRedefinitionBlockFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -34,7 +34,7 @@
 import jdk.test.lib.jittester.functions.FunctionRedefinitionBlock;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class FunctionRedefinitionBlockFactory extends Factory {
+class FunctionRedefinitionBlockFactory extends Factory<FunctionRedefinitionBlock> {
     private final int statementLimit;
     private final int operatorLimit;
     private final long complexityLimit;
@@ -53,7 +53,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public FunctionRedefinitionBlock produce() throws ProductionFailedException {
         ArrayList<IRNode> content = new ArrayList<>();
         if (functionSet.size() > 0) {
             long funcComplexity = complexityLimit / functionSet.size();
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionRedefinitionFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionRedefinitionFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -25,17 +25,19 @@
 
 import java.util.ArrayList;
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Nothing;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.VariableInfo;
 import jdk.test.lib.jittester.functions.ArgumentDeclaration;
-import jdk.test.lib.jittester.functions.FunctionDefinition;
 import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.functions.FunctionRedefinition;
+import jdk.test.lib.jittester.functions.Return;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeVoid;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class FunctionRedefinitionFactory extends Factory {
+class FunctionRedefinitionFactory extends Factory<FunctionRedefinition> {
     private final long complexityLimit;
     private final int statementLimit;
     private final int operatorLimit;
@@ -47,14 +49,14 @@
             long complexityLimit, int statementLimit, int operatorLimit, int level, int flags) {
         this.ownerClass = ownerClass;
         this.functionInfo = new FunctionInfo(functionInfo); // do deep coping
-        functionInfo.klass = ownerClass; // important! fix klass!
+        functionInfo.owner = ownerClass; // important! fix klass!
         if ((functionInfo.flags & FunctionInfo.STATIC) == 0) {
             functionInfo.argTypes.get(0).type = ownerClass; // redefine type of this
         }
         functionInfo.flags = flags; // apply new flags.
         // fix the type of class where the args would be declared
         for (VariableInfo varInfo : functionInfo.argTypes) {
-            varInfo.klass = ownerClass;
+            varInfo.owner = ownerClass;
         }
         this.complexityLimit = complexityLimit;
         this.statementLimit = statementLimit;
@@ -63,14 +65,14 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public FunctionRedefinition produce() throws ProductionFailedException {
         ArrayList<VariableInfo> argumentsInfo = functionInfo.argTypes;
         SymbolTable.push();
         IRNode body;
-        IRNode returnNode;
+        Return returnNode;
         ArrayList<ArgumentDeclaration> argumentsDeclaration;
         try {
-            if ((functionInfo.flags & FunctionInfo.STATIC) > 0) {
+            if (functionInfo.isStatic()) {
                 argumentsDeclaration = new ArrayList<>(argumentsInfo.size());
                 for (VariableInfo varInfo : argumentsInfo) {
                     argumentsDeclaration.add(new ArgumentDeclaration(varInfo));
@@ -98,13 +100,13 @@
                     .setCanHaveReturn(true)
                     .getBlockFactory()
                     .produce();
-            if (!functionInfo.type.equals(new TypeVoid())) {
+            if (!functionInfo.type.equals(TypeList.VOID)) {
                 returnNode = builder.setComplexityLimit(complexityLimit - blockComplLimit)
                         .setExceptionSafe(false)
                         .getReturnFactory()
                         .produce();
             } else {
-                returnNode = null;
+                returnNode = new Return(new Nothing());
             }
         } catch (ProductionFailedException e) {
             SymbolTable.pop();
@@ -112,12 +114,12 @@
             throw e;
         }
         SymbolTable.pop();
-        if ((functionInfo.flags & FunctionInfo.STATIC) == 0) {
+        if (!functionInfo.isStatic()) {
             functionInfo.flags &= ~FunctionInfo.ABSTRACT;
         }
         // If it's all ok, add the function to the symbol table.
         SymbolTable.add(functionInfo);
-        return new FunctionDefinition(functionInfo, argumentsDeclaration, body, returnNode);
+        return new FunctionRedefinition(functionInfo, argumentsDeclaration, body, returnNode);
     }
 
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/IRNodeBuilder.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/IRNodeBuilder.java	Fri May 20 18:05:09 2016 +0300
@@ -25,14 +25,64 @@
 
 import java.util.Collection;
 import java.util.Optional;
+
+import jdk.test.lib.jittester.BinaryOperator;
+import jdk.test.lib.jittester.Block;
+import jdk.test.lib.jittester.Break;
+import jdk.test.lib.jittester.CastOperator;
+import jdk.test.lib.jittester.Continue;
+import jdk.test.lib.jittester.Declaration;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.If;
 import jdk.test.lib.jittester.Literal;
 import jdk.test.lib.jittester.LocalVariable;
+import jdk.test.lib.jittester.NonStaticMemberVariable;
+import jdk.test.lib.jittester.Nothing;
+import jdk.test.lib.jittester.Operator;
 import jdk.test.lib.jittester.OperatorKind;
+import jdk.test.lib.jittester.PrintVariables;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Statement;
+import jdk.test.lib.jittester.StaticMemberVariable;
+import jdk.test.lib.jittester.Switch;
 import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.TernaryOperator;
+import jdk.test.lib.jittester.Throw;
+import jdk.test.lib.jittester.TryCatchBlock;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.UnaryOperator;
+import jdk.test.lib.jittester.VariableBase;
+import jdk.test.lib.jittester.VariableDeclaration;
+import jdk.test.lib.jittester.VariableDeclarationBlock;
+import jdk.test.lib.jittester.VariableInitialization;
+import jdk.test.lib.jittester.arrays.ArrayCreation;
+import jdk.test.lib.jittester.arrays.ArrayElement;
+import jdk.test.lib.jittester.arrays.ArrayExtraction;
+import jdk.test.lib.jittester.classes.ClassDefinitionBlock;
+import jdk.test.lib.jittester.classes.Interface;
+import jdk.test.lib.jittester.classes.Klass;
+import jdk.test.lib.jittester.classes.MainKlass;
+import jdk.test.lib.jittester.functions.ArgumentDeclaration;
+import jdk.test.lib.jittester.functions.ConstructorDefinition;
+import jdk.test.lib.jittester.functions.ConstructorDefinitionBlock;
+import jdk.test.lib.jittester.functions.Function;
+import jdk.test.lib.jittester.functions.FunctionDeclaration;
+import jdk.test.lib.jittester.functions.FunctionDeclarationBlock;
+import jdk.test.lib.jittester.functions.FunctionDefinition;
+import jdk.test.lib.jittester.functions.FunctionDefinitionBlock;
 import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.functions.FunctionRedefinition;
+import jdk.test.lib.jittester.functions.FunctionRedefinitionBlock;
+import jdk.test.lib.jittester.functions.Return;
+import jdk.test.lib.jittester.functions.StaticConstructorDefinition;
+import jdk.test.lib.jittester.loops.CounterInitializer;
+import jdk.test.lib.jittester.loops.CounterManipulator;
+import jdk.test.lib.jittester.loops.DoWhile;
+import jdk.test.lib.jittester.loops.For;
+import jdk.test.lib.jittester.loops.LoopingCondition;
+import jdk.test.lib.jittester.loops.While;
 import jdk.test.lib.jittester.types.TypeKlass;
 
 public class IRNodeBuilder {
@@ -63,41 +113,40 @@
     private Optional<Boolean> isConstant = Optional.empty();
     private Optional<Boolean> isInitialized = Optional.empty();
     private Optional<String> name = Optional.empty();
-    private Optional<String> printerName = Optional.empty();
     private Optional<Integer> flags = Optional.empty();
     private Optional<FunctionInfo> functionInfo = Optional.empty();
     private Optional<Boolean> semicolon = Optional.empty();
 
-    public ArgumentDeclarationFactory getArgumentDeclarationFactory() {
+    public Factory<ArgumentDeclaration> getArgumentDeclarationFactory() {
         return new ArgumentDeclarationFactory(getArgumentType(), getVariableNumber());
     }
 
-    public Factory getArithmeticOperatorFactory() throws ProductionFailedException {
+    public Factory<Operator> getArithmeticOperatorFactory() throws ProductionFailedException {
         return new ArithmeticOperatorFactory(getComplexityLimit(), getOperatorLimit(),
                 getOwnerClass(), getResultType(), getExceptionSafe(), getNoConsts());
     }
 
-    public ArrayCreationFactory getArrayCreationFactory() {
+    public Factory<ArrayCreation> getArrayCreationFactory() {
         return new ArrayCreationFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getResultType(), getExceptionSafe(), getNoConsts());
     }
 
-    public ArrayElementFactory getArrayElementFactory() {
+    public Factory<ArrayElement> getArrayElementFactory() {
         return new ArrayElementFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getResultType(), getExceptionSafe(), getNoConsts());
     }
 
-    public ArrayExtractionFactory getArrayExtractionFactory() {
+    public Factory<ArrayExtraction> getArrayExtractionFactory() {
         return new ArrayExtractionFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getResultType(), getExceptionSafe(), getNoConsts());
     }
 
-    public AssignmentOperatorFactory getAssignmentOperatorFactory() {
+    public Factory<Operator> getAssignmentOperatorFactory() {
         return new AssignmentOperatorFactory(getComplexityLimit(), getOperatorLimit(),
                 getOwnerClass(), resultType.orElse(null), getExceptionSafe(), getNoConsts());
     }
 
-    public BinaryOperatorFactory getBinaryOperatorFactory() throws ProductionFailedException {
+    public Factory<BinaryOperator> getBinaryOperatorFactory() throws ProductionFailedException {
         OperatorKind o = getOperatorKind();
         switch (o) {
             case ASSIGN:
@@ -166,7 +215,7 @@
         }
     }
 
-    public UnaryOperatorFactory getUnaryOperatorFactory() throws ProductionFailedException {
+    public Factory<UnaryOperator> getUnaryOperatorFactory() throws ProductionFailedException {
         OperatorKind o = getOperatorKind();
         switch (o) {
             case NOT:
@@ -193,24 +242,24 @@
         }
     }
 
-    public BlockFactory getBlockFactory() throws ProductionFailedException {
+    public Factory<Block> getBlockFactory() {
         return new BlockFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
-            getStatementLimit(), getOperatorLimit(), getLevel(), subBlock.orElse(false),
-            canHaveBreaks.orElse(false), canHaveContinues.orElse(false),
+                getStatementLimit(), getOperatorLimit(), getLevel(), subBlock.orElse(false),
+                canHaveBreaks.orElse(false), canHaveContinues.orElse(false),
                 canHaveReturn.orElse(false), canHaveReturn.orElse(false));
-                //now 'throw' can be placed only in the same positions as 'return'
+        //now 'throw' can be placed only in the same positions as 'return'
     }
 
-    public BreakFactory getBreakFactory() {
+    public Factory<Break> getBreakFactory() {
         return new BreakFactory();
     }
 
-    public CastOperatorFactory getCastOperatorFactory() {
+    public Factory<CastOperator> getCastOperatorFactory() {
         return new CastOperatorFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getResultType(), getExceptionSafe(), getNoConsts());
     }
 
-    public Factory getClassDefinitionBlockFactory() {
+    public Factory<ClassDefinitionBlock> getClassDefinitionBlockFactory() {
         return new ClassDefinitionBlockFactory(getPrefix(),
                 ProductionParams.classesLimit.value(),
                 ProductionParams.memberFunctionsLimit.value(),
@@ -221,7 +270,7 @@
                 getLevel());
     }
 
-    public Factory getMainKlassFactory() {
+    public Factory<MainKlass> getMainKlassFactory() {
         return new MainKlassFactory(getName(), getComplexityLimit(),
                 ProductionParams.memberFunctionsLimit.value(),
                 ProductionParams.memberFunctionsArgLimit.value(),
@@ -230,200 +279,200 @@
                 ProductionParams.operatorLimit.value());
     }
 
-    public ConstructorDefinitionBlockFactory getConstructorDefinitionBlockFactory() {
+    public Factory<ConstructorDefinitionBlock> getConstructorDefinitionBlockFactory() {
         return new ConstructorDefinitionBlockFactory(getOwnerClass(), getMemberFunctionsLimit(),
                 ProductionParams.memberFunctionsArgLimit.value(), getComplexityLimit(),
                 getStatementLimit(), getOperatorLimit(), getLevel());
     }
 
-    public ConstructorDefinitionFactory getConstructorDefinitionFactory() {
+    public Factory<ConstructorDefinition> getConstructorDefinitionFactory() {
         return new ConstructorDefinitionFactory(getOwnerClass(), getComplexityLimit(),
                 getStatementLimit(), getOperatorLimit(),
                 getMemberFunctionsArgLimit(), getLevel());
     }
 
-    public ContinueFactory getContinueFactory() {
+    public Factory<Continue> getContinueFactory() {
         return new ContinueFactory();
     }
 
-    public CounterInitializerFactory getCounterInitializerFactory(int counterValue) {
+    public Factory<CounterInitializer> getCounterInitializerFactory(int counterValue) {
         return new CounterInitializerFactory(getOwnerClass(), counterValue);
     }
 
-    public CounterManipulatorFactory getCounterManipulatorFactory() {
+    public Factory<CounterManipulator> getCounterManipulatorFactory() {
         return new CounterManipulatorFactory(getLocalVariable());
     }
 
-    public DeclarationFactory getDeclarationFactory() {
+    public Factory<Declaration> getDeclarationFactory() {
         return new DeclarationFactory(getOwnerClass(), getComplexityLimit(), getOperatorLimit(),
-            getIsLocal(), getExceptionSafe());
+                getIsLocal(), getExceptionSafe());
     }
 
-    public DoWhileFactory getDoWhileFactory() {
+    public Factory<DoWhile> getDoWhileFactory() {
         return new DoWhileFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
                 getStatementLimit(), getOperatorLimit(), getLevel(), getCanHaveReturn());
     }
 
-    public WhileFactory getWhileFactory() {
+    public Factory<While> getWhileFactory() {
         return new WhileFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
                 getStatementLimit(), getOperatorLimit(), getLevel(), getCanHaveReturn());
     }
 
-    public IfFactory getIfFactory() {
+    public Factory<If> getIfFactory() {
         return new IfFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
-        getStatementLimit(), getOperatorLimit(), getLevel(), getCanHaveBreaks(),
+                getStatementLimit(), getOperatorLimit(), getLevel(), getCanHaveBreaks(),
                 getCanHaveContinues(), getCanHaveReturn());
     }
 
-    public ForFactory getForFactory() {
+    public Factory<For> getForFactory() {
         return new ForFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
                 getStatementLimit(), getOperatorLimit(), getLevel(), getCanHaveReturn());
     }
 
-    public SwitchFactory getSwitchFactory() { // TODO: switch is not used now
+    public Factory<Switch> getSwitchFactory() { // TODO: switch is not used now
         return new SwitchFactory(getOwnerClass(), getComplexityLimit(), getStatementLimit(),
                 getOperatorLimit(), getLevel(), getCanHaveReturn());
     }
 
-    public ExpressionFactory getExpressionFactory() throws ProductionFailedException {
+    public Factory<IRNode> getExpressionFactory() throws ProductionFailedException {
         return new ExpressionFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getResultType(), getExceptionSafe(), getNoConsts());
     }
 
-    public FunctionDeclarationBlockFactory getFunctionDeclarationBlockFactory() {
+    public Factory<FunctionDeclarationBlock> getFunctionDeclarationBlockFactory() {
         return new FunctionDeclarationBlockFactory(getOwnerClass(), getMemberFunctionsLimit(),
                 getMemberFunctionsArgLimit(), getLevel());
     }
 
-    public FunctionDeclarationFactory getFunctionDeclarationFactory() {
-        return new FunctionDeclarationFactory(getName(), getOwnerClass(),resultType.orElse(null),
+    public Factory<FunctionDeclaration> getFunctionDeclarationFactory() {
+        return new FunctionDeclarationFactory(getName(), getOwnerClass(),resultType.orElse(TypeList.VOID),
                 getMemberFunctionsArgLimit(), getFlags());
     }
 
-    public FunctionDefinitionBlockFactory getFunctionDefinitionBlockFactory() {
+    public Factory<FunctionDefinitionBlock> getFunctionDefinitionBlockFactory() {
         return new FunctionDefinitionBlockFactory(getOwnerClass(), getMemberFunctionsLimit(),
                 getMemberFunctionsArgLimit(), getComplexityLimit(), getStatementLimit(),
                 getOperatorLimit(), getLevel(), getFlags());
     }
 
-    public FunctionDefinitionFactory getFunctionDefinitionFactory() {
-        return new FunctionDefinitionFactory(getName(), getOwnerClass(), resultType.orElse(null),
+    public Factory<FunctionDefinition> getFunctionDefinitionFactory() {
+        return new FunctionDefinitionFactory(getName(), getOwnerClass(), resultType.orElse(TypeList.VOID),
                 getComplexityLimit(), getStatementLimit(), getOperatorLimit(),
                 getMemberFunctionsArgLimit(), getLevel(), getFlags());
     }
 
-    public FunctionFactory getFunctionFactory() {
+    public Factory<Function> getFunctionFactory() {
         return new FunctionFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 resultType.orElse(null), getExceptionSafe());
     }
 
-    public FunctionRedefinitionBlockFactory getFunctionRedefinitionBlockFactory(Collection<Symbol>
-            functionSet) {
+    public Factory<FunctionRedefinitionBlock> getFunctionRedefinitionBlockFactory(Collection<Symbol>
+                                                                                        functionSet) {
         return new FunctionRedefinitionBlockFactory(functionSet, getOwnerClass(),
                 getComplexityLimit(), getStatementLimit(), getOperatorLimit(), getLevel());
     }
 
-    public FunctionRedefinitionFactory getFunctionRedefinitionFactory() {
+    public Factory<FunctionRedefinition> getFunctionRedefinitionFactory() {
         return new FunctionRedefinitionFactory(getFunctionInfo(), getOwnerClass(),
                 getComplexityLimit(), getStatementLimit(), getOperatorLimit(), getLevel(),
                 getFlags());
     }
 
-    public InterfaceFactory getInterfaceFactory() {
+    public Factory<Interface> getInterfaceFactory() {
         return new InterfaceFactory(getName(), getMemberFunctionsLimit(),
                 getMemberFunctionsArgLimit(), getLevel());
     }
 
-    public KlassFactory getKlassFactory() {
-        return new KlassFactory(getName(), getPrinterName(), getComplexityLimit(),
+    public Factory<Klass> getKlassFactory() {
+        return new KlassFactory(getName(), getComplexityLimit(),
                 getMemberFunctionsLimit(), getMemberFunctionsArgLimit(), getStatementLimit(),
                 getOperatorLimit(), getLevel());
     }
 
-    public LimitedExpressionFactory getLimitedExpressionFactory() throws ProductionFailedException {
+    public Factory<IRNode> getLimitedExpressionFactory() throws ProductionFailedException {
         return new LimitedExpressionFactory(getComplexityLimit(), getOperatorLimit(),
                 getOwnerClass(), getResultType(), getExceptionSafe(), getNoConsts());
     }
 
-    public LiteralFactory getLiteralFactory() {
+    public Factory<Literal> getLiteralFactory() {
         return new LiteralFactory(getResultType());
     }
 
-    public LocalVariableFactory getLocalVariableFactory() {
+    public Factory<LocalVariable> getLocalVariableFactory() {
         return new LocalVariableFactory(/*getVariableType()*/getResultType(), getFlags());
     }
 
-    public LogicOperatorFactory getLogicOperatorFactory() throws ProductionFailedException {
+    public Factory<Operator> getLogicOperatorFactory() throws ProductionFailedException {
         return new LogicOperatorFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getResultType(), getExceptionSafe(), getNoConsts());
     }
 
-    public LoopingConditionFactory getLoopingConditionFactory(Literal _limiter) {
+    public Factory<LoopingCondition> getLoopingConditionFactory(Literal _limiter) {
         return new LoopingConditionFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getLocalVariable(), _limiter);
     }
 
-    public NonStaticMemberVariableFactory getNonStaticMemberVariableFactory() {
+    public Factory<NonStaticMemberVariable> getNonStaticMemberVariableFactory() {
         return new NonStaticMemberVariableFactory(getComplexityLimit(), getOperatorLimit(),
                 getOwnerClass(), /*getVariableType()*/getResultType(), getFlags(), getExceptionSafe());
     }
 
-    public NothingFactory getNothingFactory() {
+    public Factory<Nothing> getNothingFactory() {
         return new NothingFactory();
     }
 
-    public PrintVariablesFactory getPrintVariablesFactory() {
-        return new PrintVariablesFactory(getPrinterName(), getOwnerClass(), getLevel());
+    public Factory<PrintVariables> getPrintVariablesFactory() {
+        return new PrintVariablesFactory(getOwnerClass(), getLevel());
     }
 
-    public ReturnFactory getReturnFactory() {
+    public Factory<Return> getReturnFactory() {
         return new ReturnFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getResultType(), getExceptionSafe());
     }
 
-    public ThrowFactory getThrowFactory() {
+    public Factory<Throw> getThrowFactory() {
         return new ThrowFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(), getResultType(), getExceptionSafe());
     }
 
-    public StatementFactory getStatementFactory() {
+    public Factory<Statement> getStatementFactory() {
         return new StatementFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getExceptionSafe(), getNoConsts(), semicolon.orElse(true));
     }
 
-    public StaticConstructorDefinitionFactory getStaticConstructorDefinitionFactory() {
+    public Factory<StaticConstructorDefinition> getStaticConstructorDefinitionFactory() {
         return new StaticConstructorDefinitionFactory(getOwnerClass(), getComplexityLimit(),
                 getStatementLimit(), getOperatorLimit(), getLevel());
     }
 
-    public StaticMemberVariableFactory getStaticMemberVariableFactory() {
+    public Factory<StaticMemberVariable> getStaticMemberVariableFactory() {
         return new StaticMemberVariableFactory(getOwnerClass(), /*getVariableType()*/getResultType(), getFlags());
     }
 
-    public TernaryOperatorFactory getTernaryOperatorFactory() {
+    public Factory<TernaryOperator> getTernaryOperatorFactory() {
         return new TernaryOperatorFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 getResultType(), getExceptionSafe(), getNoConsts());
     }
 
-    public VariableDeclarationBlockFactory getVariableDeclarationBlockFactory() {
+    public Factory<VariableDeclarationBlock> getVariableDeclarationBlockFactory() {
         return new VariableDeclarationBlockFactory(getOwnerClass(), getComplexityLimit(),
                 getOperatorLimit(), getLevel(), getExceptionSafe());
     }
 
-    public VariableDeclarationFactory getVariableDeclarationFactory() {
+    public Factory<VariableDeclaration> getVariableDeclarationFactory() {
         return new VariableDeclarationFactory(getOwnerClass(), getIsStatic(), getIsLocal(), getResultType());
     }
 
-    public VariableFactory getVariableFactory() {
+    public Factory<VariableBase> getVariableFactory() {
         return new VariableFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
                 /*getVariableType()*/getResultType(), getIsConstant(), getIsInitialized(), getExceptionSafe(), getNoConsts());
     }
 
-    public VariableInitializationFactory getVariableInitializationFactory() {
-            return new VariableInitializationFactory(getOwnerClass(), getIsConstant(), getIsStatic(),
-                    getIsLocal(), getComplexityLimit(), getOperatorLimit(), getExceptionSafe());
+    public Factory<VariableInitialization> getVariableInitializationFactory() {
+        return new VariableInitializationFactory(getOwnerClass(), getIsConstant(), getIsStatic(),
+                getIsLocal(), getComplexityLimit(), getOperatorLimit(), getExceptionSafe());
     }
 
-    public TryCatchBlockFactory getTryCatchBlockFactory() {
+    public Factory<TryCatchBlock> getTryCatchBlockFactory() {
         return new TryCatchBlockFactory(getOwnerClass(), getResultType(),
                 getComplexityLimit(), getStatementLimit(), getOperatorLimit(),
                 getLevel(), subBlock.orElse(false), getCanHaveBreaks(),
@@ -570,11 +619,6 @@
         return this;
     }
 
-    public IRNodeBuilder setPrinterName(String value) {
-        printerName = Optional.of(value);
-        return this;
-    }
-
     public IRNodeBuilder setSemicolon(boolean value) {
         semicolon = Optional.of(value);
         return this;
@@ -698,9 +742,4 @@
         return functionInfo.orElseThrow(() -> new IllegalArgumentException(
                 "FunctionInfo wasn't set"));
     }
-
-    private String getPrinterName() {
-        return printerName.orElseThrow(() -> new IllegalArgumentException(
-                "printerName wasn't set"));
-    }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/IfFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/IfFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,21 +23,22 @@
 
 package jdk.test.lib.jittester.factories;
 
+import jdk.test.lib.jittester.Block;
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.If;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeBoolean;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class IfFactory extends SafeFactory {
-    protected long complexityLimit;
-    protected int statementLimit;
-    protected int operatorLimit;
-    protected boolean canHaveBreaks;
-    protected boolean canHaveContinues;
-    protected boolean canHaveReturn;
+class IfFactory extends SafeFactory<If> {
+    protected final long complexityLimit;
+    protected final int statementLimit;
+    protected final int operatorLimit;
+    protected final boolean canHaveBreaks;
+    protected final boolean canHaveContinues;
+    protected final boolean canHaveReturn;
     protected final TypeKlass ownerClass;
     protected final Type returnType;
     protected final int level;
@@ -57,7 +58,7 @@
     }
 
     @Override
-    public IRNode sproduce() throws ProductionFailedException {
+    public If sproduce() throws ProductionFailedException {
         // resizeUpChildren(If.IfPart.values().length);
         if (statementLimit > 0 && complexityLimit > 0) {
             long conditionComplLimit = (long) (0.01 * PseudoRandom.random() * (complexityLimit - 1));
@@ -65,7 +66,7 @@
                     .setOwnerKlass(ownerClass)
                     .setOperatorLimit(operatorLimit);
             IRNode condition = builder.setComplexityLimit(conditionComplLimit)
-                    .setResultType(new TypeBoolean())
+                    .setResultType(TypeList.BOOLEAN)
                     .setExceptionSafe(false)
                     .setNoConsts(false)
                     .getLimitedExpressionFactory()
@@ -83,7 +84,7 @@
                 controlDeviation = PseudoRandom.randomBoolean() ? If.IfPart.THEN : If.IfPart.ELSE;
             }
             if (ifBlockLimit > 0 && ifBlockComplLimit > 0) {
-                IRNode thenBlock = null;
+                Block thenBlock;
                 builder.setResultType(returnType)
                         .setLevel(level)
                         .setComplexityLimit(ifBlockComplLimit)
@@ -104,7 +105,7 @@
                             .produce();
                 }
                 // setChild(If.IfPart.THEN.ordinal(), thenBlock);
-                IRNode elseBlock = null;
+                Block elseBlock = null;
                 if (elseBlockLimit > 0 && elseBlockComplLimit > 0) {
                     builder.setComplexityLimit(elseBlockComplLimit)
                             .setStatementLimit(elseBlockLimit);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/IncDecOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/IncDecOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,14 +23,12 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.UnaryOperator;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeBoolean;
 
 class IncDecOperatorFactory extends UnaryOperatorFactory {
     IncDecOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
@@ -40,11 +38,11 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return TypeList.isBuiltInInt(resultType) && !resultType.equals(new TypeBoolean());
+        return TypeList.isBuiltInInt(resultType) && !resultType.equals(TypeList.BOOLEAN);
     }
 
     @Override
-    protected IRNode generateProduction(Type l) throws ProductionFailedException {
+    protected UnaryOperator generateProduction(Type l) throws ProductionFailedException {
         return new UnaryOperator(opKind, new IRNodeBuilder().setComplexityLimit(complexityLimit - 1)
                 .setOperatorLimit(operatorLimit - 1)
                 .setOwnerKlass((TypeKlass) ownerClass)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/InterfaceFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/InterfaceFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -37,7 +37,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class InterfaceFactory extends Factory {
+class InterfaceFactory extends Factory<Interface> {
     private final String name;
     private final int memberFunctionsLimit;
     private final int memberFunctionsArgLimit;
@@ -52,7 +52,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Interface produce() throws ProductionFailedException {
         TypeKlass thisKlass;
         // Do we want to inherit something?
         if (!ProductionParams.disableInheritance.value()) {
@@ -76,7 +76,7 @@
             parent.addChild(name);
             for (Symbol symbol : SymbolTable.getAllCombined(parent, FunctionInfo.class)) {
                 FunctionInfo functionInfo = (FunctionInfo) symbol.deepCopy();
-                functionInfo.klass = thisKlass;
+                functionInfo.owner = thisKlass;
                 functionInfo.argTypes.get(0).type = thisKlass;
                 SymbolTable.add(functionInfo);
             }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/KlassFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/KlassFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -42,9 +42,8 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class KlassFactory extends Factory {
+class KlassFactory extends Factory<Klass> {
     private final String name;
-    private final String printerName;
     private final long complexityLimit;
     private final int statementsInFunctionLimit;
     private final int operatorLimit;
@@ -55,11 +54,10 @@
     private TypeKlass parent;
     private int memberFunctionsLimit;
 
-    KlassFactory(String name, String printerName, long complexityLimit,
+    KlassFactory(String name, long complexityLimit,
             int memberFunctionsLimit, int memberFunctionsArgLimit, int statementsInFunctionLimit,
             int operatorLimit, int level) {
         this.name = name;
-        this.printerName = printerName;
         this.complexityLimit = complexityLimit;
         this.memberFunctionsLimit = memberFunctionsLimit;
         this.memberFunctionsArgLimit = memberFunctionsArgLimit;
@@ -70,7 +68,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Klass produce() throws ProductionFailedException {
         HashSet<Symbol> abstractSet = new HashSet<>();
         HashSet<Symbol> overrideSet = new HashSet<>();
         thisKlass = new TypeKlass(name);
@@ -135,15 +133,11 @@
                 SymbolTable.remove(symbol);
             }
         } else {
-            parent = (TypeKlass) TypeList.find("java.lang.Object");
+            parent = TypeList.OBJECT;
             thisKlass.addParent(parent.getName());
             thisKlass.setParent(parent);
             parent.addChild(name);
         }
-        // Just don't print it. It's assumed that we at least are inherited from Object.
-        if (parent.getName().equals("java.lang.Object")) {
-            parent = null;
-        }
         SymbolTable.add(new VariableInfo("this", thisKlass, thisKlass,
                 VariableInfo.FINAL | VariableInfo.LOCAL | VariableInfo.INITIALIZED));
         IRNode variableDeclarations = null;
@@ -152,8 +146,7 @@
         IRNode functionDeclarations = null;
         IRNode abstractFunctionsRedefinitions = null;
         IRNode overridenFunctionsRedefinitions = null;
-        IRNodeBuilder builder = new IRNodeBuilder().setPrinterName(printerName)
-                .setOwnerKlass(thisKlass)
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(thisKlass)
                 .setExceptionSafe(true);
         try {
             builder.setLevel(level + 1)
@@ -227,7 +220,7 @@
             }
         }
         if (probableParents.isEmpty()) {
-            parent = (TypeKlass) TypeList.find("java.lang.Object");
+            parent = TypeList.OBJECT;
         } else {
             parent = (TypeKlass) PseudoRandom.randomElement(probableParents);
         }
@@ -246,7 +239,7 @@
                         functionInfo.argTypes.get(0).type = thisKlass;
                     }
                 }
-                symbolCopy.klass = thisKlass;
+                symbolCopy.owner = thisKlass;
                 SymbolTable.add(symbolCopy);
             }
         }
@@ -276,10 +269,9 @@
             interfaces.add(iface);
             iface.addChild(name);
             thisKlass.addParent(iface.getName());
-            thisKlass.setParent(iface);
             for (Symbol symbol : SymbolTable.getAllCombined(iface, FunctionInfo.class)) {
                 FunctionInfo functionInfo = (FunctionInfo) symbol.deepCopy();
-                functionInfo.klass = thisKlass;
+                functionInfo.owner = thisKlass;
                 functionInfo.argTypes.get(0).type = thisKlass;
                 SymbolTable.add(functionInfo);
             }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LiteralFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LiteralFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,23 +23,16 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.Literal;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.ProductionParams;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
-import jdk.test.lib.jittester.types.TypeBoolean;
-import jdk.test.lib.jittester.types.TypeByte;
-import jdk.test.lib.jittester.types.TypeChar;
-import jdk.test.lib.jittester.types.TypeDouble;
-import jdk.test.lib.jittester.types.TypeFloat;
-import jdk.test.lib.jittester.types.TypeInt;
-import jdk.test.lib.jittester.types.TypeLong;
-import jdk.test.lib.jittester.types.TypeShort;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class LiteralFactory extends Factory {
+import java.util.Locale;
+
+class LiteralFactory extends Factory<Literal> {
     protected final Type resultType;
 
     LiteralFactory(Type resultType) {
@@ -47,31 +40,39 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Literal produce() throws ProductionFailedException {
         Literal literal;
-        if (resultType.equals(new TypeBoolean())) {
-            literal = new Literal(PseudoRandom.randomBoolean(), new TypeBoolean());
-        } else if (resultType.equals(new TypeChar())) {
-            literal = new Literal((char) ((char) (PseudoRandom.random() * ('z' - 'A')) + 'A'), new TypeChar());
-        } else if (resultType.equals(new TypeInt())) {
-            literal = new Literal((int) (PseudoRandom.random() * Integer.MAX_VALUE), new TypeInt());
-        } else if (resultType.equals(new TypeLong())) {
-            literal = new Literal((long) (PseudoRandom.random() * Long.MAX_VALUE), new TypeLong());
-        } else if (resultType.equals(new TypeFloat())) {
-            literal = new Literal((float) (PseudoRandom.random() * Float.MAX_VALUE), new TypeFloat());
-        } else if (resultType.equals(new TypeDouble())) {
-            literal = new Literal(PseudoRandom.random() * Double.MAX_VALUE, new TypeDouble());
-        } else if (resultType.equals(new TypeByte())) {
-            literal = new Literal((byte)(PseudoRandom.random() * Byte.MAX_VALUE),new TypeByte());
-        } else if (resultType.equals(new TypeShort())) {
-            literal = new Literal((short)(PseudoRandom.random() * Short.MAX_VALUE), new TypeShort());
-        } else if (resultType.equals(TypeList.find("java.lang.String"))) {
+        if (resultType.equals(TypeList.BOOLEAN)) {
+            literal = new Literal(PseudoRandom.randomBoolean(), TypeList.BOOLEAN);
+        } else if (resultType.equals(TypeList.CHAR)) {
+            literal = new Literal((char) ((char) (PseudoRandom.random() * ('z' - 'A')) + 'A'), TypeList.CHAR);
+        } else if (resultType.equals(TypeList.INT)) {
+            literal = new Literal((int) (PseudoRandom.random() * Integer.MAX_VALUE), TypeList.INT);
+        } else if (resultType.equals(TypeList.LONG)) {
+            literal = new Literal((long) (PseudoRandom.random() * Long.MAX_VALUE), TypeList.LONG);
+        } else if (resultType.equals(TypeList.FLOAT)) {
+            literal = new Literal(new Float(String.format(
+                    (Locale) null,
+                    "%." + ProductionParams.floatingPointPrecision.value() + "EF",
+                    (float) PseudoRandom.random() * Float.MAX_VALUE)),
+                    TypeList.FLOAT);
+        } else if (resultType.equals(TypeList.DOUBLE)) {
+            literal = new Literal(new Double(String.format(
+                    (Locale) null,
+                    "%." + 2 * ProductionParams.floatingPointPrecision.value() + "E",
+                    PseudoRandom.random() * Double.MAX_VALUE)),
+                    TypeList.DOUBLE);
+        } else if (resultType.equals(TypeList.BYTE)) {
+            literal = new Literal((byte)(PseudoRandom.random() * Byte.MAX_VALUE), TypeList.BYTE);
+        } else if (resultType.equals(TypeList.SHORT)) {
+            literal = new Literal((short)(PseudoRandom.random() * Short.MAX_VALUE), TypeList.SHORT);
+        } else if (resultType.equals(TypeList.STRING)) {
             int size = (int) (PseudoRandom.random() * ProductionParams.stringLiteralSizeLimit.value());
             byte[] str = new byte[size];
             for (int i = 0; i < size; i++) {
                 str[i] = (byte) ((int) (('z' - 'a') * PseudoRandom.random()) + 'a');
             }
-            literal = new Literal("\"" + new String(str) + "\"", TypeList.find("java.lang.String"));
+            literal = new Literal(new String(str), TypeList.STRING);
         } else {
             throw new ProductionFailedException();
         }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LocalVariableFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LocalVariableFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -24,7 +24,7 @@
 package jdk.test.lib.jittester.factories;
 
 import java.util.ArrayList;
-import jdk.test.lib.jittester.IRNode;
+
 import jdk.test.lib.jittester.LocalVariable;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Symbol;
@@ -33,7 +33,7 @@
 import jdk.test.lib.jittester.VariableInfo;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class LocalVariableFactory extends Factory {
+class LocalVariableFactory extends Factory<LocalVariable> {
     private final Type type;
     private final int flags;
 
@@ -43,7 +43,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public LocalVariable produce() throws ProductionFailedException {
         // Get the variables of the requested type from SymbolTable
         ArrayList<Symbol> allVariables = new ArrayList<>(SymbolTable.get(type, VariableInfo.class));
         if (!allVariables.isEmpty()) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LogicOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LogicOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,15 +23,15 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Operator;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Rule;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class LogicOperatorFactory extends Factory {
-    private final Rule rule;
+class LogicOperatorFactory extends Factory<Operator> {
+    private final Rule<Operator> rule;
 
     LogicOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass, Type resultType,
             boolean exceptionSafe, boolean noconsts) throws ProductionFailedException {
@@ -42,7 +42,7 @@
                 .setResultType(resultType)
                 .setExceptionSafe(exceptionSafe)
                 .setNoConsts(noconsts);
-        rule = new Rule("arithmetic");
+        rule = new Rule<>("arithmetic");
         rule.add("land", builder.setOperatorKind(OperatorKind.AND).getBinaryOperatorFactory());
         rule.add("lor", builder.setOperatorKind(OperatorKind.OR).getBinaryOperatorFactory());
         rule.add("greater", builder.setOperatorKind(OperatorKind.GT).getBinaryOperatorFactory());
@@ -55,7 +55,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Operator produce() throws ProductionFailedException {
         return rule.produce();
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LogicalInversionOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LogicalInversionOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,12 +23,11 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.UnaryOperator;
-import jdk.test.lib.jittester.types.TypeBoolean;
 import jdk.test.lib.jittester.types.TypeKlass;
 
 class LogicalInversionOperatorFactory extends UnaryOperatorFactory {
@@ -39,11 +38,11 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        return resultType.equals(new TypeBoolean());
+        return resultType.equals(TypeList.BOOLEAN);
     }
 
     @Override
-    protected IRNode generateProduction(Type resultType) throws ProductionFailedException {
+    protected UnaryOperator generateProduction(Type resultType) throws ProductionFailedException {
         return new UnaryOperator(opKind, new ExpressionFactory(complexityLimit - 1,
                 operatorLimit - 1, (TypeKlass) ownerClass, resultType, exceptionSafe, noconsts).produce());
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LoopingConditionFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LoopingConditionFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -29,12 +29,12 @@
 import jdk.test.lib.jittester.LocalVariable;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.loops.LoopingCondition;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeBoolean;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class LoopingConditionFactory extends Factory {
+class LoopingConditionFactory extends Factory<LoopingCondition> {
     private final LocalVariable counter;
     private final Literal limiter;
     private final int operatorLimit;
@@ -51,11 +51,11 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public LoopingCondition produce() throws ProductionFailedException {
         IRNode leftExpression = null;
         IRNode rightExpression = null;
-        LimitedExpressionFactory exprFactory = new IRNodeBuilder()
-                .setResultType(new TypeBoolean())
+        Factory<IRNode> exprFactory = new IRNodeBuilder()
+                .setResultType(TypeList.BOOLEAN)
                 .setComplexityLimit((complexityLimit - 1) / 2)
                 .setOperatorLimit((operatorLimit - 1) / 2)
                 .setOwnerKlass(ownerClass)
@@ -75,10 +75,10 @@
         // Just as a temporary solution we'll assume that the counter is monotonically increasing.
         // And use counter < n condition to limit the loop.
         // In future we may introduce other equivalent relations as well.
-        IRNode condition = new BinaryOperator(OperatorKind.LT, counter, limiter);
-        condition = (rightExpression != null) ? new BinaryOperator(OperatorKind.AND, condition,
+        BinaryOperator condition = new BinaryOperator(OperatorKind.LT, TypeList.BOOLEAN, counter, limiter);
+        condition = (rightExpression != null) ? new BinaryOperator(OperatorKind.AND, TypeList.BOOLEAN, condition,
                 rightExpression) : condition;
-        condition = (leftExpression != null) ? new BinaryOperator(OperatorKind.AND, leftExpression,
+        condition = (leftExpression != null) ? new BinaryOperator(OperatorKind.AND, TypeList.BOOLEAN, leftExpression,
                 condition) : condition;
         return new LoopingCondition(condition);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/MainKlassFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/MainKlassFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -38,10 +38,9 @@
 import jdk.test.lib.jittester.classes.MainKlass;
 import jdk.test.lib.jittester.functions.FunctionInfo;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeVoid;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class MainKlassFactory extends Factory {
+class MainKlassFactory extends Factory<MainKlass> {
     private final String name;
     private final long complexityLimit;
     private final int statementsInTestFunctionLimit;
@@ -64,8 +63,8 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
-        TypeKlass parent = (TypeKlass) TypeList.find("java.lang.Object");
+    public MainKlass produce() throws ProductionFailedException {
+        TypeKlass parent = TypeList.OBJECT;
         thisKlass = new TypeKlass(name);
         thisKlass.addParent(parent.getName());
         thisKlass.setParent(parent);
@@ -80,8 +79,7 @@
                 .setMemberFunctionsArgLimit(memberFunctionsArgLimit)
                 .setStatementLimit(statementsInFunctionLimit)
                 .setLevel(1)
-                .setExceptionSafe(true)
-                .setPrinterName("Printer");
+                .setExceptionSafe(true);
         IRNode variableDeclarations = builder
                 .setComplexityLimit((long) (complexityLimit * 0.05))
                 .getVariableDeclarationBlockFactory().produce();
@@ -93,7 +91,7 @@
                     .getFunctionDefinitionBlockFactory()
                     .produce();
         }
-        IRNode testFunction = builder.setResultType(new TypeVoid())
+        IRNode testFunction = builder.setResultType(TypeList.VOID)
                 .setComplexityLimit(complexityLimit)
                 .setStatementLimit(statementsInTestFunctionLimit)
                 .getBlockFactory()
@@ -109,6 +107,7 @@
         childs.add(printVariables);
         ensureMinDepth(childs, builder);
         ensureMaxDepth(childs);
+        TypeList.add(thisKlass);
         return new MainKlass(name, thisKlass, variableDeclarations,
                 functionDefinitions, testFunction, printVariables);
     }
@@ -119,7 +118,7 @@
             .filter(c -> c.isCFDeviation() && c.countDepth() > maxDepth)
             .collect(Collectors.toList());
         for (IRNode child : filtered) {
-            List<IRNode> leaves = null;
+            List<IRNode> leaves;
             do {
                 long depth = Math.max(child.countDepth(), maxDepth + 1);
                 leaves = child.getDeviantBlocks(depth);
@@ -138,16 +137,14 @@
     private void addMoreChildren(List<IRNode> childs, int minDepth, IRNodeBuilder builder)
             throws ProductionFailedException {
         while (!childs.isEmpty() && IRNode.countDepth(childs) < minDepth) {
-            PseudoRandom.shuffle(childs);
-            IRNode randomChild = childs.get(0);
+            IRNode randomChild = childs.get(PseudoRandom.randomNotNegative(childs.size()));
             List<IRNode> leaves = randomChild.getStackableLeaves();
             if (!leaves.isEmpty()) {
-                PseudoRandom.shuffle(leaves);
-                Block randomLeaf = (Block) leaves.get(0);
-                TypeKlass klass = (TypeKlass) randomChild.getKlass();
+                Block randomLeaf = (Block) leaves.get(PseudoRandom.randomNotNegative(leaves.size()));
+                TypeKlass owner = randomChild.getOwner();
                 int newLevel = randomLeaf.getLevel() + 1;
-                Type retType = randomLeaf.getReturnType();
-                IRNode newBlock = builder.setOwnerKlass(klass)
+                Type retType = randomLeaf.getResultType();
+                IRNode newBlock = builder.setOwnerKlass(owner)
                         .setResultType(retType)
                         .setComplexityLimit(complexityLimit)
                         .setStatementLimit(statementsInFunctionLimit)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/NonStaticMemberVariableFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/NonStaticMemberVariableFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -34,7 +34,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class NonStaticMemberVariableFactory extends Factory {
+class NonStaticMemberVariableFactory extends Factory<NonStaticMemberVariable> {
     private final Type type;
     private final int flags;
     private final long complexityLimit;
@@ -53,7 +53,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public NonStaticMemberVariable produce() throws ProductionFailedException {
         // Get the variables of the requested type from SymbolTable
         ArrayList<Symbol> variables = new ArrayList<>(SymbolTable.get(type, VariableInfo.class));
         if (!variables.isEmpty()) {
@@ -70,7 +70,7 @@
                         && (varInfo.flags & VariableInfo.STATIC) == 0
                         && (varInfo.flags & VariableInfo.LOCAL) == 0) {
                     try {
-                        IRNode object = builder.setResultType(varInfo.klass)
+                        IRNode object = builder.setResultType(varInfo.owner)
                                 .getExpressionFactory().produce();
                         return new NonStaticMemberVariable(object, varInfo);
                     } catch (ProductionFailedException e) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/NothingFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/NothingFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -26,7 +26,7 @@
 import jdk.test.lib.jittester.Nothing;
 import jdk.test.lib.jittester.ProductionFailedException;
 
-public class NothingFactory extends Factory {
+public class NothingFactory extends Factory<Nothing> {
     @Override
     public Nothing produce() throws ProductionFailedException {
         return new Nothing();
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/OperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/OperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,12 +23,14 @@
 
 package jdk.test.lib.jittester.factories;
 
-public abstract class OperatorFactory extends Factory {
-    protected long complexityLimit;
-    protected boolean exceptionSafe;
-    protected boolean noconsts;
+import jdk.test.lib.jittester.Operator;
+
+public abstract class OperatorFactory<T extends Operator> extends Factory<T> {
+    protected final long complexityLimit;
+    protected final boolean exceptionSafe;
+    protected final boolean noconsts;
+    protected final int operatorPriority;
     protected int operatorLimit;
-    protected int operatorPriority;
 
     protected OperatorFactory(int operatorPriority, long complexityLimit, int operatorLimit,
             boolean exceptionSafe, boolean noconsts) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/PrintVariablesFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/PrintVariablesFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,27 +23,21 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.PrintVariables;
 import jdk.test.lib.jittester.ProductionFailedException;
-import jdk.test.lib.jittester.SymbolTable;
-import jdk.test.lib.jittester.VariableInfo;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class PrintVariablesFactory extends Factory {
-    private final String printerName;
+class PrintVariablesFactory extends Factory<PrintVariables> {
     private final TypeKlass ownerClass;
     private final int level;
 
-    PrintVariablesFactory(String printerName, TypeKlass ownerClass, int level) {
-        this.printerName = printerName;
+    PrintVariablesFactory(TypeKlass ownerClass, int level) {
         this.ownerClass = ownerClass;
         this.level = level;
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
-        return new PrintVariables(printerName, SymbolTable.getAllCombined(ownerClass,
-                VariableInfo.class), level);
+    public PrintVariables produce() throws ProductionFailedException {
+        return new PrintVariables(ownerClass, level);
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ReturnFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ReturnFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,13 +23,12 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.functions.Return;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class ReturnFactory extends SafeFactory {
+class ReturnFactory extends SafeFactory<Return> {
     private final long complexityLimit;
     private final int operatorLimit;
     private final Type resultType;
@@ -46,7 +45,7 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected Return sproduce() throws ProductionFailedException {
         return new Return(new IRNodeBuilder().setComplexityLimit(complexityLimit - 1)
                 .setOperatorLimit(operatorLimit - 1)
                 .setOwnerKlass(ownerClass)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/SafeFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/SafeFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -27,14 +27,14 @@
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
 
-public abstract class SafeFactory extends Factory {
-    protected abstract IRNode sproduce() throws ProductionFailedException;
+public abstract class SafeFactory<T extends IRNode> extends Factory<T> {
+    protected abstract T sproduce() throws ProductionFailedException;
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public T produce() throws ProductionFailedException {
         try {
             SymbolTable.push();
-            IRNode p = sproduce();
+            T p = sproduce();
             SymbolTable.merge();
             return p;
         } catch (ProductionFailedException e) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StatementFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StatementFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -32,15 +32,15 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class StatementFactory extends Factory {
-    private final Rule rule;
+class StatementFactory extends Factory<Statement> {
+    private final Rule<IRNode> rule;
     private final boolean needSemicolon;
 
     StatementFactory(long complexityLimit, int operatorLimit,
             TypeKlass ownerClass, boolean exceptionSafe,
             boolean noconsts, boolean needSemicolon ){
         this.needSemicolon = needSemicolon;
-        rule = new Rule("statement");
+        rule = new Rule<>("statement");
         IRNodeBuilder builder = new IRNodeBuilder()
                 .setComplexityLimit(complexityLimit)
                 .setOperatorLimit(operatorLimit)
@@ -54,7 +54,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public Statement produce() throws ProductionFailedException {
         ProductionLimiter.setLimit();
         try {
             return new Statement(rule.produce(), needSemicolon);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticConstructorDefinitionFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticConstructorDefinitionFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -26,13 +26,13 @@
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.VariableInfo;
 import jdk.test.lib.jittester.functions.StaticConstructorDefinition;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeVoid;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class StaticConstructorDefinitionFactory extends Factory {
+class StaticConstructorDefinitionFactory extends Factory<StaticConstructorDefinition> {
     private final long complexityLimit;
     private final int statementLimit;
     private final int operatorLimit;
@@ -49,7 +49,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public StaticConstructorDefinition produce() throws ProductionFailedException {
         SymbolTable.push();
         IRNode body;
         try {
@@ -57,7 +57,7 @@
             long complLimit = (long) (PseudoRandom.random() * complexityLimit);
             body = new IRNodeBuilder()
                     .setOwnerKlass(ownerClass)
-                    .setResultType(new TypeVoid())
+                    .setResultType(TypeList.VOID)
                     .setComplexityLimit(complLimit)
                     .setStatementLimit(statementLimit)
                     .setOperatorLimit(operatorLimit)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticMemberVariableFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticMemberVariableFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -24,7 +24,7 @@
 package jdk.test.lib.jittester.factories;
 
 import java.util.ArrayList;
-import jdk.test.lib.jittester.IRNode;
+
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.StaticMemberVariable;
 import jdk.test.lib.jittester.Symbol;
@@ -34,7 +34,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class StaticMemberVariableFactory extends Factory {
+class StaticMemberVariableFactory extends Factory<StaticMemberVariable> {
     private final Type type;
     private final int flags;
     private final Type ownerClass;
@@ -46,7 +46,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public StaticMemberVariable produce() throws ProductionFailedException {
         // Get the variables of the requested type from SymbolTable
         ArrayList<Symbol> variables = new ArrayList<>(SymbolTable.get(type, VariableInfo.class));
         if (!variables.isEmpty()) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/SwitchFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/SwitchFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -26,6 +26,7 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+
 import jdk.test.lib.jittester.BuiltInType;
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.Literal;
@@ -34,21 +35,18 @@
 import jdk.test.lib.jittester.Rule;
 import jdk.test.lib.jittester.Switch;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.utils.TypeUtil;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeByte;
-import jdk.test.lib.jittester.types.TypeChar;
-import jdk.test.lib.jittester.types.TypeInt;
-import jdk.test.lib.jittester.types.TypeShort;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class SwitchFactory extends SafeFactory {
-    private int caseBlockIdx;
-    protected long complexityLimit;
-    protected int statementLimit, operatorLimit;
-    private boolean canHaveReturn = false;
+class SwitchFactory extends SafeFactory<Switch> {
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final boolean canHaveReturn;
     private final TypeKlass ownerClass;
     private final int level;
+    private final long complexityLimit;
 
     SwitchFactory(TypeKlass ownerClass, long complexityLimit, int statementLimit,
             int operatorLimit, int level, boolean canHaveReturn) {
@@ -61,13 +59,13 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected Switch sproduce() throws ProductionFailedException {
         if (statementLimit > 0 && complexityLimit > 0) {
             List<Type> switchTypes = new ArrayList<>();
-            switchTypes.add(new TypeChar());
-            switchTypes.add(new TypeByte());
-            switchTypes.add(new TypeShort());
-            switchTypes.add(new TypeInt());
+            switchTypes.add(TypeList.CHAR);
+            switchTypes.add(TypeList.BYTE);
+            switchTypes.add(TypeList.SHORT);
+            switchTypes.add(TypeList.INT);
             PseudoRandom.shuffle(switchTypes);
             IRNodeBuilder builder = new IRNodeBuilder()
                     .setOwnerKlass(ownerClass)
@@ -95,8 +93,8 @@
                             .produce();
                     accumulatedComplexity += currentComplexityLimit;
                     List<Type> caseTypes = new ArrayList<>();
-                    caseTypes.add(new TypeByte());
-                    caseTypes.add(new TypeChar());
+                    caseTypes.add(TypeList.BYTE);
+                    caseTypes.add(TypeList.CHAR);
                     caseTypes = new ArrayList<>(TypeUtil.getLessCapaciousOrEqualThan(caseTypes,
                             (BuiltInType) type));
                     if (PseudoRandom.randomBoolean()) { // "default"
@@ -104,7 +102,7 @@
                                 * (statementLimit - accumulatedStatements));
                         currentComplexityLimit = (long) (PseudoRandom.random()
                                 * (complexityLimit - accumulatedComplexity));
-                        caseConsts.add(null);
+                        caseConsts.add(new Nothing());
                         caseBlocks.add(builder.setComplexityLimit(currentComplexityLimit)
                                 .setStatementLimit(currentStatementsLimit)
                                 .setLevel(level + 1)
@@ -128,7 +126,7 @@
                             if (tryCount >= 10) {
                                 continue MAIN_LOOP;
                             }
-                            Literal literal = (Literal) builder.setResultType(caseTypes.get(0))
+                            Literal literal = builder.setResultType(caseTypes.get(0))
                                     .getLiteralFactory().produce();
                             int value = 0;
                             if (literal.value instanceof Integer) {
@@ -149,7 +147,7 @@
                                 break;
                             }
                         }
-                        Rule rule = new Rule("case_block");
+                        Rule<IRNode> rule = new Rule<>("case_block");
                         rule.add("block", builder.setComplexityLimit(currentComplexityLimit)
                                 .setStatementLimit(currentStatementsLimit)
                                 .setLevel(level)
@@ -170,7 +168,7 @@
                     }
                     PseudoRandom.shuffle(caseConsts);
                     List<IRNode> accum = new ArrayList<>();
-                    caseBlockIdx = 1 + caseConsts.size();
+                    int caseBlockIdx = 1 + caseConsts.size();
                     accum.add(switchExp);
                     for (int i = 1; i < caseBlockIdx; ++i) {
                         accum.add(caseConsts.get(i - 1));
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/TernaryOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/TernaryOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,21 +23,18 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.Pair;
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
 import jdk.test.lib.jittester.TernaryOperator;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
-import jdk.test.lib.jittester.utils.TypeUtil;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeBoolean;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class TernaryOperatorFactory extends OperatorFactory {
-    protected final Type resultType;
-    protected final TypeKlass ownerClass;
+class TernaryOperatorFactory extends OperatorFactory<TernaryOperator> {
+    private final Type resultType;
+    private final TypeKlass ownerClass;
 
     TernaryOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
             Type resultType, boolean exceptionSafe, boolean noconsts) {
@@ -46,15 +43,7 @@
         this.ownerClass = ownerClass;
     }
 
-    private Pair<Type, Type> generateTypes() {
-        Pair<Type, Type> types = new Pair<>(resultType, PseudoRandom.randomElement(
-                TypeUtil.getImplicitlyCastable(TypeList.getAll(), resultType)));
-        if (PseudoRandom.randomBoolean())
-            types = new Pair<>(types.second, types.first);
-        return types;
-    }
-
-    private IRNode generateProduction(Type conditionType, Type leftType, Type rightType) throws ProductionFailedException {
+    private TernaryOperator generateProduction() throws ProductionFailedException {
         int leftOpLimit = (int) (PseudoRandom.random() * 0.3 * (operatorLimit - 1));
         int rightOpLimit = (int) (PseudoRandom.random() * 0.3 * (operatorLimit - 1));
         int condOpLimit = operatorLimit - 1 - leftOpLimit - rightOpLimit;
@@ -69,7 +58,7 @@
                 .setExceptionSafe(exceptionSafe);
         IRNode conditionalExp = builder.setComplexityLimit(condComplLimit)
                 .setOperatorLimit(condOpLimit)
-                .setResultType(conditionType)
+                .setResultType(TypeList.BOOLEAN)
                 .setNoConsts(noconsts)
                 .getExpressionFactory()
                 .produce();
@@ -79,7 +68,7 @@
         try {
             leftExp = builder.setComplexityLimit(leftComplLimit)
                     .setOperatorLimit(leftOpLimit)
-                    .setResultType(leftType)
+                    .setResultType(resultType)
                     .setNoConsts(false)
                     .getExpressionFactory()
                     .produce();
@@ -91,7 +80,7 @@
         try {
             rightExp = builder.setComplexityLimit(rightComplLimit)
                     .setOperatorLimit(rightOpLimit)
-                    .setResultType(rightType)
+                    .setResultType(resultType)
                     .setNoConsts(false)
                     .getExpressionFactory()
                     .produce();
@@ -102,16 +91,10 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
-        Pair<Type, Type> types;
-        try {
-            types = generateTypes();
-        } catch (RuntimeException ex) {
-            throw new ProductionFailedException(ex.getMessage());
-        }
+    public TernaryOperator produce() throws ProductionFailedException {
         try {
             SymbolTable.push();
-            IRNode result = generateProduction(new TypeBoolean(), types.first, types.second);
+            TernaryOperator result = generateProduction();
             SymbolTable.merge();
             return result;
         } catch (ProductionFailedException e) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ThrowFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ThrowFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -30,8 +30,8 @@
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class ThrowFactory extends SafeFactory {
-    private final Rule rule;
+class ThrowFactory extends SafeFactory<Throw> {
+    private final Rule<IRNode> rule;
 
     ThrowFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
             Type resultType, boolean exceptionSafe) {
@@ -42,7 +42,7 @@
                 .setResultType(resultType)
                 .setExceptionSafe(exceptionSafe)
                 .setNoConsts(false);
-        rule = new Rule("throw");
+        rule = new Rule<>("throw");
         rule.add("constant", b.setIsConstant(true).setIsInitialized(true).getVariableFactory());
         rule.add("variable", b.setIsConstant(false).setIsInitialized(true).getVariableFactory());
 
@@ -51,7 +51,7 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected Throw sproduce() throws ProductionFailedException {
         return new Throw(rule.produce());
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/TryCatchBlockFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/TryCatchBlockFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -25,8 +25,9 @@
 
 import java.util.ArrayList;
 import java.util.List;
+
+import jdk.test.lib.jittester.Block;
 import jdk.test.lib.jittester.CatchBlock;
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.TryCatchBlock;
 import jdk.test.lib.jittester.Type;
@@ -35,7 +36,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class TryCatchBlockFactory extends Factory {
+class TryCatchBlockFactory extends Factory<TryCatchBlock> {
     private final static double CATCH_SELECTION_COEF = 0.1d;
     private final Type returnType;
     private final long complexityLimit;
@@ -64,7 +65,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public TryCatchBlock produce() throws ProductionFailedException {
         if (complexityLimit < 1 || statementLimit < 1) {
             throw new ProductionFailedException();
         }
@@ -77,7 +78,7 @@
                 .setCanHaveReturn(canHaveReturn)
                 .setCanHaveContinues(canHaveContinues)
                 .setCanHaveBreaks(canHaveBreaks);
-        IRNode body = getBlock(builder, 0.6);
+        Block body = getBlock(builder, 0.6);
         int catchBlocksCount = (int) (CATCH_SELECTION_COEF
                 * PseudoRandom.random() * uncheckedThrowables.size());
         List<CatchBlock> catchBlocks = new ArrayList<>();
@@ -92,7 +93,7 @@
             catchBlocks.add(new CatchBlock(getBlock(builder, 0.3/catchBlocksCount),
                     whatToCatch, level));
         }
-        IRNode finallyBody = PseudoRandom.randomBoolean() || catchBlocksCount == 0 ? getBlock(builder, 0.1) : null;
+        Block finallyBody = PseudoRandom.randomBoolean() || catchBlocksCount == 0 ? getBlock(builder, 0.1) : null;
         return new TryCatchBlock(body, finallyBody, catchBlocks, level);
     }
 
@@ -106,7 +107,7 @@
         return selected;
     }
 
-    private IRNode getBlock(IRNodeBuilder builder, double weight)
+    private Block getBlock(IRNodeBuilder builder, double weight)
             throws ProductionFailedException {
         long actualComplexityLim = (long) (weight * PseudoRandom.random()
                 * complexityLimit);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/UnaryOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/UnaryOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,13 +23,13 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.UnaryOperator;
 
-public abstract class UnaryOperatorFactory extends OperatorFactory {
+public abstract class UnaryOperatorFactory extends OperatorFactory<UnaryOperator> {
     protected final OperatorKind opKind;
     protected final Type resultType;
     protected final Type ownerClass;
@@ -42,16 +42,16 @@
         this.ownerClass = ownerClass;
     }
 
-    protected Type generateType() throws ProductionFailedException {
+    protected Type generateType() {
         return resultType;
     }
 
-    protected abstract IRNode generateProduction(Type type) throws ProductionFailedException;
+    protected abstract UnaryOperator generateProduction(Type type) throws ProductionFailedException;
 
     protected abstract boolean isApplicable(Type resultType);
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public UnaryOperator produce() throws ProductionFailedException {
         if (!isApplicable(resultType)) {
             //avoid implicit use of resultType.toString()
             throw new ProductionFailedException("Type " + resultType.getName()
@@ -65,7 +65,7 @@
         }
         try {
             SymbolTable.push();
-            IRNode result = generateProduction(type);
+            UnaryOperator result = generateProduction(type);
             SymbolTable.merge();
             return result;
         } catch (ProductionFailedException e) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/UnaryPlusMinusOperatorFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/UnaryPlusMinusOperatorFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -24,15 +24,12 @@
 package jdk.test.lib.jittester.factories;
 
 import jdk.test.lib.jittester.BuiltInType;
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.utils.TypeUtil;
 import jdk.test.lib.jittester.UnaryOperator;
-import jdk.test.lib.jittester.types.TypeBoolean;
-import jdk.test.lib.jittester.types.TypeInt;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
@@ -44,16 +41,16 @@
 
     @Override
     protected boolean isApplicable(Type resultType) {
-        if (!TypeList.isBuiltIn(resultType) || resultType.equals(new TypeBoolean())) {
+        if (!TypeList.isBuiltIn(resultType) || resultType.equals(TypeList.BOOLEAN)) {
             return false;
         }
         BuiltInType resType = (BuiltInType) resultType;
-        return resType.equals(new TypeInt()) || resType.isMoreCapaciousThan(new TypeInt());
+        return resType.equals(TypeList.INT) || resType.isMoreCapaciousThan(TypeList.INT);
     }
 
     @Override
-    protected Type generateType() throws ProductionFailedException {
-        if (resultType.equals(new TypeInt())) {
+    protected Type generateType() {
+        if (resultType.equals(TypeList.INT)) {
             return PseudoRandom.randomElement(TypeUtil.getImplicitlyCastable(TypeList.getBuiltIn(), resultType));
         } else {
             return resultType;
@@ -61,7 +58,7 @@
     }
 
     @Override
-    protected IRNode generateProduction(Type type) throws ProductionFailedException {
+    protected UnaryOperator generateProduction(Type type) throws ProductionFailedException {
         return new UnaryOperator(opKind, new IRNodeBuilder()
                 .setComplexityLimit(complexityLimit)
                 .setOperatorLimit(operatorLimit)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableDeclarationBlockFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableDeclarationBlockFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -24,14 +24,15 @@
 package jdk.test.lib.jittester.factories;
 
 import java.util.ArrayList;
-import jdk.test.lib.jittester.IRNode;
+
+import jdk.test.lib.jittester.Declaration;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.ProductionParams;
 import jdk.test.lib.jittester.VariableDeclarationBlock;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class VariableDeclarationBlockFactory extends Factory {
+class VariableDeclarationBlockFactory extends Factory<VariableDeclarationBlock> {
     private final long complexityLimit;
     private final int operatorLimit;
     private final boolean exceptionSafe;
@@ -48,10 +49,10 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
-        ArrayList<IRNode> content = new ArrayList<>();
+    public VariableDeclarationBlock produce() throws ProductionFailedException {
+        ArrayList<Declaration> content = new ArrayList<>();
         int limit = (int) Math.ceil(PseudoRandom.random() * ProductionParams.dataMemberLimit.value());
-        DeclarationFactory declFactory = new IRNodeBuilder()
+        Factory<Declaration> declFactory = new IRNodeBuilder()
                 .setOwnerKlass(ownerClass)
                 .setComplexityLimit(complexityLimit)
                 .setOperatorLimit(operatorLimit)
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableDeclarationFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableDeclarationFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -24,7 +24,7 @@
 package jdk.test.lib.jittester.factories;
 
 import java.util.LinkedList;
-import jdk.test.lib.jittester.IRNode;
+
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
 import jdk.test.lib.jittester.Type;
@@ -34,10 +34,10 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class VariableDeclarationFactory extends Factory {
-    protected final boolean isStatic;
-    protected final boolean isLocal;
-    protected final TypeKlass ownerClass;
+class VariableDeclarationFactory extends Factory<VariableDeclaration> {
+    private final boolean isStatic;
+    private final boolean isLocal;
+    private final TypeKlass ownerClass;
     private Type resultType;
 
     VariableDeclarationFactory(TypeKlass ownerClass, boolean isStatic, boolean isLocal, Type resultType) {
@@ -48,8 +48,8 @@
     }
 
     @Override
-    public  IRNode produce() throws ProductionFailedException {
-        if (resultType == TypeList.getVoid()) {
+    public VariableDeclaration produce() throws ProductionFailedException {
+        if (resultType.equals(TypeList.VOID)) {
             LinkedList<Type> types = new LinkedList<>(TypeList.getAll());
             PseudoRandom.shuffle(types);
             if (types.isEmpty()) {
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,15 +23,15 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.Rule;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.VariableBase;
 import jdk.test.lib.jittester.VariableInfo;
 import jdk.test.lib.jittester.types.TypeKlass;
 
-class VariableFactory extends Factory {
-    private final Rule rule;
+class VariableFactory extends Factory<VariableBase> {
+    private final Rule<VariableBase> rule;
 
     VariableFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass, Type resultType,
             boolean constant, boolean initialized, boolean exceptionSafe, boolean noconsts) {
@@ -42,7 +42,7 @@
         if (initialized) {
             flags |= VariableInfo.INITIALIZED;
         }
-        rule = new Rule("variable");
+        rule = new Rule<>("variable");
         IRNodeBuilder b = new IRNodeBuilder().setResultType(resultType)
                 .setFlags(flags)
                 .setComplexityLimit(complexityLimit)
@@ -55,7 +55,7 @@
     }
 
     @Override
-    public IRNode produce() throws ProductionFailedException {
+    public VariableBase produce() throws ProductionFailedException {
         return rule.produce();
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableInitializationFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableInitializationFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -37,7 +37,7 @@
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class VariableInitializationFactory extends SafeFactory {
+class VariableInitializationFactory extends SafeFactory<VariableInitialization> {
     private final int operatorLimit;
     private final long complexityLimit;
     private final boolean constant;
@@ -58,7 +58,7 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected VariableInitialization sproduce() throws ProductionFailedException {
         LinkedList<Type> types = new LinkedList<>(TypeList.getAll());
         PseudoRandom.shuffle(types);
         if (types.isEmpty()) {
@@ -71,7 +71,7 @@
                 .setResultType(resultType)
                 .setExceptionSafe(exceptionSafe)
                 .setNoConsts(false);
-        Rule rule = new Rule("initializer");
+        Rule<IRNode> rule = new Rule<>("initializer");
         rule.add("literal_initializer", b.getLiteralFactory());
         if (!ProductionParams.disableExprInInit.value()) {
             rule.add("expression", b.getLimitedExpressionFactory());
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/WhileFactory.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/WhileFactory.java	Fri May 20 18:05:09 2016 +0300
@@ -23,21 +23,21 @@
 
 package jdk.test.lib.jittester.factories;
 
-import jdk.test.lib.jittester.IRNode;
-import jdk.test.lib.jittester.Initialization;
+import jdk.test.lib.jittester.Block;
 import jdk.test.lib.jittester.Literal;
 import jdk.test.lib.jittester.LocalVariable;
-import jdk.test.lib.jittester.Nothing;
 import jdk.test.lib.jittester.ProductionFailedException;
 import jdk.test.lib.jittester.SymbolTable;
 import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.loops.Loop;
 import jdk.test.lib.jittester.loops.While;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeInt;
 import jdk.test.lib.jittester.utils.PseudoRandom;
 
-class WhileFactory extends SafeFactory {
+import java.util.LinkedList;
+
+class WhileFactory extends SafeFactory<While> {
     private final Loop loop;
     private final long complexityLimit;
     private final int statementLimit;
@@ -61,7 +61,8 @@
     }
 
     @Override
-    protected IRNode sproduce() throws ProductionFailedException {
+    protected While sproduce() throws ProductionFailedException {
+        Block emptyBlock = new Block(ownerClass, returnType, new LinkedList<>(), level - 1);
         if (statementLimit <= 0 || complexityLimit <= 0) {
             throw new ProductionFailedException();
         }
@@ -91,7 +92,7 @@
                 .setResultType(returnType)
                 .setOperatorLimit(operatorLimit);
         loop.initialization = builder.getCounterInitializerFactory(0).produce();
-        IRNode header;
+        Block header;
         try {
             header = builder.setComplexityLimit(headerComplLimit)
                     .setStatementLimit(headerStatementLimit)
@@ -103,15 +104,15 @@
                     .getBlockFactory()
                     .produce();
         } catch (ProductionFailedException e) {
-            header = new Nothing();
+            header = emptyBlock;
         }
-        LocalVariable counter = new LocalVariable(((Initialization) loop.initialization).get());
-        Literal limiter = new Literal(Integer.valueOf((int) thisLoopIterLimit), new TypeInt());
+        LocalVariable counter = new LocalVariable(loop.initialization.getVariableInfo());
+        Literal limiter = new Literal((int) thisLoopIterLimit, TypeList.INT);
         loop.condition = builder.setComplexityLimit(condComplLimit)
                 .setLocalVariable(counter)
                 .getLoopingConditionFactory(limiter)
                 .produce();
-        IRNode body1;
+        Block body1;
         SymbolTable.push();
         try {
             body1 = builder.setComplexityLimit(body1ComplLimit)
@@ -124,10 +125,10 @@
                     .getBlockFactory()
                     .produce();
         } catch (ProductionFailedException e) {
-            body1 = new Nothing();
+            body1 = emptyBlock;
         }
         loop.manipulator = builder.setLocalVariable(counter).getCounterManipulatorFactory().produce();
-        IRNode body2;
+        Block body2;
         try {
             body2 = builder.setComplexityLimit(body2ComplLimit)
                     .setStatementLimit(body2StatementLimit)
@@ -139,9 +140,9 @@
                     .getBlockFactory()
                     .produce();
         } catch (ProductionFailedException e) {
-            body2 = new Nothing();
+            body2 = emptyBlock;
         }
-        IRNode body3;
+        Block body3;
         try {
             body3 = builder.setComplexityLimit(body3ComplLimit)
                     .setStatementLimit(body3StatementLimit)
@@ -153,7 +154,7 @@
                     .getBlockFactory()
                     .produce();
         } catch (ProductionFailedException e) {
-            body3 = new Nothing();
+            body3 = emptyBlock;
         }
         SymbolTable.pop();
         return new While(level, loop, thisLoopIterLimit, header, body1, body2, body3);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/ArgumentDeclaration.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/ArgumentDeclaration.java	Fri May 20 18:05:09 2016 +0300
@@ -28,9 +28,10 @@
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class ArgumentDeclaration extends IRNode {
-    public VariableInfo variableInfo;
+    public final VariableInfo variableInfo;
 
     public ArgumentDeclaration(VariableInfo variableInfo) {
+        super(variableInfo.type);
         this.variableInfo = variableInfo;
     }
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/ConstructorDefinition.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/ConstructorDefinition.java	Fri May 20 18:05:09 2016 +0300
@@ -32,7 +32,9 @@
 
     public ConstructorDefinition(FunctionInfo functionInfo,
             ArrayList<ArgumentDeclaration> argumentsDeclaration, IRNode body) {
+        super(functionInfo.type);
         this.functionInfo = functionInfo;
+        this.owner = functionInfo.owner;
         addChild(body);
         addChildren(argumentsDeclaration);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/ConstructorDefinitionBlock.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/ConstructorDefinitionBlock.java	Fri May 20 18:05:09 2016 +0300
@@ -25,10 +25,12 @@
 
 import java.util.ArrayList;
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class ConstructorDefinitionBlock extends IRNode {
     public ConstructorDefinitionBlock(ArrayList<IRNode> content, int level) {
+        super(TypeList.VOID);
         this.level = level;
         addChildren(content);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/Function.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/Function.java	Fri May 20 18:05:09 2016 +0300
@@ -36,7 +36,8 @@
     private FunctionInfo functionInfo = new FunctionInfo();
 
     public Function(TypeKlass ownerClass, FunctionInfo functionInfo, List<IRNode> args) {
-        setKlass(ownerClass);
+        super(functionInfo.type);
+        setOwner(ownerClass);
         this.functionInfo = functionInfo;
         addChildren(args);
     }
@@ -48,14 +49,14 @@
             argsComplexity += child.complexity();
         }
         long funcComplexity = functionInfo.complexity;
-        TypeKlass typeKlass = (TypeKlass) this.klass;
+        TypeKlass typeKlass = this.owner;
         if (functionInfo.isConstructor()) {
             // Sum complexities of all default constructors of parent classes
             for (TypeKlass parent : typeKlass.getAllParents()) {
                 Collection<Symbol> parentFuncs = SymbolTable.getAllCombined(parent, FunctionInfo.class);
                 for (Symbol f : parentFuncs) {
                     FunctionInfo c = (FunctionInfo) f;
-                    if (c.name.equals(c.klass.getName()) && c.argTypes.isEmpty()) {
+                    if (c.name.equals(c.owner.getName()) && c.argTypes.isEmpty()) {
                         funcComplexity += c.complexity;
                     }
                 }
@@ -66,7 +67,7 @@
             for (TypeKlass child : typeKlass.getAllChildren()) {
                 Collection<Symbol> childFuncs = SymbolTable.getAllCombined(child, FunctionInfo.class);
                 for (Symbol childFunc : childFuncs) {
-                    if (((FunctionInfo) childFunc).equals(functionInfo)) {
+                    if (childFunc.equals(functionInfo)) {
                         funcComplexity = Math.max(funcComplexity, ((FunctionInfo) childFunc).complexity);
                     }
                 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDeclaration.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDeclaration.java	Fri May 20 18:05:09 2016 +0300
@@ -32,7 +32,9 @@
 
     public FunctionDeclaration(FunctionInfo functionInfo,
             ArrayList<ArgumentDeclaration> argumentsDeclaration) {
+        super(functionInfo.type);
         this.functionInfo = functionInfo;
+        this.owner = functionInfo.owner;
         addChildren(argumentsDeclaration);
     }
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDeclarationBlock.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDeclarationBlock.java	Fri May 20 18:05:09 2016 +0300
@@ -25,12 +25,14 @@
 
 import java.util.ArrayList;
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class FunctionDeclarationBlock extends IRNode {
     public FunctionDeclarationBlock(TypeKlass ownerClass, ArrayList<IRNode> content, int level) {
-        setKlass(ownerClass);
+        super(TypeList.VOID);
+        setOwner(ownerClass);
         this.level = level;
         addChildren(content);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDefinition.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDefinition.java	Fri May 20 18:05:09 2016 +0300
@@ -23,9 +23,10 @@
 
 package jdk.test.lib.jittester.functions;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedList;
+import java.util.List;
+
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.Symbol;
 import jdk.test.lib.jittester.SymbolTable;
@@ -36,8 +37,10 @@
     private final FunctionInfo functionInfo;
 
     public FunctionDefinition(FunctionInfo functionInfo,
-            ArrayList<ArgumentDeclaration> argumentsDeclaration, IRNode body, IRNode ret) {
+                              List<? extends ArgumentDeclaration> argumentsDeclaration, IRNode body, Return ret) {
+        super(functionInfo.type);
         this.functionInfo = functionInfo;
+        this.owner = functionInfo.owner;
         addChild(body);
         addChild(ret);
         addChildren(argumentsDeclaration);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDefinitionBlock.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDefinitionBlock.java	Fri May 20 18:05:09 2016 +0300
@@ -25,12 +25,14 @@
 
 import java.util.ArrayList;
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.types.TypeKlass;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class FunctionDefinitionBlock extends IRNode {
     public FunctionDefinitionBlock(ArrayList<IRNode> content, int level, TypeKlass ownerClass) {
-        setKlass(ownerClass);
+        super(TypeList.VOID);
+        setOwner(ownerClass);
         addChildren(content);
         this.level = level;
     }
@@ -44,10 +46,6 @@
         return complexity;
     }
 
-    protected int size() {
-        return getChildren() != null ? getChildren().size() : 0;
-    }
-
     @Override
     public<T> T accept(Visitor<T> v) {
         return v.visit(this);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionInfo.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionInfo.java	Fri May 20 18:05:09 2016 +0300
@@ -25,6 +25,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+
 import jdk.test.lib.jittester.Symbol;
 import jdk.test.lib.jittester.Type;
 import jdk.test.lib.jittester.VariableInfo;
@@ -89,7 +90,7 @@
 
         try {
             FunctionInfo f = (FunctionInfo) o;
-            return klass.equals(f.klass) && hasEqualSignature(o);
+            return owner.equals(f.owner) && hasEqualSignature(o);
         } catch (Exception e) {
         }
         return false;
@@ -117,7 +118,7 @@
     }
 
     public boolean isConstructor() {
-        return name.equals(klass.getName());
+        return name.equals(owner.getName());
     }
 
     @Override
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionRedefinition.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionRedefinition.java	Fri May 20 18:05:09 2016 +0300
@@ -23,16 +23,19 @@
 
 package jdk.test.lib.jittester.functions;
 
-import java.util.ArrayList;
+import java.util.List;
+
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class FunctionRedefinition extends IRNode {
     private final FunctionInfo functionInfo;
 
-    protected FunctionRedefinition(FunctionInfo functionInfo,
-            ArrayList<ArgumentDeclaration> argumentsDeclaration, IRNode body, IRNode ret) {
+    public FunctionRedefinition(FunctionInfo functionInfo,
+                                   List<? extends ArgumentDeclaration> argumentsDeclaration, IRNode body, Return ret) {
+        super(functionInfo.type);
         this.functionInfo = functionInfo;
+        this.owner = functionInfo.owner;
         addChild(body);
         addChild(ret);
         addChildren(argumentsDeclaration);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionRedefinitionBlock.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionRedefinitionBlock.java	Fri May 20 18:05:09 2016 +0300
@@ -25,10 +25,12 @@
 
 import java.util.ArrayList;
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.TypeList;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class FunctionRedefinitionBlock extends IRNode {
     public FunctionRedefinitionBlock(ArrayList<IRNode> content, int level) {
+        super(TypeList.VOID);
         this.level = level;
         addChildren(content);
     }
@@ -42,10 +44,6 @@
         return complexity;
     }
 
-    protected int size() {
-        return getChildren() != null ? getChildren().size() : 0;
-    }
-
     @Override
     public<T> T accept(Visitor<T> v) {
         return v.visit(this);
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/Return.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/Return.java	Fri May 20 18:05:09 2016 +0300
@@ -30,6 +30,7 @@
     private final IRNode returnExpression;
 
     public Return(IRNode returnExpression) {
+        super(returnExpression.getResultType());
         this.returnExpression = returnExpression;
         addChild(returnExpression);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/StaticConstructorDefinition.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/StaticConstructorDefinition.java	Fri May 20 18:05:09 2016 +0300
@@ -28,6 +28,8 @@
 
 public class StaticConstructorDefinition extends IRNode {
     public StaticConstructorDefinition(IRNode body) {
+        super(body.getResultType());
+        this.owner = body.getOwner();
         addChild(body);
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/Printer.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.lib.jittester.jtreg;
+
+import java.util.Stack;
+
+public class Printer {
+
+    public static String print(boolean arg) {
+        return String.valueOf(arg);
+    }
+
+    public static String print(byte arg) {
+        return String.valueOf(arg);
+    }
+
+    public static String print(short arg) {
+        return String.valueOf(arg);
+    }
+
+    public static String print(char arg) {
+        return String.valueOf((int) arg);
+    }
+
+    public static String print(int arg) {
+        return String.valueOf(arg);
+    }
+
+    public static String print(long arg) {
+        return String.valueOf(arg);
+    }
+
+    public static String print(float arg) {
+        return String.valueOf(arg);
+    }
+
+    public static String print(double arg) {
+        return String.valueOf(arg);
+    }
+
+    public static String print(Object arg) {
+        return print_r(new Stack<>(), arg);
+    }
+
+    private static String print_r(Stack<Object> visitedObjects, Object arg) {
+        String result = "";
+        if (arg == null) {
+            result += "null";
+        } else if (arg.getClass().isArray()) {
+            for (int i = 0; i < visitedObjects.size(); i++) {
+                if (visitedObjects.elementAt(i) == arg) {
+                    return "<recursive>";
+                }
+            }
+
+            visitedObjects.push(arg);
+
+            final String delimiter = ", ";
+            result += "[";
+
+            if (arg instanceof Object[]) {
+                Object[] array = (Object[]) arg;
+                for (int i = 0; i < array.length; i++) {
+                    result += print_r(visitedObjects, array[i]);
+                    if (i < array.length - 1) {
+                        result += delimiter;
+                    }
+                }
+            } else if (arg instanceof boolean[]) {
+                boolean[] array = (boolean[]) arg;
+                for (int i = 0; i < array.length; i++) {
+                    result += print(array[i]);
+                    if (i < array.length - 1) {
+                        result += delimiter;
+                    }
+                }
+            } else if (arg instanceof byte[]) {
+                byte[] array = (byte[]) arg;
+                for (int i = 0; i < array.length; i++) {
+                    result += print(array[i]);
+                    if (i < array.length - 1) {
+                        result += delimiter;
+                    }
+                }
+            } else if (arg instanceof short[]) {
+                short[] array = (short[]) arg;
+                for (int i = 0; i < array.length; i++) {
+                    result += print(array[i]);
+                    if (i < array.length - 1) {
+                        result += delimiter;
+                    }
+                }
+            } else if (arg instanceof char[]) {
+                char[] array = (char[]) arg;
+                for (int i = 0; i < array.length; i++) {
+                    result += print(array[i]);
+                    if (i < array.length - 1) {
+                        result += delimiter;
+                    }
+                }
+            } else if (arg instanceof int[]) {
+                int[] array = (int[]) arg;
+                for (int i = 0; i < array.length; i++) {
+                    result += print(array[i]);
+                    if (i < array.length - 1) {
+                        result += delimiter;
+                    }
+                }
+            } else if (arg instanceof long[]) {
+                long[] array = (long[]) arg;
+                for (int i = 0; i < array.length; i++) {
+                    result += print(array[i]);
+                    if (i < array.length - 1) {
+                        result += delimiter;
+                    }
+                }
+            } else if (arg instanceof float[]) {
+                float[] array = (float[]) arg;
+                for (int i = 0; i < array.length; i++) {
+                    result += print(array[i]);
+                    if (i < array.length - 1) {
+                        result += delimiter;
+                    }
+                }
+            } else if (arg instanceof double[]) {
+                double[] array = (double[]) arg;
+                for (int i = 0; i < array.length; i++) {
+                    result += print(array[i]);
+                    if (i < array.length - 1) {
+                        result += delimiter;
+                    }
+                }
+            }
+
+            result += "]";
+            visitedObjects.pop();
+
+        } else {
+            result += arg.toString();
+        }
+
+        return result;
+    }
+}
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/CounterManipulator.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/CounterManipulator.java	Fri May 20 18:05:09 2016 +0300
@@ -25,6 +25,7 @@
 
 import jdk.test.lib.jittester.IRNode;
 import jdk.test.lib.jittester.LocalVariable;
+import jdk.test.lib.jittester.Statement;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 /*
@@ -36,7 +37,8 @@
 public class CounterManipulator extends IRNode {
     LocalVariable counter;
 
-    public CounterManipulator(IRNode manipulator) {
+    public CounterManipulator(Statement manipulator) {
+        super(manipulator.getResultType());
         addChild(manipulator);
     }
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/DoWhile.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/DoWhile.java	Fri May 20 18:05:09 2016 +0300
@@ -42,7 +42,7 @@
         HEADER,
         BODY1,
         BODY2,
-    };
+    }
     private final Loop loop;
     // header;                  [subblock]
     // do {
@@ -52,8 +52,9 @@
     // } while(condition);
     private long thisLoopIterLimit = 0;
 
-    public DoWhile(int level, Loop loop, long thisLoopIterLimit, IRNode header,
-            IRNode body1, IRNode body2) {
+    public DoWhile(int level, Loop loop, long thisLoopIterLimit, Block header,
+                   Block body1, Block body2) {
+        super(body1.getResultType());
         this.level = level;
         this.loop = loop;
         this.thisLoopIterLimit = thisLoopIterLimit;
@@ -85,13 +86,12 @@
         IRNode header = getChildren().get(DoWhilePart.HEADER.ordinal());
         List<IRNode> siblings = getParent().getChildren();
         int index = siblings.indexOf(this);
+        siblings.set(index++, loop.initialization);
         if (header instanceof Block) {
-            siblings.remove(this);
             siblings.addAll(index, header.getChildren());
         } else {
-            siblings.set(index, header);
+            siblings.add(index, header);
         }
-        siblings.add(index + header.getChildren().size(), loop.initialization);
         return true;
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/For.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/For.java	Fri May 20 18:05:09 2016 +0300
@@ -26,6 +26,7 @@
 import java.util.List;
 import jdk.test.lib.jittester.Block;
 import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Statement;
 import jdk.test.lib.jittester.visitors.Visitor;
 
 public class For extends IRNode {
@@ -45,7 +46,7 @@
         BODY1,
         BODY2,
         BODY3,
-    };
+    }
 
     private final Loop loop;
     // header;                       // [subblock]
@@ -57,8 +58,9 @@
     // }
     private long thisLoopIterLimit = 0;
     public For(int level, Loop loop, long thisLoopIterLimit,
-            IRNode header, IRNode statement1,
-            IRNode statement2, IRNode body1, IRNode body2, IRNode body3) {
+               Block header, Statement statement1,
+               Statement statement2, Block body1, Block body2, Block body3) {
+        super(body1.getResultType());
         this.level = level;
         this.loop = loop;
         this.thisLoopIterLimit = thisLoopIterLimit;
@@ -100,13 +102,12 @@
         IRNode header = getChildren().get(ForPart.HEADER.ordinal());
         List<IRNode> siblings = getParent().getChildren();
         int index = siblings.indexOf(this);
+        siblings.set(index++, loop.initialization);
         if (header instanceof Block) {
-            siblings.remove(this);
             siblings.addAll(index, header.getChildren());
         } else {
-            siblings.set(index, header);
+            siblings.add(index, header);
         }
-        siblings.add(index + header.getChildren().size(), loop.initialization);
         return true;
     }
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/Loop.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/Loop.java	Fri May 20 18:05:09 2016 +0300
@@ -23,11 +23,10 @@
 
 package jdk.test.lib.jittester.loops;
 
-import jdk.test.lib.jittester.IRNode;
 
 // Just a structure to hold the values needed to handle basic loop production
 public class Loop {
-    public IRNode initialization;
-    public IRNode condition;
-    public IRNode manipulator;
+    public CounterInitializer initialization;
+    public LoopingCondition condition;
+    public CounterManipulator manipulator;
 }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/LoopingCondition.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/LoopingCondition.java	Fri May 20 18:05:09 2016 +0300
@@ -30,6 +30,7 @@
     private final IRNode condition;
 
     public LoopingCondition(IRNode condition) {
+        super(condition.getResultType());
         this.condition = condition;
         addChild(condition);
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/While.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/While.java	Fri May 20 18:05:09 2016 +0300
@@ -38,7 +38,7 @@
         BODY1,
         BODY2,
         BODY3,
-    };
+    }
 
     private final Loop loop;
     // int counter = x;
@@ -51,8 +51,9 @@
     // }
     private final long thisLoopIterLimit;
 
-    public While(int level, Loop loop, long thisLoopIterLimit, IRNode header,
-            IRNode body1, IRNode body2, IRNode body3) {
+    public While(int level, Loop loop, long thisLoopIterLimit, Block header,
+                 Block body1, Block body2, Block body3) {
+        super(body1.getResultType());
         this.loop = loop;
         this.level = level;
         this.thisLoopIterLimit = thisLoopIterLimit;
@@ -88,13 +89,12 @@
         IRNode header = getChildren().get(WhilePart.HEADER.ordinal());
         List<IRNode> siblings = getParent().getChildren();
         int index = siblings.indexOf(this);
+        siblings.set(index++, loop.initialization);
         if (header instanceof Block) {
-            siblings.remove(this);
             siblings.addAll(index, header.getChildren());
         } else {
-            siblings.set(index, header);
+            siblings.add(index, header);
         }
-        siblings.add(index + header.getChildren().size(), loop.initialization);
         return true;
     }
 
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeArray.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeArray.java	Fri May 20 18:05:09 2016 +0300
@@ -26,6 +26,9 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
 import jdk.test.lib.jittester.ProductionParams;
 import jdk.test.lib.jittester.SymbolTable;
 import jdk.test.lib.jittester.Type;
@@ -47,26 +50,29 @@
     public final int dimensions;
     private List<Byte> dims = new ArrayList<>();
 
-    public TypeArray() {
-        this(new TypeVoid(), 0);
-    }
-
     public TypeArray(Type type, int dimensions) {
         super("Array", TypeKlass.FINAL);
-        addParent("java.lang.Object");
-        setParent((TypeKlass) TypeList.find("java.lang.Object"));
+        addParent(TypeList.OBJECT.getName());
+        setParent(TypeList.OBJECT);
         this.type = type;
         this.dimensions = dimensions;
     }
 
+    public String getName() {
+        String dimString = Stream.generate(() -> "[]")
+                .limit(dimensions)
+                .collect(Collectors.joining());
+        return type.getName() + dimString;
+    }
+
     @Override
     protected void exportSymbols() {
-        SymbolTable.add(new VariableInfo("length", this, new TypeInt(), VariableInfo.PUBLIC | VariableInfo.FINAL));
+        SymbolTable.add(new VariableInfo("length", this, TypeList.INT, VariableInfo.PUBLIC | VariableInfo.FINAL));
     }
 
     @Override
     public boolean equals(Object t) {
-                if (this == t) {
+        if (this == t) {
             return true;
         }
         if (t == null || !(t instanceof TypeArray)) {
@@ -95,8 +101,7 @@
 
     @Override
     public int compareTo(Type t) {
-        int r = 0;
-        r = super.compareTo(t);
+        int r = super.compareTo(t);
         if (r == 0) {
             try {
                 TypeArray a = (TypeArray) t;
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeKlass.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeKlass.java	Fri May 20 18:05:09 2016 +0300
@@ -33,24 +33,27 @@
 import jdk.test.lib.jittester.TypeList;
 
 public class TypeKlass extends Type {
+    private TypeKlass parentKlass;
+    private final HashSet<String> parentsList;
+    private final HashSet<String> childrenList;
+    private final HashSet<Symbol> symbolsSet;
+    private int flags;
 
-    private TypeKlass parent;
-    private HashSet<String> parentsList;
-    private HashSet<String> childrenList;
-    private final HashSet<Symbol> symbolsSet;
     public static final int NONE = 0x00;
     public static final int FINAL = 0x01;
     public static final int INTERFACE = 0x02;
     public static final int ABSTRACT = 0x04;
-    private int flags = NONE;
+
 
     public TypeKlass(String name) {
-        this(name, 0);
+        this(name, NONE);
     }
 
     public TypeKlass(String name, int flags) {
         super(name);
         this.flags = flags;
+        parentsList = new HashSet<>();
+        childrenList = new HashSet<>();
         symbolsSet = new HashSet<>();
     }
 
@@ -76,39 +79,27 @@
 
     @Override
     protected void exportSymbols() {
-        symbolsSet.stream().forEach(symbol -> {
-            SymbolTable.add(symbol);
-        });
+        symbolsSet.stream().forEach(SymbolTable::add);
     }
 
     public void setParent(TypeKlass p) {
-        parent = p;
+        parentKlass = p;
     }
 
     public void addParent(String p) {
-        if (parentsList == null) {
-            parentsList = new HashSet<>();
-        }
         parentsList.add(p);
     }
 
     public void addChild(String c) {
-        if (childrenList == null) {
-            childrenList = new HashSet<>();
-        }
         childrenList.add(c);
     }
 
     protected void removeParent(String p) {
-        if (parentsList != null) {
-            parentsList.remove(p);
-        }
+        parentsList.remove(p);
     }
 
     protected void removeChild(String c) {
-        if (childrenList != null) {
-            childrenList.remove(c);
-        }
+        childrenList.remove(c);
     }
 
     public HashSet<String> getParentsNames() {
@@ -131,37 +122,27 @@
 
     public TreeSet<TypeKlass> getAllParents() {
         TreeSet<TypeKlass> result = new TreeSet<>();
-        if (parentsList != null) {
-            for (String parentName : parentsList) {
-                Type _parentKlass = TypeList.find(new TypeKlass(parentName));
-                if (_parentKlass != null) {
-                    try {
-                        TypeKlass parentKlass = (TypeKlass) _parentKlass;
-                        result.add(parentKlass);
-                        result.addAll(parentKlass.getAllParents());
-                    } catch (Exception e) {
-                    }
-                }
-            }
-        }
+        parentsList.stream()
+                .map(TypeList::find)
+                .filter(parentKlass -> parentKlass != null)
+                .map(parentKlass -> (TypeKlass) parentKlass)
+                .forEach(parentKlass -> {
+                    result.add(parentKlass);
+                    result.addAll(parentKlass.getAllParents());
+        });
         return result;
     }
 
     public TreeSet<TypeKlass> getAllChildren() {
         TreeSet<TypeKlass> r = new TreeSet<>();
-        if (childrenList != null) {
-            for (String childName : childrenList) {
-                Type _childKlass = TypeList.find(new TypeKlass(childName));
-                if (_childKlass != null) {
-                    try {
-                        TypeKlass childKlass = (TypeKlass) _childKlass;
-                        r.add(childKlass);
-                        r.addAll(childKlass.getAllChildren());
-                    } catch (Exception e) {
-                    }
-                }
-            }
-        }
+        childrenList.stream()
+                .map(TypeList::find)
+                .filter(childKlass -> childKlass != null)
+                .map(childKlass -> (TypeKlass) childKlass)
+                .forEach(childKlass -> {
+                    r.add(childKlass);
+                    r.addAll(childKlass.getAllChildren());
+        });
         return r;
     }
 
@@ -179,8 +160,11 @@
     // we cannot guarantee that no exception will occur.
     @Override
     public boolean canExplicitlyCastTo(Type t) {
+        if (equals(t)) {
+            return true;
+        }
         if (t instanceof TypeKlass && !ProductionParams.disableDowncasts.value()) {
-            return equals(t) || getAllChildren().contains(t);
+            return getAllChildren().contains(t);
         }
 
         return false;
@@ -205,4 +189,8 @@
     public boolean isInterface() {
         return (flags & INTERFACE) > 0;
     }
+
+    public TypeKlass getParent() {
+        return parentKlass;
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/utils/FixedTrees.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.lib.jittester.utils;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import jdk.test.lib.jittester.BinaryOperator;
+import jdk.test.lib.jittester.Block;
+import jdk.test.lib.jittester.CatchBlock;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Literal;
+import jdk.test.lib.jittester.LocalVariable;
+import jdk.test.lib.jittester.NonStaticMemberVariable;
+import jdk.test.lib.jittester.Nothing;
+import jdk.test.lib.jittester.Operator;
+import jdk.test.lib.jittester.OperatorKind;
+import jdk.test.lib.jittester.PrintVariables;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.Statement;
+import jdk.test.lib.jittester.StaticMemberVariable;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.TryCatchBlock;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.VariableInitialization;
+import jdk.test.lib.jittester.functions.ArgumentDeclaration;
+import jdk.test.lib.jittester.functions.Function;
+import jdk.test.lib.jittester.functions.FunctionDefinition;
+import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.functions.Return;
+import jdk.test.lib.jittester.jtreg.Printer;
+import jdk.test.lib.jittester.loops.CounterInitializer;
+import jdk.test.lib.jittester.loops.CounterManipulator;
+import jdk.test.lib.jittester.loops.For;
+import jdk.test.lib.jittester.loops.Loop;
+import jdk.test.lib.jittester.loops.LoopingCondition;
+import jdk.test.lib.jittester.types.TypeArray;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+public class FixedTrees {
+    public static FunctionDefinition printVariablesAsFunction(PrintVariables node) {
+        TypeKlass owner = node.getOwner();
+
+        ArrayList<IRNode> nodes = new ArrayList<>();
+
+        VariableInfo resultInfo = new VariableInfo("result", node.getOwner(), TypeList.STRING, VariableInfo.LOCAL);
+        nodes.add(new Statement(new VariableInitialization(resultInfo, new Literal("[", TypeList.STRING)), true));
+        LocalVariable resultVar = new LocalVariable(resultInfo);
+
+        List<Symbol> vars = node.getVars();
+
+        TypeKlass printerKlass = new TypeKlass(Printer.class.getName());
+        Literal EOL = new Literal("\n", TypeList.STRING);
+        VariableInfo thisInfo = new VariableInfo("this", node.getOwner(),
+                node.getOwner(), VariableInfo.LOCAL | VariableInfo.INITIALIZED);
+
+        LocalVariable thisVar = new LocalVariable(thisInfo);
+
+        for (int i = 0; i < vars.size(); i++) {
+            Symbol v = vars.get(i);
+            nodes.add(new Statement(new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar,
+                    new Literal(v.owner.getName() + "." + v.name + " = ", TypeList.STRING)), true));
+            VariableInfo argInfo = new VariableInfo("arg", printerKlass,
+                    v.type instanceof TypeKlass ? TypeList.OBJECT : v.type,
+                    VariableInfo.LOCAL | VariableInfo.INITIALIZED);
+            FunctionInfo printInfo = new FunctionInfo("print", printerKlass,
+                    TypeList.STRING, 0,  FunctionInfo.PUBLIC | FunctionInfo.STATIC, argInfo);
+            Function call = new Function(owner, printInfo, null);
+            VariableInfo varInfo = new VariableInfo(v.name, v.owner, v.type, v.flags);
+            if (v.isStatic()) {
+                call.addChild(new StaticMemberVariable(v.owner, varInfo));
+            } else {
+                call.addChild(new NonStaticMemberVariable(thisVar, varInfo));
+            }
+            nodes.add(new Statement(new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar,
+                    call), true));
+            if (i < vars.size() - 1) {
+                nodes.add(new Statement(new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar,
+                        EOL), true));
+            }
+        }
+        nodes.add(new Statement(
+                new BinaryOperator(OperatorKind.COMPOUND_ADD, TypeList.STRING, resultVar, new Literal("]\n", TypeList.STRING)),
+                true));
+
+        Block block = new Block(node.getOwner(), TypeList.STRING, nodes, 1);
+        FunctionInfo toStringInfo = new FunctionInfo("toString", owner, TypeList.STRING, 0L, FunctionInfo.PUBLIC, thisInfo);
+        return new FunctionDefinition(toStringInfo, new ArrayList<>(), block, new Return(resultVar));
+    }
+    public static FunctionDefinition generateMainOrExecuteMethod(TypeKlass owner, boolean isMain) {
+        Nothing nothing = new Nothing();
+        ArrayList<IRNode> testCallNodeContent = new ArrayList<>();
+        VariableInfo tInfo = new VariableInfo("t", owner, owner, VariableInfo.LOCAL);
+        LocalVariable tVar = new LocalVariable(tInfo);
+        Function testCallNode = new Function(owner, new FunctionInfo("test", owner, TypeList.VOID,
+                0L, FunctionInfo.PRIVATE, tInfo), null);
+        testCallNode.addChild(tVar);
+        testCallNodeContent.add(new Statement(testCallNode, true));
+        // { t.test(); }
+        Block testCallNodeBlock = new Block(owner, TypeList.VOID, testCallNodeContent, 4);
+
+        IRNode tryNode = testCallNodeBlock;
+        if (isMain) {
+            VariableInfo iInfo = new VariableInfo("i", owner, TypeList.INT, VariableInfo.LOCAL);
+            LocalVariable iVar = new LocalVariable(iInfo);
+            Operator increaseCounter = new BinaryOperator(OperatorKind.ASSIGN, TypeList.INT,
+                    iVar,
+                    new BinaryOperator(OperatorKind.ADD, TypeList.INT,
+                            iVar, new Literal(1, TypeList.INT)));
+            Loop loop = new Loop();
+            Block emptyBlock = new Block(owner, TypeList.VOID, new LinkedList<>(), 3);
+            loop.initialization = new CounterInitializer(iInfo, new Literal(0, TypeList.INT));
+            loop.manipulator = new CounterManipulator(new Statement(increaseCounter, false));
+            loop.condition = new LoopingCondition(new BinaryOperator(OperatorKind.LT, TypeList.BOOLEAN, iVar,
+                    new Literal(150000, TypeList.INT)));
+            For forNode = new For(4, loop, 150000, emptyBlock, new Statement(nothing, false),
+                    new Statement(nothing, false), testCallNodeBlock, emptyBlock, emptyBlock);
+            tryNode = forNode;
+        }
+
+        FunctionInfo constrInfo = new FunctionInfo(owner.getName(), owner, owner, 0, FunctionInfo.PUBLIC);
+        Function testConstructor = new Function(owner, constrInfo, null);
+        // Test t = new Test()
+        VariableInitialization testInit = new VariableInitialization(tInfo, testConstructor);
+
+        TypeKlass throwableKlass = new TypeKlass("java.lang.Throwable");
+        List<Type> throwables = new ArrayList<>();
+        throwables.add(throwableKlass);
+
+        VariableInfo exInfo = new VariableInfo("ex", owner, throwableKlass,
+                VariableInfo.LOCAL | VariableInfo.INITIALIZED);
+        FunctionInfo printStackTraceInfo = new FunctionInfo("printStackTrace", throwableKlass,
+                TypeList.VOID, 0, FunctionInfo.PUBLIC, exInfo);
+        Function printStackTraceCall = new Function(throwableKlass, printStackTraceInfo, null);
+        printStackTraceCall.addChild(new LocalVariable(exInfo));
+        ArrayList<IRNode> printStackTraceCallBlockContent = new ArrayList<>();
+        // { ex.printStackTrace(); }
+        printStackTraceCallBlockContent.add(new Statement(printStackTraceCall, true));
+
+        Block printStackTraceCallBlock = new Block(owner, TypeList.VOID, printStackTraceCallBlockContent, 3);
+        List<CatchBlock> catchBlocks1 = new ArrayList<>();
+        catchBlocks1.add(new CatchBlock(printStackTraceCallBlock, throwables, 3));
+        List<CatchBlock> catchBlocks2 = new ArrayList<>();
+        catchBlocks2.add(new CatchBlock(printStackTraceCallBlock, throwables, 3));
+        List<CatchBlock> catchBlocks3 = new ArrayList<>();
+        catchBlocks3.add(new CatchBlock(printStackTraceCallBlock, throwables, 2));
+
+        TryCatchBlock tryCatch1 = new TryCatchBlock(tryNode, nothing, catchBlocks1, 3);
+        TypeKlass printStreamKlass = new TypeKlass("java.io.PrintStream");
+        TypeKlass systemKlass = new TypeKlass("java.lang.System");
+        FunctionInfo systemOutPrintlnInfo = new FunctionInfo("println", printStreamKlass,
+                TypeList.VOID, 0, FunctionInfo.PUBLIC,
+                new VariableInfo("this", owner, printStreamKlass, VariableInfo.LOCAL | VariableInfo.INITIALIZED),
+                new VariableInfo("t", owner, TypeList.OBJECT,
+                        VariableInfo.LOCAL  | VariableInfo.INITIALIZED));
+        List<IRNode> printlnArgs = new ArrayList<>();
+        VariableInfo systemOutInfo = new VariableInfo("out", systemKlass, printStreamKlass,
+                VariableInfo.STATIC | VariableInfo.PUBLIC);
+        StaticMemberVariable systemOutVar = new StaticMemberVariable(owner, systemOutInfo);
+        printlnArgs.add(systemOutVar);
+        printlnArgs.add(tVar);
+        Function println = new Function(printStreamKlass, systemOutPrintlnInfo, printlnArgs);
+        ArrayList<IRNode> printlnBlockContent = new ArrayList<>();
+        printlnBlockContent.add(new Statement(println, true));
+        Block printlnBlock = new Block(owner, TypeList.VOID, printlnBlockContent, 3);
+        TryCatchBlock tryCatch2 = new TryCatchBlock(printlnBlock, nothing, catchBlocks2, 3);
+
+        List<IRNode> mainTryCatchBlockContent = new ArrayList<>();
+        mainTryCatchBlockContent.add(new Statement(testInit, true));
+        mainTryCatchBlockContent.add(tryCatch1);
+        mainTryCatchBlockContent.add(tryCatch2);
+        Block mainTryCatchBlock = new Block(owner, TypeList.VOID, mainTryCatchBlockContent, 2);
+        TryCatchBlock mainTryCatch = new TryCatchBlock(mainTryCatchBlock, nothing, catchBlocks3, 2);
+        ArrayList<IRNode> bodyContent = new ArrayList<>();
+        bodyContent.add(mainTryCatch);
+        Block funcBody = new Block(owner, TypeList.VOID, bodyContent, 1);
+
+        // static main(String[] args)V or static execute()V
+        VariableInfo mainArgs = new VariableInfo("args", owner,
+                new TypeArray(TypeList.STRING, 1), VariableInfo.LOCAL);
+        FunctionInfo fInfo = isMain
+                ? new FunctionInfo("main", owner, TypeList.VOID, 0, FunctionInfo.PUBLIC | FunctionInfo.STATIC, mainArgs)
+                : new FunctionInfo("execute", owner, TypeList.VOID, 0, FunctionInfo.PUBLIC | FunctionInfo.STATIC);
+        ArrayList<ArgumentDeclaration> argDecl = new ArrayList<>();
+        if (isMain) {
+            argDecl.add(new ArgumentDeclaration(mainArgs));
+        }
+        return new FunctionDefinition(fInfo, argDecl, funcBody, new Return(nothing));
+    }
+}
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/utils/OptionResolver.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/utils/OptionResolver.java	Fri May 20 18:05:09 2016 +0300
@@ -166,11 +166,10 @@
     }
 
     public abstract class Option<T> {
-
-        Character shortName;
-        String longName;
-        protected T defaultValue;
-        protected String description;
+        protected final Character shortName;
+        protected final String longName;
+        protected final T defaultValue;
+        protected final String description;
 
         public Option(Character shortName, String longName, T defaultValue, String description) {
             this.shortName = shortName;
@@ -200,6 +199,10 @@
             return (T) values.getOrDefault(this, defaultValue);
         }
 
+        public boolean isSet() {
+            return values.containsKey(this);
+        }
+
         public boolean isFlag() {
             return false;
         }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/utils/PseudoRandom.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/utils/PseudoRandom.java	Fri May 20 18:05:09 2016 +0300
@@ -23,18 +23,31 @@
 
 package jdk.test.lib.jittester.utils;
 
+import java.lang.reflect.Field;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicLong;
 
 /**
  * This class is used for any random generation operations.
  */
 public class PseudoRandom {
 
-    private static java.util.Random random = null;
+    private static Random random = null;
+    private static final Field SEED_FIELD;
+
+    static {
+        try {
+            SEED_FIELD = Random.class.getDeclaredField("seed");
+            SEED_FIELD.setAccessible(true);
+        } catch (ReflectiveOperationException roe) {
+            throw new Error("Can't get seed field: " + roe, roe);
+        }
+    }
 
     public static void reset(String seed) {
         if (seed == null || seed.length() == 0) {
@@ -71,9 +84,9 @@
         Collections.shuffle(list, random);
     }
 
-    public static byte randomNotNegative(byte limit) {
-        byte result = (byte) (limit * random.nextDouble());
-        return (byte)Math.abs(result);
+    public static int randomNotNegative(int limit) {
+        int result = (int) (limit * random.nextDouble());
+        return Math.abs(result);
     }
 
     public static <T> T randomElement(Collection<T> collection) {
@@ -103,4 +116,21 @@
             throw new NoSuchElementException("Empty, no element can be randomly selected");
         return array[random.nextInt(array.length)];
     }
+
+    public static long getCurrentSeed() {
+        try {
+            return ((AtomicLong)SEED_FIELD.get(random)).get();
+        } catch (ReflectiveOperationException roe) {
+            throw new Error("Can't get seed: " + roe, roe);
+        }
+    }
+
+    public static void setCurrentSeed(long seed) {
+        try {
+            AtomicLong seedObject = (AtomicLong)SEED_FIELD.get(random);
+            seedObject.set(seed);
+        } catch (ReflectiveOperationException roe) {
+            throw new Error("Can't set seed: " + roe, roe);
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/visitors/ByteCodeVisitor.java	Fri May 20 18:05:09 2016 +0300
@@ -0,0 +1,1831 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.lib.jittester.visitors;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.test.lib.Pair;
+import jdk.test.lib.jittester.BinaryOperator;
+import jdk.test.lib.jittester.Block;
+import jdk.test.lib.jittester.BuiltInType;
+import jdk.test.lib.jittester.Break;
+import jdk.test.lib.jittester.CastOperator;
+import jdk.test.lib.jittester.CatchBlock;
+import jdk.test.lib.jittester.Continue;
+import jdk.test.lib.jittester.Declaration;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.If;
+import jdk.test.lib.jittester.Initialization;
+import jdk.test.lib.jittester.Literal;
+import jdk.test.lib.jittester.LocalVariable;
+import jdk.test.lib.jittester.NonStaticMemberVariable;
+import jdk.test.lib.jittester.Nothing;
+import jdk.test.lib.jittester.Operator;
+import jdk.test.lib.jittester.OperatorKind;
+import jdk.test.lib.jittester.PrintVariables;
+import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Statement;
+import jdk.test.lib.jittester.StaticMemberVariable;
+import jdk.test.lib.jittester.Switch;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.TernaryOperator;
+import jdk.test.lib.jittester.Throw;
+import jdk.test.lib.jittester.TryCatchBlock;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.UnaryOperator;
+import jdk.test.lib.jittester.VariableBase;
+import jdk.test.lib.jittester.VariableDeclaration;
+import jdk.test.lib.jittester.VariableDeclarationBlock;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.VariableInitialization;
+import jdk.test.lib.jittester.arrays.ArrayCreation;
+import jdk.test.lib.jittester.arrays.ArrayElement;
+import jdk.test.lib.jittester.arrays.ArrayExtraction;
+import jdk.test.lib.jittester.classes.ClassDefinitionBlock;
+import jdk.test.lib.jittester.classes.Interface;
+import jdk.test.lib.jittester.classes.Klass;
+import jdk.test.lib.jittester.classes.MainKlass;
+import jdk.test.lib.jittester.functions.ArgumentDeclaration;
+import jdk.test.lib.jittester.functions.ConstructorDefinition;
+import jdk.test.lib.jittester.functions.ConstructorDefinitionBlock;
+import jdk.test.lib.jittester.functions.Function;
+import jdk.test.lib.jittester.functions.FunctionDeclaration;
+import jdk.test.lib.jittester.functions.FunctionDeclarationBlock;
+import jdk.test.lib.jittester.functions.FunctionDefinition;
+import jdk.test.lib.jittester.functions.FunctionDefinitionBlock;
+import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.functions.FunctionRedefinition;
+import jdk.test.lib.jittester.functions.FunctionRedefinitionBlock;
+import jdk.test.lib.jittester.functions.Return;
+import jdk.test.lib.jittester.functions.StaticConstructorDefinition;
+import jdk.test.lib.jittester.loops.CounterInitializer;
+import jdk.test.lib.jittester.loops.CounterManipulator;
+import jdk.test.lib.jittester.loops.DoWhile;
+import jdk.test.lib.jittester.loops.For;
+import jdk.test.lib.jittester.loops.Loop;
+import jdk.test.lib.jittester.loops.LoopingCondition;
+import jdk.test.lib.jittester.loops.While;
+import jdk.test.lib.jittester.types.TypeArray;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.FixedTrees;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+public class ByteCodeVisitor implements Visitor<byte[]> {
+    private final GeneratedClassesContext context = new GeneratedClassesContext();
+    private final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+    private final int CLASS_WRITER_FLAGS = ContextDependedClassWriter.COMPUTE_MAXS | ContextDependedClassWriter.COMPUTE_FRAMES;
+    private final HashMap<String, ContextDependedClassWriter> classWriters = new HashMap<>();
+    private MethodVisitor currentMV;
+    private TypeKlass currentClass;
+    private final LocalVariablesTable locals = new LocalVariablesTable();
+    private final Deque<Label> endLabels = new ArrayDeque<>();
+    private final Deque<Label> beginLabels = new ArrayDeque<>();
+
+    @Override
+    public byte[] visit(ArgumentDeclaration node) {
+        /* handled by FunctionDefinition for ByteCodeVisitor */
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(ArrayCreation node) {
+        int dimensions = node.getDimensionsCount();
+        TypeArray arrayType = node.getArrayType();
+        Type basicType = arrayType.type;
+        for (IRNode child : node.getChildren()) {
+            child.accept(this);
+        }
+        if (dimensions == 1) {
+            if (basicType.equals(TypeList.BOOLEAN)) {
+                currentMV.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_BOOLEAN);
+            } else if (basicType.equals(TypeList.BYTE)) {
+                currentMV.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_BYTE);
+            } else if (basicType.equals(TypeList.CHAR)) {
+                currentMV.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_CHAR);
+            } else if (basicType.equals(TypeList.SHORT)) {
+                currentMV.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_SHORT);
+            } else if (basicType.equals(TypeList.INT)) {
+                currentMV.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_INT);
+            } else if (basicType.equals(TypeList.LONG)) {
+                currentMV.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_LONG);
+            } else if (basicType.equals(TypeList.FLOAT)) {
+                currentMV.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_FLOAT);
+            } else if (basicType.equals(TypeList.DOUBLE)) {
+                currentMV.visitIntInsn(Opcodes.NEWARRAY, Opcodes.T_DOUBLE);
+            } else {
+                currentMV.visitTypeInsn(Opcodes.ANEWARRAY, asInternalName(basicType.getName()));
+            }
+        } else {
+            currentMV.visitMultiANewArrayInsn(new String(arrayType.accept(this)), dimensions);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(ArrayElement node) {
+        node.getChild(0).accept(this);
+        int dimensions = node.getChildren().size() - 1;
+        Type resultType = node.getResultType();
+        for (int i = 1; i < dimensions; i++) {
+            node.getChild(i).accept(this);
+            currentMV.visitInsn(Opcodes.AALOAD);
+        }
+        node.getChild(dimensions).accept(this);
+        if (resultType.equals(TypeList.BOOLEAN) || resultType.equals(TypeList.BYTE)) {
+            currentMV.visitInsn(Opcodes.BALOAD);
+        } else if (resultType.equals(TypeList.CHAR)) {
+            currentMV.visitInsn(Opcodes.CALOAD);
+        } else if (resultType.equals(TypeList.SHORT)) {
+            currentMV.visitInsn(Opcodes.SALOAD);
+        } else if (resultType.equals(TypeList.INT)) {
+            currentMV.visitInsn(Opcodes.IALOAD);
+        } else if (resultType.equals(TypeList.LONG)) {
+            currentMV.visitInsn(Opcodes.LALOAD);
+        } else if (resultType.equals(TypeList.FLOAT)) {
+            currentMV.visitInsn(Opcodes.FALOAD);
+        } else if (resultType.equals(TypeList.DOUBLE)) {
+            currentMV.visitInsn(Opcodes.DALOAD);
+        } else {
+            currentMV.visitInsn(Opcodes.AALOAD);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(ArrayExtraction node) {
+        node.getChild(0).accept(this);
+        int dimensions = node.getChildren().size() - 1;
+        Type resultType = node.getResultType();
+        for (int i = 1; i < dimensions; i++) {
+            node.getChild(i).accept(this);
+            currentMV.visitInsn(Opcodes.AALOAD);
+        }
+        node.getChild(dimensions).accept(this);
+        if (resultType.equals(TypeList.BOOLEAN) || resultType.equals(TypeList.BYTE)) {
+            currentMV.visitInsn(Opcodes.BALOAD);
+        } else if (resultType.equals(TypeList.CHAR)) {
+            currentMV.visitInsn(Opcodes.CALOAD);
+        } else if (resultType.equals(TypeList.SHORT)) {
+            currentMV.visitInsn(Opcodes.SALOAD);
+        } else if (resultType.equals(TypeList.INT)) {
+            currentMV.visitInsn(Opcodes.IALOAD);
+        } else if (resultType.equals(TypeList.LONG)) {
+            currentMV.visitInsn(Opcodes.LALOAD);
+        } else if (resultType.equals(TypeList.FLOAT)) {
+            currentMV.visitInsn(Opcodes.FALOAD);
+        } else if (resultType.equals(TypeList.DOUBLE)) {
+            currentMV.visitInsn(Opcodes.DALOAD);
+        } else {
+            currentMV.visitInsn(Opcodes.AALOAD);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(BinaryOperator node) {
+        OperatorKind kind = node.getOperationKind();
+        IRNode left = node.getChild(Operator.Order.LEFT.ordinal());
+        IRNode right = node.getChild(Operator.Order.RIGHT.ordinal());
+        Type resultType = node.getResultType();
+        if (left == null || right == null) {
+            return EMPTY_BYTE_ARRAY;
+        }
+        boolean needTypeConversion = false;
+        boolean convertRightArg = false;
+        Type leftType = left.getResultType();
+        Type rightType = right.getResultType();
+        if (!leftType.equals(rightType) && leftType instanceof BuiltInType
+                && rightType instanceof BuiltInType
+                && kind != OperatorKind.SAR && kind != OperatorKind.SHL
+                && kind != OperatorKind.SHR && kind != OperatorKind.ASSIGN
+                && kind != OperatorKind.AND && kind != OperatorKind.OR) {
+            needTypeConversion = true;
+            BuiltInType leftBuiltIn = (BuiltInType) leftType;
+            BuiltInType rightBuiltIn = (BuiltInType) rightType;
+            convertRightArg = leftBuiltIn.isMoreCapaciousThan(rightBuiltIn);
+        }
+        Type mostCapacious = convertRightArg ? leftType : rightType;
+        if (!rightType.equals(TypeList.INT)
+                && (kind == OperatorKind.SHL || kind == OperatorKind.SHR
+                || kind == OperatorKind.SAR)) {
+            left.accept(this);
+            right.accept(this);
+            convertTopType(rightType, TypeList.INT);
+        } else if (kind != OperatorKind.ASSIGN && kind != OperatorKind.OR
+                && kind != OperatorKind.AND && kind != OperatorKind.COMPOUND_ADD
+                && kind != OperatorKind.COMPOUND_AND && kind != OperatorKind.COMPOUND_DIV
+                && kind != OperatorKind.COMPOUND_MOD && kind != OperatorKind.COMPOUND_MUL
+                && kind != OperatorKind.COMPOUND_OR && kind != OperatorKind.COMPOUND_SAR
+                && kind != OperatorKind.COMPOUND_SHL && kind != OperatorKind.COMPOUND_SHR
+                && kind != OperatorKind.COMPOUND_SUB && kind != OperatorKind.COMPOUND_XOR
+                && kind != OperatorKind.STRADD) {
+                /* "assign", "and", "or", concat and all compound operators are
+                    handled differently and shouldn't just place left and right
+                    operands on stack */
+            left.accept(this);
+            if (needTypeConversion && !convertRightArg) {
+                convertTopType(leftType, rightType);
+            }
+            right.accept(this);
+            if (needTypeConversion && convertRightArg) {
+                convertTopType(rightType, leftType);
+            }
+        }
+        switch (kind) {
+            case ASSIGN:
+                VariableInfo vi = ((VariableBase)left).getVariableInfo();
+                Type varType = vi.type;
+                if (left instanceof LocalVariable) {
+                    right.accept(this);
+                    convertTopType(rightType, leftType);
+                    int index = locals.getLocalIndex(vi);
+                    if (varType.equals(TypeList.LONG)) {
+                        currentMV.visitVarInsn(Opcodes.LSTORE, index);
+                        currentMV.visitVarInsn(Opcodes.LLOAD, index);
+                    } else if (varType.equals(TypeList.DOUBLE)) {
+                        currentMV.visitVarInsn(Opcodes.DSTORE, index);
+                        currentMV.visitVarInsn(Opcodes.DLOAD, index);
+                    } else if (varType.equals(TypeList.FLOAT)) {
+                        currentMV.visitVarInsn(Opcodes.FSTORE, index);
+                        currentMV.visitVarInsn(Opcodes.FLOAD, index);
+                    } else if (varType instanceof TypeKlass) {
+                        currentMV.visitVarInsn(Opcodes.ASTORE, index);
+                        currentMV.visitVarInsn(Opcodes.ALOAD, index);
+                    } else {
+                        currentMV.visitVarInsn(Opcodes.ISTORE, index);
+                        currentMV.visitVarInsn(Opcodes.ILOAD, index);
+                    }
+                } else if (left instanceof StaticMemberVariable) {
+                    right.accept(this);
+                    convertTopType(rightType, leftType);
+                    String typeDescr = new String(vi.type.accept(this));
+                    String ownerName = asInternalName(vi.getOwner().getName());
+                    currentMV.visitFieldInsn(Opcodes.PUTSTATIC, ownerName,
+                            vi.name, typeDescr);
+                    currentMV.visitFieldInsn(Opcodes.GETSTATIC, ownerName,
+                            vi.name, typeDescr);
+                } else if (left instanceof NonStaticMemberVariable) {
+                    // put object to stack for putfield
+                    left.getChild(0).accept(this);
+                    // put object to stack for getfield
+                    currentMV.visitInsn(Opcodes.DUP);
+                    right.accept(this);
+                    convertTopType(rightType, leftType);
+                    String typeDescr = new String(vi.type.accept(this));
+                    String ownerName = asInternalName(vi.getOwner().getName());
+                    currentMV.visitFieldInsn(Opcodes.PUTFIELD, ownerName,
+                            vi.name, typeDescr);
+                    currentMV.visitFieldInsn(Opcodes.GETFIELD, ownerName,
+                            vi.name, typeDescr);
+                } else {
+                    throw new IllegalArgumentException("illegal left operand : "
+                            + left + "("+left.getClass()+")");
+                }
+                break;
+            case OR:
+                generateBasicLogicOperator(Opcodes.IFNE, false, left, right);
+                break;
+            case AND:
+                generateBasicLogicOperator(Opcodes.IFEQ, true,  left, right);
+                break;
+            case BIT_OR:
+                if (mostCapacious.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LOR);
+                } else {
+                    currentMV.visitInsn(Opcodes.IOR);
+                }
+                break;
+            case BIT_XOR:
+                if (mostCapacious.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LXOR);
+                } else {
+                    currentMV.visitInsn(Opcodes.IXOR);
+                }
+                break;
+            case BIT_AND:
+                if (mostCapacious.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LAND);
+                } else {
+                    currentMV.visitInsn(Opcodes.IAND);
+                }
+                break;
+            case EQ:
+                generateCmpBasedCode(mostCapacious, Opcodes.IFEQ, Opcodes.IF_ICMPEQ);
+                break;
+            case NE:
+                generateCmpBasedCode(mostCapacious, Opcodes.IFNE, Opcodes.IF_ICMPNE);
+                break;
+            case GT:
+                generateCmpBasedCode(mostCapacious, Opcodes.IFGT, Opcodes.IF_ICMPGT);
+                break;
+            case LT:
+                generateCmpBasedCode(mostCapacious, Opcodes.IFLT, Opcodes.IF_ICMPLT);
+                break;
+            case GE:
+                generateCmpBasedCode(mostCapacious, Opcodes.IFGE, Opcodes.IF_ICMPGE);
+                break;
+            case LE:
+                generateCmpBasedCode(mostCapacious, Opcodes.IFLE, Opcodes.IF_ICMPLE);
+                break;
+            case SHR:
+                if (leftType.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LSHR);
+                } else {
+                    currentMV.visitInsn(Opcodes.ISHR);
+                }
+                break;
+            case SHL:
+                if (leftType.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LSHL);
+                } else {
+                    currentMV.visitInsn(Opcodes.ISHL);
+                }
+                break;
+            case SAR:
+                if (leftType.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LUSHR);
+                } else {
+                    currentMV.visitInsn(Opcodes.IUSHR);
+                }
+                break;
+            case STRADD:
+                // we use String::valueOf to change null to "null"
+                left.accept(this);
+                currentMV.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "valueOf",
+                        "(Ljava/lang/Object;)Ljava/lang/String;", false /* not interface */);
+                right.accept(this);
+                currentMV.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "valueOf",
+                        "(Ljava/lang/Object;)Ljava/lang/String;", false /* not interface */);
+                currentMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "concat",
+                        "(Ljava/lang/String;)Ljava/lang/String;", false /* not interface */);
+                break;
+            case ADD:
+                if (mostCapacious.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LADD);
+                } else if (mostCapacious.equals(TypeList.DOUBLE)) {
+                    currentMV.visitInsn(Opcodes.DADD);
+                } else if (mostCapacious.equals(TypeList.FLOAT)) {
+                    currentMV.visitInsn(Opcodes.FADD);
+                } else {
+                    currentMV.visitInsn(Opcodes.IADD);
+                }
+                break;
+            case SUB:
+                if (mostCapacious.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LSUB);
+                } else if (mostCapacious.equals(TypeList.DOUBLE)) {
+                    currentMV.visitInsn(Opcodes.DSUB);
+                } else if (mostCapacious.equals(TypeList.FLOAT)) {
+                    currentMV.visitInsn(Opcodes.FSUB);
+                } else {
+                    currentMV.visitInsn(Opcodes.ISUB);
+                }
+                break;
+            case MUL:
+                if (mostCapacious.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LMUL);
+                } else if (mostCapacious.equals(TypeList.DOUBLE)) {
+                    currentMV.visitInsn(Opcodes.DMUL);
+                } else if (mostCapacious.equals(TypeList.FLOAT)) {
+                    currentMV.visitInsn(Opcodes.FMUL);
+                } else {
+                    currentMV.visitInsn(Opcodes.IMUL);
+                }
+                break;
+            case DIV:
+                if (mostCapacious.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LDIV);
+                } else if (mostCapacious.equals(TypeList.DOUBLE)) {
+                    currentMV.visitInsn(Opcodes.DDIV);
+                } else if (mostCapacious.equals(TypeList.FLOAT)) {
+                    currentMV.visitInsn(Opcodes.FDIV);
+                } else {
+                    currentMV.visitInsn(Opcodes.IDIV);
+                }
+                break;
+            case MOD:
+                if (mostCapacious.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LREM);
+                } else if (mostCapacious.equals(TypeList.DOUBLE)) {
+                    currentMV.visitInsn(Opcodes.DREM);
+                } else if (mostCapacious.equals(TypeList.FLOAT)) {
+                    currentMV.visitInsn(Opcodes.FREM);
+                } else {
+                    currentMV.visitInsn(Opcodes.IREM);
+                }
+                break;
+            case COMPOUND_ADD:
+                lowerCompoundBinaryOperator("java.lang.String".equals(leftType.getName())
+                        ? OperatorKind.STRADD : OperatorKind.ADD, node);
+                break;
+            case COMPOUND_SUB:
+                lowerCompoundBinaryOperator(OperatorKind.SUB, node);
+                break;
+            case COMPOUND_MUL:
+                lowerCompoundBinaryOperator(OperatorKind.MUL, node);
+                break;
+            case COMPOUND_DIV:
+                lowerCompoundBinaryOperator(OperatorKind.DIV, node);
+                break;
+            case COMPOUND_MOD:
+                lowerCompoundBinaryOperator(OperatorKind.MOD, node);
+                break;
+            case COMPOUND_AND:
+                lowerCompoundBinaryOperator(leftType.equals(TypeList.BOOLEAN)
+                        ? OperatorKind.AND : OperatorKind.BIT_AND, node);
+                break;
+            case COMPOUND_OR:
+                lowerCompoundBinaryOperator(leftType.equals(TypeList.BOOLEAN)
+                        ? OperatorKind.OR : OperatorKind.BIT_OR, node);
+                break;
+            case COMPOUND_XOR:
+                lowerCompoundBinaryOperator(OperatorKind.BIT_XOR, node);
+                break;
+            case COMPOUND_SHR:
+                lowerCompoundBinaryOperator(OperatorKind.SHR, node);
+                break;
+            case COMPOUND_SHL:
+                lowerCompoundBinaryOperator(OperatorKind.SHL, node);
+                break;
+            case COMPOUND_SAR:
+                lowerCompoundBinaryOperator(OperatorKind.SAR, node);
+                break;
+            default:
+                throw new Error("Unsupported binary operator");
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    private static int tmpObject;
+    private void lowerCompoundBinaryOperator(OperatorKind kind, IRNode node) {
+        IRNode left = node.getChild(Operator.Order.LEFT.ordinal());
+        IRNode right = node.getChild(Operator.Order.RIGHT.ordinal());
+
+        if (left instanceof NonStaticMemberVariable) {
+            NonStaticMemberVariable var = (NonStaticMemberVariable) left;
+            IRNode holder = var.getChild(0);
+            Type type = holder.getResultType();
+            VariableInfo tmpInfo = new VariableInfo("tmpObject_" + tmpObject++,
+                    currentClass, type, VariableInfo.LOCAL);
+            new Statement(new VariableInitialization(tmpInfo, holder), true).accept(this);
+            left = new NonStaticMemberVariable(new LocalVariable(tmpInfo), var.getVariableInfo());
+        }
+        Type leftType = left.getResultType();
+        Type rightType = right.getResultType();
+        Type resultType = leftType;
+        if (leftType instanceof BuiltInType && rightType instanceof BuiltInType) {
+            if (kind != OperatorKind.SHL && kind != OperatorKind.SHR && kind != OperatorKind.SAR
+                    && ((BuiltInType) rightType).isMoreCapaciousThan((BuiltInType) leftType)) {
+                resultType = rightType;
+            }
+        }
+        IRNode result = new CastOperator(leftType,
+                new BinaryOperator(kind, resultType, left, right));
+        new BinaryOperator(OperatorKind.ASSIGN, leftType, left, result).accept(this);
+    }
+
+    private void generateBasicLogicOperator(int ifOpcode, boolean retTrueFirst, IRNode left,
+            IRNode right) {
+        Label secondCase = new Label();
+        Label endLabel = new Label();
+        left.accept(this);
+        currentMV.visitJumpInsn(ifOpcode, secondCase);
+        right.accept(this);
+        currentMV.visitJumpInsn(ifOpcode, secondCase);
+        currentMV.visitInsn(retTrueFirst ? Opcodes.ICONST_1 : Opcodes.ICONST_0);
+        currentMV.visitJumpInsn(Opcodes.GOTO, endLabel);
+        currentMV.visitLabel(secondCase);
+        currentMV.visitInsn(retTrueFirst ? Opcodes.ICONST_0 : Opcodes.ICONST_1);
+        currentMV.visitLabel(endLabel);
+    }
+
+    private void generateCmpBasedCode(Type type, int nonIntOpcode, int intOpcode) {
+        boolean useNonIntOpcode = false;
+        if (type.equals(TypeList.LONG) || type.equals(TypeList.FLOAT)
+                || type.equals(TypeList.DOUBLE)) {
+            if (type.equals(TypeList.LONG)) {
+                currentMV.visitInsn(Opcodes.LCMP);
+            } else if (type.equals(TypeList.FLOAT)) {
+                currentMV.visitInsn(Opcodes.FCMPL);
+            } else {
+                currentMV.visitInsn(Opcodes.DCMPL);
+            }
+            useNonIntOpcode = true;
+        }
+        int opcodeToUse;
+        if (!useNonIntOpcode) {
+            if (type instanceof TypeKlass) {
+                if (intOpcode == Opcodes.IF_ICMPEQ) {
+                    opcodeToUse = Opcodes.IF_ACMPEQ;
+                } else if (intOpcode == Opcodes.IF_ICMPNE) {
+                    opcodeToUse = Opcodes.IF_ACMPNE;
+                } else {
+                    throw new Error("Can't compare references");
+                }
+            } else {
+                opcodeToUse = intOpcode;
+            }
+        } else {
+            opcodeToUse = nonIntOpcode;
+        }
+        Label retTrue = new Label();
+        Label end = new Label();
+        currentMV.visitJumpInsn(opcodeToUse, retTrue);
+        currentMV.visitInsn(Opcodes.ICONST_0);
+        currentMV.visitJumpInsn(Opcodes.GOTO, end);
+        currentMV.visitLabel(retTrue);
+        currentMV.visitInsn(Opcodes.ICONST_1);
+        currentMV.visitLabel(end);
+    }
+
+    /*
+     * Converts top-stack element from one builtin type to another
+     */
+    private void convertTopType(Type from, Type to) {
+        if (!(from instanceof BuiltInType) || !(to instanceof BuiltInType) || from.equals(to)) {
+            return; // skip
+        }
+        boolean castedToInt = false;
+        if (from.equals(TypeList.FLOAT)) {
+            if (to.equals(TypeList.DOUBLE)) {
+                currentMV.visitInsn(Opcodes.F2D);
+            } else if (to.equals(TypeList.LONG)) {
+                currentMV.visitInsn(Opcodes.F2L);
+            } else {
+                currentMV.visitInsn(Opcodes.F2I);
+                castedToInt = true;
+            }
+        } else if (from.equals(TypeList.DOUBLE)) {
+            if (to.equals(TypeList.FLOAT)) {
+                currentMV.visitInsn(Opcodes.D2F);
+            } else if (to.equals(TypeList.LONG)) {
+                currentMV.visitInsn(Opcodes.D2L);
+            } else {
+                currentMV.visitInsn(Opcodes.D2I);
+                castedToInt = true;
+            }
+        } else if (from.equals(TypeList.LONG)) {
+            if (to.equals(TypeList.DOUBLE)) {
+                currentMV.visitInsn(Opcodes.L2D);
+            } else if (to.equals(TypeList.FLOAT)) {
+                currentMV.visitInsn(Opcodes.L2F);
+            } else {
+                currentMV.visitInsn(Opcodes.L2I);
+                castedToInt = true;
+            }
+        } else {
+            if (to.equals(TypeList.BYTE)) {
+                currentMV.visitInsn(Opcodes.I2B);
+            } else if (to.equals(TypeList.CHAR)) {
+                currentMV.visitInsn(Opcodes.I2C);
+            } else if (to.equals(TypeList.SHORT)) {
+                currentMV.visitInsn(Opcodes.I2S);
+            } else if (to.equals(TypeList.LONG)) {
+                currentMV.visitInsn(Opcodes.I2L);
+            } else if (to.equals(TypeList.FLOAT)) {
+                currentMV.visitInsn(Opcodes.I2F);
+            } else if (to.equals(TypeList.DOUBLE)) {
+                currentMV.visitInsn(Opcodes.I2D);
+            }
+        }
+        if (castedToInt) {
+            if (to.equals(TypeList.BYTE)) {
+                currentMV.visitInsn(Opcodes.I2B);
+            } else if (to.equals(TypeList.CHAR)) {
+                currentMV.visitInsn(Opcodes.I2C);
+            } else if (to.equals(TypeList.SHORT)) {
+                currentMV.visitInsn(Opcodes.I2S);
+            }
+        }
+    }
+
+    @Override
+    public byte[] visit(Block node) {
+        return iterateBlock(node);
+    }
+
+    @Override
+    public byte[] visit(Break node) {
+        Label label = endLabels.peek();
+        if (label != null) {
+            currentMV.visitJumpInsn(Opcodes.GOTO, label);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(CastOperator node) {
+        IRNode expression = node.getChild(0);
+        expression.accept(this);
+        Type to = node.getResultType();
+        Type from = expression.getResultType();
+        // TODO boxing/unboxing
+        if (!TypeList.isBuiltIn(to) || !TypeList.isBuiltIn(from)) {
+            // class cast
+            currentMV.visitTypeInsn(Opcodes.CHECKCAST, asInternalName(to.getName()));
+        } else {
+            convertTopType(from, to);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(CatchBlock node) {
+        Type type = node.throwables.get(0);
+        VariableInfo exInfo = new VariableInfo("ex", currentClass,
+                type, VariableInfo.LOCAL);
+        int index = locals.getLocalIndex(exInfo);
+        currentMV.visitVarInsn(Opcodes.ASTORE, index);
+        node.getChild(0).accept(this);
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(ClassDefinitionBlock node) {
+        return iterateBlock(node);
+    }
+
+    @Override
+    public byte[] visit(ConstructorDefinition node) {
+        FunctionInfo info = node.getFunctionInfo();
+        String ownerName = node.getOwner().getName();
+        TypeKlass parentClass = currentClass.getParent();
+        ContextDependedClassWriter cw = classWriters.get(ownerName);
+
+        String descriptor = getDescriptor(node, 1, "V");
+        currentMV = cw.visitMethod(asAccessFlags(info), "<init>", descriptor, null, null);
+        currentMV.visitVarInsn(Opcodes.ALOAD, 0);
+        currentMV.visitMethodInsn(Opcodes.INVOKESPECIAL,
+                parentClass != null ? asInternalName(parentClass.getName()) : "java/lang/Object",
+                "<init>", "()V", false);
+        locals.initConstructorArguments(node.getOwner(), info);
+        // TODO: add datamemebers as child to all ctors
+        generateDataMembers(node.getParent().getParent().getChild(Klass.KlassPart.DATA_MEMBERS.ordinal()));
+        IRNode body = node.getChild(0);
+        body.accept(this);
+        currentMV.visitInsn(Opcodes.RETURN);
+        currentMV.visitMaxs(0, 0);
+        currentMV.visitEnd();
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    private void generateDataMembers(IRNode node) {
+        // TODO shouldn't we skip declaration?
+        if (node != null) {
+            node.accept(this);
+        }
+    }
+
+    @Override
+    public byte[] visit(ConstructorDefinitionBlock node) {
+        return iterateBlock(node);
+    }
+
+    @Override
+    public byte[] visit(Continue node) {
+        Label label = beginLabels.peek();
+        if (label != null) {
+            currentMV.visitJumpInsn(Opcodes.GOTO, label);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(CounterInitializer node) {
+        visitLocalVar(node);
+        emitPop(node.getVariableInfo().type);
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    private byte[] visitLocalVar(Initialization node) {
+        VariableInfo vi = node.getVariableInfo();
+        int index = locals.addLocal(vi);
+        int store;
+        node.getChild(0).accept(this); // place initialization expression on stack
+        emitDup(vi.type);
+        if (vi.type instanceof TypeKlass) {
+            store = Opcodes.ASTORE;
+        } else if (vi.type.equals(TypeList.DOUBLE)) {
+            store = Opcodes.DSTORE;
+        } else if (vi.type.equals(TypeList.LONG)) {
+            store = Opcodes.LSTORE;
+        } else if (vi.type.equals(TypeList.FLOAT)) {
+            store = Opcodes.FSTORE;
+        } else {
+            store = Opcodes.ISTORE;
+        }
+        currentMV.visitVarInsn(store, index);
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(CounterManipulator node) {
+        return node.getChild(0).accept(this);
+    }
+
+    @Override
+    public byte[] visit(Declaration node) {
+        IRNode child = node.getChild(0);
+        child.accept(this);
+        if (child instanceof Initialization) {
+            emitPop(((Initialization) child).getVariableInfo().type);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(DoWhile node) {
+        Loop loop = node.getLoop();
+        loop.initialization.accept(this);
+        node.getChild(DoWhile.DoWhilePart.HEADER.ordinal()).accept(this);
+        Label currentLoopBegin = new Label();
+        beginLabels.push(currentLoopBegin);
+        Label currentLoopEnd = new Label();
+        endLabels.push(currentLoopEnd);
+        currentMV.visitLabel(currentLoopBegin);
+        node.getChild(DoWhile.DoWhilePart.BODY1.ordinal()).accept(this);
+        loop.manipulator.accept(this);
+        node.getChild(DoWhile.DoWhilePart.BODY2.ordinal()).accept(this);
+        loop.condition.accept(this);
+        assert loop.condition.getResultType() == TypeList.BOOLEAN;
+        currentMV.visitJumpInsn(Opcodes.IFEQ, currentLoopBegin);
+        currentMV.visitLabel(currentLoopEnd);
+        Label a = beginLabels.pop();
+        assert currentLoopBegin == a;
+        a = endLabels.pop();
+        assert currentLoopEnd == a;
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(For node) {
+        Loop loop = node.getLoop();
+        loop.initialization.accept(this);
+        node.getChild(For.ForPart.HEADER.ordinal()).accept(this);
+        node.getChild(For.ForPart.STATEMENT1.ordinal()).accept(this);
+        Label currentLoopBegin = new Label();
+        beginLabels.push(currentLoopBegin);
+        currentMV.visitLabel(currentLoopBegin);
+        loop.condition.accept(this);
+        assert loop.condition.getResultType() == TypeList.BOOLEAN;
+        Label currentLoopEnd = new Label();
+        endLabels.push(currentLoopEnd);
+        currentMV.visitJumpInsn(Opcodes.IFEQ, currentLoopEnd);
+        node.getChild(For.ForPart.STATEMENT2.ordinal()).accept(this);
+        node.getChild(For.ForPart.BODY1.ordinal()).accept(this);
+        loop.manipulator.accept(this);
+        node.getChild(For.ForPart.BODY2.ordinal()).accept(this);
+        node.getChild(For.ForPart.BODY3.ordinal()).accept(this);
+        currentMV.visitJumpInsn(Opcodes.GOTO, currentLoopBegin);
+        currentMV.visitLabel(currentLoopEnd);
+        Label a = beginLabels.pop();
+        assert currentLoopBegin == a;
+        a = endLabels.pop();
+        assert currentLoopEnd == a;
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(Function node) {
+        FunctionInfo info = node.getValue();
+        boolean needInstance = !info.isStatic() && !info.isConstructor();
+        if (needInstance) {
+            node.getChild(0).accept(this); // placing instance on stack
+        }
+        // call itself with specific invoke*
+        String signature = info.argTypes.stream()
+                .skip(!needInstance ? 0 : 1)
+                .map(vi -> new String(vi.type.accept(this)))
+                .collect(Collectors.joining("", "(", ")"))
+                + (info.isConstructor() ? "V" : new String(node.getResultType().accept(this)));
+        int invokeCode = Opcodes.INVOKEVIRTUAL;
+        if (info.isStatic()) {
+            invokeCode = Opcodes.INVOKESTATIC;
+        } else if (info.isConstructor() || info.isPrivate()) {
+            // TODO : superclass method invocation?
+            invokeCode = Opcodes.INVOKESPECIAL;
+        } else {
+            if (info.owner.isInterface()) {
+                invokeCode = Opcodes.INVOKEINTERFACE;
+            }
+        }
+        if (info.isConstructor()) {
+            currentMV.visitTypeInsn(Opcodes.NEW, asInternalName(info.owner.getName()));
+            currentMV.visitInsn(Opcodes.DUP);
+        }
+        // calculating parameters
+        node.getChildren().stream()
+                .skip(!needInstance ? 0 : 1)
+                .forEachOrdered(c -> c.accept(this));
+        currentMV.visitMethodInsn(invokeCode, asInternalName(info.owner.getName()),
+                info.isConstructor() ? "<init>" : info.name, signature,
+                invokeCode == Opcodes.INVOKEINTERFACE);
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(FunctionDeclaration node) {
+        FunctionInfo info = node.getFunctionInfo();
+        String ownerName = node.getOwner().getName();
+        ContextDependedClassWriter cw = classWriters.get(ownerName);
+        String returnType = new String(info.type.accept(this));
+
+        String descriptor = getDescriptor(node, 0, returnType);
+        currentMV = cw.visitMethod(asAccessFlags(info) + Opcodes.ACC_ABSTRACT,
+                info.name, descriptor, null, null);
+        currentMV.visitEnd();
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(FunctionDeclarationBlock node) {
+        return iterateBlock(node);
+    }
+
+    @Override
+    public byte[] visit(FunctionDefinition node) {
+        FunctionInfo info = node.getFunctionInfo();
+        String ownerName = node.getOwner().getName();
+        ContextDependedClassWriter cw = classWriters.get(ownerName);
+        String returnType = new String(info.type.accept(this));
+
+        String descriptor = getDescriptor(node, 2, returnType);
+        currentMV = cw.visitMethod(asAccessFlags(info), info.name, descriptor, null, null);
+        locals.initFunctionArguments(info);
+        IRNode body = node.getChild(0);
+        body.accept(this);
+        IRNode ret = node.getChild(1);
+        ret.accept(this);
+        currentMV.visitMaxs(0, 0);
+        currentMV.visitEnd();
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(FunctionDefinitionBlock node) {
+        return iterateBlock(node);
+    }
+
+    @Override
+    public byte[] visit(FunctionRedefinition node) {
+        FunctionInfo info = node.getFunctionInfo();
+        String ownerName = node.getOwner().getName();
+        ContextDependedClassWriter cw = classWriters.get(ownerName);
+        String returnType = new String(info.type.accept(this));
+        String descriptor = getDescriptor(node, 2, returnType);
+        currentMV = cw.visitMethod(asAccessFlags(info), info.name, descriptor, null, null);
+        locals.initFunctionArguments(info);
+        IRNode body = node.getChild(0);
+        body.accept(this);
+        IRNode ret = node.getChild(1);
+        ret.accept(this);
+        currentMV.visitMaxs(0, 0);
+        currentMV.visitEnd();
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(FunctionRedefinitionBlock node) {
+        return iterateBlock(node);
+    }
+
+    @Override
+    public byte[] visit(If node) {
+        IRNode conditionBlock = node.getChild(If.IfPart.CONDITION.ordinal());
+        // get the condition type to emit correct if
+        conditionBlock.accept(this);
+        generateIf(Opcodes.IFEQ, node.getChild(If.IfPart.THEN.ordinal()),
+                node.getChild(If.IfPart.ELSE.ordinal()));
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    /*
+     * Generates if block with then and else blocks for the given IF opcode
+     */
+    private void generateIf(int ifOpcode, IRNode thenBlock, IRNode elseBlock) {
+        Label elseLabel = new Label();
+        // if the opposite condition is met then go to the else statement
+        currentMV.visitJumpInsn(ifOpcode, elseLabel);
+        // write THEN block
+        thenBlock.accept(this);
+        if (elseBlock != null) {
+            // goto the end after THEN
+            Label endLabel = new Label();
+            currentMV.visitJumpInsn(Opcodes.GOTO, endLabel);
+            // ELSE block
+            currentMV.visitLabel(elseLabel);
+            elseBlock.accept(this);
+            currentMV.visitLabel(endLabel);
+        } else {
+            currentMV.visitLabel(elseLabel);
+        }
+    }
+
+    @Override
+    public byte[] visit(Initialization node) {
+        VariableInfo vi = node.getVariableInfo();
+        if (vi.isLocal()) {
+            return visitLocalVar(node);
+        }
+        String ownerName = vi.getOwner().getName();
+        ContextDependedClassWriter cw = classWriters.get(ownerName);
+        String typeName = new String(vi.type.accept(this));
+        // constant value used only for final static fields
+        FieldVisitor fw = cw.visitField(asAccessFlags(vi), vi.name,
+                typeName,
+                null /* Generic */,
+                null /* Constant value */);
+        fw.visitEnd(); // doesn't need visitAnnotation and visitAttribute
+        if (vi.isStatic()) {
+            node.getChild(0).accept(this); // put value to stack
+            emitDup(vi.type);
+            currentMV.visitFieldInsn(Opcodes.PUTSTATIC,
+                    asInternalName(vi.getOwner().getName()),
+                    vi.name,
+                    new String(vi.type.accept(this)));
+        } else {
+            // TODO : can it be another object?
+            currentMV.visitVarInsn(Opcodes.ALOAD, 0); // put this to stack
+            node.getChild(0).accept(this); // put value to stack
+            emitDupX1(vi.type);
+            currentMV.visitFieldInsn(Opcodes.PUTFIELD,
+                    asInternalName(vi.getOwner().getName()),
+                    vi.name,
+                    new String(vi.type.accept(this)));
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    private void emitDupX1(Type type) {
+        if (TypeList.DOUBLE.equals(type) || TypeList.LONG.equals(type)) {
+            currentMV.visitInsn(Opcodes.DUP2_X1);
+        } else if (!TypeList.VOID.equals(type)){
+            currentMV.visitInsn(Opcodes.DUP_X1);
+        }
+    }
+
+    private void emitDup(Type type) {
+        if (TypeList.DOUBLE.equals(type) || TypeList.LONG.equals(type)) {
+            currentMV.visitInsn(Opcodes.DUP2);
+        } else if (!TypeList.VOID.equals(type)){
+            currentMV.visitInsn(Opcodes.DUP);
+        }
+    }
+
+    @Override
+    public byte[] visit(Interface node) {
+        String name = node.getName();
+        ContextDependedClassWriter classWriter = new ContextDependedClassWriter(context, CLASS_WRITER_FLAGS);
+        classWriters.put(name, classWriter);
+        TypeKlass parentKlass = node.getParentKlass();
+        classWriter.visit(Opcodes.V1_8,
+                          Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE,
+                          asInternalName(name),
+                          null /* Generic */,
+                          "java/lang/Object",
+                          parentKlass == null ? null : new String[] {
+                                  asInternalName(parentKlass.getName())});
+        if (node.getChildren().size() > 0) {
+            node.getChild(0).accept(this);
+        }
+
+        classWriter.visitEnd();
+        byte[] byteCode = classWriter.toByteArray();
+        context.register(name, byteCode);
+        return byteCode;
+    }
+
+    @Override
+    public byte[] visit(Klass node) {
+        String name = node.getName();
+        TypeKlass prevClass = currentClass;
+        currentClass = node.getThisKlass();
+        ContextDependedClassWriter classWriter = new ContextDependedClassWriter(context, CLASS_WRITER_FLAGS);
+        classWriters.put(name, classWriter);
+        TypeKlass thisClass = node.getThisKlass();
+        TypeKlass parentClass = node.getParentKlass();
+        String[] interfaces = node.getInterfaces().stream()
+                .map(IRNode::getName)
+                .map(ByteCodeVisitor::asInternalName)
+                .toArray(String[]::new);
+        classWriter.visit(Opcodes.V1_8, asAccessFlags(thisClass),
+                asInternalName(name),
+                null /* Generic */,
+                parentClass != null ? asInternalName(parentClass.getName()) : "java/lang/Object",
+                interfaces);
+
+        IRNode constructors = node.getChild(Klass.KlassPart.CONSTRUCTORS.ordinal());
+        if (constructors != null) {
+            constructors.accept(this);
+        } else {
+            // generate default ctor
+            currentMV = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+            currentMV.visitVarInsn(Opcodes.ALOAD, 0);
+            currentMV.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+            locals.clear();
+            locals.addLocal(new VariableInfo("this", thisClass, thisClass, VariableInfo.NONE));
+            generateDataMembers(node.getChild(Klass.KlassPart.DATA_MEMBERS.ordinal()));
+            currentMV.visitInsn(Opcodes.RETURN);
+            currentMV.visitMaxs(0, 0);
+            currentMV.visitEnd();
+        }
+        IRNode redefinedFunctions = node.getChild(Klass.KlassPart.REDEFINED_FUNCTIONS.ordinal());
+        if (redefinedFunctions != null) {
+            redefinedFunctions.accept(this);
+        }
+        IRNode overridenFunctions = node.getChild(Klass.KlassPart.OVERRIDEN_FUNCTIONS.ordinal());
+        if (overridenFunctions != null) {
+            overridenFunctions.accept(this);
+        }
+        IRNode memberFunctions = node.getChild(Klass.KlassPart.MEMBER_FUNCTIONS.ordinal());
+        if (memberFunctions != null) {
+            memberFunctions.accept(this);
+        }
+        IRNode memberFunctionDecls = node.getChild(Klass.KlassPart.MEMBER_FUNCTIONS_DECLARATIONS.ordinal());
+        if (memberFunctionDecls != null) {
+            memberFunctionDecls.accept(this);
+        }
+        IRNode printVariables = node.getChild(Klass.KlassPart.PRINT_VARIABLES.ordinal());
+        if (printVariables != null) {
+            printVariables.accept(this);
+        }
+        classWriter.visitEnd();
+        byte[] byteCode = classWriter.toByteArray();
+        context.register(name, byteCode);
+        currentClass = prevClass;
+        return byteCode;
+    }
+
+    private void visitLiteral(boolean value) {
+        double chance = PseudoRandom.random();
+        if (chance < CONSTANT_INST_CHANCE) {
+            currentMV.visitInsn(value ? Opcodes.ICONST_1 : Opcodes.ICONST_0);
+        } else {
+            currentMV.visitIntInsn(Opcodes.BIPUSH, value ? 1 : 0);
+        }
+    }
+
+    private void visitLiteral(byte value) {
+        double chance = PseudoRandom.random();
+        if (chance < CONSTANT_INST_CHANCE && value > -2 && value < 6) {
+            currentMV.visitInsn(Opcodes.ICONST_0 + value);
+        } else {
+            currentMV.visitIntInsn(Opcodes.BIPUSH, value);
+        }
+    }
+
+    private void visitLiteral(short value) {
+        double chance = PseudoRandom.random();
+        if (chance < CONSTANT_INST_CHANCE && value > -2 && value < 6) {
+            currentMV.visitInsn(Opcodes.ICONST_0 + value);
+        } else {
+            currentMV.visitIntInsn(Opcodes.SIPUSH, value);
+        }
+    }
+
+    private void visitLiteral(char value) {
+        double chance = PseudoRandom.random();
+        if (chance < CONSTANT_INST_CHANCE && value < 6) {
+            currentMV.visitInsn(Opcodes.ICONST_0 + value);
+        } else {
+            // TODO : check for widechar/unicode
+            currentMV.visitIntInsn(Opcodes.BIPUSH, value);
+        }
+    }
+
+    private void visitLiteral(int value) {
+        double chance = PseudoRandom.random();
+        if (chance < CONSTANT_INST_CHANCE && value > -2 && value < 6) {
+            currentMV.visitInsn(Opcodes.ICONST_0 + value);
+        } else {
+            currentMV.visitLdcInsn(value);
+        }
+    }
+
+    private void visitLiteral(long value) {
+        double chance = PseudoRandom.random();
+        if (chance < CONSTANT_INST_CHANCE && value > -1 && value < 2) {
+            currentMV.visitInsn(Opcodes.LCONST_0 + (int)value);
+        } else {
+            currentMV.visitLdcInsn(value);
+        }
+    }
+
+    private void visitLiteral(float value) {
+        double chance = PseudoRandom.random();
+        if (chance < CONSTANT_INST_CHANCE && (value == 0.0f || value == 1.0f || value == 2.0f)) {
+            currentMV.visitInsn(Opcodes.FCONST_0 + (int)value);
+        } else {
+            currentMV.visitLdcInsn(value);
+        }
+    }
+
+    private void visitLiteral(double value) {
+        double chance = PseudoRandom.random();
+        if (chance < CONSTANT_INST_CHANCE && (value == 0.0 || value == 1.0)) {
+            currentMV.visitInsn(Opcodes.DCONST_0 + (int)value);
+        } else {
+            currentMV.visitLdcInsn(value);
+        }
+    }
+
+    @Override
+    public byte[] visit(Literal node) {
+        /*
+            ICONST_n (−1 ≤ n ≤ 5) <==> BIPUSH <n>
+            LCONST_n (0 ≤ n ≤ 1)
+            FCONST_n (0 ≤ n ≤ 2)
+            DCONST_n (0 ≤ n ≤ 1)
+            ACONST_NULL
+
+            BIPUSH b, −128 ≤ b < 127
+            SIPUSH s, −32768 ≤ s < 32767
+            LDC cst (int, float, long, double, String or Type)
+        */
+        Type type = node.getResultType();
+        double chance = PseudoRandom.random();
+        if (type.equals(TypeList.BOOLEAN)) {
+            visitLiteral(Boolean.valueOf(node.getValue().toString()));
+        } else if (type.equals(TypeList.BYTE)) {
+            visitLiteral(Byte.valueOf(node.getValue().toString()));
+        } else if (type.equals(TypeList.SHORT)) {
+            visitLiteral(Short.valueOf(node.getValue().toString()));
+        } else if (type.equals(TypeList.CHAR)) {
+            visitLiteral(node.getValue().toString().charAt(0));
+        } else if (type.equals(TypeList.INT)) {
+            visitLiteral(Integer.valueOf(node.getValue().toString()));
+        } else if (type.equals(TypeList.LONG)) {
+            visitLiteral(Long.valueOf(node.getValue().toString()));
+        } else if (type.equals(TypeList.FLOAT)) {
+            visitLiteral(Float.valueOf(node.getValue().toString()));
+        } else if (type.equals(TypeList.DOUBLE)) {
+            visitLiteral(Double.valueOf(node.getValue().toString()));
+        } else {
+            currentMV.visitLdcInsn(node.getValue());
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+    private static final double CONSTANT_INST_CHANCE = 0.5;
+
+    @Override
+    public byte[] visit(LocalVariable node) {
+        // This node is for "reading" only. Writing is handled in BinaryOperator visit(see ASSIGN)
+        VariableInfo vi = node.getVariableInfo();
+        Type varType = vi.type;
+        int index = locals.getLocalIndex(vi);
+        if (varType.equals(TypeList.LONG)) {
+            currentMV.visitVarInsn(Opcodes.LLOAD, index);
+        } else if (varType.equals(TypeList.DOUBLE)) {
+            currentMV.visitVarInsn(Opcodes.DLOAD, index);
+        } else if (varType.equals(TypeList.FLOAT)) {
+            currentMV.visitVarInsn(Opcodes.FLOAD, index);
+        } else if (varType instanceof TypeKlass) {
+            currentMV.visitVarInsn(Opcodes.ALOAD, index);
+        } else {
+            currentMV.visitVarInsn(Opcodes.ILOAD, index);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(LoopingCondition node) {
+        return node.getCondition().accept(this);
+    }
+
+    @Override
+    public byte[] visit(MainKlass node) {
+        TypeKlass prevClass = currentClass;
+        currentClass = node.getThisKlass();
+        String name = node.getName();
+        ContextDependedClassWriter mainClassWriter = new ContextDependedClassWriter(context, CLASS_WRITER_FLAGS);
+        classWriters.put(name, mainClassWriter);
+
+        TypeKlass thisClass = node.getThisKlass();
+        mainClassWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC,
+                asInternalName(name),
+                null /* Generic */,
+                "java/lang/Object",
+                null /* interfaces */);
+        // TODO: constructor for main class
+        currentMV = mainClassWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
+        currentMV.visitVarInsn(Opcodes.ALOAD, 0);
+        currentMV.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+        locals.clear();
+        locals.addLocal(new VariableInfo("this", thisClass, thisClass, VariableInfo.NONE));
+        generateDataMembers(node.getChild(MainKlass.MainKlassPart.DATA_MEMBERS.ordinal()));
+        currentMV.visitInsn(Opcodes.RETURN);
+        currentMV.visitMaxs(0, 0);
+        currentMV.visitEnd();
+
+        IRNode memberFunctions = node.getChild(MainKlass.MainKlassPart.MEMBER_FUNCTIONS.ordinal());
+        if (memberFunctions != null) {
+            memberFunctions.accept(this);
+        }
+        IRNode testFunction = node.getChild(MainKlass.MainKlassPart.TEST_FUNCTION.ordinal());
+        if (testFunction != null) {
+            currentMV = mainClassWriter.visitMethod(
+                    Opcodes.ACC_PRIVATE,
+                    "test",
+                    "()V",
+                    null,
+                    null);
+            locals.clear();
+            locals.addLocal(new VariableInfo("this", thisClass, thisClass, VariableInfo.NONE));
+            testFunction.accept(this);
+            currentMV.visitInsn(Opcodes.RETURN);
+            currentMV.visitMaxs(0, 0);
+            currentMV.visitEnd();
+        }
+        IRNode printVariables = node.getChild(MainKlass.MainKlassPart.PRINT_VARIABLES.ordinal());
+        if (printVariables != null) {
+            printVariables.accept(this);
+        }
+
+        mainClassWriter.visitEnd();
+
+        byte[] byteCode = mainClassWriter.toByteArray();
+        context.register(name, byteCode);
+        currentClass = prevClass;
+        return byteCode;
+    }
+
+    @Override
+    public byte[] visit(NonStaticMemberVariable node) {
+        // This node is for "reading" only. Writing is handled in BinaryOperator visit(see ASSIGN)
+        VariableInfo vi = node.getVariableInfo();
+        // put object to stack
+        node.getChild(0).accept(this);
+        currentMV.visitFieldInsn(Opcodes.GETFIELD, asInternalName(vi.getOwner().getName()), vi.name,
+                new String(vi.type.accept(this)));
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(Nothing node) {
+        // TODO : add randomness
+        currentMV.visitInsn(Opcodes.NOP);
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(PrintVariables node) {
+        return FixedTrees.printVariablesAsFunction(node).accept(this);
+    }
+
+    @Override
+    public byte[] visit(Return node) {
+        node.getExpression().accept(this);
+        Type result = node.getResultType();
+        if (result instanceof TypeKlass) {
+            currentMV.visitInsn(Opcodes.ARETURN);
+        } else if (result.equals(TypeList.VOID)) {
+            currentMV.visitInsn(Opcodes.RETURN);
+        } else if (result.equals(TypeList.DOUBLE)) {
+            currentMV.visitInsn(Opcodes.DRETURN);
+        } else if (result.equals(TypeList.FLOAT)) {
+            currentMV.visitInsn(Opcodes.FRETURN);
+        } else if (result.equals(TypeList.LONG)) {
+            currentMV.visitInsn(Opcodes.LRETURN);
+        } else {
+            currentMV.visitInsn(Opcodes.IRETURN);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(Statement node) {
+        IRNode child = node.getChild(0);
+        child.accept(this);
+        Type resultType = child.getResultType();
+        emitPop(resultType);
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    private void emitPop(Type resultType) {
+        if (resultType.equals(TypeList.LONG) || resultType.equals(TypeList.DOUBLE)) {
+            currentMV.visitInsn(Opcodes.POP2);
+        } else if (!resultType.equals(TypeList.VOID)) {
+            currentMV.visitInsn(Opcodes.POP);
+        }
+    }
+
+    @Override
+    public byte[] visit(StaticConstructorDefinition node) {
+        String ownerName = node.getOwner().getName();
+        ContextDependedClassWriter cw = classWriters.get(ownerName);
+        String descriptor = getDescriptor(node, 1, "V");
+        currentMV = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", descriptor, null, null);
+        locals.clear();
+        IRNode body = node.getChild(0);
+        body.accept(this);
+        currentMV.visitInsn(Opcodes.RETURN);
+        currentMV.visitMaxs(0, 0);
+        currentMV.visitEnd();
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(StaticMemberVariable node) {
+        // This node is for "reading" only. Writing is handled in BinaryOperator visit(see ASSIGN)
+        VariableInfo vi = node.getVariableInfo();
+        currentMV.visitFieldInsn(Opcodes.GETSTATIC,
+                asInternalName(vi.getOwner().getName()),
+                vi.name,
+                new String(vi.type.accept(this)));
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(Switch node) {
+        node.getChild(0).accept(this);
+        int caseBlockIdx = node.getCaseBlockIndex();
+        Label defaultCase = new Label();
+        IRNode defaultBlock = null;
+        SortedMap<Integer, Pair<Label, IRNode>> cases = new TreeMap<>();
+        for (int i = 0; i < caseBlockIdx - 1; ++i) {
+            if (node.getChild(i + 1) instanceof Nothing) {
+                defaultBlock = node.getChild(i + caseBlockIdx);
+            } else {
+                Literal literal = (Literal) node.getChild(i + 1);
+                int value = 0;
+                if (literal.value instanceof Integer) {
+                    value = (Integer) literal.value;
+                } else if (literal.value instanceof Short) {
+                    value = (Short) literal.value;
+                } else if (literal.value instanceof Byte) {
+                    value = (Byte) literal.value;
+                } else if (literal.value instanceof Character) {
+                    value = (Character) literal.value;
+                }
+                cases.put(value, new Pair<>(new Label(), node.getChild(i + caseBlockIdx)));
+            }
+        }
+        Label breakLabel = new Label();
+        endLabels.push(breakLabel);
+        currentMV.visitLookupSwitchInsn(defaultCase,
+                cases.keySet().stream()
+                        .mapToInt(Integer::intValue)
+                        .toArray(),
+                cases.values().stream()
+                        .map(p -> p.first)
+                        .toArray(Label[]::new));
+        for (Pair<Label, IRNode> p : cases.values()) {
+            currentMV.visitLabel(p.first);
+            p.second.accept(this);
+        }
+        currentMV.visitLabel(defaultCase);
+        if (defaultBlock != null) {
+            defaultBlock.accept(this);
+        }
+        Label a = endLabels.pop();
+        assert breakLabel == a;
+        currentMV.visitLabel(breakLabel);
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(TernaryOperator node) {
+        IRNode conditionBlock = node.getChild(TernaryOperator.TernaryPart.CONDITION.ordinal());
+        // get the condition type to emit correct if
+        conditionBlock.accept(this);
+        generateIf(Opcodes.IFEQ, node.getChild(TernaryOperator.TernaryPart.TRUE.ordinal()),
+                node.getChild(TernaryOperator.TernaryPart.FALSE.ordinal()));
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(Throw node) {
+        node.getThowable().accept(this);
+        currentMV.visitInsn(Opcodes.ATHROW);
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(TryCatchBlock node) {
+        List<? extends IRNode> children = node.getChildren();
+        IRNode tryBlock = children.get(0);
+        IRNode finallyBlock = children.get(1);
+        Label tryStart = new Label();
+        Label tryEnd = new Label();
+        Label finallyStart = new Label();
+        Label finallyEnd = new Label();
+
+        currentMV.visitLabel(tryStart);
+        tryBlock.accept(this);
+        currentMV.visitLabel(tryEnd);
+        finallyBlock.accept(this);
+        currentMV.visitJumpInsn(Opcodes.GOTO, finallyEnd);
+        VariableInfo exInfo = new VariableInfo("ex", currentClass,
+                new TypeKlass("java.lang.Throwable"), VariableInfo.LOCAL);
+        int index = locals.addLocal(exInfo);
+        for (int i = 2; i < children.size(); ++i) {
+            Label handlerBegin = new Label();
+            Label handlerEnd = new Label();
+            CatchBlock catchBlock = (CatchBlock) children.get(i);
+            for (Type t : catchBlock.throwables) {
+                currentMV.visitTryCatchBlock(tryStart, tryEnd, handlerBegin, asInternalName(t.getName()));
+            }
+            currentMV.visitLabel(handlerBegin);
+            catchBlock.accept(this);
+            currentMV.visitLabel(handlerEnd);
+            finallyBlock.accept(this);
+            currentMV.visitJumpInsn(Opcodes.GOTO, finallyEnd);
+            currentMV.visitTryCatchBlock(handlerBegin, handlerEnd, finallyStart, null);
+        }
+
+        currentMV.visitTryCatchBlock(tryStart, tryEnd, finallyStart, null);
+        currentMV.visitLabel(finallyStart);
+        currentMV.visitVarInsn(Opcodes.ASTORE, index);
+        finallyBlock.accept(this);
+        currentMV.visitVarInsn(Opcodes.ALOAD, index);
+        currentMV.visitInsn(Opcodes.ATHROW);
+        currentMV.visitLabel(finallyEnd);
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(Type node) {
+        String name;
+        if (TypeList.isBuiltIn(node)) {
+            switch (node.getName()) {
+                case "void":
+                    name = "V";
+                    break;
+                case "boolean":
+                    name = "Z";
+                    break;
+                case "byte":
+                    name = "B";
+                    break;
+                case "char":
+                    name = "C";
+                    break;
+                case "short":
+                    name = "S";
+                    break;
+                case "int":
+                    name = "I";
+                    break;
+                case "long":
+                    name = "J";
+                    break;
+                case "float":
+                    name = "F";
+                    break;
+                case "double":
+                    name = "D";
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unknown type '" + node.getName());
+            }
+        } else {
+            name = "L" + asInternalName(node.getName()) + ";";
+        }
+        return name.getBytes();
+    }
+
+    @Override
+    public byte[] visit(TypeArray node) {
+        String name;
+        String prefix = Stream.generate(() -> "[")
+                .limit(node.dimensions)
+                .collect(Collectors.joining());
+        name = prefix + new String(node.getType().accept(this));
+        return name.getBytes();
+    }
+
+    @Override
+    public byte[] visit(UnaryOperator node) {
+        OperatorKind opKind = node.getOperationKind();
+        IRNode exp = node.getChild(0);
+        // argument expression is handled separately for inc and dec operators
+        if (opKind != OperatorKind.POST_DEC && opKind != OperatorKind.POST_INC
+                && opKind != OperatorKind.PRE_DEC && opKind != OperatorKind.PRE_INC) {
+            exp.accept(this);
+        }
+        Type resultType = exp.getResultType();
+        switch (opKind) {
+            case NOT:
+                Label retTrueForNot = new Label();
+                Label endForNot = new Label();
+                currentMV.visitJumpInsn(Opcodes.IFEQ, retTrueForNot);
+                currentMV.visitInsn(Opcodes.ICONST_0);
+                currentMV.visitJumpInsn(Opcodes.GOTO, endForNot);
+                currentMV.visitLabel(retTrueForNot);
+                currentMV.visitInsn(Opcodes.ICONST_1);
+                currentMV.visitLabel(endForNot);
+                break;
+            case BIT_NOT:
+                if (resultType.equals(TypeList.LONG)) {
+                    currentMV.visitLdcInsn(-1L);
+                    currentMV.visitInsn(Opcodes.LXOR);
+                } else {
+                    currentMV.visitInsn(Opcodes.ICONST_M1);
+                    currentMV.visitInsn(Opcodes.IXOR);
+                }
+                break;
+            case UNARY_MINUS:
+                if (resultType.equals(TypeList.LONG)) {
+                    currentMV.visitInsn(Opcodes.LNEG);
+                } else if (resultType.equals(TypeList.FLOAT)) {
+                    currentMV.visitInsn(Opcodes.FNEG);
+                } else if (resultType.equals(TypeList.DOUBLE)) {
+                    currentMV.visitInsn(Opcodes.DNEG);
+                } else {
+                    currentMV.visitInsn(Opcodes.INEG);
+                }
+                break;
+            case UNARY_PLUS:
+                break;
+            case PRE_DEC:
+                lowerIncDecUnaryOperator(OperatorKind.SUB, true, node);
+                break;
+            case POST_DEC:
+                lowerIncDecUnaryOperator(OperatorKind.SUB, false, node);
+                break;
+            case PRE_INC:
+                lowerIncDecUnaryOperator(OperatorKind.ADD, true, node);
+                break;
+            case POST_INC:
+                lowerIncDecUnaryOperator(OperatorKind.ADD, false, node);
+                break;
+            default:
+                throw new RuntimeException("Incorrect unary operator: " + opKind);
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    private void lowerIncDecUnaryOperator(OperatorKind kind, boolean isPrefix, IRNode node) {
+        IRNode var = node.getChild(0);
+        Literal one;
+        Type resultType = node.getResultType();
+        if (resultType.equals(TypeList.LONG)) {
+            one = new Literal(1L, TypeList.LONG);
+        } else if (resultType.equals(TypeList.INT)) {
+            one = new Literal(1, TypeList.INT);
+        } else if (resultType.equals(TypeList.SHORT)) {
+            one = new Literal((short) 1, TypeList.SHORT);
+        } else {
+            one = new Literal((byte) 1, TypeList.BYTE);
+        }
+        if (var instanceof NonStaticMemberVariable) {
+            IRNode holder = var.getChild(0);
+            Type type = holder.getResultType();
+            VariableInfo tmpInfo = new VariableInfo("tmpObject_" + tmpObject++,
+                    currentClass, type, VariableInfo.LOCAL);
+            new Statement(new VariableInitialization(tmpInfo, holder), true).accept(this);
+            var = new NonStaticMemberVariable(new LocalVariable(tmpInfo),
+                    ((NonStaticMemberVariable) var).getVariableInfo());
+        }
+        BinaryOperator calculation = new BinaryOperator(kind, resultType, var, one);
+        BinaryOperator changeValue = new BinaryOperator(OperatorKind.ASSIGN, resultType, var, calculation);
+        Statement finalChangeStatement = new Statement(changeValue, true);
+        if (isPrefix) {
+            finalChangeStatement.accept(this);
+            var.accept(this);
+        } else {
+            var.accept(this);
+            finalChangeStatement.accept(this);
+        }
+    }
+
+    @Override
+    public byte[] visit(VariableDeclaration node) {
+        VariableInfo vi = node.getVariableInfo();
+        String ownerName = vi.getOwner().getName();
+        ContextDependedClassWriter cw = classWriters.get(ownerName);
+        String typeName = new String(vi.type.accept(this));
+        if (vi.isLocal()) {
+            locals.addLocal(vi);
+        } else {
+            FieldVisitor fv = cw.visitField(asAccessFlags(vi),
+                    vi.name,
+                    typeName,
+                    null /* Generic */,
+                    null /* Constant value */);
+            fv.visitEnd(); // doesn't need visitAnnotation and visitAttribute
+        }
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    @Override
+    public byte[] visit(VariableDeclarationBlock node) {
+        return iterateBlock(node);
+    }
+
+    @Override
+    public byte[] visit(While node) {
+        Loop loop = node.getLoop();
+        loop.initialization.accept(this);
+        node.getChild(While.WhilePart.HEADER.ordinal()).accept(this);
+        Label currentLoopBegin = new Label();
+        beginLabels.push(currentLoopBegin);
+        currentMV.visitLabel(currentLoopBegin);
+        loop.condition.accept(this);
+        assert loop.condition.getResultType() == TypeList.BOOLEAN;
+        Label currentLoopEnd = new Label();
+        endLabels.push(currentLoopEnd);
+        currentMV.visitJumpInsn(Opcodes.IFEQ, currentLoopEnd);
+        node.getChild(While.WhilePart.BODY1.ordinal()).accept(this);
+        loop.manipulator.accept(this);
+        node.getChild(While.WhilePart.BODY2.ordinal()).accept(this);
+        node.getChild(While.WhilePart.BODY3.ordinal()).accept(this);
+        currentMV.visitJumpInsn(Opcodes.GOTO, currentLoopBegin);
+        currentMV.visitLabel(currentLoopEnd);
+        Label a = beginLabels.pop();
+        assert currentLoopBegin == a;
+        a = endLabels.pop();
+        assert currentLoopEnd == a;
+        return EMPTY_BYTE_ARRAY;
+    }
+
+    public byte[] getByteCode(String name) {
+        return context.get(name);
+    }
+
+    private static byte[] concat(byte[] a, byte[] b) {
+        byte[] r = new byte[a.length + b.length];
+        System.arraycopy(a, 0, r, 0, a.length);
+        System.arraycopy(b, 0, r, a.length, b.length);
+        return r;
+    }
+
+    private String argTypeToString(ArgumentDeclaration declarations) {
+        return new String(declarations.variableInfo.type.accept(this));
+    }
+
+    private byte[] iterateBlock(IRNode node) {
+        return node.getChildren().stream()
+                .map(ch -> ch.accept(this))
+                .reduce(new byte[0], ByteCodeVisitor::concat);
+    }
+
+    private String getDescriptor(IRNode node, int skipChilds, String returnType) {
+        return node.getChildren().stream()
+                .skip(skipChilds)
+                .map(c -> argTypeToString((ArgumentDeclaration)c))
+                .collect(Collectors.joining("", "(", ")" + returnType));
+    }
+
+    private static String asInternalName(String type) {
+        return type.replace('.', '/');
+    }
+
+    private static int asAccessFlags(TypeKlass klass) {
+        int attr = Opcodes.ACC_SUPER;
+        attr |= klass.isFinal() ? Opcodes.ACC_FINAL : 0;
+        attr |= klass.isAbstract() ? Opcodes.ACC_ABSTRACT : 0;
+        attr |= klass.isInterface() ? Opcodes.ACC_INTERFACE : 0;
+
+        return attr;
+    }
+
+    private static int asAccessFlags(FunctionInfo fi) {
+        int result = asAccessFlags((Symbol) fi);
+        result |= ProductionParams.enableStrictFP.value() ? Opcodes.ACC_STRICT : 0;
+        result |= fi.isSynchronized() ? Opcodes.ACC_SYNCHRONIZED : 0;
+        return result;
+    }
+
+    private static int asAccessFlags(Symbol s) {
+        int attr = 0;
+        attr |= s.isPublic() ? Opcodes.ACC_PUBLIC : 0;
+        attr |= s.isPrivate() ? Opcodes.ACC_PRIVATE : 0;
+        attr |= s.isProtected() ? Opcodes.ACC_PROTECTED : 0;
+        attr |= s.isStatic() ? Opcodes.ACC_STATIC : 0;
+        attr |= s.isFinal() ? Opcodes.ACC_FINAL : 0;
+
+        return attr;
+    }
+
+    private static class LocalVariablesTable {
+        private int nextLocalIndex = 0;
+        // a map keeping local variable table index for a local variable
+        private final HashMap<String, Integer> locals = new HashMap<>();
+
+        public int addLocal(VariableInfo vi) {
+            int indexToReturn = nextLocalIndex;
+            locals.put(vi.name, nextLocalIndex++);
+            if (vi.type.equals(TypeList.DOUBLE) || vi.type.equals(TypeList.LONG)) {
+                nextLocalIndex++;
+            }
+            return indexToReturn;
+        }
+
+        public int getLocalIndex(VariableInfo vi) {
+            if (!locals.containsKey(vi.name)) {
+                throw new NoSuchElementException(vi.name);
+            }
+            return locals.get(vi.name);
+        }
+
+        public void clear() {
+            locals.clear();
+            nextLocalIndex = 0;
+        }
+
+        public void initFunctionArguments(FunctionInfo info) {
+            initArguments(null, info);
+        }
+
+        public void initConstructorArguments(TypeKlass owner, FunctionInfo info) {
+            Objects.requireNonNull(owner, "owner is null");
+            initArguments(owner, info);
+        }
+
+        private void initArguments(TypeKlass owner, FunctionInfo info) {
+            clear();
+            if (owner != null) {
+                addLocal(new VariableInfo("this", owner, owner, VariableInfo.LOCAL | VariableInfo.INITIALIZED));
+            }
+            for (VariableInfo vi : info.argTypes) {
+                addLocal(vi);
+            }
+        }
+    }
+
+    private static class GeneratedClassesContext extends java.lang.ClassLoader {
+        private final HashMap<String, byte[]> byteCodes = new HashMap<>();
+
+        public void register(String name, byte[] bytecode) {
+            defineClass(name, bytecode, 0, bytecode.length);
+            byteCodes.put(name, bytecode);
+        }
+
+        public byte[] get(String name) {
+            return byteCodes.get(name);
+        }
+    }
+
+
+    private static class ContextDependedClassWriter extends ClassWriter {
+        private final GeneratedClassesContext context;
+
+        public ContextDependedClassWriter(GeneratedClassesContext context, int flags) {
+            super(flags);
+            this.context = context;
+        }
+
+        protected String getCommonSuperClass(String className1, String className2) {
+            Class<?> klass1;
+            Class<?> klass2;
+            try {
+                klass1 = Class.forName(className1.replace('/', '.'), false, context);
+                klass2 = Class.forName(className2.replace('/', '.'), false, context);
+            } catch (ClassNotFoundException e) {
+                throw new Error("can not get common supper for " + className1
+                                + " and " + className2, e);
+            }
+
+            if (klass1.isAssignableFrom(klass2)) {
+                return className1;
+            } else if (klass2.isAssignableFrom(klass1)) {
+                return className2;
+            } else if (!klass1.isInterface() && !klass2.isInterface()) {
+                do {
+                    klass1 = klass1.getSuperclass();
+                } while (!klass1.isAssignableFrom(klass2));
+
+                return asInternalName(className1);
+            } else {
+                return "java/lang/Object";
+            }
+        }
+    }
+}
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/visitors/JavaCodeVisitor.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/visitors/JavaCodeVisitor.java	Fri May 20 18:05:09 2016 +0300
@@ -23,8 +23,6 @@
 
 package jdk.test.lib.jittester.visitors;
 
-import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Objects;
@@ -41,10 +39,10 @@
 import jdk.test.lib.jittester.Initialization;
 import jdk.test.lib.jittester.Literal;
 import jdk.test.lib.jittester.LocalVariable;
-import jdk.test.lib.jittester.LogicOperator;
 import jdk.test.lib.jittester.NonStaticMemberVariable;
 import jdk.test.lib.jittester.Nothing;
 import jdk.test.lib.jittester.Operator;
+import jdk.test.lib.jittester.OperatorKind;
 import jdk.test.lib.jittester.PrintVariables;
 import jdk.test.lib.jittester.ProductionParams;
 import jdk.test.lib.jittester.Statement;
@@ -89,13 +87,8 @@
 import jdk.test.lib.jittester.loops.LoopingCondition;
 import jdk.test.lib.jittester.loops.While;
 import jdk.test.lib.jittester.types.TypeArray;
-import jdk.test.lib.jittester.types.TypeByte;
 import jdk.test.lib.jittester.types.TypeKlass;
-import jdk.test.lib.jittester.types.TypeChar;
-import jdk.test.lib.jittester.types.TypeDouble;
-import jdk.test.lib.jittester.types.TypeFloat;
-import jdk.test.lib.jittester.types.TypeLong;
-import jdk.test.lib.jittester.types.TypeShort;
+import jdk.test.lib.jittester.utils.FixedTrees;
 import jdk.test.lib.jittester.utils.PrintingUtils;
 
 public class JavaCodeVisitor implements Visitor<String> {
@@ -128,7 +121,91 @@
         return attrs;
     }
 
-    public String expressionToJavaCode(Operator t, IRNode p, Operator.Order o) {
+    private String operatorToJaveCode(OperatorKind operationKind) {
+       switch (operationKind) {
+           case COMPOUND_ADD:
+               return  "+=";
+           case COMPOUND_SUB:
+               return "-=";
+           case COMPOUND_MUL:
+               return "*=";
+           case COMPOUND_DIV:
+               return "/=";
+           case COMPOUND_MOD:
+               return "%=";
+           case COMPOUND_AND:
+               return "&=";
+           case COMPOUND_OR:
+               return "|=";
+           case COMPOUND_XOR:
+               return "^=";
+           case COMPOUND_SHR:
+               return ">>=";
+           case COMPOUND_SHL:
+               return "<<=";
+           case COMPOUND_SAR:
+               return ">>>=";
+           case ASSIGN:
+               return "=";
+           case OR:
+               return "||";
+           case BIT_OR:
+               return "|";
+           case BIT_XOR:
+               return "^";
+           case AND:
+               return "&&";
+           case BIT_AND:
+               return "&";
+           case EQ:
+               return "==";
+           case NE:
+               return "!=";
+           case GT:
+               return ">";
+           case LT:
+               return "<";
+           case GE:
+               return ">=";
+           case LE:
+               return "<=";
+           case SHR:
+               return ">>";
+           case SHL:
+               return "<<";
+           case SAR:
+               return ">>>";
+           case ADD:
+           case STRADD:
+               return "+";
+           case SUB:
+               return "-";
+           case MUL:
+               return "*";
+           case DIV:
+               return "/";
+           case MOD:
+               return "%";
+           case NOT:
+               return "!";
+           case BIT_NOT:
+               return "~";
+           case UNARY_PLUS:
+               return "+";
+           case UNARY_MINUS:
+               return "-";
+           case PRE_DEC:
+           case POST_DEC:
+               return "--";
+           case PRE_INC:
+           case POST_INC:
+               return "++";
+           default:
+               throw new IllegalArgumentException("Unkown operator kind " + operationKind);
+       }
+    }
+
+    private String expressionToJavaCode(Operator t, IRNode p, Operator.Order o) {
         String result;
         try {
             if ((o == Operator.Order.LEFT && ((Operator) p).getPriority() < t.getPriority())
@@ -151,8 +228,8 @@
 
     @Override
     public String visit(ArrayCreation node) {
-        Type arrayType = node.getArrayType();
-        String type = arrayType.accept(this);
+        Type arrayElemType = node.getArrayType().type;
+        String type = arrayElemType.accept(this);
         String name = node.getVariable().getName();
         StringBuilder code = new StringBuilder()
                 .append(node.getVariable().accept(this))
@@ -165,7 +242,7 @@
                 .map(p -> p.accept(this))
                 .collect(Collectors.joining("][", "[", "]")));
         code.append(";\n");
-        if (!TypeList.isBuiltIn(arrayType)) {
+        if (!TypeList.isBuiltIn(arrayElemType)) {
             code.append(PrintingUtils.align(node.getParent().getLevel()))
                 .append("java.util.Arrays.fill(")
                 .append(name)
@@ -220,7 +297,7 @@
             return "null";
         }
         return expressionToJavaCode(node, left, Operator.Order.LEFT)
-               + " " + node.getOperationCode() + " "
+               + " " + operatorToJaveCode(node.getOperationKind()) + " "
                + expressionToJavaCode(node, right, Operator.Order.RIGHT);
     }
 
@@ -320,7 +397,7 @@
 
     @Override
     public String visit(CounterInitializer node) {
-        VariableInfo vi = node.get();
+        VariableInfo vi = node.getVariableInfo();
         return vi.type.accept(this) + " " + vi.name + " = " + node.getChild(0).accept(this)+ ";";
     }
 
@@ -407,8 +484,8 @@
                 + ")";
         String prefix = "";
         if (value.isStatic()) {
-            if(!node.getKlass().equals(value.klass)) {
-                prefix = value.klass.getName() + ".";
+            if(!node.getOwner().equals(value.owner)) {
+                prefix = value.owner.getName() + ".";
             }
         } else if (value.isConstructor()) {
             prefix = "new ";
@@ -434,7 +511,7 @@
                 .collect(Collectors.joining(", "));
 
         FunctionInfo functionInfo = node.getFunctionInfo();
-        return (functionInfo.klass.isInterface() ? "" : "abstract ")
+        return (functionInfo.owner.isInterface() ? "" : "abstract ")
                 + funcAttributes(functionInfo) + functionInfo.type.accept(this)+ " "
                 + functionInfo.name + "(" + args + ");";
     }
@@ -464,7 +541,7 @@
                 + PrintingUtils.align(node.getLevel() + 1) + "{\n"
                 + body.accept(this)
                 + (ret != null ? PrintingUtils.align(node.getLevel() + 2) + ret.accept(this) + "\n" : "")
-                + PrintingUtils.align(node.getLevel() + 1) + "}";
+                + PrintingUtils.align(node.getLevel() + 1) + "}\n";
     }
 
     @Override
@@ -483,6 +560,7 @@
     @Override
     public String visit(FunctionRedefinition node) {
         String args = node.getChildren().stream()
+                .skip(2)
                 .map(c -> c.accept(this))
                 .collect(Collectors.joining(", "));
 
@@ -490,10 +568,10 @@
         IRNode ret = node.getChild(1);
         int level = node.getLevel();
         FunctionInfo functionInfo = node.getFunctionInfo();
-        return funcAttributes(functionInfo) + functionInfo.type + " " + functionInfo.name + "(" + args + ")" + "\n"
+        return funcAttributes(functionInfo) + functionInfo.type.accept(this) + " " + functionInfo.name + "(" + args + ")" + "\n"
                 + PrintingUtils.align(level + 1) + "{\n"
-                + body
-                + (ret != null ? PrintingUtils.align(level + 2) + ret + "\n" : "")
+                + body.accept(this)
+                + (ret != null ? PrintingUtils.align(level + 2) + ret.accept(this) + "\n" : "")
                 + PrintingUtils.align(level + 1) + "}";
     }
 
@@ -551,10 +629,11 @@
                 + (thisKlass.isFinal() ? "final " : "")
                 + (thisKlass.isAbstract() ? "abstract " : "")
                 + "class " + node.getName()
-                + (node.getParentKlass()!= null ? " extends " + node.getParentKlass().getName() : "");
+                + (node.getParentKlass() != null && !node.getParentKlass().equals(TypeList.OBJECT)
+                ? " extends " + node.getParentKlass().getName() : "");
         List<TypeKlass> interfaces = node.getInterfaces();
         r += interfaces.stream()
-                .map(c -> c.getName())
+                .map(Type::getName)
                 .collect(Collectors.joining(", ", (interfaces.isEmpty() ? "" : " implements "), ""));
         IRNode dataMembers = node.getChild(Klass.KlassPart.DATA_MEMBERS.ordinal());
         IRNode constructors = node.getChild(Klass.KlassPart.CONSTRUCTORS.ordinal());
@@ -570,10 +649,7 @@
              + (overridenFunctions != null ? (overridenFunctions.accept(this)+ "\n") : "")
              + (memberFunctionDecls != null ? (memberFunctionDecls.accept(this)+ "\n") : "")
              + (memberFunctions != null ? (memberFunctions.accept(this)+ "\n") : "")
-             + "    public String toString()\n"
-             + "    {\n"
              + printVariables.accept(this)
-             + "    }\n"
              + "}\n";
         return r;
     }
@@ -582,43 +658,42 @@
     public String visit(Literal node) {
         Type resultType = node.getResultType();
         Object value = node.getValue();
-        if (resultType.equals(new TypeLong())) {
+        if (resultType.equals(TypeList.LONG)) {
             return value.toString() + "L";
         }
-        if (resultType.equals(new TypeFloat())) {
+        if (resultType.equals(TypeList.FLOAT)) {
             return String.format((Locale) null,
-                "%." + ProductionParams.floatingPointPrecision.value() + "EF",
+                "%EF",
                 Double.parseDouble(value.toString()));
         }
-        if (resultType.equals(new TypeDouble())) {
+        if (resultType.equals(TypeList.DOUBLE)) {
             return String.format((Locale) null,
-                "%." + 2 * ProductionParams.floatingPointPrecision.value() + "E",
+                "%E",
                 Double.parseDouble(value.toString()));
         }
-        if (resultType.equals(new TypeChar())) {
-            if (((Character) value).charValue() == '\\') {
+        if (resultType.equals(TypeList.CHAR)) {
+            if ((Character) value == '\\') {
                 return "\'" + "\\\\" + "\'";
             } else {
                 return "\'" + value.toString() + "\'";
             }
         }
-        if (resultType.equals(new TypeShort())) {
+        if (resultType.equals(TypeList.SHORT)) {
             return "(short) " + value.toString();
         }
-        if (resultType.equals(new TypeByte())) {
+        if (resultType.equals(TypeList.BYTE)) {
             return "(byte) " + value.toString();
         }
+        if (resultType.equals(TypeList.STRING)) {
+            // TOOD handle other non-printable
+            return "\"" + value.toString().replace("\n", "\\n") + "\"";
+        }
         return value.toString();
     }
 
     @Override
     public String visit(LocalVariable node) {
-        return node.get().name;
-    }
-
-    @Override
-    public String visit(LogicOperator node) {
-        throw new UnsupportedOperationException("Not supported yet.");
+        return node.getVariableInfo().name;
     }
 
     @Override
@@ -633,182 +708,16 @@
         IRNode memberFunctions = node.getChild(MainKlass.MainKlassPart.MEMBER_FUNCTIONS.ordinal());
         IRNode testFunction = node.getChild(MainKlass.MainKlassPart.TEST_FUNCTION.ordinal());
         IRNode printVariables = node.getChild(MainKlass.MainKlassPart.PRINT_VARIABLES.ordinal());
-        String executeFunction = "    public static String execute()\n"
-                + "    {\n"
-                + "        try {\n"
-                + "            " + name + " t = new " + name + "();\n"
-                + "            try { t.test(); }\n"
-                + "            catch(Throwable e) { }\n"
-                + "            try { return t.toString(); }\n"
-                + "            catch (Throwable e) { return \"Error during result conversion to String\"; }\n"
-                + "        } catch (Throwable e) { return \"Error during test execution\"; }\n"
-                + "    }\n";
-        String mainFunction = "    public static void main(String[] args)\n"
-                + "    {\n"
-                + "        try {\n"
-                + "            " + name + " t = new " + name + "();\n"
-                + "            try {\n"
-                + "                for (int i = 0; i < 150000; ++i) {\n"
-                + "                    t.test();\n"
-                + "                }\n"
-                + "            }\n"
-                + "            catch(Throwable e) { e.printStackTrace(); }\n"
-                + "            try { System.out.println(t); }\n"
-                + "            catch(Throwable e) { e.printStackTrace();}\n"
-                + "        } catch (Throwable e) { e.printStackTrace(); }\n"
-                + "    }\n";
-        String printerClass = "    static class Printer\n"
-                + "    {\n"
-                + "        public static String print(boolean arg) { return String.valueOf(arg); }\n"
-                + "        public static String print(byte arg)    { return String.valueOf(arg); }\n"
-                + "        public static String print(short arg)   { return String.valueOf(arg); }\n"
-                + "        public static String print(char arg)    { return String.valueOf((int)arg); }\n"
-                + "        public static String print(int arg)     { return String.valueOf(arg); }\n"
-                + "        public static String print(long arg)    { return String.valueOf(arg); }\n"
-                + "        public static String print(float arg)   { return String.valueOf(arg); }\n"
-                + "        public static String print(double arg)  { return String.valueOf(arg); }\n"
-                + "\n"
-                + "\n"
-                + "        public static String print(Object arg)\n"
-                + "        {\n"
-                + "            return print_r(new java.util.Stack(), arg);\n"
-                + "        }\n"
-                + "\n"
-                + "        private static String print_r(java.util.Stack visitedObjects, Object arg)\n"
-                + "        {\n"
-                + "            String result = \"\";\n"
-                + "            if (arg == null)\n"
-                + "                result += \"null\";\n"
-                + "            else\n"
-                + "            if (arg.getClass().isArray())\n"
-                + "            {\n"
-                + "                for (int i = 0; i < visitedObjects.size(); i++)\n"
-                + "                    if (visitedObjects.elementAt(i) == arg) return \"<recursive>\";\n"
-                + "\n"
-                + "                visitedObjects.push(arg);\n"
-                + "\n"
-                + "                final String delimiter = \", \";\n"
-                + "                result += \"[\";\n"
-                + "\n"
-                + "                if (arg instanceof Object[])\n"
-                + "                {\n"
-                + "                    Object[] array = (Object[]) arg;\n"
-                + "                    for (int i = 0; i < array.length; i++)\n"
-                + "                    {\n"
-                + "                        result += print_r(visitedObjects, array[i]);\n"
-                + "                        if (i < array.length - 1) result += delimiter;\n"
-                + "                    }\n"
-                + "                }\n"
-                + "                else\n"
-                + "                if (arg instanceof boolean[])\n"
-                + "                {\n"
-                + "                    boolean[] array = (boolean[]) arg;\n"
-                + "                    for (int i = 0; i < array.length; i++)\n"
-                + "                    {\n"
-                + "                        result += print(array[i]);\n"
-                + "                        if (i < array.length - 1) result += delimiter;\n"
-                + "                    }\n"
-                + "                }\n"
-                + "                else\n"
-                + "                if (arg instanceof byte[])\n"
-                + "                {\n"
-                + "                    byte[] array = (byte[]) arg;\n"
-                + "                    for (int i = 0; i < array.length; i++)\n"
-                + "                    {\n"
-                + "                        result += print(array[i]);\n"
-                + "                        if (i < array.length - 1) result += delimiter;\n"
-                + "                    }\n"
-                + "                }\n"
-                + "                else\n"
-                + "                if (arg instanceof short[])\n"
-                + "                {\n"
-                + "                    short[] array = (short[]) arg;\n"
-                + "                    for (int i = 0; i < array.length; i++)\n"
-                + "                    {\n"
-                + "                        result += print(array[i]);\n"
-                + "                        if (i < array.length - 1) result += delimiter;\n"
-                + "                    }\n"
-                + "                }\n"
-                + "                else\n"
-                + "                if (arg instanceof char[])\n"
-                + "                {\n"
-                + "                    char[] array = (char[]) arg;\n"
-                + "                    for (int i = 0; i < array.length; i++)\n"
-                + "                    {\n"
-                + "                        result += print(array[i]);\n"
-                + "                        if (i < array.length - 1) result += delimiter;\n"
-                + "                    }\n"
-                + "                }\n"
-                + "                else\n"
-                + "                if (arg instanceof int[])\n"
-                + "                {\n"
-                + "                     int[] array = (int[]) arg;\n"
-                + "                     for (int i = 0; i < array.length; i++)\n"
-                + "                     {\n"
-                + "                        result += print(array[i]);\n"
-                + "                        if (i < array.length - 1) result += delimiter;\n"
-                + "                     }\n"
-                + "                }\n"
-                + "                else\n"
-                + "                if (arg instanceof long[])\n"
-                + "                {\n"
-                + "                    long[] array = (long[]) arg;\n"
-                + "                    for (int i = 0; i < array.length; i++)\n"
-                + "                    {\n"
-                + "                        result += print(array[i]);\n"
-                + "                        if (i < array.length - 1) result += delimiter;\n"
-                + "                    }\n"
-                + "                }\n"
-                + "                else\n"
-                + "                if (arg instanceof float[])\n"
-                + "                {\n"
-                + "                    float[] array = (float[]) arg;\n"
-                + "                    for (int i = 0; i < array.length; i++)\n"
-                + "                    {\n"
-                + "                        result += print(array[i]);\n"
-                + "                        if (i < array.length - 1) result += delimiter;\n"
-                + "                    }\n"
-                + "                }\n"
-                + "                else\n"
-                + "                if (arg instanceof double[])\n"
-                + "                {\n"
-                + "                    double[] array = (double[]) arg;\n"
-                + "                    for (int i = 0; i < array.length; i++)\n"
-                + "                    {\n"
-                + "                        result += print(array[i]);\n"
-                + "                        if (i < array.length - 1) result += delimiter;\n"
-                + "                    }\n"
-                + "                }\n"
-                + "\n"
-                + "                result += \"]\";\n"
-                + "                visitedObjects.pop();\n"
-                + "\n"
-                + "            } else\n"
-                + "            {\n"
-                + "                result += arg.toString();\n"
-                + "            }\n"
-                + "\n"
-                + "            return result;\n"
-                + "        }\n"
-                + "    }\n";
 
         return (ProductionParams.enableStrictFP.value() ? "strictfp " : "")
                 + "public class " + name + " {\n"
                 + dataMembers.accept(this)+ "\n"
                 + (memberFunctions != null ? memberFunctions.accept(this): "") + "\n"
-                + executeFunction
-                + "\n"
-                + mainFunction
-                + "\n"
                 + "    private void test()\n"
                 + "    {\n"
                 + testFunction.accept(this)
                 + "    }" + addComplexityInfo(testFunction) + "\n"
-                + "    public String toString()\n"
-                + "    {\n"
                 + printVariables.accept(this)
-                + "    }\n"
-                + printerClass
                 + "}\n\n";
     }
 
@@ -816,7 +725,7 @@
     public String visit(NonStaticMemberVariable node) {
         IRNode object = node.getChild(0);
         String objectString = object.accept(this);
-        VariableInfo value = node.getValue();
+        VariableInfo value = node.getVariableInfo();
         if (objectString.equals("this")) {
             return value.name;
         } else {
@@ -835,38 +744,7 @@
 
     @Override
     public String visit(PrintVariables node) {
-        int level = node.getLevel();
-        List<Symbol> vars = node.getVars();
-        StringBuilder result = new StringBuilder()
-                .append(PrintingUtils.align(level))
-                .append("String result =  \"[\\n\";\n");
-        if (!vars.isEmpty()) {
-            for (int i = 0; i < vars.size(); i++) {
-                Symbol v = vars.get(i);
-                result.append(PrintingUtils.align(level))
-                        .append("result += \"").append(v.klass.getName())
-                        .append(".")
-                        .append(v.name)
-                        .append(" = \"; ")
-                        .append("result += ")
-                        .append(node.getPrinterName())
-                        .append(".print(")
-                        .append(v.name)
-                        .append(");\n")
-                        .append(PrintingUtils.align(level));
-                if (i < vars.size() - 1) {
-                    result.append("result += \"\\n\";");
-                } else {
-                    result.append("result += \"\";");
-                }
-                result.append("\n");
-            }
-        }
-        result.append(PrintingUtils.align(level))
-                .append("result += \"\\n]\";\n")
-                .append(PrintingUtils.align(level))
-                .append("return result;\n");
-        return result.toString();
+        return FixedTrees.printVariablesAsFunction(node).accept(this);
     }
 
     @Override
@@ -894,12 +772,12 @@
 
     @Override
     public String visit(StaticMemberVariable node) {
-        IRNode klass = node.getKlass();
-        VariableInfo value = node.get();
-        if (klass.equals(value.klass)) {
-            return value.name;
+        IRNode owner = node.getOwner();
+        VariableInfo info = node.getVariableInfo();
+        if (owner.equals(info.owner)) {
+            return info.name;
         } else {
-            return value.klass.getName() + "." + value.name;
+            return info.owner.getName() + "." + info.name;
         }
     }
 
@@ -910,10 +788,10 @@
         String cases = "";
         for (int i = 0; i < caseBlockIdx - 1; ++i) {
             cases += PrintingUtils.align(level + 1);
-            if (node.getChild(i + 1) != null) {
+            if (node.getChild(i + 1) instanceof Nothing) {
+                cases += "default:\n";
+            } else {
                 cases += "case " + node.getChild(i + 1).accept(this)+ ":\n";
-            } else {
-                cases += "default:\n";
             }
 
             cases += node.getChild(i + caseBlockIdx).accept(this)+ "\n";
@@ -955,11 +833,13 @@
     public String visit(UnaryOperator node) {
         IRNode exp = node.getChild(0);
         if (node.isPrefix()) {
-            return node.getOperatorText() + (exp instanceof Operator ? " " : "")
+            return operatorToJaveCode(node.getOperationKind())
+                    + (exp instanceof Operator ? " " : "")
                     + expressionToJavaCode(node, exp, Operator.Order.LEFT);
         } else {
             return expressionToJavaCode(node, exp, Operator.Order.RIGHT)
-                    + (exp instanceof Operator ? " " : "") + node.getOperatorText();
+                    + (exp instanceof Operator ? " " : "")
+                    + operatorToJaveCode(node.getOperationKind());
         }
     }
 
@@ -1024,14 +904,18 @@
         int level = node.getLevel();
         result.append("try {\n")
                 .append(body.accept(this)).append("\n")
-                .append(PrintingUtils.align(level)).append("}\n");
+                .append(PrintingUtils.align(level))
+                .append("}\n");
         for (int i = 2; i < childs.size(); i++) {
             result.append(childs.get(i).accept(this));
         }
         if (finallyBody != null) {
-            result.append(PrintingUtils.align(level)).append("finally {\n")
-                    .append(finallyBody.accept(this)).append("\n")
-                    .append(PrintingUtils.align(level)).append("}\n");
+            String finallyContent = finallyBody.accept(this);
+            if (!finallyContent.isEmpty()) {
+                result.append(PrintingUtils.align(level)).append("finally {\n")
+                        .append(finallyContent).append("\n")
+                        .append(PrintingUtils.align(level)).append("}\n");
+            }
         }
         return result.toString();
     }
--- a/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/visitors/Visitor.java	Sat May 14 15:34:30 2016 -0700
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/visitors/Visitor.java	Fri May 20 18:05:09 2016 +0300
@@ -34,7 +34,6 @@
 import jdk.test.lib.jittester.Initialization;
 import jdk.test.lib.jittester.Literal;
 import jdk.test.lib.jittester.LocalVariable;
-import jdk.test.lib.jittester.LogicOperator;
 import jdk.test.lib.jittester.NonStaticMemberVariable;
 import jdk.test.lib.jittester.Nothing;
 import jdk.test.lib.jittester.PrintVariables;
@@ -106,7 +105,6 @@
     T visit(Klass node);
     T visit(Literal node);
     T visit(LocalVariable node);
-    T visit(LogicOperator node);
     T visit(LoopingCondition node);
     T visit(MainKlass node);
     T visit(NonStaticMemberVariable node);