src/jdk.jfr/share/classes/jdk/jfr/internal/EventWriter.java
author mgronlun
Wed, 30 Oct 2019 19:43:52 +0100
changeset 58863 c16ac7a2eba4
parent 50113 caf115bb98ad
permissions -rw-r--r--
8226511: Implement JFR Event Streaming Reviewed-by: egahlin, mseledtsov, mgronlun Contributed-by: erik.gahlin@oracle.com, mikhailo.seledtsov@oracle.com, markus.gronlund@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     1
/*
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 50113
diff changeset
     2
 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     4
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    10
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    15
 * accompanied this code).
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    16
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    20
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    23
 * questions.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    24
 */
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    25
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    26
package jdk.jfr.internal;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    27
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    28
import jdk.internal.misc.Unsafe;
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 50113
diff changeset
    29
import jdk.jfr.internal.consumer.StringParser;
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    30
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    31
/**
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    32
 * Class must reside in a package with package restriction.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    33
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    34
 * Users should not have direct access to underlying memory.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    35
 *
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    36
 */
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    37
public final class EventWriter {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    38
    private static final Unsafe unsafe = Unsafe.getUnsafe();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    39
    private final static JVM jvm = JVM.getJVM();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    40
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    41
    private long startPosition;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    42
    private long startPositionAddress;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    43
    private long currentPosition;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    44
    private long maxPosition;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    45
    private final long threadID;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    46
    private PlatformEventType eventType;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    47
    private int maxEventSize;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    48
    private boolean started;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    49
    private boolean valid;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    50
    private boolean flushOnEnd;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    51
    // set by the JVM, not private to avoid being optimized out
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    52
    boolean notified;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    53
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    54
    public static EventWriter getEventWriter() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    55
        EventWriter ew = (EventWriter)JVM.getEventWriter();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    56
        return ew != null ? ew : JVM.newEventWriter();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    57
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    58
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    59
    public void putBoolean(boolean i) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    60
        if (isValidForSize(Byte.BYTES)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    61
            currentPosition += Bits.putBoolean(currentPosition, i);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    62
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    63
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    64
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    65
    public void putByte(byte i) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    66
        if (isValidForSize(Byte.BYTES)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    67
            unsafe.putByte(currentPosition, i);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    68
            ++currentPosition;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    69
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    70
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    71
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    72
    public void putChar(char v) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    73
        if (isValidForSize(Character.BYTES + 1)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    74
            putUncheckedLong(v);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    75
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    76
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    77
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    78
    private void putUncheckedChar(char v) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    79
        putUncheckedLong(v);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    80
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    81
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    82
    public void putShort(short v) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    83
        if (isValidForSize(Short.BYTES + 1)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    84
            putUncheckedLong(v & 0xFFFF);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    85
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    86
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    87
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    88
    public void putInt(int v) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    89
        if (isValidForSize(Integer.BYTES + 1)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    90
            putUncheckedLong(v & 0x00000000ffffffffL);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    91
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    92
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    93
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    94
    private void putUncheckedInt(int v) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    95
        putUncheckedLong(v & 0x00000000ffffffffL);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    96
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    97
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    98
    public void putFloat(float i) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
    99
        if (isValidForSize(Float.BYTES)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   100
            currentPosition += Bits.putFloat(currentPosition, i);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   101
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   102
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   103
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   104
    public void putLong(long v) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   105
        if (isValidForSize(Long.BYTES + 1)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   106
            putUncheckedLong(v);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   107
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   108
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   109
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   110
    public void putDouble(double i) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   111
        if (isValidForSize(Double.BYTES)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   112
            currentPosition += Bits.putDouble(currentPosition, i);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   113
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   114
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   115
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   116
    public void putString(String s, StringPool pool) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   117
        if (s == null) {
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 50113
diff changeset
   118
            putByte(StringParser.Encoding.NULL.byteValue());
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   119
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   120
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   121
        int length = s.length();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   122
        if (length == 0) {
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 50113
diff changeset
   123
            putByte(StringParser.Encoding.EMPTY_STRING.byteValue());
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   124
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   125
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   126
        if (length > StringPool.MIN_LIMIT && length < StringPool.MAX_LIMIT) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   127
            long l = StringPool.addString(s);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   128
            if (l > 0) {
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 50113
diff changeset
   129
                putByte(StringParser.Encoding.CONSTANT_POOL.byteValue());
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   130
                putLong(l);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   131
                return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   132
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   133
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   134
        putStringValue(s);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   135
        return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   136
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   137
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   138
    private void putStringValue(String s) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   139
        int length = s.length();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   140
        if (isValidForSize(1 + 5 + 3 * length)) {
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 50113
diff changeset
   141
            putUncheckedByte(StringParser.Encoding.CHAR_ARRAY.byteValue()); // 1 byte
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   142
            putUncheckedInt(length); // max 5 bytes
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   143
            for (int i = 0; i < length; i++) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   144
                putUncheckedChar(s.charAt(i)); // max 3 bytes
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   145
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   146
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   147
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   148
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   149
    public void putEventThread() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   150
        putLong(threadID);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   151
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   152
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   153
    public void putThread(Thread athread) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   154
        if (athread == null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   155
            putLong(0L);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   156
        } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   157
            putLong(jvm.getThreadId(athread));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   158
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   159
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   160
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   161
    public void putClass(Class<?> aClass) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   162
        if (aClass == null) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   163
            putLong(0L);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   164
        } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   165
            putLong(JVM.getClassIdNonIntrinsic(aClass));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   166
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   167
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   168
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   169
    public void putStackTrace() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   170
        if (eventType.getStackTraceEnabled()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   171
            putLong(jvm.getStackTraceId(eventType.getStackTraceOffset()));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   172
        } else {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   173
            putLong(0L);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   174
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   175
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   176
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   177
    private void reserveEventSizeField() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   178
        // move currentPosition Integer.Bytes offset from start position
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   179
        if (isValidForSize(Integer.BYTES)) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   180
            currentPosition += Integer.BYTES;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   181
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   182
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   183
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   184
    private void reset() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   185
        currentPosition = startPosition;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   186
        if (flushOnEnd) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   187
            flushOnEnd = flush();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   188
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   189
        valid = true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   190
        started = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   191
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   192
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   193
    private boolean isValidForSize(int requestedSize) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   194
        if (!valid) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   195
            return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   196
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   197
        if (currentPosition + requestedSize > maxPosition) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   198
            flushOnEnd = flush(usedSize(), requestedSize);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   199
            // retry
58863
c16ac7a2eba4 8226511: Implement JFR Event Streaming
mgronlun
parents: 50113
diff changeset
   200
            if (!valid) {
50113
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   201
                return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   202
            }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   203
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   204
        return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   205
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   206
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   207
    private boolean isNotified() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   208
        return notified;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   209
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   210
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   211
    private void resetNotified() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   212
        notified = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   213
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   214
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   215
    private int usedSize() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   216
        return (int) (currentPosition - startPosition);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   217
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   218
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   219
    private boolean flush() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   220
        return flush(usedSize(), 0);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   221
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   222
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   223
    private boolean flush(int usedSize, int requestedSize) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   224
        return JVM.flush(this, usedSize, requestedSize);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   225
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   226
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   227
    public boolean beginEvent(PlatformEventType eventType) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   228
        if (started) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   229
            // recursive write attempt
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   230
            return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   231
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   232
        started = true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   233
        this.eventType = eventType;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   234
        reserveEventSizeField();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   235
        putLong(eventType.getId());
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   236
        return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   237
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   238
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   239
    public boolean endEvent() {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   240
        if (!valid) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   241
            reset();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   242
            return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   243
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   244
        final int eventSize = usedSize();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   245
        if (eventSize > maxEventSize) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   246
            reset();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   247
            return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   248
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   249
        Bits.putInt(startPosition, makePaddedInt(eventSize));
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   250
        if (isNotified()) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   251
            resetNotified();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   252
            reset();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   253
            // returning false will trigger restart of the event write attempt
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   254
            return false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   255
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   256
        startPosition = currentPosition;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   257
        unsafe.putAddress(startPositionAddress, startPosition);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   258
        // the event is now committed
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   259
        if (flushOnEnd) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   260
            flushOnEnd = flush();
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   261
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   262
        started = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   263
        return true;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   264
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   265
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   266
    private EventWriter(long startPos, long maxPos, long startPosAddress, long threadID, boolean valid) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   267
        startPosition = currentPosition = startPos;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   268
        maxPosition = maxPos;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   269
        startPositionAddress = startPosAddress;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   270
        this.threadID = threadID;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   271
        started = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   272
        flushOnEnd = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   273
        this.valid = valid;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   274
        notified = false;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   275
        // event may not exceed size for a padded integer
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   276
        maxEventSize = (1 << 28) -1;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   277
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   278
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   279
    private static int makePaddedInt(int v) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   280
        // bit  0-6 + pad => bit 24 - 31
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   281
        long b1 = (((v >>> 0) & 0x7F) | 0x80) << 24;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   282
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   283
        // bit  7-13 + pad => bit 16 - 23
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   284
        long b2 = (((v >>> 7) & 0x7F) | 0x80) << 16;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   285
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   286
        // bit 14-20 + pad => bit  8 - 15
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   287
        long b3 = (((v >>> 14) & 0x7F) | 0x80) << 8;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   288
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   289
        // bit 21-28       => bit  0 -  7
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   290
        long b4 = (((v >>> 21) & 0x7F)) << 0;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   291
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   292
        return (int) (b1 + b2 + b3 + b4);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   293
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   294
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   295
    private void putUncheckedLong(long v) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   296
        if ((v & ~0x7FL) == 0L) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   297
            putUncheckedByte((byte) v); // 0-6
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   298
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   299
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   300
        putUncheckedByte((byte) (v | 0x80L)); // 0-6
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   301
        v >>>= 7;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   302
        if ((v & ~0x7FL) == 0L) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   303
            putUncheckedByte((byte) v); // 7-13
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   304
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   305
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   306
        putUncheckedByte((byte) (v | 0x80L)); // 7-13
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   307
        v >>>= 7;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   308
        if ((v & ~0x7FL) == 0L) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   309
            putUncheckedByte((byte) v); // 14-20
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   310
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   311
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   312
        putUncheckedByte((byte) (v | 0x80L)); // 14-20
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   313
        v >>>= 7;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   314
        if ((v & ~0x7FL) == 0L) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   315
            putUncheckedByte((byte) v); // 21-27
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   316
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   317
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   318
        putUncheckedByte((byte) (v | 0x80L)); // 21-27
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   319
        v >>>= 7;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   320
        if ((v & ~0x7FL) == 0L) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   321
            putUncheckedByte((byte) v); // 28-34
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   322
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   323
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   324
        putUncheckedByte((byte) (v | 0x80L)); // 28-34
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   325
        v >>>= 7;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   326
        if ((v & ~0x7FL) == 0L) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   327
            putUncheckedByte((byte) v); // 35-41
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   328
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   329
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   330
        putUncheckedByte((byte) (v | 0x80L)); // 35-41
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   331
        v >>>= 7;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   332
        if ((v & ~0x7FL) == 0L) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   333
            putUncheckedByte((byte) v); // 42-48
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   334
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   335
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   336
        putUncheckedByte((byte) (v | 0x80L)); // 42-48
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   337
        v >>>= 7;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   338
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   339
        if ((v & ~0x7FL) == 0L) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   340
            putUncheckedByte((byte) v); // 49-55
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   341
            return;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   342
        }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   343
        putUncheckedByte((byte) (v | 0x80L)); // 49-55
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   344
        putUncheckedByte((byte) (v >>> 7)); // 56-63, last byte as is.
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   345
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   346
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   347
    private void putUncheckedByte(byte i) {
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   348
        unsafe.putByte(currentPosition, i);
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   349
        ++currentPosition;
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   350
    }
caf115bb98ad 8199712: Flight Recorder
egahlin
parents:
diff changeset
   351
}