/* * Copyright (c) 2013-2015 Chris Newland. * Licensed under https://github.com/AdoptOpenJDK/jitwatch/blob/master/LICENSE-BSD * Instructions: https://github.com/AdoptOpenJDK/jitwatch/wiki */ package org.adoptopenjdk.jitwatch.util; import org.adoptopenjdk.jitwatch.model.bytecode.Opcode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.C_OPEN_ANGLE; import static org.adoptopenjdk.jitwatch.core.JITWatchConstants.S_DOUBLE_QUOTE; public final class JVMSUtil { private static final Logger logger = LoggerFactory.getLogger(JVMSUtil.class); private static Map<String, String> bcDescriptionMap = new HashMap<>(); private static final String JVMS_HTML_FILENAME = "JVMS.html"; private static final String JVMS_CSS_FILENAME = "JVMS.css"; private JVMSUtil() { } public static boolean hasLocalJVMS() { File file = new File(JVMS_HTML_FILENAME); return file.exists(); } public static boolean isJVMSLoaded() { return bcDescriptionMap.size() > 0; } public static String getJVMSCSSURL() { File cssFile = new File(JVMS_CSS_FILENAME); if (cssFile.exists()) { return cssFile.toURI().toString(); } else { return null; } } public static boolean fetchJVMS() { String html = NetUtil.fetchURL("http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html"); String css = NetUtil.fetchURL("http://docs.oracle.com/javase/specs/javaspec.css"); boolean result = false; if (html.length() > 0 && css.length() > 0) { Path pathHTML = Paths.get(new File(JVMS_HTML_FILENAME).toURI()); Path pathCSS = Paths.get(new File(JVMS_CSS_FILENAME).toURI()); try { Files.write(pathHTML, html.getBytes(StandardCharsets.UTF_8)); Files.write(pathCSS, css.getBytes(StandardCharsets.UTF_8)); result = true; } catch (IOException ioe) { logger.error("Could not save JVMS to disk", ioe); } } return result; } public static void loadJVMS() { try { Path path = Paths.get(new File(JVMS_HTML_FILENAME).toURI()); String html = new String(Files.readAllBytes(path), StandardCharsets.UTF_8); int htmlLength = html.length(); String descStart = "<div class=\"section-execution\""; int startPos = html.indexOf(descStart); while (startPos != -1 && startPos < htmlLength) { int endPos = html.indexOf(descStart, startPos + descStart.length()); if (endPos != -1) { String desc = html.substring(startPos, endPos); storeBytecodeDescription(desc); startPos = endPos; } else if (startPos != -1) { String desc = html.substring(startPos); storeBytecodeDescription(desc); break; } else { break; } } } catch (IOException ioe) { logger.error("", ioe); } } private static void storeBytecodeDescription(String description) { String title = StringUtil.getSubstringBetween(description, "<div class=\"section-execution\" title=\"", S_DOUBLE_QUOTE); if (title != null) { bcDescriptionMap.put(title, description); } } public static String getBytecodeDescriptions(Opcode opcode) { String opcodeText = opcode.getMnemonic(); String desc = bcDescriptionMap.get(opcodeText); if (desc == null) { for (Map.Entry<String, String> entry : bcDescriptionMap.entrySet()) { String key = entry.getKey(); int ltPos = key.indexOf(C_OPEN_ANGLE); // ifge => if<cond> // lconst_1 => lconst_<n> if (ltPos != -1) { if (ltPos < opcodeText.length()) { String subOpcodeText = opcodeText.substring(0, ltPos); String subKey = key.substring(0, ltPos); if (subOpcodeText.equals(subKey)) { desc = entry.getValue(); break; } } } } } return desc; } }