summaryrefslogtreecommitdiff
path: root/src/vm/gcenv.ee.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm/gcenv.ee.cpp')
-rw-r--r--src/vm/gcenv.ee.cpp60
1 files changed, 54 insertions, 6 deletions
diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp
index 3be8384b3d..61d06421ad 100644
--- a/src/vm/gcenv.ee.cpp
+++ b/src/vm/gcenv.ee.cpp
@@ -204,6 +204,7 @@ bool FindFirstInterruptiblePointStateCB(
// the end is exclusive). Return -1 if no such point exists.
unsigned FindFirstInterruptiblePoint(CrawlFrame* pCF, unsigned offs, unsigned endOffs)
{
+#ifdef USE_GC_INFO_DECODER
GCInfoToken gcInfoToken = pCF->GetGCInfoToken();
GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_FOR_RANGES_CALLBACK);
@@ -215,6 +216,10 @@ unsigned FindFirstInterruptiblePoint(CrawlFrame* pCF, unsigned offs, unsigned en
gcInfoDecoder.EnumerateInterruptibleRanges(&FindFirstInterruptiblePointStateCB, &state);
return state.returnOffs;
+#else
+ PORTABILITY_ASSERT("FindFirstInterruptiblePoint");
+ return -1;
+#endif // USE_GC_INFO_DECODER
}
#endif // WIN64EXCEPTIONS
@@ -283,7 +288,7 @@ StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData)
#endif // _DEBUG
DWORD relOffsetOverride = NO_OVERRIDE_OFFSET;
-#if defined(WIN64EXCEPTIONS)
+#if defined(WIN64EXCEPTIONS) && defined(USE_GC_INFO_DECODER)
if (pCF->ShouldParentToFuncletUseUnwindTargetLocationForGCReporting())
{
GCInfoToken gcInfoToken = pCF->GetGCInfoToken();
@@ -313,7 +318,7 @@ StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData)
}
}
-#endif // WIN64EXCEPTIONS
+#endif // WIN64EXCEPTIONS && USE_GC_INFO_DECODER
pCM->EnumGcRefs(pCF->GetRegisterSet(),
pCF->GetCodeInfo(),
@@ -1226,6 +1231,14 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->lowest_address != nullptr);
assert(args->highest_address != nullptr);
g_card_table = args->card_table;
+#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+ if (args->write_watch_table != nullptr)
+ {
+ assert(args->is_runtime_suspended);
+ g_sw_ww_table = args->write_watch_table;
+ }
+#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+
::StompWriteBarrierResize(args->is_runtime_suspended, args->requires_upper_bounds_check);
// We need to make sure that other threads executing checked write barriers
@@ -1241,10 +1254,10 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
return;
case WriteBarrierOp::StompEphemeral:
// StompEphemeral requires a new ephemeral low and a new ephemeral high
- assert(args->ephemeral_lo != nullptr);
- assert(args->ephemeral_hi != nullptr);
- g_ephemeral_low = args->ephemeral_lo;
- g_ephemeral_high = args->ephemeral_hi;
+ assert(args->ephemeral_low != nullptr);
+ assert(args->ephemeral_high != nullptr);
+ g_ephemeral_low = args->ephemeral_low;
+ g_ephemeral_high = args->ephemeral_high;
::StompWriteBarrierEphemeral(args->is_runtime_suspended);
return;
case WriteBarrierOp::Initialize:
@@ -1255,6 +1268,8 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
assert(args->card_table != nullptr);
assert(args->lowest_address != nullptr);
assert(args->highest_address != nullptr);
+ assert(args->ephemeral_low != nullptr);
+ assert(args->ephemeral_high != nullptr);
assert(args->is_runtime_suspended && "the runtime must be suspended here!");
assert(!args->requires_upper_bounds_check && "the ephemeral generation must be at the top of the heap!");
@@ -1263,8 +1278,41 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
g_lowest_address = args->lowest_address;
VolatileStore(&g_highest_address, args->highest_address);
::StompWriteBarrierResize(true, false);
+
+ // g_ephemeral_low/high aren't needed for the write barrier stomp, but they
+ // are needed in other places.
+ g_ephemeral_low = args->ephemeral_low;
+ g_ephemeral_high = args->ephemeral_high;
+ return;
+ case WriteBarrierOp::SwitchToWriteWatch:
+#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+ assert(args->write_watch_table != nullptr);
+ assert(args->is_runtime_suspended && "the runtime must be suspended here!");
+ g_sw_ww_table = args->write_watch_table;
+ g_sw_ww_enabled_for_gc_heap = true;
+ ::SwitchToWriteWatchBarrier(true);
+#else
+ assert(!"should never be called without FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP");
+#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+ return;
+ case WriteBarrierOp::SwitchToNonWriteWatch:
+#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
+ assert(args->is_runtime_suspended && "the runtime must be suspended here!");
+ g_sw_ww_enabled_for_gc_heap = false;
+ ::SwitchToNonWriteWatchBarrier(true);
+#else
+ assert(!"should never be called without FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP");
+#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
return;
default:
assert(!"unknown WriteBarrierOp enum");
}
}
+
+void GCToEEInterface::EnableFinalization(bool foundFinalizers)
+{
+ if (foundFinalizers || FinalizerThread::HaveExtraWorkForFinalizer())
+ {
+ FinalizerThread::EnableFinalization();
+ }
+}