Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 16c0ed2

Browse files
committed
Merge in 'release/3.1' changes
2 parents ffb1cfb + 56737cd commit 16c0ed2

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,9 +1142,10 @@ internal bool HasInvariantCultureName
11421142
{
11431143
Debug.Assert(name != null && (lcid != -1 || altName != null));
11441144
bool ret;
1145+
string key = lcid == 0 ? name! : name! + '\xfffd' + altName!;
11451146
lock (_lock)
11461147
{
1147-
ret = tempNameHT.TryGetValue(lcid == 0 ? name! : name! + '\xfffd' + altName!, out retval);
1148+
ret = tempNameHT.TryGetValue(key, out retval);
11481149
}
11491150

11501151
if (ret && retval != null)
@@ -1211,10 +1212,11 @@ internal bool HasInvariantCultureName
12111212

12121213
if (lcid == -1)
12131214
{
1215+
string key = name + '\xfffd' + altName;
12141216
lock (_lock)
12151217
{
12161218
// This new culture will be added only to the name hash table.
1217-
tempNameHT[name + '\xfffd' + altName] = retval;
1219+
tempNameHT[key] = retval;
12181220
}
12191221
// when lcid == -1 then TextInfo object is already get created and we need to set it as read only.
12201222
retval.TextInfo.SetReadOnlyState(true);

src/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,48 @@ internal MemberInfoCache(RuntimeTypeCache runtimeTypeCache)
235235

236236
internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInternal method, CacheType cacheType)
237237
{
238+
// First, see if we've already cached an RuntimeMethodInfo or
239+
// RuntimeConstructorInfo that corresponds to this member. Since another
240+
// thread could be updating the backing store at the same time it's
241+
// possible that the check below will result in a false negative. That's
242+
// ok; we'll handle any concurrency issues in the later call to Insert.
243+
244+
T?[]? allMembersLocal = m_allMembers;
245+
if (allMembersLocal != null)
246+
{
247+
// if not a Method or a Constructor, fall through
248+
if (cacheType == CacheType.Method)
249+
{
250+
foreach (T? candidate in allMembersLocal)
251+
{
252+
if (candidate is null)
253+
{
254+
break; // end of list; stop iteration and fall through to slower path
255+
}
256+
257+
if (candidate is RuntimeMethodInfo candidateRMI && candidateRMI.MethodHandle.Value == method.Value)
258+
{
259+
return candidateRMI; // match!
260+
}
261+
}
262+
}
263+
else if (cacheType == CacheType.Constructor)
264+
{
265+
foreach (T? candidate in allMembersLocal)
266+
{
267+
if (candidate is null)
268+
{
269+
break; // end of list; stop iteration and fall through to slower path
270+
}
271+
272+
if (candidate is RuntimeConstructorInfo candidateRCI && candidateRCI.MethodHandle.Value == method.Value)
273+
{
274+
return candidateRCI; // match!
275+
}
276+
}
277+
}
278+
}
279+
238280
T[] list = null!;
239281
MethodAttributes methodAttributes = RuntimeMethodHandle.GetAttributes(method);
240282
bool isPublic = (methodAttributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public;
@@ -262,6 +304,29 @@ internal MethodBase AddMethod(RuntimeType declaringType, RuntimeMethodHandleInte
262304

263305
internal FieldInfo AddField(RuntimeFieldHandleInternal field)
264306
{
307+
// First, see if we've already cached an RtFieldInfo that corresponds
308+
// to this field. Since another thread could be updating the backing
309+
// store at the same time it's possible that the check below will
310+
// result in a false negative. That's ok; we'll handle any concurrency
311+
// issues in the later call to Insert.
312+
313+
T?[]? allMembersLocal = m_allMembers;
314+
if (allMembersLocal != null)
315+
{
316+
foreach (T? candidate in allMembersLocal)
317+
{
318+
if (candidate is null)
319+
{
320+
break; // end of list; stop iteration and fall through to slower path
321+
}
322+
323+
if (candidate is RtFieldInfo candidateRtFI && candidateRtFI.GetFieldHandle() == field.Value)
324+
{
325+
return candidateRtFI; // match!
326+
}
327+
}
328+
}
329+
265330
// create the runtime field info
266331
FieldAttributes fieldAttributes = RuntimeFieldHandle.GetAttributes(field);
267332
bool isPublic = (fieldAttributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public;
@@ -506,7 +571,7 @@ private void MergeWithGlobalList(T[] list)
506571
}
507572

508573
Debug.Assert(cachedMembers![freeSlotIndex] == null);
509-
cachedMembers[freeSlotIndex] = newMemberInfo;
574+
Volatile.Write(ref cachedMembers[freeSlotIndex], newMemberInfo); // value may be read outside of lock
510575
freeSlotIndex++;
511576
}
512577
}

0 commit comments

Comments
 (0)