001/* 002 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package jdk.internal.jvmci.hotspot.jfr.events; 024 025import java.net.*; 026 027import jdk.internal.jvmci.hotspot.*; 028import jdk.internal.jvmci.hotspot.events.*; 029import jdk.internal.jvmci.hotspot.events.EmptyEventProvider.*; 030import jdk.internal.jvmci.service.*; 031 032import com.oracle.jrockit.jfr.*; 033 034/** 035 * A JFR implementation for {@link EventProvider}. This implementation is used when Flight Recorder 036 * is turned on. 037 */ 038@ServiceProvider(EventProvider.class) 039public final class JFREventProvider implements EventProvider { 040 041 private final boolean enabled; 042 043 @SuppressWarnings("deprecation") 044 public JFREventProvider() { 045 enabled = HotSpotJVMCIRuntime.runtime().getConfig().flightRecorder; 046 if (enabled) { 047 try { 048 /* 049 * The "HotSpot JVM" producer is a native producer and we cannot use it. So we 050 * create our own. This has the downside that Mission Control is confused and 051 * doesn't show JVMCI events in the "Code" tab. There are plans to revise the JFR 052 * code for JDK 9. 053 */ 054 Producer producer = new Producer("HotSpot JVM", "Oracle Hotspot JVM", "http://www.oracle.com/hotspot/jvm/"); 055 producer.register(); 056 // Register event classes with Producer. 057 for (Class<?> c : JFREventProvider.class.getDeclaredClasses()) { 058 if (c.isAnnotationPresent(EventDefinition.class)) { 059 assert com.oracle.jrockit.jfr.InstantEvent.class.isAssignableFrom(c) : c; 060 registerEvent(producer, c); 061 } 062 } 063 } catch (URISyntaxException e) { 064 throw new InternalError(e); 065 } 066 } 067 } 068 069 /** 070 * Register an event class with the {@link Producer}. 071 * 072 * @param c event class 073 * @return the {@link EventToken event token} 074 */ 075 @SuppressWarnings({"deprecation", "javadoc", "unchecked"}) 076 private static EventToken registerEvent(Producer producer, Class<?> c) { 077 try { 078 return producer.addEvent((Class<? extends com.oracle.jrockit.jfr.InstantEvent>) c); 079 } catch (InvalidEventDefinitionException | InvalidValueException e) { 080 throw new InternalError(e); 081 } 082 } 083 084 public CompilationEvent newCompilationEvent() { 085 if (enabled) { 086 return new JFRCompilationEvent(); 087 } 088 return new EmptyCompilationEvent(); 089 } 090 091 /** 092 * A JFR compilation event. 093 * 094 * <p> 095 * See: event {@code Compilation} in {@code src/share/vm/trace/trace.xml} 096 */ 097 @SuppressWarnings("deprecation") 098 @EventDefinition(name = "Compilation", path = "vm/compiler/compilation") 099 public static class JFRCompilationEvent extends com.oracle.jrockit.jfr.DurationEvent implements CompilationEvent { 100 101 /* 102 * FIXME method should be a Method* but we can't express that in Java. 103 */ 104 @ValueDefinition(name = "Java Method") public String method; 105 @ValueDefinition(name = "Compilation ID", relationKey = "COMP_ID") public int compileId; 106 @ValueDefinition(name = "Compilation Level") public short compileLevel; 107 @ValueDefinition(name = "Succeeded") public boolean succeeded; 108 @ValueDefinition(name = "On Stack Replacement") public boolean isOsr; 109 @ValueDefinition(name = "Compiled Code Size", contentType = ContentType.Bytes) public int codeSize; 110 @ValueDefinition(name = "Inlined Code Size", contentType = ContentType.Bytes) public int inlinedBytes; 111 112 public void setMethod(String method) { 113 this.method = method; 114 } 115 116 public void setCompileId(int id) { 117 this.compileId = id; 118 } 119 120 public void setCompileLevel(int compileLevel) { 121 this.compileLevel = (short) compileLevel; 122 } 123 124 public void setSucceeded(boolean succeeded) { 125 this.succeeded = succeeded; 126 } 127 128 public void setIsOsr(boolean isOsr) { 129 this.isOsr = isOsr; 130 } 131 132 public void setCodeSize(int codeSize) { 133 this.codeSize = codeSize; 134 } 135 136 public void setInlinedBytes(int inlinedBytes) { 137 this.inlinedBytes = inlinedBytes; 138 } 139 } 140 141 public CompilerFailureEvent newCompilerFailureEvent() { 142 if (enabled) { 143 return new JFRCompilerFailureEvent(); 144 } 145 return new EmptyCompilerFailureEvent(); 146 } 147 148 /** 149 * A JFR compiler failure event. 150 * 151 * <p> 152 * See: event {@code CompilerFailure} in {@code src/share/vm/trace/trace.xml} 153 */ 154 @SuppressWarnings("deprecation") 155 @EventDefinition(name = "Compilation Failure", path = "vm/compiler/failure") 156 public static class JFRCompilerFailureEvent extends com.oracle.jrockit.jfr.InstantEvent implements CompilerFailureEvent { 157 158 @ValueDefinition(name = "Compilation ID", relationKey = "COMP_ID") public int compileId; 159 @ValueDefinition(name = "Message", description = "The failure message") public String failure; 160 161 public void setCompileId(int id) { 162 this.compileId = id; 163 } 164 165 public void setMessage(String message) { 166 this.failure = message; 167 } 168 } 169 170}