// lock the global string literal interning map
CrstHolder gch(pStringLiteralMap->GetHashTableCrstGlobal());
- StringLiteralEntryHolder pEntry(pStringLiteralMap->GetInternedString(pProtectedStringRef, dwHash,
- /* bAddIfNotFound */ TRUE, /* bPreferFrozenObjectHeap */ FALSE));
+ StringLiteralEntryHolder pEntry(pStringLiteralMap->GetInternedString(pProtectedStringRef, dwHash, /* bAddIfNotFound */ TRUE));
DynamicStringLiteral* pStringLiteral = (DynamicStringLiteral*)m_jitTempData.New(sizeof(DynamicStringLiteral));
pStringLiteral->m_pEntry = pEntry.Extract();
// Retrieve the string literal from the global string literal map.
- // Don't use FOH for collectible modules to avoid potential memory leaks
- const bool preferFrozenObjectHeap = !bIsCollectible;
- StringLiteralEntryHolder pEntry(SystemDomain::GetGlobalStringLiteralMap()->GetInternedString(pString, dwHash, bAddIfNotFound, preferFrozenObjectHeap));
+ StringLiteralEntryHolder pEntry(SystemDomain::GetGlobalStringLiteralMap()->GetInternedString(pString, dwHash, bAddIfNotFound));
_ASSERTE(pEntry || !bAddIfNotFound);
return pEntry;
}
-StringLiteralEntry *GlobalStringLiteralMap::GetInternedString(STRINGREF *pString, DWORD dwHash, BOOL bAddIfNotFound, BOOL bPreferFrozenObjectHeap)
+StringLiteralEntry *GlobalStringLiteralMap::GetInternedString(STRINGREF *pString, DWORD dwHash, BOOL bAddIfNotFound)
{
CONTRACTL
{
else
{
if (bAddIfNotFound)
- pEntry = AddInternedString(pString, bPreferFrozenObjectHeap);
+ pEntry = AddInternedString(pString);
}
return pEntry;
return pRet;
}
-StringLiteralEntry *GlobalStringLiteralMap::AddInternedString(STRINGREF *pString, bool preferFrozenObjHeap)
+StringLiteralEntry *GlobalStringLiteralMap::AddInternedString(STRINGREF *pString)
{
CONTRACTL
}
CONTRACTL_END;
- EEStringData StringData = EEStringData((*pString)->GetStringLength(), (*pString)->GetBuffer());
- return AddStringLiteral(&StringData, preferFrozenObjHeap);
+ StringLiteralEntry* pRet;
+
+ {
+ // All frozen strings are expected to be registered in m_StringToEntryHashTable, we might relax this assert
+ // in future if we start allocating frozen strings for non-literals
+ _ASSERT(!GCHeapUtilities::GetGCHeap()->IsInFrozenSegment(STRINGREFToObject(*pString)));
+
+ PinnedHeapHandleBlockHolder pStrObj(&m_PinnedHeapHandleTable, 1);
+ SetObjectReference(pStrObj[0], (OBJECTREF)*pString);
+
+ // Since the allocation might have caused a GC we need to get the string data after it
+ EEStringData StringData = EEStringData((*pString)->GetStringLength(), (*pString)->GetBuffer());
+
+ StringLiteralEntryHolder pEntry(StringLiteralEntry::AllocateEntry(&StringData, (STRINGREF*)pStrObj[0]));
+ pStrObj.SuppressRelease();
+
+ // Insert the handle to the string into the hash table.
+ m_StringToEntryHashTable->InsertValue(&StringData, (LPVOID)pEntry, FALSE);
+ pEntry.SuppressRelease();
+ pRet = pEntry;
+ }
+
+ return pRet;
}
void GlobalStringLiteralMap::RemoveStringLiteralEntry(StringLiteralEntry *pEntry)
StringLiteralEntry *GetStringLiteral(EEStringData *pStringData, DWORD dwHash, BOOL bAddIfNotFound, BOOL bPreferFrozenObjectHeap);
// Method to explicitly intern a string object. Takes a precomputed hash (for perf).
- StringLiteralEntry *GetInternedString(STRINGREF *pString, DWORD dwHash, BOOL bAddIfNotFound, BOOL bPreferFrozenObjectHeap);
+ StringLiteralEntry *GetInternedString(STRINGREF *pString, DWORD dwHash, BOOL bAddIfNotFound);
// Method to calculate the hash
DWORD GetHash(EEStringData* pData)
StringLiteralEntry *AddStringLiteral(EEStringData *pStringData, bool preferFrozenObjHeap);
// Helper method to add an interned string.
- StringLiteralEntry *AddInternedString(STRINGREF *pString, bool preferFrozenObjHeap);
+ StringLiteralEntry *AddInternedString(STRINGREF *pString);
// Called by StringLiteralEntry when its RefCount falls to 0.
void RemoveStringLiteralEntry(StringLiteralEntry *pEntry);