Skip to content
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

Track dirty pages in regionAllocator. #338

Merged

Conversation

dsm9000
Copy link
Contributor

@dsm9000 dsm9000 commented Nov 6, 2023

Cut-down split of #335 : only the dirt tracking per se.

sdlib/d/gc/region.d Outdated Show resolved Hide resolved
@deadalnix
Copy link
Contributor

There is no test that the dirty pages are actually tracked properly. Making sure it is in all circumstance, in a data structure that make sense, is a big enough challenge, no reason to add more. However, it's a good reason to make sure this is well tested and correct in all circumstance, so it can serve as a layer fancier things can be built upon.

@dsm9000
Copy link
Contributor Author

dsm9000 commented Nov 6, 2023

@deadalnix The re-using logic and its test, were the bulk of the test for this. The remainder is e.g. here. What kind of test do you think it would be appropriate to add here while maintaining the given split?

@deadalnix
Copy link
Contributor

With all the scenari that can happen and need to be kept track off, I'm confident that if this is mixed with reusing, the testing is not appropriate. Thankfully, if the PR is made complicated enough, this fact can be obfuscated.

@dsm9000
Copy link
Contributor Author

dsm9000 commented Nov 7, 2023

@deadalnix are you able to point to something concrete and say "this part is needlessly complicated, it is possible to fulfill the spec without it" or is your objection simply "too much green in this diff" ?

sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved

auto r0 = Region.fromSlot(slot, 0);
auto r1 = Region.fromSlot(slot, 1);
static assert(Region.sizeof <= ExtentSize, "Unexpected Region size!");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't there a way to make it fit? It seems wasteful to multiply by two the amount of space taken by the metadata to store one size.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fits, naturally, if the by-dirt tree is cut out. But not otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll ask ourselves how to fit the data in there when we actually run out of space.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to run out of metadata slots other than under total OOM?

sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
@@ -144,6 +178,7 @@ private:

r.merge(adjacent);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The merging here does not keep track of dirty pages, which was the whole point of this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does though, see the Region.merge()

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Region.merge asserts a few things as it assume they are true, when they clearly do not necessarily are, which would have been obvious in the presence of tests.

Why do I need to runt he code through my mind to figure this out? If I'm wrong, it's trivial to demonstrate with a test that checks for the various permutations of things.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Region.merge() in this split is provably correct (and I'll add the test) while it remains the case that we don't purge dirties. But in order to be correct without this assumption, it needs the ordering function from part3 (and see its test.) Do you want these in part1? It seemed redundant IMHO to have them without the purging.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are correct, but you got to admit this wasn't obvious when this was drowned in a sea of unrelated changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goal is at all times to make things obviously correct to the reviewer. When failed, i.e. it it isn't obvious -- then needs rework, I won't disagree.

@deadalnix
Copy link
Contributor

There is a ton of code that has nothing to do with what this PR tries to achieve. And there is code that clearly lost track of the dirty pages in there.

Which also means that the testing for all of this is inadequate, as tests shouldn't be passing when the code is doing the wrong thing.

@dsm9000 dsm9000 force-pushed the track_dirty_pages_in_regionallocator branch 2 times, most recently from 1588a32 to faaa335 Compare November 7, 2023 19:09
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
@dsm9000 dsm9000 force-pushed the track_dirty_pages_in_regionallocator branch from faaa335 to 54654ef Compare November 7, 2023 19:11
@dsm9000 dsm9000 force-pushed the track_dirty_pages_in_regionallocator branch 3 times, most recently from 63813f7 to f60ace4 Compare November 8, 2023 04:18
Comment on lines 392 to 422
Region* merge(Region* r) {
assert(address is (r.address + r.size) || r.address is (address + size),
"Regions are not adjacent!");
auto rIsLeft = address is (r.address + r.size);
auto rIsRight = r.address is (address + size);
assert(rIsLeft || rIsRight, "Regions are not adjacent!");

auto leftRegion = rIsLeft ? r : &this;
auto rightRegion = rIsRight ? r : &this;

// Dirt is at all times contiguous within a region, and starts at the bottom.
// Given as purging is not yet supported, this invariant always holds.
assert(!leftRegion.hasClean || !rightRegion.hasDirt,
"Merge would place dirty pages in front of clean pages !");

return at(leftRegion.address, size + r.size, dirtySize + r.dirtySize);
}

void setDirt(size_t newDirtySize) {
dirtySize = newDirtySize;
}

@property
bool hasClean() {
return dirtySize < size;
}

import d.gc.util;
auto a = min(address, r.address);
return at(a, size + r.size);
@property
bool hasDirt() {
return dirtySize > 0;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

	Region* merge(Region* r) {
		assert(address is (r.address + r.size) || r.address is (address + size),
		       "Regions are not adjacent!");

		auto left = address < r.address ? &this : r;
		auto right = address < r.address ? r : &this;

		// Dirt is at all times contiguous within a region, and starts at the bottom.
		// Given as purging is not yet supported, this invariant always holds.
		assert(left.dirtySize == left.size || right.dirtySize == 0,
		       "Merge would place dirty pages in front of clean pages !");

		import d.gc.util;
		auto a = min(address, r.address);
		return at(a, size + r.size, dirtySize + r.dirtySize);
	}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return at(left.address, size + r.size, dirtySize + r.dirtySize);

sdlib/d/gc/region.d Outdated Show resolved Hide resolved
@@ -144,6 +178,7 @@ private:

r.merge(adjacent);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are correct, but you got to admit this wasn't obvious when this was drowned in a sea of unrelated changes.

sdlib/d/gc/region.d Outdated Show resolved Hide resolved
sdlib/d/gc/region.d Outdated Show resolved Hide resolved
@dsm9000 dsm9000 force-pushed the track_dirty_pages_in_regionallocator branch 3 times, most recently from d6bf7c1 to 0d2f4bb Compare November 8, 2023 18:27
@dsm9000 dsm9000 force-pushed the track_dirty_pages_in_regionallocator branch from 0d2f4bb to cbc6e12 Compare November 8, 2023 18:33
@deadalnix deadalnix merged commit fec5b85 into snazzy-d:master Nov 8, 2023
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants