-
Notifications
You must be signed in to change notification settings - Fork 1.2k
swb: annotate BaseDictionary (partial) #1797
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Please hold on review -- Curtis suggested a better approach. Will update. |
|
@dotnet-bot test Linux tests please |
|
@leirocks @curtisman @digitalinfinity Please CR, thanks! |
| Pointer(int, TAllocator) buckets; | ||
| Pointer(EntryType, TAllocator) entries; | ||
| PointerNoBarrier(AllocatorType) alloc; | ||
| int size; |
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.
For consistency, it's better if we annotate all the fields (so annotate the non-pointer fields with Field)
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.
Yes, will do (paid too much attention to buckets and entries).
| Allocate(&newBuckets, &newEntries, initBucketCount, initSize); | ||
|
|
||
| // Allocation can throw - assign only after allocation has succeeded. | ||
| SetArray<TAllocator>(this->buckets, newBuckets, initBucketCount); |
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.
This is a little counterintuitive- you're setting a field in the dictionary, not the array itself, so you don't need to trigger the write barrier for every element in the array. You could argue that SetArray is getting called here because Allocate was writing to every element in the array but Allocate just does a memset without any pointers so it's probably fine to not trigger the barrier here. So in short- any reason why you can't just do this->buckets = newBuckets here?
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.
The write barrier on elements scenario is hard to understand (I'm still not too clear after asking Lei and Curtis.) this->buckets = newBuckets is fine here, but this->entries = newEntries is not. I was thinking of how we prevent accidental error. In the case of pointer field, the operator= function takes care of all scenarios, be it raw pointer, NoWriteBarrierPtr, or WriteBarrierPtr. So in comparison, I was thinking maybe we require all array assignment through this SetArray function. SetArray determines if we need write barrier or not. Possibly we can track that in clang plugin (not trivial...).
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.
Why is this->entries = newEntries not fine? this->entries and this->buckets are both pointer types- that is, setting them goes through the barrier on the Dictionary instance itself, not on the entries. If you assign this->entries = blah, you don't need to see all the bits corresponding to the range of memory symbolized by the entries array, you need to only set the bit corresponding to the dictionary itself, since that's the memory that has changed. That being said, you'll need to do what SetArray does when you do something like memcpy or set individual elements in the array.
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.
Yes, this->entries = newEntries is fine when newEntries already takes care of write barrier on the array elements. So either I do it here with SetArray, or I do something similar ahead replacing js_memcpy_s with a version of CopyArray. Either approach has the concern that it is hard to know we missed one. Do you think CopyArray is safer in terms of write barrier correctness? e.g. is it possible GC collects in between js_memcpy_s and my current SetArray, and SetArray write barrier is too late?
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.
Making this change now. Revert SetArray, prefer earlier with CopyArray.
This probably needs the write barrier but I think you already noted that you haven't set barriers on the items themselves Refers to: lib/Common/DataStructures/BaseDictionary.h:1020 in 9958e2f. [](commit_id = 9958e2f, deletion_comment = False) |
|
|
||
| void | ||
| RecyclerWriteBarrierManager::WriteBarrier(void * address, size_t ptrCount) | ||
| RecyclerWriteBarrierManager::WriteBarrier(void * address, size_t bytes) |
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.
Curious- why this change?
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.
Dictionary's "entries" is an array of "EntryType" structs, not pointers.
| class Recycler; | ||
| class RecyclerNonLeafAllocator; | ||
|
|
||
| // Dummy tag classes to mark yes/no write barrier policy |
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.
Clever- although has the potential to be a little confusing so it's worth clearly documenting 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.
Agree, looks quite complex to myself...
|
|
I was hoping line 1046 below will take care of that. I was unsure if it would be a problem around line 1039 where we In reply to: 255494454 [](ancestors = 255494454) Refers to: lib/Common/DataStructures/BaseDictionary.h:1020 in 9958e2f. [](commit_id = 9958e2f, deletion_comment = False) |
|
LGTM |
Expand `Pointer` macro to choose `WriteBarrierPtr/NoWriteBarrierPtr` based on optional `Allocator` type using `WriteBarrierPtrTraits`. (E.g. pointer fields but using with Arena, choose NoWriteBarrierPtr.) Add `WriteBarrier` function to trigger write barrier on array content when needed. Added `CopyArray` function to copy array data. Triggers write barrier on the array content when needed. By default only pointer types, WriteBarrierPtr wrapper, or explicit _write_barrier_policy trigger write barrier (when using Recycler). Users can also use template instantiation to alter custom allocator/type write barrier policy. This change does not handle individual `Item` write barrier yet.
|
Thanks @digitalinfinity ! |
Merge pull request #1797 from jianchun:wballoc Expand `Pointer` macro to choose `WriteBarrierPtr/NoWriteBarrierPtr` based on optional `Allocator` type using `WriteBarrierPtrTraits`. (E.g. pointer fields but using with Arena, choose NoWriteBarrierPtr.) Add `WriteBarrier` function to trigger write barrier on array content when needed. Added `CopyArray` function to copy array data. Triggers write barrier on the array content when needed. By default only pointer types, WriteBarrierPtr wrapper, or explicit _write_barrier_policy trigger write barrier (when using Recycler). Users can also use template instantiation to alter custom allocator/type write barrier policy. This change does not handle individual `Item` write barrier yet.
Expand
Pointermacro to chooseWriteBarrierPtr/NoWriteBarrierPtrbased on optional
Allocatortype usingWriteBarrierPtrTraits.(E.g. pointer fields but using with Arena, choose NoWriteBarrierPtr.)
Add
WriteBarrierfunction to trigger write barrier on array contentwhen needed.
Added
CopyArrayfunction to copy array data. Triggers write barrieron the array content when needed.
By default only pointer types, WriteBarrierPtr wrapper, or explicit
_write_barrier_policy trigger write barrier (when using Recycler).
Users can also use template instantiation to alter custom allocator/type
write barrier policy.
This change does not handle individual
Itemwrite barrier yet.