Skip to content

Commit ecd0fb8

Browse files
committed
[#531] JFR events for allocation and resizing
* Requires JFR package. * Covering read and write path.
1 parent b712306 commit ecd0fb8

File tree

14 files changed

+297
-3
lines changed

14 files changed

+297
-3
lines changed

core/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
requires static jcip.annotations;
77
requires org.jboss.logging;
88
requires static org.jboss.logging.annotations;
9+
requires jdk.jfr;
910
opens org.infinispan.protostream;
1011
exports org.infinispan.protostream;
1112
exports org.infinispan.protostream.annotations;

core/src/main/java/org/infinispan/protostream/impl/ProtoStreamReaderImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.infinispan.protostream.descriptors.MapDescriptor;
2828
import org.infinispan.protostream.descriptors.Type;
2929
import org.infinispan.protostream.descriptors.WireType;
30+
import org.infinispan.protostream.impl.jfr.JfrEventPublisher;
3031
import org.jboss.logging.Logger;
3132

3233
/**
@@ -187,6 +188,7 @@ public Integer readInt(String fieldName) throws IOException {
187188
public int[] readInts(String fieldName) throws IOException {
188189
List<Integer> values = readCollection(fieldName, new ArrayList<>(), Integer.class);
189190
int[] result = new int[values.size()];
191+
JfrEventPublisher.intBufferAllocateEvent(result.length);
190192
for (int i = 0; i < values.size(); i++) {
191193
result[i] = values.get(i);
192194
}
@@ -202,6 +204,7 @@ public Long readLong(String fieldName) throws IOException {
202204
public long[] readLongs(String fieldName) throws IOException {
203205
List<Long> values = readCollection(fieldName, new ArrayList<>(), Long.class);
204206
long[] result = new long[values.size()];
207+
JfrEventPublisher.longBufferAllocateEvent(result.length);
205208
for (int i = 0; i < values.size(); i++) {
206209
result[i] = values.get(i);
207210
}
@@ -229,6 +232,7 @@ public Float readFloat(String fieldName) throws IOException {
229232
public float[] readFloats(String fieldName) throws IOException {
230233
List<Float> values = readCollection(fieldName, new ArrayList<>(), Float.class);
231234
float[] result = new float[values.size()];
235+
JfrEventPublisher.floatBufferAllocateEvent(result.length);
232236
for (int i = 0; i < values.size(); i++) {
233237
result[i] = values.get(i);
234238
}
@@ -244,6 +248,7 @@ public Double readDouble(String fieldName) throws IOException {
244248
public double[] readDoubles(String fieldName) throws IOException {
245249
List<Double> values = readCollection(fieldName, new ArrayList<>(), Double.class);
246250
double[] result = new double[values.size()];
251+
JfrEventPublisher.doubleBufferAllocateEvent(result.length);
247252
for (int i = 0; i < values.size(); i++) {
248253
result[i] = values.get(i);
249254
}
@@ -259,6 +264,7 @@ public Boolean readBoolean(String fieldName) throws IOException {
259264
public boolean[] readBooleans(String fieldName) throws IOException {
260265
List<Boolean> values = readCollection(fieldName, new ArrayList<>(), Boolean.class);
261266
boolean[] result = new boolean[values.size()];
267+
JfrEventPublisher.bufferAllocateEvent(result.length);
262268
for (int i = 0; i < values.size(); i++) {
263269
result[i] = values.get(i);
264270
}

core/src/main/java/org/infinispan/protostream/impl/ProtoStreamWriterImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.infinispan.protostream.descriptors.MapDescriptor;
2121
import org.infinispan.protostream.descriptors.Type;
2222
import org.infinispan.protostream.descriptors.WireType;
23+
import org.infinispan.protostream.impl.jfr.JfrEventPublisher;
2324
import org.jboss.logging.Logger;
2425

2526
/**
@@ -452,10 +453,12 @@ public void writeBytes(String fieldName, InputStream input) throws IOException {
452453
int len = 0;
453454
List<byte[]> chunks = new LinkedList<>();
454455
int bufLen;
456+
JfrEventPublisher.bufferAllocateEvent(CHUNK_SIZE);
455457
byte[] buffer = new byte[CHUNK_SIZE];
456458
while ((bufLen = input.read(buffer)) != -1) {
457459
chunks.add(buffer);
458460
len += bufLen;
461+
JfrEventPublisher.bufferAllocateEvent(CHUNK_SIZE);
459462
buffer = new byte[CHUNK_SIZE];
460463
}
461464
input.close();

core/src/main/java/org/infinispan/protostream/impl/RandomAccessOutputStreamImpl.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.infinispan.protostream.RandomAccessOutputStream;
1010

1111
import net.jcip.annotations.NotThreadSafe;
12+
import org.infinispan.protostream.impl.jfr.JfrEventPublisher;
1213

1314
@NotThreadSafe
1415
public class RandomAccessOutputStreamImpl extends OutputStream implements RandomAccessOutputStream {
@@ -27,6 +28,7 @@ public RandomAccessOutputStreamImpl(int capacity) {
2728
if (capacity < 0)
2829
throw new IllegalArgumentException("Negative initial capacity: " + capacity);
2930
this.buf = new byte[capacity];
31+
JfrEventPublisher.bufferAllocateEvent(capacity);
3032
}
3133

3234
@Override
@@ -73,11 +75,16 @@ public void move(int startPos, int length, int newPos) {
7375
@Override
7476
public void ensureCapacity(int capacity) {
7577
if (buf == null) {
76-
buf = new byte[Math.max(MIN_SIZE, capacity)];
78+
int cap = Math.max(MIN_SIZE, capacity);
79+
buf = new byte[cap];
80+
JfrEventPublisher.bufferAllocateEvent(cap);
7781
} else if (capacity > buf.length) {
78-
byte[] newbuf = new byte[getNewBufferSize(buf.length, capacity)];
82+
int before = buf.length;
83+
int cap = getNewBufferSize(buf.length, capacity);
84+
byte[] newbuf = new byte[cap];
7985
System.arraycopy(buf, 0, newbuf, 0, pos);
8086
buf = newbuf;
87+
JfrEventPublisher.bufferResizeEvent(before, cap);
8188
}
8289
}
8390

@@ -100,6 +107,7 @@ public void setPosition(int position) {
100107

101108
@Override
102109
public byte[] toByteArray() {
110+
JfrEventPublisher.bufferAllocateEvent(pos);
103111
return Arrays.copyOf(buf, pos);
104112
}
105113

core/src/main/java/org/infinispan/protostream/impl/StringUtil.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.function.Function;
1414
import java.util.function.Predicate;
1515

16+
import org.infinispan.protostream.impl.jfr.JfrEventPublisher;
1617
import sun.misc.Unsafe;
1718

1819
class StringUtil {
@@ -52,7 +53,9 @@ public boolean providesLatin1Bytes() {
5253

5354
@Override
5455
public byte[] getBytes(String s) {
55-
return s.getBytes(StandardCharsets.UTF_8);
56+
byte[] b = s.getBytes(StandardCharsets.UTF_8);
57+
JfrEventPublisher.bufferAllocateEvent(b.length);
58+
return b;
5659
}
5760
};
5861
}

core/src/main/java/org/infinispan/protostream/impl/TagReaderImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.infinispan.protostream.ProtobufTagMarshaller;
2222
import org.infinispan.protostream.TagReader;
2323
import org.infinispan.protostream.descriptors.WireType;
24+
import org.infinispan.protostream.impl.jfr.JfrEventPublisher;
2425

2526
/**
2627
@@ -520,6 +521,7 @@ byte[] getBufferArray(int offset) {
520521
if (offset == 0) {
521522
return array;
522523
}
524+
JfrEventPublisher.bufferAllocateEvent(array.length - offset);
523525
return Arrays.copyOfRange(array, offset, array.length);
524526
}
525527

@@ -532,6 +534,7 @@ boolean isAtEnd() {
532534
String readString() throws IOException {
533535
int length = readVarint32();
534536
if (length > 0 && length <= end - pos) {
537+
JfrEventPublisher.bufferAllocateEvent(length);
535538
String value = new String(array, pos, length, UTF8);
536539
pos += length;
537540
return value;
@@ -638,6 +641,7 @@ byte[] readRawByteArray(int length) throws IOException {
638641
if (length > 0 && length <= end - pos) {
639642
int from = pos;
640643
pos += length;
644+
JfrEventPublisher.bufferAllocateEvent(pos - from);
641645
return Arrays.copyOfRange(array, from, pos);
642646
}
643647
if (length == 0) {
@@ -728,6 +732,7 @@ byte[] getBufferArray(int offset) {
728732
if (offset == 0) {
729733
return array;
730734
}
735+
JfrEventPublisher.bufferAllocateEvent(array.length - offset);
731736
return Arrays.copyOfRange(array, offset, array.length);
732737
}
733738

@@ -741,6 +746,7 @@ boolean isAtEnd() {
741746
String readString() throws IOException {
742747
int length = readVarint32();
743748
if (length > 0 && length <= end - buf.position()) {
749+
JfrEventPublisher.bufferAllocateEvent(length);
744750
byte[] bytes = new byte[length];
745751
buf.get(bytes);
746752
return new String(bytes, 0, length, UTF8);
@@ -842,6 +848,7 @@ byte readRawByte() throws IOException {
842848
@Override
843849
byte[] readRawByteArray(int length) throws IOException {
844850
if (length > 0 && length <= end - buf.position()) {
851+
JfrEventPublisher.bufferAllocateEvent(length);
845852
byte[] bytes = new byte[length];
846853
buf.get(bytes);
847854
return bytes;
@@ -1085,6 +1092,7 @@ byte[] readRawByteArray(int length) throws IOException {
10851092
}
10861093
int readTotal = 0;
10871094
int readAmount;
1095+
JfrEventPublisher.bufferAllocateEvent(length);
10881096
byte[] array = new byte[length];
10891097
while ((readAmount = in.read(array, readTotal, length - readTotal)) != -1) {
10901098
readTotal += readAmount;

core/src/main/java/org/infinispan/protostream/impl/TagWriterImpl.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.infinispan.protostream.RandomAccessOutputStream;
2121
import org.infinispan.protostream.TagWriter;
2222
import org.infinispan.protostream.descriptors.WireType;
23+
import org.infinispan.protostream.impl.jfr.JfrEventPublisher;
2324

2425
/**
2526
@@ -584,6 +585,7 @@ void writeUTF8Field(int fieldNumber, String s) {
584585
if (c > 127) {
585586
// TODO: do this without allocating the byte[]
586587
count = s.getBytes(StandardCharsets.UTF_8).length;
588+
JfrEventPublisher.bufferAllocateEvent(count);
587589
break;
588590
}
589591
}
@@ -607,13 +609,16 @@ void resize(int maxDepth) {
607609
if (nestedPositions == null) {
608610
// We are guessing most objects won't have larger than 4 sub elements
609611
nestedPositions = new int[10];
612+
JfrEventPublisher.intBufferAllocateEvent(nestedPositions.length);
610613
} else {
611614
if (head == nestedPositions.length) {
615+
int before = nestedPositions.length;
612616
int newLength = Math.min(nestedPositions.length + 10, maxDepth);
613617
if (newLength == maxDepth) {
614618
throw log.maxNestedMessageDepth(maxDepth, null);
615619
}
616620
nestedPositions = Arrays.copyOf(nestedPositions, newLength);
621+
JfrEventPublisher.intBufferResizeEvent(before, newLength);
617622
}
618623
}
619624
}
@@ -1007,6 +1012,7 @@ void writeBytes(ByteBuffer value) throws IOException {
10071012
if (value.hasArray()) {
10081013
out.write(value.array(), value.arrayOffset(), value.remaining());
10091014
} else {
1015+
JfrEventPublisher.bufferAllocateEvent(value.remaining());
10101016
byte[] buffer = new byte[value.remaining()];
10111017
value.get(buffer, value.position(), value.remaining());
10121018
out.write(buffer);
@@ -1035,6 +1041,7 @@ private static final class OutputStreamEncoder extends Encoder {
10351041
// least their length varint should fit.
10361042
bufferSize = Math.max(bufferSize, MAX_VARINT_SIZE * 2);
10371043
buffer = new ByteArrayEncoder(new byte[bufferSize], 0, bufferSize);
1044+
JfrEventPublisher.bufferAllocateEvent(bufferSize);
10381045
this.out = out;
10391046
}
10401047

@@ -1348,6 +1355,7 @@ void writeUTF8FieldWithRewind(int number, String s) throws IOException {
13481355
}
13491356

13501357
byte[] utf8buffer = s.getBytes(StandardCharsets.UTF_8);
1358+
JfrEventPublisher.bufferAllocateEvent(utf8buffer.length);
13511359
out.ensureCapacity(startPos + MAX_INT_VARINT_SIZE + utf8buffer.length);
13521360

13531361
startPos = writeVarInt32Direct(startPos, utf8buffer.length);
@@ -1430,12 +1438,14 @@ Encoder subEncoder(int number, int maxDepth) throws IOException {
14301438
out.setPosition(pos + 1);
14311439
if (positions == null) {
14321440
positions = new int[10];
1441+
JfrEventPublisher.intBufferAllocateEvent(positions.length);
14331442
} else if (head == positions.length) {
14341443
int newSize = Math.min(head + 10, maxDepth);
14351444
if (newSize == maxDepth) {
14361445
throw log.maxNestedMessageDepth(maxDepth, null);
14371446
}
14381447
positions = Arrays.copyOf(positions, newSize);
1448+
JfrEventPublisher.intBufferResizeEvent(head, newSize);
14391449
}
14401450
positions[head++] = pos + 1;
14411451
return this;

core/src/main/java/org/infinispan/protostream/impl/UnknownFieldSetImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.infinispan.protostream.TagWriter;
1717
import org.infinispan.protostream.UnknownFieldSet;
1818
import org.infinispan.protostream.descriptors.WireType;
19+
import org.infinispan.protostream.impl.jfr.JfrEventPublisher;
1920

2021
/**
2122
* {@link UnknownFieldSet} implementation. This is not thread-safe. This class should never be directly instantiated by
@@ -208,6 +209,7 @@ public void writeExternal(ObjectOutput out) throws IOException {
208209
@Override
209210
public void readExternal(ObjectInput in) throws IOException {
210211
int len = in.readInt();
212+
JfrEventPublisher.bufferAllocateEvent(len);
211213
byte[] bytes = new byte[len];
212214
in.readFully(bytes);
213215
readAllFields(TagReaderImpl.newInstance(null, bytes));
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.infinispan.protostream.impl.jfr;
2+
3+
import jdk.jfr.Category;
4+
import jdk.jfr.DataAmount;
5+
import jdk.jfr.Description;
6+
import jdk.jfr.Enabled;
7+
import jdk.jfr.Event;
8+
9+
@Enabled(value = false)
10+
@Category("ProtoStream")
11+
class AbstractAllocatorEvent extends Event {
12+
13+
@DataAmount
14+
@Description("Allocation size")
15+
int size;
16+
17+
AbstractAllocatorEvent(int size) {
18+
this.size = size;
19+
}
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.infinispan.protostream.impl.jfr;
2+
3+
import jdk.jfr.Description;
4+
import jdk.jfr.Label;
5+
import jdk.jfr.Name;
6+
7+
@Name(BufferAllocateEvent.NAME)
8+
@Label("Buffer Allocation")
9+
@Description("Triggered when a new buffer is allocated")
10+
final class BufferAllocateEvent extends AbstractAllocatorEvent {
11+
static final String NAME = "org.infinispan.protostream.AllocateEvent";
12+
13+
private static final BufferAllocateEvent INSTANCE = new BufferAllocateEvent(0);
14+
15+
BufferAllocateEvent(int size) {
16+
super(size);
17+
}
18+
19+
public static boolean isEventEnabled() {
20+
return INSTANCE.isEnabled();
21+
}
22+
}

0 commit comments

Comments
 (0)