Skip to content

Commit e803c78

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

File tree

14 files changed

+230
-3
lines changed

14 files changed

+230
-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
@@ -26,6 +26,7 @@
2626
import org.infinispan.protostream.descriptors.MapDescriptor;
2727
import org.infinispan.protostream.descriptors.Type;
2828
import org.infinispan.protostream.descriptors.WireType;
29+
import org.infinispan.protostream.impl.jfr.JfrEventPublisher;
2930
import org.jboss.logging.Logger;
3031

3132
/**
@@ -186,6 +187,7 @@ public Integer readInt(String fieldName) throws IOException {
186187
public int[] readInts(String fieldName) throws IOException {
187188
List<Integer> values = readCollection(fieldName, new ArrayList<>(), Integer.class);
188189
int[] result = new int[values.size()];
190+
JfrEventPublisher.bufferAllocateEvent(result.length * Integer.BYTES);
189191
for (int i = 0; i < values.size(); i++) {
190192
result[i] = values.get(i);
191193
}
@@ -201,6 +203,7 @@ public Long readLong(String fieldName) throws IOException {
201203
public long[] readLongs(String fieldName) throws IOException {
202204
List<Long> values = readCollection(fieldName, new ArrayList<>(), Long.class);
203205
long[] result = new long[values.size()];
206+
JfrEventPublisher.bufferAllocateEvent(result.length * Long.BYTES);
204207
for (int i = 0; i < values.size(); i++) {
205208
result[i] = values.get(i);
206209
}
@@ -228,6 +231,7 @@ public Float readFloat(String fieldName) throws IOException {
228231
public float[] readFloats(String fieldName) throws IOException {
229232
List<Float> values = readCollection(fieldName, new ArrayList<>(), Float.class);
230233
float[] result = new float[values.size()];
234+
JfrEventPublisher.bufferAllocateEvent(result.length * Float.BYTES);
231235
for (int i = 0; i < values.size(); i++) {
232236
result[i] = values.get(i);
233237
}
@@ -243,6 +247,7 @@ public Double readDouble(String fieldName) throws IOException {
243247
public double[] readDoubles(String fieldName) throws IOException {
244248
List<Double> values = readCollection(fieldName, new ArrayList<>(), Double.class);
245249
double[] result = new double[values.size()];
250+
JfrEventPublisher.bufferAllocateEvent(result.length * Double.BYTES);
246251
for (int i = 0; i < values.size(); i++) {
247252
result[i] = values.get(i);
248253
}
@@ -258,6 +263,7 @@ public Boolean readBoolean(String fieldName) throws IOException {
258263
public boolean[] readBooleans(String fieldName) throws IOException {
259264
List<Boolean> values = readCollection(fieldName, new ArrayList<>(), Boolean.class);
260265
boolean[] result = new boolean[values.size()];
266+
JfrEventPublisher.bufferAllocateEvent(result.length);
261267
for (int i = 0; i < values.size(); i++) {
262268
result[i] = values.get(i);
263269
}

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, cap - before);
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
@@ -496,6 +497,7 @@ byte[] getBufferArray(int offset) {
496497
if (offset == 0) {
497498
return array;
498499
}
500+
JfrEventPublisher.bufferAllocateEvent(array.length - offset);
499501
return Arrays.copyOfRange(array, offset, array.length);
500502
}
501503

@@ -508,6 +510,7 @@ boolean isAtEnd() {
508510
String readString() throws IOException {
509511
int length = readVarint32();
510512
if (length > 0 && length <= end - pos) {
513+
JfrEventPublisher.bufferAllocateEvent(length);
511514
String value = new String(array, pos, length, UTF8);
512515
pos += length;
513516
return value;
@@ -614,6 +617,7 @@ byte[] readRawByteArray(int length) throws IOException {
614617
if (length > 0 && length <= end - pos) {
615618
int from = pos;
616619
pos += length;
620+
JfrEventPublisher.bufferAllocateEvent(pos - from);
617621
return Arrays.copyOfRange(array, from, pos);
618622
}
619623
if (length == 0) {
@@ -704,6 +708,7 @@ byte[] getBufferArray(int offset) {
704708
if (offset == 0) {
705709
return array;
706710
}
711+
JfrEventPublisher.bufferAllocateEvent(array.length - offset);
707712
return Arrays.copyOfRange(array, offset, array.length);
708713
}
709714

@@ -717,6 +722,7 @@ boolean isAtEnd() {
717722
String readString() throws IOException {
718723
int length = readVarint32();
719724
if (length > 0 && length <= end - buf.position()) {
725+
JfrEventPublisher.bufferAllocateEvent(length);
720726
byte[] bytes = new byte[length];
721727
buf.get(bytes);
722728
return new String(bytes, 0, length, UTF8);
@@ -818,6 +824,7 @@ byte readRawByte() throws IOException {
818824
@Override
819825
byte[] readRawByteArray(int length) throws IOException {
820826
if (length > 0 && length <= end - buf.position()) {
827+
JfrEventPublisher.bufferAllocateEvent(length);
821828
byte[] bytes = new byte[length];
822829
buf.get(bytes);
823830
return bytes;
@@ -1061,6 +1068,7 @@ byte[] readRawByteArray(int length) throws IOException {
10611068
}
10621069
int readTotal = 0;
10631070
int readAmount;
1071+
JfrEventPublisher.bufferAllocateEvent(length);
10641072
byte[] array = new byte[length];
10651073
while ((readAmount = in.read(array, readTotal, length - readTotal)) != -1) {
10661074
readTotal += readAmount;

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

Lines changed: 13 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,17 @@ 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.bufferAllocateEvent(nestedPositions.length * Integer.BYTES);
610613
} else {
611614
if (head == nestedPositions.length) {
615+
int before = nestedPositions.length * Integer.BYTES;
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+
int after = newLength * Integer.BYTES;
622+
JfrEventPublisher.bufferResizeEvent(before, newLength, after - before);
617623
}
618624
}
619625
}
@@ -1007,6 +1013,7 @@ void writeBytes(ByteBuffer value) throws IOException {
10071013
if (value.hasArray()) {
10081014
out.write(value.array(), value.arrayOffset(), value.remaining());
10091015
} else {
1016+
JfrEventPublisher.bufferAllocateEvent(value.remaining());
10101017
byte[] buffer = new byte[value.remaining()];
10111018
value.get(buffer, value.position(), value.remaining());
10121019
out.write(buffer);
@@ -1035,6 +1042,7 @@ private static final class OutputStreamEncoder extends Encoder {
10351042
// least their length varint should fit.
10361043
bufferSize = Math.max(bufferSize, MAX_VARINT_SIZE * 2);
10371044
buffer = new ByteArrayEncoder(new byte[bufferSize], 0, bufferSize);
1045+
JfrEventPublisher.bufferAllocateEvent(bufferSize);
10381046
this.out = out;
10391047
}
10401048

@@ -1348,6 +1356,7 @@ void writeUTF8FieldWithRewind(int number, String s) throws IOException {
13481356
}
13491357

13501358
byte[] utf8buffer = s.getBytes(StandardCharsets.UTF_8);
1359+
JfrEventPublisher.bufferAllocateEvent(utf8buffer.length);
13511360
out.ensureCapacity(startPos + MAX_INT_VARINT_SIZE + utf8buffer.length);
13521361

13531362
startPos = writeVarInt32Direct(startPos, utf8buffer.length);
@@ -1430,12 +1439,16 @@ Encoder subEncoder(int number, int maxDepth) throws IOException {
14301439
out.setPosition(pos + 1);
14311440
if (positions == null) {
14321441
positions = new int[10];
1442+
JfrEventPublisher.bufferAllocateEvent(positions.length * Integer.BYTES);
14331443
} else if (head == positions.length) {
1444+
int before = head * Integer.BYTES;
14341445
int newSize = Math.min(head + 10, maxDepth);
14351446
if (newSize == maxDepth) {
14361447
throw log.maxNestedMessageDepth(maxDepth, null);
14371448
}
14381449
positions = Arrays.copyOf(positions, newSize);
1450+
int after = newSize * Integer.BYTES;
1451+
JfrEventPublisher.bufferResizeEvent(before, after, after - before);
14391452
}
14401453
positions[head++] = pos + 1;
14411454
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)