|
51 | 51 | import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.AsLongNodeGen; |
52 | 52 | import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.AsPythonObjectNodeGen; |
53 | 53 | import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.CextUpcallNodeGen; |
| 54 | +import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.GetNativeClassNodeGen; |
54 | 55 | import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ObjectUpcallNodeGen; |
55 | 56 | import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ToJavaNodeGen; |
56 | 57 | import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ToSulongNodeGen; |
@@ -535,14 +536,28 @@ public static FromCharPointerNode create() { |
535 | 536 | } |
536 | 537 | } |
537 | 538 |
|
538 | | - public static class GetNativeClassNode extends CExtBaseNode { |
| 539 | + public abstract static class GetNativeClassNode extends CExtBaseNode { |
539 | 540 |
|
540 | 541 | @Child PCallNativeNode callGetObTypeNode; |
541 | 542 | @Child ToJavaNode toJavaNode; |
542 | 543 |
|
543 | 544 | @CompilationFinal private TruffleObject func; |
544 | 545 |
|
545 | | - public PythonClass execute(PythonNativeObject object) { |
| 546 | + public abstract PythonClass execute(PythonNativeObject object); |
| 547 | + |
| 548 | + @Specialization(guards = "object == cachedObject", limit = "1") |
| 549 | + PythonClass getNativeClassCached(@SuppressWarnings("unused") PythonNativeObject object, |
| 550 | + @SuppressWarnings("unused") @Cached("object") PythonNativeObject cachedObject, |
| 551 | + @Cached("getNativeClass(cachedObject)") PythonClass cachedClass) { |
| 552 | + // TODO: (tfel) is this really something we can do? It's so rare for this class to |
| 553 | + // change that it shouldn't be worth the effort, but in native code, anything can |
| 554 | + // happen. OTOH, CPython also has caches that can become invalid when someone just goes |
| 555 | + // and changes the ob_type of an object. |
| 556 | + return cachedClass; |
| 557 | + } |
| 558 | + |
| 559 | + @Specialization |
| 560 | + PythonClass getNativeClass(PythonNativeObject object) { |
546 | 561 | // do not convert wrap 'object.object' since that is really the native pointer object |
547 | 562 | Object[] args = new Object[]{object.object}; |
548 | 563 | return (PythonClass) getToJavaNode().execute(getCallGetObTypeNode().execute(getObTypeFunction(), args)); |
@@ -573,7 +588,7 @@ TruffleObject getObTypeFunction() { |
573 | 588 | } |
574 | 589 |
|
575 | 590 | public static GetNativeClassNode create() { |
576 | | - return new GetNativeClassNode(); |
| 591 | + return GetNativeClassNodeGen.create(); |
577 | 592 | } |
578 | 593 | } |
579 | 594 |
|
|
0 commit comments