165
165
import com .oracle .graal .python .builtins .objects .type .PythonClass ;
166
166
import com .oracle .graal .python .builtins .objects .type .SpecialMethodSlot ;
167
167
import com .oracle .graal .python .builtins .objects .type .TypeNodes .IsTypeNode ;
168
- import com .oracle .graal .python .builtins .objects .type .TypeNodesFactory .GetInstanceShapeNodeGen ;
169
168
import com .oracle .graal .python .lib .CanBeDoubleNodeGen ;
170
169
import com .oracle .graal .python .lib .PyFloatAsDoubleNodeGen ;
171
170
import com .oracle .graal .python .lib .PyIndexCheckNodeGen ;
193
192
import com .oracle .graal .python .runtime .exception .PException ;
194
193
import com .oracle .graal .python .runtime .exception .PythonThreadKillException ;
195
194
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
195
+ import com .oracle .graal .python .runtime .object .PythonObjectSlowPathFactory ;
196
196
import com .oracle .graal .python .runtime .sequence .PSequence ;
197
197
import com .oracle .graal .python .runtime .sequence .storage .DoubleSequenceStorage ;
198
198
import com .oracle .graal .python .runtime .sequence .storage .IntSequenceStorage ;
@@ -761,6 +761,8 @@ public static GraalHPyNativeSymbol getGetterFunctionName(LLVMType llvmType) {
761
761
@ CompilationFinal private RootCallTarget referenceCleanerCallTarget ;
762
762
private Thread hpyReferenceCleanerThread ;
763
763
764
+ private PythonObjectSlowPathFactory slowPathFactory ;
765
+
764
766
public GraalHPyContext (PythonContext context , Object hpyLibrary ) {
765
767
super (context , hpyLibrary , GraalHPyConversionNodeSupplier .HANDLE );
766
768
this .hpyContextMembers = createMembers (context , getName ());
@@ -1284,6 +1286,17 @@ void increment() {
1284
1286
}
1285
1287
}
1286
1288
1289
+ /**
1290
+ * Returns a Python object factory that should only be used on the slow path. The factory object
1291
+ * is initialized lazily.
1292
+ */
1293
+ private PythonObjectSlowPathFactory factory () {
1294
+ if (slowPathFactory == null ) {
1295
+ slowPathFactory = new PythonObjectSlowPathFactory (getContext ().getAllocationReporter ());
1296
+ }
1297
+ return slowPathFactory ;
1298
+ }
1299
+
1287
1300
@ SuppressWarnings ("static-method" )
1288
1301
public final long ctxFloatFromDouble (double value ) {
1289
1302
Counter .UpcallFloatFromDouble .increment ();
@@ -1353,14 +1366,17 @@ public final long ctxNew(long typeHandle, long dataOutVar) {
1353
1366
long basicSize = clazz .basicSize ;
1354
1367
if (basicSize == -1 ) {
1355
1368
// create the managed Python object
1356
- pythonObject = new PythonObject (clazz , clazz .getInstanceShape ());
1369
+ pythonObject = factory (). createPythonObject (clazz , clazz .getInstanceShape ());
1357
1370
} else {
1371
+ /*
1372
+ * Since this is a JNI upcall method, we know that (1) we are not running in some
1373
+ * managed mode, and (2) the data will be used in real native code. Hence, we can
1374
+ * immediately allocate native memory via Unsafe.
1375
+ */
1358
1376
long dataPtr = unsafe .allocateMemory (basicSize );
1359
1377
unsafe .setMemory (dataPtr , basicSize , (byte ) 0 );
1360
1378
unsafe .putLong (dataOutVar , dataPtr );
1361
- // create the managed Python object
1362
- pythonObject = new PythonHPyObject (clazz , clazz .getInstanceShape (), dataPtr );
1363
- // we fully control this attribute; if it is there, it's always a long
1379
+ pythonObject = factory ().createPythonHPyObject (clazz , dataPtr );
1364
1380
Object destroyFunc = clazz .hpyDestroyFunc ;
1365
1381
createHandleReference (pythonObject , dataPtr , destroyFunc != PNone .NO_VALUE ? destroyFunc : null );
1366
1382
}
@@ -1370,7 +1386,7 @@ public final long ctxNew(long typeHandle, long dataOutVar) {
1370
1386
return HPyRaiseNodeGen .getUncached ().raiseIntWithoutFrame (this , 0 , PythonBuiltinClassType .TypeError , "HPy_New arg 1 must be a type" );
1371
1387
}
1372
1388
// TODO(fa): this should actually call __new__
1373
- pythonObject = new PythonObject ( type , GetInstanceShapeNodeGen . getUncached (). execute (type ) );
1389
+ pythonObject = factory (). createPythonObject (type );
1374
1390
}
1375
1391
return GraalHPyBoxing .boxHandle (createHandle (pythonObject ).getId (this , ConditionProfile .getUncached ()));
1376
1392
}
@@ -1389,10 +1405,9 @@ public final long ctxTypeGenericNew(long typeHandle) {
1389
1405
// allocate native space
1390
1406
long dataPtr = unsafe .allocateMemory (basicSize );
1391
1407
unsafe .setMemory (dataPtr , basicSize , (byte ) 0 );
1392
- pythonObject = new PythonHPyObject ( clazz , clazz . getInstanceShape () , dataPtr );
1408
+ pythonObject = factory (). createPythonHPyObject ( clazz , dataPtr );
1393
1409
} else {
1394
- // create the managed Python object
1395
- pythonObject = new PythonObject (clazz , clazz .getInstanceShape ());
1410
+ pythonObject = factory ().createPythonObject (clazz );
1396
1411
}
1397
1412
return GraalHPyBoxing .boxHandle (createHandle (pythonObject ).getId (this , ConditionProfile .getUncached ()));
1398
1413
}
@@ -1416,14 +1431,14 @@ public final long ctxDup(long handle) {
1416
1431
}
1417
1432
}
1418
1433
1419
- public final long ctxGetItemi (long handle , long lidx ) {
1434
+ public final long ctxGetItemi (long hCollection , long lidx ) {
1420
1435
Counter .UpcallGetItemI .increment ();
1421
1436
try {
1422
- // If handle 'hSequence ' is a boxed int or double, the object is not subscriptable.
1423
- if (!GraalHPyBoxing .isBoxedHandle (handle )) {
1437
+ // If handle 'hCollection ' is a boxed int or double, the object is not subscriptable.
1438
+ if (!GraalHPyBoxing .isBoxedHandle (hCollection )) {
1424
1439
throw PRaiseNode .raiseUncached (null , PythonBuiltinClassType .TypeError , ErrorMessages .OBJ_NOT_SUBSCRIPTABLE , 0 );
1425
1440
}
1426
- Object receiver = getObjectForHPyHandle (GraalHPyBoxing .unboxHandle (handle )).getDelegate ();
1441
+ Object receiver = getObjectForHPyHandle (GraalHPyBoxing .unboxHandle (hCollection )).getDelegate ();
1427
1442
Object clazz = GetClassNode .getUncached ().execute (receiver );
1428
1443
if (clazz == PythonBuiltinClassType .PList || clazz == PythonBuiltinClassType .PTuple ) {
1429
1444
if (!PInt .isIntRange (lidx )) {
@@ -1577,7 +1592,7 @@ public final int ctxNumberCheck(long handle) {
1577
1592
return 1 ;
1578
1593
}
1579
1594
Object receiverType = GetClassNode .getUncached ().execute (receiver );
1580
- return com . oracle . graal . python . builtins . objects . ints . PInt .intValue (LookupCallableSlotInMRONode .getUncached (SpecialMethodSlot .Int ).execute (receiverType ) != PNone .NO_VALUE );
1595
+ return PInt .intValue (LookupCallableSlotInMRONode .getUncached (SpecialMethodSlot .Int ).execute (receiverType ) != PNone .NO_VALUE );
1581
1596
} catch (PException e ) {
1582
1597
HPyTransformExceptionToNativeNodeGen .getUncached ().execute (this , e );
1583
1598
return 0 ;
@@ -1607,10 +1622,9 @@ public final long ctxLength(long handle) {
1607
1622
public final int ctxListCheck (long handle ) {
1608
1623
Counter .UpcallListCheck .increment ();
1609
1624
if (GraalHPyBoxing .isBoxedHandle (handle )) {
1610
-
1611
1625
Object obj = getObjectForHPyHandle (GraalHPyBoxing .unboxHandle (handle )).getDelegate ();
1612
1626
Object clazz = GetClassNode .getUncached ().execute (obj );
1613
- return com . oracle . graal . python . builtins . objects . ints . PInt .intValue (clazz == PythonBuiltinClassType .PList || IsSubtypeNodeGen .getUncached ().execute (clazz , PythonBuiltinClassType .PList ));
1627
+ return PInt .intValue (clazz == PythonBuiltinClassType .PList || IsSubtypeNodeGen .getUncached ().execute (clazz , PythonBuiltinClassType .PList ));
1614
1628
} else {
1615
1629
return 0 ;
1616
1630
}
0 commit comments