1 /* |
1 /* |
2 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
30 |
30 |
31 import java.util.HashSet; |
31 import java.util.HashSet; |
32 import java.util.List; |
32 import java.util.List; |
33 |
33 |
34 import jdk.internal.vm.compiler.collections.EconomicMap; |
34 import jdk.internal.vm.compiler.collections.EconomicMap; |
|
35 import jdk.internal.vm.compiler.collections.Equivalence; |
35 import org.graalvm.compiler.core.common.cfg.BlockMap; |
36 import org.graalvm.compiler.core.common.cfg.BlockMap; |
36 import org.graalvm.compiler.core.common.type.ObjectStamp; |
37 import org.graalvm.compiler.core.common.type.ObjectStamp; |
37 import org.graalvm.compiler.core.common.type.Stamp; |
38 import org.graalvm.compiler.core.common.type.Stamp; |
38 import org.graalvm.compiler.core.common.type.StampFactory; |
39 import org.graalvm.compiler.core.common.type.StampFactory; |
39 import org.graalvm.compiler.debug.GraalError; |
40 import org.graalvm.compiler.debug.GraalError; |
59 import org.graalvm.compiler.nodes.StructuredGraph; |
60 import org.graalvm.compiler.nodes.StructuredGraph; |
60 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult; |
61 import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult; |
61 import org.graalvm.compiler.nodes.ValueNode; |
62 import org.graalvm.compiler.nodes.ValueNode; |
62 import org.graalvm.compiler.nodes.calc.FloatingNode; |
63 import org.graalvm.compiler.nodes.calc.FloatingNode; |
63 import org.graalvm.compiler.nodes.cfg.Block; |
64 import org.graalvm.compiler.nodes.cfg.Block; |
|
65 import org.graalvm.compiler.nodes.spi.CoreProviders; |
64 import org.graalvm.compiler.phases.BasePhase; |
66 import org.graalvm.compiler.phases.BasePhase; |
65 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator; |
67 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator; |
66 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure; |
68 import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure; |
67 import org.graalvm.compiler.phases.schedule.SchedulePhase; |
69 import org.graalvm.compiler.phases.schedule.SchedulePhase; |
68 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy; |
70 import org.graalvm.compiler.phases.schedule.SchedulePhase.SchedulingStrategy; |
69 import org.graalvm.compiler.phases.tiers.PhaseContext; |
|
70 |
71 |
71 import jdk.vm.ci.code.BytecodeFrame; |
72 import jdk.vm.ci.code.BytecodeFrame; |
72 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant; |
73 import jdk.vm.ci.hotspot.HotSpotMetaspaceConstant; |
73 import jdk.vm.ci.hotspot.HotSpotObjectConstant; |
74 import jdk.vm.ci.hotspot.HotSpotObjectConstant; |
74 import jdk.vm.ci.hotspot.HotSpotResolvedJavaType; |
75 import jdk.vm.ci.hotspot.HotSpotResolvedJavaType; |
76 import jdk.vm.ci.meta.Constant; |
77 import jdk.vm.ci.meta.Constant; |
77 import jdk.vm.ci.meta.ConstantReflectionProvider; |
78 import jdk.vm.ci.meta.ConstantReflectionProvider; |
78 import jdk.vm.ci.meta.MetaAccessProvider; |
79 import jdk.vm.ci.meta.MetaAccessProvider; |
79 import jdk.vm.ci.meta.ResolvedJavaType; |
80 import jdk.vm.ci.meta.ResolvedJavaType; |
80 |
81 |
81 public class ReplaceConstantNodesPhase extends BasePhase<PhaseContext> { |
82 public class ReplaceConstantNodesPhase extends BasePhase<CoreProviders> { |
82 |
83 |
83 private final boolean verifyFingerprints; |
84 private final boolean verifyFingerprints; |
84 |
85 |
85 static Class<?> characterCacheClass = Character.class.getDeclaredClasses()[0]; |
86 static Class<?> characterCacheClass = Character.class.getDeclaredClasses()[0]; |
86 static Class<?> byteCacheClass = Byte.class.getDeclaredClasses()[0]; |
87 static Class<?> byteCacheClass = Byte.class.getDeclaredClasses()[0]; |
316 private static void tryToReplaceWithExisting(StructuredGraph graph, ConstantNode node) { |
317 private static void tryToReplaceWithExisting(StructuredGraph graph, ConstantNode node) { |
317 ScheduleResult schedule = graph.getLastSchedule(); |
318 ScheduleResult schedule = graph.getLastSchedule(); |
318 NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap(); |
319 NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap(); |
319 BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap(); |
320 BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap(); |
320 |
321 |
321 EconomicMap<Block, Node> blockToExisting = EconomicMap.create(); |
322 EconomicMap<Block, Node> blockToExisting = EconomicMap.create(Equivalence.IDENTITY); |
322 for (Node n : node.usages().filter(n -> isReplacementNode(n))) { |
323 for (Node n : node.usages().filter(n -> isReplacementNode(n))) { |
323 blockToExisting.put(nodeToBlock.get(n), n); |
324 blockToExisting.put(nodeToBlock.get(n), n); |
324 } |
325 } |
325 for (Node use : node.usages().filter(n -> !isReplacementNode(n)).snapshot()) { |
326 for (Node use : node.usages().filter(n -> !isReplacementNode(n)).snapshot()) { |
326 boolean replaced = false; |
327 boolean replaced = false; |
446 * @param graph |
447 * @param graph |
447 * @param stateMapper |
448 * @param stateMapper |
448 * @param node |
449 * @param node |
449 * @param context |
450 * @param context |
450 */ |
451 */ |
451 private static void handleLoadMethodCounters(StructuredGraph graph, FrameStateMapperClosure stateMapper, LoadMethodCountersNode node, PhaseContext context) { |
452 private static void handleLoadMethodCounters(StructuredGraph graph, FrameStateMapperClosure stateMapper, LoadMethodCountersNode node, CoreProviders context) { |
452 ResolvedJavaType type = node.getMethod().getDeclaringClass(); |
453 ResolvedJavaType type = node.getMethod().getDeclaringClass(); |
453 Stamp hubStamp = context.getStampProvider().createHubStamp((ObjectStamp) StampFactory.objectNonNull()); |
454 Stamp hubStamp = context.getStampProvider().createHubStamp((ObjectStamp) StampFactory.objectNonNull()); |
454 ConstantReflectionProvider constantReflection = context.getConstantReflection(); |
455 ConstantReflectionProvider constantReflection = context.getConstantReflection(); |
455 ConstantNode klassHint = ConstantNode.forConstant(hubStamp, constantReflection.asObjectHub(type), context.getMetaAccess(), graph); |
456 ConstantNode klassHint = ConstantNode.forConstant(hubStamp, constantReflection.asObjectHub(type), context.getMetaAccess(), graph); |
456 FixedWithNextNode replacement = graph.add(new ResolveMethodAndLoadCountersNode(node.getMethod(), klassHint)); |
457 FixedWithNextNode replacement = graph.add(new ResolveMethodAndLoadCountersNode(node.getMethod(), klassHint)); |
464 * |
465 * |
465 * @param graph |
466 * @param graph |
466 * @param stateMapper |
467 * @param stateMapper |
467 * @param context |
468 * @param context |
468 */ |
469 */ |
469 private static void replaceLoadMethodCounters(StructuredGraph graph, FrameStateMapperClosure stateMapper, PhaseContext context) { |
470 private static void replaceLoadMethodCounters(StructuredGraph graph, FrameStateMapperClosure stateMapper, CoreProviders context) { |
470 new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true).apply(graph, false); |
471 new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, true).apply(graph, false); |
471 |
472 |
472 for (LoadMethodCountersNode node : getLoadMethodCountersNodes(graph)) { |
473 for (LoadMethodCountersNode node : getLoadMethodCountersNodes(graph)) { |
473 if (anyUsagesNeedReplacement(node)) { |
474 if (anyUsagesNeedReplacement(node)) { |
474 handleLoadMethodCounters(graph, stateMapper, node, context); |
475 handleLoadMethodCounters(graph, stateMapper, node, context); |
494 } |
495 } |
495 } |
496 } |
496 } |
497 } |
497 |
498 |
498 @Override |
499 @Override |
499 protected void run(StructuredGraph graph, PhaseContext context) { |
500 protected void run(StructuredGraph graph, CoreProviders context) { |
500 FrameStateMapperClosure stateMapper = new FrameStateMapperClosure(graph); |
501 FrameStateMapperClosure stateMapper = new FrameStateMapperClosure(graph); |
501 ReentrantNodeIterator.apply(stateMapper, graph.start(), null); |
502 ReentrantNodeIterator.apply(stateMapper, graph.start(), null); |
502 |
503 |
503 // Replace LoadMethodCountersNode with ResolveMethodAndLoadCountersNode, expose klass |
504 // Replace LoadMethodCountersNode with ResolveMethodAndLoadCountersNode, expose klass |
504 // constants. |
505 // constants. |