summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clr.coreclr.props1
-rw-r--r--clr.defines.targets1
-rw-r--r--clrdefinitions.cmake1
-rw-r--r--src/System.Private.CoreLib/ILLinkTrim.xml5
-rw-r--r--src/System.Private.CoreLib/src/System/GC.cs6
-rw-r--r--src/gc/gc.cpp22
-rw-r--r--src/gc/gc.h7
-rw-r--r--src/gc/gcee.cpp16
-rw-r--r--src/gc/gcimpl.h4
-rw-r--r--src/gc/gcinterface.h3
-rw-r--r--src/vm/comutilnative.cpp58
-rw-r--r--src/vm/comutilnative.h8
-rw-r--r--src/vm/ecalllist.h6
13 files changed, 110 insertions, 28 deletions
diff --git a/clr.coreclr.props b/clr.coreclr.props
index e935fee171..e389a27abc 100644
--- a/clr.coreclr.props
+++ b/clr.coreclr.props
@@ -8,6 +8,7 @@
<FeatureManagedEtw>true</FeatureManagedEtw>
<FeaturePerfTracing>true</FeaturePerfTracing>
<FeatureTypeEquivalence>true</FeatureTypeEquivalence>
+ <FeatureBasicFreeze>true</FeatureBasicFreeze>
<ProfilingSupportedBuild>true</ProfilingSupportedBuild>
</PropertyGroup>
diff --git a/clr.defines.targets b/clr.defines.targets
index 7a81fd8a54..5b48844caa 100644
--- a/clr.defines.targets
+++ b/clr.defines.targets
@@ -24,6 +24,7 @@
<DefineConstants Condition="'$(FeatureWin32Registry)' == 'true'">$(DefineConstants);FEATURE_WIN32_REGISTRY</DefineConstants>
<DefineConstants Condition="'$(FeatureDefaultInterfaces)' == 'true'">$(DefineConstants);FEATURE_DEFAULT_INTERFACES</DefineConstants>
<DefineConstants Condition="'$(FeatureTypeEquivalence)' == 'true'">$(DefineConstants);FEATURE_TYPEEQUIVALENCE</DefineConstants>
+ <DefineConstants Condition="'$(FeatureBasicFreeze)' == 'true'">$(DefineConstants);FEATURE_BASICFREEZE</DefineConstants>
<DefineConstants Condition="'$(ProfilingSupportedBuild)' == 'true'">$(DefineConstants);PROFILING_SUPPORTED</DefineConstants>
<DefineConstants Condition="'$(FeatureProfAttach)' == 'true'">$(DefineConstants);FEATURE_PROFAPI_ATTACH_DETACH</DefineConstants>
diff --git a/clrdefinitions.cmake b/clrdefinitions.cmake
index 23c297c45d..796261e9b2 100644
--- a/clrdefinitions.cmake
+++ b/clrdefinitions.cmake
@@ -111,6 +111,7 @@ if(WIN32)
add_definitions(-DFEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION)
endif(WIN32)
+add_definitions(-DFEATURE_BASICFREEZE)
add_definitions(-DFEATURE_CORECLR)
add_definitions(-DFEATURE_CORESYSTEM)
add_definitions(-DFEATURE_CORRUPTING_EXCEPTIONS)
diff --git a/src/System.Private.CoreLib/ILLinkTrim.xml b/src/System.Private.CoreLib/ILLinkTrim.xml
index 77f6e749b4..e334c3703e 100644
--- a/src/System.Private.CoreLib/ILLinkTrim.xml
+++ b/src/System.Private.CoreLib/ILLinkTrim.xml
@@ -5,6 +5,11 @@
instantiations to save in the ngen image. -->
<method name="CommonlyUsedWinRTRedirectedInterfaceStubs" />
</type>
+ <type fullname="System.GC">
+ <!-- Methods are used to register and unregister frozen segments. They are private and experimental. -->
+ <method name="_RegisterFrozenSegment" />
+ <method name="_UnregisterFrozenSegment" />
+ </type>
<!-- Properties and methods used by a debugger. -->
<type fullname="System.Threading.Tasks.Task">
<property name="ParentForDebugger" />
diff --git a/src/System.Private.CoreLib/src/System/GC.cs b/src/System.Private.CoreLib/src/System/GC.cs
index 1e0268e905..98266b3349 100644
--- a/src/System.Private.CoreLib/src/System/GC.cs
+++ b/src/System.Private.CoreLib/src/System/GC.cs
@@ -319,6 +319,12 @@ namespace System
return newSize;
}
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ private static extern IntPtr _RegisterFrozenSegment(IntPtr sectionAddress, int sectionSize);
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ private static extern IntPtr _UnregisterFrozenSegment(IntPtr segmentHandle);
+
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern long _GetAllocatedBytesForCurrentThread();
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index d7f8d6dfe5..d5a18b1785 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -23957,8 +23957,12 @@ uint8_t* tree_search (uint8_t* tree, uint8_t* old_address)
bool gc_heap::frozen_object_p (Object* obj)
{
#ifdef MULTIPLE_HEAPS
+#ifdef SEG_MAPPING_TABLE
+ heap_segment* pSegment = seg_mapping_table_segment_of((uint8_t*)obj);
+#else
ptrdiff_t delta = 0;
heap_segment* pSegment = segment_of ((uint8_t*)obj, delta);
+#endif
#else //MULTIPLE_HEAPS
heap_segment* pSegment = gc_heap::find_segment ((uint8_t*)obj, FALSE);
_ASSERTE(pSegment);
@@ -34523,24 +34527,6 @@ Object * GCHeap::NextObj (Object * object)
#endif // VERIFY_HEAP
}
-#ifdef VERIFY_HEAP
-
-#ifdef FEATURE_BASICFREEZE
-BOOL GCHeap::IsInFrozenSegment (Object * object)
-{
- uint8_t* o = (uint8_t*)object;
- heap_segment * hs = gc_heap::find_segment (o, FALSE);
- //We create a frozen object for each frozen segment before the segment is inserted
- //to segment list; during ngen, we could also create frozen objects in segments which
- //don't belong to current GC heap.
- //So we return true if hs is NULL. It might create a hole about detecting invalidate
- //object. But given all other checks present, the hole should be very small
- return !hs || heap_segment_read_only_p (hs);
-}
-#endif //FEATURE_BASICFREEZE
-
-#endif //VERIFY_HEAP
-
// returns TRUE if the pointer is in one of the GC heaps.
bool GCHeap::IsHeapPointer (void* vpObject, bool small_heap_only)
{
diff --git a/src/gc/gc.h b/src/gc/gc.h
index 7d63d4bc3a..225aa6ba58 100644
--- a/src/gc/gc.h
+++ b/src/gc/gc.h
@@ -264,13 +264,6 @@ public:
{
return mt->GetBaseSize() >= LARGE_OBJECT_SIZE;
}
-
-protected:
-public:
-#if defined(FEATURE_BASICFREEZE) && defined(VERIFY_HEAP)
- // Return TRUE if object lives in frozen segment
- virtual BOOL IsInFrozenSegment (Object * object) = 0;
-#endif // defined(FEATURE_BASICFREEZE) && defined(VERIFY_HEAP)
};
// Go through and touch (read) each page straddled by a memory block.
diff --git a/src/gc/gcee.cpp b/src/gc/gcee.cpp
index bd5a8f6154..68310d5b6c 100644
--- a/src/gc/gcee.cpp
+++ b/src/gc/gcee.cpp
@@ -600,6 +600,22 @@ void GCHeap::UnregisterFrozenSegment(segment_handle seg)
#endif // FEATURE_BASICFREEZE
}
+bool GCHeap::IsInFrozenSegment(Object *object)
+{
+#ifdef FEATURE_BASICFREEZE
+ uint8_t* o = (uint8_t*)object;
+ heap_segment * hs = gc_heap::find_segment (o, FALSE);
+ //We create a frozen object for each frozen segment before the segment is inserted
+ //to segment list; during ngen, we could also create frozen objects in segments which
+ //don't belong to current GC heap.
+ //So we return true if hs is NULL. It might create a hole about detecting invalidate
+ //object. But given all other checks present, the hole should be very small
+ return !hs || heap_segment_read_only_p (hs);
+#else // FEATURE_BASICFREEZE
+ return false;
+#endif
+}
+
bool GCHeap::RuntimeStructuresValid()
{
return GCScan::GetGcRuntimeStructuresValid();
diff --git a/src/gc/gcimpl.h b/src/gc/gcimpl.h
index e70555da6f..dffe2f17aa 100644
--- a/src/gc/gcimpl.h
+++ b/src/gc/gcimpl.h
@@ -236,6 +236,7 @@ public: // FIX
// frozen segment management functions
virtual segment_handle RegisterFrozenSegment(segment_info *pseginfo);
virtual void UnregisterFrozenSegment(segment_handle seg);
+ virtual bool IsInFrozenSegment(Object *object);
// Event control functions
void ControlEvents(GCEventKeyword keyword, GCEventLevel level);
@@ -303,9 +304,6 @@ protected:
public:
Object * NextObj (Object * object);
-#if defined (FEATURE_BASICFREEZE) && defined (VERIFY_HEAP)
- BOOL IsInFrozenSegment (Object * object);
-#endif // defined (FEATURE_BASICFREEZE) && defined (VERIFY_HEAP)
};
#endif // GCIMPL_H_
diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h
index 3814702763..249466aee4 100644
--- a/src/gc/gcinterface.h
+++ b/src/gc/gcinterface.h
@@ -868,6 +868,9 @@ public:
// Unregisters a frozen segment.
virtual void UnregisterFrozenSegment(segment_handle seg) = 0;
+ // Indicates whether an object is in a frozen segment.
+ virtual bool IsInFrozenSegment(Object *object) = 0;
+
/*
===========================================================================
Routines for informing the GC about which events are enabled.
diff --git a/src/vm/comutilnative.cpp b/src/vm/comutilnative.cpp
index 3ba0acefb9..aa2ed02a40 100644
--- a/src/vm/comutilnative.cpp
+++ b/src/vm/comutilnative.cpp
@@ -1238,6 +1238,64 @@ FCIMPL0(INT64, GCInterface::GetAllocatedBytesForCurrentThread)
}
FCIMPLEND
+#ifdef FEATURE_BASICFREEZE
+
+/*===============================RegisterFrozenSegment===============================
+**Action: Registers the frozen segment
+**Returns: segment_handle
+**Arguments: args-> pointer to section, size of section
+**Exceptions: None
+==============================================================================*/
+void* QCALLTYPE GCInterface::RegisterFrozenSegment(void* pSection, INT32 sizeSection)
+{
+ QCALL_CONTRACT;
+
+ void* retVal = nullptr;
+
+ BEGIN_QCALL;
+
+ _ASSERTE(pSection != nullptr);
+ _ASSERTE(sizeSection > 0);
+
+ GCX_COOP();
+
+ segment_info seginfo;
+ seginfo.pvMem = pSection;
+ seginfo.ibFirstObject = sizeof(ObjHeader);
+ seginfo.ibAllocated = sizeSection;
+ seginfo.ibCommit = seginfo.ibAllocated;
+ seginfo.ibReserved = seginfo.ibAllocated;
+
+ retVal = (void*)GCHeapUtilities::GetGCHeap()->RegisterFrozenSegment(&seginfo);
+
+ END_QCALL;
+
+ return retVal;
+}
+
+/*===============================UnregisterFrozenSegment===============================
+**Action: Unregisters the frozen segment
+**Returns: void
+**Arguments: args-> segment handle
+**Exceptions: None
+==============================================================================*/
+void QCALLTYPE GCInterface::UnregisterFrozenSegment(void* segment)
+{
+ QCALL_CONTRACT;
+
+ BEGIN_QCALL;
+
+ _ASSERTE(segment != nullptr);
+
+ GCX_COOP();
+
+ GCHeapUtilities::GetGCHeap()->UnregisterFrozenSegment((segment_handle)segment);
+
+ END_QCALL;
+}
+
+#endif // FEATURE_BASICFREEZE
+
/*==============================SuppressFinalize================================
**Action: Indicate that an object's finalizer should not be run by the system
**Arguments: Object of interest
diff --git a/src/vm/comutilnative.h b/src/vm/comutilnative.h
index e632acfb97..67c111bbb4 100644
--- a/src/vm/comutilnative.h
+++ b/src/vm/comutilnative.h
@@ -140,6 +140,14 @@ public:
static FCDECL0(INT64, GetAllocatedBytesForCurrentThread);
+#ifdef FEATURE_BASICFREEZE
+ static
+ void* QCALLTYPE RegisterFrozenSegment(void *pSection, INT32 sizeSection);
+
+ static
+ void QCALLTYPE UnregisterFrozenSegment(void *segmentHandle);
+#endif // FEATURE_BASICFREEZE
+
static
int QCALLTYPE StartNoGCRegion(INT64 totalSize, BOOL lohSizeKnown, INT64 lohSize, BOOL disallowFullBlockingGC);
diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h
index 7e1dc6954b..cc07d0e570 100644
--- a/src/vm/ecalllist.h
+++ b/src/vm/ecalllist.h
@@ -771,6 +771,12 @@ FCFuncStart(gGCInterfaceFuncs)
FCFuncElement("_ReRegisterForFinalize", GCInterface::ReRegisterForFinalize)
FCFuncElement("_GetAllocatedBytesForCurrentThread", GCInterface::GetAllocatedBytesForCurrentThread)
+
+#ifdef FEATURE_BASICFREEZE
+ QCFuncElement("_RegisterFrozenSegment", GCInterface::RegisterFrozenSegment)
+ QCFuncElement("_UnregisterFrozenSegment", GCInterface::UnregisterFrozenSegment)
+#endif // FEATURE_BASICFREEZE
+
FCFuncEnd()
FCFuncStart(gGCSettingsFuncs)