Merge
authortwisti
Thu, 26 Nov 2015 02:09:46 +0100
changeset 34227 001483ee066c
parent 34226 db9dea22fbfc (current diff)
parent 34225 773eded97d0d (diff)
child 34228 035e020c8c0d
child 34498 54f9242e3f81
Merge
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Nov 26 03:05:19 2015 +0300
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp	Thu Nov 26 02:09:46 2015 +0100
@@ -3220,12 +3220,7 @@
 DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdependencies(oop call_site) {
   assert(java_lang_invoke_MethodHandleNatives_CallSiteContext::is_instance(call_site), "");
   intptr_t* vmdeps_addr = (intptr_t*)call_site->address_field_addr(_vmdependencies_offset);
-#ifndef ASSERT
   DependencyContext dep_ctx(vmdeps_addr);
-#else
-  // Verify that call_site isn't moved during DependencyContext lifetime.
-  DependencyContext dep_ctx(vmdeps_addr, Handle(call_site));
-#endif // ASSERT
   return dep_ctx;
 }
 
--- a/hotspot/src/share/vm/code/dependencyContext.hpp	Thu Nov 26 03:05:19 2015 +0300
+++ b/hotspot/src/share/vm/code/dependencyContext.hpp	Thu Nov 26 02:09:46 2015 +0100
@@ -114,22 +114,19 @@
 
  public:
 #ifdef ASSERT
-  // Verification for dependency contexts rooted at Java objects.
-  Handle _base; // non-NULL if dependency context resides in an oop (e.g. CallSite).
-  oop _base_oop;
+  // Safepoints are forbidden during DC lifetime. GC can invalidate
+  // _dependency_context_addr if it relocates the holder
+  // (e.g. CallSiteContext Java object).
+  int _safepoint_counter;
 
-  DependencyContext(intptr_t* addr, Handle base = Handle())
-    : _dependency_context_addr(addr), _base(base)
-  {
-      _base_oop = _base();
-  }
+  DependencyContext(intptr_t* addr) : _dependency_context_addr(addr),
+    _safepoint_counter(SafepointSynchronize::_safepoint_counter) {}
 
   ~DependencyContext() {
-    // Base oop relocation invalidates _dependency_context_addr.
-    assert(_base_oop == _base(), "base oop relocation is forbidden");
+    assert(_safepoint_counter == SafepointSynchronize::_safepoint_counter, "safepoint happened");
   }
 #else
-    DependencyContext(intptr_t* addr) : _dependency_context_addr(addr) {}
+  DependencyContext(intptr_t* addr) : _dependency_context_addr(addr) {}
 #endif // ASSERT
 
   static const intptr_t EMPTY = 0; // dependencies = NULL, has_stale_entries = false
--- a/hotspot/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java	Thu Nov 26 03:05:19 2015 +0300
+++ b/hotspot/test/compiler/jvmci/compilerToVM/GetStackTraceElementTest.java	Thu Nov 26 02:09:46 2015 +0100
@@ -87,7 +87,7 @@
                         + " : unexpected line number");
             } else {
                 // native and abstract function
-                Asserts.assertLT(0, ste.getLineNumber(),
+                Asserts.assertGT(0, ste.getLineNumber(),
                         aMethod + " : unexpected line number for abstract "
                                 + "or native method");
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/Makefile	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,125 @@
+#
+# 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.
+#
+
+ifeq "x$(BOOTDIR)" "x"
+	JDK_HOME := $(shell dirname $(shell which java))/..
+else
+	JDK_HOME := $(BOOTDIR)
+endif
+
+ifeq "x$(PROPERTY_FILE)" "x"
+	PROPERTY_FILE := conf/default.properties
+endif
+
+ifeq "x$(TESTBASE_DIR)" "x"
+	TESTBASE_DIR := ws/hotspot/test
+endif
+
+JAVA = $(JDK_HOME)/bin/java
+JAVAC = $(JDK_HOME)/bin/javac
+JAR = $(JDK_HOME)/bin/jar
+
+BUILD_DIR = build
+CLASSES_DIR = $(BUILD_DIR)/classes
+SRC_DIR = src
+TEST_DIR = test
+MANIFEST = manifest.mf
+APPLICATION_ARGS = \
+    --property-file $(PROPERTY_FILE) \
+    --testbase-dir $(TESTBASE_DIR)
+MAIN_CLASS = JitTestGenerator.Automatic
+
+TESTGROUP_FILE = $(TESTBASE_DIR)/TEST.groups
+TESTROOT_FILE =  $(TESTBASE_DIR)/TEST.ROOT
+
+DIST_DIR = dist
+DIST_JAR = $(DIST_DIR)/JITtester.jar
+
+SRC_FILES = $(shell find $(SRC_DIR) -name '*.java')
+TESTLIBRARY_SRC_DIR = ../jdk/test/lib
+TESTLIBRARY_SRC_FILES = $(TESTLIBRARY_SRC_DIR)/Asserts.java \
+                        $(TESTLIBRARY_SRC_DIR)/JDKToolFinder.java \
+                        $(TESTLIBRARY_SRC_DIR)/JDKToolLauncher.java \
+                        $(TESTLIBRARY_SRC_DIR)/OutputAnalyzer.java \
+                        $(TESTLIBRARY_SRC_DIR)/OutputBuffer.java \
+                        $(TESTLIBRARY_SRC_DIR)/Pair.java \
+                        $(TESTLIBRARY_SRC_DIR)/Platform.java \
+                        $(TESTLIBRARY_SRC_DIR)/ProcessTools.java \
+                        $(TESTLIBRARY_SRC_DIR)/StreamPumper.java \
+                        $(TESTLIBRARY_SRC_DIR)/Utils.java
+
+.PHONY: cleantmp
+
+all: JAR
+
+JAR: INIT COMPILE manifest
+	$(JAR) cfm $(DIST_JAR) $(MANIFEST) -C $(CLASSES_DIR) .
+
+manifest:
+	@echo 'Manifest-Version: 1.0' > $(MANIFEST)
+	@echo 'X-COMMENT: Main-Class will be added automatically by build' >> $(MANIFEST)
+	@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
+
+COMPILE: INIT filelist compile_testlib
+	$(JAVAC) -cp $(CLASSES_DIR) -XDignore.symbol.file -Xlint -sourcepath $(SRC_DIR) -d $(CLASSES_DIR) -source 1.8 @filelist
+
+filelist: $(SRC_FILES)
+		@rm -f $@
+		@echo $(SRC_FILES) > $@
+
+INIT: $(DIST_DIR)
+	$(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)
+
+clean_testbase:
+	@rm -rf $(TESTBASE_DIR)
+
+cleantmp:
+	@rm filelist
+	@rm -rf $(CLASSES_DIR)
+
+copytestlibrary:
+	@cp -r src/jdk/test/lib/jittester/jtreg $(TESTBASE_DIR)/
+	@cp -r ../jdk $(TESTBASE_DIR)/
+
+testgroup: $(TESTBASE_DIR)
+	@echo 'jittester_all = \\' > $(TESTGROUP_FILE)
+	@echo '	/' >> $(TESTGROUP_FILE)
+	@echo '' >> $(TESTGROUP_FILE)
+	@echo 'main = \\' >> $(TESTGROUP_FILE)
+	@echo '	Test_0.java' >> $(TESTGROUP_FILE)
+
+testroot: $(TESTBASE_DIR)
+	@echo 'groups=TEST.groups' > $(TESTROOT_FILE)
+
+$(TESTBASE_DIR):
+	$(shell if [ ! -d $@ ]; then mkdir -p $@; fi)
+
+$(DIST_DIR):
+	$(shell if [ ! -d $@ ]; then mkdir -p $@; fi)
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/conf/classes.lst	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,20 @@
+java.lang.Object
+java.lang.String
+java.lang.Number
+java.lang.Boolean
+java.lang.Byte
+java.lang.Short
+java.lang.Character
+java.lang.Integer
+java.lang.Long
+java.lang.Float
+java.lang.Double
+java.lang.Math
+java.lang.System
+java.lang.Runnable
+java.util.AbstractSet
+java.util.HashSet
+java.lang.RuntimeException
+java.lang.IllegalArgumentException
+java.lang.NumberFormatException
+java.lang.IndexOutOfBoundsException
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/conf/default.properties	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,11 @@
+seed=SEED2
+number-of-tests=1000
+testbase-dir=ws/hotspot/test
+fp-precision=7
+min-cfg-depth=5
+max-cfg-depth=5
+classes-file=conf/classes.lst
+exclude-methods-file=conf/exclude.methods.lst
+print-complexity=true
+print-hierarchy=true
+disable-static=true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/conf/exclude.methods.lst	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,22 @@
+java/lang/Object::notify()
+java/lang/Object::notifyAll()
+java/lang/Object::wait()
+java/lang/Object::wait(J)
+java/lang/Object::wait(JI)
+java/lang/Object::toString()
+java/lang/String::String([BIILjava/lang/String;)
+java/lang/String::String([BLjava/lang/String;)
+java/lang/String::getBytes(Ljava/lang/String;)
+java/lang/String::join(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)
+java/lang/String::format(Ljava/lang/String;[Ljava/lang/Object;)
+java/lang/String::format(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)
+java/lang/System::exit(I)
+java/lang/System::inheritedChannel()
+java/lang/System::runFinalizersOnExit(Z)
+java/util/AbstractSet::toString()
+java/util/HashSet::toString()
+java/lang/RuntimeException::setStackTrace([Ljava/lang/StackTraceElement;)
+java/lang/RuntimeException::RuntimeException(Ljava/lang/Throwable;)
+java/lang/RuntimeException::RuntimeException(Ljava/lang/String;Ljava/lang/Throwable;)
+java/lang/annotation/IncompleteAnnotationException::IncompleteAnnotationException(Ljava/lang/Class;Ljava/lang/String;)
+java/lang/EnumConstantNotPresentException::EnumConstantNotPresentException(Ljava/lang/Class;Ljava/lang/String;)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Automatic.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,220 @@
+/*
+ * 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 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.jittester.factories.IRNodeBuilder;
+import jdk.test.lib.jittester.TypesParser;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.visitors.JavaCodeVisitor;
+import jdk.test.lib.jittester.utils.OptionResolver;
+import jdk.test.lib.jittester.utils.OptionResolver.Option;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+public class Automatic {
+    public static final int minutesToWait = 3;
+
+    private static String makeTestCase(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);
+
+            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)
+                        .getClassDefinitionBlockFactory()
+                        .produce();
+                if (privateClasses != null) {
+                    resultVis.append(privateClasses.accept(vis));
+                }
+            }
+            long mainComplexityLimit = (long) (ProductionParams.complexityLimit.value()
+                    * PseudoRandom.random());
+            IRNode mainClass = builder.setComplexityLimit(mainComplexityLimit)
+                    .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);
+        }
+        return headerBuilder.append(resultVis).toString();
+    }
+
+    private static void initializeTestGenerator(String[] params) {
+        OptionResolver parser = new OptionResolver();
+        Option<String> propertyFileOpt = parser.addStringOption('p', "property-file", "",
+                "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());
+    }
+
+    public static void main(String[] args) {
+        initializeTestGenerator(args);
+        int counter = 0;
+        try {
+            String testbaseDir = ProductionParams.testbaseDir.value();
+            do {
+                double start = System.currentTimeMillis();
+                String name = "Test_" + counter;
+                generateTestFile(name);
+                double generationTime = System.currentTimeMillis() - start;
+                String path = getJavaPath();
+                ProcessBuilder pb = new ProcessBuilder(path + "javac", testbaseDir + "/" + name + ".java");
+                runProcess(pb, testbaseDir + "/" + name);
+
+                start = System.currentTimeMillis();
+                pb = new ProcessBuilder(path + "java", "-Xint", "-cp", testbaseDir, name);
+                name = name + ".gold";
+                runProcess(pb, testbaseDir + "/" + name);
+                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;
+            } while (counter < ProductionParams.numberOfTests.value());
+        } catch (IOException | InterruptedException ex) {
+            Logger.getLogger(Automatic.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
+
+    private static String getJavaPath() {
+        String[] env = { "JDK_HOME", "JAVA_HOME", "BOOTDIR" };
+        for (String name : env) {
+            String path = System.getenv(name);
+            if (path != null) {
+                return path + "/bin/";
+            }
+        }
+        return "";
+    }
+
+    private static void 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)) {
+            try (FileWriter file = new FileWriter(name + ".exit")) {
+                file.write(Integer.toString(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);
+        }
+    }
+
+    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 r;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/BinaryOperator.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,58 @@
+/*
+ * 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 BinaryOperator extends Operator {
+    protected String operationCode;
+    protected Type resultType;
+
+    public BinaryOperator(OperatorKind opKind, IRNode leftOperand, IRNode rightOperand) {
+        super(opKind.priority);
+        operationCode = opKind.text;
+        addChild(leftOperand);
+        addChild(rightOperand);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode leftOperand = getChild(Order.LEFT.ordinal());
+        IRNode rightOperand = getChild(Order.RIGHT.ordinal());
+        if (leftOperand != null && rightOperand != null) {
+            return leftOperand.complexity() + rightOperand.complexity() + 1;
+        } else {
+            return 0;
+        }
+    }
+
+    public String getOperationCode() {
+        return operationCode;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Block.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,65 @@
+/*
+ * 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 java.util.List;
+import jdk.test.lib.jittester.types.TypeKlass;
+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);
+        addChildren(content);
+        this.level = level;
+        this.returnType = returnType;
+    }
+
+    public Type getReturnType() {
+        return returnType;
+    }
+
+    protected int size() {
+        return getChildren().size();
+    }
+
+    @Override
+    public long complexity() {
+        return getChildren()
+                .stream()
+                .mapToLong(IRNode::complexity)
+                .sum();
+    }
+
+    @Override
+    public long countDepth() {
+        return Long.max(level, super.countDepth());
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Break.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,34 @@
+/*
+ * 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 Break extends IRNode {
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/BuiltInType.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,100 @@
+/*
+ * 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;
+
+public abstract class BuiltInType extends Type {
+
+    private static class BuiltInTypeCapacityHelper {
+
+        static String builtInTypes[] = {"boolean", "byte", "short", "char", "int", "long", "float", "double"};
+
+        static private int getIndexFor(String typeName) {
+            for (int i = 0; i < builtInTypes.length; i++) {
+                if (typeName.compareTo(builtInTypes[i]) == 0) {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        static public int compare(String typeName1, String typeName2) {
+            int i1 = getIndexFor(typeName1);
+            int i2 = getIndexFor(typeName2);
+
+            return i1 - i2;
+        }
+    }
+
+    protected BuiltInType(String name) {
+        super(name);
+    }
+
+    @Override
+    public boolean canImplicitlyCastTo(Type type) {
+        if (equals(type)) {
+            return true;
+        }
+        try {
+            BuiltInType t = (BuiltInType) type;
+            // You cannot impicitly cast anything to char or boolean
+            if (t.getName().compareTo("boolean") == 0 || t.getName().compareTo("char") == 0) {
+                return false;
+            }
+            if (t.isMoreCapaciousThan(this)) {
+                return true;
+            }
+        } catch (Exception e) {
+        }
+        return false;
+    }
+
+    @Override
+    public boolean canExplicitlyCastTo(Type t) {
+        if (equals(t)) {
+            return true;
+        }
+        try {
+            BuiltInType _t = (BuiltInType) t;
+            if (_t.getName().compareTo("boolean") != 0) {
+                return true;
+            }
+        } catch (Exception e) {
+        }
+        return false;
+    }
+
+    public boolean isMoreCapaciousThan(BuiltInType t) {
+        return BuiltInTypeCapacityHelper.compare(this.getName(), t.getName()) > 0;
+    }
+
+    @Override
+    public boolean canCompareTo(Type t) {
+        return true;
+    }
+
+    @Override
+    public boolean canEquateTo(Type t) {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/CastOperator.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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 CastOperator extends Operator {
+    private final Type resultType;
+
+    public CastOperator(Type resultType, IRNode casted) {
+        super(13);
+        this.resultType = resultType;
+        addChild(casted);
+    }
+
+    @Override
+    public long complexity() {
+        return getChild(0).complexity() + 1;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public Type getResultType() {
+        return resultType;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/CatchBlock.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,43 @@
+/*
+ * 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.test.lib.jittester;
+
+import java.util.Collections;
+import java.util.List;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class CatchBlock extends IRNode {
+    public final List<Type> throwables;
+
+    public CatchBlock(IRNode body, List<Type> throwables, int level) {
+        this.level = level;
+        this.throwables = Collections.unmodifiableList(throwables);
+        addChild(body);
+    }
+
+    @Override
+    public <T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Continue.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,34 @@
+/*
+ * 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 Continue extends IRNode {
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Declaration.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,42 @@
+/*
+ * 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 Declaration extends IRNode {
+    public Declaration(IRNode declarationExpr) {
+        addChild(declarationExpr);
+    }
+
+    @Override
+    public long complexity() {
+        return getChild(0).complexity();
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/IRNode.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,201 @@
+/*
+ * 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;
+
+// Production is base class for all elements of the IR-tree.
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import jdk.test.lib.jittester.loops.For;
+import jdk.test.lib.jittester.loops.DoWhile;
+import jdk.test.lib.jittester.loops.While;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public abstract class IRNode {
+    private IRNode parent;
+    private final List<IRNode> children = new ArrayList<>();
+    protected IRNode klass;
+    protected int level;
+    //TODO
+    //private boolean isCFDeviation;
+
+    public abstract <T> T accept(Visitor<T> v);
+
+    public void setKlass(TypeKlass klass) {
+        this.klass = klass;
+        if (Objects.isNull(klass)) {
+            System.out.println(getClass().getName() + " null");
+            for (StackTraceElement s : Thread.currentThread().getStackTrace()) {
+                System.out.println(s.toString());
+            }
+        }
+    }
+
+    public void addChild(IRNode child) {
+        children.add(child);
+        if (!Objects.isNull(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;
+                }
+            }
+        }
+    }
+
+    public List<IRNode> getChildren() {
+        return children;
+    }
+
+    public IRNode getChild(int i) {
+        return i < children.size() ? children.get(i) : null;
+    }
+
+    public IRNode getKlass() {
+        return klass;
+    }
+
+    public IRNode getParent() {
+        return parent;
+    }
+
+    public void setChild(int index, IRNode child) {
+        children.set(index, child);
+        if (!Objects.isNull(child)) {
+            child.parent = this;
+        }
+    }
+
+    public boolean removeChild(IRNode l) {
+        return children.remove(l);
+    }
+
+    public boolean removeSelf() {
+        return parent.children.remove(this);
+    }
+
+    public void resizeUpChildren(int size) {
+        for (int i = children.size(); i < size; ++i) {
+            children.add(null);
+        }
+    }
+
+    public void removeAllChildren() {
+        children.clear();
+    }
+
+    public String getTreeTextView(int indent) {
+        StringBuilder sb = new StringBuilder();
+        if (level > 0) {
+        for (int i = 0; i < indent; ++i) {
+            sb.append("\t");
+        }
+        sb.append(getName())
+                .append(" [")
+                .append(level)
+                .append("]")
+                    .append(System.lineSeparator());
+        }
+        children.stream()
+                .filter(ch -> !Objects.isNull(ch))
+                .forEach(ch -> sb.append(ch.getTreeTextView(indent + 1)));
+        return sb.toString();
+    }
+
+    protected IRNode evolve() {
+        throw new Error("Not implemented");
+    }
+
+    public int getLevel() {
+        return level;
+    }
+
+    public long complexity() {
+        return 0L;
+    }
+
+    @Override
+    public final String toString() {
+        throw new Error("Should be toJavaCode");
+    }
+
+    public String getName() {
+        return this.getClass().getName();
+    }
+
+    public static long countDepth(Collection<IRNode> input) {
+        return input.stream()
+                .filter(c -> !Objects.isNull(c))
+                .mapToLong(IRNode::countDepth)
+                .max().orElse(0L);
+    }
+
+    public long countDepth() {
+        return IRNode.countDepth(children);
+    }
+
+    public List<IRNode> getStackableLeaves() {
+        List<IRNode> result = new ArrayList<>();
+        children.stream()
+                .filter(c -> !Objects.isNull(c))
+                .forEach(c -> {
+                    if (countDepth() == c.level && (c instanceof Block)) {
+                        result.add(c);
+                    } else {
+                        result.addAll(c.getStackableLeaves());
+                    }
+                });
+        return result;
+    }
+
+    public List<IRNode> getDeviantBlocks(long depth) {
+        List<IRNode> result = new ArrayList<>();
+        children.stream()
+                .filter(c -> !Objects.isNull(c))
+                .forEach(c -> {
+            if (depth == c.level && c.isCFDeviation()) {
+                        result.add(c);
+                    } else {
+                        result.addAll(c.getDeviantBlocks(depth));
+                    }
+                });
+        return result;
+    }
+
+    // TODO: add field instead this function
+    public boolean isCFDeviation() {
+        return this instanceof If || this instanceof Switch
+            || this instanceof For || this instanceof While
+            || this instanceof DoWhile
+            || (this instanceof Block && this.parent instanceof Block);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/If.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,63 @@
+/*
+ * 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 If extends IRNode {
+    public enum IfPart {
+        CONDITION,
+        THEN,
+        ELSE,
+    };
+
+    public If(IRNode condition, IRNode thenBlock, IRNode elseBlock, int level) {
+        this.level = level;
+        resizeUpChildren(IfPart.values().length);
+        setChild(IfPart.CONDITION.ordinal(), condition);
+        setChild(IfPart.THEN.ordinal(), thenBlock);
+        setChild(IfPart.ELSE.ordinal(), elseBlock);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode condition = getChild(IfPart.CONDITION.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,
+            elseBlock != null ? elseBlock.complexity() : 0);
+
+    }
+
+    @Override
+    public long countDepth() {
+        return Long.max(level, super.countDepth());
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Initialization.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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 abstract class Initialization extends IRNode {
+    protected VariableInfo variableInfo = new VariableInfo();
+
+    protected Initialization() {
+    }
+
+    protected Initialization(VariableInfo varInfo, IRNode initExpr) {
+        variableInfo = varInfo;
+        addChild(initExpr);
+    }
+
+    public VariableInfo get() {
+        return variableInfo;
+    }
+
+    @Override
+    public long complexity() {
+        return getChild(0).complexity() + 1;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public VariableInfo getVariableInfo() {
+        return variableInfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Literal.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,54 @@
+/*
+ * 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 Literal extends IRNode {
+    public final Object value;
+    protected final Type resultType;
+
+    public Literal(Object v, Type t) {
+        value = v;
+        resultType = t;
+    }
+
+    @Override
+    public long complexity() {
+        return 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public Type getResultType() {
+        return resultType;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/LiteralInitializer.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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;
+
+public class LiteralInitializer extends Literal {
+    public LiteralInitializer(Object v, Type t) {
+        super(v, t);
+        addChild(t); //TODO: check if it's needed
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/LocalVariable.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,49 @@
+/*
+ * 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 LocalVariable extends IRNode implements VariableBase {
+    private VariableInfo value = new VariableInfo();
+
+    public LocalVariable(VariableInfo value) {
+        this.value = value;
+    }
+
+    @Override
+    public VariableInfo get() {
+        return value;
+    }
+
+    @Override
+    public long complexity() {
+        return 1;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/LogicOperator.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,37 @@
+/*
+ * 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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/NonStaticMemberVariable.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,54 @@
+/*
+ * 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 NonStaticMemberVariable extends IRNode implements VariableBase {
+    private final VariableInfo value;
+
+    public NonStaticMemberVariable(IRNode object, VariableInfo value) {
+        this.value = value;
+        addChild(object);
+    }
+
+    @Override
+    public VariableInfo get() {
+        return value;
+    }
+
+    @Override
+    public long complexity() {
+        return getChild(0).complexity();
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public VariableInfo getValue() {
+        return value;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Nothing.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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 Nothing extends IRNode {
+
+    @Override
+    public long complexity() {
+        return 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Operator.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+public abstract class Operator extends IRNode {
+    protected int operatorPriority;
+
+    public int getPriority() {
+        return operatorPriority;
+    }
+
+    public enum Order {
+        LEFT, RIGHT
+    };
+
+    // This constructor is called to construct an IR-tree node.
+    protected Operator(int operatorPriority) {
+        this.operatorPriority = operatorPriority;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/OperatorKind.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,83 @@
+/*
+ * 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.test.lib.jittester;
+
+// 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),
+    ;
+
+    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(String text, int priority, boolean isPrefix) {
+        this.text = text;
+        this.priority = priority;
+        this.isPrefix = isPrefix;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/PrintVariables.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,52 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.List;
+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;
+        this.level = level;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public List<Symbol> getVars() {
+        return vars;
+    }
+
+    public String getPrinterName() {
+        return printerName;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionFailedException.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+public class ProductionFailedException extends Exception {
+    static final long serialVersionUID = -2325617203741536725L;
+
+    public ProductionFailedException(String msg) {
+        super(msg);
+    }
+
+    public ProductionFailedException() {
+        super();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionLimiter.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,48 @@
+/*
+ * 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;
+// an utility class to limit steps in the production of an expression
+public class ProductionLimiter {
+
+    private static Integer limit = -1;
+
+    public static void setUnlimited() {
+        limit = -1;
+    }
+
+    // initialize limit state
+    public static void setLimit() {
+        limit = ProductionParams.productionLimit.value();
+    }
+
+    // iterate a limit, throwing exception in case it hit
+    public static void limitProduction() throws ProductionFailedException {
+        if (limit > 0) {
+            limit--;
+        }
+        if (limit != -1 && limit <= 0) {
+            throw new ProductionFailedException();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/ProductionParams.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,127 @@
+/*
+ * 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.utils.OptionResolver;
+import jdk.test.lib.jittester.utils.OptionResolver.Option;
+
+public class ProductionParams {
+
+    public static Option<Integer> productionLimit = null;
+    public static Option<Integer> dataMemberLimit = null;
+    public static Option<Integer> statementLimit = null;
+    public static Option<Integer> testStatementLimit = null;
+    public static Option<Integer> operatorLimit = null;
+    public static Option<Long> complexityLimit = null;
+    public static Option<Integer> memberFunctionsLimit = null;
+    public static Option<Integer> memberFunctionsArgLimit = null;
+    public static Option<Integer> stringLiteralSizeLimit = null;
+    public static Option<Integer> classesLimit = null;
+    public static Option<Integer> implementationLimit = null;
+    public static Option<Integer> dimensionsLimit = null;
+    public static Option<Integer> floatingPointPrecision = null;
+    public static Option<Integer> minCfgDepth = null;
+    public static Option<Integer> maxCfgDepth = null;
+    public static Option<Boolean> enableStrictFP = null;
+    public static Option<Boolean> printComplexity = null;
+    public static Option<Boolean> printHierarchy = null;
+    //public static BooleanOption disableFinals = optionResolver.addBooleanOption("disable-finals", "Don\'t use finals");
+    public static Option<Boolean> disableFinalClasses = null;
+    public static Option<Boolean> disableFinalMethods = null;
+    public static Option<Boolean> disableFinalVariables = null;
+    public static Option<Boolean> disableIf = null;
+    public static Option<Boolean> disableSwitch = null;
+    public static Option<Boolean> disableWhile = null;
+    public static Option<Boolean> disableDoWhile = null;
+    public static Option<Boolean> disableFor = null;
+    public static Option<Boolean> disableFunctions = null;
+    public static Option<Boolean> disableVarsInBlock = null;
+    public static Option<Boolean> disableExprInInit = null;
+    public static Option<Boolean> disableExternalSymbols = null;
+    public static Option<String> addExternalSymbols = null;
+    public static Option<Boolean> disableInheritance = null;
+    public static Option<Boolean> disableDowncasts = null;
+    public static Option<Boolean> disableStatic = null;
+    public static Option<Boolean> disableInterfaces = null;
+    public static Option<Boolean> disableClasses = null;
+    public static Option<Boolean> disableNestedBlocks = null;
+    public static Option<Boolean> disableArrays = null;
+    public static Option<Boolean> enableFinalizers = 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<String> classesFile = null;
+    public static Option<String> excludeMethodsFile = null;
+
+    public static void register(OptionResolver optionResolver) {
+        productionLimit = optionResolver.addIntegerOption('l', "production-limit", 100, "Limit on steps in the production of an expression");
+        dataMemberLimit = optionResolver.addIntegerOption('v', "data-member-limit", 10, "Upper limit on data members");
+        statementLimit = optionResolver.addIntegerOption('s', "statement-limit", 30, "Upper limit on statements in function");
+        testStatementLimit = optionResolver.addIntegerOption('e', "test-statement-limit", 300, "Upper limit on statements in test() function");
+        operatorLimit = optionResolver.addIntegerOption('o', "operator-limit", 50, "Upper limit on operators in a statement");
+        complexityLimit = optionResolver.addLongOption('x', "complexity-limit", 10000000, "Upper limit on complexity");
+        memberFunctionsLimit = optionResolver.addIntegerOption('m', "member-functions-limit", 15, "Upper limit on member functions");
+        memberFunctionsArgLimit = optionResolver.addIntegerOption('a', "member-functions-arg-limit", 5, "Upper limit on the number of member function args");
+        stringLiteralSizeLimit = optionResolver.addIntegerOption("string-literal-size-limit", 10, "Upper limit on the number of chars in string literal");
+        classesLimit = optionResolver.addIntegerOption('c', "classes-limit", 12, "Upper limit on the number of classes");
+        implementationLimit = optionResolver.addIntegerOption('i', "implementation-limit", 3, "Upper limit on a number of interfaces a class can implement");
+        dimensionsLimit = optionResolver.addIntegerOption('d', "dimensions-limit", 3, "Upper limit on array dimensions");
+        floatingPointPrecision = optionResolver.addIntegerOption("fp-precision", 8, "A non-negative decimal integer used to restrict the number of digits after the decimal separator");
+        minCfgDepth = optionResolver.addIntegerOption("min-cfg-depth", 2, "A non-negative decimal integer used to restrict the lower bound of depth of control flow graph");
+        maxCfgDepth = optionResolver.addIntegerOption("max-cfg-depth", 3, "A non-negative decimal integer used to restrict the upper bound of depth of control flow graph");
+        enableStrictFP = optionResolver.addBooleanOption("enable-strict-fp", "Add strictfp attribute to test class");
+        printComplexity = optionResolver.addBooleanOption("print-complexity", "Print complexity of each statement");
+        printHierarchy = optionResolver.addBooleanOption("print-hierarchy", "Print resulting class hierarchy");
+        //disableFinals = optionResolver.addBooleanOption("disable-finals", "Don\'t use finals");
+        disableFinalClasses = optionResolver.addBooleanOption("disable-final-classes", "Don\'t use final classes");
+        disableFinalMethods = optionResolver.addBooleanOption("disable-final-methods", "Don\'t use final methods");
+        disableFinalVariables = optionResolver.addBooleanOption("disable-final-variabless", "Don\'t use final variables");
+        disableIf = optionResolver.addBooleanOption("disable-if", "Don\'t use conditionals");
+        disableSwitch = optionResolver.addBooleanOption("disable-switch", "Don\'t use switch");
+        disableWhile = optionResolver.addBooleanOption("disable-while", "Don\'t use while");
+        disableDoWhile = optionResolver.addBooleanOption("disable-do-while", "Don\'t use do-while");
+        disableFor = optionResolver.addBooleanOption("disable-for", "Don\'t use for");
+        disableFunctions = optionResolver.addBooleanOption("disable-functions", "Don\'t use functions");
+        disableVarsInBlock = optionResolver.addBooleanOption("disable-vars-in-block", "Don\'t generate variables in blocks");
+        disableExprInInit = optionResolver.addBooleanOption("disable-expr-in-init", "Don\'t use complex expressions in variable initialization");
+        disableExternalSymbols = optionResolver.addBooleanOption("disable-external-symbols", "Don\'t use external symbols");
+        addExternalSymbols = optionResolver.addStringOption("add-external-symbols", "all", "Add symbols for listed classes (comma-separated list)");
+        disableInheritance = optionResolver.addBooleanOption("disable-inheritance", "Disable inheritance");
+        disableDowncasts = optionResolver.addBooleanOption("disable-downcasts", "Disable downcasting of objects");
+        disableStatic = optionResolver.addBooleanOption("disable-static", "Disable generation of static objects and functions");
+        disableInterfaces = optionResolver.addBooleanOption("disable-interfaces", "Disable generation of interfaces");
+        disableClasses = optionResolver.addBooleanOption("disable-classes", "Disable generation of classes");
+        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)");
+        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");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Rule.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,122 @@
+/*
+ * 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 java.util.Iterator;
+import java.util.LinkedList;
+import java.util.TreeSet;
+import jdk.test.lib.jittester.factories.Factory;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+/**
+ * The Rule. A helper to perform production.
+ */
+public class Rule extends Factory implements Comparable<Rule> {
+    private String name;
+    private Integer limit = -1;
+
+    @Override
+    public int compareTo(Rule 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) {
+        add(ruleName, factory, 1.0);
+    }
+
+    public void add(String ruleName, Factory factory, double weight) {
+        variants.add(new RuleEntry(ruleName, factory, weight));
+    }
+
+    public int size() {
+        return variants.size();
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        if (!variants.isEmpty()) {
+            // Begin production.
+            LinkedList<RuleEntry> rulesList = new LinkedList<>(variants);
+            PseudoRandom.shuffle(rulesList);
+
+            while (!rulesList.isEmpty() && (limit == -1 || limit > 0)) {
+                double sum = rulesList.stream()
+                        .mapToDouble(r -> r.weight)
+                        .sum();
+                double rnd = PseudoRandom.random() * sum;
+                Iterator<RuleEntry> iterator = rulesList.iterator();
+                RuleEntry ruleEntry;
+                double weightAccumulator = 0;
+                do {
+                    ruleEntry = iterator.next();
+                    weightAccumulator += ruleEntry.weight;
+                    if (weightAccumulator >= rnd) {
+                        break;
+                    }
+                } while (iterator.hasNext());
+                try {
+                    return ruleEntry.produce();
+                } catch (ProductionFailedException e) {
+                }
+                iterator.remove();
+                if (limit != -1) {
+                    limit--;
+                }
+            }
+            //throw new ProductionFailedException();
+        }
+        // should probably throw exception here..
+        //return getChildren().size() > 0 ? getChild(0).produce() : null;
+        throw new ProductionFailedException();
+    }
+
+    private class RuleEntry extends Factory implements Comparable<RuleEntry> {
+        private final double weight;
+        private final Factory factory;
+        private final String name;
+
+        private RuleEntry(String name, Factory factory, double weight) {
+            this.name = name;
+            this.weight = weight;
+            this.factory = factory;
+        }
+
+        @Override
+        public IRNode produce() throws ProductionFailedException {
+            return factory.produce();
+        }
+
+        @Override
+        public int compareTo(RuleEntry entry) {
+            return name.compareTo(entry.name);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Statement.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,49 @@
+/*
+ * 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 Statement extends IRNode {
+    private final boolean needSemicolon;
+
+    public Statement(IRNode statementBody, boolean needSemicolon) {
+        this.needSemicolon = needSemicolon;
+        addChild(statementBody);
+    }
+
+    @Override
+    public long complexity() {
+        return getChild(0).complexity();
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public boolean isSemicolonNeeded() {
+        return needSemicolon;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/StaticMemberVariable.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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.types.TypeKlass;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class StaticMemberVariable extends IRNode implements VariableBase {
+    private final VariableInfo varInfo;
+
+    public StaticMemberVariable(TypeKlass owner, VariableInfo varInfo) {
+        setKlass(owner);
+        this.varInfo = varInfo;
+    }
+
+    @Override
+    public VariableInfo get() {
+        return varInfo;
+    }
+
+    @Override
+    public long complexity() {
+        return 1;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Switch.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,61 @@
+/*
+ * 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 java.util.List;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class Switch extends IRNode {
+    private final int caseBlockIdx;
+
+    public Switch(int level, List<IRNode> chldrn, int caseBlockIdx) {
+        this.level = level;
+        addChildren(chldrn);
+        this.caseBlockIdx = caseBlockIdx;
+    }
+
+    @Override
+    public long complexity() {
+        IRNode switchExp = getChild(0);
+        long complexity = switchExp != null ? switchExp.complexity() : 0;
+        for (int i = caseBlockIdx; i < getChildren().size(); ++i) {
+            complexity += getChild(i).complexity();
+        }
+        return complexity;
+    }
+
+    @Override
+    public long countDepth() {
+        return Long.max(level, super.countDepth());
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public int getCaseBlockIndex() {
+        return caseBlockIdx;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Symbol.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,113 @@
+/*
+ * 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.types.TypeKlass;
+
+public class Symbol {
+
+    public String name;
+    public Type type;
+    public TypeKlass klass;
+    public static final int NONE = 0x00;
+    public static final int PRIVATE = 0x01;
+    public static final int DEFAULT = 0x02;
+    public static final int PROTECTED = 0x04;
+    public static final int PUBLIC = 0x08;
+    public static final int ACCESS_ATTRS_MASK = PRIVATE + PROTECTED + DEFAULT + PUBLIC;
+    public static final int STATIC = 0x10;
+    public static final int FINAL = 0x20;
+    public int flags = NONE;
+
+    protected Symbol() {
+    }
+
+    protected Symbol(String name) {
+        this.name = name;
+    }
+
+    public Symbol(String name, TypeKlass klass, Type type, int flags) {
+        this.name = name;
+        this.klass = klass;
+        this.type = type;
+        this.flags = flags;
+    }
+
+    protected Symbol(Symbol value) {
+        this.name = value.name;
+        this.klass = value.klass;
+        this.type = value.type;
+        this.flags = value.flags;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || !(o instanceof Symbol)) {
+            return false;
+        }
+        try {
+            Symbol s = (Symbol) o;
+            return klass.equals(s.klass) && name.equals(s.name);
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+
+    public boolean isStatic() {
+        return (flags & STATIC) > 0;
+    }
+
+    public boolean isFinal() {
+        return (flags & FINAL) > 0;
+    }
+
+    public boolean isPublic() {
+        return (flags & PUBLIC) > 0;
+    }
+
+    public boolean isProtected() {
+        return (flags & PROTECTED) > 0;
+    }
+
+    public boolean isPrivate() {
+        return (flags & PRIVATE) > 0;
+    }
+
+    protected Symbol copy() {
+        return new Symbol(this);
+    }
+
+    public Symbol deepCopy() {
+        return new Symbol(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/SymbolTable.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,293 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Stack;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+
+public class SymbolTable {
+
+    private static final Stack<HashMap<Type, ArrayList<Symbol>>> SYMBOL_STACK
+            = new Stack<>();
+    private static int VARIABLE_NUMBER = 0;
+    private static int FUNCTION_NUMBER = 0;
+
+    static private void initExternalSymbols() {
+
+        String classList = ProductionParams.addExternalSymbols.value();
+        if (classList.equals("all")) {
+            for (Type type : TypeList.getReferenceTypes()) {
+                type.exportSymbols();
+            }
+        } else {
+            String[] splittedList = classList.split(",");
+            for (Type type : TypeList.getReferenceTypes()) {
+                for (String str : splittedList) {
+                    if (type.getName().equals(str)) {
+                        type.exportSymbols();
+                        break;
+                    }
+                }
+            }
+        }
+
+    }
+
+    static {
+        SYMBOL_STACK.push(new HashMap<>());
+        if (!ProductionParams.disableExternalSymbols.value()) {
+            initExternalSymbols();
+        }
+    }
+
+    public static void add(Symbol symbol) {
+        HashMap<Type, ArrayList<Symbol>> vars = SYMBOL_STACK.peek();
+        if (!vars.containsKey(symbol.type)) {
+            vars.put(symbol.type, new ArrayList<>());
+        }
+        vars.get(symbol.type).add(symbol);
+    }
+
+    public static void remove(Symbol symbol) {
+        HashMap<Type, ArrayList<Symbol>> vars = SYMBOL_STACK.peek();
+        if (vars.containsKey(symbol.type)) {
+            ArrayList<Symbol> symbolsOfType = vars.get(symbol.type);
+            symbolsOfType.remove(symbol);
+            if (symbolsOfType.isEmpty()) {
+                vars.remove(symbol.type);
+            }
+        }
+    }
+
+    protected static Collection<Symbol> get(Type type) {
+        HashMap<Type, ArrayList<Symbol>> vars = SYMBOL_STACK.peek();
+        if (vars.containsKey(type)) {
+            return vars.get(type);
+        }
+        return new ArrayList<>();
+    }
+
+    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 new ArrayList<>();
+    }
+
+    protected static Collection<Symbol> get(TypeKlass typeKlass, 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) && typeKlass.equals(symbol.klass)) {
+                    result.add(symbol);
+                }
+            }
+            return result;
+        }
+        return new ArrayList<>();
+    }
+
+    protected static HashMap<Type, ArrayList<Symbol>> getAll() {
+        return SYMBOL_STACK.peek();
+    }
+
+    protected static HashMap<Type, ArrayList<Symbol>> getAll(Class<?> classToCheck) {
+        HashMap<Type, ArrayList<Symbol>> result = new HashMap<>();
+
+        for (Type type : SYMBOL_STACK.peek().keySet()) {
+            ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type);
+            for (Symbol symbol : symbolsOfType) {
+                if (classToCheck.isInstance(symbol)) {
+                    if (!result.containsKey(type)) {
+                        result.put(type, new ArrayList<>());
+                    }
+                    result.get(type).add(symbol);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    protected static HashMap<Type, ArrayList<Symbol>> getAll(TypeKlass typeKlass, Class<?> classToCheck) {
+        HashMap<Type, ArrayList<Symbol>> result = new HashMap<>();
+
+        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 (!result.containsKey(type)) {
+                        result.put(type, new ArrayList<>());
+                    }
+                    result.get(type).add(symbol);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    protected static ArrayList<Symbol> getAllCombined() {
+        ArrayList<Symbol> result = new ArrayList<>();
+        for (Type type : SYMBOL_STACK.peek().keySet()) {
+            ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type);
+            for (Symbol symbol : symbolsOfType) {
+                result.add(symbol);
+            }
+        }
+
+        return result;
+    }
+
+    public static ArrayList<Symbol> getAllCombined(Class<?> classToCheck) {
+        ArrayList<Symbol> result = new ArrayList<>();
+        for (Type type : SYMBOL_STACK.peek().keySet()) {
+            ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type);
+            for (Symbol symbol : symbolsOfType) {
+                if (classToCheck.isInstance(symbol)) {
+                    result.add(symbol);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public static ArrayList<Symbol> getAllCombined(TypeKlass typeKlass, Class<?> classToCheck) {
+        ArrayList<Symbol> result = new ArrayList<>();
+        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)) {
+                    result.add(symbol);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public static ArrayList<Symbol> getAllCombined(TypeKlass typeKlass) {
+        ArrayList<Symbol> result = new ArrayList<>();
+        for (Type t : SYMBOL_STACK.peek().keySet()) {
+            ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(t);
+            for (Symbol symbol : symbolsOfType) {
+                if (typeKlass.equals(symbol.klass)) {
+                    result.add(symbol);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    protected static ArrayList<Symbol> getAllCombined(String name, Class<?> classToCheck) {
+        ArrayList<Symbol> result = new ArrayList<>();
+        for (Type type : SYMBOL_STACK.peek().keySet()) {
+            ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type);
+            for (Symbol symbol : symbolsOfType) {
+                if (classToCheck.isInstance(symbol) && name.equals(symbol.name)) {
+                    result.add(symbol);
+                }
+            }
+        }
+
+        return result;
+    }
+
+    public static Symbol get(String name, Class<?> classToCheck) {
+        for (Type type : SYMBOL_STACK.peek().keySet()) {
+            ArrayList<Symbol> symbolsOfType = SYMBOL_STACK.peek().get(type);
+            for (Symbol symbol : symbolsOfType) {
+                if (classToCheck.isInstance(symbol) && name.equals(symbol.name)) {
+                    return symbol;
+                }
+            }
+        }
+        return null;
+    }
+
+    public static void removeAll() {
+        SYMBOL_STACK.clear();
+        SYMBOL_STACK.push(new HashMap<>());
+        VARIABLE_NUMBER = 0;
+        FUNCTION_NUMBER = 0;
+        if (!ProductionParams.disableExternalSymbols.value()) {
+            initExternalSymbols();
+        }
+    }
+
+    public static void push() {
+        // Do deep cloning..
+        HashMap<Type, ArrayList<Symbol>> prev = SYMBOL_STACK.peek();
+        SYMBOL_STACK.push(new HashMap<>());
+        HashMap<Type, ArrayList<Symbol>> top = SYMBOL_STACK.peek();
+        for (Type type : prev.keySet()) {
+            ArrayList<Symbol> prevArray = prev.get(type);
+            top.put(type, new ArrayList<>(prevArray.size()));
+            ArrayList<Symbol> topArray = top.get(type);
+            for (Symbol symbol : prevArray) {
+                topArray.add(symbol.copy());
+            }
+        }
+    }
+
+    public static void merge() {
+        // Merging means moving element at the top of stack one step down, while removing the
+        // previous element.
+        HashMap<Type, ArrayList<Symbol>> top = SYMBOL_STACK.pop();
+        SYMBOL_STACK.pop();
+        SYMBOL_STACK.push(top);
+    }
+
+    public static void pop() {
+        SYMBOL_STACK.pop();
+    }
+
+    public static int getNextVariableNumber() {
+        return ++VARIABLE_NUMBER;
+    }
+
+    public static int getNextFunctionNumber() {
+        return ++FUNCTION_NUMBER;
+    }
+
+    @Override
+    public String toString() {
+        return SYMBOL_STACK.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TernaryOperator.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,61 @@
+/*
+ * 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 TernaryOperator extends Operator {
+    public enum TernaryPart {
+        CONDITION,
+        TRUE,
+        FALSE,
+    };
+    //protected Production conditionalExpression, leftExpression, rightExpression;
+    protected Type resultType;
+
+    public TernaryOperator(IRNode condition, IRNode trueBranch, IRNode falseBranch) {
+        super(2);
+        resizeUpChildren(TernaryPart.values().length);
+        setChild(TernaryPart.CONDITION.ordinal(), condition);
+        setChild(TernaryPart.TRUE.ordinal(), trueBranch);
+        setChild(TernaryPart.FALSE.ordinal(), falseBranch);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode conditionalExp = getChild(TernaryPart.CONDITION.ordinal());
+        IRNode trueBranch = getChild(TernaryPart.TRUE.ordinal());
+        IRNode falseBranch = getChild(TernaryPart.FALSE.ordinal());
+        if (conditionalExp != null && trueBranch != null && falseBranch != null) {
+            return conditionalExp.complexity() + trueBranch.complexity() + falseBranch.complexity() + 1;
+        } else {
+            return 0;
+        }
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Throw.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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 Throw extends IRNode {
+    public Throw(IRNode throwable) {
+        addChild(throwable);
+    }
+
+    @Override
+    public long complexity() {
+        return getThowable().complexity();
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public IRNode getThowable() {
+        return getChild(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TryCatchBlock.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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.test.lib.jittester;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class TryCatchBlock extends IRNode {
+    public TryCatchBlock(IRNode body, IRNode finallyBlock, List<CatchBlock> catchBlocks, int level) {
+        this.level = level;
+        addChild(body);
+        addChild(finallyBlock);
+        addChildren(catchBlocks);
+    }
+
+    @Override
+    public <T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    @Override
+    public long complexity() {
+        return getChildren().stream()
+                .filter(elem -> elem != null)
+                .collect(Collectors.summingLong(IRNode::complexity));
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/Type.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,80 @@
+/*
+ * 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;
+
+/**
+ * Type system's core..
+ */
+public abstract class Type extends IRNode implements Comparable<Type> {
+
+    private final String typeName;
+
+    protected Type(String typeName) {
+        this.typeName = typeName;
+    }
+
+    @Override
+    public boolean equals(Object t) {
+        if (this == t) {
+            return true;
+        }
+        if (t == null || !(t instanceof Type)) {
+            return false;
+        }
+        return typeName.equals(((Type) t).typeName);
+    }
+
+    @Override
+    public int compareTo(Type t) {
+        return typeName.compareTo(t.typeName);
+    }
+
+    @Override
+    public int hashCode() {
+        return typeName.hashCode();
+    }
+
+    public abstract boolean canImplicitlyCastTo(Type t);
+
+    public abstract boolean canExplicitlyCastTo(Type t);
+
+    public abstract boolean canCompareTo(Type t);
+
+    public abstract boolean canEquateTo(Type t);
+
+    protected void exportSymbols() {
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    @Override
+    public String getName() {
+        return typeName;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TypeList.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,154 @@
+/*
+ * 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 java.util.ArrayList;
+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.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();
+    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<>();
+    private static final List<Type> BUILTIN_FP_TYPES = new ArrayList<>();
+    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_TYPES.addAll(BUILTIN_INT_TYPES);
+        BUILTIN_TYPES.addAll(BUILTIN_FP_TYPES);
+
+        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;
+    }
+
+    public static Collection<Type> getAll() {
+        return TYPES;
+    }
+
+    public static Collection<Type> getBuiltIn() {
+        return BUILTIN_TYPES;
+    }
+
+    public static Collection<Type> getBuiltInInt() {
+        return BUILTIN_INT_TYPES;
+    }
+
+    protected static Collection<Type> getBuiltInFP() {
+        return BUILTIN_FP_TYPES;
+    }
+
+    protected static Collection<Type> getReferenceTypes() {
+        return REFERENCE_TYPES;
+    }
+
+    protected static boolean isBuiltInFP(Type t) {
+        return BUILTIN_FP_TYPES.contains(t);
+    }
+
+    public static boolean isBuiltInInt(Type t) {
+        return BUILTIN_INT_TYPES.contains(t);
+    }
+
+    public static boolean isBuiltIn(Type t) {
+        return isBuiltInInt(t) || isBuiltInFP(t);
+    }
+
+    protected static boolean isIn(Type t) {
+        return TYPES.contains(t);
+    }
+
+    protected static boolean isReferenceType(Type t) {
+        return REFERENCE_TYPES.contains(t);
+    }
+
+    public static Type find(Type t) {
+        int i = TYPES.indexOf(t);
+        if (i != -1) {
+            return TYPES.get(i);
+        }
+        return null;
+    }
+
+    protected static Type findReferenceType(Type t) {
+        int i = REFERENCE_TYPES.indexOf(t);
+        if (i != -1) {
+            return REFERENCE_TYPES.get(i);
+        }
+        return null;
+    }
+
+    public static Type find(String name) {
+        for (Type t : TYPES) {
+            if (t.getName().equals(name)) {
+                return t;
+            }
+        }
+        return null;
+    }
+
+    public static void add(Type t) {
+        REFERENCE_TYPES.add(t);
+        TYPES.add(t);
+    }
+
+    protected static void remove(Type t) {
+        REFERENCE_TYPES.remove(t);
+        TYPES.remove(t);
+    }
+
+    public static void removeAll() {
+        Predicate<? super Type> isNotBasic = t -> t.getName().startsWith("Test_");
+        TYPES.removeIf(isNotBasic);
+        REFERENCE_TYPES.removeIf(isNotBasic);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TypeUtil.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,85 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class TypeUtil {
+
+    public static Collection<Type> getImplicitlyCastable(Collection<Type> types, Type type) {
+        ArrayList<Type> result = new ArrayList<>(types);
+        Iterator<Type> iterator = result.iterator();
+        while (iterator.hasNext()) {
+            if (!iterator.next().canImplicitlyCastTo(type)) {
+                iterator.remove();
+            }
+        }
+        return result;
+    }
+
+    public static Collection<Type> getExplicitlyCastable(Collection<Type> types, Type type) {
+        ArrayList<Type> result = new ArrayList<>(types);
+        Iterator<Type> iterator = result.iterator();
+        while (iterator.hasNext()) {
+            if (!iterator.next().canExplicitlyCastTo(type)) {
+                iterator.remove();
+            }
+        }
+        return result;
+    }
+
+    public static List<Type> getMoreCapatiousThan(Collection<Type> types, BuiltInType type) {
+        ArrayList<Type> result = new ArrayList<>();
+        Iterator<Type> iterator = types.iterator();
+        while (iterator.hasNext()) {
+            try {
+                BuiltInType builtInType = (BuiltInType) iterator.next();
+                if (builtInType.isMoreCapaciousThan(type)) {
+                    result.add(builtInType);
+                }
+            } catch (Exception e) {
+            }
+        }
+        return result;
+    }
+
+    public static List<Type> getLessCapatiousOrEqualThan(Collection<Type> types, BuiltInType type) {
+        ArrayList<Type> result = new ArrayList<>();
+        Iterator<Type> iterator = types.iterator();
+        while (iterator.hasNext()) {
+            try {
+                BuiltInType builtInType = (BuiltInType) iterator.next();
+                if (!builtInType.isMoreCapaciousThan(type) || builtInType.equals(type)) {
+                    result.add(builtInType);
+                }
+            } catch (Exception e) {
+            }
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/TypesParser.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,359 @@
+/*
+ * 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.test.lib.jittester;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringReader;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import jdk.test.lib.Asserts;
+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
+ */
+public class TypesParser {
+
+    private static final HashMap<Class<?>, Type> TYPE_CACHE = new HashMap<>();
+
+    /**
+     * Parses included classes file and excluded methods file to TypeList and SymbolTable.
+     * This routine takes all classes named in the classes file and puts them to the TypeList,
+     * it also puts all the methods of the classes to the SymbolTable.
+     * Excluded methods file is used to remove methods from the SymbolTable.
+     * @param klassesFileName - name of the included classes file
+     * @param exMethodsFileName - name of the excluded method file
+     */
+    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);
+        Set<Executable> methodsToExclude;
+        if (exMethodsFileName != null && !exMethodsFileName.isEmpty()) {
+            methodsToExclude = parseMethods(exMethodsFileName);
+        } else {
+            methodsToExclude = new HashSet<>();
+        }
+        klasses.stream().forEach(klass -> {
+            TypeKlass typeKlass = (TypeKlass) getType(klass);
+            if (TypeList.isReferenceType(typeKlass)) {
+                return;
+            }
+            TypeList.add(typeKlass);
+            Set<Executable> methods = new HashSet<>();
+            methods.addAll(Arrays.asList(klass.getMethods()));
+            methods.addAll(Arrays.asList(klass.getConstructors()));
+            methods.removeAll(methodsToExclude);
+            methods.stream().forEach(method -> {
+                if (method.isSynthetic()) {
+                    return;
+                }
+                String name = method.getName();
+                boolean isConstructor = false;
+                Type returnType;
+                if (name.equals(klass.getName())) {
+                    isConstructor = true;
+                    returnType = typeKlass;
+                } else {
+                    returnType = getType(((Method) method).getReturnType());
+                }
+                ArrayList<VariableInfo> paramList = new ArrayList<>();
+                int flags = getMethodFlags(method);
+                if (!isConstructor && ((flags & FunctionInfo.STATIC) == 0)) {
+                    paramList.add(new VariableInfo("this", typeKlass, typeKlass,
+                            VariableInfo.LOCAL | VariableInfo.INITIALIZED));
+                }
+                Class<?>[] paramKlasses = method.getParameterTypes();
+                int argNum = 0;
+                for (Class<?> paramKlass : paramKlasses) {
+                    argNum++;
+                    Type paramType = getType(paramKlass);
+                    paramList.add(new VariableInfo("arg" + argNum, typeKlass, paramType,
+                            VariableInfo.LOCAL | VariableInfo.INITIALIZED));
+                }
+                typeKlass.addSymbol(new FunctionInfo(name, typeKlass, returnType, 1, flags,
+                        paramList));
+            });
+        });
+    }
+
+    private static Type getType(Class<?> klass) {
+        Type type = TYPE_CACHE.get(klass);
+        if (type != null) {
+            return type;
+        }
+        if (klass.isPrimitive()) {
+            if (klass.equals(void.class)) {
+                type = new TypeVoid();
+            } else {
+                type = TypeList.find(klass.getName());
+            }
+        } else {
+            int flags = getKlassFlags(klass);
+            if (klass.isArray()) {
+                TypeKlass elementType
+                        = new TypeKlass(klass.getCanonicalName().replaceAll("\\[\\]", ""), flags);
+                int dim = getArrayClassDimension(klass);
+                type = new TypeArray(elementType, dim);
+            } else {
+                String canonicalName = klass.getCanonicalName();
+                if (!"java.lang.Object".equals(canonicalName)) {
+                    flags |= TypeKlass.FINAL;
+                }
+                type = new TypeKlass(canonicalName, flags);
+            }
+            Class<?> parentKlass = klass.getSuperclass();
+            if (parentKlass != null) {
+                TypeKlass parentTypeKlass = (TypeKlass) getType(parentKlass);
+                ((TypeKlass) type).addParent(parentTypeKlass.getName());
+                ((TypeKlass) type).setParent(parentTypeKlass);
+            }
+        }
+        TYPE_CACHE.put(klass, type);
+        return type;
+    }
+
+    private static int getArrayClassDimension(Class<?> klass) {
+        if (!klass.isArray()) {
+            return 0;
+        }
+        String name = klass.getName();
+        int begin = name.indexOf('[');
+        name = name.substring(begin, name.length());
+        return name.length() / 2;
+    }
+
+    private static int getKlassFlags(Class<?> klass) {
+        int flags = TypeKlass.NONE;
+        if (klass.isInterface()) {
+            flags = flags | TypeKlass.INTERFACE;
+        } else if ((klass.getModifiers() & Modifier.ABSTRACT) != 0) {
+            flags = flags | TypeKlass.ABSTRACT;
+        } else if ((klass.getModifiers() & Modifier.FINAL) != 0) {
+            flags = flags | TypeKlass.FINAL;
+        }
+        return flags;
+    }
+
+    private static int getMethodFlags(Executable method) {
+        int flags = FunctionInfo.NONE;
+        int modifiers = method.getModifiers();
+        if (Modifier.isAbstract(modifiers)) {
+            flags |= FunctionInfo.ABSTRACT;
+        }
+        if (Modifier.isFinal(modifiers)) {
+            flags |= FunctionInfo.FINAL;
+        }
+        if (Modifier.isPublic(modifiers)) {
+            flags |= FunctionInfo.PUBLIC;
+        } else if (Modifier.isProtected(modifiers)) {
+            flags |= FunctionInfo.PROTECTED;
+        } else if (Modifier.isPrivate(modifiers)) {
+            flags |= FunctionInfo.PRIVATE;
+        } else {
+            flags |= FunctionInfo.DEFAULT;
+        }
+        if (Modifier.isStatic(modifiers)) {
+            flags |= FunctionInfo.STATIC;
+        }
+        if (Modifier.isSynchronized(modifiers)) {
+            flags |= FunctionInfo.SYNCHRONIZED;
+        }
+        return flags;
+    }
+
+    private static Set<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<>();
+        Path klassesFilePath = (new File(klassesFileName)).toPath();
+        try {
+            Files.lines(klassesFilePath).forEach(line -> {
+                line = line.trim();
+                if (line.isEmpty()) {
+                    return;
+                }
+                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(";", ""));
+            });
+        } catch (IOException ex) {
+            throw new Error("Error reading klasses file", ex);
+        }
+        Set<Class<?>> klassesSet = new HashSet<>();
+        klassNamesSet.stream().forEach(klassName -> {
+            try {
+                klassesSet.add(Class.forName(klassName));
+            } catch (ClassNotFoundException ex) {
+                throw new Error("Unexpected exception while parsing klasses file", ex);
+            }
+        });
+        return klassesSet;
+    }
+
+    private static Set<Executable> parseMethods(String methodsFileName) {
+        Asserts.assertNotNull(methodsFileName, "Methods exclude input file name is null");
+        Asserts.assertFalse(methodsFileName.isEmpty(), "Methods exclude input file name is empty");
+        LinkedList<String> methodNamesList = new LinkedList<>();
+        Path klassesFilePath = (new File(methodsFileName)).toPath();
+        try {
+            Files.lines(klassesFilePath).forEach(line -> {
+                line = line.trim();
+                if (line.isEmpty()) {
+                    return;
+                }
+                String msg = String.format("Format of the methods exclude input file \"%s\" is incorrect,"
+                        + " line \"%s\" has wrong format", methodsFileName, line);
+                Asserts.assertTrue(line.matches("\\w[\\w/$]*::[\\w$]+\\((\\[?[ZBSCIJFD]|\\[?L[\\w/$]+;)*\\)"), msg);
+                methodNamesList.add(line.substring(0, line.length() - 1));
+            });
+        } catch (IOException ex) {
+            throw new Error("Error reading exclude method file", ex);
+        }
+        Set<Executable> methodsList = new HashSet<>();
+        methodNamesList.stream().forEach(methodName -> {
+            String[] klassAndNameAndSig = methodName.split("::");
+            String klassName = klassAndNameAndSig[0].replaceAll("/", "\\.");
+            String[] nameAndSig = klassAndNameAndSig[1].split("[\\(\\)]");
+            String name = nameAndSig[0];
+            String signature = "";
+            if (nameAndSig.length > 1) {
+                signature = nameAndSig[1];
+            }
+            Class<?> klass = null;
+            List<Class<?>> signatureTypes = null;
+            try {
+                klass = Class.forName(klassName);
+                signatureTypes = parseSignature(signature);
+            } catch (ClassNotFoundException ex) {
+                throw new Error("Unexpected exception while parsing exclude methods file", ex);
+            }
+            try {
+                Executable method;
+                if (name.equals(klass.getSimpleName())) {
+                    method = klass.getConstructor(signatureTypes.toArray(new Class<?>[0]));
+                } else {
+                    method = klass.getMethod(name, signatureTypes.toArray(new Class<?>[0]));
+                }
+                methodsList.add(method);
+            } catch (NoSuchMethodException | SecurityException ex) {
+                throw new Error("Unexpected exception while parsing exclude methods file", ex);
+            }
+        });
+        return methodsList;
+    }
+
+    private static List<Class<?>> parseSignature(String signature) throws ClassNotFoundException {
+        LinkedList<Class<?>> sigClasses = new LinkedList<>();
+        char typeChar;
+        boolean isArray;
+        String klassName;
+        StringBuilder sb;
+        StringBuilder arrayDim;
+        try (StringReader str = new StringReader(signature)) {
+            int symbol = str.read();
+            while (symbol != -1){
+                typeChar = (char) symbol;
+                arrayDim = new StringBuilder();
+                Class<?> primArrayClass = null;
+                if (typeChar == '[') {
+                    isArray = true;
+                    arrayDim.append('[');
+                    symbol = str.read();
+                    while (symbol == '['){
+                        arrayDim.append('[');
+                        symbol = str.read();
+                    }
+                    typeChar = (char) symbol;
+                    if (typeChar != 'L') {
+                        primArrayClass = Class.forName(arrayDim.toString() + typeChar);
+                    }
+                } else {
+                    isArray = false;
+                }
+                switch (typeChar) {
+                    case 'Z':
+                        sigClasses.add(isArray ? primArrayClass : boolean.class);
+                        break;
+                    case 'I':
+                        sigClasses.add(isArray ? primArrayClass : int.class);
+                        break;
+                    case 'J':
+                        sigClasses.add(isArray ? primArrayClass : long.class);
+                        break;
+                    case 'F':
+                        sigClasses.add(isArray ? primArrayClass : float.class);
+                        break;
+                    case 'D':
+                        sigClasses.add(isArray ? primArrayClass : double.class);
+                        break;
+                    case 'B':
+                        sigClasses.add(isArray ? primArrayClass : byte.class);
+                        break;
+                    case 'S':
+                        sigClasses.add(isArray ? primArrayClass : short.class);
+                        break;
+                    case 'C':
+                        sigClasses.add(isArray ? primArrayClass : char.class);
+                        break;
+                    case 'L':
+                        sb = new StringBuilder();
+                        symbol = str.read();
+                        while (symbol != ';') {
+                            sb.append((char) symbol);
+                            symbol = str.read();
+                        }
+                        klassName = sb.toString().replaceAll("/", "\\.");
+                        if (isArray) {
+                            klassName = arrayDim.toString() + "L" + klassName + ";";
+                        }
+                        Class<?> klass = Class.forName(klassName);
+                        sigClasses.add(klass);
+                        break;
+                    default:
+                        throw new Error("Unknown type " + typeChar);
+                }
+                symbol = str.read();
+            }
+        } catch (IOException ex) {
+            throw new Error("Unexpected exception while parsing exclude methods file", ex);
+        }
+        return sigClasses;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/UnaryOperator.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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 UnaryOperator extends Operator {
+    protected OperatorKind opKind;
+    protected Type resultType;
+
+    public UnaryOperator(OperatorKind opKind, IRNode expression) {
+        super(opKind.priority);
+        this.opKind = opKind;
+        addChild(expression);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode expression = getChild(0);
+        return expression != null ? expression.complexity() + 1 : 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public boolean isPrefix() {
+        return opKind.isPrefix;
+    }
+
+    public String getOperatorText() {
+        return opKind.text;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableBase.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+public interface VariableBase {
+
+    VariableInfo get();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableDeclaration.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,48 @@
+/*
+ * 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 VariableDeclaration extends IRNode {
+    protected final VariableInfo variableInfo;
+
+    public VariableDeclaration(VariableInfo value) {
+        variableInfo = value;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public VariableInfo getVariableInfo() {
+        return variableInfo;
+    }
+
+    @Override
+    public String getName() {
+        return variableInfo.name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableDeclarationBlock.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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 java.util.ArrayList;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class VariableDeclarationBlock extends IRNode {
+    public VariableDeclarationBlock(ArrayList<IRNode> content, int level) {
+        addChildren(content);
+        this.level = level;
+    }
+
+    @Override
+    public long complexity() {
+        return getChildren()
+                .stream()
+                .mapToLong(IRNode::complexity)
+                .sum();
+    }
+
+    protected int size() {
+        return getChildren() != null ? getChildren().size() : 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableInfo.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,58 @@
+/*
+ * 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.types.TypeKlass;
+
+
+public class VariableInfo extends Symbol {
+
+    public static final int LOCAL = 0x40;
+    public static final int INITIALIZED = 0x80;
+
+    protected VariableInfo() {
+    }
+
+    public VariableInfo(VariableInfo value) {
+        super(value);
+    }
+
+    public VariableInfo(String name, TypeKlass owner, Type type, int flags) {
+        super(name, owner, type, flags);
+    }
+
+    public VariableInfo(TypeKlass owner, Type type) {
+        super("", owner, type, Symbol.NONE);
+    }
+
+    @Override
+    protected Symbol copy() {
+        return new VariableInfo(this);
+    }
+
+    @Override
+    public Symbol deepCopy() {
+        return new VariableInfo(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/VariableInitialization.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+public class VariableInitialization extends Initialization {
+    public VariableInitialization(VariableInfo info, IRNode initExpression) {
+        super(info, initExpression);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/arrays/ArrayCreation.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,78 @@
+/*
+ * 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.arrays;
+
+import java.util.ArrayList;
+import java.util.List;
+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;
+
+public class ArrayCreation extends IRNode {
+    private final VariableDeclaration variable;
+    private final TypeArray array;
+    private final List<Byte> dims;
+
+    public ArrayCreation(VariableDeclaration var, TypeArray array, ArrayList<IRNode> dimensionSizeExpressions) {
+        this.variable = var;
+        this.array = array;
+        addChildren(dimensionSizeExpressions);
+        this.dims = dimensionSizeExpressions.stream()
+                .map(d -> {
+                    if (d instanceof Literal) {
+                        Literal n = (Literal) d;
+                        return (Byte)n.getValue();
+                    }
+                    return (byte)0;
+                })
+                .collect(Collectors.toList());
+        TypeArray type = (TypeArray) variable.getVariableInfo().type;
+        type.setDimentions(dims);
+    }
+
+    public Type getArrayType() {
+        return array.type;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public byte getDimensionSize(int dimensionIndex) {
+        return dims.get(dimensionIndex);
+    }
+
+    public int getDimensionsCount() {
+        return dims.size();
+    }
+
+    public VariableDeclaration getVariable() {
+        return variable;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/arrays/ArrayElement.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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.arrays;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class ArrayElement extends IRNode {
+    public ArrayElement(IRNode array, ArrayList<IRNode> dimensionExpressions) {
+        addChild(array);
+        addChildren(dimensionExpressions);
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/arrays/ArrayExtraction.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,89 @@
+/*
+ * 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.arrays;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Literal;
+import jdk.test.lib.jittester.LocalVariable;
+import jdk.test.lib.jittester.types.TypeArray;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+
+/*
+Array extraction produces and array with N dimentions from an array with M
+dimentions, where N < M.
+ */
+public class ArrayExtraction extends IRNode {
+    private final List<Byte> dims;
+    public ArrayExtraction(IRNode array, ArrayList<IRNode> dimensionExpressions) {
+        addChild(array);
+        addChildren(dimensionExpressions);
+        if (array instanceof ArrayCreation) {
+            dims = new ArrayList<>();
+            ArrayCreation ac = (ArrayCreation) array;
+            for (int i = dimensionExpressions.size(); i < ac.getDimensionsCount(); ++i) {
+                dims.add(ac.getDimensionSize(i));
+            }
+        } else if (array instanceof ArrayExtraction) {
+            dims = new ArrayList<>();
+            ArrayExtraction ae = (ArrayExtraction) array;
+            for (int i = dimensionExpressions.size(); i < ae.getDimsNumber(); ++i) {
+                dims.add(ae.getDim(i));
+            }
+        } else if (array instanceof LocalVariable) {
+            LocalVariable loc = (LocalVariable) array;
+            TypeArray type = (TypeArray) loc.get().type;
+            dims = type.getDims();
+            for (int i = dimensionExpressions.size(); i < type.dimensions; ++i) {
+                dims.add(type.getDims().get(i));
+            }
+        } else {
+            dims = dimensionExpressions.stream()
+                .map(d -> {
+                    if (d instanceof Literal) {
+                        Literal n = (Literal) d;
+                        return (Byte)n.getValue();
+                    }
+                    return (byte)0;
+                })
+                .collect(Collectors.toList());
+        }
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public byte getDim(int dim) {
+        return dims.get(dim);
+    }
+
+    public int getDimsNumber() {
+        return dims.size();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/ClassDefinitionBlock.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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.classes;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class ClassDefinitionBlock extends IRNode {
+    public ClassDefinitionBlock(ArrayList<IRNode> content, int level) {
+        this.level = level;
+        addChildren(content);
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/Interface.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,59 @@
+/*
+ * 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.classes;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class Interface extends IRNode {
+    private final String name;
+    private TypeKlass parent = null;
+
+    public Interface(TypeKlass parent, String name, int level, IRNode functionDeclaraionBlock) {
+        this.parent = parent;
+        this.name = name;
+        this.level = level;
+        addChild(functionDeclaraionBlock);
+    }
+
+    @Override
+    public long complexity() {
+        return 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public TypeKlass getParentKlass() {
+        return parent;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/Klass.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,97 @@
+/*
+ * 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.classes;
+
+import java.util.ArrayList;
+import java.util.List;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+
+public class Klass extends IRNode {
+
+    public TypeKlass getThisKlass() {
+        return thisKlass;
+    }
+
+    public List<TypeKlass> getInterfaces() {
+        return interfaces;
+    }
+
+    public TypeKlass getParentKlass() {
+        return parentKlass;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    public enum KlassPart {
+        DATA_MEMBERS,
+        CONSTRUCTORS,
+        REDEFINED_FUNCTIONS,
+        OVERRIDEN_FUNCTIONS,
+        MEMBER_FUNCTIONS,
+        MEMBER_FUNCTIONS_DECLARATIONS,
+        PRINT_VARIABLES,
+    }
+
+    protected final String name;
+    protected final TypeKlass thisKlass;
+    private final TypeKlass parentKlass;
+    private final ArrayList<TypeKlass> interfaces;
+
+    public Klass(TypeKlass thisKlass, TypeKlass parent,
+            ArrayList<TypeKlass> interfaces, String name, int level,
+            IRNode variableDeclarations, IRNode constructorDefinitions,
+            IRNode functionDefinitions, IRNode abstractFunctionRedefinitions,
+            IRNode overridenFunctionRedefitions, IRNode functionDeclarations,
+            IRNode printVariablesBlock) {
+        this.thisKlass = thisKlass;
+        klass = 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);
+    }
+
+    @Override
+    public long complexity() {
+        return 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/classes/MainKlass.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,67 @@
+/*
+ * 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.classes;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class MainKlass extends IRNode {
+    public enum MainKlassPart {
+        DATA_MEMBERS,
+        MEMBER_FUNCTIONS,
+        TEST_FUNCTION,
+        PRINT_VARIABLES,
+    }
+
+    private final String name;
+    private final TypeKlass thisKlass;
+
+    public MainKlass(String name, TypeKlass thisKlass, IRNode variableDeclarations,
+            IRNode functionDefinitions, IRNode testFunction, IRNode printVariables) {
+        addChild(variableDeclarations);
+        addChild(functionDefinitions);
+        addChild(testFunction);
+        addChild(printVariables);
+        this.name = name;
+        this.thisKlass = thisKlass;
+    }
+
+    @Override
+    public long complexity() {
+        IRNode dataMembers = getChild(MainKlassPart.DATA_MEMBERS.ordinal());
+        IRNode testFunction = getChild(MainKlassPart.TEST_FUNCTION.ordinal());
+        return dataMembers.complexity() + testFunction.complexity();
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArgumentDeclarationFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.ProductionParams;
+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.functions.ArgumentDeclaration;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class ArgumentDeclarationFactory extends Factory {
+    private final int argumentNumber;
+    private final TypeKlass ownerClass;
+
+    ArgumentDeclarationFactory(TypeKlass ownerClass, int argumentNumber) {
+        this.ownerClass = ownerClass;
+        this.argumentNumber = argumentNumber;
+    }
+
+    @Override
+    public ArgumentDeclaration produce() throws ProductionFailedException {
+        Type resultType = PseudoRandom.randomElement(TypeList.getAll());
+        String resultName = "arg_" + argumentNumber;
+        int flags = ((!ProductionParams.disableFinalVariables.value()
+                && PseudoRandom.randomBoolean()) ? VariableInfo.FINAL : VariableInfo.NONE)
+                | VariableInfo.LOCAL | VariableInfo.INITIALIZED;
+        VariableInfo v = new VariableInfo(resultName, ownerClass, resultType, flags);
+        SymbolTable.add(v);
+        return new ArgumentDeclaration(v);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArithmeticOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,61 @@
+/*
+ * 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.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.Rule;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class ArithmeticOperatorFactory extends Factory {
+    private final Rule rule;
+
+    ArithmeticOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) throws ProductionFailedException {
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setOwnerKlass(ownerClass)
+                .setResultType(resultType)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts);
+        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());
+        if (!exceptionSafe) {
+            rule.add("div", builder.setOperatorKind(OperatorKind.DIV).getBinaryOperatorFactory());
+            rule.add("mod", builder.setOperatorKind(OperatorKind.MOD).getBinaryOperatorFactory());
+        }
+        rule.add("unary_plus", builder.setOperatorKind(OperatorKind.UNARY_PLUS).getUnaryOperatorFactory());
+        rule.add("unary_minus", builder.setOperatorKind(OperatorKind.UNARY_MINUS).getUnaryOperatorFactory());
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        return rule.produce();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArrayCreationFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,98 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+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.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 {
+    private final long complexityLimit;
+    private final int operatorLimit;
+    private final Type resultType;
+    private final boolean exceptionSafe;
+    private final boolean noconsts;
+    private final TypeKlass ownerClass;
+
+    ArrayCreationFactory(long complexityLimit, int operatorLimit,
+            TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+        this.ownerClass = ownerClass;
+        this.resultType = resultType;
+        this.exceptionSafe = exceptionSafe;
+        this.noconsts = noconsts;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        if (resultType instanceof TypeArray) {
+            TypeArray arrayResultType = (TypeArray) resultType;
+            if (arrayResultType.type.equals(new TypeVoid())) {
+                arrayResultType = arrayResultType.produce();
+            }
+            IRNodeBuilder builder = new IRNodeBuilder()
+                    .setComplexityLimit(complexityLimit)
+                    .setOwnerKlass(ownerClass)
+                    .setResultType(new TypeByte())
+                    .setExceptionSafe(exceptionSafe)
+                    .setNoConsts(noconsts);
+            double chanceExpression = ProductionParams.chanceExpressionIndex.value() / 100;
+            ArrayList<IRNode> dims = new ArrayList<>(arrayResultType.dimensions);
+            for (int i = 0; i < arrayResultType.dimensions; i++) {
+                if (PseudoRandom.randomBoolean(chanceExpression)) {
+                    dims.add(builder.setOperatorLimit((int) (PseudoRandom.random()
+                                * operatorLimit / arrayResultType.dimensions))
+                            .getExpressionFactory()
+                            .produce());
+                } else {
+                    Literal dimension = (Literal)builder.getLiteralFactory().produce();
+                    while (Integer.valueOf(dimension.getValue().toString()) < 1) {
+                        dimension = (Literal)builder.getLiteralFactory().produce();
+                    }
+                    dims.add(dimension);
+                }
+            }
+            VariableDeclaration var =  (VariableDeclaration) builder
+                    .setOwnerKlass(ownerClass)
+                    .setResultType(arrayResultType)
+                    .setIsLocal(true)
+                    .setIsStatic(false)
+                    .getVariableDeclarationFactory()
+                    .produce();
+            return new ArrayCreation(var, arrayResultType, dims);
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArrayElementFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,104 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+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.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 {
+    private final long complexityLimit;
+    private final int operatorLimit;
+    private final Type resultType;
+    private final TypeKlass ownerClass;
+    private final boolean exceptionSafe;
+    private final boolean noconsts;
+
+    ArrayElementFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) {
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+        this.ownerClass = ownerClass;
+        this.resultType = resultType;
+        this.exceptionSafe = exceptionSafe;
+        this.noconsts = noconsts;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        if (resultType instanceof TypeArray) {
+            throw new ProductionFailedException();
+        }
+        long arrayComplexityLimit = (long) (complexityLimit * 0.5 * PseudoRandom.random());
+        int arrayOperatorLimit = (int) (operatorLimit * 0.5 * PseudoRandom.random());
+        int dimensionsCount = PseudoRandom.randomNotZero(ProductionParams.dimensionsLimit.value());
+        long complexityPerDimension = (long) ((complexityLimit - arrayComplexityLimit)
+                * PseudoRandom.random()) / dimensionsCount;
+        int operatorLimitPerDimension = (int) ((operatorLimit - arrayOperatorLimit - dimensionsCount)
+                * PseudoRandom.random()) / dimensionsCount;
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(ownerClass)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts);
+        IRNode arrayReturningExpression = builder
+                .setComplexityLimit(arrayComplexityLimit)
+                .setOperatorLimit(arrayOperatorLimit)
+                .setResultType(new TypeArray(resultType, dimensionsCount))
+                .getExpressionFactory()
+                .produce();
+        ExpressionFactory expressionFactory = builder
+                .setComplexityLimit(complexityPerDimension)
+                .setOperatorLimit(operatorLimitPerDimension)
+                .setResultType(new TypeByte())
+                .getExpressionFactory();
+        double chanceExpression = ProductionParams.chanceExpressionIndex.value() / 100.;
+        ArrayList<IRNode> perDimensionExpressions = new ArrayList<>(dimensionsCount);
+        for (int i = 0; i < dimensionsCount; i++) {
+            if (PseudoRandom.randomBoolean(chanceExpression)) {
+                perDimensionExpressions.add(expressionFactory.produce());
+            } else {
+                byte dimLimit = 0;
+                if (arrayReturningExpression instanceof ArrayCreation) {
+                    ArrayCreation arrayCreation = (ArrayCreation) arrayReturningExpression;
+                    dimLimit = arrayCreation.getDimensionSize(i);
+                } else if (arrayReturningExpression instanceof ArrayExtraction) {
+                    ArrayExtraction arrayExtraction = (ArrayExtraction) arrayReturningExpression;
+                    if (i < arrayExtraction.getDimsNumber())
+                        dimLimit = arrayExtraction.getDim(i);
+                }
+                perDimensionExpressions.add(new Literal(PseudoRandom.randomNotNegative(dimLimit), new TypeByte()));
+            }
+        }
+        return new ArrayElement(arrayReturningExpression, perDimensionExpressions);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ArrayExtractionFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,105 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+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.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 {
+    private final long complexityLimit;
+    private final int operatorLimit;
+    private final Type resultType;
+    private final TypeKlass ownerClass;
+    private final boolean exceptionSafe;
+    private final boolean noconsts;
+
+    ArrayExtractionFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) {
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+        this.ownerClass = ownerClass;
+        this.resultType = resultType;
+        this.exceptionSafe = exceptionSafe;
+        this.noconsts = noconsts;
+    }
+
+    @Override
+    public IRNode sproduce() throws ProductionFailedException {
+        if (resultType instanceof TypeArray) {
+            TypeArray arrayType = (TypeArray) resultType;
+            int delta = PseudoRandom.randomNotZero(ProductionParams.dimensionsLimit.value()
+                    - arrayType.dimensions);
+            if (arrayType.dimensions + delta <= ProductionParams.dimensionsLimit.value()) {
+                long arrayComplLimit = (long) (complexityLimit * 0.5 * PseudoRandom.random());
+                int arrayOpLimit = (int) (operatorLimit * 0.5 * PseudoRandom.random());
+                IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(ownerClass)
+                        .setExceptionSafe(exceptionSafe)
+                        .setNoConsts(noconsts);
+                IRNode arrayReturningExpression = builder
+                        .setComplexityLimit(arrayComplLimit)
+                        .setOperatorLimit(arrayOpLimit)
+                        .setResultType(new TypeArray(arrayType.type, arrayType.dimensions + delta))
+                        .getExpressionFactory().produce();
+                ArrayList<IRNode> perDimensionExpression = new ArrayList<>(delta);
+                long dimComplLimit = (long) ((complexityLimit - arrayComplLimit)
+                        * PseudoRandom.random()) / delta;
+                int dimOpLimit = (int) ((operatorLimit - arrayOpLimit - delta)
+                        * PseudoRandom.random()) / delta;
+                double chanceExpression = ProductionParams.chanceExpressionIndex.value() / 100.;
+                for (int i = 0; i < delta; i++) {
+                    if (PseudoRandom.randomBoolean(chanceExpression)) {
+                        perDimensionExpression.add(builder.setResultType(new TypeByte())
+                                .setComplexityLimit(dimComplLimit)
+                                .setOperatorLimit(dimOpLimit)
+                                .getExpressionFactory()
+                                .produce());
+                    } else {
+                        byte dimLimit = 0;
+                        if (arrayReturningExpression instanceof ArrayCreation) {
+                            ArrayCreation arratCreation = (ArrayCreation) arrayReturningExpression;
+                            dimLimit = arratCreation.getDimensionSize(i);
+                        } else if (arrayReturningExpression instanceof ArrayExtraction) {
+                            ArrayExtraction arrayExtraction = (ArrayExtraction) arrayReturningExpression;
+                            if (i < arrayExtraction.getDimsNumber())
+                                dimLimit = arrayExtraction.getDim(i);
+                        }
+                        perDimensionExpression.add(new Literal(PseudoRandom.randomNotNegative(dimLimit), new TypeByte()));
+                    }
+                }
+                return new ArrayExtraction(arrayReturningExpression, perDimensionExpression);
+            }
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/AssignmentOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,106 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.OperatorKind;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.Rule;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class AssignmentOperatorFactory extends Factory {
+    private final int operatorLimit;
+    private final long complexityLimit;
+    private final Type resultType;
+    private final boolean exceptionSafe;
+    private final boolean noconsts;
+    private final TypeKlass ownerClass;
+
+    private Rule fillRule(Type resultType) throws ProductionFailedException {
+        Rule rule = new Rule("assignment");
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setOwnerKlass(ownerClass)
+                .setResultType(resultType)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts);
+        rule.add("simple_assign", builder.setOperatorKind(OperatorKind.ASSIGN).getBinaryOperatorFactory());
+        rule.add("compound_add", builder.setOperatorKind(OperatorKind.COMPOUND_ADD).getBinaryOperatorFactory());
+        rule.add("compound_sub", builder.setOperatorKind(OperatorKind.COMPOUND_SUB).getBinaryOperatorFactory());
+        rule.add("compound_mul", builder.setOperatorKind(OperatorKind.COMPOUND_MUL).getBinaryOperatorFactory());
+        if (!exceptionSafe) {
+            rule.add("compound_div", builder.setOperatorKind(OperatorKind.COMPOUND_DIV).getBinaryOperatorFactory());
+            rule.add("compound_mod", builder.setOperatorKind(OperatorKind.COMPOUND_MOD).getBinaryOperatorFactory());
+        }
+        rule.add("compound_and", builder.setOperatorKind(OperatorKind.COMPOUND_AND).getBinaryOperatorFactory());
+        rule.add("compound_or", builder.setOperatorKind(OperatorKind.COMPOUND_OR).getBinaryOperatorFactory());
+        rule.add("compound_xor", builder.setOperatorKind(OperatorKind.COMPOUND_XOR).getBinaryOperatorFactory());
+        rule.add("compound_shr", builder.setOperatorKind(OperatorKind.COMPOUND_SHR).getBinaryOperatorFactory());
+        rule.add("compound_sar", builder.setOperatorKind(OperatorKind.COMPOUND_SAR).getBinaryOperatorFactory());
+        rule.add("compound_shl", builder.setOperatorKind(OperatorKind.COMPOUND_SHL).getBinaryOperatorFactory());
+
+        rule.add("prefix_inc", builder.setOperatorKind(OperatorKind.PRE_INC).getUnaryOperatorFactory());
+        rule.add("prefix_dec", builder.setOperatorKind(OperatorKind.PRE_DEC).getUnaryOperatorFactory());
+        rule.add("postfix_inc", builder.setOperatorKind(OperatorKind.POST_INC).getUnaryOperatorFactory());
+        rule.add("postfix_dec", builder.setOperatorKind(OperatorKind.POST_DEC).getUnaryOperatorFactory());
+        return rule;
+    }
+
+    AssignmentOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) {
+        this.ownerClass = ownerClass;
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+        this.resultType = resultType;
+        this.exceptionSafe = exceptionSafe;
+        this.noconsts = noconsts;
+    }
+
+    @Override
+    public IRNode 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();
+                    SymbolTable.merge();
+                    return result;
+                } catch (ProductionFailedException e) {
+                    SymbolTable.pop();
+                }
+            }
+        } else {
+            return fillRule(resultType).produce();
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/AssignmentOperatorImplFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,90 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+import jdk.test.lib.jittester.BinaryOperator;
+import jdk.test.lib.jittester.IRNode;
+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.TypeList;
+import jdk.test.lib.jittester.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;
+
+class AssignmentOperatorImplFactory extends BinaryOperatorFactory {
+    AssignmentOperatorImplFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(OperatorKind.ASSIGN, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return true;
+    }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        return new Pair<>(resultType, PseudoRandom.randomElement(
+                TypeUtil.getImplicitlyCastable(TypeList.getAll(), resultType)));
+    }
+
+    @Override
+    protected BinaryOperator generateProduction(Type leftOperandType, Type rightOperandType)
+            throws ProductionFailedException {
+        long leftComplexityLimit = (long) (PseudoRandom.random() * complexityLimit);
+        long rightComplexityLimit = complexityLimit - leftComplexityLimit;
+        int leftOperatorLimit = (int) (PseudoRandom.random() * operatorLimit);
+        int rightOperatorLimit = operatorLimit = leftOperatorLimit;
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass((TypeKlass) ownerClass)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts)
+                .setComplexityLimit(leftComplexityLimit)
+                .setOperatorLimit(leftOperatorLimit)
+                .setResultType(leftOperandType)
+                .setIsConstant(false);
+        Rule 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();
+        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;
+            }
+        } catch (Exception e) {
+            throw new ProductionFailedException(e.getMessage());
+        }
+        return new BinaryOperator(opKind, leftOperandValue, rightOperandValue);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryArithmeticOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,66 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+import jdk.test.lib.jittester.BuiltInType;
+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.TypeUtil;
+import jdk.test.lib.jittester.types.TypeInt;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+import java.util.Collection;
+
+class BinaryArithmeticOperatorFactory extends BinaryOperatorFactory {
+    BinaryArithmeticOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
+            TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        // 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());
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        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()) ?
+                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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryBitwiseOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,60 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+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.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;
+
+class BinaryBitwiseOperatorFactory extends BinaryOperatorFactory {
+    BinaryBitwiseOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
+            TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return resultType.equals(new TypeInt()) || resultType.equals(new TypeLong()) || resultType.equals(new TypeBoolean());
+    }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        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;
+        //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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryComparisonOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+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.types.TypeBoolean;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class BinaryComparisonOperatorFactory extends BinaryOperatorFactory {
+    BinaryComparisonOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
+            TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return resultType.equals(new TypeBoolean());
+    }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        final List<Type> builtInExceptBoolean = new ArrayList<>(TypeList.getBuiltIn());
+        builtInExceptBoolean.remove(new TypeBoolean());
+        return new Pair<>(PseudoRandom.randomElement(builtInExceptBoolean),
+                PseudoRandom.randomElement(builtInExceptBoolean));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryEqualityOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+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.types.TypeBoolean;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class BinaryEqualityOperatorFactory extends BinaryOperatorFactory {
+    BinaryEqualityOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
+            TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return resultType.equals(new TypeBoolean());
+    }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        final List<Type> builtInExceptBoolean = new ArrayList<>(TypeList.getBuiltIn());
+        builtInExceptBoolean.remove(new TypeBoolean());
+        return new Pair<>(PseudoRandom.randomElement(builtInExceptBoolean), PseudoRandom.randomElement(builtInExceptBoolean));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryLogicOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,86 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+import jdk.test.lib.jittester.BinaryOperator;
+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.types.TypeBoolean;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+public class BinaryLogicOperatorFactory extends BinaryOperatorFactory {
+    BinaryLogicOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
+            TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return resultType.equals(new TypeBoolean());
+    }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        return new Pair<>(resultType, resultType);
+    }
+
+    @Override
+    protected BinaryOperator generateProduction(Type leftType, Type rightType) throws ProductionFailedException {
+        int leftOpLimit = (int) (PseudoRandom.random() * (operatorLimit - 1));
+        int rightOpLimit = operatorLimit - 1 - leftOpLimit;
+        long leftComplLimit = (long) (PseudoRandom.random() * (complexityLimit - 1));
+        long rightComplLimit = complexityLimit - 1 - leftComplLimit;
+        if (leftOpLimit == 0 || rightOpLimit == 0 || leftComplLimit == 0 || rightComplLimit == 0) {
+            throw new ProductionFailedException();
+        }
+        boolean swap = PseudoRandom.randomBoolean();
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass((TypeKlass) ownerClass)
+                .setExceptionSafe(exceptionSafe);
+        IRNode leftOperand = builder.setComplexityLimit(leftComplLimit)
+                .setOperatorLimit(leftOpLimit)
+                .setResultType(leftType)
+                .setNoConsts(swap && noconsts)
+                .getExpressionFactory()
+                .produce();
+        // Right branch won't necessarily execute. Ignore initalization performed in it.
+        SymbolTable.push();
+        IRNode rightOperand;
+        try {
+            rightOperand = builder.setComplexityLimit(rightComplLimit)
+                    .setOperatorLimit(rightOpLimit)
+                    .setResultType(rightType)
+                    .setNoConsts(!swap && noconsts)
+                    .getExpressionFactory()
+                    .produce();
+        } finally {
+            SymbolTable.pop();
+        }
+        return new BinaryOperator(opKind, leftOperand, rightOperand);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,102 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+import jdk.test.lib.jittester.BinaryOperator;
+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.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+abstract class BinaryOperatorFactory extends OperatorFactory {
+    protected final OperatorKind opKind;
+    protected final Type resultType;
+    protected final Type ownerClass;
+
+    protected BinaryOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
+            Type ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind.priority, complexityLimit, operatorLimit, exceptionSafe, noconsts);
+        this.opKind = opKind;
+        this.resultType = resultType;
+        this.ownerClass = ownerClass;
+    }
+
+    protected abstract boolean isApplicable(Type resultType);
+
+    protected abstract Pair<Type, Type> generateTypes() throws ProductionFailedException;
+
+    protected BinaryOperator generateProduction(Type leftType, Type rightType) throws ProductionFailedException {
+        int leftOpLimit = (int) (PseudoRandom.random() * (operatorLimit - 1));
+        int rightOpLimit = operatorLimit - 1 - leftOpLimit;
+        long leftComplLimit = (long) (PseudoRandom.random() * (complexityLimit - 1));
+        long rightComplLimit = complexityLimit - 1 - leftComplLimit;
+        if (leftOpLimit == 0 || rightOpLimit == 0 || leftComplLimit == 0 || rightComplLimit == 0) {
+            throw new ProductionFailedException();
+        }
+        boolean swap = PseudoRandom.randomBoolean();
+        IRNodeBuilder builder = new IRNodeBuilder().setExceptionSafe(exceptionSafe)
+                .setOwnerKlass((TypeKlass) ownerClass)
+                .setNoConsts(!swap && noconsts);
+        IRNode leftExpr = builder.setComplexityLimit(leftComplLimit)
+                .setOperatorLimit(leftOpLimit)
+                .setResultType(leftType)
+                .getExpressionFactory()
+                .produce();
+        IRNode rightExpr = builder.setComplexityLimit(rightComplLimit)
+                .setOperatorLimit(rightOpLimit)
+                .setResultType(rightType)
+                .getExpressionFactory()
+                .produce();
+        return new BinaryOperator(opKind, leftExpr, rightExpr);
+    }
+
+    @Override
+    public final IRNode produce() throws ProductionFailedException {
+        if (!isApplicable(resultType)) {
+            //avoid implicit use of resultType.toString()
+            throw new ProductionFailedException("Type " + resultType.getName() + " is not applicable by " + getClass().getName());
+        }
+
+        Pair<Type, Type> types;
+        try {
+            types = generateTypes();
+        } catch (RuntimeException ex) {
+            throw new ProductionFailedException(ex.getMessage());
+        }
+
+        try {
+            SymbolTable.push();
+            IRNode p = generateProduction(types.first, types.second);
+            SymbolTable.merge();
+            return p;
+        } catch (ProductionFailedException e) {
+            SymbolTable.pop();
+            throw e;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryShiftOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,54 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+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.TypeUtil;
+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;
+
+class BinaryShiftOperatorFactory extends BinaryOperatorFactory {
+    BinaryShiftOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
+            TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return resultType.equals(new TypeInt()) || resultType.equals(new TypeLong());
+    }
+
+    @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()));
+        return new Pair<>(leftType, rightType);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BinaryStringPlusFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,48 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+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.types.TypeKlass;
+
+class BinaryStringPlusFactory extends BinaryOperatorFactory {
+    BinaryStringPlusFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(OperatorKind.STRADD, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return resultType.equals(TypeList.find("java.lang.String"));
+        }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        return new Pair<>(resultType, resultType);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BitwiseInversionOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,69 @@
+/*
+ * 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.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.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 {
+    BitwiseInversionOperatorFactory(long complexityLimit, int operatorLimit, Type ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(OperatorKind.BIT_NOT, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return resultType.equals(new TypeInt()) || resultType.equals(new TypeLong());
+    }
+
+    @Override
+    protected Type generateType() throws ProductionFailedException {
+        if (resultType.equals(new TypeInt())) {
+            return PseudoRandom.randomElement(TypeUtil.getImplicitlyCastable(TypeList.getBuiltIn(), resultType));
+        } else {
+            return resultType;
+        }
+    }
+
+    @Override
+    protected IRNode generateProduction(Type resultType) throws ProductionFailedException {
+        return new UnaryOperator(opKind, new IRNodeBuilder().setComplexityLimit(complexityLimit - 1)
+                .setOperatorLimit(operatorLimit - 1)
+                .setOwnerKlass((TypeKlass) ownerClass)
+                .setResultType(resultType)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts)
+                .getExpressionFactory()
+                .produce());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BitwiseOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,59 @@
+/*
+ * 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.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.Rule;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class BitwiseOperatorFactory extends Factory {
+    private final Rule rule;
+
+    BitwiseOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) throws ProductionFailedException {
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setOwnerKlass(ownerClass)
+                .setResultType(resultType)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts);
+        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());
+        rule.add("not", builder.setOperatorKind(OperatorKind.BIT_NOT).getUnaryOperatorFactory());
+        rule.add("shl", builder.setOperatorKind(OperatorKind.SHL).getBinaryOperatorFactory());
+        rule.add("shr", builder.setOperatorKind(OperatorKind.SHR).getBinaryOperatorFactory());
+        rule.add("sar", builder.setOperatorKind(OperatorKind.SAR).getBinaryOperatorFactory());
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        return rule.produce();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BlockFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,186 @@
+/*
+ * 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.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.ProductionParams;
+import jdk.test.lib.jittester.Rule;
+import jdk.test.lib.jittester.Switch;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.TypeUtil;
+import jdk.test.lib.jittester.loops.DoWhile;
+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 {
+    private final Type returnType;
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final boolean subBlock;
+    private final boolean canHaveBreaks;
+    private final boolean canHaveContinues;
+    private final boolean canHaveReturn;
+    private final boolean canHaveThrow;
+    private final int level;
+    private final TypeKlass ownerClass;
+
+    BlockFactory(TypeKlass klass, Type returnType, long complexityLimit, int statementLimit,
+                 int operatorLimit, int level, boolean subBlock, boolean canHaveBreaks,
+                 boolean canHaveContinues, boolean canHaveReturn, boolean canHaveThrows) {
+        this.ownerClass = klass;
+        this.returnType = returnType;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        this.subBlock = subBlock;
+        this.canHaveBreaks = canHaveBreaks;
+        this.canHaveContinues = canHaveContinues;
+        this.canHaveReturn = canHaveReturn;
+        this.canHaveThrow = canHaveThrows;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        if (statementLimit > 0 && complexityLimit > 0) {
+            List<IRNode> content = new ArrayList<>();
+            int slimit = PseudoRandom.randomNotZero(statementLimit);
+            long climit = complexityLimit;
+            IRNodeBuilder builder = new IRNodeBuilder()
+                    .setOperatorLimit(operatorLimit)
+                    .setOwnerKlass(ownerClass)
+                    .setResultType(returnType)
+                    .setCanHaveReturn(canHaveReturn)
+                    .setCanHaveThrow(canHaveThrow)
+                    .setCanHaveBreaks(canHaveBreaks)
+                    .setCanHaveContinues(canHaveContinues)
+                    .setExceptionSafe(false)
+                    .setNoConsts(false);
+            Rule 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.add("statement", builder.getStatementFactory(), 5);
+                if (!ProductionParams.disableVarsInBlock.value()) {
+                    rule.add("decl", builder.setIsLocal(true).getDeclarationFactory());
+                }
+                if (subLimit > 0) {
+                    builder.setStatementLimit(subLimit).setLevel(level + 1);
+                    if (!ProductionParams.disableNestedBlocks.value()) {
+                        rule.add("block", builder.setCanHaveReturn(false)
+                                .setCanHaveThrow(false)
+                                .setCanHaveBreaks(false)
+                                .setCanHaveContinues(false)
+                                .getBlockFactory());
+                        rule.add("try-catch", builder.getTryCatchBlockFactory(), 0.3);
+                        builder.setCanHaveReturn(canHaveReturn)
+                                .setCanHaveThrow(canHaveThrow)
+                                .setCanHaveBreaks(canHaveBreaks)
+                                .setCanHaveContinues(canHaveContinues);
+                    }
+                    addControlFlowDeviation(rule, builder);
+                }
+                try {
+                    IRNode choiceResult = rule.produce();
+                    if (choiceResult instanceof If || choiceResult instanceof While || choiceResult instanceof DoWhile
+                            || choiceResult instanceof For || choiceResult instanceof Switch) {
+                        i += subLimit;
+                    } else {
+                        i++;
+                    }
+                    //climit -= subBlockComplLimit; // very approximate. to obnain a precise value, change to p.complexity()
+                    climit -= choiceResult.complexity();
+                    content.add(choiceResult);
+                } catch (ProductionFailedException e) {
+                    i++;
+                }
+            }
+            // Ok, if the block can end with break and continue. Generate the appropriate productions.
+            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())) {
+                rule.add("return", builder.setComplexityLimit(climit).getReturnFactory());
+            }
+            if (canHaveThrow && !subBlock) {
+                Type rtException = TypeList.find("java.lang.RuntimeException");
+                rtException = PseudoRandom.randomElement(TypeUtil.getImplicitlyCastable(TypeList.getAll(), rtException));
+                rule.add("throw", builder.setResultType(rtException)
+                        .setComplexityLimit(Math.max(climit, 5))
+                        .setOperatorLimit(Math.max(operatorLimit, 5))
+                        .getThrowFactory());
+            }
+
+            try {
+                if (rule.size() > 0) {
+                    content.add(rule.produce());
+                }
+            } catch (ProductionFailedException e) {
+            }
+            if (!subBlock) {
+                SymbolTable.pop();
+            } else {
+                SymbolTable.merge();
+            }
+            return new Block(ownerClass, returnType, content, level);
+        }
+        throw new ProductionFailedException();
+    }
+
+    private void addControlFlowDeviation(Rule rule, IRNodeBuilder builder) {
+        if (!ProductionParams.disableIf.value()) {
+            rule.add("if", builder.getIfFactory());
+        }
+        if (!ProductionParams.disableWhile.value()) {
+            rule.add("while", builder.getWhileFactory());
+        }
+        if (!ProductionParams.disableDoWhile.value()) {
+            rule.add("do_while", builder.getDoWhileFactory());
+        }
+        if (!ProductionParams.disableFor.value()) {
+            rule.add("for", builder.getForFactory());
+        }
+        if (!ProductionParams.disableSwitch.value()) {
+            rule.add("switch", builder.getSwitchFactory(), 0.1);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/BreakFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.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 {
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        return new Break();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CastOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,80 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.CastOperator;
+import jdk.test.lib.jittester.IRNode;
+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.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class CastOperatorFactory extends OperatorFactory {
+    private final Type resultType;
+    private final Type ownerClass;
+
+    CastOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(13, complexityLimit, operatorLimit, exceptionSafe, noconsts);
+        this.resultType = resultType;
+        this.ownerClass = ownerClass;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        ArrayList<Type> argType = new ArrayList<>(TypeList.getAll());
+        PseudoRandom.shuffle(argType);
+        for (Type type : argType) {
+            try {
+                ExpressionFactory expressionFactory = new IRNodeBuilder()
+                        .setComplexityLimit(complexityLimit - 1)
+                        .setOperatorLimit(operatorLimit - 1)
+                        .setOwnerKlass((TypeKlass) ownerClass)
+                        .setExceptionSafe(exceptionSafe)
+                        .setNoConsts(noconsts)
+                        .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)) {
+                    // In safe mode we cannot explicitly cast an object, because it may throw.
+                    IRNode castOperator = new CastOperator(resultType, expressionFactory.produce());
+                    SymbolTable.merge();
+                    return castOperator;
+                }
+                throw new ProductionFailedException();
+            } catch (ProductionFailedException e) {
+                SymbolTable.pop();
+            }
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ClassDefinitionBlockFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,150 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.stream.Collectors;
+import jdk.test.lib.jittester.Block;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Rule;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.classes.ClassDefinitionBlock;
+import jdk.test.lib.jittester.classes.Klass;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class ClassDefinitionBlockFactory extends Factory {
+    private final String prefix;
+    private final long complexityLimit;
+    private final int classesLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final int memberFunctionsLimit;
+    private final int memberFunctionsArgLimit;
+    private final int level;
+
+    ClassDefinitionBlockFactory(String prefix, int classesLimit, int memberFunctionsLimit,
+            int memberFunctionsArgLimit, long complexityLimit, int statementLimit,
+            int operatorLimit, int level) {
+        this.prefix = prefix;
+        this.classesLimit = classesLimit;
+        this.memberFunctionsLimit = memberFunctionsLimit;
+        this.memberFunctionsArgLimit = memberFunctionsArgLimit;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        ArrayList<IRNode> content = new ArrayList<>();
+        int limit = (int) Math.ceil(PseudoRandom.random() * classesLimit);
+        if (limit > 0) {
+            long classCompl = complexityLimit / limit;
+            IRNodeBuilder builder = new IRNodeBuilder().setLevel(level)
+                    .setMemberFunctionsArgLimit(memberFunctionsArgLimit)
+                    .setStatementLimit(statementLimit)
+                    .setOperatorLimit(operatorLimit)
+                    .setComplexityLimit(classCompl);
+            for (int i = 0; i < limit; i++) {
+                try {
+                    Rule rule = new Rule("class");
+                    rule.add("basic_class", builder.setName(prefix + "_Class_" + i)
+                            .setPrinterName(prefix + ".Printer")
+                            .setMemberFunctionsLimit(memberFunctionsLimit)
+                            .getKlassFactory());
+                    if (!ProductionParams.disableInterfaces.value()) {
+                        rule.add("interface", builder.setName(prefix + "_Interface_" + i)
+                                .setMemberFunctionsLimit((int) (memberFunctionsLimit * 0.2))
+                                .getInterfaceFactory(), 0.1);
+                    }
+                    // TODO: Add enums
+                    content.add(rule.produce());
+                } catch (ProductionFailedException e) {
+                }
+            }
+        }
+        ensureMinDepth(content);
+        ensureMaxDepth(content);
+        return new ClassDefinitionBlock(content, level);
+    }
+
+    private void ensureMinDepth(Collection<IRNode> content) throws ProductionFailedException {
+        int minDepth = ProductionParams.minCfgDepth.value();
+        List<IRNode> childs = content.stream()
+                .filter(c -> c instanceof Klass)
+                .collect(Collectors.toList());
+        addMoreChildren(childs, content, minDepth);
+    }
+
+    private void addMoreChildren(List<IRNode> childs, Collection<IRNode> content, int minDepth)
+        throws ProductionFailedException {
+        while (!childs.isEmpty() && IRNode.countDepth(content) < minDepth) {
+            PseudoRandom.shuffle(childs);
+            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();
+                int newLevel = randomLeaf.getLevel() + 1;
+                Type retType = randomLeaf.getReturnType();
+                IRNodeBuilder b = new IRNodeBuilder()
+                        .setOwnerKlass(klass)
+                        .setResultType(retType)
+                        .setComplexityLimit(complexityLimit)
+                        .setStatementLimit(statementLimit)
+                        .setOperatorLimit(operatorLimit)
+                        .setLevel(newLevel);
+                IRNode newBlock = b.getBlockFactory().produce();
+                List<IRNode> siblings = randomLeaf.getChildren();
+                // to avoid break;
+                int index = PseudoRandom.randomNotZero(siblings.size() - 1);
+                siblings.add(index, newBlock);
+            }
+        }
+    }
+
+    private void ensureMaxDepth(Collection<IRNode> content) {
+        int maxDepth = ProductionParams.maxCfgDepth.value();
+        List<IRNode> childs = content.stream()
+                .filter(c -> c instanceof Klass && c.countDepth() > maxDepth)
+                .collect(Collectors.toList());
+        for (IRNode ch : childs) {
+            List<IRNode> leaves = null;
+            do {
+                long depth = Math.max(ch.countDepth(), maxDepth + 1);
+                leaves = ch.getDeviantBlocks(depth);
+                if(leaves.size() > 0) {
+                    leaves.get(0).removeSelf();
+                }
+            } while (!leaves.isEmpty() && ch.countDepth() > maxDepth);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CompoundArithmeticAssignmentOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,78 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+import jdk.test.lib.jittester.BinaryOperator;
+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.TypeUtil;
+import jdk.test.lib.jittester.types.TypeBoolean;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class CompoundArithmeticAssignmentOperatorFactory extends BinaryOperatorFactory {
+    CompoundArithmeticAssignmentOperatorFactory(OperatorKind opKind, long complexityLimit,
+            int operatorLimit, TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return TypeList.isBuiltIn(resultType) && !resultType.equals(new TypeBoolean());
+    }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        return new Pair<>(resultType, PseudoRandom.randomElement(
+                TypeUtil.getExplicitlyCastable(TypeList.getBuiltIn(), resultType)));
+    }
+
+    @Override
+    protected BinaryOperator generateProduction(Type leftType, Type rightType) throws ProductionFailedException {
+        long leftComplexityLimit = (long) (PseudoRandom.random() * complexityLimit);
+        long rightComplexityLimit = complexityLimit - leftComplexityLimit;
+        int leftOperatorLimit = (int) (PseudoRandom.random() * operatorLimit);
+        int rightOperatorLimit = operatorLimit = leftOperatorLimit;
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass((TypeKlass) ownerClass)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts);
+        IRNode rightExpr = builder.setComplexityLimit(rightComplexityLimit)
+                .setOperatorLimit(rightOperatorLimit)
+                .setResultType(rightType)
+                .getExpressionFactory()
+                .produce();
+        IRNode leftExpr = builder.setComplexityLimit(leftComplexityLimit)
+                .setOperatorLimit(leftOperatorLimit)
+                .setResultType(leftType)
+                .setIsConstant(false)
+                .setIsInitialized(true)
+                .getVariableFactory()
+                .produce();
+        return new BinaryOperator(opKind, leftExpr, rightExpr);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CompoundBitwiseAssignmentOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+import jdk.test.lib.jittester.BinaryOperator;
+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.TypeUtil;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class CompoundBitwiseAssignmentOperatorFactory extends BinaryOperatorFactory {
+    CompoundBitwiseAssignmentOperatorFactory(OperatorKind opKind, long complexityLimit,
+            int operatorLimit, TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return TypeList.isBuiltInInt(resultType);
+    }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        return new Pair<>(resultType, PseudoRandom.randomElement(TypeUtil.getExplicitlyCastable(TypeList.getBuiltInInt(), resultType)));
+    }
+
+    @Override
+    protected BinaryOperator generateProduction(Type leftType, Type rightType) throws ProductionFailedException {
+        long leftComplexityLimit = (long) (PseudoRandom.random() * complexityLimit);
+        long rightComplexityLimit = complexityLimit - leftComplexityLimit;
+        int leftOperatorLimit = (int) (PseudoRandom.random() * operatorLimit);
+        int rightOperatorLimit = operatorLimit = leftOperatorLimit;
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass((TypeKlass) ownerClass)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts);
+        IRNode leftExpr = builder.setComplexityLimit(leftComplexityLimit)
+                .setOperatorLimit(leftOperatorLimit)
+                .setResultType(leftType)
+                .setIsConstant(false)
+                .setIsInitialized(true)
+                .getVariableFactory()
+                .produce();
+        IRNode rightExpr = builder.setComplexityLimit(rightComplexityLimit)
+                .setOperatorLimit(rightOperatorLimit)
+                .setResultType(rightType)
+                .getExpressionFactory()
+                .produce();
+        return new BinaryOperator(opKind, leftExpr, rightExpr);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CompoundShiftAssignmentOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,78 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.Pair;
+import jdk.test.lib.jittester.BinaryOperator;
+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.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 {
+    CompoundShiftAssignmentOperatorFactory(OperatorKind opKind, long complexityLimit,
+            int operatorLimit, TypeKlass ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return TypeList.isBuiltInInt(resultType) && !resultType.equals(new TypeBoolean());
+    }
+
+    @Override
+    protected Pair<Type, Type> generateTypes() throws ProductionFailedException {
+        return new Pair<>(resultType, PseudoRandom.randomElement(
+                TypeUtil.getExplicitlyCastable(TypeList.getBuiltInInt(), resultType)));
+    }
+
+    @Override
+    protected BinaryOperator generateProduction(Type leftType, Type rightType) throws ProductionFailedException {
+        long leftComplexityLimit = (long) (PseudoRandom.random() * complexityLimit);
+        long rightComplexityLimit = complexityLimit - leftComplexityLimit;
+        int leftOperatorLimit = (int) (PseudoRandom.random() * operatorLimit);
+        int rightOperatorLimit = operatorLimit = leftOperatorLimit;
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass((TypeKlass) ownerClass)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts);
+        IRNode leftExpr = builder.setComplexityLimit(leftComplexityLimit)
+                .setOperatorLimit(leftOperatorLimit)
+                .setResultType(leftType)
+                .setIsConstant(false)
+                .setIsInitialized(true)
+                .getVariableFactory()
+                .produce();
+        IRNode rightExpr = builder.setComplexityLimit(rightComplexityLimit)
+                .setOperatorLimit(rightOperatorLimit)
+                .setResultType(rightType)
+                .getExpressionFactory()
+                .produce();
+        return new BinaryOperator(opKind, leftExpr, rightExpr);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ConstructorDefinitionBlockFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,89 @@
+/*
+ * 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.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.ProductionParams;
+import jdk.test.lib.jittester.functions.ConstructorDefinitionBlock;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class ConstructorDefinitionBlockFactory extends Factory {
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final int memberFunctionsLimit;
+    private final int memberFunctionsArgLimit;
+    private final TypeKlass ownerClass;
+    private final int level;
+
+    ConstructorDefinitionBlockFactory(TypeKlass ownerClass, int memberFunctionsLimit,
+            int memberFunctionsArgLimit, long complexityLimit, int statementLimit,
+            int operatorLimit, int level) {
+        this.ownerClass = ownerClass;
+        this.memberFunctionsLimit = memberFunctionsLimit;
+        this.memberFunctionsArgLimit = memberFunctionsArgLimit;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setOwnerKlass(ownerClass)
+                .setStatementLimit(statementLimit)
+                .setOperatorLimit(operatorLimit)
+                .setLevel(level);
+        ArrayList<IRNode> content = new ArrayList<>();
+        int memFunLimit = PseudoRandom.randomNotZero(memberFunctionsLimit);
+        builder.setComplexityLimit(complexityLimit / memFunLimit);
+        if (!ProductionParams.disableStatic.value() && PseudoRandom.randomBoolean()) {
+            // Generate static constructor
+            content.add(builder.getStaticConstructorDefinitionFactory().produce());
+            // take static constructor into account
+            --memFunLimit;
+        }
+        // No matter what, generate default constructor first.
+        // This would guarantee a way to initialize a data member in case,
+        // when arguments to a non-default constructor cannot be generated.
+        content.add(builder.setMemberFunctionsArgLimit(0)
+                .getConstructorDefinitionFactory()
+                .produce());
+        if (--memFunLimit > 0) {
+            for (int i = 0; i < memFunLimit; i++) {
+                try {
+                    content.add(builder.setMemberFunctionsArgLimit(memberFunctionsArgLimit)
+                            .getConstructorDefinitionFactory()
+                            .produce());
+                } catch (ProductionFailedException e) {
+                }
+            }
+        }
+        return new ConstructorDefinitionBlock(content, level);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ConstructorDefinitionFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,113 @@
+/*
+ * 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.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.Symbol;
+import jdk.test.lib.jittester.SymbolTable;
+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 {
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final int memberFunctionsArgLimit;
+    private final int level;
+    private final TypeKlass ownerClass;
+
+    ConstructorDefinitionFactory(TypeKlass ownerClass, long complexityLimit, int statementLimit,
+            int operatorLimit, int memberFunctionsArgLimit, int level) {
+        this.ownerClass = ownerClass;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.memberFunctionsArgLimit = memberFunctionsArgLimit;
+        this.level = level;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        int argNumber = (int) (PseudoRandom.random() * memberFunctionsArgLimit);
+        ArrayList<VariableInfo> argumentsInfo = new ArrayList<>(argNumber);
+        ArrayList<ArgumentDeclaration> argumentsDeclaration = new ArrayList<>(argNumber);
+        SymbolTable.push();
+        IRNode body;
+        FunctionInfo functionInfo;
+        try {
+            int i = 0;
+            IRNodeBuilder builder = new IRNodeBuilder().setArgumentType(ownerClass).setOwnerKlass(ownerClass);
+            for (; i < argNumber; i++) {
+                ArgumentDeclaration d = builder.setVariableNumber(i).getArgumentDeclarationFactory()
+                        .produce();
+                argumentsDeclaration.add(d);
+                argumentsInfo.add(d.variableInfo);
+            }
+            for (boolean dup = true; dup; i++) {
+                /* Check if these is a function with a same signature
+                (includes original class name) defined. */
+                functionInfo = new FunctionInfo(ownerClass.getName(), ownerClass,
+                        ownerClass, 0, FunctionInfo.PUBLIC, argumentsInfo);
+                dup = false;
+                for (Symbol symbol : SymbolTable.get(ownerClass, FunctionInfo.class)) {
+                    if (functionInfo.equals(symbol)) {
+                        ArgumentDeclaration argDecl = builder.setVariableNumber(i)
+                                .getArgumentDeclarationFactory().produce();
+                        argumentsDeclaration.add(argDecl);
+                        argumentsInfo.add(argDecl.variableInfo);
+                        dup = true;
+                        break;
+                    }
+                }
+            }
+            long blockComplLimit = (long) (PseudoRandom.random() * complexityLimit);
+            try {
+                body = builder.setResultType(new TypeVoid())
+                        .setComplexityLimit(blockComplLimit)
+                        .setStatementLimit(statementLimit)
+                        .setOperatorLimit(operatorLimit)
+                        .setLevel(level)
+                        .setSubBlock(true)
+                        .getBlockFactory()
+                        .produce();
+            } catch (ProductionFailedException e) {
+                body = null;
+            }
+        } finally {
+            SymbolTable.pop();
+        }
+        functionInfo = new FunctionInfo(ownerClass.getName(), ownerClass, ownerClass,
+                body != null ? body.complexity() : 0, FunctionInfo.PUBLIC, argumentsInfo);
+        // If it's all ok, add the function to the symbol table.
+        SymbolTable.add(functionInfo);
+        return new ConstructorDefinition(functionInfo, argumentsDeclaration, body);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ContinueFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.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 {
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        return new Continue();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CounterInitializerFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,61 @@
+/*
+ * 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.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.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 {
+    private final int counterValue;
+    private final TypeKlass ownerClass;
+
+    CounterInitializerFactory(TypeKlass ownerClass, int counterValue) {
+        this.ownerClass = ownerClass;
+        this.counterValue = counterValue;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        List<Type> types = TypeUtil.getMoreCapatiousThan(TypeList.getBuiltIn(), new TypeInt());
+        types.add(new TypeInt());
+        final Type selectedType = PseudoRandom.randomElement(types);
+        IRNode init = new LiteralInitializer(counterValue, selectedType);
+        String resultName = "var_" + SymbolTable.getNextVariableNumber();
+        VariableInfo varInfo = new VariableInfo(resultName, ownerClass, selectedType,
+                VariableInfo.FINAL | VariableInfo.LOCAL | VariableInfo.INITIALIZED);
+        SymbolTable.add(varInfo);
+        return new CounterInitializer(varInfo, init);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/CounterManipulatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.LocalVariable;
+import jdk.test.lib.jittester.OperatorKind;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.UnaryOperator;
+import jdk.test.lib.jittester.loops.CounterManipulator;
+
+class CounterManipulatorFactory extends Factory {
+    private final LocalVariable counter;
+
+    CounterManipulatorFactory(LocalVariable counter) {
+        this.counter = counter;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        // We'll keep it simple for the time being..
+        IRNode manipulator = new UnaryOperator(OperatorKind.POST_DEC, counter);
+        return new CounterManipulator(manipulator);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/DeclarationFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,78 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.Declaration;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Rule;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class DeclarationFactory extends Factory {
+    private final int operatorLimit;
+    private final long complexityLimit;
+    private final boolean isLocal;
+    private final boolean exceptionSafe;
+    private final TypeKlass ownerClass;
+
+    DeclarationFactory(TypeKlass ownerClass, long complexityLimit,
+            int operatorLimit, boolean isLocal, boolean safe) {
+        this.ownerClass = ownerClass;
+        this.isLocal = isLocal;
+        this.exceptionSafe = safe;
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        Rule rule = new Rule("declaration");
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(ownerClass)
+                .setResultType(TypeList.getVoid())
+                .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());
+        if (!ProductionParams.disableFinalVariables.value()) {
+            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());
+            if (!ProductionParams.disableFinalVariables.value()) {
+                rule.add("static_const_decl_and_init", builder.setIsConstant(true)
+                        .setIsStatic(true).getVariableInitializationFactory());
+            }
+        }
+        return new Declaration(rule.produce());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/DoWhileFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,150 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+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.SymbolTable;
+import jdk.test.lib.jittester.Type;
+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 {
+    private final Loop loop;
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private boolean canHaveReturn = false;
+    private final TypeKlass ownerClass;
+    private final int level;
+    private final Type returnType;
+    private long thisLoopIterLimit;
+
+    DoWhileFactory(TypeKlass ownerClass, Type returnType, long complexityLimit, int statementLimit,
+            int operatorLimit, int level, boolean canHaveReturn) {
+        loop = new Loop();
+        this.ownerClass = ownerClass;
+        this.returnType = returnType;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        this.canHaveReturn = canHaveReturn;
+        thisLoopIterLimit = 0;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        if (statementLimit > 0 && complexityLimit > 0) {
+            long complexity = complexityLimit;
+            // Loop header parameters
+            long headerComplLimit = (long) (0.005 * complexity * PseudoRandom.random());
+            complexity -= headerComplLimit;
+            int headerStatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 3.0));
+            // Loop body parameters
+            thisLoopIterLimit = (long) (0.0001 * complexity * PseudoRandom.random());
+            if (thisLoopIterLimit > Integer.MAX_VALUE || thisLoopIterLimit == 0) {
+                throw new ProductionFailedException();
+            }
+            complexity = thisLoopIterLimit > 0 ? complexity / thisLoopIterLimit : 0;
+            long condComplLimit = (long) (complexity * PseudoRandom.random());
+            complexity -= condComplLimit;
+            long body1ComplLimit = (long) (complexity * PseudoRandom.random());
+            complexity -= body1ComplLimit;
+            int body1StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 3.0));
+            long body2ComplLimit = (long) (complexity * PseudoRandom.random());
+            complexity -= body2ComplLimit;
+            int body2StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 3.0));
+            // Production
+            IRNodeBuilder builder = new IRNodeBuilder()
+                    .setOwnerKlass(ownerClass)
+                    .setResultType(returnType)
+                    .setOperatorLimit(operatorLimit);
+            loop.initialization = builder.getCounterInitializerFactory(0).produce();
+            IRNode header;
+            try {
+                header = builder.setComplexityLimit(headerComplLimit)
+                        .setStatementLimit(headerStatementLimit)
+                        .setLevel(level - 1)
+                        .setSubBlock(true)
+                        .setCanHaveBreaks(false)
+                        .setCanHaveContinues(false)
+                        .setCanHaveReturn(false)
+                        .getBlockFactory()
+                        .produce();
+            } catch (ProductionFailedException e) {
+                header = new Nothing();
+            }
+            // 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());
+            loop.condition = builder.setComplexityLimit(condComplLimit)
+                    .setLocalVariable(counter)
+                    .getLoopingConditionFactory(limiter)
+                    .produce();
+            SymbolTable.push();
+            IRNode body1;
+            try {
+                body1 = builder.setComplexityLimit(body1ComplLimit)
+                        .setStatementLimit(body1StatementLimit)
+                        .setLevel(level)
+                        .setSubBlock(true)
+                        .setCanHaveBreaks(true)
+                        .setCanHaveContinues(false)
+                        .setCanHaveReturn(false)
+                        .getBlockFactory()
+                        .produce();
+            } catch (ProductionFailedException e) {
+                body1 = new Nothing();
+            }
+            // getChildren().set(DoWhile.DoWhilePart.BODY1.ordinal(), body1);
+            loop.manipulator = builder.setLocalVariable(counter).getCounterManipulatorFactory().produce();
+            IRNode body2;
+            try {
+                body2 = builder.setComplexityLimit(body2ComplLimit)
+                        .setStatementLimit(body2StatementLimit)
+                        .setLevel(level)
+                        .setSubBlock(true)
+                        .setCanHaveBreaks(true)
+                        .setCanHaveContinues(false)
+                        .setCanHaveReturn(canHaveReturn)
+                        .getBlockFactory()
+                        .produce();
+            } catch (ProductionFailedException e) {
+                body2 = new Nothing();
+            }
+            // getChildren().set(DoWhile.DoWhilePart.BODY2.ordinal(), body2);
+            SymbolTable.pop();
+            return new DoWhile(level, loop, thisLoopIterLimit, header, body1, body2);
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ExpressionFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,79 @@
+/*
+ * 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.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.ProductionLimiter;
+import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Rule;
+import jdk.test.lib.jittester.Type;;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class ExpressionFactory extends SafeFactory {
+    private final Rule rule;
+
+    ExpressionFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass, Type resultType,
+            boolean exceptionSafe, boolean noconsts) throws ProductionFailedException {
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setOwnerKlass(ownerClass)
+                .setResultType(resultType)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts);
+        rule = new Rule("expression");
+        if (!noconsts) {
+            rule.add("literal", builder.getLiteralFactory());
+            rule.add("constant", builder.setIsConstant(true)
+                    .setIsInitialized(true)
+                    //.setVariableType(resultType)
+                    .getVariableFactory());
+        }
+        rule.add("variable", builder.setIsConstant(false).setIsInitialized(true).getVariableFactory());
+        if (operatorLimit > 0 && complexityLimit > 0) {
+            rule.add("cast", builder.getCastOperatorFactory(), 0.1);
+            rule.add("arithmetic", builder.getArithmeticOperatorFactory());
+            rule.add("logic", builder.getLogicOperatorFactory());
+            rule.add("bitwise", new BitwiseOperatorFactory(complexityLimit, operatorLimit, ownerClass,
+                    resultType, exceptionSafe, noconsts));
+            rule.add("assignment", builder.getAssignmentOperatorFactory());
+            rule.add("ternary", builder.getTernaryOperatorFactory());
+            rule.add("function", builder.getFunctionFactory(), 0.1);
+            rule.add("str_plus", builder.setOperatorKind(OperatorKind.STRADD).getBinaryOperatorFactory());
+            if (!ProductionParams.disableArrays.value() && !exceptionSafe) {
+                //rule.add("array_creation", builder.getArrayCreationFactory());
+                rule.add("array_element", builder.getArrayElementFactory());
+                rule.add("array_extraction", builder.getArrayExtractionFactory());
+            }
+        }
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        ProductionLimiter.limitProduction();
+        return rule.produce();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/Factory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,31 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+
+public abstract class Factory {
+    public abstract IRNode produce() throws ProductionFailedException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ForFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,192 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+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.SymbolTable;
+import jdk.test.lib.jittester.Type;
+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 {
+    private final Loop loop;
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    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,
+            int operatorLimit, int level, boolean canHaveReturn) {
+        this.ownerClass = ownerClass;
+        this.returnType = returnType;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        loop = new Loop();
+        this.canHaveReturn = canHaveReturn;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        if (statementLimit <= 0 || complexityLimit <= 0) {
+            throw new ProductionFailedException();
+        }
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setOwnerKlass(ownerClass)
+                .setResultType(returnType)
+                .setOperatorLimit(operatorLimit)
+                .setSemicolon(false)
+                .setExceptionSafe(false)
+                .setNoConsts(false);
+        long complexity = complexityLimit;
+        // Loop header parameters
+        long headerComplLimit = (long) (0.005 * complexity * PseudoRandom.random());
+        complexity -= headerComplLimit;
+        int headerStatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 4.0));
+        long statement1ComplLimit = (long) (0.005 * complexity * PseudoRandom.random());
+        complexity -= statement1ComplLimit;
+        // Loop body parameters
+        thisLoopIterLimit = (long) (0.0001 * complexity * PseudoRandom.random());
+        if (thisLoopIterLimit > Integer.MAX_VALUE || thisLoopIterLimit == 0) {
+            throw new ProductionFailedException();
+        }
+        complexity = thisLoopIterLimit > 0 ? complexity / thisLoopIterLimit : 0;
+        long condComplLimit = (long) (complexity * PseudoRandom.random());
+        complexity -= condComplLimit;
+        long statement2ComplLimit = (long) (complexity * PseudoRandom.random());
+        complexity -= statement2ComplLimit;
+        long body1ComplLimit = (long) (complexity * PseudoRandom.random());
+        complexity -= body1ComplLimit;
+        int body1StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 4.0));
+        long body2ComplLimit = (long) (complexity * PseudoRandom.random());
+        complexity -= body2ComplLimit;
+        int body2StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 4.0));
+        long body3ComplLimit = complexity;
+        int body3StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 4.0));
+        // Production
+        loop.initialization = builder.getCounterInitializerFactory(0).produce();
+        IRNode header;
+        try {
+            header = builder.setComplexityLimit(headerComplLimit)
+                    .setStatementLimit(headerStatementLimit)
+                    .setLevel(level - 1)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(false)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(false)
+                    .getBlockFactory()
+                    .produce();
+        } catch (ProductionFailedException e) {
+            header = new Nothing();
+        }
+        SymbolTable.push();
+        IRNode statement1;
+        try {
+            Rule rule = new Rule("statement1");
+            builder.setComplexityLimit(statement1ComplLimit);
+            rule.add("assignment", builder.getAssignmentOperatorFactory());
+            rule.add("function", builder.getFunctionFactory(), 0.1);
+            rule.add("initialization", builder.setIsConstant(false)
+                    .setIsStatic(false)
+                    .setIsLocal(true)
+                    .getVariableInitializationFactory());
+            statement1 = rule.produce();
+        } catch (ProductionFailedException e) {
+            statement1 = new Nothing();
+        }
+        LocalVariable counter = new LocalVariable(((Initialization) loop.initialization).get());
+        Literal limiter = new Literal(Integer.valueOf((int) thisLoopIterLimit), new TypeInt());
+        loop.condition = builder.setComplexityLimit(condComplLimit)
+                .setLocalVariable(counter)
+                .getLoopingConditionFactory(limiter)
+                .produce();
+        IRNode statement2;
+        try {
+            statement2 =  builder.setComplexityLimit(statement2ComplLimit)
+                    .getAssignmentOperatorFactory().produce();
+        } catch (ProductionFailedException e) {
+            statement2 = new Nothing();
+        }
+        IRNode body1;
+        try {
+            body1 = builder.setComplexityLimit(body1ComplLimit)
+                    .setStatementLimit(body1StatementLimit)
+                    .setLevel(level)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(true)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(false)
+                    .getBlockFactory()
+                    .produce();
+        } catch (ProductionFailedException e) {
+            body1 = new Nothing();
+        }
+        loop.manipulator = builder.setLocalVariable(counter).getCounterManipulatorFactory().produce();
+        IRNode body2;
+        try {
+            body2 = builder.setComplexityLimit(body2ComplLimit)
+                    .setStatementLimit(body2StatementLimit)
+                    .setLevel(level)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(true)
+                    .setCanHaveContinues(true)
+                    .setCanHaveReturn(false)
+                    .getBlockFactory()
+                    .produce();
+        } catch (ProductionFailedException e) {
+            body2 = new Nothing();
+        }
+        IRNode body3;
+        try {
+            body3 = builder.setComplexityLimit(body3ComplLimit)
+                    .setStatementLimit(body3StatementLimit)
+                    .setLevel(level)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(true)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(canHaveReturn)
+                    .getBlockFactory()
+                    .produce();
+        } catch (ProductionFailedException e) {
+            body3 = new Nothing();
+        }
+        SymbolTable.pop();
+        return new For(level, loop, thisLoopIterLimit, header, statement1, statement2, body1,
+                body2, body3);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDeclarationBlockFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,67 @@
+/*
+ * 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.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.functions.FunctionDeclarationBlock;
+import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class FunctionDeclarationBlockFactory extends Factory {
+    private final int memberFunctionsLimit;
+    private final int memberFunctionsArgLimit;
+    private final int level;
+    private final TypeKlass ownerClass;
+
+    FunctionDeclarationBlockFactory(TypeKlass ownerClass, int memberFunctionsLimit,
+            int memberFunctionsArgLimit, int level) {
+        this.ownerClass = ownerClass;
+        this.memberFunctionsLimit = memberFunctionsLimit;
+        this.memberFunctionsArgLimit = memberFunctionsArgLimit;
+        this.level = level;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        ArrayList<IRNode> content = new ArrayList<>();
+        int memFunLimit = (int) (PseudoRandom.random() * memberFunctionsLimit);
+        if (memFunLimit > 0) {
+            IRNodeBuilder builder = new IRNodeBuilder()
+                    .setOwnerKlass(ownerClass)
+                    .setMemberFunctionsArgLimit(memberFunctionsArgLimit)
+                    .setFlags(FunctionInfo.ABSTRACT | FunctionInfo.PUBLIC);
+            for (int i = 0; i < memFunLimit; i++) {
+                try {
+                    content.add(builder.setName("func_" + i).getFunctionDeclarationFactory().produce());
+                } catch (ProductionFailedException e) {
+                    // TODO: do we have to react here?
+                }
+            }
+        }
+        return new FunctionDeclarationBlock(ownerClass, content, level);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDeclarationFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,110 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+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;
+import jdk.test.lib.jittester.Type;
+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.FunctionDeclaration;
+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 {
+    private final Type resultType;
+    private final TypeKlass ownerClass;
+    private final String name;
+    private final int memberFunctionsArgLimit;
+    private final int flags;
+
+    FunctionDeclarationFactory(String name, TypeKlass ownerClass, Type resultType,
+            int memberFunctionsArgLimit, int flags) {
+        this.name = name;
+        this.ownerClass = ownerClass;
+        this.resultType = resultType;
+        this.memberFunctionsArgLimit = memberFunctionsArgLimit;
+        this.flags = flags;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        Type resType = resultType;
+        if (resType == null) {
+            List<Type> types = new ArrayList<>(TypeList.getAll());
+            types.add(new TypeVoid());
+            resType = PseudoRandom.randomElement(types);
+        }
+        int argNumber = (int) (PseudoRandom.random() * memberFunctionsArgLimit);
+        ArrayList<VariableInfo> argumentsInfo = new ArrayList<>(argNumber + 1);
+        argumentsInfo.add(new VariableInfo("this", ownerClass, ownerClass,
+                VariableInfo.FINAL | VariableInfo.LOCAL | VariableInfo.INITIALIZED));
+        ArrayList<ArgumentDeclaration> argumentsDeclaration = new ArrayList<>(argNumber);
+        SymbolTable.push();
+        FunctionInfo functionInfo;
+        IRNodeBuilder builder = new IRNodeBuilder().setArgumentType(ownerClass);
+        try {
+            int i = 0;
+            for (; i < argNumber; i++) {
+                ArgumentDeclaration d = builder.setVariableNumber(i)
+                        .getArgumentDeclarationFactory().produce();
+                argumentsDeclaration.add(d);
+                argumentsInfo.add(d.variableInfo);
+            }
+            Collection<Symbol> thisKlassFuncs = SymbolTable
+                    .getAllCombined(ownerClass, FunctionInfo.class);
+            Collection<Symbol> parentFuncs = FunctionDefinition.getFuncsFromParents(ownerClass);
+            while (true) {
+                functionInfo = new FunctionInfo(name, ownerClass, resType, 0, flags, argumentsInfo);
+                if (thisKlassFuncs.contains(functionInfo)
+                        || FunctionDefinition.isInvalidOverride(functionInfo, parentFuncs)) {
+                    // try changing the signature, and go checking again.
+                    ArgumentDeclaration d = builder.setVariableNumber(i++)
+                            .getArgumentDeclarationFactory().produce();
+                    argumentsDeclaration.add(d);
+                    argumentsInfo.add(d.variableInfo);
+                } else {
+                    break;
+                }
+            }
+        } finally {
+            SymbolTable.pop();
+        }
+        //addChildren(argumentsDeclaration); // not neccessary while complexity is 0
+        functionInfo = new FunctionInfo(name, ownerClass, resType, 0, flags, argumentsInfo);
+        // If it's all ok, add the function to the symbol table.
+        SymbolTable.add(functionInfo);
+        return new FunctionDeclaration(functionInfo, argumentsDeclaration);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDefinitionBlockFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,120 @@
+/*
+ * 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.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.ProductionParams;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.functions.FunctionDefinitionBlock;
+import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class FunctionDefinitionBlockFactory extends Factory {
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final int memberFunctionsLimit;
+    private final int memberFunctionsArgLimit;
+    private final int initialFlags;
+    private final int level;
+    private final TypeKlass ownerClass;
+
+    FunctionDefinitionBlockFactory(TypeKlass ownerClass, int memberFunctionsLimit,
+            int memberFunctionsArgLimit, long complexityLimit, int statementLimit,
+            int operatorLimit, int level, int initialFlags) {
+        this.ownerClass = ownerClass;
+        this.memberFunctionsLimit = memberFunctionsLimit;
+        this.memberFunctionsArgLimit = memberFunctionsArgLimit;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        this.initialFlags = initialFlags;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        ArrayList<IRNode> content = new ArrayList<>();
+        int memFunLimit = (int) (PseudoRandom.random() * memberFunctionsLimit);
+        if (memFunLimit > 0) {
+            long memFunCompl = complexityLimit / memFunLimit;
+            IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(ownerClass)
+                    .setComplexityLimit(memFunCompl)
+                    .setStatementLimit(statementLimit)
+                    .setOperatorLimit(operatorLimit)
+                    .setMemberFunctionsArgLimit(memberFunctionsArgLimit)
+                    .setLevel(level);
+            for (int i = 0; i < memFunLimit; i++) {
+                int flags = initialFlags;
+                if (PseudoRandom.randomBoolean()) {
+                    flags |= FunctionInfo.STATIC;
+                }
+                if (!ProductionParams.disableFinalMethods.value() && PseudoRandom.randomBoolean()) {
+                    flags |= FunctionInfo.FINAL;
+                }
+                if (PseudoRandom.randomBoolean()) {
+                    flags |= FunctionInfo.NONRECURSIVE;
+                }
+                if (PseudoRandom.randomBoolean()) {
+                    flags |= FunctionInfo.SYNCHRONIZED;
+                }
+                switch ((int) (PseudoRandom.random() * 4)) {
+                    case 0:
+                        flags |= FunctionInfo.PRIVATE;
+                        break;
+                    case 1:
+                        flags |= FunctionInfo.PROTECTED;
+                        break;
+                    case 2:
+                        flags |= FunctionInfo.DEFAULT;
+                        break;
+                    case 3:
+                        flags |= FunctionInfo.PUBLIC;
+                        break;
+                }
+                Symbol thisSymbol = null;
+                if ((flags & FunctionInfo.STATIC) > 0) {
+                    thisSymbol = SymbolTable.get("this", VariableInfo.class);
+                    SymbolTable.remove(thisSymbol);
+                }
+                try {
+                    content.add(builder.setName("func_" + i)
+                            .setFlags(flags)
+                            .getFunctionDefinitionFactory()
+                            .produce());
+                } catch (ProductionFailedException e) {
+                }
+                if ((flags & FunctionInfo.STATIC) > 0) {
+                    SymbolTable.add(thisSymbol);
+                }
+            }
+        }
+        return new FunctionDefinitionBlock(content, level, ownerClass);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionDefinitionFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,148 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+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;
+import jdk.test.lib.jittester.Type;
+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.types.TypeKlass;
+import jdk.test.lib.jittester.types.TypeVoid;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class FunctionDefinitionFactory extends Factory {
+    private final Type resultType;
+    private final String name;
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final int memberFunctionsArgLimit;
+    private final int flags;
+    private final int level;
+    private final TypeKlass ownerClass;
+
+    FunctionDefinitionFactory(String name, TypeKlass ownerClass, Type resultType,
+            long complexityLimit, int statementLimit, int operatorLimit,
+            int memberFunctionsArgLimit, int level, int flags) {
+        this.name = name;
+        this.ownerClass = ownerClass;
+        this.resultType = resultType;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.memberFunctionsArgLimit = memberFunctionsArgLimit;
+        this.level = level;
+        this.flags = flags;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        Type resType = resultType;
+        if (resType == null) {
+            List<Type> types = new ArrayList<>(TypeList.getAll());
+            types.add(new TypeVoid());
+            resType = PseudoRandom.randomElement(types);
+        }
+        int argNumber = (int) (PseudoRandom.random() * memberFunctionsArgLimit);
+        ArrayList<VariableInfo> argumentsInfo;
+        if ((flags & FunctionInfo.STATIC) > 0) {
+            argumentsInfo = new ArrayList<>(argNumber);
+        } else {
+            argumentsInfo = new ArrayList<>(argNumber + 1);
+            argumentsInfo.add(new VariableInfo("this", ownerClass, ownerClass,
+                    VariableInfo.FINAL | VariableInfo.LOCAL | VariableInfo.INITIALIZED));
+        }
+        ArrayList<ArgumentDeclaration> argumentsDeclaration = new ArrayList<>(argNumber);
+        SymbolTable.push();
+        IRNode body;
+        IRNode returnNode;
+        FunctionInfo functionInfo;
+        try {
+            IRNodeBuilder builder = new IRNodeBuilder().setArgumentType(ownerClass);
+            int i = 0;
+            for (; i < argNumber; i++) {
+                ArgumentDeclaration d = builder.setVariableNumber(i).getArgumentDeclarationFactory()
+                        .produce();
+                argumentsDeclaration.add(d);
+                argumentsInfo.add(d.variableInfo);
+            }
+            Collection<Symbol> thisKlassFuncs = SymbolTable.getAllCombined(ownerClass,
+                    FunctionInfo.class);
+            Collection<Symbol> parentFuncs = FunctionDefinition.getFuncsFromParents(ownerClass);
+            while (true) {
+                functionInfo = new FunctionInfo(name, ownerClass, resType, 0, flags,
+                        argumentsInfo);
+                if (thisKlassFuncs.contains(functionInfo)
+                        || FunctionDefinition.isInvalidOverride(functionInfo, parentFuncs)) {
+                    // try changing the signature, and go checking again.
+                    ArgumentDeclaration argDecl = builder.setVariableNumber(i++)
+                            .getArgumentDeclarationFactory().produce();
+                    argumentsDeclaration.add(argDecl);
+                    argumentsInfo.add(argDecl.variableInfo);
+                } else {
+                    break;
+                }
+            }
+            long blockComplLimit = (long) (PseudoRandom.random() * complexityLimit);
+            body = builder.setOwnerKlass(ownerClass)
+                    .setResultType(resType)
+                    .setComplexityLimit(blockComplLimit)
+                    .setStatementLimit(statementLimit)
+                    .setOperatorLimit(operatorLimit)
+                    .setLevel(level)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(false)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(true)
+                    .getBlockFactory()
+                    .produce();
+            if (!resType.equals(new TypeVoid())) {
+                returnNode = builder.setComplexityLimit(complexityLimit - blockComplLimit)
+                        .setExceptionSafe(false)
+                        .getReturnFactory()
+                        .produce();
+            } else {
+                returnNode = null;
+            }
+        } finally {
+            SymbolTable.pop();
+        }
+        // addChildren(argumentsDeclaration); // not neccessary while complexity() doesn't use it
+        functionInfo = new FunctionInfo(name, ownerClass, resType, body == null ? 0 : body.complexity(),
+                flags, argumentsInfo);
+        // If it's all ok, add the function to the symbol table.
+        SymbolTable.add(functionInfo);
+        return new FunctionDefinition(functionInfo, argumentsDeclaration, body, returnNode);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,156 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+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;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.functions.Function;
+import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class FunctionFactory extends SafeFactory {
+    private final FunctionInfo functionInfo;
+    private final int operatorLimit;
+    private final long complexityLimit;
+    private final boolean exceptionSafe;
+    private final TypeKlass ownerClass;
+
+    FunctionFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe) {
+        functionInfo = new FunctionInfo();
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+        this.ownerClass = ownerClass;
+        this.functionInfo.type = resultType;
+        this.exceptionSafe = exceptionSafe;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        // Currently no function is exception-safe
+        if (exceptionSafe) {
+            throw new ProductionFailedException();
+        }
+        ArrayList<Symbol> allFunctions;
+        if (functionInfo.type == null) {
+            allFunctions = new ArrayList<>(SymbolTable.getAllCombined(FunctionInfo.class));
+        } else {
+            allFunctions = new ArrayList<>(SymbolTable.get(functionInfo.type, FunctionInfo.class));
+        }
+        if (!allFunctions.isEmpty()) {
+            PseudoRandom.shuffle(allFunctions);
+            Collection<TypeKlass> klassHierarchy = ownerClass.getAllParents();
+            for (Symbol function : allFunctions) {
+                FunctionInfo functionInfo = (FunctionInfo) function;
+                // Don't try to construct abstract classes.
+                if (functionInfo.isConstructor() && functionInfo.klass.isAbstract()) {
+                    continue;
+                }
+                // We don't call methods from the same class which are not final, because if we
+                // do this may produce an infinite recursion. Simple example:
+                // class  A
+                // {
+                //     f1() { }
+                //     f2() { f1(); }
+                // }
+                //
+                // class B : A
+                // {
+                //    f1() { f2(); }
+                // }
+                //
+                // However the same example is obviously safe for static and final functions
+                // Also we introduce a special flag NONRECURSIVE to mark functions that
+                // are not overrided. We may also call such functions.
+
+                // 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 ((functionInfo.flags & FunctionInfo.FINAL) == 0 && (functionInfo.flags & FunctionInfo.STATIC) == 0
+                            && (functionInfo.flags & FunctionInfo.NONRECURSIVE) == 0) {
+                        continue;
+                    }
+                    if (inHierarchy && (functionInfo.flags & FunctionInfo.PRIVATE) > 0) {
+                        continue;
+                    }
+                } else {
+                    if ((functionInfo.flags & FunctionInfo.PUBLIC) == 0
+                            && (functionInfo.flags & FunctionInfo.DEFAULT) == 0) {
+                        continue;
+                    }
+                }
+                if (functionInfo.complexity < complexityLimit - 1) {
+                    try {
+                        List<IRNode> accum = new ArrayList<>();
+                        if (!functionInfo.argTypes.isEmpty()) {
+                            // Here we should do some analysis here to determine if
+                            // there are any conflicting functions due to possible
+                            // constant folding.
+
+                            // For example the following can be done:
+                            // Scan all the hieirachy where the class is declared.
+                            // 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,
+                                    FunctionInfo.class);
+                            for (Symbol s2 : allFuncsInKlass) {
+                                FunctionInfo i2 = (FunctionInfo) function;
+                                if (!i2.equals(functionInfo) && i2.name.equals(functionInfo.name)
+                                        && i2.argTypes.size() == functionInfo.argTypes.size()) {
+                                    noconsts = true;
+                                    break;
+                                }
+                            }
+                            long argComp = (complexityLimit - 1 - functionInfo.complexity) / functionInfo.argTypes.size();
+                            int argumentOperatorLimit = (operatorLimit - 1) / functionInfo.argTypes.size();
+                            IRNodeBuilder b = new IRNodeBuilder().setOwnerKlass(ownerClass)
+                                    .setComplexityLimit(argComp)
+                                    .setOperatorLimit(argumentOperatorLimit)
+                                    .setExceptionSafe(exceptionSafe)
+                                    .setNoConsts(noconsts);
+                            for (VariableInfo argType : functionInfo.argTypes) {
+                                accum.add(b.setResultType(argType.type)
+                                        .getExpressionFactory()
+                                        .produce());
+                            }
+                        }
+                        return new Function(ownerClass, functionInfo, accum);
+                    } catch (ProductionFailedException e) {
+                        // removeAllChildren();
+                    }
+                }
+            }
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionRedefinitionBlockFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,89 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.functions.FunctionRedefinitionBlock;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class FunctionRedefinitionBlockFactory extends Factory {
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final long complexityLimit;
+    private final int level;
+    private final TypeKlass ownerClass;
+    private final Collection<Symbol> functionSet;
+
+    FunctionRedefinitionBlockFactory(Collection<Symbol> functionSet, TypeKlass ownerClass,
+            long complexityLimit, int statementLimit, int operatorLimit, int level) {
+        this.functionSet = functionSet;
+        this.ownerClass = ownerClass;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        ArrayList<IRNode> content = new ArrayList<>();
+        if (functionSet.size() > 0) {
+            long funcComplexity = complexityLimit / functionSet.size();
+            IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(ownerClass)
+                    .setComplexityLimit(funcComplexity)
+                    .setStatementLimit(statementLimit)
+                    .setOperatorLimit(operatorLimit)
+                    .setLevel(level);
+            for (Symbol symbol : functionSet) {
+                FunctionInfo functionInfo = (FunctionInfo) symbol;
+                Symbol thisSymbol = null;
+                if ((functionInfo.flags & FunctionInfo.STATIC) > 0) {
+                    thisSymbol = SymbolTable.get("this", VariableInfo.class);
+                    SymbolTable.remove(thisSymbol);
+                }
+                try {
+                    content.add(builder.setFunctionInfo(functionInfo)
+                            .setFlags(functionInfo.flags)
+                            .getFunctionRedefinitionFactory()
+                            .produce());
+                } catch (ProductionFailedException e) {
+                    if ((functionInfo.flags & FunctionInfo.STATIC) == 0) {
+                        ownerClass.setAbstract();
+                    }
+                }
+                if ((functionInfo.flags & FunctionInfo.STATIC) > 0) {
+                    SymbolTable.add(thisSymbol);
+                }
+            }
+        }
+        return new FunctionRedefinitionBlock(content, level);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/FunctionRedefinitionFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,123 @@
+/*
+ * 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.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.SymbolTable;
+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.types.TypeKlass;
+import jdk.test.lib.jittester.types.TypeVoid;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class FunctionRedefinitionFactory extends Factory {
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final int level;
+    private final TypeKlass ownerClass;
+    private final FunctionInfo functionInfo;
+
+    FunctionRedefinitionFactory(FunctionInfo functionInfo, TypeKlass ownerClass,
+            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!
+        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;
+        }
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        ArrayList<VariableInfo> argumentsInfo = functionInfo.argTypes;
+        SymbolTable.push();
+        IRNode body;
+        IRNode returnNode;
+        ArrayList<ArgumentDeclaration> argumentsDeclaration;
+        try {
+            if ((functionInfo.flags & FunctionInfo.STATIC) > 0) {
+                argumentsDeclaration = new ArrayList<>(argumentsInfo.size());
+                for (VariableInfo varInfo : argumentsInfo) {
+                    argumentsDeclaration.add(new ArgumentDeclaration(varInfo));
+                    SymbolTable.add(varInfo);
+                }
+            } else {
+                argumentsDeclaration = new ArrayList<>(argumentsInfo.size() - 1);
+                SymbolTable.add(argumentsInfo.get(0));
+                for (int i = 1; i < argumentsInfo.size(); i++) {
+                    argumentsDeclaration.add(new ArgumentDeclaration(argumentsInfo.get(i)));
+                    SymbolTable.add(argumentsInfo.get(i));
+                }
+            }
+            long blockComplLimit = (long) (PseudoRandom.random() * complexityLimit);
+            IRNodeBuilder builder = new IRNodeBuilder()
+                    .setOwnerKlass(ownerClass)
+                    .setResultType(functionInfo.type)
+                    .setStatementLimit(statementLimit)
+                    .setOperatorLimit(operatorLimit);
+            body = builder.setComplexityLimit(blockComplLimit)
+                    .setLevel(level)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(false)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(true)
+                    .getBlockFactory()
+                    .produce();
+            if (!functionInfo.type.equals(new TypeVoid())) {
+                returnNode = builder.setComplexityLimit(complexityLimit - blockComplLimit)
+                        .setExceptionSafe(false)
+                        .getReturnFactory()
+                        .produce();
+            } else {
+                returnNode = null;
+            }
+        } catch (ProductionFailedException e) {
+            SymbolTable.pop();
+            SymbolTable.add(functionInfo);
+            throw e;
+        }
+        SymbolTable.pop();
+        if ((functionInfo.flags & FunctionInfo.STATIC) == 0) {
+            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);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/IRNodeBuilder.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,706 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.Collection;
+import java.util.Optional;
+import jdk.test.lib.jittester.Literal;
+import jdk.test.lib.jittester.LocalVariable;
+import jdk.test.lib.jittester.OperatorKind;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+public class IRNodeBuilder {
+    //private Optional<Type> variableType = Optional.empty();
+    private Optional<TypeKlass> argumentType = Optional.empty();
+    private Optional<Integer> variableNumber = Optional.empty();
+    private Optional<Long> complexityLimit = Optional.empty();
+    private Optional<Integer> operatorLimit = Optional.empty();
+    private Optional<TypeKlass> ownerClass = Optional.empty();
+    private Optional<Type> resultType = Optional.empty();
+    private Optional<Boolean> safe = Optional.empty();
+    private Optional<Boolean> noConsts = Optional.empty();
+    private Optional<OperatorKind> opKind = Optional.empty();
+    private Optional<Integer> statementLimit = Optional.empty();
+    private Optional<Boolean> subBlock = Optional.empty();
+    private Optional<Boolean> canHaveBreaks = Optional.empty();
+    private Optional<Boolean> canHaveContinues = Optional.empty();
+    private Optional<Boolean> canHaveReturn = Optional.empty();
+    //not in use yet because 'throw' is only placed to the locations where 'return' is allowed
+    private Optional<Boolean> canHaveThrow = Optional.empty();
+    private Optional<Integer> level = Optional.empty();
+    private Optional<String> prefix = Optional.empty();
+    private Optional<Integer> memberFunctionsLimit = Optional.empty();
+    private Optional<Integer> memberFunctionsArgLimit = Optional.empty();
+    private Optional<LocalVariable> localVariable = Optional.empty();
+    private Optional<Boolean> isLocal = Optional.empty();
+    private Optional<Boolean> isStatic = Optional.empty();
+    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() {
+        return new ArgumentDeclarationFactory(getArgumentType(), getVariableNumber());
+    }
+
+    public Factory getArithmeticOperatorFactory() throws ProductionFailedException {
+        return new ArithmeticOperatorFactory(getComplexityLimit(), getOperatorLimit(),
+                getOwnerClass(), getResultType(), getExceptionSafe(), getNoConsts());
+    }
+
+    public ArrayCreationFactory getArrayCreationFactory() {
+        return new ArrayCreationFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getResultType(), getExceptionSafe(), getNoConsts());
+    }
+
+    public ArrayElementFactory getArrayElementFactory() {
+        return new ArrayElementFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getResultType(), getExceptionSafe(), getNoConsts());
+    }
+
+    public ArrayExtractionFactory getArrayExtractionFactory() {
+        return new ArrayExtractionFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getResultType(), getExceptionSafe(), getNoConsts());
+    }
+
+    public AssignmentOperatorFactory getAssignmentOperatorFactory() {
+        return new AssignmentOperatorFactory(getComplexityLimit(), getOperatorLimit(),
+                getOwnerClass(), resultType.orElse(null), getExceptionSafe(), getNoConsts());
+    }
+
+    public BinaryOperatorFactory getBinaryOperatorFactory() throws ProductionFailedException {
+        OperatorKind o = getOperatorKind();
+        switch (o) {
+            case ASSIGN:
+                return new AssignmentOperatorImplFactory(getComplexityLimit(), getOperatorLimit(),
+                        getOwnerClass(), resultType.orElse(null), getExceptionSafe(), getNoConsts());
+            case AND:
+            case OR:
+                return new BinaryLogicOperatorFactory(o, getComplexityLimit(), getOperatorLimit(),
+                        getOwnerClass(), resultType.orElse(null), getExceptionSafe(), getNoConsts());
+            case BIT_OR:
+            case BIT_XOR:
+            case BIT_AND:
+                return new BinaryBitwiseOperatorFactory(o, getComplexityLimit(), getOperatorLimit(),
+                        getOwnerClass(), resultType.orElse(null), getExceptionSafe(), getNoConsts());
+
+            case EQ:
+            case NE:
+                return new BinaryEqualityOperatorFactory(o, getComplexityLimit(),
+                        getOperatorLimit(), getOwnerClass(), resultType.orElse(null), getExceptionSafe(),
+                        getNoConsts());
+            case GT:
+            case LT:
+            case GE:
+            case LE:
+                return new BinaryComparisonOperatorFactory(o, getComplexityLimit(),
+                        getOperatorLimit(), getOwnerClass(), resultType.orElse(null), getExceptionSafe(),
+                        getNoConsts());
+            case SHR:
+            case SHL:
+            case SAR:
+                return new BinaryShiftOperatorFactory(o, getComplexityLimit(), getOperatorLimit(),
+                        getOwnerClass(), resultType.orElse(null), getExceptionSafe(), getNoConsts());
+            case ADD:
+            case SUB:
+            case MUL:
+            case DIV:
+            case MOD:
+                return new BinaryArithmeticOperatorFactory(o, getComplexityLimit(),
+                        getOperatorLimit(), getOwnerClass(), resultType.orElse(null), getExceptionSafe(),
+                        getNoConsts());
+            case STRADD:
+                return new BinaryStringPlusFactory(getComplexityLimit(), getOperatorLimit(),
+                        getOwnerClass(), resultType.orElse(null), getExceptionSafe(), getNoConsts());
+            case COMPOUND_ADD:
+            case COMPOUND_SUB:
+            case COMPOUND_MUL:
+            case COMPOUND_DIV:
+            case COMPOUND_MOD:
+                return new CompoundArithmeticAssignmentOperatorFactory(o, getComplexityLimit(),
+                        getOperatorLimit(), getOwnerClass(), resultType.orElse(null), getExceptionSafe(),
+                        getNoConsts());
+            case COMPOUND_AND:
+            case COMPOUND_OR:
+            case COMPOUND_XOR:
+                return new CompoundBitwiseAssignmentOperatorFactory(o, getComplexityLimit(),
+                        getOperatorLimit(), getOwnerClass(), resultType.orElse(null), getExceptionSafe(),
+                        getNoConsts());
+            case COMPOUND_SHR:
+            case COMPOUND_SHL:
+            case COMPOUND_SAR:
+                return new CompoundShiftAssignmentOperatorFactory(o, getComplexityLimit(),
+                        getOperatorLimit(), getOwnerClass(), resultType.orElse(null), getExceptionSafe(),
+                        getNoConsts());
+            default:
+                throw new ProductionFailedException();
+        }
+    }
+
+    public UnaryOperatorFactory getUnaryOperatorFactory() throws ProductionFailedException {
+        OperatorKind o = getOperatorKind();
+        switch (o) {
+            case NOT:
+                return new LogicalInversionOperatorFactory(getComplexityLimit(),
+                        getOperatorLimit(), getOwnerClass(), resultType.orElse(null), getExceptionSafe(),
+                        getNoConsts());
+            case BIT_NOT:
+                return new BitwiseInversionOperatorFactory(getComplexityLimit(),
+                        getOperatorLimit(), getOwnerClass(), resultType.orElse(null), getExceptionSafe(),
+                        getNoConsts());
+            case UNARY_PLUS:
+            case UNARY_MINUS:
+                return new UnaryPlusMinusOperatorFactory(o, getComplexityLimit(),
+                        getOperatorLimit(), getOwnerClass(), resultType.orElse(null), getExceptionSafe(),
+                        getNoConsts());
+            case PRE_DEC:
+            case POST_DEC:
+            case PRE_INC:
+            case POST_INC:
+                return new IncDecOperatorFactory(o, getComplexityLimit(), getOperatorLimit(),
+                        getOwnerClass(), resultType.orElse(null), getExceptionSafe(), getNoConsts());
+            default:
+                throw new ProductionFailedException();
+        }
+    }
+
+    public BlockFactory getBlockFactory() throws ProductionFailedException {
+        return new BlockFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
+            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'
+    }
+
+    public BreakFactory getBreakFactory() {
+        return new BreakFactory();
+    }
+
+    public CastOperatorFactory getCastOperatorFactory() {
+        return new CastOperatorFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getResultType(), getExceptionSafe(), getNoConsts());
+    }
+
+    public Factory getClassDefinitionBlockFactory() {
+        return new ClassDefinitionBlockFactory(getPrefix(),
+                ProductionParams.classesLimit.value(),
+                ProductionParams.memberFunctionsLimit.value(),
+                ProductionParams.memberFunctionsArgLimit.value(),
+                getComplexityLimit(),
+                ProductionParams.statementLimit.value(),
+                ProductionParams.operatorLimit.value(),
+                getLevel());
+    }
+
+    public Factory getMainKlassFactory() {
+        return new MainKlassFactory(getName(), getComplexityLimit(),
+                ProductionParams.memberFunctionsLimit.value(),
+                ProductionParams.memberFunctionsArgLimit.value(),
+                ProductionParams.statementLimit.value(),
+                ProductionParams.testStatementLimit.value(),
+                ProductionParams.operatorLimit.value());
+    }
+
+    public ConstructorDefinitionBlockFactory getConstructorDefinitionBlockFactory() {
+        return new ConstructorDefinitionBlockFactory(getOwnerClass(), getMemberFunctionsLimit(),
+                ProductionParams.memberFunctionsArgLimit.value(), getComplexityLimit(),
+                getStatementLimit(), getOperatorLimit(), getLevel());
+    }
+
+    public ConstructorDefinitionFactory getConstructorDefinitionFactory() {
+        return new ConstructorDefinitionFactory(getOwnerClass(), getComplexityLimit(),
+                getStatementLimit(), getOperatorLimit(),
+                getMemberFunctionsArgLimit(), getLevel());
+    }
+
+    public ContinueFactory getContinueFactory() {
+        return new ContinueFactory();
+    }
+
+    public CounterInitializerFactory getCounterInitializerFactory(int counterValue) {
+        return new CounterInitializerFactory(getOwnerClass(), counterValue);
+    }
+
+    public CounterManipulatorFactory getCounterManipulatorFactory() {
+        return new CounterManipulatorFactory(getLocalVariable());
+    }
+
+    public DeclarationFactory getDeclarationFactory() {
+        return new DeclarationFactory(getOwnerClass(), getComplexityLimit(), getOperatorLimit(),
+            getIsLocal(), getExceptionSafe());
+    }
+
+    public DoWhileFactory getDoWhileFactory() {
+        return new DoWhileFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
+                getStatementLimit(), getOperatorLimit(), getLevel(), getCanHaveReturn());
+    }
+
+    public WhileFactory getWhileFactory() {
+        return new WhileFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
+                getStatementLimit(), getOperatorLimit(), getLevel(), getCanHaveReturn());
+    }
+
+    public IfFactory getIfFactory() {
+        return new IfFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
+        getStatementLimit(), getOperatorLimit(), getLevel(), getCanHaveBreaks(),
+                getCanHaveContinues(), getCanHaveReturn());
+    }
+
+    public ForFactory getForFactory() {
+        return new ForFactory(getOwnerClass(), getResultType(), getComplexityLimit(),
+                getStatementLimit(), getOperatorLimit(), getLevel(), getCanHaveReturn());
+    }
+
+    public SwitchFactory getSwitchFactory() { // TODO: switch is not used now
+        return new SwitchFactory(getOwnerClass(), getComplexityLimit(), getStatementLimit(),
+                getOperatorLimit(), getLevel(), getCanHaveReturn());
+    }
+
+    public ExpressionFactory getExpressionFactory() throws ProductionFailedException {
+        return new ExpressionFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getResultType(), getExceptionSafe(), getNoConsts());
+    }
+
+    public FunctionDeclarationBlockFactory getFunctionDeclarationBlockFactory() {
+        return new FunctionDeclarationBlockFactory(getOwnerClass(), getMemberFunctionsLimit(),
+                getMemberFunctionsArgLimit(), getLevel());
+    }
+
+    public FunctionDeclarationFactory getFunctionDeclarationFactory() {
+        return new FunctionDeclarationFactory(getName(), getOwnerClass(),resultType.orElse(null),
+                getMemberFunctionsArgLimit(), getFlags());
+    }
+
+    public FunctionDefinitionBlockFactory getFunctionDefinitionBlockFactory() {
+        return new FunctionDefinitionBlockFactory(getOwnerClass(), getMemberFunctionsLimit(),
+                getMemberFunctionsArgLimit(), getComplexityLimit(), getStatementLimit(),
+                getOperatorLimit(), getLevel(), getFlags());
+    }
+
+    public FunctionDefinitionFactory getFunctionDefinitionFactory() {
+        return new FunctionDefinitionFactory(getName(), getOwnerClass(), resultType.orElse(null),
+                getComplexityLimit(), getStatementLimit(), getOperatorLimit(),
+                getMemberFunctionsArgLimit(), getLevel(), getFlags());
+    }
+
+    public FunctionFactory getFunctionFactory() {
+        return new FunctionFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                resultType.orElse(null), getExceptionSafe());
+    }
+
+    public FunctionRedefinitionBlockFactory getFunctionRedefinitionBlockFactory(Collection<Symbol>
+            functionSet) {
+        return new FunctionRedefinitionBlockFactory(functionSet, getOwnerClass(),
+                getComplexityLimit(), getStatementLimit(), getOperatorLimit(), getLevel());
+    }
+
+    public FunctionRedefinitionFactory getFunctionRedefinitionFactory() {
+        return new FunctionRedefinitionFactory(getFunctionInfo(), getOwnerClass(),
+                getComplexityLimit(), getStatementLimit(), getOperatorLimit(), getLevel(),
+                getFlags());
+    }
+
+    public InterfaceFactory getInterfaceFactory() {
+        return new InterfaceFactory(getName(), getMemberFunctionsLimit(),
+                getMemberFunctionsArgLimit(), getLevel());
+    }
+
+    public KlassFactory getKlassFactory() {
+        return new KlassFactory(getName(), getPrinterName(), getComplexityLimit(),
+                getMemberFunctionsLimit(), getMemberFunctionsArgLimit(), getStatementLimit(),
+                getOperatorLimit(), getLevel());
+    }
+
+    public LimitedExpressionFactory getLimitedExpressionFactory() throws ProductionFailedException {
+        return new LimitedExpressionFactory(getComplexityLimit(), getOperatorLimit(),
+                getOwnerClass(), getResultType(), getExceptionSafe(), getNoConsts());
+    }
+
+    public LiteralFactory getLiteralFactory() {
+        return new LiteralFactory(getResultType());
+    }
+
+    public LocalVariableFactory getLocalVariableFactory() {
+        return new LocalVariableFactory(/*getVariableType()*/getResultType(), getFlags());
+    }
+
+    public LogicOperatorFactory getLogicOperatorFactory() throws ProductionFailedException {
+        return new LogicOperatorFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getResultType(), getExceptionSafe(), getNoConsts());
+    }
+
+    public LoopingConditionFactory getLoopingConditionFactory(Literal _limiter) {
+        return new LoopingConditionFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getLocalVariable(), _limiter);
+    }
+
+    public NonStaticMemberVariableFactory getNonStaticMemberVariableFactory() {
+        return new NonStaticMemberVariableFactory(getComplexityLimit(), getOperatorLimit(),
+                getOwnerClass(), /*getVariableType()*/getResultType(), getFlags(), getExceptionSafe());
+    }
+
+    public NothingFactory getNothingFactory() {
+        return new NothingFactory();
+    }
+
+    public PrintVariablesFactory getPrintVariablesFactory() {
+        return new PrintVariablesFactory(getPrinterName(), getOwnerClass(), getLevel());
+    }
+
+    public ReturnFactory getReturnFactory() {
+        return new ReturnFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getResultType(), getExceptionSafe());
+    }
+
+    public ThrowFactory getThrowFactory() {
+        return new ThrowFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(), getResultType(), getExceptionSafe());
+    }
+
+    public StatementFactory getStatementFactory() {
+        return new StatementFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getExceptionSafe(), getNoConsts(), semicolon.orElse(true));
+    }
+
+    public StaticConstructorDefinitionFactory getStaticConstructorDefinitionFactory() {
+        return new StaticConstructorDefinitionFactory(getOwnerClass(), getComplexityLimit(),
+                getStatementLimit(), getOperatorLimit(), getLevel());
+    }
+
+    public StaticMemberVariableFactory getStaticMemberVariableFactory() {
+        return new StaticMemberVariableFactory(getOwnerClass(), /*getVariableType()*/getResultType(), getFlags());
+    }
+
+    public TernaryOperatorFactory getTernaryOperatorFactory() {
+        return new TernaryOperatorFactory(getComplexityLimit(), getOperatorLimit(), getOwnerClass(),
+                getResultType(), getExceptionSafe(), getNoConsts());
+    }
+
+    public VariableDeclarationBlockFactory getVariableDeclarationBlockFactory() {
+        return new VariableDeclarationBlockFactory(getOwnerClass(), getComplexityLimit(),
+                getOperatorLimit(), getLevel(), getExceptionSafe());
+    }
+
+    public VariableDeclarationFactory getVariableDeclarationFactory() {
+        return new VariableDeclarationFactory(getOwnerClass(), getIsStatic(), getIsLocal(), getResultType());
+    }
+
+    public VariableFactory 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 TryCatchBlockFactory getTryCatchBlockFactory() {
+        return new TryCatchBlockFactory(getOwnerClass(), getResultType(),
+                getComplexityLimit(), getStatementLimit(), getOperatorLimit(),
+                getLevel(), subBlock.orElse(false), getCanHaveBreaks(),
+                getCanHaveContinues(), getCanHaveReturn());
+    }
+
+/*    public IRNodeBuilder setVariableType(Type value) {
+        variableType = Optional.of(value);
+        return this;
+    }*/
+
+    public IRNodeBuilder setArgumentType(TypeKlass value) {
+        argumentType = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setVariableNumber(int value) {
+        variableNumber = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setComplexityLimit(long value) {
+        complexityLimit = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setOperatorLimit(int value) {
+        operatorLimit = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setStatementLimit(int value) {
+        statementLimit = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setOwnerKlass(TypeKlass value) {
+        ownerClass = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setResultType(Type value) {
+        resultType = Optional.of(value);
+        return this;
+    }
+    // TODO: check if safe is always true in current implementation
+    public IRNodeBuilder setExceptionSafe(boolean value) {
+        safe = Optional.of(value);
+        return this;
+    }
+    // TODO: check is noconsts is always false in current implementation
+    public IRNodeBuilder setNoConsts(boolean value) {
+        noConsts = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setOperatorKind(OperatorKind value) {
+        opKind = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setLevel(int value) {
+        level = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setSubBlock(boolean value) {
+        subBlock = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setCanHaveBreaks(boolean value) {
+        canHaveBreaks = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setCanHaveContinues(boolean value) {
+        canHaveContinues = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setCanHaveReturn(boolean value) {
+        canHaveReturn = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setCanHaveThrow(boolean value) {
+        canHaveThrow = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setPrefix(String value) {
+        prefix = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setMemberFunctionsLimit(int value) {
+        memberFunctionsLimit = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setMemberFunctionsArgLimit(int value) {
+        memberFunctionsArgLimit = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setLocalVariable(LocalVariable value) {
+        localVariable = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setIsLocal(boolean value) {
+        isLocal = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setIsStatic(boolean value) {
+        isStatic = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setIsInitialized(boolean value) {
+        isInitialized = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setIsConstant(boolean value) {
+        isConstant = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setName(String value) {
+        name = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setFlags(int value) {
+        flags = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setFunctionInfo(FunctionInfo value) {
+        functionInfo = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setPrinterName(String value) {
+        printerName = Optional.of(value);
+        return this;
+    }
+
+    public IRNodeBuilder setSemicolon(boolean value) {
+        semicolon = Optional.of(value);
+        return this;
+    }
+
+    // getters
+/*    private Type getVariableType() {
+        return variableType.orElseThrow(() -> new IllegalArgumentException(
+                "Variable type wasn't set"));
+    }*/
+
+    private TypeKlass getArgumentType() {
+        return argumentType.orElseThrow(() -> new IllegalArgumentException(
+                "Argument type wasn't set"));
+    }
+
+    private int getVariableNumber() {
+        return variableNumber.orElseThrow(() -> new IllegalArgumentException(
+                "Variable number wasn't set"));
+    }
+
+    private long getComplexityLimit() {
+        return complexityLimit.orElseThrow(() -> new IllegalArgumentException(
+                "Complexity limit wasn't set"));
+    }
+
+    private int getOperatorLimit() {
+        return operatorLimit.orElseThrow(() -> new IllegalArgumentException(
+                "Operator limit wasn't set"));
+    }
+
+    private int getStatementLimit() {
+        return statementLimit.orElseThrow(() -> new IllegalArgumentException(
+                "Statement limit wasn't set"));
+    }
+
+    private TypeKlass getOwnerClass() {
+        return ownerClass.orElseThrow(() -> new IllegalArgumentException("Type_Klass wasn't set"));
+    }
+
+    private Type getResultType() {
+        return resultType.orElseThrow(() -> new IllegalArgumentException("Return type wasn't set"));
+    }
+
+    private boolean getExceptionSafe() {
+        return safe.orElseThrow(() -> new IllegalArgumentException("Safe wasn't set"));
+    }
+
+    private boolean getNoConsts() {
+        return noConsts.orElseThrow(() -> new IllegalArgumentException("NoConsts wasn't set"));
+    }
+
+    private OperatorKind getOperatorKind() {
+        return opKind.orElseThrow(() -> new IllegalArgumentException("Operator kind wasn't set"));
+    }
+
+    private int getLevel() {
+        return level.orElseThrow(() -> new IllegalArgumentException("Level wasn't set"));
+    }
+
+    private String getPrefix() {
+        return prefix.orElseThrow(() -> new IllegalArgumentException("Prefix wasn't set"));
+    }
+
+    private int getMemberFunctionsLimit() {
+        return memberFunctionsLimit.orElseThrow(() -> new IllegalArgumentException(
+                "memberFunctions limit wasn't set"));
+    }
+
+    private int getMemberFunctionsArgLimit() {
+        return memberFunctionsArgLimit.orElseThrow(() -> new IllegalArgumentException(
+                "memberFunctionsArg limit wasn't set"));
+    }
+
+    private LocalVariable getLocalVariable() {
+        return localVariable.orElseThrow(() -> new IllegalArgumentException(
+                "local variable wasn't set"));
+    }
+
+    private boolean getIsLocal() {
+        return isLocal.orElseThrow(() -> new IllegalArgumentException("isLocal wasn't set"));
+    }
+
+    private boolean getIsStatic() {
+        return isStatic.orElseThrow(() -> new IllegalArgumentException("isStatic wasn't set"));
+    }
+
+    private boolean getIsInitialized() {
+        return isInitialized.orElseThrow(() -> new IllegalArgumentException(
+                "isInitialized wasn't set"));
+    }
+
+    private boolean getIsConstant() {
+        return isConstant.orElseThrow(() -> new IllegalArgumentException("isConstant wasn't set"));
+    }
+
+    private boolean getCanHaveReturn() {
+        return canHaveReturn.orElseThrow(() -> new IllegalArgumentException(
+                "canHaveReturn wasn't set"));
+    }
+
+    private boolean getCanHaveBreaks() {
+        return canHaveBreaks.orElseThrow(() -> new IllegalArgumentException(
+                "canHaveBreaks wasn't set"));
+    }
+
+    private boolean getCanHaveContinues() {
+        return canHaveContinues.orElseThrow(() -> new IllegalArgumentException(
+                "canHaveContinues wasn't set"));
+    }
+
+    private String getName() {
+        return name.orElseThrow(() -> new IllegalArgumentException("Name wasn't set"));
+    }
+
+    private int getFlags() {
+        return flags.orElseThrow(() -> new IllegalArgumentException("Flags wasn't set"));
+    }
+
+    private FunctionInfo getFunctionInfo() {
+        return functionInfo.orElseThrow(() -> new IllegalArgumentException(
+                "FunctionInfo wasn't set"));
+    }
+
+    private String getPrinterName() {
+        return printerName.orElseThrow(() -> new IllegalArgumentException(
+                "printerName wasn't set"));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/IfFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,133 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+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.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;
+    protected final TypeKlass ownerClass;
+    protected final Type returnType;
+    protected final int level;
+
+    IfFactory(TypeKlass ownerClass, Type returnType, long complexityLimit, int statementLimit,
+            int operatorLimit, int level, boolean canHaveBreaks, boolean canHaveContinues,
+            boolean canHaveReturn) {
+        this.ownerClass = ownerClass;
+        this.returnType = returnType;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        this.canHaveBreaks = canHaveBreaks;
+        this.canHaveContinues = canHaveContinues;
+        this.canHaveReturn = canHaveReturn;
+    }
+
+    @Override
+    public IRNode sproduce() throws ProductionFailedException {
+        // resizeUpChildren(If.IfPart.values().length);
+        if (statementLimit > 0 && complexityLimit > 0) {
+            long conditionComplLimit = (long) (0.01 * PseudoRandom.random() * (complexityLimit - 1));
+            IRNodeBuilder builder = new IRNodeBuilder()
+                    .setOwnerKlass(ownerClass)
+                    .setOperatorLimit(operatorLimit);
+            IRNode condition = builder.setComplexityLimit(conditionComplLimit)
+                    .setResultType(new TypeBoolean())
+                    .setExceptionSafe(false)
+                    .setNoConsts(false)
+                    .getLimitedExpressionFactory()
+                    .produce();
+            // setChild(If.IfPart.CONDITION.ordinal(), condition);
+            long remainder = complexityLimit - 1 - condition.complexity();
+            long ifBlockComplLimit = (long) (PseudoRandom.random() * remainder);
+            long elseBlockComplLimit = remainder - ifBlockComplLimit;
+            int ifBlockLimit = (int) (PseudoRandom.random() * statementLimit);
+            int elseBlockLimit = statementLimit - ifBlockLimit;
+            If.IfPart controlDeviation;
+            if (ifBlockLimit > 0 && elseBlockLimit <= 0) {
+                controlDeviation = If.IfPart.THEN;
+            } else {
+                controlDeviation = PseudoRandom.randomBoolean() ? If.IfPart.THEN : If.IfPart.ELSE;
+            }
+            if (ifBlockLimit > 0 && ifBlockComplLimit > 0) {
+                IRNode thenBlock = null;
+                builder.setResultType(returnType)
+                        .setLevel(level)
+                        .setComplexityLimit(ifBlockComplLimit)
+                        .setStatementLimit(ifBlockLimit);
+                if (controlDeviation == If.IfPart.THEN) {
+                    thenBlock = builder.setSubBlock(false)
+                            .setCanHaveBreaks(canHaveBreaks)
+                            .setCanHaveContinues(canHaveContinues)
+                            .setCanHaveReturn(canHaveReturn)
+                            .getBlockFactory()
+                            .produce();
+                } else {
+                    thenBlock = builder.setSubBlock(false)
+                            .setCanHaveBreaks(false)
+                            .setCanHaveContinues(false)
+                            .setCanHaveReturn(false)
+                            .getBlockFactory()
+                            .produce();
+                }
+                // setChild(If.IfPart.THEN.ordinal(), thenBlock);
+                IRNode elseBlock = null;
+                if (elseBlockLimit > 0 && elseBlockComplLimit > 0) {
+                    builder.setComplexityLimit(elseBlockComplLimit)
+                            .setStatementLimit(elseBlockLimit);
+                    if (controlDeviation == If.IfPart.ELSE) {
+                        elseBlock = builder.setSubBlock(false)
+                            .setCanHaveBreaks(canHaveBreaks)
+                            .setCanHaveContinues(canHaveContinues)
+                            .setCanHaveReturn(canHaveReturn)
+                            .getBlockFactory()
+                            .produce();
+                    } else {
+                        elseBlock = builder.setSubBlock(false)
+                            .setCanHaveBreaks(false)
+                            .setCanHaveContinues(false)
+                            .setCanHaveReturn(false)
+                            .getBlockFactory()
+                            .produce();
+                    }
+                }
+                // setChild(If.IfPart.ELSE.ordinal(), elseBlock);
+                return new If(condition, thenBlock, elseBlock, level);
+            }
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/IncDecOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,59 @@
+/*
+ * 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.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,
+                          Type klass, Type resultType, boolean safe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, klass, resultType, safe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return TypeList.isBuiltInInt(resultType) && !resultType.equals(new TypeBoolean());
+    }
+
+    @Override
+    protected IRNode generateProduction(Type l) throws ProductionFailedException {
+        return new UnaryOperator(opKind, new IRNodeBuilder().setComplexityLimit(complexityLimit - 1)
+                .setOperatorLimit(operatorLimit - 1)
+                .setOwnerKlass((TypeKlass) ownerClass)
+                .setResultType(l)
+                .setIsConstant(false)
+                .setIsInitialized(true)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(exceptionSafe)
+                .getVariableFactory()
+                .produce());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/InterfaceFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,97 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.classes.Interface;
+import jdk.test.lib.jittester.functions.FunctionInfo;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class InterfaceFactory extends Factory {
+    private final String name;
+    private final int memberFunctionsLimit;
+    private final int memberFunctionsArgLimit;
+    private final int level;
+    private TypeKlass parent = null;
+
+    InterfaceFactory(String name, int memberFunctionsLimit, int memberFuncArgLimit, int lvl) {
+        this.name = name;
+        this.memberFunctionsLimit = memberFunctionsLimit;
+        this.memberFunctionsArgLimit = memberFuncArgLimit;
+        this.level = lvl;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        TypeKlass thisKlass;
+        // Do we want to inherit something?
+        if (!ProductionParams.disableInheritance.value()) {
+            // Grab all Klasses from the TypeList and select one to be a parent
+            LinkedList<Type> types = new LinkedList<>(TypeList.getAll());
+            for (Iterator<Type> i = types.iterator(); i.hasNext();) {
+                Type klass = i.next();
+                if (!(klass instanceof TypeKlass) || !((TypeKlass) klass).isInterface()) {
+                    i.remove();
+                }
+            }
+            PseudoRandom.shuffle(types);
+            if (!types.isEmpty()) {
+                parent = (TypeKlass) types.getFirst();
+            }
+        }
+        thisKlass = new TypeKlass(name, TypeKlass.INTERFACE);
+        if (parent != null) {
+            thisKlass.addParent(parent.getName());
+            thisKlass.setParent(parent);
+            parent.addChild(name);
+            for (Symbol symbol : SymbolTable.getAllCombined(parent, FunctionInfo.class)) {
+                FunctionInfo functionInfo = (FunctionInfo) symbol.deepCopy();
+                functionInfo.klass = thisKlass;
+                functionInfo.argTypes.get(0).type = thisKlass;
+                SymbolTable.add(functionInfo);
+            }
+        }
+        IRNode functionDeclarations = null;
+        try {
+            functionDeclarations = new IRNodeBuilder().setOwnerKlass(thisKlass)
+                    .setMemberFunctionsLimit(memberFunctionsLimit)
+                    .setMemberFunctionsArgLimit(memberFunctionsArgLimit)
+                    .setLevel(level + 1)
+                    .getFunctionDeclarationBlockFactory()
+                    .produce();
+        } finally {
+            TypeList.add(thisKlass);
+        }
+        return new Interface(parent, name, level, functionDeclarations);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/KlassFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,288 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Symbol;
+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.classes.Klass;
+import jdk.test.lib.jittester.functions.FunctionDeclarationBlock;
+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.utils.PseudoRandom;
+
+class KlassFactory extends Factory {
+    private final String name;
+    private final String printerName;
+    private final long complexityLimit;
+    private final int statementsInFunctionLimit;
+    private final int operatorLimit;
+    private final int memberFunctionsArgLimit;
+    private final int level;
+    private final ArrayList<TypeKlass> interfaces;
+    private TypeKlass thisKlass;
+    private TypeKlass parent;
+    private int memberFunctionsLimit;
+
+    KlassFactory(String name, String printerName, 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;
+        this.statementsInFunctionLimit = statementsInFunctionLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        interfaces = new ArrayList<>();
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        HashSet<Symbol> abstractSet = new HashSet<>();
+        HashSet<Symbol> overrideSet = new HashSet<>();
+        thisKlass = new TypeKlass(name);
+        // Do we want to inherit something?
+        if (!ProductionParams.disableInheritance.value()) {
+            inheritClass();
+            inheritInterfaces();
+            // Now, we should carefully construct a set of all methods with are still abstract.
+            // In order to do that, we will make two sets of methods: abstract and non-abstract.
+            // Then by substracting non-abstract from abstract we'll get what we want.
+            HashSet<Symbol> nonAbstractSet = new HashSet<>();
+            for (Symbol symbol : SymbolTable.getAllCombined(thisKlass, FunctionInfo.class)) {
+                FunctionInfo functionInfo = (FunctionInfo) symbol;
+                // There could be multiple definitions or declarations encountered,
+                // but all we interested in are signatures.
+                if ((functionInfo.flags & FunctionInfo.ABSTRACT) > 0) {
+                    abstractSet.add(functionInfo);
+                } else {
+                    nonAbstractSet.add(functionInfo);
+                }
+            }
+            abstractSet.removeAll(nonAbstractSet);
+            // We may randomly remove some elements from the abstract set in order to force generation
+            // of an abstract class.
+            if (PseudoRandom.randomBoolean(0.2)) {
+                // so, we want to be abstract..
+                for (Iterator<Symbol> i = abstractSet.iterator(); i.hasNext();) {
+                    i.next();
+                    if (PseudoRandom.randomBoolean(0.2)) {
+                        thisKlass.setAbstract();
+                        i.remove();
+                    }
+                }
+            }
+            if (PseudoRandom.randomBoolean(0.2)) {
+                int redefineLimit = (int) (memberFunctionsLimit * PseudoRandom.random());
+                if (redefineLimit > 0) {
+                    // We may also select some functions from the hierarchy that we want
+                    // to redefine..
+                    int i = 0;
+                    ArrayList<Symbol> shuffledNonAbstractSet = new ArrayList<>(nonAbstractSet);
+                    PseudoRandom.shuffle(shuffledNonAbstractSet);
+                    for (Symbol symbol : shuffledNonAbstractSet) {
+                        if (++i > redefineLimit) {
+                            break;
+                        }
+                        FunctionInfo functionInfo = (FunctionInfo) symbol;
+                        if ((functionInfo.flags & FunctionInfo.FINAL) > 0) {
+                            continue;
+                        }
+                        overrideSet.add(functionInfo);
+                    }
+                }
+            }
+            memberFunctionsLimit -= abstractSet.size() + overrideSet.size();
+            // Ok, remove the symbols from the table which are going to be overrided.
+            // Because the redefiner would probably modify them and put them back into table.
+            for (Symbol symbol : abstractSet) {
+                SymbolTable.remove(symbol);
+            }
+            for (Symbol symbol : overrideSet) {
+                SymbolTable.remove(symbol);
+            }
+        } else {
+            parent = (TypeKlass) TypeList.find("java.lang.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;
+        IRNode constructorDefinitions = null;
+        IRNode functionDefinitions = null;
+        IRNode functionDeclarations = null;
+        IRNode abstractFunctionsRedefinitions = null;
+        IRNode overridenFunctionsRedefinitions = null;
+        IRNodeBuilder builder = new IRNodeBuilder().setPrinterName(printerName)
+                .setOwnerKlass(thisKlass)
+                .setExceptionSafe(true);
+        try {
+            builder.setLevel(level + 1)
+                    .setOperatorLimit(operatorLimit)
+                    .setStatementLimit(statementsInFunctionLimit)
+                    .setMemberFunctionsArgLimit(memberFunctionsArgLimit);
+            variableDeclarations = builder.setComplexityLimit((long) (complexityLimit * 0.001 * PseudoRandom.random()))
+                    .getVariableDeclarationBlockFactory().produce();
+            if (!ProductionParams.disableFunctions.value()) {
+                // Try to implement all methods.
+                abstractFunctionsRedefinitions = builder.setComplexityLimit((long) (complexityLimit * 0.3 * PseudoRandom.random()))
+                        .setLevel(level + 1)
+                        .getFunctionRedefinitionBlockFactory(abstractSet)
+                        .produce();
+                overridenFunctionsRedefinitions = builder.setComplexityLimit((long) (complexityLimit * 0.3 * PseudoRandom.random()))
+                        .getFunctionRedefinitionBlockFactory(overrideSet)
+                        .produce();
+                if (PseudoRandom.randomBoolean(0.2)) { // wanna be abstract ?
+                    functionDeclarations = builder.setMemberFunctionsLimit((int) (memberFunctionsLimit * 0.2
+                                    * PseudoRandom.random()))
+                            .getFunctionDeclarationBlockFactory()
+                            .produce();
+                    if (((FunctionDeclarationBlock) functionDeclarations).size() > 0) {
+                        thisKlass.setAbstract();
+                    }
+                }
+                functionDefinitions = builder.setComplexityLimit((long) (complexityLimit * 0.5 * PseudoRandom.random()))
+                        .setMemberFunctionsLimit((int) (memberFunctionsLimit * 0.6
+                                * PseudoRandom.random()))
+                        .setFlags(FunctionInfo.NONE)
+                        .getFunctionDefinitionBlockFactory()
+                        .produce();
+                constructorDefinitions = builder.setComplexityLimit((long) (complexityLimit * 0.2 * PseudoRandom.random()))
+                        .setMemberFunctionsLimit((int) (memberFunctionsLimit * 0.2
+                                * PseudoRandom.random()))
+                        .setStatementLimit(statementsInFunctionLimit)
+                        .setOperatorLimit(operatorLimit)
+                        .setLevel(level + 1)
+                        .getConstructorDefinitionBlockFactory()
+                        .produce();
+            }
+        } catch (ProductionFailedException e) {
+            System.out.println("Exception during klass production process:");
+            e.printStackTrace(System.out);
+            throw e;
+        } finally {
+            SymbolTable.remove(new Symbol("this", thisKlass, thisKlass, VariableInfo.NONE));
+        }
+        // a non-abstract class can be final, so we should allow this to happen.
+        if (!ProductionParams.disableFinalClasses.value() && !thisKlass.isAbstract()
+                && PseudoRandom.randomBoolean()) {
+            thisKlass.setFinal();
+        }
+        TypeList.add(thisKlass);
+        IRNode printVariables = builder.setLevel(2).getPrintVariablesFactory().produce();
+        return new Klass(thisKlass, parent, interfaces, name, level,
+                variableDeclarations, constructorDefinitions, functionDefinitions,
+                abstractFunctionsRedefinitions, overridenFunctionsRedefinitions,
+                functionDeclarations, printVariables);
+    }
+
+   private void inheritClass() {
+        // Grab all Klasses from the TypeList and select one to be a parent
+        LinkedList<Type> probableParents = new LinkedList<>(TypeList.getAll());
+        for (Iterator<Type> i = probableParents.iterator(); i.hasNext();) {
+            Type klass = i.next();
+            if (!(klass instanceof TypeKlass) || ((TypeKlass) klass).isFinal()
+                    || ((TypeKlass) klass).isInterface()) {
+                // we can not derive from finals and interfaces
+                i.remove();
+            }
+        }
+        if (probableParents.isEmpty()) {
+            parent = (TypeKlass) TypeList.find("java.lang.Object");
+        } else {
+            parent = (TypeKlass) PseudoRandom.randomElement(probableParents);
+        }
+        thisKlass.addParent(parent.getName());
+        thisKlass.setParent(parent);
+        parent.addChild(name);
+        for (Symbol symbol : SymbolTable.getAllCombined(parent)) {
+            if ((symbol.flags & Symbol.PRIVATE) == 0) {
+                Symbol symbolCopy = symbol.deepCopy();
+                if (symbolCopy instanceof FunctionInfo) {
+                    FunctionInfo functionInfo = (FunctionInfo) symbolCopy;
+                    if (functionInfo.isConstructor()) {
+                        continue;
+                    }
+                    if ((functionInfo.flags & FunctionInfo.STATIC) == 0) {
+                        functionInfo.argTypes.get(0).type = thisKlass;
+                    }
+                }
+                symbolCopy.klass = thisKlass;
+                SymbolTable.add(symbolCopy);
+            }
+        }
+    }
+
+    private void inheritInterfaces() {
+        // Select interfaces that we'll implement.
+        LinkedList<Type> probableInterfaces = new LinkedList<>(TypeList.getAll());
+        for (Iterator<Type> i = probableInterfaces.iterator(); i.hasNext();) {
+            Type klass = i.next();
+            if (!(klass instanceof TypeKlass) || !((TypeKlass) klass).isInterface()) {
+                i.remove();
+            }
+        }
+        PseudoRandom.shuffle(probableInterfaces);
+        int implLimit = (int) (ProductionParams.implementationLimit.value() * PseudoRandom.random());
+        // Mulitiple inheritance compatibility check
+        compatibility_check:
+        for (Iterator<Type> i = probableInterfaces.iterator(); i.hasNext() && implLimit > 0; implLimit--) {
+            TypeKlass iface = (TypeKlass) i.next();
+            ArrayList<Symbol> ifaceFuncSet = SymbolTable.getAllCombined(iface, FunctionInfo.class);
+            for (Symbol symbol : SymbolTable.getAllCombined(thisKlass, FunctionInfo.class)) {
+                if (FunctionDefinition.isInvalidOverride((FunctionInfo) symbol, ifaceFuncSet)) {
+                    continue compatibility_check;
+                }
+            }
+            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.argTypes.get(0).type = thisKlass;
+                SymbolTable.add(functionInfo);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LimitedExpressionFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,47 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.ProductionLimiter;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class LimitedExpressionFactory extends ExpressionFactory {
+    LimitedExpressionFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) throws ProductionFailedException {
+        super(complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    public IRNode sproduce() throws ProductionFailedException {
+        ProductionLimiter.setLimit();
+        try {
+            return super.sproduce();
+        } finally {
+            ProductionLimiter.setUnlimited();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LiteralFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,80 @@
+/*
+ * 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.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 {
+    protected final Type resultType;
+
+    LiteralFactory(Type resultType) {
+        this.resultType = resultType;
+    }
+
+    @Override
+    public IRNode 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"))) {
+            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"));
+        } else {
+            throw new ProductionFailedException();
+        }
+        return literal;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LocalVariableFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,62 @@
+/*
+ * 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.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;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class LocalVariableFactory extends Factory {
+    private final Type type;
+    private final int flags;
+
+    LocalVariableFactory(Type type, int flags) {
+        this.type = type;
+        this.flags = flags;
+    }
+
+    @Override
+    public IRNode 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()) {
+            PseudoRandom.shuffle(allVariables);
+            for (Symbol symbol : allVariables) {
+                VariableInfo varInfo = (VariableInfo) symbol;
+                if ((varInfo.flags & VariableInfo.FINAL) == (flags & VariableInfo.FINAL)
+                        && (varInfo.flags & VariableInfo.INITIALIZED) == (flags & VariableInfo.INITIALIZED)
+                        && (varInfo.flags & VariableInfo.LOCAL) > 0) {
+                    return new LocalVariable(varInfo);
+                }
+            }
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LogicOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,61 @@
+/*
+ * 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.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.Rule;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class LogicOperatorFactory extends Factory {
+    private final Rule rule;
+
+    LogicOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass, Type resultType,
+            boolean exceptionSafe, boolean noconsts) throws ProductionFailedException {
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setOwnerKlass(ownerClass)
+                .setResultType(resultType)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts);
+        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());
+        rule.add("less", builder.setOperatorKind(OperatorKind.LT).getBinaryOperatorFactory());
+        rule.add("ge", builder.setOperatorKind(OperatorKind.GE).getBinaryOperatorFactory());
+        rule.add("le", builder.setOperatorKind(OperatorKind.LE).getBinaryOperatorFactory());
+        rule.add("eq", builder.setOperatorKind(OperatorKind.EQ).getBinaryOperatorFactory());
+        rule.add("neq", builder.setOperatorKind(OperatorKind.NE).getBinaryOperatorFactory());
+        rule.add("lnot", builder.setOperatorKind(OperatorKind.NOT).getUnaryOperatorFactory());
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        return rule.produce();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LogicalInversionOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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.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.UnaryOperator;
+import jdk.test.lib.jittester.types.TypeBoolean;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class LogicalInversionOperatorFactory extends UnaryOperatorFactory {
+    LogicalInversionOperatorFactory(long complexityLimit, int operatorLimit,
+            Type ownerType, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(OperatorKind.NOT, complexityLimit, operatorLimit, ownerType, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        return resultType.equals(new TypeBoolean());
+    }
+
+    @Override
+    protected IRNode generateProduction(Type resultType) throws ProductionFailedException {
+        return new UnaryOperator(opKind, new ExpressionFactory(complexityLimit - 1,
+                operatorLimit - 1, (TypeKlass) ownerClass, resultType, exceptionSafe, noconsts).produce());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/LoopingConditionFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,85 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.BinaryOperator;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Literal;
+import jdk.test.lib.jittester.LocalVariable;
+import jdk.test.lib.jittester.OperatorKind;
+import jdk.test.lib.jittester.ProductionFailedException;
+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 {
+    private final LocalVariable counter;
+    private final Literal limiter;
+    private final int operatorLimit;
+    private final long complexityLimit;
+    private final TypeKlass ownerClass;
+
+    LoopingConditionFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            LocalVariable counter, Literal limiter) {
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+        this.counter = counter;
+        this.limiter = limiter;
+        this.ownerClass = ownerClass;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        IRNode leftExpression = null;
+        IRNode rightExpression = null;
+        LimitedExpressionFactory exprFactory = new IRNodeBuilder()
+                .setResultType(new TypeBoolean())
+                .setComplexityLimit((complexityLimit - 1) / 2)
+                .setOperatorLimit((operatorLimit - 1) / 2)
+                .setOwnerKlass(ownerClass)
+                .setExceptionSafe(false)
+                .setNoConsts(false)
+                .getLimitedExpressionFactory();
+        if (PseudoRandom.randomBoolean()) {
+            leftExpression = exprFactory.produce();
+        }
+        if (PseudoRandom.randomBoolean()) {
+            rightExpression = exprFactory.produce();
+        }
+        // Depending on loop counter direction, we should synthesize limiting condition.
+        // Example: If the counter is counting forward. Then the looping condition can be:
+        // counter < n, counter <= n, n > counter, n >= counter, n - counter > 0, etc..
+
+        // 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,
+                rightExpression) : condition;
+        condition = (leftExpression != null) ? new BinaryOperator(OperatorKind.AND, leftExpression,
+                condition) : condition;
+        return new LoopingCondition(condition);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/MainKlassFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,164 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import jdk.test.lib.jittester.Block;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Symbol;
+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.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 {
+    private final String name;
+    private final long complexityLimit;
+    private final int statementsInTestFunctionLimit;
+    private final int statementsInFunctionLimit;
+    private final int operatorLimit;
+    private final int memberFunctionsLimit;
+    private final int memberFunctionsArgLimit;
+    private TypeKlass thisKlass;
+
+    MainKlassFactory(String name, long complexityLimit, int memberFunctionsLimit,
+            int memberFunctionsArgLimit, int statementsInFunctionLimit,
+            int statementsInTestFunctionLimit, int operatorLimit) {
+        this.name = name;
+        this.complexityLimit = complexityLimit;
+        this.memberFunctionsLimit = memberFunctionsLimit;
+        this.memberFunctionsArgLimit = memberFunctionsArgLimit;
+        this.statementsInFunctionLimit = statementsInFunctionLimit;
+        this.statementsInTestFunctionLimit = statementsInTestFunctionLimit;
+        this.operatorLimit = operatorLimit;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        TypeKlass parent = (TypeKlass) TypeList.find("java.lang.Object");
+        thisKlass = new TypeKlass(name);
+        thisKlass.addParent(parent.getName());
+        thisKlass.setParent(parent);
+        parent.addChild(name);
+        parent.addChild(thisKlass);
+        SymbolTable.add(new VariableInfo("this", thisKlass, thisKlass,
+                VariableInfo.FINAL | VariableInfo.LOCAL | VariableInfo.INITIALIZED));
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setOwnerKlass(thisKlass)
+                .setOperatorLimit(operatorLimit)
+                .setMemberFunctionsLimit(memberFunctionsLimit)
+                .setMemberFunctionsArgLimit(memberFunctionsArgLimit)
+                .setStatementLimit(statementsInFunctionLimit)
+                .setLevel(1)
+                .setExceptionSafe(true)
+                .setPrinterName("Printer");
+        IRNode variableDeclarations = builder
+                .setComplexityLimit((long) (complexityLimit * 0.05))
+                .getVariableDeclarationBlockFactory().produce();
+        IRNode functionDefinitions = null;
+        if (!ProductionParams.disableFunctions.value()) {
+            functionDefinitions = builder
+                    .setComplexityLimit((long) (complexityLimit * 0.01 * PseudoRandom.random()))
+                    .setFlags(FunctionInfo.NONRECURSIVE)
+                    .getFunctionDefinitionBlockFactory()
+                    .produce();
+        }
+        IRNode testFunction = builder.setResultType(new TypeVoid())
+                .setComplexityLimit(complexityLimit)
+                .setStatementLimit(statementsInTestFunctionLimit)
+                .getBlockFactory()
+                .produce();
+        SymbolTable.remove(new Symbol("this", thisKlass, thisKlass, VariableInfo.NONE));
+        IRNode printVariables = builder.setLevel(2)
+                .getPrintVariablesFactory()
+                .produce();
+        List<IRNode> childs = new ArrayList<>();
+        childs.add(variableDeclarations);
+        childs.add(functionDefinitions);
+        childs.add(testFunction);
+        childs.add(printVariables);
+        ensureMinDepth(childs, builder);
+        ensureMaxDepth(childs);
+        return new MainKlass(name, thisKlass, variableDeclarations,
+                functionDefinitions, testFunction, printVariables);
+    }
+
+    private void ensureMaxDepth(List<IRNode> childs) {
+        int maxDepth = ProductionParams.maxCfgDepth.value();
+        List<IRNode> filtered = childs.stream()
+            .filter(c -> c.isCFDeviation() && c.countDepth() > maxDepth)
+            .collect(Collectors.toList());
+        for (IRNode child : filtered) {
+            List<IRNode> leaves = null;
+            do {
+                long depth = Math.max(child.countDepth(), maxDepth + 1);
+                leaves = child.getDeviantBlocks(depth);
+                leaves.get(0).removeSelf();
+            } while (!leaves.isEmpty() && child.countDepth() > maxDepth);
+        }
+    }
+
+    private void ensureMinDepth(List<IRNode> childs, IRNodeBuilder builder)
+            throws ProductionFailedException {
+        int minDepth = ProductionParams.minCfgDepth.value();
+        List<IRNode> filtered = new ArrayList<>(childs);
+        addMoreChildren(filtered, minDepth, builder);
+    }
+
+    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);
+            List<IRNode> leaves = randomChild.getStackableLeaves();
+            if (!leaves.isEmpty()) {
+                PseudoRandom.shuffle(leaves);
+                Block randomLeaf = (Block) leaves.get(0);
+                TypeKlass klass = (TypeKlass) randomChild.getKlass();
+                int newLevel = randomLeaf.getLevel() + 1;
+                Type retType = randomLeaf.getReturnType();
+                IRNode newBlock = builder.setOwnerKlass(klass)
+                        .setResultType(retType)
+                        .setComplexityLimit(complexityLimit)
+                        .setStatementLimit(statementsInFunctionLimit)
+                        .setLevel(newLevel)
+                        .getBlockFactory()
+                        .produce();
+                List<IRNode> siblings = randomLeaf.getChildren();
+                // to avoid break;
+                int index = PseudoRandom.randomNotZero(siblings.size() - 1);
+                siblings.add(index, newBlock);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/NonStaticMemberVariableFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,83 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.NonStaticMemberVariable;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class NonStaticMemberVariableFactory extends Factory {
+    private final Type type;
+    private final int flags;
+    private final long complexityLimit;
+    private final int operatorLimit;
+    private final boolean exceptionSafe;
+    private final Type ownerClass;
+
+    NonStaticMemberVariableFactory(long complexityLimit, int operatorLimit,
+            TypeKlass ownerClass, Type type, int flags, boolean exceptionSafe) {
+        this.ownerClass = ownerClass;
+        this.type = type;
+        this.flags = flags;
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+        this.exceptionSafe = exceptionSafe;
+    }
+
+    @Override
+    public IRNode 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()) {
+            PseudoRandom.shuffle(variables);
+            IRNodeBuilder builder = new IRNodeBuilder().setComplexityLimit(complexityLimit)
+                    .setOperatorLimit(operatorLimit)
+                    .setOwnerKlass((TypeKlass) ownerClass)
+                    .setExceptionSafe(exceptionSafe)
+                    .setNoConsts(false);
+            for (Symbol symbol : variables) {
+                VariableInfo varInfo = (VariableInfo) symbol;
+                if ((varInfo.flags & VariableInfo.FINAL) == (flags & VariableInfo.FINAL)
+                        && (varInfo.flags & VariableInfo.INITIALIZED) == (flags & VariableInfo.INITIALIZED)
+                        && (varInfo.flags & VariableInfo.STATIC) == 0
+                        && (varInfo.flags & VariableInfo.LOCAL) == 0) {
+                    try {
+                        IRNode object = builder.setResultType(varInfo.klass)
+                                .getExpressionFactory().produce();
+                        return new NonStaticMemberVariable(object, varInfo);
+                    } catch (ProductionFailedException e) {
+                    }
+                }
+            }
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/NothingFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,34 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.Nothing;
+import jdk.test.lib.jittester.ProductionFailedException;
+
+public class NothingFactory extends Factory {
+    @Override
+    public Nothing produce() throws ProductionFailedException {
+        return new Nothing();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/OperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,41 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+public abstract class OperatorFactory extends Factory {
+    protected long complexityLimit;
+    protected boolean exceptionSafe;
+    protected boolean noconsts;
+    protected int operatorLimit;
+    protected int operatorPriority;
+
+    protected OperatorFactory(int operatorPriority, long complexityLimit, int operatorLimit,
+            boolean exceptionSafe, boolean noconsts) {
+        this.operatorLimit = operatorLimit;
+        this.complexityLimit = complexityLimit;
+        this.operatorPriority = operatorPriority;
+        this.exceptionSafe = exceptionSafe;
+        this.noconsts = noconsts;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/PrintVariablesFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,49 @@
+/*
+ * 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.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;
+    private final TypeKlass ownerClass;
+    private final int level;
+
+    PrintVariablesFactory(String printerName, TypeKlass ownerClass, int level) {
+        this.printerName = printerName;
+        this.ownerClass = ownerClass;
+        this.level = level;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        return new PrintVariables(printerName, SymbolTable.getAllCombined(ownerClass,
+                VariableInfo.class), level);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ReturnFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,59 @@
+/*
+ * 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.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 {
+    private final long complexityLimit;
+    private final int operatorLimit;
+    private final Type resultType;
+    private final boolean exceptionSafe;
+    private final TypeKlass ownerClass;
+
+    ReturnFactory(long compLimit, int opLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe) {
+        this.complexityLimit = compLimit;
+        this.operatorLimit = opLimit;
+        this.resultType = resultType;
+        this.ownerClass = ownerClass;
+        this.exceptionSafe = exceptionSafe;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        return new Return(new IRNodeBuilder().setComplexityLimit(complexityLimit - 1)
+                .setOperatorLimit(operatorLimit - 1)
+                .setOwnerKlass(ownerClass)
+                .setResultType(resultType)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(false)
+                .getLimitedExpressionFactory()
+                .produce());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/SafeFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.SymbolTable;
+
+public abstract class SafeFactory extends Factory {
+    protected abstract IRNode sproduce() throws ProductionFailedException;
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        try {
+            SymbolTable.push();
+            IRNode p = sproduce();
+            SymbolTable.merge();
+            return p;
+        } catch (ProductionFailedException e) {
+            SymbolTable.pop();
+            throw e;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StatementFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,65 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.ProductionLimiter;
+import jdk.test.lib.jittester.Rule;
+import jdk.test.lib.jittester.Statement;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class StatementFactory extends Factory {
+    private final Rule 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");
+        IRNodeBuilder builder = new IRNodeBuilder()
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setOwnerKlass(ownerClass)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts)
+                .setResultType(PseudoRandom.randomElement(TypeList.getAll()));
+        rule.add("array_creation", builder.getArrayCreationFactory());
+        rule.add("assignment", builder.getAssignmentOperatorFactory());
+        rule.add("function", builder.getFunctionFactory(), 0.1);
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        ProductionLimiter.setLimit();
+        try {
+            return new Statement(rule.produce(), needSemicolon);
+        } finally {
+            ProductionLimiter.setUnlimited();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticConstructorDefinitionFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.SymbolTable;
+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 {
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final int level;
+    private final TypeKlass ownerClass;
+
+    StaticConstructorDefinitionFactory(TypeKlass ownerClass, long complexityLimit,
+            int statementLimit, int operatorLimit, int level) {
+        this.ownerClass = ownerClass;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        SymbolTable.push();
+        IRNode body;
+        try {
+            SymbolTable.remove(SymbolTable.get("this", VariableInfo.class));
+            long complLimit = (long) (PseudoRandom.random() * complexityLimit);
+            body = new IRNodeBuilder()
+                    .setOwnerKlass(ownerClass)
+                    .setResultType(new TypeVoid())
+                    .setComplexityLimit(complLimit)
+                    .setStatementLimit(statementLimit)
+                    .setOperatorLimit(operatorLimit)
+                    .setLevel(level)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(true)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(false)
+                    .getBlockFactory()
+                    .produce();
+        } finally {
+            SymbolTable.pop();
+        }
+        return new StaticConstructorDefinition(body);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/StaticMemberVariableFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,65 @@
+/*
+ * 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.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;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class StaticMemberVariableFactory extends Factory {
+    private final Type type;
+    private final int flags;
+    private final Type ownerClass;
+
+    StaticMemberVariableFactory(TypeKlass ownerClass, Type type, int flags) {
+        this.ownerClass = ownerClass;
+        this.type = type;
+        this.flags = flags;
+    }
+
+    @Override
+    public IRNode 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()) {
+            PseudoRandom.shuffle(variables);
+            for (Symbol symbol : variables) {
+                VariableInfo varInfo = (VariableInfo) symbol;
+                if ((varInfo.flags & VariableInfo.FINAL) == (flags & VariableInfo.FINAL)
+                        && (varInfo.flags & VariableInfo.INITIALIZED) == (flags & VariableInfo.INITIALIZED)
+                        && (varInfo.flags & VariableInfo.STATIC) > 0) {
+                    return new StaticMemberVariable((TypeKlass) ownerClass, varInfo);
+                }
+            }
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/SwitchFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,188 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+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;
+import jdk.test.lib.jittester.Nothing;
+import jdk.test.lib.jittester.ProductionFailedException;
+import jdk.test.lib.jittester.Rule;
+import jdk.test.lib.jittester.Switch;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.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;
+    private final TypeKlass ownerClass;
+    private final int level;
+
+    SwitchFactory(TypeKlass ownerClass, long complexityLimit, int statementLimit,
+            int operatorLimit, int level, boolean canHaveReturn) {
+        this.ownerClass = ownerClass;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        this.canHaveReturn = canHaveReturn;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        if (statementLimit > 0 && complexityLimit > 0) {
+            ArrayList<Type> switchTypes = new ArrayList<>();
+            switchTypes.add(new TypeChar());
+            switchTypes.add(new TypeByte());
+            switchTypes.add(new TypeShort());
+            switchTypes.add(new TypeInt());
+            PseudoRandom.shuffle(switchTypes);
+            IRNodeBuilder builder = new IRNodeBuilder()
+                    .setOwnerKlass(ownerClass)
+                    .setOperatorLimit(operatorLimit)
+                    .setSubBlock(false)
+                    .setCanHaveBreaks(true)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(canHaveReturn);
+            MAIN_LOOP:
+            for (Type type : switchTypes) {
+                ArrayList<IRNode> caseConsts = new ArrayList<>();
+                ArrayList<IRNode> caseBlocks = new ArrayList<>();
+                try {
+                    int accumulatedStatements = 0;
+                    int currentStatementsLimit = 0;
+                    long accumulatedComplexity = 0L;
+                    long currentComplexityLimit = 0L;
+                    currentComplexityLimit = (long) (PseudoRandom.random()
+                            * (complexityLimit - accumulatedComplexity));
+                    IRNode switchExp = builder.setComplexityLimit(currentComplexityLimit)
+                            .setResultType(type)
+                            .setExceptionSafe(false)
+                            .setNoConsts(true)
+                            .getLimitedExpressionFactory()
+                            .produce();
+                    accumulatedComplexity += currentComplexityLimit;
+                    ArrayList<Type> caseTypes = new ArrayList<>();
+                    caseTypes.add(new TypeByte());
+                    caseTypes.add(new TypeChar());
+                    caseTypes = new ArrayList<>(TypeUtil.getLessCapatiousOrEqualThan(caseTypes,
+                            (BuiltInType) type));
+                    if (PseudoRandom.randomBoolean()) { // "default"
+                        currentStatementsLimit = (int) (PseudoRandom.random()
+                                * (statementLimit - accumulatedStatements));
+                        currentComplexityLimit = (long) (PseudoRandom.random()
+                                * (complexityLimit - accumulatedComplexity));
+                        caseConsts.add(null);
+                        caseBlocks.add(builder.setComplexityLimit(currentComplexityLimit)
+                                .setStatementLimit(currentStatementsLimit)
+                                .setLevel(level + 1)
+                                .setCanHaveReturn(false)
+                                .setCanHaveBreaks(false)
+                                .getBlockFactory()
+                                .produce());
+                        builder.setCanHaveBreaks(true)
+                                .setCanHaveReturn(canHaveReturn);
+                        accumulatedStatements += currentStatementsLimit;
+                        accumulatedComplexity += currentComplexityLimit;
+                    }
+                    HashSet<Integer> cases = new HashSet<>();
+                    while (accumulatedStatements < statementLimit) { // "case"s
+                        currentStatementsLimit = (int) (PseudoRandom.random()
+                                * (statementLimit - accumulatedStatements));
+                        currentComplexityLimit = (long) (PseudoRandom.random()
+                                * (complexityLimit - accumulatedComplexity));
+                        PseudoRandom.shuffle(caseTypes);
+                        for (int tryCount = 0; true; tryCount++) {
+                            if (tryCount >= 10) {
+                                continue MAIN_LOOP;
+                            }
+                            Literal literal = (Literal) builder.setResultType(caseTypes.get(0))
+                                    .getLiteralFactory().produce();
+                            int value = 0;
+                            if (literal.value instanceof Integer) {
+                                value = (Integer) literal.value;
+                            }
+                            if (literal.value instanceof Short) {
+                                value = (Short) literal.value;
+                            }
+                            if (literal.value instanceof Byte) {
+                                value = (Byte) literal.value;
+                            }
+                            if (literal.value instanceof Character) {
+                                value = (Character) literal.value;
+                            }
+                            if (!cases.contains(value)) {
+                                cases.add(value);
+                                caseConsts.add(literal);
+                                break;
+                            }
+                        }
+                        Rule rule = new Rule("case_block");
+                        rule.add("block", builder.setComplexityLimit(currentComplexityLimit)
+                                .setStatementLimit(currentStatementsLimit)
+                                .setLevel(level)
+                                .setCanHaveReturn(false)
+                                .setCanHaveBreaks(false)
+                                .getBlockFactory());
+                        builder.setCanHaveBreaks(true)
+                                .setCanHaveReturn(canHaveReturn);
+                        rule.add("nothing", builder.getNothingFactory());
+                        IRNode choiceResult = rule.produce();
+                        caseBlocks.add(choiceResult);
+                        if (choiceResult instanceof Nothing) {
+                            accumulatedStatements++;
+                        } else {
+                            accumulatedStatements += currentStatementsLimit;
+                            accumulatedComplexity += currentComplexityLimit;
+                        }
+                    }
+                    PseudoRandom.shuffle(caseConsts);
+                    List<IRNode> accum = new ArrayList<>();
+                    caseBlockIdx = 1 + caseConsts.size();
+                    accum.add(switchExp);
+                    for (int i = 1; i < caseBlockIdx; ++i) {
+                        accum.add(caseConsts.get(i - 1));
+                    }
+                    for (int i = caseBlockIdx; i < 1 + caseConsts.size() + caseBlocks.size(); ++i) {
+                        accum.add(caseBlocks.get(i - caseBlockIdx));
+                    }
+                    return new Switch(level, accum, caseBlockIdx);
+                } catch (ProductionFailedException e) {
+                }
+            }
+        }
+        throw new ProductionFailedException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/TernaryOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,122 @@
+/*
+ * 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.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.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;
+
+    TernaryOperatorFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(2, complexityLimit, operatorLimit, exceptionSafe, noconsts);
+        this.resultType = resultType;
+        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 {
+        int leftOpLimit = (int) (PseudoRandom.random() * 0.3 * (operatorLimit - 1));
+        int rightOpLimit = (int) (PseudoRandom.random() * 0.3 * (operatorLimit - 1));
+        int condOpLimit = operatorLimit - 1 - leftOpLimit - rightOpLimit;
+        long leftComplLimit = (long) (PseudoRandom.random() * 0.3 * (complexityLimit - 1));
+        long rightComplLimit = (long) (PseudoRandom.random() * 0.3 * (complexityLimit - 1));
+        long condComplLimit = complexityLimit - 1 - leftComplLimit - rightComplLimit;
+        if (leftComplLimit == 0 || rightComplLimit == 0 || condComplLimit == 0
+                || leftOpLimit == 0 || rightOpLimit == 0 || condOpLimit == 0) {
+            throw new ProductionFailedException();
+        }
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(ownerClass)
+                .setExceptionSafe(exceptionSafe);
+        IRNode conditionalExp = builder.setComplexityLimit(condComplLimit)
+                .setOperatorLimit(condOpLimit)
+                .setResultType(conditionType)
+                .setNoConsts(noconsts)
+                .getExpressionFactory()
+                .produce();
+        // Ignore initializations performed in left and right branches:
+        IRNode leftExp;
+        SymbolTable.push();
+        try {
+            leftExp = builder.setComplexityLimit(leftComplLimit)
+                    .setOperatorLimit(leftOpLimit)
+                    .setResultType(leftType)
+                    .setNoConsts(false)
+                    .getExpressionFactory()
+                    .produce();
+        } finally {
+            SymbolTable.pop();
+        }
+        IRNode rightExp;
+        SymbolTable.push();
+        try {
+            rightExp = builder.setComplexityLimit(rightComplLimit)
+                    .setOperatorLimit(rightOpLimit)
+                    .setResultType(rightType)
+                    .setNoConsts(false)
+                    .getExpressionFactory()
+                    .produce();
+        } finally {
+            SymbolTable.pop();
+        }
+        return new TernaryOperator(conditionalExp, leftExp, rightExp);
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        Pair<Type, Type> types;
+        try {
+            types = generateTypes();
+        } catch (RuntimeException ex) {
+            throw new ProductionFailedException(ex.getMessage());
+        }
+        try {
+            SymbolTable.push();
+            IRNode result = generateProduction(new TypeBoolean(), types.first, types.second);
+            SymbolTable.merge();
+            return result;
+        } catch (ProductionFailedException e) {
+            SymbolTable.pop();
+            throw e;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/ThrowFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,57 @@
+/*
+ * 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.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.Throw;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class ThrowFactory extends SafeFactory {
+    private final Rule rule;
+
+    ThrowFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass,
+            Type resultType, boolean exceptionSafe) {
+        IRNodeBuilder b = new IRNodeBuilder()
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setOwnerKlass(ownerClass)
+                .setResultType(resultType)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(false);
+        rule = new Rule("throw");
+        rule.add("constant", b.setIsConstant(true).setIsInitialized(true).getVariableFactory());
+        rule.add("variable", b.setIsConstant(false).setIsInitialized(true).getVariableFactory());
+
+        rule.add("assignment", b.getAssignmentOperatorFactory());
+        rule.add("function", b.getFunctionFactory(), 2);
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        return new Throw(rule.produce());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/TryCatchBlockFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,129 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+import java.util.ArrayList;
+import java.util.List;
+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;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.TypeUtil;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class TryCatchBlockFactory extends Factory {
+    private final static double CATCH_SELECTION_COEF = 0.1d;
+    private final Type returnType;
+    private final long complexityLimit;
+    private final int statementLimit, operatorLimit;
+    private final boolean subBlock;
+    private final boolean canHaveBreaks;
+    private final boolean canHaveContinues;
+    private final boolean canHaveReturn;
+    private final int level;
+    private final TypeKlass ownerClass;
+
+    TryCatchBlockFactory(TypeKlass ownerClass, Type returnType,
+            long complexityLimit, int statementLimit, int operatorLimit,
+            int level, boolean subBlock, boolean canHaveBreaks,
+            boolean canHaveContinues, boolean canHaveReturn) {
+        this.ownerClass = ownerClass;
+        this.returnType = returnType;
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        this.subBlock = subBlock;
+        this.canHaveBreaks = canHaveBreaks;
+        this.canHaveContinues = canHaveContinues;
+        this.canHaveReturn = canHaveReturn;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        if (complexityLimit < 1 || statementLimit < 1) {
+            throw new ProductionFailedException();
+        }
+        List<Type> uncheckedThrowables = getUncheckedThrowables();
+        IRNodeBuilder builder = new IRNodeBuilder().setOwnerKlass(ownerClass)
+                .setResultType(returnType)
+                .setOperatorLimit(operatorLimit)
+                .setLevel(level)
+                .setSubBlock(subBlock)
+                .setCanHaveReturn(canHaveReturn)
+                .setCanHaveContinues(canHaveContinues)
+                .setCanHaveBreaks(canHaveBreaks);
+        IRNode body = getBlock(builder, 0.6);
+        int catchBlocksCount = (int) (CATCH_SELECTION_COEF
+                * PseudoRandom.random() * uncheckedThrowables.size());
+        List<CatchBlock> catchBlocks = new ArrayList<>();
+        List<Type> caught = new ArrayList<>();
+        for (int i = 0; i < catchBlocksCount; i++) {
+            List<Type> whatToCatch = new ArrayList<>();
+            int throwableLimit = 1 + (int) ((1/(2*CATCH_SELECTION_COEF))
+                    * PseudoRandom.random());
+            for (int j = 0; j < throwableLimit; j++) {
+                whatToCatch.add(selectUniqueThrowable(uncheckedThrowables, caught));
+            }
+            catchBlocks.add(new CatchBlock(getBlock(builder, 0.3/catchBlocksCount),
+                    whatToCatch, level));
+        }
+        IRNode finallyBody = PseudoRandom.randomBoolean() || catchBlocksCount == 0 ? getBlock(builder, 0.1) : null;
+        return new TryCatchBlock(body, finallyBody, catchBlocks, level);
+    }
+
+    private Type selectUniqueThrowable(List<Type> variants, List<Type> caught) {
+        Type selected;
+        do {
+            int randomIndex = PseudoRandom.randomNotZero(variants.size()) - 1;
+            selected = variants.get(randomIndex);
+        } while (caught.contains(selected));
+        caught.add(selected);
+        return selected;
+    }
+
+    private IRNode getBlock(IRNodeBuilder builder, double weight)
+            throws ProductionFailedException {
+        long actualComplexityLim = (long) (weight * PseudoRandom.random()
+                * complexityLimit);
+        int actualStatementLim = (int) (weight * PseudoRandom.random()
+                * statementLimit);
+        return builder.setStatementLimit(actualStatementLim)
+                .setComplexityLimit(actualComplexityLim)
+                .getBlockFactory()
+                .produce();
+    }
+
+    private List<Type> getUncheckedThrowables() {
+        List<Type> result = new ArrayList<>();
+        result.addAll(TypeUtil.getImplicitlyCastable(TypeList.getAll(),
+                new TypeKlass("java.lang.Error")));
+        result.addAll(TypeUtil.getImplicitlyCastable(TypeList.getAll(),
+                new TypeKlass("java.lang.RuntimeException")));
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/UnaryOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,76 @@
+/*
+ * 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.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;
+
+public abstract class UnaryOperatorFactory extends OperatorFactory {
+    protected final OperatorKind opKind;
+    protected final Type resultType;
+    protected final Type ownerClass;
+
+    protected UnaryOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
+            Type ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind.priority, complexityLimit, operatorLimit, exceptionSafe, noconsts);
+        this.opKind = opKind;
+        this.resultType = resultType;
+        this.ownerClass = ownerClass;
+    }
+
+    protected Type generateType() throws ProductionFailedException {
+        return resultType;
+    }
+
+    protected abstract IRNode generateProduction(Type type) throws ProductionFailedException;
+
+    protected abstract boolean isApplicable(Type resultType);
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        if (!isApplicable(resultType)) {
+            //avoid implicit use of resultType.toString()
+            throw new ProductionFailedException("Type " + resultType.getName()
+                    + " is not applicable by " + getClass().getName());
+        }
+        Type type;
+        try {
+            type = generateType();
+        } catch (Exception ex) {
+            throw new ProductionFailedException(ex.getMessage());
+        }
+        try {
+            SymbolTable.push();
+            IRNode result = generateProduction(type);
+            SymbolTable.merge();
+            return result;
+        } catch (ProductionFailedException e) {
+            SymbolTable.pop();
+            throw e;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/UnaryPlusMinusOperatorFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,75 @@
+/*
+ * 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.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.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;
+
+class UnaryPlusMinusOperatorFactory extends UnaryOperatorFactory {
+    UnaryPlusMinusOperatorFactory(OperatorKind opKind, long complexityLimit, int operatorLimit,
+            Type ownerClass, Type resultType, boolean exceptionSafe, boolean noconsts) {
+        super(opKind, complexityLimit, operatorLimit, ownerClass, resultType, exceptionSafe, noconsts);
+    }
+
+    @Override
+    protected boolean isApplicable(Type resultType) {
+        if (!TypeList.isBuiltIn(resultType) || resultType.equals(new TypeBoolean())) {
+            return false;
+        }
+        BuiltInType resType = (BuiltInType) resultType;
+        return resType.equals(new TypeInt()) || resType.isMoreCapaciousThan(new TypeInt());
+    }
+
+    @Override
+    protected Type generateType() throws ProductionFailedException {
+        if (resultType.equals(new TypeInt())) {
+            return PseudoRandom.randomElement(TypeUtil.getImplicitlyCastable(TypeList.getBuiltIn(), resultType));
+        } else {
+            return resultType;
+        }
+    }
+
+    @Override
+    protected IRNode generateProduction(Type type) throws ProductionFailedException {
+        return new UnaryOperator(opKind, new IRNodeBuilder()
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setOwnerKlass((TypeKlass) ownerClass)
+                .setResultType(type)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(noconsts)
+                .getExpressionFactory()
+                .produce());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableDeclarationBlockFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,69 @@
+/*
+ * 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.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.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 {
+    private final long complexityLimit;
+    private final int operatorLimit;
+    private final boolean exceptionSafe;
+    private final int level;
+    private final TypeKlass ownerClass;
+
+    VariableDeclarationBlockFactory(TypeKlass ownerClass, long complexityLimit,
+            int operatorLimit, int level, boolean exceptionSafe) {
+        this.ownerClass = ownerClass;
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        this.exceptionSafe = exceptionSafe;
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        ArrayList<IRNode> content = new ArrayList<>();
+        int limit = (int) Math.ceil(PseudoRandom.random() * ProductionParams.dataMemberLimit.value());
+        DeclarationFactory declFactory = new IRNodeBuilder()
+                .setOwnerKlass(ownerClass)
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setIsLocal(false)
+                .setExceptionSafe(exceptionSafe)
+                .getDeclarationFactory();
+        for (int i = 0; i < limit; i++) {
+            try {
+                content.add(declFactory.produce());
+            } catch (ProductionFailedException e) {
+            }
+        }
+        return new VariableDeclarationBlock(content, level);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableDeclarationFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,72 @@
+/*
+ * 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.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;
+import jdk.test.lib.jittester.TypeList;
+import jdk.test.lib.jittester.VariableDeclaration;
+import jdk.test.lib.jittester.VariableInfo;
+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;
+    private Type resultType;
+
+    VariableDeclarationFactory(TypeKlass ownerClass, boolean isStatic, boolean isLocal, Type resultType) {
+        this.ownerClass = ownerClass;
+        this.isStatic = isStatic;
+        this.isLocal = isLocal;
+        this.resultType = resultType;
+    }
+
+    @Override
+    public  IRNode produce() throws ProductionFailedException {
+        if (resultType == TypeList.getVoid()) {
+            LinkedList<Type> types = new LinkedList<>(TypeList.getAll());
+            PseudoRandom.shuffle(types);
+            if (types.isEmpty()) {
+                throw new ProductionFailedException();
+            }
+            resultType = types.getFirst();
+        }
+        String resultName = "var_" + SymbolTable.getNextVariableNumber();
+        int flags = VariableInfo.NONE;
+        if (isStatic) {
+            flags |= VariableInfo.STATIC;
+        }
+        if (isLocal) {
+            flags |= VariableInfo.LOCAL;
+        }
+        VariableInfo varInfo = new VariableInfo(resultName, ownerClass, resultType, flags);
+        SymbolTable.add(varInfo);
+        return new VariableDeclaration(varInfo);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,61 @@
+/*
+ * 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.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.VariableInfo;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+class VariableFactory extends Factory {
+    private final Rule rule;
+
+    VariableFactory(long complexityLimit, int operatorLimit, TypeKlass ownerClass, Type resultType,
+            boolean constant, boolean initialized, boolean exceptionSafe, boolean noconsts) {
+        int flags = VariableInfo.NONE;
+        if (constant) {
+            flags |= VariableInfo.FINAL;
+        }
+        if (initialized) {
+            flags |= VariableInfo.INITIALIZED;
+        }
+        rule = new Rule("variable");
+        IRNodeBuilder b = new IRNodeBuilder().setResultType(resultType)
+                .setFlags(flags)
+                .setComplexityLimit(complexityLimit)
+                .setOperatorLimit(operatorLimit)
+                .setOwnerKlass(ownerClass)
+                .setExceptionSafe(exceptionSafe);
+        rule.add("non_static_member_variable", b.getNonStaticMemberVariableFactory());
+        rule.add("static_member_variable", b.getStaticMemberVariableFactory());
+        rule.add("local_variable", b.getLocalVariableFactory());
+    }
+
+    @Override
+    public IRNode produce() throws ProductionFailedException {
+        return rule.produce();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/VariableInitializationFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,107 @@
+/*
+ * 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.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.ProductionParams;
+import jdk.test.lib.jittester.Rule;
+import jdk.test.lib.jittester.Symbol;
+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.VariableInitialization;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+class VariableInitializationFactory extends SafeFactory {
+    private final int operatorLimit;
+    private final long complexityLimit;
+    private final boolean constant;
+    private final boolean isStatic;
+    private final boolean isLocal;
+    private final boolean exceptionSafe;
+    private final TypeKlass ownerClass;
+
+    VariableInitializationFactory(TypeKlass ownerClass, boolean constant, boolean isStatic,
+            boolean isLocal, long complexityLimit, int operatorLimit, boolean exceptionSafe) {
+        this.ownerClass = ownerClass;
+        this.constant = constant;
+        this.isStatic = isStatic;
+        this.isLocal = isLocal;
+        this.complexityLimit = complexityLimit;
+        this.operatorLimit = operatorLimit;
+        this.exceptionSafe = exceptionSafe;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        LinkedList<Type> types = new LinkedList<>(TypeList.getAll());
+        PseudoRandom.shuffle(types);
+        if (types.isEmpty()) {
+            throw new ProductionFailedException();
+        }
+        Type resultType = types.getFirst();
+        IRNodeBuilder b = new IRNodeBuilder().setComplexityLimit(complexityLimit - 1)
+                .setOperatorLimit(operatorLimit - 1)
+                .setOwnerKlass(ownerClass)
+                .setResultType(resultType)
+                .setExceptionSafe(exceptionSafe)
+                .setNoConsts(false);
+        Rule rule = new Rule("initializer");
+        rule.add("literal_initializer", b.getLiteralFactory());
+        if (!ProductionParams.disableExprInInit.value()) {
+            rule.add("expression", b.getLimitedExpressionFactory());
+        }
+        Symbol thisSymbol = null;
+        if (isStatic) {
+            thisSymbol = SymbolTable.get("this", VariableInfo.class);
+            SymbolTable.remove(thisSymbol);
+        }
+        IRNode init;
+        try {
+            init = rule.produce();
+        } finally {
+            if (isStatic) {
+                SymbolTable.add(thisSymbol);
+            }
+        }
+        String resultName = "var_" + SymbolTable.getNextVariableNumber();
+        int flags = VariableInfo.INITIALIZED;
+        if (constant) {
+            flags |= VariableInfo.FINAL;
+        }
+        if (isStatic) {
+            flags |= VariableInfo.STATIC;
+        }
+        if (isLocal) {
+            flags |= VariableInfo.LOCAL;
+        }
+        VariableInfo varInfo = new VariableInfo(resultName, ownerClass, resultType, flags);
+        SymbolTable.add(varInfo);
+        return new VariableInitialization(varInfo, init);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/factories/WhileFactory.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,161 @@
+/*
+ * 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.test.lib.jittester.factories;
+
+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.SymbolTable;
+import jdk.test.lib.jittester.Type;
+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 {
+    private final Loop loop;
+    private final long complexityLimit;
+    private final int statementLimit;
+    private final int operatorLimit;
+    private final TypeKlass ownerClass;
+    private final int level;
+    private final Type returnType;
+    private long thisLoopIterLimit = 0;
+    private final boolean canHaveReturn;
+
+    WhileFactory(TypeKlass ownerClass, Type returnType, long complexityLimit, int statementLimit,
+            int operatorLimit, int level, boolean canHaveReturn) {
+        this.ownerClass = ownerClass;
+        this.returnType = returnType;
+        loop = new Loop();
+        this.complexityLimit = complexityLimit;
+        this.statementLimit = statementLimit;
+        this.operatorLimit = operatorLimit;
+        this.level = level;
+        this.canHaveReturn = canHaveReturn;
+    }
+
+    @Override
+    protected IRNode sproduce() throws ProductionFailedException {
+        if (statementLimit <= 0 || complexityLimit <= 0) {
+            throw new ProductionFailedException();
+        }
+        long complexity = complexityLimit;
+        // Loop header parameters
+        long headerComplLimit = (long) (0.005 * complexity * PseudoRandom.random());
+        complexity -= headerComplLimit;
+        int headerStatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 3.0));
+        // Loop body parameters
+        thisLoopIterLimit = (long) (0.0001 * complexity * PseudoRandom.random());
+        if (thisLoopIterLimit > Integer.MAX_VALUE || thisLoopIterLimit == 0) {
+            throw new ProductionFailedException();
+        }
+        complexity = thisLoopIterLimit > 0 ? complexity / thisLoopIterLimit : 0;
+        long condComplLimit = (long) (complexity * PseudoRandom.random());
+        complexity -= condComplLimit;
+        long body1ComplLimit = (long) (complexity * PseudoRandom.random());
+        complexity -= body1ComplLimit;
+        int body1StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 4.0));
+        long body2ComplLimit = (long) (complexity * PseudoRandom.random());
+        complexity -= body2ComplLimit;
+        int body2StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 4.0));
+        long body3ComplLimit = complexity;
+        int body3StatementLimit = PseudoRandom.randomNotZero((int) (statementLimit / 4.0));
+        // Production
+        IRNodeBuilder builder =  new IRNodeBuilder().setOwnerKlass(ownerClass)
+                .setResultType(returnType)
+                .setOperatorLimit(operatorLimit);
+        loop.initialization = builder.getCounterInitializerFactory(0).produce();
+        IRNode header;
+        try {
+            header = builder.setComplexityLimit(headerComplLimit)
+                    .setStatementLimit(headerStatementLimit)
+                    .setLevel(level - 1)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(false)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(false)
+                    .getBlockFactory()
+                    .produce();
+        } catch (ProductionFailedException e) {
+            header = new Nothing();
+        }
+        LocalVariable counter = new LocalVariable(((Initialization) loop.initialization).get());
+        Literal limiter = new Literal(Integer.valueOf((int) thisLoopIterLimit), new TypeInt());
+        loop.condition = builder.setComplexityLimit(condComplLimit)
+                .setLocalVariable(counter)
+                .getLoopingConditionFactory(limiter)
+                .produce();
+        IRNode body1;
+        SymbolTable.push();
+        try {
+            body1 = builder.setComplexityLimit(body1ComplLimit)
+                    .setStatementLimit(body1StatementLimit)
+                    .setLevel(level)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(true)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(canHaveReturn)
+                    .getBlockFactory()
+                    .produce();
+        } catch (ProductionFailedException e) {
+            body1 = new Nothing();
+        }
+        loop.manipulator = builder.setLocalVariable(counter).getCounterManipulatorFactory().produce();
+        IRNode body2;
+        try {
+            body2 = builder.setComplexityLimit(body2ComplLimit)
+                    .setStatementLimit(body2StatementLimit)
+                    .setLevel(level)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(true)
+                    .setCanHaveContinues(true)
+                    .setCanHaveReturn(canHaveReturn)
+                    .getBlockFactory()
+                    .produce();
+        } catch (ProductionFailedException e) {
+            body2 = new Nothing();
+        }
+        IRNode body3;
+        try {
+            body3 = builder.setComplexityLimit(body3ComplLimit)
+                    .setStatementLimit(body3StatementLimit)
+                    .setLevel(level)
+                    .setSubBlock(true)
+                    .setCanHaveBreaks(true)
+                    .setCanHaveContinues(false)
+                    .setCanHaveReturn(canHaveReturn)
+                    .getBlockFactory()
+                    .produce();
+        } catch (ProductionFailedException e) {
+            body3 = new Nothing();
+        }
+        SymbolTable.pop();
+        return new While(level, loop, thisLoopIterLimit, header, body1, body2, body3);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/ArgumentDeclaration.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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.functions;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class ArgumentDeclaration extends IRNode {
+    public VariableInfo variableInfo;
+
+    public ArgumentDeclaration(VariableInfo variableInfo) {
+        this.variableInfo = variableInfo;
+    }
+
+    @Override
+    public long complexity() {
+        return 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/ConstructorDefinition.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,54 @@
+/*
+ * 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.functions;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class ConstructorDefinition extends IRNode {
+    private final FunctionInfo functionInfo;
+
+    public ConstructorDefinition(FunctionInfo functionInfo,
+            ArrayList<ArgumentDeclaration> argumentsDeclaration, IRNode body) {
+        this.functionInfo = functionInfo;
+        addChild(body);
+        addChildren(argumentsDeclaration);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode body = getChild(0);
+        return body != null ? body.complexity() : 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public FunctionInfo getFunctionInfo() {
+        return functionInfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/ConstructorDefinitionBlock.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,49 @@
+/*
+ * 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.functions;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class ConstructorDefinitionBlock extends IRNode {
+    public ConstructorDefinitionBlock(ArrayList<IRNode> content, int level) {
+        this.level = level;
+        addChildren(content);
+    }
+
+    @Override
+    public long complexity() {
+        int complexity = 0;
+        for (IRNode child : getChildren()) {
+            complexity += child.complexity();
+        }
+        return complexity;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/Function.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,86 @@
+/*
+ * 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.functions;
+
+import java.util.Collection;
+import java.util.List;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+
+public class Function extends IRNode {
+    private FunctionInfo functionInfo = new FunctionInfo();
+
+    public Function(TypeKlass ownerClass, FunctionInfo functionInfo, List<IRNode> args) {
+        setKlass(ownerClass);
+        this.functionInfo = functionInfo;
+        addChildren(args);
+    }
+
+    @Override
+    public long complexity() {
+        int argsComplexity = 0;
+        for (IRNode child : getChildren()) {
+            argsComplexity += child.complexity();
+        }
+        long funcComplexity = functionInfo.complexity;
+        TypeKlass typeKlass = (TypeKlass) this.klass;
+        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()) {
+                        funcComplexity += c.complexity;
+                    }
+                }
+            }
+            // TODO: Complexities of all non-static initializers should be also added..
+        } else {
+            // Perform the CHA and find the highest complexity
+            for (TypeKlass child : typeKlass.getAllChildren()) {
+                Collection<Symbol> childFuncs = SymbolTable.getAllCombined(child, FunctionInfo.class);
+                for (Symbol childFunc : childFuncs) {
+                    if (((FunctionInfo) childFunc).equals(functionInfo)) {
+                        funcComplexity = Math.max(funcComplexity, ((FunctionInfo) childFunc).complexity);
+                    }
+                }
+            }
+        }
+        return argsComplexity + funcComplexity;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public FunctionInfo getValue() {
+        return functionInfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDeclaration.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,52 @@
+/*
+ * 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.functions;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class FunctionDeclaration extends IRNode {
+    private final FunctionInfo functionInfo;
+
+    public FunctionDeclaration(FunctionInfo functionInfo,
+            ArrayList<ArgumentDeclaration> argumentsDeclaration) {
+        this.functionInfo = functionInfo;
+        addChildren(argumentsDeclaration);
+    }
+
+    @Override
+    public long complexity() {
+        return 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public FunctionInfo getFunctionInfo() {
+        return functionInfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDeclarationBlock.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.functions;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+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);
+        this.level = level;
+        addChildren(content);
+    }
+
+    @Override
+    public long complexity() {
+        int complexity = 0;
+        for (IRNode child : getChildren()) {
+            complexity += child.complexity();
+        }
+        return complexity;
+    }
+
+    public int size() {
+        return getChildren() != null ? getChildren().size() : 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDefinition.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,93 @@
+/*
+ * 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.functions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.types.TypeKlass;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class FunctionDefinition extends IRNode {
+    private final FunctionInfo functionInfo;
+
+    public FunctionDefinition(FunctionInfo functionInfo,
+            ArrayList<ArgumentDeclaration> argumentsDeclaration, IRNode body, IRNode ret) {
+        this.functionInfo = functionInfo;
+        addChild(body);
+        addChild(ret);
+        addChildren(argumentsDeclaration);
+    }
+
+    // get the list of all functions from all parents of the given class.
+    public static Collection<Symbol> getFuncsFromParents(TypeKlass typeKlass) {
+        LinkedList<Symbol> result = new LinkedList<>();
+        for (TypeKlass parent : typeKlass.getAllParents()) {
+            result.addAll(SymbolTable.getAllCombined(parent, FunctionInfo.class));
+        }
+        return result;
+    }
+
+    // Check if the given function prototype f1 is a valid overload of
+    // prototypes in collection S.
+    // The override is invalid if function f1 has the same signature as
+    // function f2 in S, but has different return type.
+    public static boolean isInvalidOverride(FunctionInfo f1, Collection<Symbol> symbols) {
+        for (Symbol symbol : symbols) {
+            FunctionInfo f2 = (FunctionInfo) symbol;
+            if (f1.hasEqualSignature(f2)) {
+                if (!f1.type.equals(f2.type)) {
+                    return true;
+                }
+                if ((f2.flags & FunctionInfo.NONRECURSIVE) > 0
+                        || ((f1.flags & FunctionInfo.ABSTRACT) > 0 && (f2.flags & FunctionInfo.ABSTRACT) == 0)
+                        || (f1.flags & FunctionInfo.STATIC) != (f2.flags & FunctionInfo.STATIC)
+                        || (f2.flags & FunctionInfo.FINAL) > 0
+                        || (f1.flags & FunctionInfo.ACCESS_ATTRS_MASK) < (f2.flags & FunctionInfo.ACCESS_ATTRS_MASK)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public long complexity() {
+        IRNode body = getChild(0);
+        IRNode ret = getChild(1);
+        return body.complexity() + (ret != null ? ret.complexity() : 0);
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public FunctionInfo getFunctionInfo() {
+        return functionInfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionDefinitionBlock.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.functions;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+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);
+        addChildren(content);
+        this.level = level;
+    }
+
+    @Override
+    public long complexity() {
+        int complexity = 0;
+        for (IRNode child : getChildren()) {
+            complexity += child.complexity();
+        }
+        return complexity;
+    }
+
+    protected int size() {
+        return getChildren() != null ? getChildren().size() : 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionInfo.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,132 @@
+/*
+ * 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.functions;
+
+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;
+import jdk.test.lib.jittester.types.TypeKlass;
+
+public class FunctionInfo extends Symbol {
+    public ArrayList<VariableInfo> argTypes;
+    public long complexity = 0;
+    public static final int ABSTRACT = 0x40;
+    public static final int NONRECURSIVE = 0x80;
+    public static final int SYNCHRONIZED = 0x100;
+
+    public FunctionInfo() {
+    }
+
+    public FunctionInfo(String name, TypeKlass ownerClass, Type returnType,
+            long complexity, int flags, VariableInfo... args) {
+        super(name, ownerClass, returnType, flags);
+        argTypes = new ArrayList<>();
+        argTypes.addAll(Arrays.asList(args));
+        this.complexity = complexity;
+    }
+
+    public FunctionInfo(String name, TypeKlass ownerClass, Type returnType,
+            long complexity, int flags, ArrayList<VariableInfo> args) {
+        super(name, ownerClass, returnType, flags);
+        argTypes = args;
+        this.complexity = complexity;
+    }
+
+    public FunctionInfo(FunctionInfo value) {
+        super(value);
+        argTypes = new ArrayList<>();
+        for (VariableInfo i : value.argTypes) {
+            argTypes.add(new VariableInfo(i));
+        }
+        complexity = value.complexity;
+    }
+
+    public boolean isSynchronized() {
+        return (flags & SYNCHRONIZED) > 0;
+    }
+
+    @Override
+    protected Symbol copy() {
+        return this;
+    }
+
+    @Override
+    public Symbol deepCopy() {
+        return new FunctionInfo(this);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || !(o instanceof FunctionInfo)) {
+            return false;
+        }
+
+        try {
+            FunctionInfo f = (FunctionInfo) o;
+            return klass.equals(f.klass) && hasEqualSignature(o);
+        } catch (Exception e) {
+        }
+        return false;
+    }
+
+    protected boolean hasEqualSignature(Object o) {
+        try {
+            FunctionInfo f = (FunctionInfo) o;
+            if (name.equals(f.name)) {
+                int i = (flags & STATIC) > 0 ? 0 : 1;
+                int j = (f.flags & STATIC) > 0 ? 0 : 1;
+
+                if (argTypes.size() - i == f.argTypes.size() - j) {
+                    while (i < argTypes.size() && j < f.argTypes.size()) {
+                        if (!argTypes.get(i++).type.equals(f.argTypes.get(j++).type)) {
+                            return false;
+                        }
+                    }
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+        }
+        return false;
+    }
+
+    public boolean isConstructor() {
+        return name.equals(klass.getName());
+    }
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public boolean isStatic() {
+        return (flags & STATIC) > 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionRedefinition.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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.functions;
+
+import java.util.ArrayList;
+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) {
+        this.functionInfo = functionInfo;
+        addChild(body);
+        addChild(ret);
+        addChildren(argumentsDeclaration);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode body = getChild(0);
+        IRNode ret = getChild(1);
+        return body.complexity() + (ret != null ? ret.complexity() : 0);
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public FunctionInfo getFunctionInfo() {
+        return functionInfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/FunctionRedefinitionBlock.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,53 @@
+/*
+ * 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.functions;
+
+import java.util.ArrayList;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class FunctionRedefinitionBlock extends IRNode {
+    public FunctionRedefinitionBlock(ArrayList<IRNode> content, int level) {
+        this.level = level;
+        addChildren(content);
+    }
+
+    @Override
+    public long complexity() {
+        int complexity = 0;
+        for (IRNode child : getChildren()) {
+            complexity += child.complexity();
+        }
+        return complexity;
+    }
+
+    protected int size() {
+        return getChildren() != null ? getChildren().size() : 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/Return.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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.functions;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class Return extends IRNode {
+    private final IRNode returnExpression;
+
+    public Return(IRNode returnExpression) {
+        this.returnExpression = returnExpression;
+        addChild(returnExpression);
+    }
+
+    @Override
+    public long complexity() {
+        return returnExpression.complexity();
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public IRNode getExpression() {
+        return returnExpression;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/functions/StaticConstructorDefinition.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,44 @@
+/*
+ * 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.test.lib.jittester.functions;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class StaticConstructorDefinition extends IRNode {
+    public StaticConstructorDefinition(IRNode body) {
+        addChild(body);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode body = getChild(0);
+        return body != null ? body.complexity() : 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/jtreg/JitTesterDriver.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,87 @@
+/*
+ * 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.test.lib.jittester.jtreg;
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.Utils;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class JitTesterDriver {
+
+    public static void main(String[] args) {
+        if (args.length != 1) {
+            throw new IllegalArgumentException(
+                    "[TESTBUG]: wrong number of argument : " + args.length
+                    + ". Expected 1 argument -- jit-tester test name.");
+        }
+        OutputAnalyzer oa;
+        try {
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, args[0]);
+            oa = new OutputAnalyzer(pb.start());
+        } catch (Exception e) {
+            throw new Error("Unexpected exception on test jvm start :" + e, e);
+        }
+
+        Path testDir = Paths.get(Utils.TEST_SRC);
+        String goldOut = formatOutput(streamGoldFile(testDir, args[0], "out"), s -> true);
+        Asserts.assertEQ(oa.getStdout(), goldOut, "Actual stdout isn't equal to golden one");
+
+        // TODO: add a comment why we skip such lines
+        Predicate<String> notStartWhitespaces = s -> !(s.startsWith("\t") || s.startsWith(" "));
+        String goldErr = formatOutput(streamGoldFile(testDir, args[0], "err"), notStartWhitespaces);
+        String anlzErr = formatOutput(Arrays.stream(oa.getStderr().split(Utils.NEW_LINE)),
+                                      notStartWhitespaces);
+        Asserts.assertEQ(anlzErr, goldErr, "Actual stderr isn't equal to golden one");
+
+        int exitValue = Integer.parseInt(streamGoldFile(testDir, args[0], "exit").findFirst().get());
+        oa.shouldHaveExitValue(exitValue);
+    }
+
+    private static String formatOutput(Stream<String> stream, Predicate<String> predicate) {
+        String result = stream
+                .filter(predicate)
+                .collect(Collectors.joining(Utils.NEW_LINE));
+        if (result.length() > 0) {
+            result += Utils.NEW_LINE;
+        }
+        return result;
+    }
+
+    private static Stream<String> streamGoldFile(Path dir, String name, String suffix) {
+        try {
+            return Files.lines(dir.resolve(name + ".gold." + suffix));
+        } catch (IOException e) {
+            throw new Error(String.format("Can't read golden %s for %s : %s", suffix, name, e), e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/CounterInitializer.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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.loops;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.Initialization;
+import jdk.test.lib.jittester.VariableInfo;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class CounterInitializer extends Initialization {
+    public CounterInitializer(VariableInfo varInfo, IRNode expression) {
+        super(varInfo, expression);
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/CounterManipulator.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,53 @@
+/*
+ * 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.loops;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.LocalVariable;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+/*
+ * Note: Can be theoretically subclassed from Operator and have an
+ * operatorPriority field. Therefore, it can used later as a part
+ * of some expression.
+ */
+
+public class CounterManipulator extends IRNode {
+    LocalVariable counter;
+
+    public CounterManipulator(IRNode manipulator) {
+        addChild(manipulator);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode manipulator = getChild(0);
+        return manipulator != null ? manipulator.complexity() : 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/DoWhile.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,97 @@
+/*
+ * 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.loops;
+
+import java.util.List;
+import jdk.test.lib.jittester.Block;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class DoWhile extends IRNode {
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public Loop getLoop() {
+        return loop;
+    }
+    public enum DoWhilePart {
+        HEADER,
+        BODY1,
+        BODY2,
+    };
+    private final Loop loop;
+    // header;                  [subblock]
+    // do {
+    //      body1;              [subblock with breaks]
+    //      mutate(counter);
+    //      body2;              [subblock with breaks]
+    // } while(condition);
+    private long thisLoopIterLimit = 0;
+
+    public DoWhile(int level, Loop loop, long thisLoopIterLimit, IRNode header,
+            IRNode body1, IRNode body2) {
+        this.level = level;
+        this.loop = loop;
+        this.thisLoopIterLimit = thisLoopIterLimit;
+        addChild(header);
+        addChild(body1);
+        addChild(body2);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode header = getChild(DoWhilePart.HEADER.ordinal());
+        IRNode body1 = getChild(DoWhilePart.BODY1.ordinal());
+        IRNode body2 = getChild(DoWhilePart.BODY2.ordinal());
+        return loop.initialization.complexity()
+                + header.complexity()
+                + thisLoopIterLimit * (body1.complexity()
+                + loop.manipulator.complexity()
+                + body2.complexity()
+                + loop.condition.complexity());
+    }
+
+    @Override
+    public long countDepth() {
+        return Long.max(level, super.countDepth());
+    }
+
+    @Override
+    public boolean removeSelf() {
+        IRNode header = getChildren().get(DoWhilePart.HEADER.ordinal());
+        List<IRNode> siblings = getParent().getChildren();
+        int index = siblings.indexOf(this);
+        if (header instanceof Block) {
+            siblings.remove(this);
+            siblings.addAll(index, header.getChildren());
+        } else {
+            siblings.set(index, header);
+        }
+        siblings.add(index + header.getChildren().size(), loop.initialization);
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/For.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,112 @@
+/*
+ * 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.loops;
+
+import java.util.List;
+import jdk.test.lib.jittester.Block;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class For extends IRNode {
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public Loop getLoop() {
+        return loop;
+    }
+    public enum ForPart {
+        HEADER,
+        STATEMENT1,
+        STATEMENT2,
+        BODY1,
+        BODY2,
+        BODY3,
+    };
+
+    private final Loop loop;
+    // header;                       // [subblock]
+    // statement1, statement2;       // for (statement; condition; statement) {
+    // body1;                        //    [subblock with breaks]
+    //    mutate(x);
+    // body2;                        //    [subblock with breaks and continues]
+    // body3;                        //    [subblock with breaks]
+    // }
+    private long thisLoopIterLimit = 0;
+    public For(int level, Loop loop, long thisLoopIterLimit,
+            IRNode header, IRNode statement1,
+            IRNode statement2, IRNode body1, IRNode body2, IRNode body3) {
+        this.level = level;
+        this.loop = loop;
+        this.thisLoopIterLimit = thisLoopIterLimit;
+        resizeUpChildren(ForPart.values().length);
+        getChildren().set(ForPart.HEADER.ordinal(), header);
+        getChildren().set(ForPart.STATEMENT1.ordinal(), statement1);
+        getChildren().set(ForPart.STATEMENT2.ordinal(), statement2);
+        getChildren().set(ForPart.BODY1.ordinal(), body1);
+        getChildren().set(ForPart.BODY2.ordinal(), body2);
+        getChildren().set(ForPart.BODY3.ordinal(), body3);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode header = getChild(ForPart.HEADER.ordinal());
+        IRNode statement1 = getChild(ForPart.STATEMENT1.ordinal());
+        IRNode statement2 = getChild(ForPart.STATEMENT2.ordinal());
+        IRNode body1 = getChild(ForPart.BODY1.ordinal());
+        IRNode body2 = getChild(ForPart.BODY2.ordinal());
+        IRNode body3 = getChild(ForPart.BODY3.ordinal());
+        return loop.initialization.complexity()
+                + header.complexity()
+                + statement1.complexity()
+                + thisLoopIterLimit * (loop.condition.complexity()
+                + statement2.complexity()
+                + body1.complexity()
+                + loop.manipulator.complexity()
+                + body2.complexity()
+                + body3.complexity());
+    }
+
+    @Override
+    public long countDepth() {
+        return Long.max(level, super.countDepth());
+    }
+
+    @Override
+    public boolean removeSelf() {
+        IRNode header = getChildren().get(ForPart.HEADER.ordinal());
+        List<IRNode> siblings = getParent().getChildren();
+        int index = siblings.indexOf(this);
+        if (header instanceof Block) {
+            siblings.remove(this);
+            siblings.addAll(index, header.getChildren());
+        } else {
+            siblings.set(index, header);
+        }
+        siblings.add(index + header.getChildren().size(), loop.initialization);
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/Loop.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/LoopingCondition.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,50 @@
+/*
+ * 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.loops;
+
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class LoopingCondition extends IRNode {
+    private final IRNode condition;
+
+    public LoopingCondition(IRNode condition) {
+        this.condition = condition;
+        addChild(condition);
+    }
+
+    @Override
+    public long complexity() {
+        return condition != null ? condition.complexity() : 0;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public IRNode getCondition() {
+        return condition;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/loops/While.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,105 @@
+/*
+ * 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.loops;
+
+import java.util.List;
+import jdk.test.lib.jittester.Block;
+import jdk.test.lib.jittester.IRNode;
+import jdk.test.lib.jittester.visitors.Visitor;
+
+public class While extends IRNode {
+
+    public Loop getLoop() {
+        return loop;
+    }
+    public enum WhilePart {
+        HEADER,
+        BODY1,
+        BODY2,
+        BODY3,
+    };
+
+    private final Loop loop;
+    // int counter = x;
+    // header;                                // [subblock]
+    // while (condition) {
+    //      body1;                                 //    [subblock with breaks]
+    //      mutate(counter);
+    //      body2;                                 //    [subblock with breaks and continues]
+    //      body3;                                 //    [subblock with breaks]
+    // }
+    private final long thisLoopIterLimit;
+
+    public While(int level, Loop loop, long thisLoopIterLimit, IRNode header,
+            IRNode body1, IRNode body2, IRNode body3) {
+        this.loop = loop;
+        this.level = level;
+        this.thisLoopIterLimit = thisLoopIterLimit;
+        resizeUpChildren(WhilePart.values().length);
+        getChildren().set(WhilePart.HEADER.ordinal(), header);
+        getChildren().set(WhilePart.BODY1.ordinal(), body1);
+        getChildren().set(WhilePart.BODY2.ordinal(), body2);
+        getChildren().set(WhilePart.BODY3.ordinal(), body3);
+    }
+
+    @Override
+    public long complexity() {
+        IRNode header = getChildren().get(WhilePart.HEADER.ordinal());
+        IRNode body1 = getChildren().get(WhilePart.BODY1.ordinal());
+        IRNode body2 = getChildren().get(WhilePart.BODY2.ordinal());
+        IRNode body3 = getChildren().get(WhilePart.BODY3.ordinal());
+        return loop.initialization.complexity()
+                + header.complexity()
+                + thisLoopIterLimit * (loop.condition.complexity()
+                + body1.complexity()
+                + loop.manipulator.complexity()
+                + body2.complexity()
+                + body3.complexity());
+    }
+
+    @Override
+    public long countDepth() {
+        return Long.max(level, super.countDepth());
+    }
+
+    @Override
+    public boolean removeSelf() {
+        IRNode header = getChildren().get(WhilePart.HEADER.ordinal());
+        List<IRNode> siblings = getParent().getChildren();
+        int index = siblings.indexOf(this);
+        if (header instanceof Block) {
+            siblings.remove(this);
+            siblings.addAll(index, header.getChildren());
+        } else {
+            siblings.set(index, header);
+        }
+        siblings.add(index + header.getChildren().size(), loop.initialization);
+        return true;
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeArray.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,139 @@
+/*
+ * 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.types;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import jdk.test.lib.jittester.ProductionParams;
+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.visitors.Visitor;
+import jdk.test.lib.jittester.utils.PseudoRandom;
+
+public class TypeArray extends TypeKlass {
+
+    public List<Byte> getDims() {
+        return dims;
+    }
+
+    public void setDimentions(List<Byte> dims) {
+        this.dims = dims;
+    }
+    public final Type type;
+    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"));
+        this.type = type;
+        this.dimensions = dimensions;
+    }
+
+    @Override
+    protected void exportSymbols() {
+        SymbolTable.add(new VariableInfo("length", this, new TypeInt(), VariableInfo.PUBLIC | VariableInfo.FINAL));
+    }
+
+    @Override
+    public boolean equals(Object t) {
+                if (this == t) {
+            return true;
+        }
+        if (t == null || !(t instanceof TypeArray)) {
+            return false;
+        }
+
+        if (super.equals(t)) { // make sure we're compating to an array
+            try {
+                TypeArray a = (TypeArray) t;
+                return a.type.equals(type) && (a.dimensions == dimensions
+                        || a.dimensions == -1
+                        || dimensions == -1);
+            } catch (Exception e) {
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 53 * hash + Objects.hashCode(this.type);
+        hash = 313 * hash + this.dimensions;
+        return hash;
+    }
+
+    @Override
+    public int compareTo(Type t) {
+        int r = 0;
+        r = super.compareTo(t);
+        if (r == 0) {
+            try {
+                TypeArray a = (TypeArray) t;
+                r = type.compareTo(t);
+                if (r == 0) {
+                    r = dimensions - a.dimensions;
+                }
+            } catch (Exception e) {
+            }
+        }
+
+        return r;
+    }
+
+    public TypeArray produce() {
+        ArrayList<Type> all = new ArrayList<>(TypeList.getAll());
+        PseudoRandom.shuffle(all);
+        for (Type t : all) {
+            if (t instanceof TypeArray) {
+                continue;
+            }
+            int dims = PseudoRandom.randomNotZero(ProductionParams.dimensionsLimit.value());
+            return new TypeArray(t, dims);
+        }
+        throw new Error("Shouldn't happen");
+    }
+
+    @Override
+    public<T> T accept(Visitor<T> v) {
+        return v.visit(this);
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public int getDimensions() {
+        return dimensions;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeBoolean.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.types;
+
+import jdk.test.lib.jittester.BuiltInType;
+import jdk.test.lib.jittester.Type;
+
+
+public class TypeBoolean extends BuiltInType {
+
+    @Override
+    public boolean canImplicitlyCastTo(Type t) {
+        return equals(t);
+    }
+
+    @Override
+    public boolean canExplicitlyCastTo(Type t) {
+        return equals(t);
+    }
+
+    @Override
+    public boolean canCompareTo(Type t) {
+        return false;
+    }
+
+    @Override
+    public boolean canEquateTo(Type t) {
+        return equals(t);
+    }
+
+    public TypeBoolean() {
+        super("boolean");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeByte.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.types;
+
+import jdk.test.lib.jittester.BuiltInType;
+
+public class TypeByte extends BuiltInType {
+
+    public TypeByte() {
+        super("byte");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeChar.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,49 @@
+/*
+ * 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.types;
+
+import jdk.test.lib.jittester.BuiltInType;
+import jdk.test.lib.jittester.Type;
+
+public class TypeChar extends BuiltInType {
+
+    public TypeChar() {
+        super("char");
+    }
+
+    @Override
+    public boolean canImplicitlyCastTo(Type t) {
+        if (equals(t)) {
+            return true;
+        }
+        try {
+            BuiltInType _t = (BuiltInType) t;
+            if (_t.isMoreCapaciousThan(this)) {
+                return true;
+            }
+        } catch (Exception e) {
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeDouble.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.types;
+
+import jdk.test.lib.jittester.BuiltInType;
+
+public class TypeDouble extends BuiltInType {
+
+    public TypeDouble() {
+        super("double");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeFloat.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.types;
+
+import jdk.test.lib.jittester.BuiltInType;
+
+public class TypeFloat extends BuiltInType {
+
+    public TypeFloat() {
+        super("float");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeInt.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.types;
+
+import jdk.test.lib.jittester.BuiltInType;
+
+public class TypeInt extends BuiltInType {
+
+    public TypeInt() {
+        super("int");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeKlass.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,208 @@
+/*
+ * 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.types;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.TreeSet;
+import jdk.test.lib.jittester.ProductionParams;
+import jdk.test.lib.jittester.Symbol;
+import jdk.test.lib.jittester.SymbolTable;
+import jdk.test.lib.jittester.Type;
+import jdk.test.lib.jittester.TypeList;
+
+public class TypeKlass extends Type {
+
+    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);
+    }
+
+    public TypeKlass(String name, int flags) {
+        super(name);
+        this.flags = flags;
+        symbolsSet = new HashSet<>();
+    }
+
+    public boolean addSymbol(Symbol s) {
+        return symbolsSet.add(s);
+    }
+
+    public boolean addAllSymbols(Collection<? extends Symbol> symbols) {
+        return symbolsSet.addAll(symbols);
+    }
+
+    public boolean containsSymbol(Symbol s) {
+        return symbolsSet.contains(s);
+    }
+
+    public boolean removeSymbol(Symbol s) {
+        return symbolsSet.remove(s);
+    }
+
+    public boolean removeAllSymbols(Collection<? extends Symbol> symbols) {
+        return symbolsSet.removeAll(symbols);
+    }
+
+    @Override
+    protected void exportSymbols() {
+        symbolsSet.stream().forEach(symbol -> {
+            SymbolTable.add(symbol);
+        });
+    }
+
+    public void setParent(TypeKlass p) {
+        parent = 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);
+        }
+    }
+
+    protected void removeChild(String c) {
+        if (childrenList != null) {
+            childrenList.remove(c);
+        }
+    }
+
+    public HashSet<String> getParentsNames() {
+        return parentsList;
+    }
+
+    public HashSet<String> getChildrenNames() {
+        return childrenList;
+    }
+
+    @Override
+    public boolean canCompareTo(Type t) {
+        return false;
+    }
+
+    @Override
+    public boolean canEquateTo(Type t) {
+        return true;
+    }
+
+    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) {
+                    }
+                }
+            }
+        }
+        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) {
+                    }
+                }
+            }
+        }
+        return r;
+    }
+
+    @Override
+    public boolean canImplicitlyCastTo(Type t) {
+        // We can implicitly cast to anything up the hierarchy and to self
+        if (t instanceof TypeKlass) {
+            return equals(t) || getAllParents().contains(t);
+        }
+        return false;
+    }
+
+    // If canExplicitlyCastTo() returns true in this case it doesn't mean that
+    // it would really be successful. Since explicit casts are inherintly dynamic
+    // we cannot guarantee that no exception will occur.
+    @Override
+    public boolean canExplicitlyCastTo(Type t) {
+        if (t instanceof TypeKlass && !ProductionParams.disableDowncasts.value()) {
+            return equals(t) || getAllChildren().contains(t);
+        }
+
+        return false;
+    }
+
+    public boolean isFinal() {
+        return (flags & FINAL) > 0;
+    }
+
+    public void setFinal() {
+        flags |= FINAL;
+    }
+
+    public boolean isAbstract() {
+        return (flags & ABSTRACT) > 0;
+    }
+
+    public void setAbstract() {
+        flags |= ABSTRACT;
+    }
+
+    public boolean isInterface() {
+        return (flags & INTERFACE) > 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeLong.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.types;
+
+import jdk.test.lib.jittester.BuiltInType;
+
+public class TypeLong extends BuiltInType {
+
+    public TypeLong() {
+        super("long");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeShort.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,33 @@
+/*
+ * 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.types;
+
+import jdk.test.lib.jittester.BuiltInType;
+
+public class TypeShort extends BuiltInType {
+
+    public TypeShort() {
+        super("short");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/types/TypeVoid.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,59 @@
+/*
+ * 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.types;
+
+import jdk.test.lib.jittester.BuiltInType;
+import jdk.test.lib.jittester.Type;
+
+public class TypeVoid extends BuiltInType {
+
+    public TypeVoid() {
+        super("void");
+    }
+
+    @Override
+    public boolean canImplicitlyCastTo(Type t) {
+        return false;
+    }
+
+    @Override
+    public boolean canExplicitlyCastTo(Type t) {
+        return false;
+    }
+
+    @Override
+    public boolean isMoreCapaciousThan(BuiltInType t) {
+        return false;
+    }
+
+    @Override
+    public boolean canCompareTo(Type t) {
+        return false;
+    }
+
+    @Override
+    public boolean canEquateTo(Type t) {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/utils/OptionResolver.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,267 @@
+/*
+ * 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.test.lib.jittester.utils;
+
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.*;
+
+public class OptionResolver {
+    private final Map<String, Option<?>> options = new LinkedHashMap<>(20);
+    private Map<Option<?>, Object> values = Collections.emptyMap();
+
+    public OptionResolver() {
+    }
+
+    public final void parse(String[] argv) {
+        parse(argv, null);
+    }
+
+    public final void parse(String[] argv, Option<String> propertyFileOption) {
+        int position = 0;
+        this.values = new HashMap<>(argv.length / 2);
+
+        while (position < argv.length) {
+            String curArg = argv[position];
+            if (curArg.startsWith("-")) {
+                String valueArg = null;
+                int opt;
+                if (curArg.startsWith("--")) {
+                    opt = curArg.indexOf("=");
+                    if (opt != -1) {
+                        valueArg = curArg.substring(opt + 1);
+                        curArg = curArg.substring(0, opt);
+                    }
+                } else if (curArg.length() > 2) {
+                    for (opt = 1; opt < curArg.length(); ++opt) {
+                        final char key = curArg.charAt(opt);
+                        Option<?> flagOption = this.options.get("-" + key);
+
+                        if (!flagOption.isFlag()) {
+                            throw new IllegalArgumentException("Unknown flag option " + key);
+                        }
+
+                        values.put(flagOption, Boolean.TRUE);
+                    }
+
+                    ++position;
+                    continue;
+                }
+
+                Option<?> currentOption = this.options.get(curArg);
+                if (currentOption == null) {
+                    throw new IllegalArgumentException("Unknown option " + curArg);
+                }
+
+                Object value;
+                if (!currentOption.isFlag()) {
+                    if (valueArg == null) {
+                        ++position;
+                        if (position < argv.length) {
+                            valueArg = argv[position];
+                        }
+                    }
+                }
+                try {
+                    value = currentOption.parseFromString(valueArg);
+                } catch (Exception ex) {
+                    throw new IllegalArgumentException("Error parsing " + valueArg + ", option " + curArg, ex);
+                }
+                values.put(currentOption, value);
+            }
+            ++position;
+        }
+
+        if (propertyFileOption != null && values.containsKey(propertyFileOption)) {
+            parseProperties(propertyFileOption.value());
+        }
+    }
+
+    private void parseProperties(String fileName) {
+        Properties properties = new Properties();
+        try {
+            properties.load(new FileReader(fileName));
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        for (String optionName : properties.stringPropertyNames()) {
+            Option<?> currentOption = this.options.get("--" + optionName);
+            if (currentOption == null) {
+                throw new IllegalArgumentException("Unknown option in property file" + optionName);
+            }
+
+            final String propertyValue = properties.getProperty(optionName);
+            try {
+                values.putIfAbsent(currentOption, currentOption.parseFromString(propertyValue));
+            } catch (Exception ex) {
+                throw new IllegalArgumentException("Error parsing " + propertyValue + ", property " + optionName, ex);
+            }
+        }
+    }
+
+    public Option<Integer> addIntegerOption(Character key, String name, int defaultValue, String description) {
+        final Option<Integer> option = new IntOption(key, name, defaultValue, description);
+        register(option);
+        return option;
+    }
+
+    public Option<Long> addLongOption(Character key, String name, long defaultValue, String description) {
+        final Option<Long> option = new LongOption(key, name, defaultValue, description);
+        register(option);
+        return option;
+    }
+
+    public Option<String> addStringOption(Character key, String name, String defaultValue, String description) {
+        final Option<String> option = new StringOption(key, name, defaultValue, description);
+        register(option);
+        return option;
+    }
+
+    public Option<Boolean> addBooleanOption(Character key, String name, boolean defaultValue, String description) {
+        final Option<Boolean> option = new BooleanOption(key, name, defaultValue, description);
+        register(option);
+        return option;
+    }
+
+    public Option<Integer> addIntegerOption(String name, int defaultValue, String description) {
+        return addIntegerOption(null, name, defaultValue, description);
+    }
+
+    public Option<String> addStringOption(String name, String defaultValue, String description) {
+        return addStringOption(null, name, defaultValue, description);
+    }
+
+    public Option<Boolean> addBooleanOption(String name, String description) {
+        return addBooleanOption(null, name, false, description);
+    }
+
+    private void register(Option<?> option) {
+        if (options.put("--" + option.longName, option) != null) {
+            throw new RuntimeException("Option is already registered for key " + option.longName);
+        }
+        if (option.shortName != null && options.put("-" + option.shortName, option) != null) {
+            throw new RuntimeException("Option is already registered for key " + option.shortName);
+        }
+    }
+
+    public abstract class Option<T> {
+
+        Character shortName;
+        String longName;
+        protected T defaultValue;
+        protected String description;
+
+        public Option(Character shortName, String longName, T defaultValue, String description) {
+            this.shortName = shortName;
+            this.longName = longName;
+            this.defaultValue = defaultValue;
+            this.description = description;
+        }
+
+        public Character getShortName() {
+            return shortName;
+        }
+
+        public String getLongName() {
+            return longName;
+        }
+
+        public T getDefaultValue() {
+            return defaultValue;
+        }
+
+        public String getDescription() {
+            return description;
+        }
+
+        @SuppressWarnings("unchecked")
+        public T value() {
+            return (T) values.getOrDefault(this, defaultValue);
+        }
+
+        public boolean isFlag() {
+            return false;
+        }
+
+        public abstract T parseFromString(String arg);
+    }
+
+    private class StringOption extends Option<String> {
+
+        StringOption(Character s, String l, String v, String d) {
+            super(s, l, v, d);
+        }
+
+        @Override
+        public String parseFromString(String arg) {
+            return arg;
+        }
+    }
+
+    private class LongOption extends Option<Long> {
+
+        LongOption(Character s, String l, long v, String d) {
+            super(s, l, v, d);
+        }
+
+        @Override
+        public Long parseFromString(String arg) {
+            return new Long(arg);
+        }
+    }
+
+    private class IntOption extends Option<Integer> {
+
+        IntOption(Character s, String l, int v, String d) {
+            super(s, l, v, d);
+        }
+
+        @Override
+        public Integer parseFromString(String arg) {
+            return new Integer(arg);
+        }
+    }
+
+    private class BooleanOption extends Option<Boolean> {
+
+        BooleanOption(Character s, String l, boolean v, String d) {
+            super(s, l, v, d);
+        }
+
+        @Override
+        public boolean isFlag() {
+            return true;
+        }
+
+        @Override
+        public Boolean parseFromString(String arg) {
+            //null and empty value is considered true, as option is flag and value could be absent
+            return arg == null || "".equals(arg) || "1".equalsIgnoreCase(arg) || "true".equalsIgnoreCase(arg);
+        }
+    }
+
+    public Collection<Option<?>> getRegisteredOptions() {
+        return Collections.unmodifiableSet(new LinkedHashSet<>(options.values()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/utils/PrintingUtils.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,35 @@
+/*
+ * 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.utils;
+
+public class PrintingUtils {
+
+    static public String align(int l) {
+        String shift = "";
+        for (int i = 0; i < l; i++) {
+            shift += "    ";
+        }
+        return shift;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/utils/PseudoRandom.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,106 @@
+/*
+ * 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.test.lib.jittester.utils;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+
+/**
+ * This class is used for any random generation operations.
+ */
+public class PseudoRandom {
+
+    private static java.util.Random random = null;
+
+    public static void reset(String seed) {
+        if (seed == null || seed.length() == 0) {
+            seed = String.valueOf(System.currentTimeMillis());
+        }
+        random = new java.util.Random(seed.hashCode());
+    }
+
+    public static double random() {
+        return random.nextDouble();
+    }
+
+    // uniformly distributed boolean
+    public static boolean randomBoolean() {
+        return random.nextBoolean();
+    }
+
+    // non-uniformly distributed boolean. 0 probability - never true, 1 - always true
+    public static boolean randomBoolean(double probability) {
+        return random.nextDouble() < probability;
+    }
+
+    public static long randomNotZero(long limit) {
+        long result = (long) (limit * random.nextDouble());
+        return result > 0L ? result : 1L;
+    }
+
+    public static int randomNotZero(int limit) {
+        int result = (int) (limit * random.nextDouble());
+        return result > 0 ? result : 1;
+    }
+
+    public static void shuffle(List<?> list) {
+        Collections.shuffle(list, random);
+    }
+
+    public static byte randomNotNegative(byte limit) {
+        byte result = (byte) (limit * random.nextDouble());
+        return (byte)Math.abs(result);
+    }
+
+    public static <T> T randomElement(Collection<T> collection) {
+        if (collection.isEmpty())
+            throw new NoSuchElementException("Empty, no element can be randomly selected");
+        if (collection instanceof List)
+            return randomElement((List<T>) collection);
+        else {
+            int ix = random.nextInt(collection.size());
+            final Iterator<T> iterator = collection.iterator();
+            while (ix > 0) {
+                ix--;
+                iterator.next();
+            }
+            return iterator.next();
+        }
+    }
+
+    public static <T> T randomElement(List<T> list) {
+        if (list.isEmpty())
+            throw new NoSuchElementException("Empty, no element can be randomly selected");
+        return list.get(random.nextInt(list.size()));
+    }
+
+    public static <T> T randomElement(T[] array) {
+        if (array.length == 0)
+            throw new NoSuchElementException("Empty, no element can be randomly selected");
+        return array[random.nextInt(array.length)];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/visitors/JavaCodeVisitor.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,1044 @@
+/*
+ * 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.test.lib.jittester.visitors;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Objects;
+import java.util.stream.Collectors;
+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.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.LogicOperator;
+import jdk.test.lib.jittester.NonStaticMemberVariable;
+import jdk.test.lib.jittester.Nothing;
+import jdk.test.lib.jittester.Operator;
+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.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.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.PrintingUtils;
+
+public class JavaCodeVisitor implements Visitor<String> {
+
+    public static String funcAttributes(FunctionInfo fi) {
+        String attrs = attributes(fi);
+        if (fi.isSynchronized()) {
+            attrs += "synchronized ";
+        }
+        return attrs;
+    }
+
+    public static String attributes(Symbol s) {
+        String attrs = "";
+        if (s.isPrivate()) {
+            attrs += "private ";
+        }
+        if (s.isProtected()) {
+            attrs += "protected ";
+        }
+        if (s.isPublic()) {
+            attrs += "public ";
+        }
+        if (s.isFinal()) {
+            attrs += "final ";
+        }
+        if (s.isStatic()) {
+            attrs += "static ";
+        }
+        return attrs;
+    }
+
+    public String expressionToJavaCode(Operator t, IRNode p, Operator.Order o) {
+        String result;
+        try {
+            if ((o == Operator.Order.LEFT && ((Operator) p).getPriority() < t.getPriority())
+                    || (o == Operator.Order.RIGHT && ((Operator) p).getPriority() <= t.getPriority())) {
+                result = "(" + p.accept(this)+ ")";
+            } else {
+                result = p.accept(this);
+            }
+        } catch (Exception e) {
+            result = p.accept(this);
+        }
+        return result;
+    }
+
+    @Override
+    public String visit(ArgumentDeclaration node) {
+        VariableInfo vi = node.variableInfo;
+        return attributes(vi) + vi.type.accept(this) + " " + vi.name;
+    }
+
+    @Override
+    public String visit(ArrayCreation node) {
+        Type arrayType = node.getArrayType();
+        String type = arrayType.accept(this);
+        String name = node.getVariable().getName();
+        StringBuilder code = new StringBuilder()
+                .append(node.getVariable().accept(this))
+                .append(";\n")
+                .append(PrintingUtils.align(node.getParent().getLevel()))
+                .append(name)
+                .append(" = new ")
+                .append(type);
+        code.append(node.getChildren().stream()
+                .map(p -> p.accept(this))
+                .collect(Collectors.joining("][", "[", "]")));
+        code.append(";\n")
+                .append(PrintingUtils.align(node.getParent().getLevel()))
+                .append("java.util.Arrays.fill(")
+                .append(name)
+                .append(", ");
+        if (TypeList.find("boolean") == arrayType) {
+            code.append("false");
+        } else if (TypeList.isBuiltIn(arrayType)) {
+            code.append("0");
+        } else {
+            code.append("new ")
+                .append(type)
+                .append("()");
+        }
+        code.append(");\n");
+        return code.toString();
+    }
+
+    @Override
+    public String visit(ArrayElement node) {
+        IRNode array = node.getChild(0);
+        StringBuilder code = new StringBuilder();
+        if (array instanceof VariableBase || array instanceof Function) {
+            code.append(array.accept(this));
+        } else {
+            code.append("(")
+                .append(array.accept(this))
+                .append(")");
+        }
+        code.append(node.getChildren().stream()
+                .skip(1)
+                .map(c -> c.accept(this))
+                .collect(Collectors.joining("][", "[", "]")));
+        return code.toString();
+    }
+
+    @Override
+    public String visit(ArrayExtraction node) {
+        IRNode array = node.getChild(0);
+        StringBuilder code = new StringBuilder();
+        if (array instanceof VariableBase || array instanceof Function) {
+            code.append(array.accept(this));
+        } else {
+            code.append("(")
+                .append(array.accept(this))
+                .append(")");
+        }
+        code.append(node.getChildren().stream()
+                .skip(1)
+                .map(c -> c.accept(this))
+                .collect(Collectors.joining("][", "[", "]")));
+        return code.toString();
+    }
+
+    @Override
+    public String visit(BinaryOperator node) {
+        IRNode left = node.getChild(Operator.Order.LEFT.ordinal());
+        IRNode right = node.getChild(Operator.Order.RIGHT.ordinal());
+        if (left == null || right == null) {
+            return "null";
+        }
+        return expressionToJavaCode(node, left, Operator.Order.LEFT)
+               + " " + node.getOperationCode() + " "
+               + expressionToJavaCode(node, right, Operator.Order.RIGHT);
+    }
+
+    @Override
+    public String visit(Block node) {
+        StringBuilder code = new StringBuilder();
+        for (IRNode i : node.getChildren()) {
+            String s = i.accept(this);
+            if (!s.isEmpty()) {
+                int level = node.getLevel();
+                if (i instanceof Block) {
+                    code.append(PrintingUtils.align(level + 1))
+                        .append("{\n")
+                        .append(s)
+                        .append(PrintingUtils.align(level + 1))
+                        .append("}");
+                } else {
+                    code.append(PrintingUtils.align(level + 1))
+                        .append(s);
+                }
+                code.append(addComplexityInfo(i));
+                code.append("\n");
+            }
+        }
+        return code.toString();
+    }
+
+    private String addComplexityInfo(IRNode node) {
+        if (ProductionParams.printComplexity.value()) {
+            return " /* " + node.complexity() + " */";
+        }
+        return "";
+    }
+
+    @Override
+    public String visit(Break node) {
+        return "break;";
+    }
+
+    @Override
+    public String visit(CastOperator node) {
+        return "(" + node.getResultType().accept(this)+ ")"
+                + expressionToJavaCode(node, node.getChild(0), Operator.Order.LEFT);
+    }
+
+    @Override
+    public String visit(ClassDefinitionBlock node) {
+        StringBuilder code = new StringBuilder();
+        for (IRNode i : node.getChildren()) {
+            code.append("\n")
+                .append(PrintingUtils.align(node.getLevel()))
+                .append(i.accept(this))
+                .append("\n");
+        }
+
+        return code.toString();
+    }
+
+    @Override
+    public String visit(ConstructorDefinition node) {
+        String args = node.getChildren().stream()
+                .skip(1)
+                .map(c -> c.accept(this))
+                .collect(Collectors.joining(", "));
+        IRNode body = node.getChild(0);
+        StringBuilder code = new StringBuilder();
+        code.append(funcAttributes(node.getFunctionInfo()))
+            .append(node.getFunctionInfo().name)
+            .append("(")
+            .append(args)
+            .append(")\n")
+            .append(PrintingUtils.align(node.getLevel() + 1))
+            .append("{\n")
+            .append(body != null ? body.accept(this) : "")
+            .append(PrintingUtils.align(node.getLevel() + 1))
+            .append("}");
+        return code.toString();
+    }
+
+    @Override
+    public String visit(ConstructorDefinitionBlock node) {
+        StringBuilder code = new StringBuilder();
+        for (IRNode i : node.getChildren()) {
+            code.append("\n")
+                .append(PrintingUtils.align(node.getLevel()))
+                .append(i.accept(this))
+                .append(addComplexityInfo(i))
+                .append("\n");
+        }
+        return code.toString();
+    }
+
+    @Override
+    public String visit(Continue node) {
+        return "continue;";
+    }
+
+    @Override
+    public String visit(CounterInitializer node) {
+        VariableInfo vi = node.get();
+        return vi.type.accept(this) + " " + vi.name + " = " + node.getChild(0).accept(this)+ ";";
+    }
+
+    @Override
+    public String visit(CounterManipulator node) {
+        return node.getChild(0).accept(this);
+    }
+
+    @Override
+    public String visit(Declaration node) {
+        return node.getChild(0).accept(this)+ ";";
+    }
+
+    @Override
+    public String visit(DoWhile node) {
+        IRNode header = node.getChild(DoWhile.DoWhilePart.HEADER.ordinal());
+        IRNode body1 = node.getChild(DoWhile.DoWhilePart.BODY1.ordinal());
+        IRNode body2 = node.getChild(DoWhile.DoWhilePart.BODY2.ordinal());
+        StringBuilder code = new StringBuilder();
+        Loop loop = node.getLoop();
+        int level = node.getLevel();
+        code.append(loop.initialization.accept(this))
+            .append("\n")
+            .append(header.accept(this))
+            .append(PrintingUtils.align(level))
+            .append("do\n")
+            .append(PrintingUtils.align(level))
+            .append("{\n")
+            .append(body1.accept(this))
+            .append(PrintingUtils.align(level + 1))
+            .append(loop.manipulator.accept(this))
+            .append(";\n")
+            .append(body2.accept(this))
+            .append(PrintingUtils.align(level))
+            .append("} while (")
+            .append(loop.condition.accept(this))
+            .append(");");
+        return code.toString();
+    }
+
+    @Override
+    public String visit(For node) {
+        IRNode header = node.getChild(For.ForPart.HEADER.ordinal());
+        IRNode statement1 = node.getChild(For.ForPart.STATEMENT1.ordinal());
+        IRNode statement2 = node.getChild(For.ForPart.STATEMENT2.ordinal());
+        IRNode body1 = node.getChild(For.ForPart.BODY1.ordinal());
+        IRNode body2 = node.getChild(For.ForPart.BODY2.ordinal());
+        IRNode body3 = node.getChild(For.ForPart.BODY3.ordinal());
+        Loop loop = node.getLoop();
+        StringBuilder code = new StringBuilder();
+        int level = node.getLevel();
+        code.append(loop.initialization.accept(this))
+            .append("\n")
+            .append(header.accept(this))
+            .append(PrintingUtils.align(level))
+            .append("for (")
+            .append(statement1.accept(this))
+            .append("; ")
+            .append(loop.condition.accept(this))
+            .append("; ")
+            .append(statement2.accept(this))
+            .append(")\n")
+            .append(PrintingUtils.align(level))
+            .append("{\n")
+            .append(body1.accept(this))
+            .append(PrintingUtils.align(level + 1))
+            .append(loop.manipulator.accept(this))
+            .append(";\n")
+            .append(body2.accept(this))
+            .append(body3.accept(this))
+            .append(PrintingUtils.align(level))
+            .append("}");
+        return code.toString();
+    }
+
+    @Override
+    public String visit(Function node) {
+        FunctionInfo value = node.getValue();
+        String nameAndArgs = value.name + "("
+                + node.getChildren().stream()
+                    .skip(value.isStatic() || value.isConstructor() ? 0 : 1)
+                    .map(c -> c.accept(this))
+                    .collect(Collectors.joining(", "))
+                + ")";
+        String prefix = "";
+        if (value.isStatic()) {
+            if(!node.getKlass().equals(value.klass)) {
+                prefix = value.klass.getName() + ".";
+            }
+        } else if (value.isConstructor()) {
+            prefix = "new ";
+        } else {
+            IRNode object = node.getChild(0);
+            String objectString = object.accept(this);
+            if (!objectString.equals("this")) {
+                 if (object instanceof VariableBase || object instanceof Function
+                            || object instanceof Literal) {
+                     prefix = objectString + ".";
+                 } else {
+                     prefix = "(" + objectString + ")" + ".";
+                 }
+            }
+        }
+        return prefix + nameAndArgs;
+    }
+
+    @Override
+    public String visit(FunctionDeclaration node) {
+        String args = node.getChildren().stream()
+                .map(c -> c.accept(this))
+                .collect(Collectors.joining(", "));
+
+        FunctionInfo functionInfo = node.getFunctionInfo();
+        return (functionInfo.klass.isInterface() ? "" : "abstract ")
+                + funcAttributes(functionInfo) + functionInfo.type.accept(this)+ " "
+                + functionInfo.name + "(" + args + ");";
+    }
+
+    @Override
+    public String visit(FunctionDeclarationBlock node) {
+        StringBuilder code = new StringBuilder();
+        for (IRNode i : node.getChildren()) {
+            code.append(PrintingUtils.align(node.getLevel()))
+                .append(i.accept(this))
+                .append(addComplexityInfo(i))
+                .append("\n");
+        }
+        return code.toString();
+    }
+
+    @Override
+    public String visit(FunctionDefinition node) {
+        String args = node.getChildren().stream()
+                .skip(2)
+                .map(c -> c.accept(this))
+                .collect(Collectors.joining(", "));
+        IRNode body = node.getChild(0);
+        IRNode ret = node.getChild(1);
+        FunctionInfo functionInfo = node.getFunctionInfo();
+        return funcAttributes(functionInfo) + functionInfo.type.accept(this) + " " + functionInfo.name + "(" + args + ")" + "\n"
+                + 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) + "}";
+    }
+
+    @Override
+    public String visit(FunctionDefinitionBlock node) {
+        StringBuilder code = new StringBuilder();
+        for (IRNode i : node.getChildren()) {
+            code.append("\n")
+                .append(PrintingUtils.align(node.getLevel()))
+                .append(i.accept(this))
+                .append(addComplexityInfo(i))
+                .append("\n");
+        }
+        return code.toString();
+    }
+
+    @Override
+    public String visit(FunctionRedefinition node) {
+        String args = node.getChildren().stream()
+                .map(c -> c.accept(this))
+                .collect(Collectors.joining(", "));
+
+        IRNode body = node.getChild(0);
+        IRNode ret = node.getChild(1);
+        int level = node.getLevel();
+        FunctionInfo functionInfo = node.getFunctionInfo();
+        return funcAttributes(functionInfo) + functionInfo.type + " " + functionInfo.name + "(" + args + ")" + "\n"
+                + PrintingUtils.align(level + 1) + "{\n"
+                + body
+                + (ret != null ? PrintingUtils.align(level + 2) + ret + "\n" : "")
+                + PrintingUtils.align(level + 1) + "}";
+    }
+
+    @Override
+    public String visit(FunctionRedefinitionBlock node) {
+        StringBuilder code = new StringBuilder();
+        for (IRNode i : node.getChildren()) {
+            code.append("\n")
+                .append(PrintingUtils.align(node.getLevel()))
+                .append(i.accept(this))
+                .append(addComplexityInfo(i))
+                .append("\n");
+        }
+        return code.toString();
+    }
+
+    @Override
+    public String visit(If node) {
+        int level = node.getLevel();
+        String thenBlockString = PrintingUtils.align(level) + "{\n"
+                                 + node.getChild(If.IfPart.THEN.ordinal()).accept(this)
+                                 + PrintingUtils.align(level) + "}";
+
+        String elseBlockString = null;
+        if (node.getChild(If.IfPart.ELSE.ordinal()) != null) {
+            elseBlockString = PrintingUtils.align(level) + "{\n"
+                              + node.getChild(If.IfPart.ELSE.ordinal()).accept(this)
+                              + PrintingUtils.align(level) + "}";
+        }
+
+        return "if (" + node.getChild(If.IfPart.CONDITION.ordinal()).accept(this)+ ")\n"
+            + thenBlockString + (elseBlockString != null ? "\n"
+            + PrintingUtils.align(level) + "else\n" + elseBlockString : "");
+    }
+
+    @Override
+    public String visit(Initialization node) {
+        VariableInfo vi = node.getVariableInfo();
+        return attributes(vi) + vi.type.accept(this)+ " " + vi.name + " = "
+                + node.getChild(0).accept(this);
+    }
+
+    @Override
+    public String visit(Interface node) {
+        return "interface " + node.getName() + (node.getParentKlass() != null ? " extends "
+                + node.getParentKlass().getName() : "") + " {\n"
+                + (node.getChildren().size() > 0 ? node.getChild(0).accept(this) : "")
+                + "}\n";
+    }
+
+    @Override
+    public String visit(Klass node) {
+        TypeKlass thisKlass = node.getThisKlass();
+        String r = (ProductionParams.enableStrictFP.value() ? "strictfp " : "")
+                + (thisKlass.isFinal() ? "final " : "")
+                + (thisKlass.isAbstract() ? "abstract " : "")
+                + "class " + node.getName()
+                + (node.getParentKlass()!= null ? " extends " + node.getParentKlass().getName() : "");
+        List<TypeKlass> interfaces = node.getInterfaces();
+        r += interfaces.stream()
+                .map(c -> c.getName())
+                .collect(Collectors.joining(", ", (interfaces.isEmpty() ? "" : " implements "), ""));
+        IRNode dataMembers = node.getChild(Klass.KlassPart.DATA_MEMBERS.ordinal());
+        IRNode constructors = node.getChild(Klass.KlassPart.CONSTRUCTORS.ordinal());
+        IRNode redefinedFunctions = node.getChild(Klass.KlassPart.REDEFINED_FUNCTIONS.ordinal());
+        IRNode overridenFunctions = node.getChild(Klass.KlassPart.OVERRIDEN_FUNCTIONS.ordinal());
+        IRNode memberFunctions = node.getChild(Klass.KlassPart.MEMBER_FUNCTIONS.ordinal());
+        IRNode memberFunctionDecls = node.getChild(Klass.KlassPart.MEMBER_FUNCTIONS_DECLARATIONS.ordinal());
+        IRNode printVariables = node.getChild(Klass.KlassPart.PRINT_VARIABLES.ordinal());
+        r += " {\n"
+             + (dataMembers != null ? (dataMembers.accept(this)+ "\n") : "")
+             + (constructors != null ? (constructors.accept(this)+ "\n") : "")
+             + (redefinedFunctions != null ? (redefinedFunctions.accept(this)+ "\n") : "")
+             + (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;
+    }
+
+    @Override
+    public String visit(Literal node) {
+        Type resultType = node.getResultType();
+        Object value = node.getValue();
+        if (resultType.equals(new TypeLong())) {
+            return value.toString() + "L";
+        }
+        if (resultType.equals(new TypeFloat())) {
+            return String.format((Locale) null,
+                "%." + ProductionParams.floatingPointPrecision.value() + "EF",
+                Double.parseDouble(value.toString()));
+        }
+        if (resultType.equals(new TypeDouble())) {
+            return String.format((Locale) null,
+                "%." + 2 * ProductionParams.floatingPointPrecision.value() + "E",
+                Double.parseDouble(value.toString()));
+        }
+        if (resultType.equals(new TypeChar())) {
+            if (((Character) value).charValue() == '\\') {
+                return "\'" + "\\\\" + "\'";
+            } else {
+                return "\'" + value.toString() + "\'";
+            }
+        }
+        if (resultType.equals(new TypeShort())) {
+            return "(short) " + value.toString();
+        }
+        if (resultType.equals(new TypeByte())) {
+            return "(byte) " + value.toString();
+        }
+        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.");
+    }
+
+    @Override
+    public String visit(LoopingCondition node) {
+        return node.getCondition().accept(this);
+    }
+
+    @Override
+    public String visit(MainKlass node) {
+        String name = node.getName();
+        IRNode dataMembers = node.getChild(MainKlass.MainKlassPart.DATA_MEMBERS.ordinal());
+        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";
+    }
+
+    @Override
+    public String visit(NonStaticMemberVariable node) {
+        IRNode object = node.getChild(0);
+        String objectString = object.accept(this);
+        VariableInfo value = node.getValue();
+        if (objectString.equals("this")) {
+            return value.name;
+        } else {
+            if (object instanceof VariableBase || object instanceof Function || object instanceof Literal) {
+                return objectString + "." + value.name;
+            } else {
+                return "(" + objectString + ")" + "." + value.name;
+            }
+        }
+    }
+
+    @Override
+    public String visit(Nothing node) {
+        return "";
+    }
+
+    @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();
+    }
+
+    @Override
+    public String visit(Return node) {
+        return "return " + node.getExpression().accept(this) + ";";
+    }
+
+    @Override
+    public String visit(Throw node) {
+        return "throw " + node.getThowable().accept(this) + ";";
+    }
+
+    @Override
+    public String visit(Statement node) {
+        return node.getChild(0).accept(this)+ (node.isSemicolonNeeded() ? ";" : "");
+    }
+
+    @Override
+    public String visit(StaticConstructorDefinition node) {
+        IRNode body = node.getChild(0);
+        return "static {\n"
+                + (body != null ? body.accept(this): "")
+                + PrintingUtils.align(node.getLevel()) + "}";
+    }
+
+    @Override
+    public String visit(StaticMemberVariable node) {
+        IRNode klass = node.getKlass();
+        VariableInfo value = node.get();
+        if (klass.equals(value.klass)) {
+            return value.name;
+        } else {
+            return value.klass.getName() + "." + value.name;
+        }
+    }
+
+    @Override
+    public String visit(Switch node) {
+        int level = node.getLevel();
+        int caseBlockIdx = node.getCaseBlockIndex();
+        String cases = "";
+        for (int i = 0; i < caseBlockIdx - 1; ++i) {
+            cases += PrintingUtils.align(level + 1);
+            if (node.getChild(i + 1) != null) {
+                cases += "case " + node.getChild(i + 1).accept(this)+ ":\n";
+            } else {
+                cases += "default:\n";
+            }
+
+            cases += node.getChild(i + caseBlockIdx).accept(this)+ "\n";
+        }
+        return "switch (" + node.getChild(0).accept(this)+ ")\n"
+               + PrintingUtils.align(level) + "{\n"
+               + cases
+               + PrintingUtils.align(level) + "}";
+    }
+
+    @Override
+    public String visit(TernaryOperator node) {
+        IRNode conditionalExp = node.getChild(TernaryOperator.TernaryPart.CONDITION.ordinal());
+        IRNode leftExp = node.getChild(TernaryOperator.TernaryPart.TRUE.ordinal());
+        IRNode rightExp = node.getChild(TernaryOperator.TernaryPart.FALSE.ordinal());
+        if (Objects.isNull(conditionalExp) || Objects.isNull(leftExp) || Objects.isNull(rightExp)) {
+            return "null";
+        }
+        return expressionToJavaCode(node, conditionalExp, Operator.Order.RIGHT) + " ? "
+                + expressionToJavaCode(node, leftExp, Operator.Order.RIGHT) + " : "
+                + expressionToJavaCode(node, rightExp, Operator.Order.RIGHT);
+    }
+
+    @Override
+    public String visit(Type node) {
+        return node.getName();
+    }
+
+    @Override
+    public String visit(TypeArray node) {
+        String r = node.getType().accept(this);
+        for (int i = 0; i < node.getDimensions(); i++) {
+            r += "[]";
+        }
+        return r;
+    }
+
+    @Override
+    public String visit(UnaryOperator node) {
+        IRNode exp = node.getChild(0);
+        if (node.isPrefix()) {
+            return node.getOperatorText() + (exp instanceof Operator ? " " : "")
+                    + expressionToJavaCode(node, exp, Operator.Order.LEFT);
+        } else {
+            return expressionToJavaCode(node, exp, Operator.Order.RIGHT)
+                    + (exp instanceof Operator ? " " : "") + node.getOperatorText();
+        }
+    }
+
+    @Override
+    public String visit(VariableDeclaration node) {
+        VariableInfo vi = node.getVariableInfo();
+        return attributes(vi) + vi.type.accept(this)+ " " + vi.name;
+    }
+
+    @Override
+    public String visit(VariableDeclarationBlock node) {
+        StringBuilder code = new StringBuilder();
+        for (IRNode i : node.getChildren()) {
+            code.append(PrintingUtils.align(node.getLevel()))
+                .append(i.accept(this))
+                .append(addComplexityInfo(i))
+                .append("\n");
+        }
+        return code.toString();
+    }
+
+    @Override
+    public String visit(While node) {
+        IRNode header = node.getChild(While.WhilePart.HEADER.ordinal());
+        IRNode body1 = node.getChild(While.WhilePart.BODY1.ordinal());
+        IRNode body2 = node.getChild(While.WhilePart.BODY2.ordinal());
+        IRNode body3 = node.getChild(While.WhilePart.BODY3.ordinal());
+        int level = node.getLevel();
+        Loop loop = node.getLoop();
+        return loop.initialization.accept(this)+ "\n"
+                + header.accept(this)
+                + PrintingUtils.align(level) + "while (" + loop.condition.accept(this)+ ")\n"
+                + PrintingUtils.align(level) + "{\n"
+                + body1.accept(this)
+                + PrintingUtils.align(level + 1) + loop.manipulator.accept(this)+ ";\n"
+                + body2.accept(this)
+                + body3.accept(this)
+                + PrintingUtils.align(level) + "}";
+    }
+
+    @Override
+    public String visit(CatchBlock node) {
+        StringBuilder result = new StringBuilder();
+        int level = node.getLevel();
+        result.append(PrintingUtils.align(level)).append("catch(");
+        result.append(node.throwables.get(0).accept(this));
+        for (int i = 1; i < node.throwables.size(); i++) {
+            result.append(" | ").append(node.throwables.get(i).accept(this));
+        }
+        result.append(" ex) {\n");
+        result.append(node.getChild(0).accept(this));
+        result.append(PrintingUtils.align(level)).append("}\n");
+        return result.toString();
+    }
+
+    @Override
+    public String visit(TryCatchBlock node) {
+        StringBuilder result = new StringBuilder();
+        List<? extends IRNode> childs = node.getChildren();
+        IRNode body = childs.get(0);
+        IRNode finallyBody = childs.get(1);
+        int level = node.getLevel();
+        result.append("try {\n")
+                .append(body.accept(this)).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");
+        }
+        return result.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/testlibrary/jittester/src/jdk/test/lib/jittester/visitors/Visitor.java	Thu Nov 26 02:09:46 2015 +0100
@@ -0,0 +1,130 @@
+/*
+ * 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.test.lib.jittester.visitors;
+
+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.CatchBlock;
+import jdk.test.lib.jittester.Continue;
+import jdk.test.lib.jittester.Declaration;
+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.LogicOperator;
+import jdk.test.lib.jittester.NonStaticMemberVariable;
+import jdk.test.lib.jittester.Nothing;
+import jdk.test.lib.jittester.PrintVariables;
+import jdk.test.lib.jittester.Statement;
+import jdk.test.lib.jittester.StaticMemberVariable;
+import jdk.test.lib.jittester.Switch;
+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.UnaryOperator;
+import jdk.test.lib.jittester.VariableDeclaration;
+import jdk.test.lib.jittester.VariableDeclarationBlock;
+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.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.TypeArray;
+
+public interface Visitor<T> {
+    T visit(ArgumentDeclaration node);
+    T visit(ArrayCreation node);
+    T visit(ArrayElement node);
+    T visit(ArrayExtraction node);
+    T visit(BinaryOperator node);
+    T visit(Block node);
+    T visit(Break node);
+    T visit(CastOperator node);
+    T visit(ClassDefinitionBlock node);
+    T visit(ConstructorDefinition node);
+    T visit(ConstructorDefinitionBlock node);
+    T visit(Continue node);
+    T visit(CounterInitializer node);
+    T visit(CounterManipulator node);
+    T visit(Declaration node);
+    T visit(DoWhile node);
+    T visit(For node);
+    T visit(Function node);
+    T visit(FunctionDeclaration node);
+    T visit(FunctionDeclarationBlock node);
+    T visit(FunctionDefinition node);
+    T visit(FunctionDefinitionBlock node);
+    T visit(FunctionRedefinition node);
+    T visit(FunctionRedefinitionBlock node);
+    T visit(If node);
+    T visit(Initialization node);
+    T visit(Interface node);
+    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);
+    T visit(Nothing node);
+    T visit(PrintVariables node);
+    T visit(Return node);
+    T visit(Throw node);
+    T visit(Statement node);
+    T visit(StaticConstructorDefinition node);
+    T visit(StaticMemberVariable node);
+    T visit(Switch node);
+    T visit(TernaryOperator node);
+    T visit(Type node);
+    T visit(TypeArray node);
+    T visit(UnaryOperator node);
+    T visit(VariableDeclaration node);
+    T visit(VariableDeclarationBlock node);
+    T visit(While node);
+    T visit(CatchBlock node);
+    T visit(TryCatchBlock node);
+}