Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b0cf14d

Browse files
Remove ReferenceQueue from TaintedMap implementation and purge inline (DataDog#6241)
Move to an inline purge map and drop the reference queue
1 parent 6e9eadb commit b0cf14d

File tree

18 files changed

+467
-668
lines changed

18 files changed

+467
-668
lines changed

‎dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapEmptyBenchmark.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.openjdk.jmh.annotations.Setup;
1616
import org.openjdk.jmh.annotations.State;
1717
import org.openjdk.jmh.annotations.Warmup;
18+
import org.openjdk.jmh.infra.BenchmarkParams;
1819
import org.openjdk.jmh.infra.Blackhole;
1920

2021
@Warmup(iterations = 2, time = 1000, timeUnit = MILLISECONDS)
@@ -30,8 +31,17 @@ public class TaintedMapEmptyBenchmark {
3031
private final Object anyObject = new Object();
3132

3233
@Setup(Level.Iteration)
33-
public void setup() {
34-
map = new TaintedMap();
34+
public void setup(BenchmarkParams params) {
35+
final boolean baseline = params.getBenchmark().endsWith("baseline");
36+
map = baseline ? TaintedMap.NoOp.INSTANCE : new TaintedMap.TaintedMapImpl();
37+
}
38+
39+
@Benchmark
40+
@OperationsPerInvocation(OP_COUNT)
41+
public void baseline(final Blackhole bh) {
42+
for (int i = 0; i < OP_COUNT; i++) {
43+
bh.consume(map.get(anyObject));
44+
}
3545
}
3646

3747
@Benchmark

‎dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapGetsBenchmark.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.openjdk.jmh.annotations.Setup;
1919
import org.openjdk.jmh.annotations.State;
2020
import org.openjdk.jmh.annotations.Warmup;
21+
import org.openjdk.jmh.infra.BenchmarkParams;
2122
import org.openjdk.jmh.infra.Blackhole;
2223

2324
@Warmup(iterations = 1, time = 1000, timeUnit = MILLISECONDS)
@@ -28,35 +29,36 @@
2829
@State(Scope.Benchmark)
2930
public class TaintedMapGetsBenchmark {
3031

31-
private static final int INITIAL_OP_COUNT = TaintedMap.DEFAULT_FLAT_MODE_THRESHOLD;
32+
private static final int INITIAL_OP_COUNT = 1 << 12;
3233
private static final int OP_COUNT = 1024;
3334

3435
private TaintedMap map;
3536
private List<Object> objectList;
3637
private List<Object> initialObjectList;
3738

3839
@Setup(Level.Iteration)
39-
public void setup() {
40-
map = new TaintedMap();
40+
public void setup(BenchmarkParams params) {
41+
final boolean baseline = params.getBenchmark().endsWith("baseline");
42+
map = baseline ? TaintedMap.NoOp.INSTANCE : new TaintedMap.TaintedMapImpl();
4143
initialObjectList = new ArrayList<>(INITIAL_OP_COUNT);
4244
objectList = new ArrayList<>(OP_COUNT);
4345
for (int i = 0; i < INITIAL_OP_COUNT; i++) {
4446
final Object k = new Object();
4547
initialObjectList.add(k);
46-
map.put(new TaintedObject(k, new Range[0], map.getReferenceQueue()));
48+
map.put(new TaintedObject(k, new Range[0]));
4749
}
4850
for (int i = 0; i < OP_COUNT; i++) {
4951
final Object k = new Object();
5052
objectList.add(k);
51-
map.put(new TaintedObject(k, new Range[0], map.getReferenceQueue()));
53+
map.put(new TaintedObject(k, new Range[0]));
5254
}
5355
}
5456

5557
@Benchmark
5658
@OperationsPerInvocation(OP_COUNT)
57-
public void getsBaseline(final Blackhole bh) {
59+
public void baseline(final Blackhole bh) {
5860
for (int i = 0; i < OP_COUNT; i++) {
59-
bh.consume(objectList.get(i));
61+
bh.consume(map.get(objectList.get(i)));
6062
}
6163
}
6264

‎dd-java-agent/agent-iast/src/jmh/java/com/datadog/iast/taint/TaintedMapPutsBenchmark.java

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
import com.datadog.iast.model.Range;
77
import datadog.trace.test.util.CircularBuffer;
88
import java.util.ArrayList;
9+
import java.util.IdentityHashMap;
910
import java.util.List;
11+
import java.util.Map;
1012
import org.openjdk.jmh.annotations.Benchmark;
1113
import org.openjdk.jmh.annotations.BenchmarkMode;
1214
import org.openjdk.jmh.annotations.Fork;
@@ -20,45 +22,47 @@
2022
import org.openjdk.jmh.annotations.State;
2123
import org.openjdk.jmh.annotations.Timeout;
2224
import org.openjdk.jmh.annotations.Warmup;
23-
import org.openjdk.jmh.infra.Blackhole;
25+
import org.openjdk.jmh.infra.BenchmarkParams;
2426

25-
@Warmup(iterations = 1, time = 1000, timeUnit = MILLISECONDS)
26-
@Measurement(iterations = 3, time = 1000, timeUnit = MILLISECONDS)
27+
@Warmup(iterations = 3, time = 1000, timeUnit = MILLISECONDS)
28+
@Measurement(iterations = 5, time = 1000, timeUnit = MILLISECONDS)
2729
@Timeout(time = 10000, timeUnit = MILLISECONDS)
2830
@Fork(3)
2931
@OutputTimeUnit(NANOSECONDS)
3032
@BenchmarkMode(Mode.AverageTime)
3133
@State(Scope.Benchmark)
3234
public class TaintedMapPutsBenchmark {
3335

34-
private static final int INITIAL_OP_COUNT = TaintedMap.DEFAULT_FLAT_MODE_THRESHOLD;
36+
private static final int INITIAL_OP_COUNT = 1 << 12;
3537
private static final int OP_COUNT = 1024;
3638

3739
private static final Range[] EMPTY_RANGES = new Range[0];
3840

3941
private TaintedMap map;
4042
private List<Object> initialObjectList;
41-
private CircularBuffer<Object> objectBuffer;
43+
private GarbageCollectorHandlergcHandler;
4244

4345
@Setup(Level.Iteration)
44-
public void setup() {
45-
map = new TaintedMap();
46-
objectBuffer = new CircularBuffer<>(OP_COUNT);
46+
public void setup(BenchmarkParams params) {
47+
final boolean baseline = params.getBenchmark().endsWith("baseline");
48+
map = baseline ? TaintedMap.NoOp.INSTANCE : new TaintedMap.TaintedMapImpl();
49+
gcHandler = new GarbageCollectorHandler(OP_COUNT);
4750
initialObjectList = new ArrayList<>(INITIAL_OP_COUNT);
4851
for (int i = 0; i < INITIAL_OP_COUNT; i++) {
4952
final Object k = new Object();
5053
initialObjectList.add(k);
51-
map.put(new TaintedObject(k, EMPTY_RANGES, map.getReferenceQueue()));
54+
map.put(new TaintedObject(k, EMPTY_RANGES));
5255
}
5356
}
5457

5558
@Benchmark
5659
@OperationsPerInvocation(OP_COUNT)
57-
public void putsBaseline(finalBlackholebh) {
60+
public void baseline() {
5861
for (int i = 0; i < OP_COUNT; i++) {
5962
final Object k = new Object();
60-
objectBuffer.add(k);
61-
bh.consume(new TaintedObject(k, EMPTY_RANGES, map.getReferenceQueue()));
63+
final TaintedObject to = new TaintedObject(k, EMPTY_RANGES);
64+
gcHandler.add(to);
65+
map.put(to);
6266
}
6367
}
6468

@@ -67,8 +71,37 @@ public void putsBaseline(final Blackhole bh) {
6771
public void puts() {
6872
for (int i = 0; i < OP_COUNT; i++) {
6973
final Object k = new Object();
70-
objectBuffer.add(k);
71-
map.put(new TaintedObject(k, EMPTY_RANGES, map.getReferenceQueue()));
74+
final TaintedObject to = new TaintedObject(k, EMPTY_RANGES);
75+
gcHandler.add(to);
76+
map.put(to);
77+
}
78+
}
79+
80+
/**
81+
* Reference queue that holds a circular buffer of alive objects and enqueues to be purged when
82+
* they are removed
83+
*/
84+
private static class GarbageCollectorHandler {
85+
86+
private final Map<Object, TaintedObject> map;
87+
private final CircularBuffer<Object> alive;
88+
89+
public GarbageCollectorHandler(final int aliveCount) {
90+
map = new IdentityHashMap<>(aliveCount);
91+
alive = new CircularBuffer<>(aliveCount);
92+
}
93+
94+
public void add(TaintedObject reference) {
95+
if (reference == null || reference.get() == null) {
96+
return;
97+
}
98+
final Object referent = reference.get();
99+
final Object toRemove = alive.add(referent);
100+
if (toRemove != null) {
101+
final TaintedObject taintedObject = map.remove(toRemove);
102+
taintedObject.enqueue();
103+
}
104+
map.put(reference.get(), reference);
72105
}
73106
}
74107
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /