Path: blob/master/test/hotspot/jtreg/compiler/compilercontrol/share/scenario/JcmdStateBuilder.java
41161 views
/*1* Copyright (c) 2015, 2016, 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 compiler.compilercontrol.share.method.MethodDescriptor;26import compiler.compilercontrol.share.method.MethodGenerator;27import compiler.compilercontrol.share.pool.PoolHelper;28import jdk.test.lib.util.Pair;2930import java.lang.reflect.Executable;31import java.util.ArrayList;32import java.util.HashMap;33import java.util.Iterator;34import java.util.LinkedHashMap;35import java.util.List;36import java.util.Map;37import java.util.concurrent.Callable;38import java.util.stream.Collectors;3940public class JcmdStateBuilder implements StateBuilder<JcmdCommand> {41private static final List<Pair<Executable, Callable<?>>> METHODS42= new PoolHelper().getAllMethods();43private final Map<Executable, State> stateMap = new HashMap<>();44private final DirectiveBuilder directiveBuilder;45private final Map<MethodDescriptor, List<CompileCommand>> matchBlocks46= new LinkedHashMap<>();47private final List<CompileCommand> inlines = new ArrayList<>();48public boolean isFileValid = true;4950public JcmdStateBuilder(String fileName) {51directiveBuilder = new DirectiveBuilder(fileName);52}5354@Override55public void add(JcmdCommand compileCommand) {56switch (compileCommand.jcmdType) {57case ADD:58directiveBuilder.add(compileCommand);59addCommand(compileCommand);60break;61case PRINT:62// doesn't change the state63break;64case CLEAR:65matchBlocks.clear();66inlines.clear();67break;68case REMOVE:69removeDirective();70break;71}72}7374private void addCommand(JcmdCommand compileCommand) {75isFileValid &= compileCommand.isValid();76MethodDescriptor methodDescriptor = compileCommand.methodDescriptor;7778switch (compileCommand.command) {79case INLINE:80case DONTINLINE:81inlines.add(compileCommand);82break;83}84for (MethodDescriptor md: matchBlocks.keySet()) {85if (methodDescriptor.getCanonicalString().matches(md.getRegexp())) {86matchBlocks.get(md).add(compileCommand);87}88}89if (!matchBlocks.containsKey(compileCommand.methodDescriptor)) {90List<CompileCommand> commands = new ArrayList<>();91commands.add(compileCommand);92matchBlocks.put(compileCommand.methodDescriptor, commands);93}94}9596private void removeDirective() {97Iterator<MethodDescriptor> iterator = matchBlocks.keySet().iterator();98if (iterator.hasNext()) {99MethodDescriptor md = iterator.next();100matchBlocks.remove(md);101}102}103104@Override105public boolean isValid() {106// VM skips invalid directive file added via jcmd command107return true;108}109110@Override111public Map<Executable, State> getStates() {112directiveBuilder.getStates();113for (MethodDescriptor matchDescriptor : matchBlocks.keySet()) {114if ("Inlinee.caller()".matches(matchDescriptor.getRegexp())115&& !inlines.isEmpty()) {116// Got a *.* match block, where inline would be written117inlines.clear();118}119}120/*121* Write inline directive in the end to the latest match block122* if we didn't do this before123* Inlinee caller methods should match this block only124*/125if (!inlines.isEmpty()) {126Pair<Executable, Callable<?>> pair = METHODS.get(0);127MethodDescriptor md = MethodGenerator.anyMatchDescriptor(128pair.first);129CompileCommand cc = new CompileCommand(Command.QUIET, md,130null, Scenario.Type.DIRECTIVE);131List<CompileCommand> commands = new ArrayList<>();132133// Add appropriate "*.*" match block134commands.add(cc);135matchBlocks.put(md, commands);136}137if (isFileValid) {138// Build states for each method according to match blocks139for (Pair<Executable, Callable<?>> pair : METHODS) {140State state = getState(pair);141if (state != null) {142stateMap.put(pair.first, state);143}144}145return stateMap;146} else {147// return empty map because invalid file doesn't change states148return new HashMap<>();149}150}151152private State getState(Pair<Executable, Callable<?>> pair) {153State state = null;154MethodDescriptor execDesc = MethodGenerator.commandDescriptor(155pair.first);156boolean isMatchFound = false;157158if (stateMap.containsKey(pair.first)) {159state = stateMap.get(pair.first);160}161for (MethodDescriptor matchDesc : matchBlocks.keySet()) {162if (execDesc.getCanonicalString().matches(matchDesc.getRegexp())) {163/*164* if executable matches regex165* then apply commands from this match to the state166*/167for (CompileCommand cc : matchBlocks.get(matchDesc)) {168if (state == null) {169state = new State();170}171if (!isMatchFound) {172// this is a first found match, apply all commands173state.apply(cc);174} else {175// apply only inline directives176switch (cc.command) {177case INLINE:178case DONTINLINE:179state.apply(cc);180break;181}182}183}184isMatchFound = true;185}186}187return state;188}189190@Override191public List<String> getOptions() {192return new ArrayList<>();193}194195@Override196public List<JcmdCommand> getCompileCommands() {197if (isFileValid) {198return matchBlocks.keySet().stream()199/* only method descriptor is required200to check print_directives */201.map(md -> new JcmdCommand(null, md, null, null,202Scenario.JcmdType.ADD))203.collect(Collectors.toList());204} else {205return new ArrayList<>();206}207}208}209210211