88using System . Runtime . CompilerServices ;
99using System . Text . Json . Serialization ;
1010using System . Text . Json . Serialization . Metadata ;
11+ using System . Threading ;
1112
1213namespace System . Text . Json
1314{
@@ -20,8 +21,7 @@ public sealed partial class JsonSerializerOptions
2021 private CachingContext ? _cachingContext ;
2122
2223 // Simple LRU cache for the public (de)serialize entry points that avoid some lookups in _cachingContext.
23- // Although this may be written by multiple threads, 'volatile' was not added since any local affinity is fine.
24- private JsonTypeInfo ? _lastTypeInfo ;
24+ private volatile JsonTypeInfo ? _lastTypeInfo ;
2525
2626 internal JsonTypeInfo GetOrAddJsonTypeInfo ( Type type )
2727 {
@@ -90,10 +90,11 @@ internal sealed class CachingContext
9090 public CachingContext ( JsonSerializerOptions options )
9191 {
9292 Options = options ;
93- _ = Count ;
9493 }
9594
9695 public JsonSerializerOptions Options { get ; }
96+ // Property only accessed by reflection in testing -- do not remove.
97+ // If changing please ensure that src/ILLink.Descriptors.LibraryBuild.xml is up-to-date.
9798 public int Count => _converterCache . Count + _jsonTypeInfoCache . Count ;
9899 public JsonConverter GetOrAddConverter ( Type type ) => _converterCache . GetOrAdd ( type , Options . GetConverterFromType ) ;
99100 public JsonTypeInfo GetOrAddJsonTypeInfo ( Type type ) => _jsonTypeInfoCache . GetOrAdd ( type , Options . GetJsonTypeInfoFromContextOrCreate ) ;
@@ -109,7 +110,7 @@ public void Clear()
109110
110111 /// <summary>
111112 /// Defines a cache of CachingContexts; instead of using a ConditionalWeakTable which can be slow to traverse
112- /// this approach uses a regular dictionary pointing to weak references of <see cref="CachingContext"/>.
113+ /// this approach uses a concurrent dictionary pointing to weak references of <see cref="CachingContext"/>.
113114 /// Relevant caching contexts are looked up using the equality comparison defined by <see cref="EqualityComparer"/>.
114115 /// </summary>
115116 internal static class TrackedCachingContexts
@@ -188,6 +189,8 @@ private static bool TryEvictDanglingEntries()
188189 // across multiple initializations. The backoff count is determined by the eviction
189190 // rates of the most recent runs.
190191
192+ Debug . Assert ( Monitor . IsEntered ( s_cache ) ) ;
193+
191194 if ( s_evictionRunsToSkip > 0 )
192195 {
193196 -- s_evictionRunsToSkip ;
@@ -252,7 +255,7 @@ static int EstimateEvictionRunsToSkip(int latestEvictionCount)
252255 /// If two instances are equivalent, they should generate identical metadata caches;
253256 /// the converse however does not necessarily hold.
254257 /// </summary>
255- private class EqualityComparer : IEqualityComparer < JsonSerializerOptions >
258+ private sealed class EqualityComparer : IEqualityComparer < JsonSerializerOptions >
256259 {
257260 public bool Equals ( JsonSerializerOptions ? left , JsonSerializerOptions ? right )
258261 {
@@ -276,9 +279,9 @@ public bool Equals(JsonSerializerOptions? left, JsonSerializerOptions? right)
276279 left . _propertyNameCaseInsensitive == right . _propertyNameCaseInsensitive &&
277280 left . _writeIndented == right . _writeIndented &&
278281 left . _serializerContext == right . _serializerContext &&
279- CompareConverters ( left . Converters , right . Converters ) ;
282+ CompareConverters ( left . _converters , right . _converters ) ;
280283
281- static bool CompareConverters ( IList < JsonConverter > left , IList < JsonConverter > right )
284+ static bool CompareConverters ( ConverterList left , ConverterList right )
282285 {
283286 int n ;
284287 if ( ( n = left . Count ) != right . Count )
@@ -321,9 +324,9 @@ public int GetHashCode(JsonSerializerOptions options)
321324 hc . Add ( options . _writeIndented ) ;
322325 hc . Add ( options . _serializerContext ) ;
323326
324- foreach ( JsonConverter converter in options . Converters )
327+ for ( int i = 0 ; i < options . _converters . Count ; i ++ )
325328 {
326- hc . Add ( converter ) ;
329+ hc . Add ( options . _converters [ i ] ) ;
327330 }
328331
329332 return hc . ToHashCode ( ) ;
0 commit comments