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

[JSC] Reland Handler IC #28106

Merged

Conversation

Constellation
Copy link
Member

@Constellation Constellation commented May 3, 2024

13455c7

[JSC] Reland Handler IC
https://bugs.webkit.org/show_bug.cgi?id=273693
rdar://127496851

Reviewed by Keith Miller.

This patch enables limited variant of Handler IC. The limitation means,

1. Only enabled for Baseline JIT.
2. Getter and Setter are not supported yet.
3. We are caching entire code as an one handler. This is not the final form we would like to have.
   Next step is splitting them into one per AccessCase and chain them.
4. After (3) gets done, we would like to put more data into InlineCacheHandler itself so that code
   can be more and more sharable.

But even with this limited form, we are already observing good cache hit rate. So we take an approach starting with this,
and further extending Handler IC based on the above milestones.

We enable Handler IC, which is only enabled for Baseline JIT right now.
The IC is hash-consed via SharedJITStubSet. And InlineCacheCompiler first search for an already compiled stub, if it finds it,
we register watchpoint to this stub and use it without new compilation. If it is not found, we compile a new stub and register it to this table if possible.
When nobody uses this stub, then refCount becomes zero, and it automatically unregister itself from the table.
Each StructureStubInfo site's access cases is always subsumes stub's access cases. So GC will check validity via this StructureStubInfo's access cases, and
drop stub when it is no longer valid (as the same to the current IC).

The major difference from the last patch is adding multiple owners to the shared JIT IC.
Stubs are unregistering themselves from SharedJITStubSet when it reaches to zero-ref-count.
But this does not work well since CodeBlock can be destroyed lazily: if CodeBlock is dead, during that,
no GC scanning happens to this stub while ref-count is still non-zero.
For normal JIT stubs, we have owner concept for JIT stub. At GC end phase, we iterate stubs and check whether the owner is already dead.
And if it is dead, we mark it m_ownerIsDead. But shared JIT stub does not have this concept.
Instead, we have HashCountedSet for shared JIT stub, and register multiple owners for shared JIT stub. And at GC end phase, we scan owners
to wipe dead owners, and when live owners become zero, we mark the stub as m_ownerIsDead too.

* Source/JavaScriptCore/bytecode/AccessCase.cpp:
(JSC::AccessCase::tryGetAlternateBaseImpl const):
(JSC::AccessCase::canBeShared):
(JSC::AccessCase::tryGetAlternateBase const):
(JSC::AccessCase::hasAlternateBaseImpl const): Deleted.
(JSC::AccessCase::alternateBaseImpl const): Deleted.
(JSC::AccessCase::hasAlternateBase const): Deleted.
(JSC::AccessCase::alternateBase const): Deleted.
* Source/JavaScriptCore/bytecode/AccessCase.h:
(JSC::AccessCase::identifier const):
(JSC::AccessCase::dumpImpl const):
(JSC::AccessCase::updateIdentifier): Deleted.
* Source/JavaScriptCore/bytecode/GetByStatus.cpp:
(JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback):
* Source/JavaScriptCore/bytecode/GetterSetterAccessCase.cpp:
(JSC::GetterSetterAccessCase::tryGetAlternateBaseImpl const):
(JSC::GetterSetterAccessCase::hasAlternateBaseImpl const): Deleted.
(JSC::GetterSetterAccessCase::alternateBaseImpl const): Deleted.
* Source/JavaScriptCore/bytecode/GetterSetterAccessCase.h:
* Source/JavaScriptCore/bytecode/InlineCacheCompiler.cpp:
(JSC::InlineCacheCompiler::generateImpl):
(JSC::InlineCacheCompiler::regenerate):
(JSC::isMegamorphicById): Deleted.
* Source/JavaScriptCore/bytecode/PutByStatus.cpp:
(JSC::PutByStatus::computeForStubInfo):
* Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h:
(JSC::PolymorphicAccessJITStubRoutine::isStillValid const):
* Source/JavaScriptCore/runtime/StructureID.h:

Canonical link: https://commits.webkit.org/278369@main

b6b9842

Misc iOS, tvOS & watchOS macOS Linux Windows
βœ… πŸ§ͺ style βœ… πŸ›  ios βœ… πŸ›  mac βœ… πŸ›  wpe βœ… πŸ›  wincairo
βœ… πŸ›  ios-sim βœ… πŸ›  mac-AS-debug βœ… πŸ§ͺ wpe-wk2
βœ… πŸ§ͺ webkitperl βœ… πŸ§ͺ ios-wk2 βœ… πŸ§ͺ api-mac βœ… πŸ§ͺ api-wpe
βœ… πŸ§ͺ ios-wk2-wpt βœ… πŸ§ͺ mac-wk1 βœ… πŸ›  wpe-skia
βœ… πŸ›  πŸ§ͺ jsc βœ… πŸ§ͺ api-ios βœ… πŸ§ͺ mac-wk2 βœ… πŸ›  gtk
βœ… πŸ›  πŸ§ͺ jsc-arm64 βœ… πŸ›  tv ❌ πŸ§ͺ mac-AS-debug-wk2 βœ… πŸ§ͺ gtk-wk2
βœ… πŸ›  tv-sim βœ… πŸ§ͺ mac-wk2-stress βœ… πŸ§ͺ api-gtk
βœ… πŸ›  watch βœ… πŸ›  jsc-armv7
βœ… πŸ›  πŸ§ͺ unsafe-merge βœ… πŸ›  watch-sim βœ… πŸ§ͺ jsc-armv7-tests

@Constellation Constellation self-assigned this May 3, 2024
@Constellation Constellation added the JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues. label May 3, 2024
@Constellation Constellation marked this pull request as ready for review May 3, 2024 16:57
@Constellation Constellation requested a review from a team as a code owner May 3, 2024 16:57
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 3, 2024
@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label May 3, 2024
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 3, 2024
Copy link
Contributor

@kmiller68 kmiller68 left a comment

Choose a reason for hiding this comment

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

r=me with nits.

Comment on lines +103 to +104
template<typename Functor>
bool removeAllIf(const Functor&);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: could be const auto&

Copy link
Member Author

Choose a reason for hiding this comment

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

Changed.

@@ -84,6 +84,27 @@ IGNORE_GCC_WARNINGS_BEGIN("sequence-point")
IGNORE_GCC_WARNINGS_END
}

bool GCAwareJITStubRoutine::removeDeadOwners(VM& vm)
{
if (m_owner)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add: ASSERT(vm.heap.isInPhase(CollectorPhase::End)); here.

Copy link
Member Author

Choose a reason for hiding this comment

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

Changed.

@Constellation Constellation removed the merging-blocked Applied to prevent a change from being merged label May 3, 2024
@webkit-ews-buildbot webkit-ews-buildbot added the merging-blocked Applied to prevent a change from being merged label May 4, 2024
@Constellation
Copy link
Member Author

I've searched fast/webgpu/texture-supports-blending.html in the history data, and it is crashing exact same reason occasionally without this change. So it is flaky tests. And this is the signal that WebCore DOM object is not correctly keeping wrapper alive (and then wrapper gets collected, causing semantic issue). So landing.
https://build.webkit.org/#/builders/933/builds/1463
https://build.webkit.org/#/builders/934/builds/2534
https://build.webkit.org/#/builders/934/builds/2525
https://build.webkit.org/#/builders/934/builds/2521

@Constellation Constellation added unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing and removed merging-blocked Applied to prevent a change from being merged labels May 4, 2024
@webkit-commit-queue
Copy link
Collaborator

@webkit-commit-queue webkit-commit-queue added merging-blocked Applied to prevent a change from being merged and removed unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing labels May 4, 2024
@Constellation Constellation added unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing and removed merging-blocked Applied to prevent a change from being merged labels May 4, 2024
https://bugs.webkit.org/show_bug.cgi?id=273693
rdar://127496851

Reviewed by Keith Miller.

This patch enables limited variant of Handler IC. The limitation means,

1. Only enabled for Baseline JIT.
2. Getter and Setter are not supported yet.
3. We are caching entire code as an one handler. This is not the final form we would like to have.
   Next step is splitting them into one per AccessCase and chain them.
4. After (3) gets done, we would like to put more data into InlineCacheHandler itself so that code
   can be more and more sharable.

But even with this limited form, we are already observing good cache hit rate. So we take an approach starting with this,
and further extending Handler IC based on the above milestones.

We enable Handler IC, which is only enabled for Baseline JIT right now.
The IC is hash-consed via SharedJITStubSet. And InlineCacheCompiler first search for an already compiled stub, if it finds it,
we register watchpoint to this stub and use it without new compilation. If it is not found, we compile a new stub and register it to this table if possible.
When nobody uses this stub, then refCount becomes zero, and it automatically unregister itself from the table.
Each StructureStubInfo site's access cases is always subsumes stub's access cases. So GC will check validity via this StructureStubInfo's access cases, and
drop stub when it is no longer valid (as the same to the current IC).

The major difference from the last patch is adding multiple owners to the shared JIT IC.
Stubs are unregistering themselves from SharedJITStubSet when it reaches to zero-ref-count.
But this does not work well since CodeBlock can be destroyed lazily: if CodeBlock is dead, during that,
no GC scanning happens to this stub while ref-count is still non-zero.
For normal JIT stubs, we have owner concept for JIT stub. At GC end phase, we iterate stubs and check whether the owner is already dead.
And if it is dead, we mark it m_ownerIsDead. But shared JIT stub does not have this concept.
Instead, we have HashCountedSet for shared JIT stub, and register multiple owners for shared JIT stub. And at GC end phase, we scan owners
to wipe dead owners, and when live owners become zero, we mark the stub as m_ownerIsDead too.

* Source/JavaScriptCore/bytecode/AccessCase.cpp:
(JSC::AccessCase::tryGetAlternateBaseImpl const):
(JSC::AccessCase::canBeShared):
(JSC::AccessCase::tryGetAlternateBase const):
(JSC::AccessCase::hasAlternateBaseImpl const): Deleted.
(JSC::AccessCase::alternateBaseImpl const): Deleted.
(JSC::AccessCase::hasAlternateBase const): Deleted.
(JSC::AccessCase::alternateBase const): Deleted.
* Source/JavaScriptCore/bytecode/AccessCase.h:
(JSC::AccessCase::identifier const):
(JSC::AccessCase::dumpImpl const):
(JSC::AccessCase::updateIdentifier): Deleted.
* Source/JavaScriptCore/bytecode/GetByStatus.cpp:
(JSC::GetByStatus::computeForStubInfoWithoutExitSiteFeedback):
* Source/JavaScriptCore/bytecode/GetterSetterAccessCase.cpp:
(JSC::GetterSetterAccessCase::tryGetAlternateBaseImpl const):
(JSC::GetterSetterAccessCase::hasAlternateBaseImpl const): Deleted.
(JSC::GetterSetterAccessCase::alternateBaseImpl const): Deleted.
* Source/JavaScriptCore/bytecode/GetterSetterAccessCase.h:
* Source/JavaScriptCore/bytecode/InlineCacheCompiler.cpp:
(JSC::InlineCacheCompiler::generateImpl):
(JSC::InlineCacheCompiler::regenerate):
(JSC::isMegamorphicById): Deleted.
* Source/JavaScriptCore/bytecode/PutByStatus.cpp:
(JSC::PutByStatus::computeForStubInfo):
* Source/JavaScriptCore/jit/GCAwareJITStubRoutine.h:
(JSC::PolymorphicAccessJITStubRoutine::isStillValid const):
* Source/JavaScriptCore/runtime/StructureID.h:

Canonical link: https://commits.webkit.org/278369@main
@webkit-commit-queue
Copy link
Collaborator

Committed 278369@main (13455c7): https://commits.webkit.org/278369@main

Reviewed commits have been landed. Closing PR #28106 and removing active labels.

@webkit-commit-queue webkit-commit-queue merged commit 13455c7 into WebKit:main May 4, 2024
@webkit-commit-queue webkit-commit-queue removed the unsafe-merge-queue Applied to send a pull request to merge-queue, but skip building and testing label May 4, 2024
@Constellation Constellation deleted the eng/JSC-Reland-Handler-IC branch May 4, 2024 07:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
JavaScriptCore For bugs in JavaScriptCore, the JS engine used by WebKit, other than kxmlcore issues.
Projects
None yet
5 participants