From 979bd13725b0f7887c40ce8cb84c8d4eb1f37d56 Mon Sep 17 00:00:00 2001 From: dingxin-tech <453127511@qq.com> Date: Tue, 3 Jun 2025 14:10:07 +0800 Subject: [PATCH] perf(runtime): Optimize thread safety and performance for DFA state management Signed-off-by: dingxin-tech <453127511@qq.com> --- .../v4/runtime/atn/LexerATNSimulator.java | 19 ++++++------- .../v4/runtime/atn/ParserATNSimulator.java | 28 +++++++++---------- .../src/org/antlr/v4/runtime/dfa/DFA.java | 4 +-- 3 files changed, 24 insertions(+), 27 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 254e17839b..219ffe6f71 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java @@ -687,18 +687,17 @@ protected DFAState addDFAState(ATNConfigSet configs) { } DFA dfa = decisionToDFA[mode]; - synchronized (dfa.states) { - DFAState existing = dfa.states.get(proposed); - if ( existing!=null ) return existing; - DFAState newState = proposed; + DFAState existing = dfa.states.get(proposed); + if ( existing!=null ) return existing; - newState.stateNumber = dfa.states.size(); - configs.setReadonly(true); - newState.configs = configs; - dfa.states.put(newState, newState); - return newState; - } + DFAState newState = proposed; + + newState.stateNumber = dfa.states.size(); + configs.setReadonly(true); + newState.configs = configs; + dfa.states.put(newState, newState); + return newState; } 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 80b08993fa..7dd7430796 100755 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNSimulator.java @@ -2101,26 +2101,24 @@ protected DFAState addDFAState(DFA dfa, DFAState D) { return D; } - synchronized (dfa.states) { - DFAState existing = dfa.states.get(D); + DFAState existing = dfa.states.get(D); - if ( existing!=null ) { - if ( trace_atn_sim ) System.out.println("addDFAState " + D + " exists"); - return existing; - } + if ( existing!=null ) { + if ( trace_atn_sim ) System.out.println("addDFAState " + D + " exists"); + return existing; + } - D.stateNumber = dfa.states.size(); + D.stateNumber = dfa.states.size(); - if (!D.configs.isReadonly()) { - D.configs.optimizeConfigs(this); - D.configs.setReadonly(true); - } + if (!D.configs.isReadonly()) { + D.configs.optimizeConfigs(this); + D.configs.setReadonly(true); + } - if ( trace_atn_sim ) System.out.println("addDFAState new "+D); + if ( trace_atn_sim ) System.out.println("addDFAState new "+D); - dfa.states.put(D, D); - return D; - } + dfa.states.put(D, D); + return D; } protected void reportAttemptingFullContext(DFA dfa, BitSet conflictingAlts, ATNConfigSet configs, int startIndex, int stopIndex) { diff --git a/runtime/Java/src/org/antlr/v4/runtime/dfa/DFA.java b/runtime/Java/src/org/antlr/v4/runtime/dfa/DFA.java index 3c91daba8c..b1d7565b6f 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/dfa/DFA.java +++ b/runtime/Java/src/org/antlr/v4/runtime/dfa/DFA.java @@ -16,17 +16,17 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; public class DFA { /** A set of all DFA states. Use {@link Map} so we can get old state back * ({@link Set} only allows you to see if it's there). */ - public final Map states = new HashMap(); + public final Map states = new ConcurrentHashMap<>(); public volatile DFAState s0;