1 /*
   2  * Copyright (c) 2016, 2017, 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 jdk.tools.jaotc;
  25 
  26 import java.io.FileWriter;
  27 import java.io.IOException;
  28 import java.io.PrintWriter;
  29 import java.lang.management.ManagementFactory;
  30 import java.lang.management.MemoryUsage;
  31 import java.nio.file.Path;
  32 import java.nio.file.Paths;
  33 import java.text.MessageFormat;
  34 import java.util.Date;
  35 
  36 import jdk.tools.jaotc.binformat.ByteContainer;
  37 import jdk.tools.jaotc.binformat.BinaryContainer;
  38 
  39 final class LogPrinter {
  40 
  41     private static FileWriter logFile = null;
  42     private final Options options;
  43     private final PrintWriter log;
  44 
  45     LogPrinter(Main main, PrintWriter log) {
  46         this.options = main.options;
  47         this.log = log;
  48     }
  49 
  50     void printInfo(String message) {
  51         if (options.info) {
  52             log.print(message);
  53             log.flush();
  54         }
  55     }
  56 
  57     void printlnInfo(String message) {
  58         if (options.info) {
  59             log.println(message);
  60             log.flush();
  61         }
  62     }
  63 
  64     void printVerbose(String message) {
  65         if (options.verbose) {
  66             log.print(message);
  67             log.flush();
  68         }
  69     }
  70 
  71     void printlnVerbose(String message) {
  72         if (options.verbose) {
  73             log.println(message);
  74             log.flush();
  75         }
  76     }
  77 
  78     void printDebug(String message) {
  79         if (options.debug) {
  80             log.print(message);
  81             log.flush();
  82         }
  83     }
  84 
  85     void printlnDebug(String message) {
  86         if (options.debug) {
  87             log.println(message);
  88             log.flush();
  89         }
  90     }
  91 
  92     void printError(String message) {
  93         log.println("Error: " + message);
  94         log.flush();
  95     }
  96 
  97     void reportError(Throwable e) {
  98         log.println("Error: " + e.getMessage());
  99         if (options.info) {
 100             e.printStackTrace(log);
 101         }
 102         log.flush();
 103     }
 104 
 105     void reportError(String key, Object... args) {
 106         printError(MessageFormat.format(key, args));
 107     }
 108 
 109     private static String humanReadableByteCount(long bytes) {
 110         int unit = 1024;
 111 
 112         if (bytes < unit) {
 113             return bytes + " B";
 114         }
 115 
 116         int exp = (int) (Math.log(bytes) / Math.log(unit));
 117         char pre = "KMGTPE".charAt(exp - 1);
 118         return String.format("%.1f %cB", bytes / Math.pow(unit, exp), pre);
 119     }
 120 
 121     void printMemoryUsage() {
 122         if (options.verbose) {
 123             MemoryUsage memusage = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
 124             float freeratio = 1f - (float) memusage.getUsed() / memusage.getCommitted();
 125             log.format(" [used: %-7s, comm: %-7s, freeRatio ~= %.1f%%]",
 126                             humanReadableByteCount(memusage.getUsed()),
 127                             humanReadableByteCount(memusage.getCommitted()),
 128                             freeratio * 100);
 129         }
 130     }
 131 
 132     private void printContainerInfo(ByteContainer container) {
 133         printlnVerbose(container.getContainerName() + ": " + container.getByteStreamSize() + " bytes");
 134     }
 135 
 136     void containersInfo(BinaryContainer binaryContainer) {
 137         printContainerInfo(binaryContainer.getHeaderContainer().getContainer());
 138         printContainerInfo(binaryContainer.getConfigContainer());
 139         printContainerInfo(binaryContainer.getKlassesOffsetsContainer());
 140         printContainerInfo(binaryContainer.getMethodsOffsetsContainer());
 141         printContainerInfo(binaryContainer.getKlassesDependenciesContainer());
 142         printContainerInfo(binaryContainer.getStubsOffsetsContainer());
 143         printContainerInfo(binaryContainer.getMethodMetadataContainer());
 144         printContainerInfo(binaryContainer.getCodeContainer());
 145         printContainerInfo(binaryContainer.getCodeSegmentsContainer());
 146         printContainerInfo(binaryContainer.getConstantDataContainer());
 147         printContainerInfo(binaryContainer.getKlassesGotContainer());
 148         printContainerInfo(binaryContainer.getCountersGotContainer());
 149         printContainerInfo(binaryContainer.getMetadataGotContainer());
 150         printContainerInfo(binaryContainer.getMethodStateContainer());
 151         printContainerInfo(binaryContainer.getOopGotContainer());
 152         printContainerInfo(binaryContainer.getMetaspaceNamesContainer());
 153     }
 154 
 155     static void openLog() {
 156         int v = Integer.getInteger("jdk.tools.jaotc.logCompilation", 0);
 157         if (v == 0) {
 158             logFile = null;
 159             return;
 160         }
 161         // Create log file in current directory
 162         String fileName = "aot_compilation" + new Date().getTime() + ".log";
 163         Path logFilePath = Paths.get("./", fileName);
 164         String logFileName = logFilePath.toString();
 165         try {
 166             // Create file to which we do not append
 167             logFile = new FileWriter(logFileName, false);
 168         } catch (IOException e) {
 169             System.out.println("Unable to open logfile :" + logFileName + "\nNo logs will be created");
 170             logFile = null;
 171         }
 172     }
 173 
 174     static void writeLog(String str) {
 175         if (logFile != null) {
 176             try {
 177                 logFile.write(str + "\n");
 178                 logFile.flush();
 179             } catch (IOException e) {
 180                 // Print to console
 181                 System.out.println(str + "\n");
 182             }
 183         }
 184     }
 185 
 186     static void closeLog() {
 187         if (logFile != null) {
 188             try {
 189                 logFile.close();
 190             } catch (IOException e) {
 191                 // Do nothing
 192             }
 193         }
 194     }
 195 
 196 }