Skip to content
This repository has been archived by the owner on Nov 1, 2020. It is now read-only.

Commit

Permalink
ARM64: FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP (#8331)
Browse files Browse the repository at this point in the history
Implements the missing parts of the software write watch system. Activates and deactivates the tracking based on the GC state. Code is based on the same function in the runime

Generates an compiler error if FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP is enabled for anything else than ARM64 UNIX as all other assembler helpers are not updated to support it.
  • Loading branch information
RalfKornmannEnvision authored Sep 15, 2020
1 parent a7ff563 commit 27fb761
Showing 1 changed file with 34 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/Native/Runtime/gcrhenv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,10 @@ void GCToEEInterface::DiagWalkBGCSurvivors(void* gcContext)
#endif // FEATURE_EVENT_TRACE
}

#if defined(FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP) && (!defined(TARGET_ARM64) || !defined(TARGET_UNIX))
#error FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP is only implemented for ARM64 and UNIX
#endif

void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
{
// CoreRT doesn't patch the write barrier like CoreCLR does, but it
Expand Down Expand Up @@ -1198,6 +1202,14 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
g_card_bundle_table = args->card_bundle_table;
#endif

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
if (g_sw_ww_enabled_for_gc_heap && (args->write_watch_table != nullptr))
{
assert(args->is_runtime_suspended);
g_write_watch_table = args->write_watch_table;
}
#endif // FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP

// IMPORTANT: managed heap segments may surround unmanaged/stack segments. In such cases adding another managed
// heap segment may put a stack/unmanaged write inside the new heap range. However the old card table would
// not cover it. Therefore we must ensure that the write barriers see the new table before seeing the new bounds.
Expand Down Expand Up @@ -1251,14 +1263,35 @@ void GCToEEInterface::StompWriteBarrier(WriteBarrierParameters* args)
g_card_bundle_table = args->card_bundle_table;
#endif

#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
assert(g_write_watch_table == nullptr);
g_write_watch_table = args->write_watch_table;
#endif

g_lowest_address = args->lowest_address;
g_highest_address = args->highest_address;
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->is_runtime_suspended && "the runtime must be suspended here!");
assert(args->write_watch_table != nullptr);
g_write_watch_table = args->write_watch_table;
g_sw_ww_enabled_for_gc_heap = 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
break;

case WriteBarrierOp::SwitchToNonWriteWatch:
assert(!"CoreRT does not have an implementation of non-OS WriteWatch");
#ifdef FEATURE_USE_SOFTWARE_WRITE_WATCH_FOR_GC_HEAP
assert(args->is_runtime_suspended && "the runtime must be suspended here!");
g_write_watch_table = nullptr;
g_sw_ww_enabled_for_gc_heap = false;
#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(!"Unknokwn WriteBarrierOp enum");
Expand Down

0 comments on commit 27fb761

Please sign in to comment.