-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[Local GC] Move Software Write Watch's write barrier updates to GCToEEInterface::StompWriteBarrier #8605
Conversation
@dotnet-bot test OSX Release longgc |
@dotnet-bot test Windows_NT Release standalone_gc |
@dotnet-bot test Windows_NT Release standalone_gc |
assert(address != nullptr); | ||
|
||
// The implementation is limited to writes of a pointer size or less. Writes of | ||
// a pointer or larger may cross page boundaries and would require us to potentially |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Writes of a pointer or larger" should be "Writes larger than pointer size" right (since it's <=
)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're right, that's what I meant to say - thanks.
I didn't get a chance to review the last PR on this issue so this is a comment on your last PR, can we use ephemeral_low and ephemeral_high like we do in GC instead of ephemeral_lo and ephemeral_hi? Refers to: src/gc/gcinterface.h:90 in df94473. [](commit_id = df94473, deletion_comment = False) |
@Maoni0 I tried, but |
assert(write_size <= sizeof(void*)); | ||
|
||
size_t table_byte_index = reinterpret_cast<size_t>(address) >> SOFTWARE_WRITE_WATCH_AddressToTableByteIndexShift; | ||
assert(table_byte_index != 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assert(table_byte_index != 0); [](start = 8, length = 30)
is there any reason to replace the original assert assert(GetTableByteIndex(reinterpret_cast<uint8_t *>(address) + (writeByteSize - 1)) == tableByteIndex); with this one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
none in particular, I'll bring it over
@swgillespie ahh, right there's the macro. can we name them gc_ephemeral_low/high? |
@Maoni0 will do! the macros, or the fields of |
@swgillespie I looked at this a bit more - we really should get rid of #define ephemeral_* g_ephemeral_* to do a proper separation because you are already passing ephemeral_low/high as fields in the fields of WriteBarrierParameters. g_ephemeral_low/high are only used on the VM side - GC only uses its own, ie, ephemeral_low/high (it only looks at the g_* version in verify_heap). can you try to just get rid of the macros and see if you can compile? if you are getting a lot of errors you can just rename ephemeral_* to gc_ephemeral* in WriteBarrierParameters and the places these fields are used and be done with this PR. I can help you make the proper change after I get back. |
@@ -94,7 +94,7 @@ inline void ErectWriteBarrier(Object ** dst, Object * ref) | |||
if (((uint8_t*)dst < g_gc_lowest_address) || ((uint8_t*)dst >= g_gc_highest_address)) | |||
return; | |||
|
|||
if((uint8_t*)ref >= g_gc_ephemeral_low && (uint8_t*)ref < g_gc_ephemeral_high) | |||
//if((uint8_t*)ref >= g_gc_ephemeral_low && (uint8_t*)ref < g_gc_ephemeral_high) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll clean this up before check-in - removing g_gc_ephemeral_* broke the sample here.
@dotnet-bot test OSX Release longgc |
GCToEEInterface::StompWriteBarrier to stomp the EE's write barrier.
f55b6d2
to
3952b64
Compare
I just squashed all of my commits - this PR should be ready to merge as long as there aren't any objections. |
Post-holiday ping - if there aren't any objections I'm hoping to get this merged soon and do a CoreRT GC refresh. |
|
||
g_sw_ww_enabled_for_gc_heap = true; | ||
SwitchToWriteWatchBarrier(true); | ||
WriteBarrierParameters args = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a nit - you could use the new syntax for structure initialization. It looks little nicer to me.
WriteBarrierParameters args = {
.operation = WriteBarrierOp::SwitchToWriteWatch,
.write_watch_table = g_gc_sw_ww_table,
.is_runtime_suspended = true
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice! will do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this standard C++? MSVC rejects it and GCC issues a warning in pedantic mode that C99-style initializers like this aren't permitted in C++.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not bother with this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am sorry, I did not know that this is really a C99 feature and not a C++ feature. So please ignore my comment.
I'll look again this afternnon |
// | ||
// For Server GC, where there are multiple ephemeral regions, we must always touch the card table. | ||
#ifndef MULTIPLE_HEAPS | ||
if ( (((uint8_t*)*rover) >= gc_heap::ephemeral_low) && (((uint8_t*)*rover) < gc_heap::ephemeral_high) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if ( (((uint8_t*)rover) >= gc_heap::ephemeral_low) && (((uint8_t)*rover) < gc_heap::ephemeral_high) ) [](start = 8, length = 103)
this should not be changed - this function shouldn't know about gc_heap::ephemeral_low/high - it should use g_gc_* version as it's an external function to GC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree - it may be best to move this to the EE side, and remove it from the GC/EE interface. It is on the EE side in CoreRT already: https://github.com/dotnet/corert/search?utf8=%E2%9C%93&q=InlinedBulkWriteBarrier
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, will do!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep that would be best.
I would just call this only in workstation GC case and get rid of the code for server GC in it. actually it's better to just update the g_gc_ephemeral_* in there instead of in this method so it's clear that the ephemral range only matters in wks case. Refers to: src/gc/gc.cpp:9680 in 3952b64. [](commit_id = 3952b64, deletion_comment = False) |
that was all my comments. sorry some of them didn't display correctly on GH... |
I ended up removing I figure there are two solutions:
Either one is fine with me, does anyone have any thoughts or opinions? I suppose after thinking about it more I'm more inclined to go with the first. |
Ideally, we should be eliminating places where EE does explicitly things differently for Server GC. The GC should set g_ephemeral_low/g_ephemeral_high to 1 and ~0 (or they should be set to this value by default). The EE should look at the current values of g_ephemeral_low/g_ephemeral_high, and if they are the boundary values, skip the ephemeral checks in the optimized write barrier. |
Okay, will do! |
Ubuntu leg hit #6574. @dotnet-bot test Ubuntu x64 Checked |
@dotnet-bot test Ubuntu x64 Checked Build and Test |
thanks! |
…EInterface::StompWriteBarrier (dotnet/coreclr#8605) * Move Software Write Watch's write barrier updates to use the new GCToEEInterface::StompWriteBarrier to stomp the EE's write barrier. * Address code review feedback, move SetCardsAfterBulkCopy to EE side of the interface Commit migrated from dotnet/coreclr@c10c1ff
This PR completes https://github.com/dotnet/coreclr/issues/8359 by removing the shared globals used by the write barrier and
softwarewritewatch.cpp
, which lies on the GC side of the GC-EE interface. The two shared globals areg_sw_ww_table
, the table used by the write barrier for software write watch, andg_sw_ww_enabled_for_gc_heap
, whether or not the GC has requested that write watch be active. In the same vein as what was done in #8568, the EE and GC share copies of these two global variables, which are synchronized inGCToEEInterface::StompWriteBarrier
. The GC callsSoftwareWriteWatch::EnableForGCHeap
when it wants to track writes to the heap, andSoftwareWriteWatch::DisableForGCHeap
when it is done - both calls end up callingGCToEEInterface::StompWriteBarrier
and may bash the write barrier to a version that records writes to the heap using the software write watch table.This PR also removes all inclusions of
softwarewritewatch.h
from within the EE.