|
42 | 42 | import com.oracle.svm.core.graal.code.SubstrateBackend; |
43 | 43 | import com.oracle.svm.core.graal.meta.KnownOffsets; |
44 | 44 | import com.oracle.svm.core.graal.meta.RuntimeConfiguration; |
| 45 | +import com.oracle.svm.core.graal.nodes.LoadOpenTypeWorldDispatchTableStartingOffset; |
45 | 46 | import com.oracle.svm.core.graal.nodes.LoweredDeadEndNode; |
46 | 47 | import com.oracle.svm.core.graal.nodes.ThrowBytecodeExceptionNode; |
47 | 48 | import com.oracle.svm.core.meta.SharedMethod; |
|
78 | 79 | import jdk.graal.compiler.nodes.PiNode; |
79 | 80 | import jdk.graal.compiler.nodes.StructuredGraph; |
80 | 81 | import jdk.graal.compiler.nodes.ValueNode; |
| 82 | +import jdk.graal.compiler.nodes.calc.AddNode; |
81 | 83 | import jdk.graal.compiler.nodes.calc.IsNullNode; |
82 | 84 | import jdk.graal.compiler.nodes.extended.BranchProbabilityNode; |
83 | 85 | import jdk.graal.compiler.nodes.extended.BytecodeExceptionNode; |
|
92 | 94 | import jdk.graal.compiler.nodes.memory.ReadNode; |
93 | 95 | import jdk.graal.compiler.nodes.memory.address.AddressNode; |
94 | 96 | import jdk.graal.compiler.nodes.memory.address.OffsetAddressNode; |
| 97 | +import jdk.graal.compiler.nodes.spi.Lowerable; |
95 | 98 | import jdk.graal.compiler.nodes.spi.LoweringTool; |
96 | 99 | import jdk.graal.compiler.nodes.spi.LoweringTool.StandardLoweringStage; |
97 | 100 | import jdk.graal.compiler.nodes.spi.StampProvider; |
@@ -295,10 +298,12 @@ public void lower(FixedNode node, LoweringTool tool) { |
295 | 298 | NodeInputList<ValueNode> parameters = callTarget.arguments(); |
296 | 299 | ValueNode receiver = parameters.size() <= 0 ? null : parameters.get(0); |
297 | 300 | FixedGuardNode nullCheck = null; |
| 301 | + List<Lowerable> nodesToLower = new ArrayList<>(3); |
298 | 302 | if (!callTarget.isStatic() && receiver.getStackKind() == JavaKind.Object && !StampTool.isPointerNonNull(receiver)) { |
299 | 303 | LogicNode isNull = graph.unique(IsNullNode.create(receiver)); |
300 | 304 | nullCheck = graph.add(new FixedGuardNode(isNull, DeoptimizationReason.NullCheckException, DeoptimizationAction.None, true)); |
301 | 305 | graph.addBeforeFixed(node, nullCheck); |
| 306 | + nodesToLower.add(nullCheck); |
302 | 307 | } |
303 | 308 | SharedMethod method = (SharedMethod) callTarget.targetMethod(); |
304 | 309 | JavaType[] signature = method.getSignature().toParameterTypes(callTarget.isStatic() ? null : method.getDeclaringClass()); |
@@ -349,7 +354,6 @@ public void lower(FixedNode node, LoweringTool tool) { |
349 | 354 | reportError.setNext(graph.add(new LoweredDeadEndNode())); |
350 | 355 | } |
351 | 356 |
|
352 | | - LoadHubNode hub = null; |
353 | 357 | CallTargetNode loweredCallTarget; |
354 | 358 | if (invokeKind.isDirect() || implementations.length == 1) { |
355 | 359 | SharedMethod targetMethod = method; |
@@ -408,25 +412,51 @@ public void lower(FixedNode node, LoweringTool tool) { |
408 | 412 | loweredCallTarget = createUnreachableCallTarget(tool, node, parameters, callTarget.returnStamp(), signature, method, callType, invokeKind); |
409 | 413 |
|
410 | 414 | } else { |
411 | | - int vtableEntryOffset = knownOffsets.getVTableOffset(method.getVTableIndex()); |
| 415 | + LoadHubNode hub = graph.unique(new LoadHubNode(runtimeConfig.getProviders().getStampProvider(), graph.addOrUnique(PiNode.create(receiver, nullCheck)))); |
| 416 | + nodesToLower.add(hub); |
412 | 417 |
|
413 | | - hub = graph.unique(new LoadHubNode(runtimeConfig.getProviders().getStampProvider(), graph.addOrUnique(PiNode.create(receiver, nullCheck)))); |
414 | | - AddressNode address = graph.unique(new OffsetAddressNode(hub, ConstantNode.forIntegerKind(ConfigurationValues.getWordKind(), vtableEntryOffset, graph))); |
415 | | - ReadNode entry = graph.add(new ReadNode(address, SubstrateBackend.getVTableIdentity(), FrameAccess.getWordStamp(), BarrierType.NONE, MemoryOrderMode.PLAIN)); |
416 | | - loweredCallTarget = createIndirectCall(graph, callTarget, parameters, method, signature, callType, invokeKind, entry); |
| 418 | + if (SubstrateOptions.closedTypeWorld()) { |
| 419 | + int vtableEntryOffset = knownOffsets.getVTableOffset(method.getVTableIndex(), true); |
417 | 420 |
|
418 | | - graph.addBeforeFixed(node, entry); |
| 421 | + AddressNode address = graph.unique(new OffsetAddressNode(hub, ConstantNode.forIntegerKind(ConfigurationValues.getWordKind(), vtableEntryOffset, graph))); |
| 422 | + ReadNode entry = graph.add(new ReadNode(address, SubstrateBackend.getVTableIdentity(), FrameAccess.getWordStamp(), BarrierType.NONE, MemoryOrderMode.PLAIN)); |
| 423 | + |
| 424 | + loweredCallTarget = createIndirectCall(graph, callTarget, parameters, method, signature, callType, invokeKind, entry); |
| 425 | + |
| 426 | + graph.addBeforeFixed(node, entry); |
| 427 | + } else { |
| 428 | + |
| 429 | + // Compute the dispatch table starting offset |
| 430 | + LoadOpenTypeWorldDispatchTableStartingOffset tableStartingOffset = graph.add(new LoadOpenTypeWorldDispatchTableStartingOffset(hub, method)); |
| 431 | + nodesToLower.add(tableStartingOffset); |
| 432 | + |
| 433 | + // Add together table starting offset and index offset |
| 434 | + ValueNode methodAddressOffset = graph.unique(new AddNode(tableStartingOffset, |
| 435 | + ConstantNode.forIntegerKind(ConfigurationValues.getWordKind(), knownOffsets.getVTableOffset(method.getVTableIndex(), false), graph))); |
| 436 | + |
| 437 | + // The load the method address for the dispatch table |
| 438 | + AddressNode dispatchTableAddress = graph.unique(new OffsetAddressNode(hub, methodAddressOffset)); |
| 439 | + ReadNode entry = graph.add(new ReadNode(dispatchTableAddress, SubstrateBackend.getVTableIdentity(), FrameAccess.getWordStamp(), BarrierType.NONE, MemoryOrderMode.PLAIN)); |
| 440 | + |
| 441 | + loweredCallTarget = createIndirectCall(graph, callTarget, parameters, method, signature, callType, invokeKind, entry); |
| 442 | + |
| 443 | + // wire in the new nodes |
| 444 | + FixedWithNextNode predecessor = (FixedWithNextNode) node.predecessor(); |
| 445 | + predecessor.setNext(tableStartingOffset); |
| 446 | + tableStartingOffset.setNext(entry); |
| 447 | + entry.setNext(node); |
| 448 | + |
| 449 | + /* |
| 450 | + * note here we don't delete the invoke because it remains in the graph, |
| 451 | + * albeit with a different call target |
| 452 | + */ |
| 453 | + } |
419 | 454 | } |
420 | 455 |
|
421 | 456 | callTarget.replaceAndDelete(loweredCallTarget); |
422 | 457 |
|
423 | 458 | // Recursive lowering |
424 | | - if (nullCheck != null) { |
425 | | - nullCheck.lower(tool); |
426 | | - } |
427 | | - if (hub != null) { |
428 | | - hub.lower(tool); |
429 | | - } |
| 459 | + nodesToLower.forEach(n -> n.lower(tool)); |
430 | 460 | } |
431 | 461 | } |
432 | 462 |
|
|
0 commit comments