11/*
2- * Copyright (c) 2016, 2021 , Oracle and/or its affiliates.
2+ * Copyright (c) 2016, 2022 , Oracle and/or its affiliates.
33 *
44 * All rights reserved.
55 *
@@ -174,9 +174,15 @@ public int getSize() {
174174 return 1 ;
175175 }
176176
177- @ TruffleBoundary
178177 @ ExportMessage
179178 public void toNative (@ Cached LLVMToNativeNode toNative ) {
179+ if (address == 0 ) {
180+ doToNative (toNative );
181+ }
182+ }
183+
184+ @ TruffleBoundary
185+ private synchronized void doToNative (LLVMToNativeNode toNative ) {
180186 if (address == 0 ) {
181187 LLVMMemory memory = LLVMLanguage .get (null ).getLLVMMemory ();
182188 LLVMNativePointer pointer = memory .allocateMemory (toNative , 8 );
@@ -205,16 +211,19 @@ static class ReadI8 {
205211 @ Specialization (guards = "self.isPointer()" )
206212 static byte readNative (LLVMGlobalContainer self , long offset ,
207213 @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
214+ assert self .isPointer ();
208215 return LLVMLanguage .get (location ).getLLVMMemory ().getI8 (location , self .getAddress () + offset );
209216 }
210217
211- @ Specialization (guards = "!self.isPointer() " )
218+ @ Specialization (replaces = "readNative " )
212219 @ GenerateAOT .Exclude
213220 static byte readManaged (LLVMGlobalContainer self , long offset ,
214- @ CachedLibrary ("self" ) InteropLibrary interop ,
215- @ CachedLibrary ("self" ) LLVMManagedReadLibrary read ) {
216- interop .toNative (self );
217- return read .readI8 (self , offset );
221+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
222+ @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
223+ self .toNative (toNative );
224+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
225+ // We already know we'll be in the self.isPointer() case after toNative.
226+ return readNative (self , offset , location );
218227 }
219228 }
220229
@@ -224,16 +233,19 @@ static class ReadI16 {
224233 @ Specialization (guards = "self.isPointer()" )
225234 static short readNative (LLVMGlobalContainer self , long offset ,
226235 @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
236+ assert self .isPointer ();
227237 return LLVMLanguage .get (location ).getLLVMMemory ().getI16 (location , self .getAddress () + offset );
228238 }
229239
230- @ Specialization (guards = "!self.isPointer() " )
240+ @ Specialization (replaces = "readNative " )
231241 @ GenerateAOT .Exclude
232242 static short readManaged (LLVMGlobalContainer self , long offset ,
233- @ CachedLibrary ("self" ) InteropLibrary interop ,
234- @ CachedLibrary ("self" ) LLVMManagedReadLibrary read ) {
235- interop .toNative (self );
236- return read .readI16 (self , offset );
243+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
244+ @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
245+ self .toNative (toNative );
246+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
247+ // We already know we'll be in the self.isPointer() case after toNative.
248+ return readNative (self , offset , location );
237249 }
238250 }
239251
@@ -243,16 +255,19 @@ static class ReadI32 {
243255 @ Specialization (guards = "self.isPointer()" )
244256 static int readNative (LLVMGlobalContainer self , long offset ,
245257 @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
258+ assert self .isPointer ();
246259 return LLVMLanguage .get (location ).getLLVMMemory ().getI32 (location , self .getAddress () + offset );
247260 }
248261
249- @ Specialization (guards = "!self.isPointer() " )
262+ @ Specialization (replaces = "readNative " )
250263 @ GenerateAOT .Exclude
251264 static int readManaged (LLVMGlobalContainer self , long offset ,
252- @ CachedLibrary ("self" ) InteropLibrary interop ,
253- @ CachedLibrary ("self" ) LLVMManagedReadLibrary read ) {
254- interop .toNative (self );
255- return read .readI32 (self , offset );
265+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
266+ @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
267+ self .toNative (toNative );
268+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
269+ // We already know we'll be in the self.isPointer() case after toNative.
270+ return readNative (self , offset , location );
256271 }
257272 }
258273
@@ -262,16 +277,19 @@ static class ReadFloat {
262277 @ Specialization (guards = "self.isPointer()" )
263278 static float readNative (LLVMGlobalContainer self , long offset ,
264279 @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
280+ assert self .isPointer ();
265281 return LLVMLanguage .get (location ).getLLVMMemory ().getFloat (location , self .getAddress () + offset );
266282 }
267283
268- @ Specialization (guards = "!self.isPointer() " )
284+ @ Specialization (replaces = "readNative " )
269285 @ GenerateAOT .Exclude
270286 static float readManaged (LLVMGlobalContainer self , long offset ,
271- @ CachedLibrary ("self" ) InteropLibrary interop ,
272- @ CachedLibrary ("self" ) LLVMManagedReadLibrary read ) {
273- interop .toNative (self );
274- return read .readFloat (self , offset );
287+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
288+ @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
289+ self .toNative (toNative );
290+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
291+ // We already know we'll be in the self.isPointer() case after toNative.
292+ return readNative (self , offset , location );
275293 }
276294 }
277295
@@ -281,16 +299,19 @@ static class ReadDouble {
281299 @ Specialization (guards = "self.isPointer()" )
282300 static double readNative (LLVMGlobalContainer self , long offset ,
283301 @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
302+ assert self .isPointer ();
284303 return LLVMLanguage .get (location ).getLLVMMemory ().getDouble (location , self .getAddress () + offset );
285304 }
286305
287- @ Specialization (guards = "!self.isPointer() " )
306+ @ Specialization (replaces = "readNative " )
288307 @ GenerateAOT .Exclude
289308 static double readManaged (LLVMGlobalContainer self , long offset ,
290- @ CachedLibrary ("self" ) InteropLibrary interop ,
291- @ CachedLibrary ("self" ) LLVMManagedReadLibrary read ) {
292- interop .toNative (self );
293- return read .readDouble (self , offset );
309+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
310+ @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
311+ self .toNative (toNative );
312+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
313+ // We already know we'll be in the self.isPointer() case after toNative.
314+ return readNative (self , offset , location );
294315 }
295316 }
296317
@@ -304,6 +325,7 @@ static Assumption singleContextAssumption() {
304325 @ Specialization (guards = "self.isPointer()" )
305326 static long readNative (LLVMGlobalContainer self , long offset ,
306327 @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
328+ assert self .isPointer ();
307329 return LLVMLanguage .get (location ).getLLVMMemory ().getI64 (location , self .getAddress () + offset );
308330 }
309331
@@ -322,10 +344,12 @@ static Object readI64Managed(LLVMGlobalContainer self, long offset) {
322344 @ Specialization (guards = {"!self.isPointer()" , "offset != 0" })
323345 @ GenerateAOT .Exclude
324346 static Object readFallback (LLVMGlobalContainer self , long offset ,
325- @ CachedLibrary ("self" ) InteropLibrary interop ,
326- @ CachedLibrary ("self" ) LLVMManagedReadLibrary read ) {
327- interop .toNative (self );
328- return read .readGenericI64 (self , offset );
347+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
348+ @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
349+ self .toNative (toNative );
350+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
351+ // We already know we'll be in the self.isPointer() case after toNative.
352+ return readNative (self , offset , location );
329353 }
330354 }
331355
@@ -339,6 +363,7 @@ static Assumption singleContextAssumption() {
339363 @ Specialization (guards = "self.isPointer()" )
340364 static LLVMPointer readNative (LLVMGlobalContainer self , long offset ,
341365 @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
366+ assert self .isPointer ();
342367 return LLVMLanguage .get (location ).getLLVMMemory ().getPointer (location , self .getAddress () + offset );
343368 }
344369
@@ -359,10 +384,12 @@ static LLVMPointer readManaged(LLVMGlobalContainer self, long offset,
359384 @ Specialization (guards = {"!self.isPointer()" , "offset != 0" })
360385 @ GenerateAOT .Exclude
361386 static LLVMPointer readFallback (LLVMGlobalContainer self , long offset ,
362- @ CachedLibrary ("self" ) InteropLibrary interop ,
363- @ CachedLibrary ("self" ) LLVMManagedReadLibrary read ) {
364- interop .toNative (self );
365- return read .readPointer (self , offset );
387+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
388+ @ CachedLibrary ("self" ) LLVMManagedReadLibrary location ) {
389+ self .toNative (toNative );
390+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
391+ // We already know we'll be in the self.isPointer() case after toNative.
392+ return readNative (self , offset , location );
366393 }
367394 }
368395
@@ -372,16 +399,19 @@ static class WriteI8 {
372399 @ Specialization (guards = "self.isPointer()" )
373400 static void writeNative (LLVMGlobalContainer self , long offset , byte value ,
374401 @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
402+ assert self .isPointer ();
375403 LLVMLanguage .get (location ).getLLVMMemory ().putI8 (location , self .getAddress () + offset , value );
376404 }
377405
378- @ Specialization (guards = "!self.isPointer() " )
406+ @ Specialization (replaces = "writeNative " )
379407 @ GenerateAOT .Exclude
380408 static void writeManaged (LLVMGlobalContainer self , long offset , byte value ,
381- @ CachedLibrary ("self" ) InteropLibrary interop ,
382- @ CachedLibrary ("self" ) LLVMManagedWriteLibrary write ) {
383- interop .toNative (self );
384- write .writeI8 (self , offset , value );
409+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
410+ @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
411+ self .toNative (toNative );
412+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
413+ // We already know we'll be in the self.isPointer() case after toNative.
414+ writeNative (self , offset , value , location );
385415 }
386416 }
387417
@@ -391,16 +421,19 @@ static class WriteI16 {
391421 @ Specialization (guards = "self.isPointer()" )
392422 static void writeNative (LLVMGlobalContainer self , long offset , short value ,
393423 @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
424+ assert self .isPointer ();
394425 LLVMLanguage .get (location ).getLLVMMemory ().putI16 (location , self .getAddress () + offset , value );
395426 }
396427
397- @ Specialization (guards = "!self.isPointer() " )
428+ @ Specialization (replaces = "writeNative " )
398429 @ GenerateAOT .Exclude
399430 static void writeManaged (LLVMGlobalContainer self , long offset , short value ,
400- @ CachedLibrary ("self" ) InteropLibrary interop ,
401- @ CachedLibrary ("self" ) LLVMManagedWriteLibrary write ) {
402- interop .toNative (self );
403- write .writeI16 (self , offset , value );
431+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
432+ @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
433+ self .toNative (toNative );
434+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
435+ // We already know we'll be in the self.isPointer() case after toNative.
436+ writeNative (self , offset , value , location );
404437 }
405438 }
406439
@@ -410,16 +443,19 @@ static class WriteI32 {
410443 @ Specialization (guards = "self.isPointer()" )
411444 static void writeNative (LLVMGlobalContainer self , long offset , int value ,
412445 @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
446+ assert self .isPointer ();
413447 LLVMLanguage .get (location ).getLLVMMemory ().putI32 (location , self .getAddress () + offset , value );
414448 }
415449
416- @ Specialization (guards = "!self.isPointer() " )
450+ @ Specialization (replaces = "writeNative " )
417451 @ GenerateAOT .Exclude
418452 static void writeManaged (LLVMGlobalContainer self , long offset , int value ,
419- @ CachedLibrary ("self" ) InteropLibrary interop ,
420- @ CachedLibrary ("self" ) LLVMManagedWriteLibrary write ) {
421- interop .toNative (self );
422- write .writeI32 (self , offset , value );
453+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
454+ @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
455+ self .toNative (toNative );
456+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
457+ // We already know we'll be in the self.isPointer() case after toNative.
458+ writeNative (self , offset , value , location );
423459 }
424460 }
425461
@@ -429,16 +465,19 @@ static class WriteFloat {
429465 @ Specialization (guards = "self.isPointer()" )
430466 static void writeNative (LLVMGlobalContainer self , long offset , float value ,
431467 @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
468+ assert self .isPointer ();
432469 LLVMLanguage .get (location ).getLLVMMemory ().putFloat (location , self .getAddress () + offset , value );
433470 }
434471
435- @ Specialization (guards = "!self.isPointer() " )
472+ @ Specialization (replaces = "writeNative " )
436473 @ GenerateAOT .Exclude
437474 static void writeManaged (LLVMGlobalContainer self , long offset , float value ,
438- @ CachedLibrary ("self" ) InteropLibrary interop ,
439- @ CachedLibrary ("self" ) LLVMManagedWriteLibrary write ) {
440- interop .toNative (self );
441- write .writeFloat (self , offset , value );
475+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
476+ @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
477+ self .toNative (toNative );
478+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
479+ // We already know we'll be in the self.isPointer() case after toNative.
480+ writeNative (self , offset , value , location );
442481 }
443482 }
444483
@@ -448,16 +487,19 @@ static class WriteDouble {
448487 @ Specialization (guards = "self.isPointer()" )
449488 static void writeNative (LLVMGlobalContainer self , long offset , double value ,
450489 @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
490+ assert self .isPointer ();
451491 LLVMLanguage .get (location ).getLLVMMemory ().putDouble (location , self .getAddress () + offset , value );
452492 }
453493
454- @ Specialization (guards = "!self.isPointer() " )
494+ @ Specialization (replaces = "writeNative " )
455495 @ GenerateAOT .Exclude
456496 static void writeManaged (LLVMGlobalContainer self , long offset , double value ,
457- @ CachedLibrary ("self" ) InteropLibrary interop ,
458- @ CachedLibrary ("self" ) LLVMManagedWriteLibrary write ) {
459- interop .toNative (self );
460- write .writeDouble (self , offset , value );
497+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
498+ @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
499+ self .toNative (toNative );
500+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
501+ // We already know we'll be in the self.isPointer() case after toNative.
502+ writeNative (self , offset , value , location );
461503 }
462504 }
463505
@@ -471,6 +513,7 @@ static Assumption singleContextAssumption() {
471513 @ Specialization (guards = "self.isPointer()" )
472514 static void writeNative (LLVMGlobalContainer self , long offset , long value ,
473515 @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
516+ assert self .isPointer ();
474517 LLVMLanguage .get (location ).getLLVMMemory ().putI64 (location , self .getAddress () + offset , value );
475518 }
476519
@@ -498,10 +541,12 @@ static void writeManaged(LLVMGlobalContainer self, long offset, long value) {
498541 @ Specialization (guards = {"!self.isPointer()" , "offset != 0" })
499542 @ GenerateAOT .Exclude
500543 static void writeFallback (LLVMGlobalContainer self , long offset , long value ,
501- @ CachedLibrary ("self" ) InteropLibrary interop ,
502- @ CachedLibrary ("self" ) LLVMManagedWriteLibrary write ) {
503- interop .toNative (self );
504- write .writeI64 (self , offset , value );
544+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
545+ @ CachedLibrary ("self" ) LLVMManagedWriteLibrary location ) {
546+ self .toNative (toNative );
547+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
548+ // We already know we'll be in the self.isPointer() case after toNative.
549+ writeNative (self , offset , value , location );
505550 }
506551 }
507552
@@ -515,6 +560,7 @@ static Assumption singleContextAssumption() {
515560 @ Specialization (limit = "3" , guards = "self.isPointer()" )
516561 static void writeNative (LLVMGlobalContainer self , long offset , Object value ,
517562 @ CachedLibrary ("value" ) LLVMNativeLibrary toNative ) {
563+ assert self .isPointer ();
518564 long ptr = toNative .toNativePointer (value ).asNative ();
519565 LLVMLanguage .get (toNative ).getLLVMMemory ().putI64 (toNative , self .getAddress () + offset , ptr );
520566 }
@@ -543,10 +589,12 @@ static void writeI64Managed(LLVMGlobalContainer self, long offset, Object value)
543589 @ Specialization (guards = {"!self.isPointer()" , "offset != 0" })
544590 @ GenerateAOT .Exclude
545591 static void writeFallback (LLVMGlobalContainer self , long offset , Object value ,
546- @ CachedLibrary ("self" ) InteropLibrary interop ,
547- @ CachedLibrary ("self" ) LLVMManagedWriteLibrary write ) {
548- interop .toNative (self );
549- write .writeGenericI64 (self , offset , value );
592+ @ Shared ("toNative" ) @ Cached LLVMToNativeNode toNative ,
593+ @ CachedLibrary ("self" ) LLVMNativeLibrary nativeLib ) {
594+ self .toNative (toNative );
595+ // Don't dispatch through the LLVMManagedReadLibrary again to break recursion.
596+ // We already know we'll be in the self.isPointer() case after toNative.
597+ writeNative (self , offset , value , nativeLib );
550598 }
551599 }
552600
0 commit comments