src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java
changeset 50113 caf115bb98ad
child 57360 5d043a159d5c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java	Tue May 15 20:24:34 2018 +0200
@@ -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<SettingDescriptor> 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<SettingDescriptor> getSettings() {
+        if (dynamicSettings) {
+            List<SettingDescriptor> list = new ArrayList<>(settings.size());
+            for (SettingDescriptor s : settings) {
+                if (Utils.isSettingVisible(s.getTypeId(), hasHook)) {
+                    list.add(s);
+                }
+            }
+            return list;
+        }
+        return settings;
+    }
+
+    public List<SettingDescriptor> 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;
+    }
+}