Skip to content

ProgramMemory: only copy mValues on write#6646

Merged
chrchr-github merged 6 commits intocppcheck-opensource:mainfrom
firewave:pm-shared
Jul 31, 2024
Merged

ProgramMemory: only copy mValues on write#6646
chrchr-github merged 6 commits intocppcheck-opensource:mainfrom
firewave:pm-shared

Conversation

@firewave
Copy link
Copy Markdown
Collaborator

No description provided.

@firewave
Copy link
Copy Markdown
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().

Comment thread lib/programmemory.cpp Outdated
copyOnWrite();
pm.copyOnWrite();

mValues->swap(*pm.mValues);
Copy link
Copy Markdown
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
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Comment thread lib/programmemory.cpp Outdated

void ProgramMemory::copyOnWrite()
{
if (!mCopyValues)
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Comment thread lib/programmemory.h Outdated
mValues = other.mValues;
mCopyValues = true;
return *this;
}
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Comment thread lib/valueflow.cpp Outdated
using ProgramState = ProgramMemory::Map;

virtual ProgramState getProgramState() const = 0;
virtual std::shared_ptr<ProgramState> getProgramState() const = 0;
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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

Comment thread lib/programmemory.h Outdated
ProgramMemory() : mValues(new Map()) {}

explicit ProgramMemory(Map values) : mValues(std::move(values)) {}
explicit ProgramMemory(std::shared_ptr<Map> values) : mValues(std::move(values)) {}
Copy link
Copy Markdown
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
Copy Markdown
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.

Comment thread lib/programmemory.h

Map::iterator begin() {
return mValues.begin();
return mValues->begin();
Copy link
Copy Markdown
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
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Comment thread lib/programmemory.h

Map::iterator end() {
return mValues.end();
return mValues->end();
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Comment thread lib/programmemory.cpp
// TODO: how to delay until we actuallly modify?
copyOnWrite();

for (auto it = mValues->begin(); it != mValues->end();) {
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Comment thread lib/programmemory.h
ProgramMemory() : mValues(new Map()) {}

explicit ProgramMemory(Map values) : mValues(std::move(values)) {}
explicit ProgramMemory(Map values) : mValues(new Map(std::move(values))) {}
Copy link
Copy Markdown
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
Copy Markdown
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 cppcheck-opensource:main Jul 31, 2024
@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