changeset 34227:001483ee066c

Merge
author twisti
date Thu, 26 Nov 2015 02:09:46 +0100
parents db9dea22fbfc 773eded97d0d
children 035e020c8c0d 54f9242e3f81
files
diffstat 167 files changed, 14873 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- 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.ad