-
Notifications
You must be signed in to change notification settings - Fork 55
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
Resize-in-place for large allocs. (Shrink-only) #289
Conversation
ef3b736
to
0ac6d69
Compare
1ac74c0
to
4b96dad
Compare
sdlib/d/gc/arena.d
Outdated
uint oldSize = cast(uint) e.size; | ||
uint oldPages = oldSize / PageSize; |
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 cast should be on oldPages. Also, it's the currentSize.
sdlib/d/gc/arena.d
Outdated
|
||
auto computedPageCount = alignUp(size, PageSize) / PageSize; | ||
uint newPages = computedPageCount & uint.max; | ||
|
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.
Remove that empty line. the assert being on its own is quite confusing as it's not obvious that it is just a sanity check on the previous computation (check that there is no truncation going on, which should be impossible considering the allocatable size we have).
sdlib/d/gc/arena.d
Outdated
e.at(e.address, newPages * PageSize, hpd); | ||
hpd.clear(n + newPages, oldPages - newPages); |
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 tells me what you actually need as input is e
, n + newPages
, newPages
, delta
. It's 4 just as before, but it maps to what you actually need in there.
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.
Probably named e
, index
, pages
, delta
.
This is looking good, but there is probably some simplification in argument passing in the various functions in the arena. |
assert(isLargeSize(size)); | ||
|
||
// Huge is not supported: | ||
if (e.isHuge()) { |
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.
Can this happen if the isLarge assert pass.
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, please see definition, isLarge
includes any extent that isn't a slab.
sdlib/d/gc/arena.d
Outdated
@@ -338,6 +392,22 @@ private: | |||
unusedExtents.insert(e); | |||
} | |||
|
|||
void shrinkAllocImpl(Extent* e, uint index, uint pages, uint delta) { | |||
assert(mutex.isHeld(), "Mutex not held!"); | |||
assert(index <= PageCount - pages, "Invalid index!"); |
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.
Not a blocker, but 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.
Thank you, fixed.
sdlib/d/gc/arena.d
Outdated
auto currentSize = e.size; | ||
uint oldPages = cast(uint) (currentSize / PageSize); |
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.
e.pageCount
sdlib/d/gc/arena.d
Outdated
uint currentPages = cast(uint) (e.size / PageSize); | ||
assert(currentPages > pages, "Invalid shrink pages!"); |
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.
e.pageCount
auto hpd = e.hpd; | ||
unregisterHPD(hpd); | ||
|
||
e.at(e.address, pages * PageSize, hpd); | ||
hpd.clear(index, delta); | ||
|
||
assert(!hpd.empty); | ||
registerHPD(hpd); |
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 great how clean this became.
sdlib/d/gc/arena.d
Outdated
|
||
uint delta = currentPages - pages; | ||
|
||
uint n = ((cast(size_t) e.address) / PageSize) % PageCount; |
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.
e.hpdIndex
sdlib/d/gc/arena.d
Outdated
auto computedPageCount = alignUp(size, PageSize) / PageSize; | ||
uint newPages = computedPageCount & uint.max; | ||
assert(newPages == computedPageCount, "Unexpected page count!"); |
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.
getPageCount
auto p4 = threadCache.realloc(p3, 16000, false); | ||
assert(p4 !is p3); | ||
assert(p4 is p3); | ||
assert(threadCache.getCapacity(p4[0 .. 16000]) == 16384); |
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 there a test shrink from large to small?
In re: #265 .
realloc()
now resizes in place when possible, using appropriate size class.Currently only supports realloc() downwards.