RESOLVED FIXED223495
BrandedStructure should keep its members alive.
https://bugs.webkit.org/show_bug.cgi?id=223495
Summary BrandedStructure should keep its members alive.
Mark Lam
Reported 2021-03-18 19:03:55 PDT
Attachments
proposed patch. (4.40 KB, patch)
2021-03-18 19:10 PDT, Mark Lam
ews-feeder: commit-queue-
proposed patch. (6.12 KB, patch)
2021-03-18 19:42 PDT, Mark Lam
saam: review+
ews-feeder: commit-queue-
patch for landing. (5.70 KB, patch)
2021-03-18 21:44 PDT, Mark Lam
ews-feeder: commit-queue-
Mark Lam
Comment 1 2021-03-18 19:10:01 PDT
Created attachment 423682 [details] proposed patch.
Mark Lam
Comment 2 2021-03-18 19:42:37 PDT
Created attachment 423684 [details] proposed patch.
Saam Barati
Comment 3 2021-03-18 21:26:31 PDT
Comment on attachment 423684 [details] proposed patch. View in context: https://bugs.webkit.org/attachment.cgi?id=423684&action=review > Source/JavaScriptCore/runtime/BrandedStructure.cpp:59 > +void BrandedStructure::destruct() Can we put this in the header and inline it? It’s so trivial
Mark Lam
Comment 4 2021-03-18 21:27:48 PDT
Comment on attachment 423684 [details] proposed patch. View in context: https://bugs.webkit.org/attachment.cgi?id=423684&action=review >> Source/JavaScriptCore/runtime/BrandedStructure.cpp:59 >> +void BrandedStructure::destruct() > > Can we put this in the header and inline it? It’s so trivial Will do.
Mark Lam
Comment 5 2021-03-18 21:44:19 PDT
Created attachment 423689 [details] patch for landing.
Caio Lima
Comment 6 2021-03-19 05:04:07 PDT
Comment on attachment 423689 [details] patch for landing. View in context: https://bugs.webkit.org/attachment.cgi?id=423689&action=review > Source/JavaScriptCore/ChangeLog:27 > + 1. m_parentBrand was not visited by visitChildren(). I'm curious to know why this is necessary. I introduced it at first, but then I removed based on the reasoning that `m_parentBrand` will always point backwards to a structure from the transition chain. Given that, when `m_previous` is visited, it will eventually visit its `m_parentBrand`. Did you find a case where this is not true? I took it a bit further and figured out that is possible to implement the brand check without `m_parentBrand`, but decided to keep it there as a shortcut to avoid traverse the entire chain.
EWS
Comment 7 2021-03-19 09:45:50 PDT
Tools/Scripts/svn-apply failed to apply attachment 423689 [details] to trunk. Please resolve the conflicts and upload a new patch.
Mark Lam
Comment 8 2021-03-19 10:44:50 PDT
Comment on attachment 423689 [details] patch for landing. View in context: https://bugs.webkit.org/attachment.cgi?id=423689&action=review >> Source/JavaScriptCore/ChangeLog:27 >> + 1. m_parentBrand was not visited by visitChildren(). > > I'm curious to know why this is necessary. I introduced it at first, but then I removed based on the reasoning that `m_parentBrand` will always point backwards to a structure from the transition chain. Given that, when `m_previous` is visited, it will eventually visit its `m_parentBrand`. Did you find a case where this is not true? > > I took it a bit further and figured out that is possible to implement the brand check without `m_parentBrand`, but decided to keep it there as a shortcut to avoid traverse the entire chain. See Structure::setBrandTransition(), specifically this scenario: ``` if (structure->isDictionary()) { PropertyTable* table = transition->ensurePropertyTable(vm); transition->pin(holdLock(transition->m_lock), vm, table); ``` pin() does the following: ``` void Structure::pin(const AbstractLocker&, VM& vm, PropertyTable* table) { setIsPinnedPropertyTable(true); setPropertyTable(vm, table); clearPreviousID(); m_transitionPropertyName = nullptr; } ``` clearPreviousID() clears the structure chain link, which leaves m_parentBrand vulnerable.
Mark Lam
Comment 9 2021-03-19 10:49:55 PDT
Caio Lima
Comment 10 2021-03-19 11:48:42 PDT
(In reply to Mark Lam from comment #8) > Comment on attachment 423689 [details] > patch for landing. > > View in context: > https://bugs.webkit.org/attachment.cgi?id=423689&action=review > > >> Source/JavaScriptCore/ChangeLog:27 > >> + 1. m_parentBrand was not visited by visitChildren(). > > > > I'm curious to know why this is necessary. I introduced it at first, but then I removed based on the reasoning that `m_parentBrand` will always point backwards to a structure from the transition chain. Given that, when `m_previous` is visited, it will eventually visit its `m_parentBrand`. Did you find a case where this is not true? > > > > I took it a bit further and figured out that is possible to implement the brand check without `m_parentBrand`, but decided to keep it there as a shortcut to avoid traverse the entire chain. > > See Structure::setBrandTransition(), specifically this scenario: > > ``` > if (structure->isDictionary()) { > PropertyTable* table = transition->ensurePropertyTable(vm); > transition->pin(holdLock(transition->m_lock), vm, table); > ``` > > pin() does the following: > ``` > void Structure::pin(const AbstractLocker&, VM& vm, PropertyTable* table) > { > setIsPinnedPropertyTable(true); > setPropertyTable(vm, table); > clearPreviousID(); > m_transitionPropertyName = nullptr; > } > ``` > > clearPreviousID() clears the structure chain link, which leaves > m_parentBrand vulnerable. Oh, I totally missed that. Thanks for explaining and for the fix as well.
Note You need to log in before you can comment on or make changes to this bug.