270270@ ExportLibrary (value = NativeTypeLibrary .class , useForAOT = false )
271271public class GraalHPyContext extends CExtContext implements TruffleObject {
272272
273- private static final boolean TRACE ;
274- private static final int TRACE_SLEEP_TIME ;
275- static {
276- String prop = System .getProperty ("HPyTraceUpcalls" );
277- boolean doTrace = false ;
278- int sleepTime = 5000 ;
279- if (prop != null ) {
280- if (prop .equals ("true" )) {
281- doTrace = true ;
282- } else {
283- try {
284- sleepTime = Integer .parseInt (prop );
285- doTrace = true ;
286- } catch (NumberFormatException e ) {
287- // pass
288- }
289- }
290- }
291- TRACE = doTrace ;
292- TRACE_SLEEP_TIME = sleepTime ;
293- }
273+ private final boolean traceJNIUpcalls ;
294274
295275 private static final TruffleLogger LOGGER = PythonLanguage .getLogger (GraalHPyContext .class );
296276
@@ -857,8 +837,12 @@ public static GraalHPyNativeSymbol getGetterFunctionName(LLVMType llvmType) {
857837
858838 public GraalHPyContext (PythonContext context , Object hpyLibrary ) {
859839 super (context , hpyLibrary , GraalHPyConversionNodeSupplier .HANDLE );
840+ PythonLanguage language = context .getLanguage ();
841+ useNativeFastPaths = language .getEngineOption (PythonOptions .HPyEnableJNIFastPaths );
842+ int traceJNISleepTime = language .getEngineOption (PythonOptions .HPyTraceUpcalls );
843+ traceJNIUpcalls = traceJNISleepTime != 0 ;
860844 this .slowPathFactory = context .factory ();
861- this .hpyContextMembers = createMembers (context , getName ());
845+ this .hpyContextMembers = createMembers (context , getName (), traceJNIUpcalls );
862846 for (Object member : hpyContextMembers ) {
863847 if (member instanceof GraalHPyHandle ) {
864848 GraalHPyHandle handle = (GraalHPyHandle ) member ;
@@ -869,7 +853,9 @@ public GraalHPyContext(PythonContext context, Object hpyLibrary) {
869853 }
870854 hpyHandleTable = Arrays .copyOf (hpyHandleTable , IMMUTABLE_HANDLE_COUNT * 2 );
871855 nextHandle = IMMUTABLE_HANDLE_COUNT ;
872- this .useNativeFastPaths = context .getLanguage ().getEngineOption (PythonOptions .HPyEnableJNIFastPaths );
856+ if (traceJNIUpcalls ) {
857+ startUpcallsDaemon (traceJNISleepTime );
858+ }
873859 }
874860
875861 protected String getName () {
@@ -1394,45 +1380,23 @@ public enum Counter {
13941380 UpcallListNew ,
13951381 UpcallTupleFromArray ;
13961382
1397- long count ;
1398-
1399- void increment () {
1400- if (TRACE ) {
1401- count ++;
1402- }
1403- }
1383+ @ CompilationFinal (dimensions = 1 ) private static final Counter [] VALUES = values ();
14041384 }
14051385
1406- static {
1407- if (TRACE ) {
1408- Thread thread = new Thread (() -> {
1409-
1410- while (true ) {
1411- try {
1412- Thread .sleep (TRACE_SLEEP_TIME );
1413- } catch (InterruptedException e ) {
1414- // fall through
1415- }
1416- System .out .println ("==== HPy counts" );
1417- for (Counter c : Counter .values ()) {
1418- System .out .printf (" %20s: %8d\n " , c .name (), c .count );
1419- }
1420- }
1421-
1422- });
1423- thread .setDaemon (true );
1424- thread .start ();
1386+ private void increment (Counter upcall ) {
1387+ if (traceJNIUpcalls ) {
1388+ jniCounts [upcall .ordinal ()]++;
14251389 }
14261390 }
14271391
14281392 @ SuppressWarnings ("static-method" )
14291393 public final long ctxFloatFromDouble (double value ) {
1430- Counter .UpcallFloatFromDouble . increment ( );
1394+ increment ( Counter .UpcallFloatFromDouble );
14311395 return GraalHPyBoxing .boxDouble (value );
14321396 }
14331397
14341398 public final double ctxFloatAsDouble (long handle ) {
1435- Counter .UpcallFloatAsDouble . increment ( );
1399+ increment ( Counter .UpcallFloatAsDouble );
14361400
14371401 if (GraalHPyBoxing .isBoxedDouble (handle )) {
14381402 return GraalHPyBoxing .unboxDouble (handle );
@@ -1446,7 +1410,7 @@ public final double ctxFloatAsDouble(long handle) {
14461410 }
14471411
14481412 public final long ctxLongAsLong (long handle ) {
1449- Counter .UpcallLongAsLong . increment ( );
1413+ increment ( Counter .UpcallLongAsLong );
14501414
14511415 if (GraalHPyBoxing .isBoxedInt (handle )) {
14521416 return GraalHPyBoxing .unboxInt (handle );
@@ -1462,7 +1426,7 @@ public final long ctxLongAsLong(long handle) {
14621426 }
14631427
14641428 public final double ctxLongAsDouble (long handle ) {
1465- Counter .UpcallLongAsDouble . increment ( );
1429+ increment ( Counter .UpcallLongAsDouble );
14661430
14671431 if (GraalHPyBoxing .isBoxedInt (handle )) {
14681432 return GraalHPyBoxing .unboxInt (handle );
@@ -1478,7 +1442,7 @@ public final double ctxLongAsDouble(long handle) {
14781442 }
14791443
14801444 public final long ctxLongFromLong (long l ) {
1481- Counter .UpcallLongFromLong . increment ( );
1445+ increment ( Counter .UpcallLongFromLong );
14821446
14831447 if (com .oracle .graal .python .builtins .objects .ints .PInt .isIntRange (l )) {
14841448 return GraalHPyBoxing .boxInt ((int ) l );
@@ -1487,14 +1451,14 @@ public final long ctxLongFromLong(long l) {
14871451 }
14881452
14891453 public final long ctxAsStruct (long handle ) {
1490- Counter .UpcallCast . increment ( );
1454+ increment ( Counter .UpcallCast );
14911455
14921456 Object receiver = getObjectForHPyHandle (GraalHPyBoxing .unboxHandle (handle )).getDelegate ();
14931457 return (long ) HPyGetNativeSpacePointerNodeGen .getUncached ().execute (receiver );
14941458 }
14951459
14961460 public final long ctxNew (long typeHandle , long dataOutVar ) {
1497- Counter .UpcallNew . increment ( );
1461+ increment ( Counter .UpcallNew );
14981462
14991463 Object type = getObjectForHPyHandle (GraalHPyBoxing .unboxHandle (typeHandle )).getDelegate ();
15001464 PythonObject pythonObject ;
@@ -1536,7 +1500,7 @@ public final long ctxNew(long typeHandle, long dataOutVar) {
15361500 }
15371501
15381502 public final long ctxTypeGenericNew (long typeHandle ) {
1539- Counter .UpcallTypeGenericNew . increment ( );
1503+ increment ( Counter .UpcallTypeGenericNew );
15401504
15411505 Object type = getObjectForHPyHandle (GraalHPyBoxing .unboxHandle (typeHandle )).getDelegate ();
15421506
@@ -1568,12 +1532,12 @@ private void closeNativeHandle(long handle) {
15681532 }
15691533
15701534 public final void ctxClose (long handle ) {
1571- Counter .UpcallClose . increment ( );
1535+ increment ( Counter .UpcallClose );
15721536 closeNativeHandle (handle );
15731537 }
15741538
15751539 public final void ctxBulkClose (long unclosedHandlePtr , int size ) {
1576- Counter .UpcallBulkClose . increment ( );
1540+ increment ( Counter .UpcallBulkClose );
15771541 for (int i = 0 ; i < size ; i ++) {
15781542 long handle = unsafe .getLong (unclosedHandlePtr );
15791543 unclosedHandlePtr += 8 ;
@@ -1584,7 +1548,7 @@ public final void ctxBulkClose(long unclosedHandlePtr, int size) {
15841548 }
15851549
15861550 public final long ctxDup (long handle ) {
1587- Counter .UpcallDup . increment ( );
1551+ increment ( Counter .UpcallDup );
15881552 if (GraalHPyBoxing .isBoxedHandle (handle )) {
15891553 GraalHPyHandle pyHandle = getObjectForHPyHandle (GraalHPyBoxing .unboxHandle (handle ));
15901554 return GraalHPyBoxing .boxHandle (createHandle (pyHandle .getDelegate ()).getId (this , ConditionProfile .getUncached ()));
@@ -1594,7 +1558,7 @@ public final long ctxDup(long handle) {
15941558 }
15951559
15961560 public final long ctxGetItemi (long hCollection , long lidx ) {
1597- Counter .UpcallGetItemI . increment ( );
1561+ increment ( Counter .UpcallGetItemI );
15981562 try {
15991563 // If handle 'hCollection' is a boxed int or double, the object is not subscriptable.
16001564 if (!GraalHPyBoxing .isBoxedHandle (hCollection )) {
@@ -1648,7 +1612,7 @@ public final long ctxGetItemi(long hCollection, long lidx) {
16481612 * @return {@code 0} on success; {@code -1} on error
16491613 */
16501614 public final int ctxSetItem (long hSequence , long hKey , long hValue ) {
1651- Counter .UpcallSetItem . increment ( );
1615+ increment ( Counter .UpcallSetItem );
16521616 try {
16531617 // If handle 'hSequence' is a boxed int or double, the object is not a sequence.
16541618 if (!GraalHPyBoxing .isBoxedHandle (hSequence )) {
@@ -1691,7 +1655,7 @@ public final int ctxSetItem(long hSequence, long hKey, long hValue) {
16911655 }
16921656
16931657 public final int ctxSetItemi (long hSequence , long lidx , long hValue ) {
1694- Counter .UpcallSetItemI . increment ( );
1658+ increment ( Counter .UpcallSetItemI );
16951659 try {
16961660 // If handle 'hSequence' is a boxed int or double, the object is not a sequence.
16971661 if (!GraalHPyBoxing .isBoxedHandle (hSequence )) {
@@ -1748,7 +1712,7 @@ private static int setItemGeneric(Object receiver, Object clazz, Object key, Obj
17481712 }
17491713
17501714 public final int ctxNumberCheck (long handle ) {
1751- Counter .UpcallNumberCheck . increment ( );
1715+ increment ( Counter .UpcallNumberCheck );
17521716 if (GraalHPyBoxing .isBoxedDouble (handle ) || GraalHPyBoxing .isBoxedInt (handle )) {
17531717 return 1 ;
17541718 }
@@ -1777,7 +1741,7 @@ private static PythonBuiltinClassType getBuiltinClass(Object cls) {
17771741 }
17781742
17791743 public final int ctxTypeCheck (long handle , long typeHandle ) {
1780- Counter .UpcallTypeCheck . increment ( );
1744+ increment ( Counter .UpcallTypeCheck );
17811745 Object receiver ;
17821746 if (GraalHPyBoxing .isBoxedDouble (handle )) {
17831747 receiver = PythonBuiltinClassType .PFloat ;
@@ -1820,7 +1784,7 @@ public final int ctxTypeCheck(long handle, long typeHandle) {
18201784 }
18211785
18221786 public final long ctxLength (long handle ) {
1823- Counter .UpcallLength . increment ( );
1787+ increment ( Counter .UpcallLength );
18241788 assert GraalHPyBoxing .isBoxedHandle (handle );
18251789
18261790 Object receiver = getObjectForHPyHandle (GraalHPyBoxing .unboxHandle (handle )).getDelegate ();
@@ -1840,7 +1804,7 @@ public final long ctxLength(long handle) {
18401804 }
18411805
18421806 public final int ctxListCheck (long handle ) {
1843- Counter .UpcallListCheck . increment ( );
1807+ increment ( Counter .UpcallListCheck );
18441808 if (GraalHPyBoxing .isBoxedHandle (handle )) {
18451809 Object obj = getObjectForHPyHandle (GraalHPyBoxing .unboxHandle (handle )).getDelegate ();
18461810 Object clazz = GetClassNode .getUncached ().execute (obj );
@@ -1851,7 +1815,7 @@ public final int ctxListCheck(long handle) {
18511815 }
18521816
18531817 public final long ctxUnicodeFromWideChar (long wcharArrayPtr , long size ) {
1854- Counter .UpcallUnicodeFromWideChar . increment ( );
1818+ increment ( Counter .UpcallUnicodeFromWideChar );
18551819
18561820 if (!PInt .isIntRange (size )) {
18571821 // NULL handle
@@ -1873,19 +1837,19 @@ public final long ctxUnicodeFromWideChar(long wcharArrayPtr, long size) {
18731837 }
18741838
18751839 public final long ctxUnicodeFromJCharArray (char [] arr ) {
1876- Counter .UpcallUnicodeFromJCharArray . increment ( );
1840+ increment ( Counter .UpcallUnicodeFromJCharArray );
18771841 return createHandle (new String (arr , 0 , arr .length )).getId (this , ConditionProfile .getUncached ());
18781842 }
18791843
18801844 public final long ctxDictNew () {
1881- Counter .UpcallDictNew . increment ( );
1845+ increment ( Counter .UpcallDictNew );
18821846 PDict dict = PythonObjectFactory .getUncached ().createDict ();
18831847 return createHandle (dict ).getId (this , ConditionProfile .getUncached ());
18841848 }
18851849
18861850 public final long ctxListNew (long llen ) {
18871851 try {
1888- Counter .UpcallListNew . increment ( );
1852+ increment ( Counter .UpcallListNew );
18891853 int len = CastToJavaIntExactNode .getUncached ().execute (llen );
18901854 Object [] data = new Object [len ];
18911855 Arrays .fill (data , PNone .NONE );
@@ -1904,7 +1868,7 @@ public final long ctxListNew(long llen) {
19041868 * is useful to implement, e.g., tuple builder.
19051869 */
19061870 public final long ctxTupleFromArray (long [] hItems , boolean steal ) {
1907- Counter .UpcallTupleFromArray . increment ( );
1871+ increment ( Counter .UpcallTupleFromArray );
19081872
19091873 Object [] objects = new Object [hItems .length ];
19101874 for (int i = 0 ; i < hItems .length ; i ++) {
@@ -2014,7 +1978,7 @@ final Object invokeMember(String key, Object[] args,
20141978 return memberInvokeLib .execute (member , args );
20151979 }
20161980
2017- private static Object [] createMembers (PythonContext context , String name ) {
1981+ private static Object [] createMembers (PythonContext context , String name , boolean traceJNIUpcalls ) {
20181982 Object [] members = new Object [HPyContextMember .VALUES .length ];
20191983
20201984 members [HPyContextMember .NAME .ordinal ()] = new CStringWrapper (name );
@@ -2276,7 +2240,7 @@ private static Object[] createMembers(PythonContext context, String name) {
22762240 members [HPyContextMember .CTX_GLOBAL_LOAD .ordinal ()] = new GraalHPyGlobalLoad ();
22772241 members [HPyContextMember .CTX_DUMP .ordinal ()] = new GraalHPyDump ();
22782242
2279- if (TRACE ) {
2243+ if (traceJNIUpcalls ) {
22802244 for (int i = 0 ; i < members .length ; i ++) {
22812245 Object m = members [i ];
22822246 if (m != null && !(m instanceof Number || m instanceof GraalHPyHandle )) {
@@ -2290,30 +2254,32 @@ private static Object[] createMembers(PythonContext context, String name) {
22902254 }
22912255
22922256 static final int [] counts = new int [HPyContextMember .VALUES .length ];
2257+ static final int [] jniCounts = new int [Counter .values ().length ];
22932258
2294- static {
2295- if (TRACE ) {
2296- Thread thread = new Thread () {
2297- @ Override
2298- public void run () {
2299- while (true ) {
2300- try {
2301- Thread .sleep (TRACE_SLEEP_TIME );
2302- } catch (InterruptedException e ) {
2303- e .printStackTrace ();
2304- }
2305- System .out .println ("========= stats" );
2306- for (int i = 0 ; i < counts .length ; i ++) {
2307- if (counts [i ] != 0 ) {
2308- System .out .printf (" %40s[%3d]: %d\n " , HPyContextMember .VALUES [i ].name , i , counts [i ]);
2309- }
2310- }
2259+ private static void startUpcallsDaemon (int traceJNISleepTime ) {
2260+ Thread thread = new Thread (() -> {
2261+ while (true ) {
2262+ try {
2263+ Thread .sleep (traceJNISleepTime );
2264+ } catch (InterruptedException e ) {
2265+ e .printStackTrace ();
2266+ }
2267+ System .out .println ("========= HPy LLVM/NFI upcall counts" );
2268+ for (int i = 0 ; i < counts .length ; i ++) {
2269+ if (counts [i ] != 0 ) {
2270+ System .out .printf (" %40s[%3d]: %d\n " , HPyContextMember .VALUES [i ].name , i , counts [i ]);
23112271 }
23122272 }
2313- };
2314- thread .setDaemon (true );
2315- thread .start ();
2316- }
2273+ System .out .println ("==== HPy JNI upcall counts" );
2274+ for (int i = 0 ; i < jniCounts .length ; i ++) {
2275+ if (jniCounts [i ] != 0 ) {
2276+ System .out .printf (" %40s[%3d]: %d\n " , Counter .VALUES [i ].name (), i , jniCounts [i ]);
2277+ }
2278+ }
2279+ }
2280+ });
2281+ thread .setDaemon (true );
2282+ thread .start ();
23172283 }
23182284
23192285 @ ExportLibrary (value = InteropLibrary .class , delegateTo = "delegate" )
0 commit comments