From 754e6eb5932d5dac87b6e2b73e4d9cea1f853005 Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Wed, 1 Aug 2012 18:25:25 -0700 Subject: [PATCH] mirrored parser ATN sim changes in lexer ATN sim for thread safety. reduced contention for contextCache. --- .../v4/runtime/atn/LexerATNSimulator.java | 42 +++++++++++-------- .../v4/runtime/atn/ParserATNSimulator.java | 14 +++---- .../v4/runtime/atn/PredictionContext.java | 18 +++++--- 3 files changed, 41 insertions(+), 33 deletions(-) diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java index b36cf1711..9b63852f0 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java @@ -706,11 +706,14 @@ public class LexerATNSimulator extends ATNSimulator { protected void addDFAEdge(@NotNull DFAState p, int t, @NotNull DFAState q) { if (t < 0 || t > MAX_DFA_EDGE) return; // Only track edges within the DFA bounds - if ( p.edges==null ) { - // make room for tokens 1..n and -1 masquerading as index 0 - p.edges = new DFAState[MAX_DFA_EDGE+1]; // TODO: make adaptive + DFA dfa = decisionToDFA[mode]; + synchronized (dfa) { + if ( p.edges==null ) { + // make room for tokens 1..n and -1 masquerading as index 0 + p.edges = new DFAState[MAX_DFA_EDGE+1]; // TODO: make adaptive + } + p.edges[t] = q; // connect } - p.edges[t] = q; // connect } /** Add a new DFA state if there isn't one with this set of @@ -724,11 +727,6 @@ public class LexerATNSimulator extends ATNSimulator { if ( configs.hasSemanticContext ) return null; DFAState proposed = new DFAState(configs); - DFAState existing = decisionToDFA[mode].states.get(proposed); - if ( existing!=null ) return existing; - - DFAState newState = proposed; - ATNConfig firstConfigWithRuleStopState = null; for (ATNConfig c : configs) { if ( c.state instanceof RuleStopState ) { @@ -738,18 +736,26 @@ public class LexerATNSimulator extends ATNSimulator { } if ( firstConfigWithRuleStopState!=null ) { - newState.isAcceptState = true; - newState.lexerRuleIndex = firstConfigWithRuleStopState.state.ruleIndex; - newState.lexerActionIndex = + proposed.isAcceptState = true; + proposed.lexerRuleIndex = firstConfigWithRuleStopState.state.ruleIndex; + proposed.lexerActionIndex = ((LexerATNConfig)firstConfigWithRuleStopState).lexerActionIndex; - newState.prediction = atn.ruleToTokenType[newState.lexerRuleIndex]; + proposed.prediction = atn.ruleToTokenType[proposed.lexerRuleIndex]; } - newState.stateNumber = decisionToDFA[mode].states.size(); - configs.setReadonly(true); - newState.configs = configs; - decisionToDFA[mode].states.put(newState, newState); - return newState; + DFA dfa = decisionToDFA[mode]; + synchronized (dfa) { + DFAState existing = dfa.states.get(proposed); + if ( existing!=null ) return existing; + + DFAState newState = proposed; + + newState.stateNumber = dfa.states.size(); + configs.setReadonly(true); + newState.configs = configs; + decisionToDFA[mode].states.put(newState, newState); + return newState; + } } @Nullable diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java index 0e01330a9..1e47b197d 100755 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java @@ -283,9 +283,7 @@ public class ParserATNSimulator extends ATNSimulator { if ( s.isCtxSensitive && !SLL ) { if ( dfa_debug ) System.out.println("ctx sensitive state "+outerContext+" in "+s); PredictionContext predictionCtx = PredictionContext.fromRuleContext(outerContext); - synchronized (sharedContextCache) { - predictionCtx = getCachedContext(predictionCtx); - } + predictionCtx = getCachedContext(predictionCtx); Integer predI = s.contextToPredictedAlt.get(predictionCtx); if ( predI!=null ) { return predI; // ha! quick exit :) @@ -543,9 +541,7 @@ public class ParserATNSimulator extends ATNSimulator { greedy); // not accept state: isCtxSensitive PredictionContext predictionCtx = PredictionContext.fromRuleContext(outerContext); - synchronized (sharedContextCache) { - predictionCtx = getCachedContext(predictionCtx); - } + predictionCtx = getCachedContext(predictionCtx); D.isCtxSensitive = true; // always force DFA to ATN simulate predictedAlt = fullCtxSet.uniqueAlt; D.prediction = ATN.INVALID_ALT_NUMBER; @@ -1436,10 +1432,10 @@ public class ParserATNSimulator extends ATNSimulator { if ( debug ) System.out.println("EDGE "+from+" -> "+to+" upon "+getTokenName(t)); if ( from==null || t < -1 || to == null ) return; to = addDFAState(dfa, to); // used existing if possible not incoming - if ( from.edges==null ) { - from.edges = new DFAState[atn.maxTokenType+1+1]; // TODO: make adaptive - } synchronized (dfa) { + if ( from.edges==null ) { + from.edges = new DFAState[atn.maxTokenType+1+1]; // TODO: make adaptive + } from.edges[t+1] = to; // connect } if ( debug ) System.out.println("DFA=\n"+dfa.toString(parser!=null?parser.getTokenNames():null)); diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/PredictionContext.java b/runtime/Java/src/org/antlr/v4/runtime/atn/PredictionContext.java index 755316363..d71a03b16 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/PredictionContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/PredictionContext.java @@ -416,10 +416,12 @@ public abstract class PredictionContext implements Iterable