119 } 120 return FingerprintUtil.getFingerprint((HotSpotResolvedObjectType) type) == 0; 121 } 122 123 /** 124 * Replace {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} with indirection. 125 * 126 * @param graph 127 * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs 128 * resolution. 129 */ 130 private void handleHotSpotMetaspaceConstant(StructuredGraph graph, ConstantNode node) { 131 HotSpotMetaspaceConstant metaspaceConstant = (HotSpotMetaspaceConstant) node.asConstant(); 132 HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) metaspaceConstant.asResolvedJavaType(); 133 134 if (type != null) { 135 if (verifyFingerprints && checkForBadFingerprint(type)) { 136 throw new GraalError("Type with bad fingerprint: " + type); 137 } 138 assert !metaspaceConstant.isCompressed() : "No support for replacing compressed metaspace constants"; 139 replaceWithInitialization(graph, node); 140 if (anyUsagesNeedReplacement(node)) { 141 replaceWithResolution(graph, node); 142 } 143 } else { 144 throw new GraalError("Unsupported metaspace constant type: " + type); 145 } 146 } 147 148 /** 149 * Find the lowest dominating {@link FixedWithNextNode} before given node. 150 * 151 * @param graph 152 * @param node 153 * @return the last {@link FixedWithNextNode} that is scheduled before node. 154 */ 155 private static FixedWithNextNode findFixedWithNextBefore(StructuredGraph graph, Node node) { 156 ScheduleResult schedule = graph.getLastSchedule(); 157 NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap(); 158 BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap(); 159 160 Block block = nodeToBlock.get(node); 161 FixedWithNextNode result = null; 162 for (Node n : blockToNodes.get(block)) { 163 if (n instanceof FixedWithNextNode) { 164 result = (FixedWithNextNode) n; 165 } 166 if (n.equals(node)) { 167 break; 168 } 169 } 170 assert result != null; 171 return result; 172 } 173 174 /** 175 * Try to find dominating {@link InitializeKlassNode} that can be reused. 176 * 177 * @param graph 178 * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs 179 * resolution. 180 */ 181 private static void replaceWithInitialization(StructuredGraph graph, ConstantNode node) { 182 ScheduleResult schedule = graph.getLastSchedule(); 183 NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap(); 184 BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap(); 185 186 EconomicMap<Block, Node> blockToInit = EconomicMap.create(); 187 for (Node n : node.usages().filter(InitializeKlassNode.class)) { 188 blockToInit.put(nodeToBlock.get(n), n); 189 } 190 for (Node use : node.usages().filter(n -> !isReplacementNode(n)).snapshot()) { 191 boolean replaced = false; 192 Block b = nodeToBlock.get(use); 193 InitializeKlassNode i = (InitializeKlassNode) blockToInit.get(b); 194 if (i != null) { 195 // There is an initialization in the same block as the use, look if the use is 196 // scheduled after it. 197 for (Node n : blockToNodes.get(b)) { 198 if (n.equals(use)) { 199 // Usage is before initialization, can't use it 200 break; 201 } 202 if (n.equals(i)) { 203 use.replaceFirstInput(node, i); 204 replaced = true; 205 break; 206 } 207 } 208 } 209 if (!replaced) { 210 // Look for dominating blocks that have initializations 211 for (Block d : blockToInit.getKeys()) { 212 if (strictlyDominates(d, b)) { 213 use.replaceFirstInput(node, blockToInit.get(d)); 214 break; 215 } 216 } 217 } 218 } 219 } 220 221 /** 222 * Replace the uses of a constant with either {@link LoadConstantIndirectlyNode} or 223 * {@link ResolveConstantNode}. 224 * 225 * @param graph 226 * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs 227 * resolution. 228 */ 229 private static void replaceWithResolution(StructuredGraph graph, ConstantNode node) { 230 HotSpotMetaspaceConstant metaspaceConstant = (HotSpotMetaspaceConstant) node.asConstant(); 231 HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) metaspaceConstant.asResolvedJavaType(); 232 ResolvedJavaType topMethodHolder = graph.method().getDeclaringClass(); 233 ValueNode replacement; | 119 } 120 return FingerprintUtil.getFingerprint((HotSpotResolvedObjectType) type) == 0; 121 } 122 123 /** 124 * Replace {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} with indirection. 125 * 126 * @param graph 127 * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs 128 * resolution. 129 */ 130 private void handleHotSpotMetaspaceConstant(StructuredGraph graph, ConstantNode node) { 131 HotSpotMetaspaceConstant metaspaceConstant = (HotSpotMetaspaceConstant) node.asConstant(); 132 HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) metaspaceConstant.asResolvedJavaType(); 133 134 if (type != null) { 135 if (verifyFingerprints && checkForBadFingerprint(type)) { 136 throw new GraalError("Type with bad fingerprint: " + type); 137 } 138 assert !metaspaceConstant.isCompressed() : "No support for replacing compressed metaspace constants"; 139 tryToReplaceWithExisting(graph, node); 140 if (anyUsagesNeedReplacement(node)) { 141 replaceWithResolution(graph, node); 142 } 143 } else { 144 throw new GraalError("Unsupported metaspace constant type: " + type); 145 } 146 } 147 148 /** 149 * Find the lowest dominating {@link FixedWithNextNode} before given node. 150 * 151 * @param graph 152 * @param node 153 * @return the last {@link FixedWithNextNode} that is scheduled before node. 154 */ 155 private static FixedWithNextNode findFixedWithNextBefore(StructuredGraph graph, Node node) { 156 ScheduleResult schedule = graph.getLastSchedule(); 157 NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap(); 158 BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap(); 159 160 Block block = nodeToBlock.get(node); 161 FixedWithNextNode result = null; 162 for (Node n : blockToNodes.get(block)) { 163 if (n instanceof FixedWithNextNode) { 164 result = (FixedWithNextNode) n; 165 } 166 if (n.equals(node)) { 167 break; 168 } 169 } 170 assert result != null; 171 return result; 172 } 173 174 /** 175 * Try to find dominating node doing the resolution that can be reused. 176 * 177 * @param graph 178 * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs 179 * resolution. 180 */ 181 private static void tryToReplaceWithExisting(StructuredGraph graph, ConstantNode node) { 182 ScheduleResult schedule = graph.getLastSchedule(); 183 NodeMap<Block> nodeToBlock = schedule.getNodeToBlockMap(); 184 BlockMap<List<Node>> blockToNodes = schedule.getBlockToNodesMap(); 185 186 EconomicMap<Block, Node> blockToExisting = EconomicMap.create(); 187 for (Node n : node.usages().filter(n -> isReplacementNode(n))) { 188 blockToExisting.put(nodeToBlock.get(n), n); 189 } 190 for (Node use : node.usages().filter(n -> !isReplacementNode(n)).snapshot()) { 191 boolean replaced = false; 192 Block b = nodeToBlock.get(use); 193 Node e = blockToExisting.get(b); 194 if (e != null) { 195 // There is an initialization or resolution in the same block as the use, look if 196 // the use is scheduled after it. 197 for (Node n : blockToNodes.get(b)) { 198 if (n.equals(use)) { 199 // Usage is before initialization, can't use it 200 break; 201 } 202 if (n.equals(e)) { 203 use.replaceFirstInput(node, e); 204 replaced = true; 205 break; 206 } 207 } 208 } 209 if (!replaced) { 210 // Look for dominating blocks that have existing nodes 211 for (Block d : blockToExisting.getKeys()) { 212 if (strictlyDominates(d, b)) { 213 use.replaceFirstInput(node, blockToExisting.get(d)); 214 break; 215 } 216 } 217 } 218 } 219 } 220 221 /** 222 * Replace the uses of a constant with either {@link LoadConstantIndirectlyNode} or 223 * {@link ResolveConstantNode}. 224 * 225 * @param graph 226 * @param node {@link ConstantNode} containing a {@link HotSpotResolvedJavaType} that needs 227 * resolution. 228 */ 229 private static void replaceWithResolution(StructuredGraph graph, ConstantNode node) { 230 HotSpotMetaspaceConstant metaspaceConstant = (HotSpotMetaspaceConstant) node.asConstant(); 231 HotSpotResolvedJavaType type = (HotSpotResolvedJavaType) metaspaceConstant.asResolvedJavaType(); 232 ResolvedJavaType topMethodHolder = graph.method().getDeclaringClass(); 233 ValueNode replacement; |