8066153: JEP-JDK-8046155: Test task: cover existing

Tests for CompilerCommand and CompilerControl's directives

Reviewed-by: kvn
This commit is contained in:
Pavel Punegov 2015-10-20 21:09:57 +03:00
parent 5a5faf94bf
commit 0ea5332014
35 changed files with 2787 additions and 1 deletions

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests CompileCommand=compileonly
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build CompileOnlyTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.commandfile.CompileOnlyTest
*/
package compiler.compilercontrol.commandfile;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class CompileOnlyTest {
public static void main(String[] args) {
new SingleCommand(Command.COMPILEONLY, Scenario.Type.FILE).test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests CompileCommand=exclude
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build ExcludeTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.commands.ExcludeTest
*/
package compiler.compilercontrol.commandfile;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class ExcludeTest {
public static void main(String[] args) {
new SingleCommand(Command.EXCLUDE, Scenario.Type.FILE).test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests CompileCommand=log
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build LogTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.commandfile.LogTest
*/
package compiler.compilercontrol.commandfile;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class LogTest {
public static void main(String[] args) {
new SingleCommand(Command.LOG, Scenario.Type.FILE).test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests CompileCommand=print
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build PrintTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.commandfile.PrintTest
*/
package compiler.compilercontrol.commandfile;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class PrintTest {
public static void main(String[] args) {
new SingleCommand(Command.PRINT, Scenario.Type.FILE).test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests CompileCommand=compileonly
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build CompileOnlyTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.commands.CompileOnlyTest
*/
package compiler.compilercontrol.commands;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class CompileOnlyTest {
public static void main(String[] args) {
new SingleCommand(Command.COMPILEONLY, Scenario.Type.OPTION).test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests CompileCommand=exclude
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build ExcludeTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.commands.ExcludeTest
*/
package compiler.compilercontrol.commands;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class ExcludeTest {
public static void main(String[] args) {
new SingleCommand(Command.EXCLUDE, Scenario.Type.OPTION).test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests CompileCommand=log
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build LogTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.commands.LogTest
*/
package compiler.compilercontrol.commands;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class LogTest {
public static void main(String[] args) {
new SingleCommand(Command.LOG, Scenario.Type.OPTION).test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests CompileCommand=print
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build PrintTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.commands.PrintTest
*/
package compiler.compilercontrol.commands;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class PrintTest {
public static void main(String[] args) {
new SingleCommand(Command.PRINT, Scenario.Type.OPTION).test();
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8137167
* @summary Tests directives to be able to compile only specified methods
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build CompileOnlyTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.directives.CompileOnlyTest
*/
package compiler.compilercontrol.directives;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class CompileOnlyTest {
public static void main(String[] args) {
new SingleCommand(Command.COMPILEONLY, Scenario.Type.DIRECTIVE)
.test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests directives to be able to exclude methods from compilation
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build ExcludeTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.directives.ExcludeTest
*/
package compiler.compilercontrol.directives;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class ExcludeTest {
public static void main(String[] args) {
new SingleCommand(Command.EXCLUDE, Scenario.Type.DIRECTIVE).test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests directives to be able to turn on LogCompilation
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build LogTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.directives.LogTest
*/
package compiler.compilercontrol.directives;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class LogTest {
public static void main(String[] args) {
new SingleCommand(Command.LOG, Scenario.Type.DIRECTIVE).test();
}
}

View File

@ -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.
*/
/*
* @test
* @bug 8137167
* @summary Tests directives to be able to turn on print_assembly
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build PrintTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm compiler.compilercontrol.directives.PrintTest
*/
package compiler.compilercontrol.directives;
import compiler.compilercontrol.share.SingleCommand;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.Scenario;
public class PrintTest {
public static void main(String[] args) {
new SingleCommand(Command.PRINT, Scenario.Type.DIRECTIVE).test();
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8137167
* @summary Randomly generates commands with random types
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build RandomCommandsTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm/timeout=600 compiler.compilercontrol.mixed.RandomCommandsTest
*/
package compiler.compilercontrol.mixed;
import compiler.compilercontrol.share.MultiCommand;
public class RandomCommandsTest {
public static void main(String[] args) {
MultiCommand.generateRandomTest(false).test();
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8137167
* @summary Randomly generates valid commands with random types
* @library /testlibrary /../../test/lib /compiler/testlibrary ../share /
* @build RandomValidCommandsTest pool.sub.* pool.subpack.* sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils compiler.compilercontrol.share.actions.*
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm/timeout=600 compiler.compilercontrol.mixed.RandomValidCommandsTest
*/
package compiler.compilercontrol.mixed;
import compiler.compilercontrol.share.MultiCommand;
public class RandomValidCommandsTest {
public static void main(String[] args) {
MultiCommand.generateRandomTest(true).test();
}
}

View File

@ -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 compiler.compilercontrol.share;
import compiler.compilercontrol.share.method.MethodDescriptor;
import compiler.compilercontrol.share.method.MethodGenerator;
import jdk.test.lib.Pair;
import pool.PoolHelper;
import java.lang.reflect.Executable;
import java.util.List;
import java.util.concurrent.Callable;
public abstract class AbstractTestBase {
protected static final MethodGenerator METHOD_GEN = new MethodGenerator();
protected static final int ATTEMPTS = 25;
protected static final List<Pair<Executable, Callable<?>>> METHODS
= new PoolHelper().getAllMethods(PoolHelper.METHOD_FILTER);
public abstract void test();
/**
* Generate random valid method descriptor
*
* @param exec method to make descriptor for
* @return a valid {@link MethodDescriptor#isValid()} descriptor instance
*/
public static MethodDescriptor getValidMethodDescriptor(Executable exec) {
MethodDescriptor md = METHOD_GEN.generateRandomDescriptor(exec);
for (int i = 0; !md.isValid() && i < ATTEMPTS; i++) {
md = METHOD_GEN.generateRandomDescriptor(exec);
}
if (!md.isValid()) {
System.out.println("WARN: Using predefined pattern");
md = MethodGenerator.commandDescriptor(exec);
}
return md;
}
}

View File

@ -0,0 +1,189 @@
/*
* 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 compiler.compilercontrol.share;
import java.io.FileNotFoundException;
import java.io.PrintStream;
import java.util.Objects;
import java.util.Stack;
/**
* Simple JSON file writer
*/
public class JSONFile implements AutoCloseable {
private final Stack<Element> stack;
private final String fileName;
private final PrintStream out;
private int spaces;
/**
* JSON element
*/
public enum Element {
OBJECT,
ARRAY,
PAIR,
VALUE
}
/**
* Constructor. Creates file with default name
*/
public JSONFile() {
this("directives_file.json");
}
/**
* Constructor
*
* @param fileName file name
*/
public JSONFile(String fileName) {
this.spaces = 0;
this.stack = new Stack<>();
this.fileName = fileName;
try {
out = new PrintStream(fileName);
} catch (FileNotFoundException e) {
throw new Error("TESTBUG: can't open/create file " + fileName, e);
}
}
/**
* Gets file name
*
* @return file name string
*/
public String getFileName() {
return fileName;
}
/**
* Gets current JSON element in the file.
* The element is a current {@linkplain Element}
* that was written into a file.
*
* @return the type of the current element,
* or null if there are nothing written
*/
public Element getElement() {
if (stack.empty()) {
return null;
}
return stack.peek();
}
/**
* Writes given type with a value to file.
* Note that only PAIR and VALUE types accept a single value parameter.
* OBJECT and ARRAY do not have a value
*
* @param element JSON element type
* @param value element's value
* @return this file instance
*/
public JSONFile write(Element element, String... value) {
if (value.length > 1) {
throw new Error("TESTBUG: Unexpected value length: "
+ value.length);
}
if (!stack.empty()) {
if (stack.peek() == Element.VALUE) {
out.print(", ");
stack.pop();
}
}
switch (element) {
case OBJECT:
out.print("{");
spaces++;
stack.push(Element.VALUE);
break;
case ARRAY:
out.print("[");
stack.push(Element.VALUE);
break;
case PAIR:
fillSpaces();
Objects.requireNonNull(value, "TESTBUG: " + element
+ "requires a value to be set");
out.print(value[0] + ": ");
break;
case VALUE:
Objects.requireNonNull(value, "TESTBUG: " + element
+ "requires a value to be set");
out.print(value[0]);
break;
}
stack.push(element);
return this;
}
private void fillSpaces() {
out.println();
for (int i = 0; i < spaces; i++) {
// Fill with spaces to be more readable
out.print(" ");
}
}
/**
* Ends current object or array of {@linkplain Element}
*
* @return this file instance
*/
public JSONFile end() {
if (!stack.empty()) {
Element prev = stack.pop();
while (prev != Element.OBJECT && prev != Element.ARRAY
&& !stack.empty()) {
prev = stack.pop();
}
switch (prev) {
case OBJECT:
spaces--;
fillSpaces();
out.print("}");
break;
case ARRAY:
out.print("]");
break;
default:
throw new Error("TESTBUG: Incorrect end. " +
"Wrong type found: " + prev);
}
} else {
throw new Error("TESTBUG: Incorrect end. Empty stack");
}
return this;
}
/**
* Closes this file
*/
@Override
public void close() {
out.close();
}
}

View File

@ -0,0 +1,82 @@
/*
* 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 compiler.compilercontrol.share;
import compiler.compilercontrol.share.method.MethodDescriptor;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.CommandGenerator;
import compiler.compilercontrol.share.scenario.CompileCommand;
import compiler.compilercontrol.share.scenario.Scenario;
import jdk.test.lib.Utils;
import java.lang.reflect.Executable;
import java.util.ArrayList;
import java.util.List;
public class MultiCommand extends AbstractTestBase {
private final List<CompileCommand> testCases;
public MultiCommand(List<CompileCommand> testCases) {
this.testCases = testCases;
}
/**
* Generates a test containing multiple random commands
*
* @param validOnly shows that all commands should be valid
* @return test instance to run
*/
public static AbstractTestBase generateRandomTest(boolean validOnly) {
CommandGenerator cmdGen = new CommandGenerator();
List<Command> commands = cmdGen.generateCommands();
List<CompileCommand> testCases = new ArrayList<>();
for (Command cmd : commands) {
if (validOnly && cmd == Command.NONEXISTENT) {
// skip invalid command
continue;
}
Executable exec = Utils.getRandomElement(METHODS).first;
MethodDescriptor md;
if (validOnly) {
md = AbstractTestBase.getValidMethodDescriptor(exec);
} else {
md = AbstractTestBase.METHOD_GEN.generateRandomDescriptor(exec);
}
CompileCommand cc = cmdGen.generateCompileCommand(cmd, md, null);
testCases.add(cc);
}
return new MultiCommand(testCases);
}
@Override
public void test() {
Scenario.Builder builder = Scenario.getBuilder();
for (CompileCommand cc : testCases) {
cc.print();
builder.add(cc);
}
Scenario scenario = builder.build();
scenario.execute();
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.compilercontrol.share;
import compiler.compilercontrol.share.method.MethodDescriptor;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.CommandGenerator;
import compiler.compilercontrol.share.scenario.CompileCommand;
import compiler.compilercontrol.share.scenario.Scenario;
import jdk.test.lib.Utils;
import java.lang.reflect.Executable;
public class SingleCommand extends AbstractTestBase {
private final Command command;
private final Scenario.Type type;
public SingleCommand(Command command, Scenario.Type type) {
this.command = command;
this.type = type;
}
@Override
public void test() {
Scenario.Builder builder = Scenario.getBuilder();
Executable exec = Utils.getRandomElement(METHODS).first;
MethodDescriptor md = getValidMethodDescriptor(exec);
CommandGenerator cmdGen = new CommandGenerator();
CompileCommand compileCommand = cmdGen.generateCompileCommand(command,
md, type);
compileCommand.print();
builder.add(compileCommand);
Scenario scenario = builder.build();
scenario.execute();
}
}

View File

@ -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 compiler.compilercontrol.share.actions;
import compiler.compilercontrol.share.scenario.State;
import jdk.test.lib.Pair;
import jdk.test.lib.ProcessTools;
import pool.PoolHelper;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.IOException;
import java.lang.reflect.Executable;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
public class BaseAction {
private static final List<Pair<Executable, Callable<?>>> METHODS;
private static final Map<String, Executable> METHODS_NAMES;
static {
METHODS = new PoolHelper().getAllMethods();
METHODS_NAMES = METHODS.stream().collect(Collectors.toMap(
pair -> pair.first.toGenericString(),
pair -> pair.first));
}
public static void main(String[] args) {
if (args.length < 1) {
throw new Error("TESTBUG: requires port as parameter: "
+ Arrays.toString(args));
}
int pid;
try {
pid = ProcessTools.getProcessId();
} catch (Exception e) {
throw new Error("Could not determine own pid", e);
}
int port = Integer.parseInt(args[0]);
System.out.println("INFO: Client connection port = " + port);
List<String> lines;
try (
Socket socket = new Socket(InetAddress.getLocalHost(), port);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream()))) {
// send own pid to execute jcmd if needed
out.println(String.valueOf(pid));
out.flush();
lines = in.lines().collect(Collectors.toList());
} catch (IOException e) {
throw new Error("Error on performing network operation", e);
}
check(decodeMap(lines));
}
private static Map<Executable, State> decodeMap(List<String> lines) {
if (lines == null || lines.size() == 0) {
throw new Error("TESTBUG: unexpected lines list");
}
Map<Executable, State> stateMap = new HashMap<>();
int startIndex = 0;
ListIterator<String> iterator = lines.listIterator();
while (iterator.hasNext()) {
int index = iterator.nextIndex();
String next = iterator.next();
switch (next) {
case "{" :
startIndex = index;
break;
case "}" :
// method name goes after {
Executable executable = METHODS_NAMES.get(lines.get(
++startIndex));
// state description starts after method
State state = State.fromString(lines.subList(++startIndex,
index).toArray(new String[index - startIndex]));
stateMap.put(executable, state);
break;
}
}
return stateMap;
}
protected static void check(Map<Executable, State> methodStates) {
// Check each method from the pool
METHODS.forEach(pair -> {
Executable x = pair.first;
CompileAction.checkCompiled(x, methodStates.get(x));
});
}
}

View File

@ -0,0 +1,108 @@
/*
* 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 compiler.compilercontrol.share.actions;
import compiler.compilercontrol.share.scenario.State;
import compiler.testlibrary.CompilerUtils;
import jdk.test.lib.Asserts;
import jdk.test.lib.Pair;
import jdk.test.lib.Utils;
import pool.PoolHelper;
import sun.hotspot.WhiteBox;
import java.lang.reflect.Executable;
import java.util.List;
import java.util.concurrent.Callable;
public class CompileAction {
private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
private static final int[] COMP_LEVELS;
private static final List<Pair<Executable, Callable<?>>> METHODS
= new PoolHelper().getAllMethods();
private static final int EXEC_AMOUNT = 100;
static {
COMP_LEVELS = CompilerUtils.getAvailableCompilationLevels();
if (COMP_LEVELS.length == 0) {
throw new Error("TESTBUG: test requires JIT " +
"compiler to be available");
}
}
/**
* Checks executable if it could be compiled
*
* @param executable given executable to check
* @param state method compilation state
*/
public static void checkCompiled(Executable executable,
State state) {
int first = COMP_LEVELS[0];
if (first < 4) {
checkCompilation(executable, first, state.isC1Compilable());
}
int last = COMP_LEVELS[COMP_LEVELS.length - 1];
if (last == 4) {
checkCompilation(executable, last, state.isC2Compilable());
}
}
private static void checkCompilation(Executable executable,
int level,
boolean expectedCompiled) {
execute(executable);
WHITE_BOX.enqueueMethodForCompilation(executable, level);
Utils.waitForCondition(
() -> {
execute(executable);
return !WHITE_BOX.isMethodQueuedForCompilation(executable);
}, 100L);
execute(executable);
boolean isCompiled = WHITE_BOX.isMethodCompiled(executable);
Asserts.assertEQ(isCompiled, expectedCompiled,
String.format("FAILED: method %s compiled: %b, but should: %b"
+ " on required level: %d", executable, isCompiled,
expectedCompiled, level));
}
private static void execute(Executable executable) {
Callable<?> callable = getCallableFor(executable);
try {
for (int i = 0; i < EXEC_AMOUNT; i++) {
callable.call();
}
} catch (Exception e) {
throw new Error("Got exception during execution", e);
}
}
private static Callable<?> getCallableFor(Executable executable) {
for (Pair<Executable, Callable<?>> pair : METHODS) {
if (pair.first == executable) {
return pair.second;
}
}
throw new Error("TESTBUG: wrong executable: " + executable);
}
}

View File

@ -123,6 +123,23 @@ public class MethodGenerator {
return md;
}
/**
* Method descriptor that matches any method. Its full signature is *.*
*
* @param executable executable used to generate descriptor
* @return MethodDescriptor instance
*/
public static MethodDescriptor anyMatchDescriptor(Executable executable) {
MethodDescriptor md = new MethodDescriptor(executable);
Combination<PatternType> patterns = new Combination<>(PatternType.ANY,
PatternType.ANY, PatternType.ANY);
md.aClass.setSeparator(Separator.SLASH);
md.aMethod.setSeparator(Separator.DOT);
md.aSignature.setSeparator(Separator.NONE);
md.setPatterns(patterns);
return md;
}
/**
* Generates a list of method patterns from the pool of methods
*

View File

@ -29,6 +29,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.regex.Pattern;
/**
* This class represents a signature of the method
@ -66,7 +67,8 @@ public class SignatureType extends MethodElementType {
if (element.isEmpty()) {
setPattern(MethodDescriptor.PatternType.ANY);
} else {
super.setElement(element);
this.element = element;
this.regexp = element;
}
}
@ -148,4 +150,12 @@ public class SignatureType extends MethodElementType {
+ patternType);
}
}
@Override
public String getRegexp() {
if ("\\(.*\\).*".equals(regexp)) {
return regexp;
}
return Pattern.quote(regexp);
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.compilercontrol.share.processors;
import compiler.compilercontrol.share.method.MethodDescriptor;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.CompileCommand;
import jdk.test.lib.OutputAnalyzer;
import java.util.List;
import java.util.function.Consumer;
/**
* Checks that output contains a string with commands and full method pattern
*/
public class CommandProcessor implements Consumer<OutputAnalyzer> {
protected final List<CompileCommand> commands;
public CommandProcessor(List<CompileCommand> commands) {
this.commands = commands;
}
@Override
public void accept(OutputAnalyzer outputAnalyzer) {
for (CompileCommand command : commands) {
MethodDescriptor methodDescriptor = command.methodDescriptor;
if (methodDescriptor.isValid()) {
Command cmd = command.command;
String method = methodDescriptor.getCanonicalString();
outputAnalyzer.shouldContain("CompileCommand: " + cmd.name
+ " " + method);
outputAnalyzer.shouldNotContain("CompileCommand: An error "
+ "occurred during parsing");
} else {
outputAnalyzer.shouldMatch("(CompileCommand: )"
+ "(unrecognized command)|(Bad pattern)|"
+ "(An error occurred during parsing)");
}
}
}
}

View File

@ -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 compiler.compilercontrol.share.processors;
import compiler.compilercontrol.share.method.MethodDescriptor;
import compiler.compilercontrol.share.method.MethodGenerator;
import compiler.compilercontrol.share.scenario.State;
import jdk.test.lib.Asserts;
import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.Pair;
import pool.PoolHelper;
import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Executable;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Log compilation file processor
*/
public class LogProcessor implements Consumer<OutputAnalyzer> {
public static final String LOG_FILE = "compilation.log";
private static final String TASK_ELEMENT = "<task [^>]*>";
private static final String TASK_DONE_ELEMENT = "<task_done [^>]*>";
private static final String TASK_END_ELEMENT = "</task>";
private static final String ANY_ELEMENT = "<[^>]*>";
private static final Pattern METHOD_PATTERN = Pattern.compile(
"method='([^']+)'");
private final List<String> loggedMethods;
private final List<String> testMethods;
private Scanner scanner = null;
public LogProcessor(Map<Executable, State> states) {
loggedMethods = states.keySet().stream()
.filter(x -> states.get(x).isLog())
.map(MethodGenerator::logDescriptor)
.map(MethodDescriptor::getString)
.collect(Collectors.toList());
testMethods = new PoolHelper().getAllMethods()
.stream()
.map(pair -> pair.first)
.map(MethodGenerator::logDescriptor)
.map(MethodDescriptor::getString)
.collect(Collectors.toList());
}
@Override
public void accept(OutputAnalyzer outputAnalyzer) {
if (loggedMethods.isEmpty()) {
return;
}
getScanner();
matchTasks();
}
/*
* Gets scanner for log file of the test case
*/
private Scanner getScanner() {
File logFile = new File(LOG_FILE);
try {
scanner = new Scanner(logFile);
} catch (FileNotFoundException e) {
throw new Error("TESTBUG: file not found: " + logFile, e);
}
return scanner;
}
/*
* Parses for &lt;task method='java.lang.String indexOf (I)I' &gt;
* and finds if there is a compilation log for this task
*/
private void matchTasks() {
String task = scanner.findWithinHorizon(TASK_ELEMENT, 0);
while (task != null) {
String element = scanner.findWithinHorizon(ANY_ELEMENT, 0);
if (Pattern.matches(TASK_DONE_ELEMENT, element)
|| Pattern.matches(TASK_END_ELEMENT, element)) {
/* If there is nothing between <task> and </task>
except <task done /> then compilation log is empty */
Asserts.assertTrue(matchMethod(task), "Compilation log "
+ "expected. Met: " + element);
}
task = scanner.findWithinHorizon(TASK_ELEMENT, 0);
}
}
// Matches given string to regular expression
private boolean matchMethod(String input) {
Matcher matcher = METHOD_PATTERN.matcher(input);
Asserts.assertTrue(matcher.find(), "Wrong matcher or input");
// Get method and normalize it
String method = normalize(matcher.group(1));
// Check that this method matches regexp
return loggedMethods.contains(method) || !testMethods.contains(method);
}
// Normalize given signature to conform regular expression used in tests
private String normalize(String method) {
return method.replaceAll("\\.", "/") // replace dots in a class string
.replaceFirst(" ", ".") // replace space between class and method
.replaceFirst(" ", "") // remove space between method and signature
.replace("&lt;", "<")
.replace("&gt;", ">");
}
}

View File

@ -0,0 +1,115 @@
/*
* 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 compiler.compilercontrol.share.processors;
import com.sun.management.HotSpotDiagnosticMXBean;
import compiler.compilercontrol.share.method.MethodDescriptor;
import compiler.compilercontrol.share.method.MethodGenerator;
import compiler.compilercontrol.share.scenario.State;
import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.Pair;
import pool.PoolHelper;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Executable;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Process output to find compiled methods assemblies printed by print command
*/
public class PrintProcessor implements Consumer<OutputAnalyzer> {
/**
* Compiled method string pattern.
* Capturing groups are
* 1. Compiler used to compile this method
* 2. Time stamp
* 3. Compile ID
* 4. Method attributes
* 5. Compilation level
* 6. Method name
*/
private static final Pattern COMPILED_METHOD
= Pattern.compile("Compiled method (?<compiler>\\(.*\\))[ ]+"
+ "(?<time>[0-9]+)[ ]+(?<id>[0-9]+) (?<attr>[ !%sbn]{6})"
+ "(?<level>[0-9]+)[ ]+(?<name>[^ ]+).*");
private final List<String> printMethods;
private final List<String> testMethods;
public PrintProcessor(Map<Executable, State> states) {
printMethods = states.keySet().stream()
.filter(x -> states.get(x).isPrintAssembly())
.map(MethodGenerator::logDescriptor)
.map(MethodDescriptor::getString)
.map(s -> s.replaceFirst("\\(.*", "")) // remove signature
.collect(Collectors.toList());
testMethods = new PoolHelper().getAllMethods()
.stream()
.map(pair -> pair.first)
.map(MethodGenerator::logDescriptor)
.map(MethodDescriptor::getString)
.map(s -> s.replaceFirst("\\(.*", "")) // remove signature
.collect(Collectors.toList());
}
@Override
public void accept(OutputAnalyzer outputAnalyzer) {
boolean wizardMode = false;
try {
wizardMode = Boolean.parseBoolean(ManagementFactory
.getPlatformMXBean(HotSpotDiagnosticMXBean.class)
.getVMOption("WizardMode").getValue());
} catch (IllegalArgumentException e) {
// ignore exception because WizardMode exists in debug only builds
}
if (wizardMode) {
System.out.println("SKIP: WizardMode's output are not supported");
return;
}
for (String line : outputAnalyzer.asLines()) {
Matcher matcher = COMPILED_METHOD.matcher(line);
if (matcher.matches()) {
String method = normalize(matcher.group("name"));
if (!printMethods.contains(normalize(method))
&& testMethods.contains(method)) {
System.out.println(outputAnalyzer.getOutput());
throw new AssertionError("FAILED: wrong method "
+ "was printed: " + method + " LINE: " + line);
}
}
}
}
// Normalize given signature to conform regular expression used in tests
private String normalize(String method) {
return method.replaceAll("\\.", "/") // replace dots in a class string
.replaceFirst("::", ".") // replace :: between class and method
.replace("&lt;", "<")
.replace("&gt;", ">");
}
}

View File

@ -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 compiler.compilercontrol.share.processors;
import compiler.compilercontrol.share.method.MethodDescriptor;
import compiler.compilercontrol.share.scenario.Command;
import compiler.compilercontrol.share.scenario.CompileCommand;
import jdk.test.lib.OutputAnalyzer;
import java.util.List;
import java.util.function.Consumer;
public class QuietProcessor implements Consumer<OutputAnalyzer> {
private final List<CompileCommand> commands;
public QuietProcessor(List<CompileCommand> compileCommands) {
commands = compileCommands;
}
@Override
public void accept(OutputAnalyzer outputAnalyzer) {
for (CompileCommand command : commands) {
MethodDescriptor methodDescriptor = command.methodDescriptor;
if (methodDescriptor.isValid()) {
Command cmd = command.command;
String method = methodDescriptor.getCanonicalString();
outputAnalyzer.shouldNotContain("CompileCommand: "
+ cmd.name + " " + method);
outputAnalyzer.shouldNotContain("CompileCommand: An error "
+ "occurred during parsing");
} else {
outputAnalyzer.shouldMatch("(CompileCommand: )"
+ "(unrecognized command)|(Bad pattern)|"
+ "(An error occurred during parsing)");
}
}
}
}

View File

@ -0,0 +1,95 @@
/*
* 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 compiler.compilercontrol.share.scenario;
import compiler.compilercontrol.share.method.MethodDescriptor;
import jdk.test.lib.Pair;
import pool.PoolHelper;
import java.lang.reflect.Executable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* An abstract class that builds states by applying
* commands one after another
*/
public abstract class AbstractCommandBuilder
implements StateBuilder<CompileCommand> {
protected static final List<Pair<Executable, Callable<?>>> METHODS
= new PoolHelper().getAllMethods();
protected final List<CompileCommand> compileCommands = new ArrayList<>();
@Override
public void add(CompileCommand command) {
compileCommands.add(command);
}
@Override
public Map<Executable, State> getStates() {
Map<Executable, State> states = new HashMap<>();
for (CompileCommand compileCommand : compileCommands) {
if (compileCommand.isValid()) {
CompileCommand cc = new CompileCommand(compileCommand.command,
compileCommand.methodDescriptor,
/* CompileCommand option and file doesn't support
compiler setting */
null,
compileCommand.type);
MethodDescriptor md = cc.methodDescriptor;
for (Pair<Executable, Callable<?>> pair: METHODS) {
Executable exec = pair.first;
State state = states.getOrDefault(exec, new State());
MethodDescriptor execDesc = new MethodDescriptor(exec);
// if executable matches regex then apply the state
if (execDesc.getCanonicalString().matches(md.getRegexp())) {
state.apply(cc);
} else {
if (cc.command == Command.COMPILEONLY) {
state.setC1Compilable(false);
state.setC2Compilable(false);
}
}
states.put(exec, state);
}
}
}
return states;
}
@Override
public List<CompileCommand> getCompileCommands() {
return Collections.unmodifiableList(compileCommands);
}
@Override
public boolean isValid() {
// CompileCommand ignores invalid items
return true;
}
}

View File

@ -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 compiler.compilercontrol.share.scenario;
import compiler.compilercontrol.share.processors.LogProcessor;
import java.util.Arrays;
/**
* Represents a CompileCommand command set
*/
public enum Command {
COMPILEONLY("compileonly", ".*", "-Xbatch"),
EXCLUDE("exclude", "", "-Xbatch"),
INLINE("inline", ".*"),
DONTINLINE("dontinline", ""),
LOG("log", "", "-XX:+UnlockDiagnosticVMOptions",
"-XX:+LogCompilation", "-XX:LogFile=" + LogProcessor.LOG_FILE),
PRINT("print", ""),
QUIET("quiet", ""),
NONEXISTENT("nonexistent", ""); // wrong command for a negative case
/**
* Command name
*/
public final String name;
/**
* Base regular expression
*/
public final String regex;
/**
* Additional VM options for this command
*/
public final String[] vmOpts;
private Command(String name, String regex, String... vmOptions) {
this.name = name;
this.regex = regex;
String[] wbOpts = new String[] { "-Xbootclasspath/a:.",
"-XX:+UnlockDiagnosticVMOptions", "-XX:+WhiteBoxAPI" };
int length = (vmOptions != null) ? vmOptions.length : 0;
this.vmOpts = Arrays.copyOf(wbOpts, wbOpts.length + length);
if (vmOptions != null) {
System.arraycopy(vmOptions, 0, vmOpts, wbOpts.length, length);
}
}
}

View File

@ -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 compiler.compilercontrol.share.scenario;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
/**
* Creates CompileCommandFile from the given array of commands
*/
public class CommandFileBuilder extends AbstractCommandBuilder {
private final String fileName;
public CommandFileBuilder(String fileName) {
this.fileName = fileName;
}
@Override
public List<String> getOptions() {
// Create CommandFile
try (PrintWriter pw = new PrintWriter(fileName)) {
compileCommands.stream()
.map(cc -> cc.command.name + " "
+ cc.methodDescriptor.getString())
.forEach(pw::println);
if (pw.checkError()) {
throw new Error("TESTBUG: write error");
}
} catch (IOException e) {
throw new Error("TESTBUG: can't write a file", e);
}
List<String> opt = new ArrayList<>();
opt.add("-XX:CompileCommandFile=" + fileName);
return opt;
}
}

View File

@ -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 compiler.compilercontrol.share.scenario;
import compiler.compilercontrol.share.method.MethodDescriptor;
import jdk.test.lib.Utils;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Generates random commands
*/
public class CommandGenerator {
private static final int MAX_COMMANDS = Integer.getInteger(
"compiler.compilercontrol.share.scenario.CommandGenerator.commands",
100);
private static final Random RANDOM = Utils.getRandomInstance();
/**
* Generates random command
*
* @return command
*/
public Command generateCommand() {
return Utils.getRandomElement(Command.values());
}
/**
* Generates random number of random command
*
* @return a list of random commands
*/
public List<Command> generateCommands() {
int amount = 1 + RANDOM.nextInt(MAX_COMMANDS - 1);
return generateCommands(amount);
}
/**
* Generates specified amount of random command
*
* @param amount amount of commands to generate
* @return a list of random commands
*/
public List<Command> generateCommands(int amount) {
return Stream.generate(this::generateCommand)
.limit(amount)
.collect(Collectors.toList());
}
/**
* Generates random compile command {@link CompileCommand} with specified
* command and method descriptor
*
* @param command a command type
* @param md a method descriptor
* @param type a type of the command, or null to generate any
* @return the generated compile command
*/
public CompileCommand generateCompileCommand(Command command,
MethodDescriptor md, Scenario.Type type) {
if (type == null) {
type = Utils.getRandomElement(Scenario.Type.values());
}
return type.createCompileCommand(command, md, generateCompiler());
}
/**
* Generates type of compiler that should be used for the command, or null
* if any or all compilers should be used
*
* @return Compiler value, or null
*/
public Scenario.Compiler generateCompiler() {
Scenario.Compiler[] compilers = Scenario.Compiler.values();
int compiler = RANDOM.nextInt(compilers.length + 1) - 1;
return (compiler != -1) ? compilers[compiler] : null;
}
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package compiler.compilercontrol.share.scenario;
import compiler.compilercontrol.share.method.MethodDescriptor;
import java.util.List;
import java.util.stream.Collectors;
/**
* Creates VM options by adding CompileCommand prefix to commands
*/
public class CommandOptionsBuilder extends AbstractCommandBuilder {
@Override
public List<String> getOptions() {
return compileCommands.stream()
.map(cc -> "-XX:CompileCommand="
+ cc.command.name
+ MethodDescriptor.Separator.COMMA.symbol
+ cc.methodDescriptor.getString())
.collect(Collectors.toList());
}
}

View File

@ -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 compiler.compilercontrol.share.scenario;
import compiler.compilercontrol.share.method.MethodDescriptor;
/**
* Compile Command description interface
*/
public class CompileCommand {
public final Command command;
public final MethodDescriptor methodDescriptor;
public final Scenario.Compiler compiler;
public final Scenario.Type type;
public CompileCommand(Command command,
MethodDescriptor methodDescriptor,
Scenario.Compiler compiler,
Scenario.Type type) {
this.command = command;
this.methodDescriptor = methodDescriptor;
this.compiler = compiler;
this.type = type;
}
/**
* Shows that this compile command is valid
*
* @return true if this is a valid command
*/
public boolean isValid() {
if (command == Command.NONEXISTENT) {
return false;
}
return methodDescriptor.isValid();
}
/**
* Prints compile command to the system output
*/
public void print() {
System.out.printf("%s (type: %s): %s (valid: %b)%n", command.name(),
type.name(), methodDescriptor.getString(), isValid());
}
}

View File

@ -0,0 +1,236 @@
/*
* 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 compiler.compilercontrol.share.scenario;
import compiler.compilercontrol.share.JSONFile;
import compiler.compilercontrol.share.method.MethodDescriptor;
import compiler.compilercontrol.share.method.MethodGenerator;
import jdk.test.lib.Pair;
import pool.PoolHelper;
import java.lang.reflect.Executable;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.concurrent.Callable;
/**
* Directive file and state builder class
*/
public class DirectiveBuilder implements StateBuilder<CompileCommand> {
private static final List<Pair<Executable, Callable<?>>> METHODS
= new PoolHelper().getAllMethods();
private final Map<Executable, State> stateMap = new HashMap<>();
private final String fileName;
private Map<MethodDescriptor, List<CompileCommand>> matchBlocks
= new LinkedHashMap<>();
private List<String> inlineMatch = new ArrayList<>();
private boolean isFileValid = true;
public DirectiveBuilder(String fileName) {
this.fileName = fileName;
}
@Override
public List<String> getOptions() {
List<String> options = new ArrayList<>();
if (!matchBlocks.isEmpty()) {
// add option only if there are any directive available
options.add("-XX:CompilerDirectivesFile=" + fileName);
}
return options;
}
@Override
public List<CompileCommand> getCompileCommands() {
throw new Error("TESTBUG: isn't applicable for directives");
}
@Override
public boolean isValid() {
// Invalid directives file makes VM exit with error code
return isFileValid;
}
@Override
public Map<Executable, State> getStates() {
try (DirectiveWriter dirFile = new DirectiveWriter(fileName)) {
for (MethodDescriptor matchDescriptor : matchBlocks.keySet()) {
// Write match block with all options converted from commands
dirFile.match(matchDescriptor);
for (CompileCommand compileCommand :
matchBlocks.get(matchDescriptor)) {
isFileValid &= compileCommand.isValid();
handleCommand(dirFile, compileCommand);
}
if ("Inlinee.caller".matches((matchDescriptor.getRegexp()))) {
// Got a *.* match block, where inline would be written
dirFile.inline(inlineMatch.toArray(
new String[inlineMatch.size()]));
inlineMatch.clear();
}
dirFile.end(); // ends match block
}
/*
* Write inline directive in the end to the latest match block
* if we didn't do this before
* Inlinee caller methods should match this block only
*/
if (!inlineMatch.isEmpty()) {
Pair<Executable, Callable<?>> pair = METHODS.get(0);
MethodDescriptor md = MethodGenerator.anyMatchDescriptor(
pair.first);
CompileCommand cc = new CompileCommand(Command.QUIET, md, null,
Scenario.Type.DIRECTIVE);
List<CompileCommand> commands = new ArrayList<>();
// Add appropriate "*.*" match block
commands.add(cc);
matchBlocks.put(md, commands);
// Add match block for this descriptor with inlines
dirFile.match(md);
dirFile.inline(inlineMatch.toArray(
new String[inlineMatch.size()]));
dirFile.end();
}
if (!matchBlocks.isEmpty()) {
// terminates file
dirFile.end();
}
// Build states for each method according to match blocks
for (Pair<Executable, Callable<?>> pair : METHODS) {
State state = getState(pair);
if (state != null) {
stateMap.put(pair.first, state);
}
}
}
if (isFileValid) {
return stateMap;
} else {
// return empty map because invalid file doesn't change states
return new HashMap<>();
}
}
private State getState(Pair<Executable, Callable<?>> pair) {
State state = null;
MethodDescriptor execDesc = MethodGenerator.commandDescriptor(
pair.first);
boolean isMatchFound = false;
if (stateMap.containsKey(pair.first)) {
state = stateMap.get(pair.first);
}
for (MethodDescriptor matchDesc : matchBlocks.keySet()) {
if (execDesc.getCanonicalString().matches(matchDesc.getRegexp())) {
/*
* if executable matches regex
* then apply commands from this match to the state
*/
for (CompileCommand cc : matchBlocks.get(matchDesc)) {
state = new State();
if (!isMatchFound) {
// this is a first found match, apply all commands
state.apply(cc);
} else {
// apply only inline directives
switch (cc.command) {
case INLINE:
case DONTINLINE:
state.apply(cc);
break;
}
}
}
isMatchFound = true;
}
}
return state;
}
private void handleCommand(DirectiveWriter dirFile, CompileCommand cmd) {
Command command = cmd.command;
switch (command) {
case COMPILEONLY:
dirFile.excludeCompile(cmd.compiler, false);
break;
case EXCLUDE:
dirFile.excludeCompile(cmd.compiler, true);
break;
case INLINE:
case DONTINLINE:
// Inline commands will be written later
break;
case LOG:
dirFile.option(DirectiveWriter.Option.LOG, true);
break;
case QUIET:
// there are no appropriate directive for this
break;
case PRINT:
dirFile.option(DirectiveWriter.Option.PRINT_ASSEMBLY, true);
break;
case NONEXISTENT:
dirFile.write(JSONFile.Element.PAIR, command.name);
dirFile.write(JSONFile.Element.OBJECT);
dirFile.write(JSONFile.Element.PAIR, command.name);
dirFile.write(JSONFile.Element.VALUE,
cmd.methodDescriptor.getString());
dirFile.end(); // ends object
break;
default:
throw new Error("TESTBUG: wrong command: " + command);
}
}
@Override
public void add(CompileCommand compileCommand) {
MethodDescriptor methodDescriptor = compileCommand.methodDescriptor;
switch (compileCommand.command) {
case INLINE:
inlineMatch.add("+" + methodDescriptor.getString());
break;
case DONTINLINE:
inlineMatch.add("-" + methodDescriptor.getString());
break;
}
for (MethodDescriptor md: matchBlocks.keySet()) {
if (methodDescriptor.getCanonicalString().matches(md.getRegexp())) {
matchBlocks.get(md).add(compileCommand);
}
}
if (!matchBlocks.containsKey(compileCommand.methodDescriptor)) {
List<CompileCommand> commands = new ArrayList<>();
commands.add(compileCommand);
matchBlocks.put(compileCommand.methodDescriptor, commands);
}
}
}

View File

@ -0,0 +1,187 @@
/*
* 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 compiler.compilercontrol.share.scenario;
import compiler.compilercontrol.share.JSONFile;
import compiler.compilercontrol.share.method.MethodDescriptor;
/**
* Simple directive file writer.
*/
public class DirectiveWriter implements AutoCloseable {
private final JSONFile jsonFile;
/**
* Builds directive file for the given name
*
* @param fileName name the file to be created
*/
public DirectiveWriter(String fileName) {
jsonFile = new JSONFile(fileName);
}
/**
* Emits match block with a given methods
*
* @param methods methods used for the match
* @return this DirectiveWriter instance
*/
public DirectiveWriter match(String... methods) {
if (jsonFile.getElement() == null) {
write(JSONFile.Element.ARRAY);
}
write(JSONFile.Element.OBJECT);
write(JSONFile.Element.PAIR, "match");
writeMethods(methods);
return this;
}
/**
* Emits match block with a given methods
*
* @param methodDescriptors method descriptors used for the match
* @return this DirectiveWriter instance
*/
public DirectiveWriter match(MethodDescriptor... methodDescriptors) {
String[] methods = new String[methodDescriptors.length];
for (int i = 0; i < methodDescriptors.length; i++) {
methods[i] = methodDescriptors[i].getString();
}
match(methods);
return this;
}
/**
* Emits inline block with a given methods to be inlined or not.
* Each method should be prepended with + or - to show if it should be
* inlined or not.
*
* @param methods methods used for the inline
* @return this DirectiveWriter instance
*/
public DirectiveWriter inline(String... methods) {
write(JSONFile.Element.PAIR, "inline");
writeMethods(methods);
return this;
}
private void writeMethods(String[] methods) {
if (methods.length == 0) {
throw new IllegalArgumentException("ERROR: empty methods array");
}
if (methods.length > 1) {
write(JSONFile.Element.ARRAY);
for (String method : methods) {
write(JSONFile.Element.VALUE, "\"" + method + "\"");
}
end(); // ends array
} else {
write(JSONFile.Element.VALUE, "\"" + methods[0] + "\"");
}
}
/**
* Emits compiler blocks that makes current match to be excluded or not
* from compilation with specified compiler
*
* @param compiler compiler to be excluded or null, for all
* @param exclude shows if compiler should be disabled for this match
* @return this DirectiveWriter instance
*/
public DirectiveWriter excludeCompile(Scenario.Compiler compiler,
boolean exclude) {
if (compiler != null) {
emitCompiler(compiler);
option(Option.EXCLUDE, exclude);
end();
} else {
for (Scenario.Compiler comp : Scenario.Compiler.values()) {
emitCompiler(comp);
option(Option.EXCLUDE, exclude);
end(); // end compiler block
}
}
return this;
}
/**
* Emits compiler directive block
*
* @return this DirectiveWriter instance
*/
public DirectiveWriter emitCompiler(Scenario.Compiler compiler) {
write(JSONFile.Element.PAIR, compiler.name);
write(JSONFile.Element.OBJECT);
return this;
}
@Override
public void close() {
jsonFile.close();
}
/**
* Ends current object element. It could be either a
* c1 or c2 block, or a whole match block
*
* @return this DirectiveWriter instance
*/
public DirectiveWriter end() {
jsonFile.end();
return this;
}
public DirectiveWriter write(JSONFile.Element element, String... value) {
jsonFile.write(element, value);
return this;
}
/**
* Emits directive option with a given value
*
* @param option directive to be set
* @param value value of the directive
* @return this DirectiveWriter instance
*/
public DirectiveWriter option(Option option, Object value) {
write(JSONFile.Element.PAIR, option.string);
write(JSONFile.Element.VALUE, String.valueOf(value));
return this;
}
/**
* Directive option list
*/
public enum Option {
PRINT_ASSEMBLY("PrintAssembly"),
LOG("Log"),
EXCLUDE("Exclude");
public final String string;
private Option(String directive) {
this.string = directive;
}
}
}

View File

@ -0,0 +1,272 @@
/*
* 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 compiler.compilercontrol.share.scenario;
import compiler.compilercontrol.share.actions.BaseAction;
import compiler.compilercontrol.share.method.MethodDescriptor;
import compiler.compilercontrol.share.processors.CommandProcessor;
import compiler.compilercontrol.share.processors.LogProcessor;
import compiler.compilercontrol.share.processors.PrintProcessor;
import compiler.compilercontrol.share.processors.QuietProcessor;
import jdk.test.lib.Asserts;
import jdk.test.lib.OutputAnalyzer;
import jdk.test.lib.Pair;
import jdk.test.lib.ProcessTools;
import pool.PoolHelper;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.Executable;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
/**
* Test scenario
*/
public final class Scenario {
private final boolean isValid;
private final List<String> vmopts;
private final Map<Executable, State> states;
private final List<Consumer<OutputAnalyzer>> processors;
private Scenario(boolean isValid,
List<String> vmopts,
Map<Executable, State> states,
List<CompileCommand> compileCommands) {
this.isValid = isValid;
this.vmopts = vmopts;
this.states = states;
processors = new ArrayList<>();
processors.add(new LogProcessor(states));
processors.add(new PrintProcessor(states));
List<CompileCommand> nonQuieted = new ArrayList<>();
List<CompileCommand> quieted = new ArrayList<>();
boolean metQuiet = false;
for (CompileCommand cc : compileCommands) {
metQuiet |= cc.command == Command.QUIET;
if (metQuiet) {
quieted.add(cc);
} else {
nonQuieted.add(cc);
}
}
processors.add(new CommandProcessor(nonQuieted));
processors.add(new QuietProcessor(quieted));
}
/**
* Executes scenario
*/
public void execute() {
// Construct execution command with CompileCommand and class
List<String> argsList = new ArrayList<>();
// Add VM options
argsList.addAll(vmopts);
// Add class name that would be executed in a separate VM
String classCmd = BaseAction.class.getName();
argsList.add(classCmd);
OutputAnalyzer output;
try (ServerSocket serverSocket = new ServerSocket(0)) {
if (isValid) {
// Get port test VM will connect to
int port = serverSocket.getLocalPort();
if (port == -1) {
throw new Error("Socket is not bound: " + port);
}
argsList.add(String.valueOf(port));
// Start separate thread to connect with test VM
new Thread(() -> connectTestVM(serverSocket)).start();
}
// Start test VM
output = ProcessTools.executeTestJvmAllArgs(
argsList.toArray(new String[argsList.size()]));
} catch (Throwable thr) {
throw new Error("Execution failed", thr);
}
if (isValid) {
output.shouldHaveExitValue(0);
for (Consumer<OutputAnalyzer> processor : processors) {
processor.accept(output);
}
} else {
Asserts.assertNE(output.getExitValue(), 0, "VM should exit with "
+ "error for incorrect directives");
output.shouldContain("Parsing of compiler directives failed");
}
}
/*
* Performs connection with a test VM, sends method states
*/
private void connectTestVM(ServerSocket serverSocket) {
/*
* There are no way to prove that accept was invoked before we started
* test VM that connects to this serverSocket. Connection timeout is
* enough
*/
try (
Socket socket = serverSocket.accept();
PrintWriter pw = new PrintWriter(socket.getOutputStream(),
true);
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()))) {
// Get pid of the executed process
int pid = Integer.parseInt(in.readLine());
Asserts.assertNE(pid, 0, "Got incorrect pid");
// serialize and send state map
for (Executable x : states.keySet()) {
pw.println("{");
pw.println(x.toGenericString());
pw.println(states.get(x).toString());
pw.println("}");
}
} catch (IOException e) {
throw new Error("Failed to write data", e);
}
}
/**
* Gets states of methods for this scenario
*
* @return pairs of executable and its state
*/
public Map<Executable, State> getStates() {
return states;
}
public static enum Compiler {
C1("c1"),
C2("c2");
public final String name;
Compiler(String name) {
this.name = name;
}
}
/**
* Type of the compile command
*/
public static enum Type {
OPTION(""),
FILE("command_file"),
DIRECTIVE("directives.json");
public final String fileName;
public CompileCommand createCompileCommand(Command command,
MethodDescriptor md, Compiler compiler) {
return new CompileCommand(command, md, compiler, this);
}
private Type(String fileName) {
this.fileName = fileName;
}
}
public static Builder getBuilder() {
return new Builder();
}
public static class Builder {
private final Set<String> vmopts = new LinkedHashSet<>();
private final Map<Type, StateBuilder<CompileCommand>> builders
= new HashMap<>();
public Builder() {
builders.put(Type.FILE, new CommandFileBuilder(Type.FILE.fileName));
builders.put(Type.OPTION, new CommandOptionsBuilder());
builders.put(Type.DIRECTIVE, new DirectiveBuilder(
Type.DIRECTIVE.fileName));
}
public void add(CompileCommand compileCommand) {
String[] vmOptions = compileCommand.command.vmOpts;
Collections.addAll(vmopts, vmOptions);
StateBuilder builder = builders.get(compileCommand.type);
if (builder == null) {
throw new Error("TESTBUG: Missing builder for the type: "
+ compileCommand.type);
}
builder.add(compileCommand);
}
public Scenario build() {
boolean isValid = true;
// Get states from each of the state builders
Map<Executable, State> commandFileStates
= builders.get(Type.FILE).getStates();
Map<Executable, State> commandOptionStates
= builders.get(Type.OPTION).getStates();
Map<Executable, State> directiveFileStates
= builders.get(Type.DIRECTIVE).getStates();
// Merge states
List<Pair<Executable, Callable<?>>> methods = new PoolHelper()
.getAllMethods();
Map<Executable, State> finalStates = new HashMap<>();
for (Pair<Executable, Callable<?>> pair : methods) {
Executable x = pair.first;
State commandOptionState = commandOptionStates.get(x);
State commandFileState = commandFileStates.get(x);
State st = State.merge(commandOptionState, commandFileState);
State directiveState = directiveFileStates.get(x);
if (directiveState != null) {
st = directiveState;
}
finalStates.put(x, st);
}
/*
* Create a list of commands from options and file
* to handle quiet command
*/
List<CompileCommand> ccList = new ArrayList<>();
ccList.addAll(builders.get(Type.OPTION).getCompileCommands());
ccList.addAll(builders.get(Type.FILE).getCompileCommands());
// Get all VM options after we build all states and files
List<String> options = new ArrayList<>();
options.addAll(vmopts);
for (StateBuilder<?> builder : builders.values()) {
options.addAll(builder.getOptions());
isValid &= builder.isValid();
}
return new Scenario(isValid, options, finalStates, ccList);
}
}
}