[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.
"Writes of a pointer or larger" should be "Writes larger than pointer size" right (since it's <=)?
There was a problem hiding this comment.
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.
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.
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. |
| 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.
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.
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.
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.
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.
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.
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
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::EnableForGCHeapwhen it wants to track writes to the heap, andSoftwareWriteWatch::DisableForGCHeapwhen it is done - both calls end up callingGCToEEInterface::StompWriteBarrierand 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.hfrom within the EE.