1 /*
   2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package sun.hotspot.tools.ctw;
  25 
  26 import sun.hotspot.WhiteBox;
  27 
  28 import java.lang.reflect.Executable;
  29 
  30 /**
  31  * Compilation of method.
  32  * Will compile method on all available comp levels.
  33  *
  34  * @author igor.ignatyev@oracle.com
  35  */
  36 public class CompileMethodCommand implements Runnable {
  37     private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
  38     private final long classId;
  39     private final String className;
  40     private final Executable method;
  41 
  42     /**
  43      * @param classId   id of class
  44      * @param className name of class
  45      * @param method    compiled for compilation
  46      */
  47     public CompileMethodCommand(long classId, String className,
  48             Executable method) {
  49         this.classId = classId;
  50         this.className = className;
  51         this.method = method;
  52     }
  53 
  54     @Override
  55     public final void run() {
  56         int compLevel = Utils.INITIAL_COMP_LEVEL;
  57         if (Utils.TIERED_COMPILATION) {
  58             for (int i = compLevel; i <= Utils.TIERED_STOP_AT_LEVEL; ++i) {
  59                 WHITE_BOX.deoptimizeMethod(method);
  60                 compileMethod(method, i);
  61             }
  62         } else {
  63             compileMethod(method, compLevel);
  64         }
  65     }
  66 
  67     private void waitCompilation() {
  68         if (!Utils.BACKGROUND_COMPILATION) {
  69             return;
  70         }
  71         final Object obj = new Object();
  72         synchronized (obj) {
  73             for (int i = 0;
  74                  i < 10 && WHITE_BOX.isMethodQueuedForCompilation(method);
  75                  ++i) {
  76                 try {
  77                     obj.wait(1000);
  78                 } catch (InterruptedException e) {
  79                     Thread.currentThread().interrupt();
  80                 }
  81             }
  82         }
  83     }
  84 
  85     private void compileMethod(Executable method, int compLevel) {
  86         if (WHITE_BOX.isMethodCompilable(method, compLevel)) {
  87             try {
  88                 WHITE_BOX.enqueueMethodForCompilation(method, compLevel);
  89                 waitCompilation();
  90                 int tmp = WHITE_BOX.getMethodCompilationLevel(method);
  91                 if (tmp != compLevel) {
  92                     logMethod(method, "compilation level = " + tmp
  93                             + ", but not " + compLevel);
  94                 } else if (Utils.IS_VERBOSE) {
  95                     logMethod(method, "compilation level = " + tmp + ". OK");
  96                 }
  97             } catch (Throwable t) {
  98                 logMethod(method, "error on compile at " + compLevel
  99                         + " level");
 100                 t.printStackTrace();
 101             }
 102         } else if (Utils.IS_VERBOSE) {
 103             logMethod(method, "not compilable at " + compLevel);
 104         }
 105     }
 106 
 107     private void logMethod(Executable method, String message) {
 108         StringBuilder builder = new StringBuilder("[");
 109         builder.append(classId);
 110         builder.append("]\t");
 111         builder.append(className);
 112         builder.append("::");
 113         builder.append(method.getName());
 114         builder.append('(');
 115         Class[] params = method.getParameterTypes();
 116         for (int i = 0, n = params.length - 1; i < n; ++i) {
 117             builder.append(params[i].getName());
 118             builder.append(", ");
 119         }
 120         if (params.length != 0) {
 121             builder.append(params[params.length - 1].getName());
 122         }
 123         builder.append(')');
 124         if (message != null) {
 125             builder.append('\t');
 126             builder.append(message);
 127         }
 128         System.err.println(builder);
 129     }
 130 }
 131