mirrored parser ATN sim changes in lexer ATN sim for thread safety. reduced contention for contextCache.

This commit is contained in:
Terence Parr 2012-08-01 18:25:25 -07:00
parent b0b30fec68
commit 754e6eb593
3 changed files with 41 additions and 33 deletions

View File

@ -706,12 +706,15 @@ 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
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
}
}
/** Add a new DFA state if there isn't one with this set of
configurations already. This method also detects the first
@ -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,19 +736,27 @@ 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();
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
public DFA getDFA(int mode) {

View File

@ -283,9 +283,7 @@ public class ParserATNSimulator<Symbol extends Token> 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);
}
Integer predI = s.contextToPredictedAlt.get(predictionCtx);
if ( predI!=null ) {
return predI; // ha! quick exit :)
@ -543,9 +541,7 @@ public class ParserATNSimulator<Symbol extends Token> extends ATNSimulator {
greedy);
// not accept state: isCtxSensitive
PredictionContext predictionCtx = PredictionContext.fromRuleContext(outerContext);
synchronized (sharedContextCache) {
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<Symbol extends Token> 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
synchronized (dfa) {
if ( from.edges==null ) {
from.edges = new DFAState[atn.maxTokenType+1+1]; // TODO: make adaptive
}
synchronized (dfa) {
from.edges[t+1] = to; // connect
}
if ( debug ) System.out.println("DFA=\n"+dfa.toString(parser!=null?parser.getTokenNames():null));

View File

@ -416,11 +416,13 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
return existing;
}
synchronized (contextCache) {
existing = contextCache.get(context);
if (existing != null) {
visited.put(context, existing);
return existing;
}
}
boolean changed = false;
PredictionContext[] parents = new PredictionContext[context.size()];
@ -441,7 +443,9 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
}
if (!changed) {
synchronized (contextCache) {
contextCache.add(context);
}
visited.put(context, context);
return context;
}
@ -458,7 +462,9 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
updated = new ArrayPredictionContext(parents, arrayPredictionContext.invokingStates);
}
synchronized (contextCache) {
contextCache.add(updated);
}
visited.put(updated, updated);
visited.put(context, updated);