--- /dev/null 2019-02-07 20:54:51.336000000 +0300 +++ new/src/share/classes/jdk/jfr/internal/PlatformEventType.java 2019-02-08 18:32:32.710281297 +0300 @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jfr.internal; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import jdk.jfr.SettingDescriptor; + +/** + * Implementation of event type. + * + * To avoid memory leaks, this class must not hold strong reference to an event + * class or a setting class + */ +public final class PlatformEventType extends Type { + private final boolean isJVM; + private final boolean isJDK; + private final boolean isMethodSampling; + private final List settings = new ArrayList<>(5); + private final boolean dynamicSettings; + private final int stackTraceOffset; + + // default values + private boolean enabled = false; + private boolean stackTraceEnabled = true; + private long thresholdTicks = 0; + private long period = 0; + private boolean hasHook; + + private boolean beginChunk; + private boolean endChunk; + private boolean hasStackTrace = true; + private boolean hasDuration = true; + private boolean hasPeriod = true; + private boolean hasCutoff = false; + private boolean isInstrumented; + private boolean markForInstrumentation; + private boolean registered = true; + private boolean commitable = enabled && registered; + + + // package private + PlatformEventType(String name, long id, boolean isJDK, boolean dynamicSettings) { + super(name, Type.SUPER_TYPE_EVENT, id); + this.dynamicSettings = dynamicSettings; + this.isJVM = Type.isDefinedByJVM(id); + this.isMethodSampling = name.equals(Type.EVENT_NAME_PREFIX + "ExecutionSample") || name.equals(Type.EVENT_NAME_PREFIX + "NativeMethodSample"); + this.isJDK = isJDK; + this.stackTraceOffset = stackTraceOffset(name, isJDK); + } + + private static int stackTraceOffset(String name, boolean isJDK) { + if (isJDK) { + if (name.equals(Type.EVENT_NAME_PREFIX + "JavaExceptionThrow")) { + return 5; + } + if (name.equals(Type.EVENT_NAME_PREFIX + "JavaErrorThrow")) { + return 5; + } + } + return 4; + } + + public void add(SettingDescriptor settingDescriptor) { + Objects.requireNonNull(settingDescriptor); + settings.add(settingDescriptor); + } + + public List getSettings() { + if (dynamicSettings) { + List list = new ArrayList<>(settings.size()); + for (SettingDescriptor s : settings) { + if (Utils.isSettingVisible(s.getTypeId(), hasHook)) { + list.add(s); + } + } + return list; + } + return settings; + } + + public List getAllSettings() { + return settings; + } + + public void setHasStackTrace(boolean hasStackTrace) { + this.hasStackTrace = hasStackTrace; + } + + public void setHasDuration(boolean hasDuration) { + this.hasDuration = hasDuration; + } + + public void setHasCutoff(boolean hasCutoff) { + this.hasCutoff = hasCutoff; + } + + public void setCutoff(long cutoffNanos) { + if (isJVM) { + long cutoffTicks = Utils.nanosToTicks(cutoffNanos); + JVM.getJVM().setCutoff(getId(), cutoffTicks); + } + } + + public void setHasPeriod(boolean hasPeriod) { + this.hasPeriod = hasPeriod; + } + + public boolean hasStackTrace() { + return this.hasStackTrace; + } + + public boolean hasDuration() { + return this.hasDuration; + } + + public boolean hasPeriod() { + return this.hasPeriod; + } + + public boolean hasCutoff() { + return this.hasCutoff; + } + + public boolean isEnabled() { + return enabled; + } + + public boolean isJVM() { + return isJVM; + } + + public boolean isJDK() { + return isJDK; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + updateCommitable(); + if (isJVM) { + if (isMethodSampling) { + long p = enabled ? period : 0; + JVM.getJVM().setMethodSamplingInterval(getId(), p); + } else { + JVM.getJVM().setEnabled(getId(), enabled); + } + } + } + + public void setPeriod(long periodMillis, boolean beginChunk, boolean endChunk) { + if (isMethodSampling) { + long p = enabled ? periodMillis : 0; + JVM.getJVM().setMethodSamplingInterval(getId(), p); + } + this.beginChunk = beginChunk; + this.endChunk = endChunk; + this.period = periodMillis; + } + + public void setStackTraceEnabled(boolean stackTraceEnabled) { + this.stackTraceEnabled = stackTraceEnabled; + if (isJVM) { + JVM.getJVM().setStackTraceEnabled(getId(), stackTraceEnabled); + } + } + + public void setThreshold(long thresholdNanos) { + this.thresholdTicks = Utils.nanosToTicks(thresholdNanos); + if (isJVM) { + JVM.getJVM().setThreshold(getId(), thresholdTicks); + } + } + + public boolean isEveryChunk() { + return period == 0; + } + + public boolean getStackTraceEnabled() { + return stackTraceEnabled; + } + + public long getThresholdTicks() { + return thresholdTicks; + } + + public long getPeriod() { + return period; + } + + public boolean hasEventHook() { + return hasHook; + } + + public void setEventHook(boolean hasHook) { + this.hasHook = hasHook; + } + + public boolean isBeginChunk() { + return beginChunk; + } + + public boolean isEndChunk() { + return endChunk; + } + + public boolean isInstrumented() { + return isInstrumented; + } + + public void setInstrumented() { + isInstrumented = true; + } + + public void markForInstrumentation(boolean markForInstrumentation) { + this.markForInstrumentation = markForInstrumentation; + } + + public boolean isMarkedForInstrumentation() { + return markForInstrumentation; + } + + public boolean setRegistered(boolean registered) { + if (this.registered != registered) { + this.registered = registered; + updateCommitable(); + LogTag logTag = isJVM() || isJDK() ? LogTag.JFR_SYSTEM_EVENT : LogTag.JFR_EVENT; + if (registered) { + Logger.log(logTag, LogLevel.INFO, "Registered " + getLogName()); + } else { + Logger.log(logTag, LogLevel.INFO, "Unregistered " + getLogName()); + } + if (!registered) { + MetadataRepository.getInstance().setUnregistered(); + } + return true; + } + return false; + } + + private void updateCommitable() { + this.commitable = enabled && registered; + } + + public final boolean isRegistered() { + return registered; + } + + // Efficient check of enabled && registered + public boolean isCommitable() { + return commitable; + } + + public int getStackTraceOffset() { + return stackTraceOffset; + } +}