Bug #3694
closedMultithreading issue: Internal error: Cannot set local variable: no slot allocated
100%
Description
Summary
This problem arises when a template rule is defined in more than one mode, and when JIT is enabled (which is the default), and when the first activations of the template rule in two different modes occur in different threads. Several threads initializing the template rule simultaneously can then interfere with each other. The observed problem was with allocation of slot numbers to local variables, but it could manifest itself with different symptoms.
Hello,
The attached archive contains the TEI XSLTs. If I run the following line a couple of times (the ThreadManagerEE from the exception makes me believe this is a threading issue) I will eventually hit the exception from below. Deactivating the optimizations appears to fix the issue (again, being a threading issue I can't tell for sure).
java -cp saxon9ee.jar net.sf.saxon.Transform -s:TEI-Lite-P5-documentation.xml -xsl:stylesheet\profiles\default\epub\to.xsl -o:index.html
java.util.concurrent.ExecutionException: java.lang.AssertionError: Internal error: Cannot set local variable: no slot allocated
at java.util.concurrent.FutureTask.report(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at com.saxonica.ee.trans.ThreadManagerEE.waitForChildThreads(ThreadManagerEE.java:83)
at net.sf.saxon.expr.XPathContextMajor.waitForChildThreads(XPathContextMajor.java:221)
at net.sf.saxon.Controller.transformDocument(Controller.java:2421)
at net.sf.saxon.Controller.transform(Controller.java:1970)
at net.sf.saxon.s9api.Xslt30Transformer.applyTemplates(Xslt30Transformer.java:593)
at net.sf.saxon.Transform.processFile(Transform.java:1259)
at net.sf.saxon.Transform.doTransform(Transform.java:782)
at net.sf.saxon.Transform.main(Transform.java:81)
Caused by: java.lang.AssertionError: Internal error: Cannot set local variable: no slot allocated
at net.sf.saxon.expr.XPathContextMinor.setLocalVariable(XPathContextMinor.java:324)
at net.sf.saxon.expr.LetExpression.processLeavingTail(LetExpression.java:693)
at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:879)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:347)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:502)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:295)
at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:252)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:687)
at net.sf.saxon.expr.instruct.TemplateRule.applyLeavingTail(TemplateRule.java:347)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:502)
at net.sf.saxon.expr.instruct.ApplyTemplates.apply(ApplyTemplates.java:295)
at net.sf.saxon.expr.instruct.ApplyTemplates.processLeavingTail(ApplyTemplates.java:252)
at net.sf.saxon.expr.instruct.Choose.processLeavingTail(Choose.java:879)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:151)
at net.sf.saxon.expr.instruct.ForEach.processLeavingTail(ForEach.java:472)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:151)
at net.sf.saxon.expr.instruct.DocumentInstr.evaluateItem(DocumentInstr.java:302)
at net.sf.saxon.expr.instruct.DocumentInstr.evaluateItem(DocumentInstr.java:50)
at net.sf.saxon.expr.parser.ExpressionTool.evaluate(ExpressionTool.java:328)
at net.sf.saxon.expr.LetExpression.eval(LetExpression.java:511)
at net.sf.saxon.expr.LetExpression.process(LetExpression.java:580)
at com.saxonica.ee.bytecode.ByteCodeCandidate.process(ByteCodeCandidate.java:141)
at net.sf.saxon.expr.parser.ExpressionTool.evaluate(ExpressionTool.java:350)
at net.sf.saxon.expr.instruct.UserFunction.call(UserFunction.java:616)
at net.sf.saxon.expr.UserFunctionCall.callFunction(UserFunctionCall.java:541)
at net.sf.saxon.expr.UserFunctionCall.iterate(UserFunctionCall.java:487)
at net.sf.saxon.expr.AdjacentTextNodeMerger.iterate(AdjacentTextNodeMerger.java:229)
at net.sf.saxon.expr.Atomizer.iterate(Atomizer.java:321)
at net.sf.saxon.expr.AtomicSequenceConverter.iterate(AtomicSequenceConverter.java:266)
at net.sf.saxon.expr.parser.Evaluator$5.evaluate(Evaluator.java:101)
at net.sf.saxon.expr.SystemFunctionCall.evaluateArguments(SystemFunctionCall.java:448)
at net.sf.saxon.expr.FunctionCall.iterate(FunctionCall.java:545)
at net.sf.saxon.expr.Expression.evaluateItem(Expression.java:840)
at net.sf.saxon.expr.Expression.evaluateAsString(Expression.java:899)
at net.sf.saxon.expr.instruct.SimpleNodeConstructor.processLeavingTail(SimpleNodeConstructor.java:218)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:687)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:151)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:337)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:284)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:687)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:151)
at com.saxonica.ee.bytecode.ByteCodeCandidate.process(ByteCodeCandidate.java:141)
at net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:264)
at net.sf.saxon.expr.instruct.CallTemplate.process(CallTemplate.java:353)
at net.sf.saxon.expr.instruct.CallTemplate.processLeavingTail(CallTemplate.java:411)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:687)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:151)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:337)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:284)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:151)
at net.sf.saxon.expr.instruct.ForEach.processLeavingTail(ForEach.java:472)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:151)
at net.sf.saxon.expr.LetExpression.process(LetExpression.java:588)
at com.saxonica.ee.bytecode.ByteCodeCandidate.process(ByteCodeCandidate.java:141)
at net.sf.saxon.expr.instruct.UserFunction.process(UserFunction.java:650)
at net.sf.saxon.expr.UserFunctionCall.process(UserFunctionCall.java:589)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:689)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:151)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:337)
at net.sf.saxon.expr.instruct.ElementCreator.processLeavingTail(ElementCreator.java:284)
at net.sf.saxon.expr.instruct.Instruction.process(Instruction.java:151)
at com.saxonica.ee.bytecode.ByteCodeCandidate.process(ByteCodeCandidate.java:141)
at net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:264)
at net.sf.saxon.expr.instruct.CallTemplate.process(CallTemplate.java:353)
at net.sf.saxon.expr.instruct.ResultDocument.processInstruction(ResultDocument.java:480)
at com.saxonica.config.EnterpriseConfiguration$5.call(EnterpriseConfiguration.java:1973)
at com.saxonica.config.EnterpriseConfiguration$5.call(EnterpriseConfiguration.java:1969)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Files
Updated by Michael Kay over 6 years ago
- Category set to Multithreading
- Status changed from New to In Progress
- Assignee set to Michael Kay
- Priority changed from Low to Normal
Thanks for reporting it. Problem successfully reproduced.
Updated by Michael Kay over 6 years ago
Very odd. The stack trace shows LetExpression.processLeavingTail() calling XPathContextMinor.setLocalVariable(): in the calling method the slot number is 2, in the called method the slot number is -999.
The offending variable is
<xsl:variable name="context" select="name(parent::*)"/>
at line 504 of common/functions.xsl
On a second run, catching it in the LetExpression.eval(), the slot number is indeed -999. An oddity is that the stackframe variable map for the template rule shows three variables, all called $context, while the template body clearly only has one variable.
Updated by Michael Kay over 6 years ago
May be a tangential issue, but
(a) the problem doesn't seem to occur when -jit:on or -jit:off is specified on the command line, but does occur with -jit:20
(b) the -jit option doesn't seem to be documented
(c) in Transform.java, the data for the -jit option says it's a QName, which is clearly wrong
(d) -jit:20 should be an error (the value must be a boolean) but isn't.
I can't see why -jit:on should behave differently from omitting the -jit option, but this appears to be the case.
Updated by Michael Kay over 6 years ago
Note that the template rule has two modes.
It seems that the JIT initializer for the template is running twice, and on each occasion it is initializing the template for both modes. Moreover this is happening in different threads:
Initializing template net.sf.saxon.style.XSLTemplate@13ba2ae with match = text() at line 496 in thread 11
Allocate slots for text() in mode Mode plain
Allocate slots for text() in mode The unnamed mode
Initializing template net.sf.saxon.style.XSLTemplate@13ba2ae with match = text() at line 496 in thread 1
Allocate slots for text() in mode Mode plain
Allocate slots for text() in mode The unnamed mode
Thus two initializations of the same template may occur in parallel, which is presumably playing havoc with the slot number allocations.
I think the theory was that we would initialize the template in all modes as soon as it is executed in one mode. But the problem is that a reference to the initializer is held in the TemplateRuleEE object, which has one occurrence for each mode.
The simplest solution to this is probably that TemplateRuleInitializer.init() (which is synchronized) should do nothing if it is called a second or subsequent time.
No: this doesn't work, because we are calling two different TemplateRuleInitializer objects.
Updated by Michael Kay over 6 years ago
- Subject changed from Internal error: Cannot set local variable: no slot allocated to Multithreading issue: Internal error: Cannot set local variable: no slot allocated
- Description updated (diff)
Fixed the problem by changes to TemplateRuleInitializer so it (a) does the processing for the template rule as a whole if it has not already been done, and then (b) does the processing for one particular mode.
Updated by Michael Kay over 6 years ago
- Status changed from In Progress to Resolved
- Applies to branch trunk added
- Fix Committed on Branch 9.8, trunk added
Also fixed the failure to validate the -jit option. The failure to document the option is the subject of a separate bug.
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.10 added
Bug fix applied in the Saxon 9.8.0.10 maintenance release.
Please register to edit this issue