Mercurial > hg > graal-jvmci-8
comparison graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/generator/NodeCodeGenerator.java @ 17260:222b60e248ba
Truffle-DSL: fixed regression with @SlowPath on specialize0.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Tue, 30 Sep 2014 00:48:47 +0200 |
parents | 6ee7afea175a |
children | b4e38f4ca414 |
comparison
equal
deleted
inserted
replaced
17259:eff18e262a13 | 17260:222b60e248ba |
---|---|
127 | 127 |
128 private static String castValueName(Parameter parameter) { | 128 private static String castValueName(Parameter parameter) { |
129 return valueName(parameter) + "Cast"; | 129 return valueName(parameter) + "Cast"; |
130 } | 130 } |
131 | 131 |
132 private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean evaluated) { | 132 private void addInternalValueParameters(CodeExecutableElement method, TemplateMethod specialization, boolean forceFrame, boolean disableFrame, boolean evaluated) { |
133 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { | 133 if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) { |
134 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); | 134 method.addParameter(new CodeVariableElement(getContext().getTruffleTypes().getFrame(), "frameValue")); |
135 } | 135 } |
136 for (Parameter parameter : specialization.getParameters()) { | 136 for (Parameter parameter : specialization.getParameters()) { |
137 ParameterSpec spec = parameter.getSpecification(); | 137 ParameterSpec spec = parameter.getSpecification(); |
138 if (forceFrame && spec.getName().equals("frame")) { | 138 if ((disableFrame || forceFrame) && spec.getName().equals("frame")) { |
139 continue; | 139 continue; |
140 } | 140 } |
141 if (spec.isLocal()) { | 141 if (spec.isLocal()) { |
142 continue; | 142 continue; |
143 } | 143 } |
150 method.addParameter(new CodeVariableElement(parameter.getType(), name)); | 150 method.addParameter(new CodeVariableElement(parameter.getType(), name)); |
151 } | 151 } |
152 } | 152 } |
153 | 153 |
154 private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, | 154 private static void addInternalValueParameterNames(CodeTreeBuilder builder, TemplateMethod source, TemplateMethod specialization, String unexpectedValueName, boolean forceFrame, |
155 Map<String, String> customNames) { | 155 boolean disableFrame, Map<String, String> customNames) { |
156 if (forceFrame && specialization.getSpecification().findParameterSpec("frame") != null) { | 156 if (forceFrame && !disableFrame && specialization.getSpecification().findParameterSpec("frame") != null) { |
157 builder.string("frameValue"); | 157 builder.string("frameValue"); |
158 } | 158 } |
159 for (Parameter parameter : specialization.getParameters()) { | 159 for (Parameter parameter : specialization.getParameters()) { |
160 ParameterSpec spec = parameter.getSpecification(); | 160 ParameterSpec spec = parameter.getSpecification(); |
161 if (forceFrame && spec.getName().equals("frame")) { | 161 if ((disableFrame || forceFrame) && spec.getName().equals("frame")) { |
162 continue; | 162 continue; |
163 } | 163 } |
164 | 164 |
165 if (parameter.getSpecification().isLocal()) { | 165 if (parameter.getSpecification().isLocal()) { |
166 continue; | 166 continue; |
320 } | 320 } |
321 | 321 |
322 /** | 322 /** |
323 * <pre> | 323 * <pre> |
324 * variant1 $condition != null | 324 * variant1 $condition != null |
325 * | 325 * |
326 * $type $name = defaultValue($type); | 326 * $type $name = defaultValue($type); |
327 * if ($condition) { | 327 * if ($condition) { |
328 * $name = $value; | 328 * $name = $value; |
329 * } | 329 * } |
330 * | 330 * |
331 * variant2 $condition != null | 331 * variant2 $condition != null |
332 * $type $name = $value; | 332 * $type $name = $value; |
333 * </pre> | 333 * </pre> |
334 * | 334 * |
335 * . | 335 * . |
1032 } | 1032 } |
1033 | 1033 |
1034 private Element createInfoMessage(NodeData node) { | 1034 private Element createInfoMessage(NodeData node) { |
1035 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), CREATE_INFO); | 1035 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, STATIC), getContext().getType(String.class), CREATE_INFO); |
1036 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message")); | 1036 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "message")); |
1037 addInternalValueParameters(method, node.getGenericSpecialization(), false, false); | 1037 addInternalValueParameters(method, node.getGenericSpecialization(), false, false, false); |
1038 | 1038 |
1039 CodeTreeBuilder builder = method.createBuilder(); | 1039 CodeTreeBuilder builder = method.createBuilder(); |
1040 | 1040 |
1041 builder.startIf().tree(truffleBooleanOption(builder, TruffleTypes.OPTION_DETAILED_REWRITE_REASONS)).end(); | 1041 builder.startIf().tree(truffleBooleanOption(builder, TruffleTypes.OPTION_DETAILED_REWRITE_REASONS)).end(); |
1042 builder.startBlock(); | 1042 builder.startBlock(); |
1087 return method; | 1087 return method; |
1088 } | 1088 } |
1089 | 1089 |
1090 private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph) { | 1090 private CodeExecutableElement createCachedExecute(NodeData node, SpecializationData polymorph) { |
1091 CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_CHAINED); | 1091 CodeExecutableElement cachedExecute = new CodeExecutableElement(modifiers(PROTECTED, ABSTRACT), polymorph.getReturnType().getType(), EXECUTE_CHAINED); |
1092 addInternalValueParameters(cachedExecute, polymorph, true, false); | 1092 addInternalValueParameters(cachedExecute, polymorph, true, false, false); |
1093 | 1093 |
1094 ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0); | 1094 ExecutableTypeData sourceExecutableType = node.findExecutableType(polymorph.getReturnType().getTypeSystemType(), 0); |
1095 boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(getContext()); | 1095 boolean sourceThrowsUnexpected = sourceExecutableType != null && sourceExecutableType.hasUnexpectedValue(getContext()); |
1096 if (sourceThrowsUnexpected && sourceExecutableType.getType().equals(node.getGenericSpecialization().getReturnType().getTypeSystemType())) { | 1096 if (sourceThrowsUnexpected && sourceExecutableType.getType().equals(node.getGenericSpecialization().getReturnType().getTypeSystemType())) { |
1097 sourceThrowsUnexpected = false; | 1097 sourceThrowsUnexpected = false; |
1242 | 1242 |
1243 protected final CodeExecutableElement createExecuteUninitialized() { | 1243 protected final CodeExecutableElement createExecuteUninitialized() { |
1244 NodeData node = getModel().getNode(); | 1244 NodeData node = getModel().getNode(); |
1245 SpecializationData generic = node.getGenericSpecialization(); | 1245 SpecializationData generic = node.getGenericSpecialization(); |
1246 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), generic.getReturnType().getType(), EXECUTE_UNINITIALIZED); | 1246 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED), generic.getReturnType().getType(), EXECUTE_UNINITIALIZED); |
1247 addInternalValueParameters(method, generic, true, false); | 1247 addInternalValueParameters(method, generic, true, false, false); |
1248 CodeTreeBuilder builder = method.createBuilder(); | 1248 CodeTreeBuilder builder = method.createBuilder(); |
1249 | 1249 |
1250 boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); | |
1250 CodeTreeBuilder createSpecializationCall = builder.create(); | 1251 CodeTreeBuilder createSpecializationCall = builder.create(); |
1251 createSpecializationCall.startCall(SPECIALIZE); | 1252 createSpecializationCall.startCall(SPECIALIZE); |
1252 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, node.isFrameUsedByAnyGuard(getContext()), null); | 1253 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); |
1253 createSpecializationCall.end(); | 1254 createSpecializationCall.end(); |
1254 builder.declaration(baseClassName(node), "newNode", createSpecializationCall); | 1255 builder.declaration(baseClassName(node), "newNode", createSpecializationCall); |
1255 | 1256 |
1256 if (generic.isReachable()) { | 1257 if (generic.isReachable()) { |
1257 builder.startIf().string("newNode == null").end().startBlock(); | 1258 builder.startIf().string("newNode == null").end().startBlock(); |
1267 } | 1268 } |
1268 | 1269 |
1269 builder.startReturn(); | 1270 builder.startReturn(); |
1270 builder.startStaticCall(context.getTruffleTypes().getDslShare(), "rewriteUninitialized").string("this").string("newNode").end(); | 1271 builder.startStaticCall(context.getTruffleTypes().getDslShare(), "rewriteUninitialized").string("this").string("newNode").end(); |
1271 builder.string(".").startCall(EXECUTE_CHAINED); | 1272 builder.string(".").startCall(EXECUTE_CHAINED); |
1272 addInternalValueParameterNames(builder, generic, generic, null, true, null); | 1273 addInternalValueParameterNames(builder, generic, generic, null, true, false, null); |
1273 builder.end(); | 1274 builder.end(); |
1274 builder.end(); | 1275 builder.end(); |
1275 | 1276 |
1276 if (generic.isReachable()) { | 1277 if (generic.isReachable()) { |
1277 builder.end(); | 1278 builder.end(); |
1281 } | 1282 } |
1282 | 1283 |
1283 private CodeTree createInfoCall(CodeTreeBuilder parent, SpecializationData specialization, String reason) { | 1284 private CodeTree createInfoCall(CodeTreeBuilder parent, SpecializationData specialization, String reason) { |
1284 CodeTreeBuilder builder = parent.create(); | 1285 CodeTreeBuilder builder = parent.create(); |
1285 builder.startCall(CREATE_INFO).string(reason); | 1286 builder.startCall(CREATE_INFO).string(reason); |
1286 addInternalValueParameterNames(builder, specialization, specialization, null, false, null); | 1287 addInternalValueParameterNames(builder, specialization, specialization, null, false, false, null); |
1287 builder.end(); | 1288 builder.end(); |
1288 return builder.getRoot(); | 1289 return builder.getRoot(); |
1289 } | 1290 } |
1290 | 1291 |
1291 private CodeExecutableElement createMonomorphicRewrite() { | 1292 private CodeExecutableElement createMonomorphicRewrite() { |
1292 NodeData node = getModel().getNode(); | 1293 NodeData node = getModel().getNode(); |
1293 | 1294 |
1294 SpecializationData generic = node.getGenericSpecialization(); | 1295 SpecializationData generic = node.getGenericSpecialization(); |
1295 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), generic.getReturnType().getType(), REWRITE); | 1296 CodeExecutableElement method = new CodeExecutableElement(modifiers(PROTECTED, FINAL), generic.getReturnType().getType(), REWRITE); |
1296 addInternalValueParameters(method, generic, true, false); | 1297 addInternalValueParameters(method, generic, true, false, false); |
1297 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); | 1298 method.addParameter(new CodeVariableElement(getContext().getType(String.class), "reason")); |
1298 | 1299 |
1300 boolean needsFrame = node.isFrameUsedByAnyGuard(getContext()); | |
1299 CodeTreeBuilder builder = method.createBuilder(); | 1301 CodeTreeBuilder builder = method.createBuilder(); |
1300 | 1302 |
1301 builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end().end(); | 1303 builder.startStatement().startStaticCall(context.getTruffleTypes().getCompilerAsserts(), "neverPartOfCompilation").end().end(); |
1302 String baseClassName = baseClassName(getModel().getNode()); | 1304 String baseClassName = baseClassName(getModel().getNode()); |
1303 CodeTreeBuilder createSpecializationCall = builder.create(); | 1305 CodeTreeBuilder createSpecializationCall = builder.create(); |
1304 createSpecializationCall.startCall(SPECIALIZE); | 1306 createSpecializationCall.startCall(SPECIALIZE); |
1305 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, node.isFrameUsedByAnyGuard(getContext()), null); | 1307 addInternalValueParameterNames(createSpecializationCall, generic, generic, null, needsFrame, !needsFrame, null); |
1306 createSpecializationCall.end(); | 1308 createSpecializationCall.end(); |
1307 builder.declaration(baseClassName, "newNode", createSpecializationCall); | 1309 builder.declaration(baseClassName, "newNode", createSpecializationCall); |
1308 | 1310 |
1309 builder.startIf().string("newNode == null").end().startBlock(); | 1311 builder.startIf().string("newNode == null").end().startBlock(); |
1310 builder.startStatement(); | 1312 builder.startStatement(); |
1326 builder.tree(createRewritePolymorphic(builder, node, "this")); | 1328 builder.tree(createRewritePolymorphic(builder, node, "this")); |
1327 builder.end(); | 1329 builder.end(); |
1328 | 1330 |
1329 builder.startReturn(); | 1331 builder.startReturn(); |
1330 builder.startCall("returnNode", EXECUTE_CHAINED); | 1332 builder.startCall("returnNode", EXECUTE_CHAINED); |
1331 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, null); | 1333 addInternalValueParameterNames(builder, node.getGenericSpecialization(), node.getGenericSpecialization(), null, true, false, null); |
1332 builder.end(); | 1334 builder.end(); |
1333 builder.end(); | 1335 builder.end(); |
1334 | 1336 |
1335 return method; | 1337 return method; |
1336 } | 1338 } |
1361 | 1363 |
1362 if (!needsFrame) { | 1364 if (!needsFrame) { |
1363 method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath())); | 1365 method.getAnnotationMirrors().add(new CodeAnnotationMirror(getContext().getTruffleTypes().getSlowPath())); |
1364 } | 1366 } |
1365 | 1367 |
1366 addInternalValueParameters(method, node.getGenericSpecialization(), needsFrame, false); | 1368 addInternalValueParameters(method, node.getGenericSpecialization(), needsFrame, !needsFrame, false); |
1367 final CodeTreeBuilder builder = method.createBuilder(); | 1369 final CodeTreeBuilder builder = method.createBuilder(); |
1368 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, new CodeBlock<SpecializationData>() { | 1370 builder.tree(createExecuteTree(builder, node.getGenericSpecialization(), group, new CodeBlock<SpecializationData>() { |
1369 | 1371 |
1370 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { | 1372 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { |
1371 return createCreateSpecializationMethodBody0(builder, current, needsFrame); | 1373 return createCreateSpecializationMethodBody0(builder, current, needsFrame); |
2227 | 2229 |
2228 builder.startReturn(); | 2230 builder.startReturn(); |
2229 | 2231 |
2230 CodeTreeBuilder execute = new CodeTreeBuilder(builder); | 2232 CodeTreeBuilder execute = new CodeTreeBuilder(builder); |
2231 execute.startCall("next0", EXECUTE_CHAINED); | 2233 execute.startCall("next0", EXECUTE_CHAINED); |
2232 addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, null); | 2234 addInternalValueParameterNames(execute, specialization, polymorphic, param.getLocalName(), true, false, null); |
2233 execute.end(); | 2235 execute.end(); |
2234 | 2236 |
2235 TypeData sourceType = polymorphic.getReturnType().getTypeSystemType(); | 2237 TypeData sourceType = polymorphic.getReturnType().getTypeSystemType(); |
2236 | 2238 |
2237 builder.tree(createExpectExecutableType(node, sourceType, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), execute.getRoot())); | 2239 builder.tree(createExpectExecutableType(node, sourceType, currentExecutable.hasUnexpectedValue(context), currentExecutable.getType(), execute.getRoot())); |
2343 protected CodeTree createCallRewriteMonomorphic(CodeTreeBuilder parent, boolean hasUnexpected, TypeData returnType, SpecializationData current, Parameter exceptionParam, String reason) { | 2345 protected CodeTree createCallRewriteMonomorphic(CodeTreeBuilder parent, boolean hasUnexpected, TypeData returnType, SpecializationData current, Parameter exceptionParam, String reason) { |
2344 NodeData node = current.getNode(); | 2346 NodeData node = current.getNode(); |
2345 SpecializationData generic = node.getGenericSpecialization(); | 2347 SpecializationData generic = node.getGenericSpecialization(); |
2346 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); | 2348 CodeTreeBuilder specializeCall = new CodeTreeBuilder(parent); |
2347 specializeCall.startCall(REWRITE); | 2349 specializeCall.startCall(REWRITE); |
2348 addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, null); | 2350 addInternalValueParameterNames(specializeCall, generic, node.getGenericSpecialization(), exceptionParam != null ? exceptionParam.getLocalName() : null, true, false, null); |
2349 specializeCall.doubleQuote(reason); | 2351 specializeCall.doubleQuote(reason); |
2350 specializeCall.end().end(); | 2352 specializeCall.end().end(); |
2351 | 2353 |
2352 CodeTreeBuilder builder = new CodeTreeBuilder(parent); | 2354 CodeTreeBuilder builder = new CodeTreeBuilder(parent); |
2353 | 2355 |
2665 executeMethod.getModifiers().remove(Modifier.ABSTRACT); | 2667 executeMethod.getModifiers().remove(Modifier.ABSTRACT); |
2666 CodeTreeBuilder builder = executeMethod.createBuilder(); | 2668 CodeTreeBuilder builder = executeMethod.createBuilder(); |
2667 | 2669 |
2668 if (specialization.isPolymorphic()) { | 2670 if (specialization.isPolymorphic()) { |
2669 builder.startReturn().startCall("this.next0", EXECUTE_CHAINED); | 2671 builder.startReturn().startCall("this.next0", EXECUTE_CHAINED); |
2670 addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, null); | 2672 addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, false, null); |
2671 builder.end().end(); | 2673 builder.end().end(); |
2672 } else if (specialization.isUninitialized()) { | 2674 } else if (specialization.isUninitialized()) { |
2673 builder.tree(createDeoptimizeUninitialized(node, builder)); | 2675 builder.tree(createDeoptimizeUninitialized(node, builder)); |
2674 builder.startReturn().startCall("this", EXECUTE_UNINITIALIZED); | 2676 builder.startReturn().startCall("this", EXECUTE_UNINITIALIZED); |
2675 addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, null); | 2677 addInternalValueParameterNames(builder, polymorphic, polymorphic, null, true, false, null); |
2676 builder.end().end(); | 2678 builder.end().end(); |
2677 } else { | 2679 } else { |
2678 CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder); | 2680 CodeTreeBuilder elseBuilder = new CodeTreeBuilder(builder); |
2679 elseBuilder.startReturn().startCall("this.next0", EXECUTE_CHAINED); | 2681 elseBuilder.startReturn().startCall("this.next0", EXECUTE_CHAINED); |
2680 addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, null); | 2682 addInternalValueParameterNames(elseBuilder, polymorphic, polymorphic, null, true, false, null); |
2681 elseBuilder.end().end(); | 2683 elseBuilder.end().end(); |
2682 | 2684 |
2683 builder.tree(createExecuteTree(builder, polymorphic, SpecializationGroup.create(specialization), new CodeBlock<SpecializationData>() { | 2685 builder.tree(createExecuteTree(builder, polymorphic, SpecializationGroup.create(specialization), new CodeBlock<SpecializationData>() { |
2684 | 2686 |
2685 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { | 2687 public CodeTree create(CodeTreeBuilder b, SpecializationData current) { |
2862 } | 2864 } |
2863 | 2865 |
2864 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent); | 2866 CodeTreeBuilder returnBuilder = new CodeTreeBuilder(parent); |
2865 if (specialization.isPolymorphic()) { | 2867 if (specialization.isPolymorphic()) { |
2866 returnBuilder.startCall("next0", EXECUTE_CHAINED); | 2868 returnBuilder.startCall("next0", EXECUTE_CHAINED); |
2867 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, null); | 2869 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null); |
2868 returnBuilder.end(); | 2870 returnBuilder.end(); |
2869 } else if (specialization.isUninitialized()) { | 2871 } else if (specialization.isUninitialized()) { |
2870 returnBuilder.startCall(EXECUTE_UNINITIALIZED); | 2872 returnBuilder.startCall(EXECUTE_UNINITIALIZED); |
2871 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, null); | 2873 addInternalValueParameterNames(returnBuilder, specialization, specialization, null, true, false, null); |
2872 returnBuilder.end(); | 2874 returnBuilder.end(); |
2873 } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { | 2875 } else if (specialization.getMethod() == null && !node.needsRewrites(context)) { |
2874 emitEncounteredSynthetic(builder, specialization); | 2876 emitEncounteredSynthetic(builder, specialization); |
2875 } else { | 2877 } else { |
2876 returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null)); | 2878 returnBuilder.tree(createTemplateMethodCall(returnBuilder, null, specialization, specialization, null)); |