55
66import java .io .InputStream ;
77import java .lang .invoke .MethodHandle ;
8- import java .lang .invoke .MethodHandles ;
9- import java .lang .invoke .MethodType ;
108import java .util .concurrent .atomic .AtomicReferenceArray ;
11- import java .util .function .Predicate ;
129
1310/**
1411 * This is a custom implementation of the Jackson's RecyclerPool intended to work equally well with
@@ -37,10 +34,9 @@ final class HybridBufferRecycler implements BufferRecycler {
3734
3835 private static final HybridBufferRecycler INSTANCE = new HybridBufferRecycler ();
3936
40- private static final Predicate <Thread > isVirtual = VirtualPredicate .findIsVirtualPredicate ();
41-
4237 private static final BufferRecycler NATIVE_RECYCLER = ThreadLocalPool .shared ();
4338 private static final BufferRecycler VIRTUAL_RECYCLER = StripedLockFreePool .shared ();
39+ private static final boolean VT_ENABLED = Runtime .version ().feature () >= 21 ;
4440
4541 private HybridBufferRecycler () {
4642 }
@@ -51,21 +47,21 @@ static HybridBufferRecycler shared() {
5147
5248 @ Override
5349 public JsonGenerator generator (JsonOutput target ) {
54- return isVirtual . test ( Thread . currentThread () )
50+ return VT_ENABLED && ThreadFunctions . isVirtual ( )
5551 ? VIRTUAL_RECYCLER .generator (target )
5652 : NATIVE_RECYCLER .generator (target );
5753 }
5854
5955 @ Override
6056 public JsonParser parser (byte [] bytes ) {
61- return isVirtual . test ( Thread . currentThread () )
57+ return VT_ENABLED && ThreadFunctions . isVirtual ( )
6258 ? VIRTUAL_RECYCLER .parser (bytes )
6359 : NATIVE_RECYCLER .parser (bytes );
6460 }
6561
6662 @ Override
6763 public JsonParser parser (InputStream in ) {
68- return isVirtual . test ( Thread . currentThread () )
64+ return VT_ENABLED && ThreadFunctions . isVirtual ( )
6965 ? VIRTUAL_RECYCLER .parser (in )
7066 : NATIVE_RECYCLER .parser (in );
7167 }
@@ -131,9 +127,8 @@ public JsonGenerator generator(JsonOutput target) {
131127 if (generatorStacks .compareAndSet (index , currentHead , currentHead .next )) {
132128 currentHead .next = null ;
133129 return currentHead .value .prepare (target );
134- } else {
135- currentHead = generatorStacks .get (index );
136130 }
131+ currentHead = generatorStacks .get (index );
137132 }
138133 }
139134
@@ -149,9 +144,8 @@ private JsonParser parser() {
149144 if (parserStacks .compareAndSet (index , currentHead , currentHead .next )) {
150145 currentHead .next = null ;
151146 return currentHead .value ;
152- } else {
153- currentHead = parserStacks .get (index );
154147 }
148+ currentHead = parserStacks .get (index );
155149 }
156150 }
157151
@@ -166,9 +160,8 @@ public void recycle(JsonGenerator recycler) {
166160 if (generatorStacks .compareAndSet (vThreadBufferRecycler .slot , next , newHead )) {
167161 newHead .next = next ;
168162 return ;
169- } else {
170- next = generatorStacks .get (vThreadBufferRecycler .slot );
171163 }
164+ next = generatorStacks .get (vThreadBufferRecycler .slot );
172165 }
173166 }
174167
@@ -183,9 +176,8 @@ public void recycle(JsonParser recycler) {
183176 if (parserStacks .compareAndSet (vThreadBufferRecycler .slot , next , newHead )) {
184177 newHead .next = next ;
185178 return ;
186- } else {
187- next = parserStacks .get (vThreadBufferRecycler .slot );
188179 }
180+ next = parserStacks .get (vThreadBufferRecycler .slot );
189181 }
190182 }
191183
@@ -236,35 +228,6 @@ private VThreadJParser(int slot) {
236228 }
237229 }
238230
239- private static final class VirtualPredicate {
240- private static final MethodHandle virtualMh = findVirtualMH ();
241-
242- private static MethodHandle findVirtualMH () {
243- try {
244- return MethodHandles .publicLookup ()
245- .findVirtual (Thread .class , "isVirtual" , MethodType .methodType (boolean .class ));
246- } catch (Exception e ) {
247- return null ;
248- }
249- }
250-
251- private static Predicate <Thread > findIsVirtualPredicate () {
252- return virtualMh == null ? VirtualPredicate ::notVirtual : VirtualPredicate ::isVirtual ;
253- }
254-
255- private static boolean isVirtual (Thread thread ) {
256- try {
257- return (boolean ) virtualMh .invokeExact (thread );
258- } catch (Throwable e ) {
259- throw new RuntimeException (e );
260- }
261- }
262-
263- private static boolean notVirtual (Thread thread ) {
264- return false ;
265- }
266- }
267-
268231 private static final class XorShiftThreadProbe {
269232
270233 private final int mask ;
@@ -282,7 +245,7 @@ private int probe() {
282245 // 0x9e3779b9 is the integral part of the Golden Ratio's fractional part 0.61803398875…
283246 // (sqrt(5)-1)/2
284247 // multiplied by 2^32, which has the best possible scattering properties.
285- int probe = (int ) ((Thread . currentThread () .getId () * 0x9e3779b9 ) & Integer .MAX_VALUE );
248+ int probe = (int ) ((ThreadFunctions .getId () * 0x9e3779b9 ) & Integer .MAX_VALUE );
286249 // xorshift
287250 probe ^= probe << 13 ;
288251 probe ^= probe >>> 17 ;
0 commit comments