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

ProgramMemory: only copy mValues on write #6646

Merged
merged 6 commits into from
Jul 31, 2024

Conversation

firewave
Copy link
Collaborator

No description provided.

@firewave
Copy link
Collaborator Author

firewave commented Jul 29, 2024

Some unit tests (e.g.TestBufferOverrun) still fail. The test I added for ProgramMemory works. Maybe I need to add test for each of the functions (well, I should).

There may also be unnecessary copies introduced by my changes related to getProgramState().

copyOnWrite();
pm.copyOnWrite();

mValues->swap(*pm.mValues);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be mValues.swap(pm.mValues).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.


void ProgramMemory::copyOnWrite()
{
if (!mCopyValues)
Copy link
Contributor

Choose a reason for hiding this comment

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

There is no need for the mCopyValues variable. Just check mValues.use_count() == 1 instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Will do.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

mValues = other.mValues;
mCopyValues = true;
return *this;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Just use the default-generated copy constructor and assignment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Without the need for mCopyValues I can do taht now.

It would have also required the move constructor/assignment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@@ -896,7 +896,7 @@ struct ValueFlowAnalyzer : Analyzer {

using ProgramState = ProgramMemory::Map;

virtual ProgramState getProgramState() const = 0;
virtual std::shared_ptr<ProgramState> getProgramState() const = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this changed to a shared_ptr? Its never shared.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because it is used to construct a ProgramMemory object in ValueFlowAnalyzer::evaluateInt().

Copy link
Contributor

Choose a reason for hiding this comment

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

But you can just move it instead.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Reverted.

@firewave firewave changed the title ProgramMemory: copy-on-write mValues [skip ci] ProgramMemory: copy-on-write mValues Jul 29, 2024
@firewave
Copy link
Collaborator Author

With the first round of review comments addressed the unit tests now all pass.

Here some preliminary numbers (without having looked at the profiling data if everything is on the up and up).

-D__GNUC__ --check-level=exhaustive ../lib/utils.cpp

Clang 17 883,929,117 -> 878,381,287

The example from https://trac.cppcheck.net/ticket/10765#comment:4:

Clang 17 8,156,089,970 -> 4,782,261,960


explicit ProgramMemory(Map values) : mValues(std::move(values)) {}
explicit ProgramMemory(std::shared_ptr<Map> values) : mValues(std::move(values)) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

This should not need to be changed to a shared_ptr, you can implement it as:

explicit ProgramMemory(Map values) : mValues(new Map()) {
    *mValues = std::move(values);
}

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. Did it even simpler by moving it into the constructor.

@@ -134,19 +134,19 @@ struct ProgramMemory {
void insert(const ProgramMemory &pm);

Map::iterator begin() {
return mValues.begin();
return mValues->begin();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

lacks copyOnWrite() as it returns something mutable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

}

Map::iterator end() {
return mValues.end();
return mValues->end();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

lacks copyOnWrite() as it returns something mutable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@firewave firewave force-pushed the pm-shared branch 3 times, most recently from 6704722 to 25ec10a Compare July 29, 2024 18:08
@firewave
Copy link
Collaborator Author

I added some more early outs (might split those into a separate commit later) and removed some unused code.

@firewave firewave force-pushed the pm-shared branch 2 times, most recently from 30284cc to 4454389 Compare July 29, 2024 19:27
@firewave firewave changed the title ProgramMemory: copy-on-write mValues ProgramMemory: only copy mValues on write Jul 29, 2024
@firewave
Copy link
Collaborator Author

Unfortunately this does not seem to help much with the selfcheck. ☹

@firewave firewave marked this pull request as ready for review July 30, 2024 06:42
// TODO: how to delay until we actuallly modify?
copyOnWrite();

for (auto it = mValues->begin(); it != mValues->end();) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can't this be written as remove-erase?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Possibly but that would not fix the TODO and just clean up the code.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If the call to remove_if() returns end(), no modification takes place, or am I missing something?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But we would have to determine if a modification happens, then make the copy and afterwards iterate it again because the existing result is based on a different container.

We only need to make this optimization if it is a hot spot.

Copy link
Collaborator

Choose a reason for hiding this comment

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


explicit ProgramMemory(Map values) : mValues(std::move(values)) {}
explicit ProgramMemory(Map values) : mValues(new Map(std::move(values))) {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

make_shared?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That would construct a shared_ptr object with an shared_ptr which is unnecessary.

@chrchr-github chrchr-github merged commit 53e55be into danmar:main Jul 31, 2024
63 checks passed
@firewave firewave deleted the pm-shared branch July 31, 2024 11:56
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.

3 participants