Project

Profile

Help

Bug #3352

closed

Tail call optimization of xsl:call-template not working in 9.8

Added by Michael Kay over 6 years ago. Updated over 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Performance
Sprint/Milestone:
-
Start date:
2017-07-15
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
9.8
Fix Committed on Branch:
9.8
Fixed in Maintenance Release:
Platforms:

Description

Tail call optimization of xsl;call-template (and possibly xsl:apply-templates) is not working in 9.8. Deep recursion results in

Too many nested template or function calls. The stylesheet may be looping.
  at xsl:call-template name="call" (file:/Users/mike/Desktop/temp/test.xsl#22)
  at xsl:call-template name="call" (file:/Users/mike/Desktop/temp/test.xsl#22)

In 9.7, XSLTemplate.postValidate() contained the code

isTailRecursive = markTailCalls();

which has disappeared in 9.8.

Actions #1

Updated by Michael Kay over 6 years ago

The reason this has changed is a side-effect of JIT compilation of template rules. We need to determine whether a template is tail recursive at the point where we compile the code.

Actions #2

Updated by Michael Kay over 6 years ago

  • Status changed from New to Resolved
  • Fix Committed on Branch 9.8 added

Fixed on the 9.8 branch.

Actions #3

Updated by Michael Kay over 6 years ago

  • Status changed from Resolved to In Progress

Reopening because test case isn't working when running with bytecode enabled.

New tests were added to xslt30extra / optimize - opt-024 and opt-025.

Actions #4

Updated by Michael Kay over 6 years ago

Turns out it's a little more complicated than this. The xsl:call-template instruction is being marked with a flag "use tail recursion" at the time it is compiled, but this doesn't take account of the face that with multiple packages and separate compilation, not to mention JIT compilation, we can no longer know that the target template is tail recursive at the point where we compile the call-templates instruction. We need to make this decision at run-time when we know what template we are actually calling.

Actions #5

Updated by Michael Kay over 6 years ago

  • Status changed from In Progress to Resolved

Ignore the last comment.

There's a property on an xsl:call-template instruction to say whether it's a tail call or not. This has nothing to do with knowing whether the target template is tail recursive.

The reason my test was failing was that it was exporting and re-importing the compiled package, and the above-mentioned property is not being preserved across export/import. I've fixed this.

There is also a property on a template to say whether it is tail recursive. This property is used only to prevent byte code being generated for that template. I'm not sure why (or whether) that is necessary, but I'm going to leave it alone for the moment.

Actions #6

Updated by O'Neil Delpratt over 6 years ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 9.8.0.4 added

Bug fix applied in the Saxon 9.8.0.4 maintenance release.

Please register to edit this issue

Also available in: Atom PDF