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
[JSC] Make Strong::set cheap #1150
[JSC] Make Strong::set cheap #1150
Conversation
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.
r=me. I think there's at least one case in HandleSet::writeBarrier below where the isOnList check can be turned into an ASSERT. And if we can strengthen the entry check in HandleSet::writeBarrier, we may be able to remove the other isOnList check too.
if (!value == !*slot) { | ||
if constexpr (isCellOnly) { | ||
ASSERT(slot->isCell() == value.isCell()); | ||
return; | ||
} | ||
if (slot->isCell() == value.isCell()) | ||
return; | ||
} |
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.
Let's see ... the possibilities are:
-
value == empty, *slot == empty: then slot->isCell() is true and value.isCell() is true even though empty != cell. But this is ok because we don't need to so anything if both are empty.
-
value == cell, *slot == cell: this is ok too because we don't need to do anything.
-
value == number, *slot == number: this is ok too because we don't need to do anything.
-
value == cell, *slot == number: in the generic case, the (slot->isCell() == value.isCell()) test will fail, and we won't return early, which is good. In the isCellOnly case, this is impossible.
-
value == cell, *slot == empty: the (!value == !*slot) test will fail, and we won't return early, which is good.
-
value == empty, *slot == cell: the (!value == !*slot) test will fail, and we won't return early, which is good.
-
value == empty, *slot == number: the (!value == !*slot) test will fail, and we won't return early, which is good. However, we'll need to check below if the node is already on list before removing. This case is impossible for the isCellOnly case.
-
value == number, *slot == empty: the (!value == !*slot) test will fail, and we won't return early, which is not great. And we'll need to check below if value is a cell before adding it to m_strongList. This case is impossible for the isCellOnly case.
-
value == number, *slot == cell: in the generic case, the (slot->isCell() == value.isCell()) test will fail, and we won't return early, which is good. However, we'll need to check below if value is a cell before adding it to m_strongList. This case is impossible for the isCellOnly case.
I'm using "number" to represent all the other types of JSValue that are non-cell but are not empty as well.
if (!value) { | ||
ASSERT(node->isOnList()); | ||
NodeList::remove(node); | ||
return; |
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.
If we get here, if value is empty, then we know that *slot must have a cell. Hence, we should remove the node from the m_strongList. So, this is correct.
ASSERT(!node->isOnList()); | ||
m_strongList.push(node); |
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.
If we get here, then we know that *slot must not have had a cell (because value has a cell). So, we must push the node onto m_strongList. So, this is also correct.
if (!node->isOnList()) | ||
m_strongList.push(node); |
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.
If we get here, value must be a cell. But we know from the entry check that the only way that we can get here is if *slot is either empty or a number. In both case, node should not already be on m_strongList. So, we can turn this if check into an ASSERT.
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.
Nice, fixed.
if (node->isOnList()) | ||
NodeList::remove(node); |
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.
If we get here, then we know value is not cell. Because of the entry check, we know that *slot can either be a number of a cell. So, it makes sense that we need this isOnList check. However, if the entry check also ensures that *slot cannot be a number, then we can turn this isOnList check into an ASSERT.
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.
OK, I've changed the condition,
150 bool valueIsNonEmptyCell = value && (isCellOnly || value.isCell());
151 bool slotIsNonEmptyCell = *slot && (isCellOnly || slot->isCell());
152 if (valueIsNonEmptyCell == slotIsNonEmptyCell)
153 return;
So, now, after this fast path check, we can make this isOnList()
removed :)
3386960
to
b7731f2
Compare
b7731f2
to
6b54cb4
Compare
Committed r295036 (251131@main): https://commits.webkit.org/251131@main Reviewed commits have been landed. Closing PR #1150 and removing active labels. |
…ki/linux_MemoryPressureMonitor_cgroupV1_honors_memory.memsw.usage_in_bytes_if_exist Linux MemoryPressureMonitor (cgroupV1) honors memory.memsw.usage_in_b…
6b54cb4