hotspot/test/compiler/compilercontrol/share/scenario/DirectiveBuilder.java
changeset 34226 db9dea22fbfc
parent 34216 2818af1ce748
child 40059 c2304140ed64
equal deleted inserted replaced
34222:57d99d1614e0 34226:db9dea22fbfc
    44 public class DirectiveBuilder implements StateBuilder<CompileCommand> {
    44 public class DirectiveBuilder implements StateBuilder<CompileCommand> {
    45     private static final List<Pair<Executable, Callable<?>>> METHODS
    45     private static final List<Pair<Executable, Callable<?>>> METHODS
    46             = new PoolHelper().getAllMethods();
    46             = new PoolHelper().getAllMethods();
    47     private final Map<Executable, State> stateMap = new HashMap<>();
    47     private final Map<Executable, State> stateMap = new HashMap<>();
    48     private final String fileName;
    48     private final String fileName;
    49     private Map<MethodDescriptor, List<CompileCommand>> matchBlocks
    49     private final Map<MethodDescriptor, List<CompileCommand>> matchBlocks
    50             = new LinkedHashMap<>();
    50             = new LinkedHashMap<>();
    51     private List<String> inlineMatch = new ArrayList<>();
    51     private final List<CompileCommand> inlines = new ArrayList<>();
    52     private boolean isFileValid = true;
    52     private boolean isFileValid = true;
    53 
    53 
    54     public DirectiveBuilder(String fileName) {
    54     public DirectiveBuilder(String fileName) {
    55         this.fileName = fileName;
    55         this.fileName = fileName;
    56     }
    56     }
    79         return isFileValid;
    79         return isFileValid;
    80     }
    80     }
    81 
    81 
    82     @Override
    82     @Override
    83     public Map<Executable, State> getStates() {
    83     public Map<Executable, State> getStates() {
       
    84         writeDirectiveFile();
       
    85         if (isFileValid) {
       
    86             // Build states for each method according to match blocks
       
    87             for (Pair<Executable, Callable<?>> pair : METHODS) {
       
    88                 State state = getState(pair);
       
    89                 if (state != null) {
       
    90                     stateMap.put(pair.first, state);
       
    91                 }
       
    92             }
       
    93             return stateMap;
       
    94         } else {
       
    95             // return empty map because invalid file doesn't change states
       
    96             return new HashMap<>();
       
    97         }
       
    98     }
       
    99 
       
   100     private void writeDirectiveFile() {
    84         try (DirectiveWriter dirFile = new DirectiveWriter(fileName)) {
   101         try (DirectiveWriter dirFile = new DirectiveWriter(fileName)) {
    85             for (MethodDescriptor matchDescriptor : matchBlocks.keySet()) {
   102             for (MethodDescriptor matchDescriptor : matchBlocks.keySet()) {
    86                 // Write match block with all options converted from commands
   103                 // Write match block with all options converted from commands
    87                 dirFile.match(matchDescriptor);
   104                 dirFile.match(matchDescriptor);
    88                 for (CompileCommand compileCommand :
   105                 for (CompileCommand compileCommand :
    89                         matchBlocks.get(matchDescriptor)) {
   106                         matchBlocks.get(matchDescriptor)) {
    90                     isFileValid &= compileCommand.isValid();
       
    91                     handleCommand(dirFile, compileCommand);
   107                     handleCommand(dirFile, compileCommand);
    92                 }
   108                 }
    93                 if ("Inlinee.caller".matches((matchDescriptor.getRegexp()))) {
   109                 if ("Inlinee.caller()".matches(matchDescriptor.getRegexp())
       
   110                         && !inlines.isEmpty()) {
    94                     // Got a *.* match block, where inline would be written
   111                     // Got a *.* match block, where inline would be written
    95                     dirFile.inline(inlineMatch.toArray(
   112                     writeInlines(dirFile);
    96                             new String[inlineMatch.size()]));
   113                     inlines.clear();
    97                     inlineMatch.clear();
       
    98                 }
   114                 }
    99                 dirFile.end(); // ends match block
   115                 dirFile.end(); // ends match block
   100             }
   116             }
   101 
   117 
   102             /*
   118             /*
   103              * Write inline directive in the end to the latest match block
   119              * Write inline directive in the end to the latest match block
   104              * if we didn't do this before
   120              * if we didn't do this before
   105              * Inlinee caller methods should match this block only
   121              * Inlinee caller methods should match this block only
   106              */
   122              */
   107             if (!inlineMatch.isEmpty()) {
   123             if (!inlines.isEmpty()) {
   108                 Pair<Executable, Callable<?>> pair = METHODS.get(0);
   124                 Pair<Executable, Callable<?>> pair = METHODS.get(0);
   109                 MethodDescriptor md = MethodGenerator.anyMatchDescriptor(
   125                 MethodDescriptor md = MethodGenerator.anyMatchDescriptor(
   110                         pair.first);
   126                         pair.first);
   111                 CompileCommand cc = new CompileCommand(Command.QUIET, md, null,
   127                 CompileCommand cc = new CompileCommand(Command.QUIET, md,
   112                         Scenario.Type.DIRECTIVE);
   128                         null, Scenario.Type.DIRECTIVE);
   113                 List<CompileCommand> commands = new ArrayList<>();
   129                 List<CompileCommand> commands = new ArrayList<>();
   114 
   130 
   115                 // Add appropriate "*.*" match block
   131                 // Add appropriate "*.*" match block
   116                 commands.add(cc);
   132                 commands.add(cc);
   117                 matchBlocks.put(md, commands);
   133                 matchBlocks.put(md, commands);
   118                 // Add match block for this descriptor with inlines
   134                 // Add match block for this descriptor with inlines
   119                 dirFile.match(md);
   135                 dirFile.match(md);
   120                 dirFile.inline(inlineMatch.toArray(
   136                 writeInlines(dirFile);
   121                         new String[inlineMatch.size()]));
       
   122                 dirFile.end();
   137                 dirFile.end();
   123             }
   138             }
   124             if (!matchBlocks.isEmpty()) {
   139             if (!matchBlocks.isEmpty()) {
   125                 // terminates file
   140                 // terminates file
   126                 dirFile.end();
   141                 dirFile.end();
   127             }
   142             }
   128 
   143 
   129             // Build states for each method according to match blocks
       
   130             for (Pair<Executable, Callable<?>> pair : METHODS) {
       
   131                 State state = getState(pair);
       
   132                 if (state != null) {
       
   133                     stateMap.put(pair.first, state);
       
   134                 }
       
   135             }
       
   136         }
       
   137         if (isFileValid) {
       
   138             return stateMap;
       
   139         } else {
       
   140             // return empty map because invalid file doesn't change states
       
   141             return new HashMap<>();
       
   142         }
   144         }
   143     }
   145     }
   144 
   146 
   145     private State getState(Pair<Executable, Callable<?>> pair) {
   147     private State getState(Pair<Executable, Callable<?>> pair) {
   146         State state = null;
   148         State state = null;
   156                 /*
   158                 /*
   157                  * if executable matches regex
   159                  * if executable matches regex
   158                  * then apply commands from this match to the state
   160                  * then apply commands from this match to the state
   159                  */
   161                  */
   160                 for (CompileCommand cc : matchBlocks.get(matchDesc)) {
   162                 for (CompileCommand cc : matchBlocks.get(matchDesc)) {
   161                     state = new State();
   163                     if (state == null) {
       
   164                         state = new State();
       
   165                     }
   162                     if (!isMatchFound) {
   166                     if (!isMatchFound) {
   163                         // this is a first found match, apply all commands
   167                         // this is a first found match, apply all commands
   164                         state.apply(cc);
   168                         state.apply(cc);
   165                     } else {
   169                     } else {
   166                         // apply only inline directives
   170                         // apply only inline directives
   186                 dirFile.excludeCompile(cmd.compiler, false);
   190                 dirFile.excludeCompile(cmd.compiler, false);
   187                 break;
   191                 break;
   188             case EXCLUDE:
   192             case EXCLUDE:
   189                 dirFile.excludeCompile(cmd.compiler, true);
   193                 dirFile.excludeCompile(cmd.compiler, true);
   190                 break;
   194                 break;
       
   195             case QUIET:
       
   196                 /* there are no appropriate directive for this, just make
       
   197                    match be enabled */
   191             case INLINE:
   198             case INLINE:
   192             case DONTINLINE:
   199             case DONTINLINE:
   193                 // Inline commands will be written later
   200                 /* Inline commands will be written later.
       
   201                    Just make this match be enabled */
       
   202                 dirFile.emitCompiler(Scenario.Compiler.C1);
       
   203                 dirFile.option(DirectiveWriter.Option.ENABLE, true);
       
   204                 dirFile.end();
       
   205                 dirFile.emitCompiler(Scenario.Compiler.C2);
       
   206                 dirFile.option(DirectiveWriter.Option.ENABLE, true);
       
   207                 dirFile.end();
   194                 break;
   208                 break;
   195             case LOG:
   209             case LOG:
   196                 dirFile.option(DirectiveWriter.Option.LOG, true);
   210                 dirFile.option(DirectiveWriter.Option.LOG, true);
   197                 break;
       
   198             case QUIET:
       
   199                 // there are no appropriate directive for this
       
   200                 break;
   211                 break;
   201             case PRINT:
   212             case PRINT:
   202                 dirFile.option(DirectiveWriter.Option.PRINT_ASSEMBLY, true);
   213                 dirFile.option(DirectiveWriter.Option.PRINT_ASSEMBLY, true);
   203                 break;
   214                 break;
   204             case NONEXISTENT:
   215             case NONEXISTENT:
   212             default:
   223             default:
   213                 throw new Error("TESTBUG: wrong command: " + command);
   224                 throw new Error("TESTBUG: wrong command: " + command);
   214         }
   225         }
   215     }
   226     }
   216 
   227 
       
   228     private void writeInlines(DirectiveWriter dirFile) {
       
   229         List<String> c1Block = new ArrayList<>();
       
   230         List<String> c2Block = new ArrayList<>();
       
   231         List<String> allBlock = new ArrayList<>();
       
   232         for (CompileCommand cc : inlines) {
       
   233             String inlineMethodPattern;
       
   234             switch (cc.command) {
       
   235                 case INLINE:
       
   236                     inlineMethodPattern = "+" + cc.methodDescriptor.getString();
       
   237                     break;
       
   238                 case DONTINLINE:
       
   239                     inlineMethodPattern = "-" + cc.methodDescriptor.getString();
       
   240                     break;
       
   241                 default:
       
   242                     throw new Error("TESTBUG: incorrect command got in "
       
   243                             + "the list: " + cc.command);
       
   244             }
       
   245             if (cc.compiler == Scenario.Compiler.C1) {
       
   246                 c1Block.add(inlineMethodPattern);
       
   247             } else if (cc.compiler == Scenario.Compiler.C2) {
       
   248                 c2Block.add(inlineMethodPattern);
       
   249             } else {
       
   250                 allBlock.add(inlineMethodPattern);
       
   251             }
       
   252         }
       
   253         dirFile.emitCompiler(Scenario.Compiler.C1);
       
   254         if (!c1Block.isEmpty()) {
       
   255             dirFile.inline(c1Block);
       
   256         } else {
       
   257             dirFile.option(DirectiveWriter.Option.ENABLE, true);
       
   258         }
       
   259         dirFile.end();
       
   260         dirFile.emitCompiler(Scenario.Compiler.C2);
       
   261         if (!c2Block.isEmpty()) {
       
   262             dirFile.inline(c2Block);
       
   263         } else {
       
   264             dirFile.option(DirectiveWriter.Option.ENABLE, true);
       
   265         }
       
   266         dirFile.end();
       
   267         if (!allBlock.isEmpty()) {
       
   268             dirFile.inline(allBlock);
       
   269         }
       
   270     }
       
   271 
   217     @Override
   272     @Override
   218     public void add(CompileCommand compileCommand) {
   273     public void add(CompileCommand compileCommand) {
       
   274         isFileValid &= compileCommand.isValid();
   219         MethodDescriptor methodDescriptor = compileCommand.methodDescriptor;
   275         MethodDescriptor methodDescriptor = compileCommand.methodDescriptor;
   220 
   276 
   221         switch (compileCommand.command) {
   277         switch (compileCommand.command) {
   222             case INLINE:
   278             case INLINE:
   223                 inlineMatch.add("+" + methodDescriptor.getString());
       
   224                 break;
       
   225             case DONTINLINE:
   279             case DONTINLINE:
   226                 inlineMatch.add("-" + methodDescriptor.getString());
   280                 inlines.add(compileCommand);
   227                 break;
   281                 break;
   228         }
   282         }
   229         for (MethodDescriptor md: matchBlocks.keySet()) {
   283         for (MethodDescriptor md: matchBlocks.keySet()) {
   230             if (methodDescriptor.getCanonicalString().matches(md.getRegexp())) {
   284             if (methodDescriptor.getCanonicalString().matches(md.getRegexp())) {
   231                 matchBlocks.get(md).add(compileCommand);
   285                 matchBlocks.get(md).add(compileCommand);