Path: blob/master/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/State.java
41161 views
/*1* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package compiler.compilercontrol.share.scenario;2425import jdk.test.lib.Asserts;2627import java.util.Arrays;28import java.util.Optional;2930/**31* Represents method compilation state32*/33public class State {34// Each of the two-elements array contains a state for each compiler35private Optional<Boolean>[] compile =36(Optional<Boolean>[]) new Optional[Scenario.Compiler.values().length];37private Optional<Boolean>[] forceInline =38(Optional<Boolean>[]) new Optional[Scenario.Compiler.values().length];39private Optional<Boolean>[] dontInline =40(Optional<Boolean>[]) new Optional[Scenario.Compiler.values().length];41private Optional<Boolean> printAssembly = Optional.empty();42private Optional<Boolean> printInline = Optional.empty();43private Optional<Boolean> log = Optional.empty();44private Optional<String> controlIntrinsic = Optional.empty();4546public State() {47Arrays.fill(compile, Optional.empty());48Arrays.fill(forceInline, Optional.empty());49Arrays.fill(dontInline, Optional.empty());50}5152/**53* Creates state from the string54*55* @param strings array of strings that represent the state56* @return State instance57* @see #toString()58*/59public static State fromString(String[] strings) {60Asserts.assertNotNull(strings, "Non null array is required");61Asserts.assertNE(strings.length, 0, "Non empty array is required");62State st = new State();63for (String string : strings) {64int i = string.indexOf(' ');65String command = string.substring(0, i);66String values = string.substring(i + 1); // skip space symbol67switch (command) {68case "compile" :69parseArray(st.compile, values);70break;71case "force_inline" :72parseArray(st.forceInline, values);73break;74case "dont_inline" :75parseArray(st.dontInline, values);76break;77case "log" :78st.log = parseElement(values);79break;80case "print_assembly" :81st.printAssembly = parseElement(values);82break;83case "print_inline" :84st.printInline = parseElement(values);85break;86default:87throw new Error("TESTBUG: ");88}89}90return st;91}9293private static void parseArray(Optional<Boolean>[] array, String str) {94Asserts.assertNotNull(str);95int beginBrace = 0;96int endBrace = str.length() - 1;97if (str.charAt(beginBrace) != '[' || str.charAt(endBrace) != ']') {98throw new Error("TESTBUG: not an array type: " + str);99}100// Get all elements divided with comma as an array101String[] strValues = str.substring(beginBrace + 1, endBrace)102.split(", ");103Asserts.assertEQ(strValues.length, array.length, "Different amount of "104+ "elements in the string");105for (int i = 0; i < strValues.length; i++) {106array[i] = parseElement(strValues[i]);107}108}109110private static Optional<Boolean> parseElement(String str) {111Asserts.assertNotNull(str);112Asserts.assertTrue(str.startsWith(Optional.class.getSimpleName()),113"String is not of type Optional: " + str);114if ("Optional.empty".equals(str)) {115return Optional.empty();116}117int begin = str.indexOf('[');118Asserts.assertNE(begin, -1, "TEST BUG: Wrong Optional string");119int end = str.indexOf(']');120Asserts.assertEQ(end, str.length() - 1);121boolean b = Boolean.parseBoolean(str.substring(begin + 1, end));122return Optional.of(b);123}124125/**126* Gets string representation of this state127*/128@Override129public String toString() {130return "compile " + Arrays.toString(compile)131+ "\nforce_inline " + Arrays.toString(forceInline)132+ "\ndont_inline " + Arrays.toString(dontInline)133+ "\nlog " + log134+ "\nprint_assembly " + printAssembly135+ "\nprint_inline " + printInline;136}137138public Optional<Boolean> getCompilableOptional(Scenario.Compiler compiler) {139return compile[compiler.ordinal()];140}141142public boolean isC1Compilable() {143return compile[Scenario.Compiler.C1.ordinal()].orElse(true);144}145146public boolean isC2Compilable() {147return compile[Scenario.Compiler.C2.ordinal()].orElse(true);148}149150public boolean isCompilable() {151return isC1Compilable() && isC2Compilable();152}153154public void setC1Compilable(boolean value) {155setCompilable(Scenario.Compiler.C1.ordinal(), value);156}157158public void setC2Compilable(boolean value) {159setCompilable(Scenario.Compiler.C2.ordinal(), value);160}161162public void setCompilable(Scenario.Compiler compiler, boolean value) {163if (compiler == null) {164setC1Compilable(value);165setC2Compilable(value);166return;167}168switch (compiler) {169case C1:170setC1Compilable(value);171break;172case C2:173setC2Compilable(value);174break;175default:176throw new Error("Unknown compiler");177}178}179180private void setCompilable(int level, boolean value) {181check(level);182compile[level] = Optional.of(value);183if (!value) {184setDontInline(level);185}186}187188public boolean isC1Inlinable() {189return ! dontInline[Scenario.Compiler.C1.ordinal()].orElse(false)190&& isC1Compilable();191}192193public boolean isC2Inlinable() {194return ! dontInline[Scenario.Compiler.C2.ordinal()].orElse(false)195&& isC2Compilable();196}197198public boolean isInlinable() {199return isC1Inlinable() && isC2Inlinable();200}201202private void setDontInline(int level) {203check(level);204dontInline[level] = Optional.of(true);205forceInline[level] = Optional.of(false);206}207208private void setForceInline(int level) {209check(level);210dontInline[level] = Optional.of(false);211forceInline[level] = Optional.of(true);212}213214public boolean isC1ForceInline() {215return forceInline[Scenario.Compiler.C1.ordinal()].orElse(false)216&& isC1Compilable();217}218219public boolean isC2ForceInline() {220return forceInline[Scenario.Compiler.C2.ordinal()].orElse(false)221&& isC2Compilable();222}223224public boolean isForceInline() {225return isC1ForceInline() && isC2ForceInline();226}227228public void setC1Inline(boolean value) {229if (value && isC1Compilable()) {230setForceInline(Scenario.Compiler.C1.ordinal());231} else {232setDontInline(Scenario.Compiler.C1.ordinal());233}234}235236public void setC2Inline(boolean value) {237if (value && isC2Compilable()) {238setForceInline(Scenario.Compiler.C2.ordinal());239} else {240setDontInline(Scenario.Compiler.C2.ordinal());241}242}243244public void setInline(Scenario.Compiler compiler, boolean value) {245if (compiler == null) {246setC1Inline(value);247setC2Inline(value);248return;249}250switch (compiler) {251case C1:252setC1Inline(value);253break;254case C2:255setC2Inline(value);256break;257default:258throw new Error("Unknown compiler");259}260}261262public boolean isPrintAssembly() {263return printAssembly.orElse(false);264}265266public void setPrintAssembly(boolean value) {267printAssembly = Optional.of(value);268}269270public boolean isPrintInline() {271return printInline.orElse(false);272}273274public void setPrintInline(boolean value) {275printInline = Optional.of(value);276}277278public void setControlIntrinsic(String argument) {279if (argument != null) {280controlIntrinsic = Optional.of(argument);281}282}283284public boolean isLog() {285return log.orElse(false);286}287288public void setLog(boolean log) {289this.log = Optional.of(log);290}291292private void check(int level) {293if (level < 0 || level > compile.length) {294throw new IllegalArgumentException("TESTBUG: Wrong level " + level);295}296}297298/**299* Applies given command to the state.300*301* @param compileCommand command to be applied302*/303public void apply(CompileCommand compileCommand) {304switch (compileCommand.command) {305case COMPILEONLY:306setCompilable(compileCommand.compiler, true);307break;308case EXCLUDE:309setCompilable(compileCommand.compiler, false);310break;311case INLINE:312setInline(compileCommand.compiler, true);313break;314case DONTINLINE:315setInline(compileCommand.compiler, false);316break;317case LOG:318setLog(true);319break;320case PRINT:321setPrintAssembly(true);322break;323case INTRINSIC:324setControlIntrinsic(compileCommand.argument);325break;326case QUIET:327case NONEXISTENT:328// doesn't apply the state329break;330default:331throw new Error("Wrong command: " + compileCommand.command);332}333}334335/**336* Merges two given states with different priority337*338* @param low state with lower merge priority339* @param high state with higher merge priority340*/341public static State merge(State low, State high) {342if (high == null) {343if (low == null) {344return new State();345}346return low;347}348if (low == null) {349return high;350}351State result = new State();352// Compilable353result.compile[Scenario.Compiler.C1.ordinal()] = mergeOptional(354high.compile[Scenario.Compiler.C1.ordinal()],355low.compile[Scenario.Compiler.C1.ordinal()]);356result.compile[Scenario.Compiler.C2.ordinal()] = mergeOptional(357high.compile[Scenario.Compiler.C2.ordinal()],358low.compile[Scenario.Compiler.C2.ordinal()]);359// Force inline360result.forceInline[Scenario.Compiler.C1.ordinal()] = mergeOptional(361high.forceInline[Scenario.Compiler.C1.ordinal()],362low.forceInline[Scenario.Compiler.C1.ordinal()]);363result.forceInline[Scenario.Compiler.C2.ordinal()] = mergeOptional(364high.forceInline[Scenario.Compiler.C2.ordinal()],365low.forceInline[Scenario.Compiler.C2.ordinal()]);366// Don't inline367result.dontInline[Scenario.Compiler.C1.ordinal()] = mergeOptional(368high.dontInline[Scenario.Compiler.C1.ordinal()],369low.dontInline[Scenario.Compiler.C1.ordinal()]);370result.dontInline[Scenario.Compiler.C2.ordinal()] = mergeOptional(371high.dontInline[Scenario.Compiler.C2.ordinal()],372low.dontInline[Scenario.Compiler.C2.ordinal()]);373// set PrintAssembly374result.printAssembly = mergeOptional(high.printAssembly,375low.printAssembly);376// set PrintInline377result.printInline = mergeOptional(high.printInline, low.printInline);378// set LogCompilation379result.log = mergeOptional(high.log, low.log);380// set controlIntrinsic381result.controlIntrinsic = mergeOptional(high.controlIntrinsic, low.controlIntrinsic);382383return result;384}385386private static <T> Optional<T> mergeOptional(Optional<T> high,387Optional<T> low) {388T val = high.orElse(low.orElse(null));389return Optional.ofNullable(val);390}391}392393394