Closed Bug 1662559 Opened 4 years ago Closed 4 years ago

Change storage for private methods to save space

Categories

(Core :: JavaScript Engine, task, P3)

task

Tracking

()

RESOLVED FIXED
90 Branch
Tracking Status
firefox90 --- fixed

People

(Reporter: mgaudet, Assigned: jorendorff)

References

(Blocks 1 open bug, Regressed 2 open bugs)

Details

Attachments

(20 files, 5 obsolete files)

48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review

Currently the storage of private methods means that every private method is treated like a field on an object.

This can be improved.

Severity: -- → N/A
Priority: -- → P3
Depends on: 1697223
Assignee: nobody → jorendorff
Status: NEW → ASSIGNED

The new class is not actually used yet; see the next patch.

Depends on D108283

It is a copy of BlockLexicalEnvironmentObject. Note that

  • ClassBodyScope is not a LexicalScope, BUT

  • ClassBodyLexicalEnvironmentObject is a LexicalEnvironmentObject

This is strictly a matter of how much implementation is shared. The word
"Lexical" in LexicalEnvironmentObject, and to some extent throughout
SpiderMonkey, is alas already pretty meaningless. In the language
specification, all environments are lexical environments.

Depends on D108286

Not every class gets this special binding. It will be needed for all classes
that have any nonstatic private methods, getters, or setters. With this patch,
we create a .privateBrand binding in the scopes for such classes, and populate
it with a symbol when initializing the class. However, it is not yet being used
anywhere; the constructor does not yet stamp instances with the private brand.

Depends on D108288

This adds a hasPrivateBrand bit to the MemberInitializers struct in the
stencil. It is necessary to persist this bit across compilation units because
emitInitializeInstanceMembers can be called in direct eval code inside a
derived-class constructor.

Since .privateBrand is currently a let binding, this currently emits an
unnecessary CheckAliasedLexical instruction in the constructor for each class
that has nonstatic private methods. We'll eliminate these later on.

Depends on D108289

This is currently used only by the bindings in a ClassBodyScope.

The behavior of these bindings is like Var bindings. There is no longer a TDZ
check, and we don't bother marking them as Uninitialized. So the special case
introduced in bug 1683746, peeking at the binding name to see if we should skip
the TDZ check, is no longer needed.

Depends on D108290

This is how the frontend will later identify private methods in order to emit
special bytecode.

Depends on D108291

This affects bytecode, as Synthetic bindings do not get TDZ checks.

This patch also tightens up some assertions when creating ScopeData. There are
several methods that create ScopeData, and they had gotten out of sync. The
assertions check that the ScopeData is not silently dropping bindings that were
present in ParseContext::Scope::declared_.

Depends on D108292

This would cause private methods to be marked as such on scopes, except that
the parser still declares them as DeclarationKind::Synthetic for now.

Depends on D108293

The diff is a mess, but this is very straightforward--we have a combination of
if-statements and a switch that could just be a single switch.

Depends on D108295

The new parse nodes then need to be handled throughout the BytecodeEmitter. No
change in behavior.

Depends on D108296

At the same time, the initialization and storage of private methods is changed
to what the PrivateOpEmitter expects.

There are some barely-observable differences in behavior, resulting in two jit-test changes:

  • fields/bug1683784.js - An error message changed. Not really better or worse.

  • js/src/jit-test/tests/parser/script-source-extent.js - The debugger is able
    to observe initializers as individual scripts. We are no longer using
    initializers for private methods that can be optimized, and the debugger
    therefore observes the change. I adjusted the test to expect the new
    behavior.

Two jit-tests fail:

  • fields/private-eval-in-frame.js - The very dynamic scopes in which
    Frame.prototype.eval runs do not pass through static information about
    private methods, so an assertion in lookupPrivate fails. One possible
    workaround would be to ban the use of private fields and methods in
    eval-in-frame code.

  • debug/private-methods-eval-in-frame.js - Same.

All js/src/tests pass.

Depends on D108300

Attachment #9208835 - Attachment description: Bug 1662559 - Part 1: Rename NameLocation::fromBinding() -> BindingIter::nameLocation(). r=mgaudet → Bug 1662559 - Part 1: Rename NameLocation::fromBinding() -> BindingIter::nameLocation(). r=arai
Attachment #9208835 - Attachment description: Bug 1662559 - Part 1: Rename NameLocation::fromBinding() -> BindingIter::nameLocation(). r=arai → WIP: Bug 1662559 - Part 1: Rename NameLocation::fromBinding() -> BindingIter::nameLocation(). r=arai
Attachment #9208836 - Attachment description: Bug 1662559 - Part 2: Clone LexicalScope -> ClassBodyScope. r=mgaudet → WIP: Bug 1662559 - Part 2: Clone LexicalScope{Node} -> ClassBodyScope{Node}. r=arai
Attachment #9208838 - Attachment description: Bug 1662559 - Part 4: Tighten up type of the ClassMemberList node kind. r=mgaudet → WIP: Bug 1662559 - Part 3: Tighten up type of the ClassMemberList node kind. r=arai
Attachment #9208839 - Attachment description: Bug 1662559 - Part 5: Introduce ClassBodyLexicalEnvironmentObject. r=mgaudet → WIP: Bug 1662559 - Part 4: Introduce ClassBodyLexicalEnvironmentObject. r=arai
Attachment #9208841 - Attachment description: Bug 1662559 - Part 7: Add .privateBrand to class body scopes. r=mgaudet → WIP: Bug 1662559 - Part 5: Add .privateBrand to class body scopes. r=arai
Attachment #9208842 - Attachment description: Bug 1662559 - Part 8: Stamp the private brand on instances. r=mgaudet → WIP: Bug 1662559 - Part 6: Stamp the private brand on instances. r=mgaudet
Attachment #9208843 - Attachment description: Bug 1662559 - Part 9: Add BindingKind::Synthetic, a kind of binding for pseudo-bindings. r=mgaudet → WIP: Bug 1662559 - Part 7: Add BindingKind::Synthetic, a kind of binding for pseudo-bindings. r=arai
Attachment #9208844 - Attachment description: Bug 1662559 - Part 10: Add BindingKind::PrivateMethod. r=mgaudet → WIP: Bug 1662559 - Part 8: Add BindingKind::PrivateMethod. r=arai
Attachment #9208845 - Attachment description: Bug 1662559 - Part 11: Migrate all ClassBodyScope bindings to be Synthetic. r=mgaudet → WIP: Bug 1662559 - Part 9: Migrate all ClassBodyScope bindings to be Synthetic. r=arai
Attachment #9208846 - Attachment description: Bug 1662559 - Part 12: Propagate BindingKind::PrivateMethod to scope data. r=mgaudet → WIP: Bug 1662559 - Part 10: Propagate BindingKind::PrivateMethod to scope data. r=arai
Attachment #9208847 - Attachment description: Bug 1662559 - Part 13: Move .privateBrand to a fixed location and add BytecodeEmitter::lookupPrivate() to find it. r=mgaudet → WIP: Bug 1662559 - Part 11: Move .privateBrand to a fixed location and add BytecodeEmitter::lookupPrivate() to find it. r=arai

By storing NameLocations we also get a BindingKind, which allows us to disambiguate between
PrivateMethods and Synthetics.

Depends on D108295

In order to correctly support this with the optimized storage for methods we
would need new bytecode like GetAliasedVar which is able to traverse
non-EnvironmentObject environments like DebugEnvironmentProxy.

Depends on D109401

Attachment #9208848 - Attachment description: Bug 1662559 - Part 14: Minor refactor for BytecodeEmitter::emitSetOrInitializeDestructuring. r=mgaudet → WIP: Bug 1662559 - Part 14: Minor refactor for BytecodeEmitter::emitSetOrInitializeDestructuring. r=arai
Attachment #9208849 - Attachment description: Bug 1662559 - Part 15: Add AST node types for private member access expressions (`obj.#member`). r=mgaudet → WIP: Bug 1662559 - Part 15: Add AST node types for private member access expressions (`obj.#member`). r=arai
Attachment #9208850 - Attachment description: Bug 1662559 - Part 16: Add PrivateOpEmitter, based on PropOpEmitter. r=mgaudet → WIP: Bug 1662559 - Part 16: Add PrivateOpEmitter, based on PropOpEmitter. r=arai
Attachment #9208851 - Attachment description: Bug 1662559 - Part 17: Change BytecodeEmitter to use the new PrivateOpEmitter class. r=mgaudet → WIP: Bug 1662559 - Part 17: Change BytecodeEmitter to use the new PrivateOpEmitter class. r=arai
Attachment #9208852 - Attachment description: Bug 1662559 - Part 18: Remove all support for private members from ElemOpEmitter. r=mgaudet → WIP: Bug 1662559 - Part 18: Remove all support for private members from ElemOpEmitter. r=arai
Attachment #9208853 - Attachment description: Bug 1662559 - Part 19: Emit DeclarationKind::PrivateName declarations and use all the optimized paths in PrivateOpEmitter. r=mgaudet → WIP: Bug 1662559 - Part 19: Emit DeclarationKind::PrivateName declarations and use all the optimized paths in PrivateOpEmitter. r=arai
Attachment #9208854 - Attachment description: Bug 1662559 - Part 20: Tweak some comments in NameOpEmitter.h. r=mgaudet → WIP: Bug 1662559 - Part 20: Tweak some comments in NameOpEmitter.h. r=arai
Attachment #9208837 - Attachment is obsolete: true
Attachment #9208840 - Attachment is obsolete: true
Attachment #9208835 - Attachment description: WIP: Bug 1662559 - Part 1: Rename NameLocation::fromBinding() -> BindingIter::nameLocation(). r=arai → Bug 1662559 - Part 1: Rename NameLocation::fromBinding() -> BindingIter::nameLocation(). r=arai
Attachment #9208836 - Attachment description: WIP: Bug 1662559 - Part 2: Clone LexicalScope{Node} -> ClassBodyScope{Node}. r=arai → Bug 1662559 - Part 2: Clone LexicalScope{Node} -> ClassBodyScope{Node}. r=arai
Attachment #9208838 - Attachment description: WIP: Bug 1662559 - Part 3: Tighten up type of the ClassMemberList node kind. r=arai → Bug 1662559 - Part 3: Tighten up type of the ClassMemberList node kind. r=arai
Attachment #9208839 - Attachment description: WIP: Bug 1662559 - Part 4: Introduce ClassBodyLexicalEnvironmentObject. r=arai → Bug 1662559 - Part 4: Introduce ClassBodyLexicalEnvironmentObject. r=arai
Attachment #9208841 - Attachment description: WIP: Bug 1662559 - Part 5: Add .privateBrand to class body scopes. r=arai → Bug 1662559 - Part 5: Add .privateBrand to class body scopes. r=arai
Attachment #9208842 - Attachment description: WIP: Bug 1662559 - Part 6: Stamp the private brand on instances. r=mgaudet → Bug 1662559 - Part 6: Stamp the private brand on instances. r=mgaudet
Attachment #9208843 - Attachment description: WIP: Bug 1662559 - Part 7: Add BindingKind::Synthetic, a kind of binding for pseudo-bindings. r=arai → Bug 1662559 - Part 7: Add BindingKind::Synthetic, a kind of binding for pseudo-bindings. r=arai
Attachment #9208844 - Attachment description: WIP: Bug 1662559 - Part 8: Add BindingKind::PrivateMethod. r=arai → Bug 1662559 - Part 8: Add BindingKind::PrivateMethod. r=arai
Attachment #9208845 - Attachment description: WIP: Bug 1662559 - Part 9: Migrate all ClassBodyScope bindings to be Synthetic. r=arai → Bug 1662559 - Part 9: Migrate all ClassBodyScope bindings to be Synthetic. r=arai
Attachment #9208846 - Attachment description: WIP: Bug 1662559 - Part 10: Propagate BindingKind::PrivateMethod to scope data. r=arai → Bug 1662559 - Part 10: Propagate BindingKind::PrivateMethod to scope data. r=arai
Attachment #9208847 - Attachment description: WIP: Bug 1662559 - Part 11: Move .privateBrand to a fixed location and add BytecodeEmitter::lookupPrivate() to find it. r=arai → Bug 1662559 - Part 11: Move .privateBrand to a fixed location and add BytecodeEmitter::lookupPrivate() to find it. r=arai
Attachment #9210839 - Attachment description: WIP: Bug 1662559 - Part 12: Modify effectiveScopePrivateFieldCache to store NameLocations as well. → Bug 1662559 - Part 12: Modify effectiveScopePrivateFieldCache to store NameLocations as well. r?arai
Attachment #9210840 - Attachment description: WIP: Bug 1662559 - Part 13: Disallow invocation of private methods inside of evalInFrame → Bug 1662559 - Part 13: Disallow invocation of private methods inside of evalInFrame r?arai
Attachment #9208848 - Attachment description: WIP: Bug 1662559 - Part 14: Minor refactor for BytecodeEmitter::emitSetOrInitializeDestructuring. r=arai → Bug 1662559 - Part 14: Minor refactor for BytecodeEmitter::emitSetOrInitializeDestructuring. r=arai
Attachment #9208849 - Attachment description: WIP: Bug 1662559 - Part 15: Add AST node types for private member access expressions (`obj.#member`). r=arai → Bug 1662559 - Part 15: Add AST node types for private member access expressions (`obj.#member`). r=arai
Attachment #9208850 - Attachment description: WIP: Bug 1662559 - Part 16: Add PrivateOpEmitter, based on PropOpEmitter. r=arai → Bug 1662559 - Part 16: Add PrivateOpEmitter, based on PropOpEmitter. r=arai
Attachment #9208851 - Attachment description: WIP: Bug 1662559 - Part 17: Change BytecodeEmitter to use the new PrivateOpEmitter class. r=arai → Bug 1662559 - Part 17: Change BytecodeEmitter to use the new PrivateOpEmitter class. r=arai
Attachment #9208852 - Attachment description: WIP: Bug 1662559 - Part 18: Remove all support for private members from ElemOpEmitter. r=arai → Bug 1662559 - Part 18: Remove all support for private members from ElemOpEmitter. r=arai
Attachment #9208853 - Attachment description: WIP: Bug 1662559 - Part 19: Emit DeclarationKind::PrivateName declarations and use all the optimized paths in PrivateOpEmitter. r=arai → Bug 1662559 - Part 19: Emit DeclarationKind::PrivateName declarations and use all the optimized paths in PrivateOpEmitter. r=arai
Attachment #9208854 - Attachment description: WIP: Bug 1662559 - Part 20: Tweak some comments in NameOpEmitter.h. r=arai → Bug 1662559 - Part 20: Tweak some comments in NameOpEmitter.h. r=arai
Attachment #9208842 - Attachment description: Bug 1662559 - Part 6: Stamp the private brand on instances. r=mgaudet → Bug 1662559 - Part 6: Stamp the private brand on instances. r=arai
Regressions: 1702038
Pushed by mgaudet@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/88203b6f2e5a Part 1: Rename NameLocation::fromBinding() -> BindingIter::nameLocation(). r=arai https://hg.mozilla.org/integration/autoland/rev/8970e82f0312 Part 2: Clone LexicalScope{Node} -> ClassBodyScope{Node}. r=arai https://hg.mozilla.org/integration/autoland/rev/547e0b38d66e Part 3: Tighten up type of the ClassMemberList node kind. r=arai https://hg.mozilla.org/integration/autoland/rev/ae45d407929f Part 4: Introduce ClassBodyLexicalEnvironmentObject. r=arai https://hg.mozilla.org/integration/autoland/rev/e200366e7e3a Part 5: Add .privateBrand to class body scopes. r=arai https://hg.mozilla.org/integration/autoland/rev/0b01a60bb702 Part 6: Stamp the private brand on instances. r=arai https://hg.mozilla.org/integration/autoland/rev/3902d4cb84cc Part 7: Add BindingKind::Synthetic, a kind of binding for pseudo-bindings. r=arai https://hg.mozilla.org/integration/autoland/rev/70d767bf04ad Part 8: Add BindingKind::PrivateMethod. r=arai https://hg.mozilla.org/integration/autoland/rev/1420d94f0d59 Part 9: Migrate all ClassBodyScope bindings to be Synthetic. r=arai https://hg.mozilla.org/integration/autoland/rev/0b14a97cd0fb Part 10: Propagate BindingKind::PrivateMethod to scope data. r=arai https://hg.mozilla.org/integration/autoland/rev/1bac4e440311 Part 11: Move .privateBrand to a fixed location and add BytecodeEmitter::lookupPrivate() to find it. r=arai https://hg.mozilla.org/integration/autoland/rev/0f5bcb3ca09f Part 12: Modify effectiveScopePrivateFieldCache to store NameLocations as well. r=arai https://hg.mozilla.org/integration/autoland/rev/118b19a448fa Part 13: Disallow invocation of private methods inside of evalInFrame r=arai https://hg.mozilla.org/integration/autoland/rev/cc3a2fadee36 Part 14: Minor refactor for BytecodeEmitter::emitSetOrInitializeDestructuring. r=arai https://hg.mozilla.org/integration/autoland/rev/405a80f38f5c Part 15: Add AST node types for private member access expressions (`obj.#member`). r=arai https://hg.mozilla.org/integration/autoland/rev/be3069057f5a Part 16: Add PrivateOpEmitter, based on PropOpEmitter. r=arai https://hg.mozilla.org/integration/autoland/rev/bd328ac14770 Part 17: Change BytecodeEmitter to use the new PrivateOpEmitter class. r=arai https://hg.mozilla.org/integration/autoland/rev/5e4ca6c62d4b Part 18: Remove all support for private members from ElemOpEmitter. r=arai https://hg.mozilla.org/integration/autoland/rev/0fbfd31e0f78 Part 19: Emit DeclarationKind::PrivateName declarations and use all the optimized paths in PrivateOpEmitter. r=arai https://hg.mozilla.org/integration/autoland/rev/4c69d3aabee4 Part 20: Tweak some comments in NameOpEmitter.h. r=arai
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Target Milestone: 89 Branch → ---
Regressions: 1702734

(This will be rolled into Part 4 for landing)

The intention of the Patch stack, among other things, is to separate the
handling of regular lexical bindings from those that are synthetic and private
methods; things never exposed to or handled in script. As a result of this
divergence, a case in the NameOpEmitter was missed: here we emit SetLocal
instead of the expected InitializeLexical (well, as expected as can be without
thinking about a potentially more accurate bytecode called
InitializeSyntheticOrPrivate)

We also handle EnvironmentCoordinates in the same way

This will be rolled into Part 9 for landing.

Depends on D108293

Attachment #9210839 - Attachment description: Bug 1662559 - Part 12: Modify effectiveScopePrivateFieldCache to store NameLocations as well. r?arai → Bug 1662559 - Part 12: Modify effectiveScopePrivateFieldCache to store NameLocations as well. r=arai
Attachment #9210840 - Attachment description: Bug 1662559 - Part 13: Disallow invocation of private methods inside of evalInFrame r?arai → Bug 1662559 - Part 13: Disallow invocation of private methods inside of evalInFrame r=arai

This will be rolled into Part 19 for landing.

Note: This is the fixup patch I am least comfortable with. I am open to the
suggestion that maybe the -correct- action here is to break apart
PrivateOpEmitter::emitGet(), which appears to have far too complex a semantics
to reason about.

Depends on D108301

Attachment #9213841 - Attachment is obsolete: true
Attachment #9213842 - Attachment is obsolete: true
Attachment #9213840 - Attachment is obsolete: true
Pushed by mgaudet@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/86392a2f9d18 Part 1: Rename NameLocation::fromBinding() -> BindingIter::nameLocation(). r=arai https://hg.mozilla.org/integration/autoland/rev/a7ffffabe660 Part 2: Clone LexicalScope{Node} -> ClassBodyScope{Node}. r=arai https://hg.mozilla.org/integration/autoland/rev/235c9126589a Part 3: Tighten up type of the ClassMemberList node kind. r=arai https://hg.mozilla.org/integration/autoland/rev/d3b226ecc677 Part 4: Introduce ClassBodyLexicalEnvironmentObject. r=arai https://hg.mozilla.org/integration/autoland/rev/dd28bf5beaf8 Part 5: Add .privateBrand to class body scopes. r=arai https://hg.mozilla.org/integration/autoland/rev/5ce850a6e268 Part 6: Stamp the private brand on instances. r=arai https://hg.mozilla.org/integration/autoland/rev/0954e98760d0 Part 7: Add BindingKind::Synthetic, a kind of binding for pseudo-bindings. r=arai https://hg.mozilla.org/integration/autoland/rev/58e84f08f369 Part 8: Add BindingKind::PrivateMethod. r=arai https://hg.mozilla.org/integration/autoland/rev/7045f0aa9352 Part 9: Migrate all ClassBodyScope bindings to be Synthetic. r=arai https://hg.mozilla.org/integration/autoland/rev/fafe4be45090 Part 10: Propagate BindingKind::PrivateMethod to scope data. r=arai https://hg.mozilla.org/integration/autoland/rev/462358e96220 Part 11: Move .privateBrand to a fixed location and add BytecodeEmitter::lookupPrivate() to find it. r=arai https://hg.mozilla.org/integration/autoland/rev/2ae9723b04dc Part 12: Modify effectiveScopePrivateFieldCache to store NameLocations as well. r=arai https://hg.mozilla.org/integration/autoland/rev/686e81e46bfb Part 13: Disallow invocation of private methods inside of evalInFrame r=arai https://hg.mozilla.org/integration/autoland/rev/4082f63c554a Part 14: Minor refactor for BytecodeEmitter::emitSetOrInitializeDestructuring. r=arai https://hg.mozilla.org/integration/autoland/rev/75ca82a2e26a Part 15: Add AST node types for private member access expressions (`obj.#member`). r=arai https://hg.mozilla.org/integration/autoland/rev/8dd759f91922 Part 16: Add PrivateOpEmitter, based on PropOpEmitter. r=arai https://hg.mozilla.org/integration/autoland/rev/051adeafc417 Part 17: Change BytecodeEmitter to use the new PrivateOpEmitter class. r=arai https://hg.mozilla.org/integration/autoland/rev/a48c2c09a753 Part 18: Remove all support for private members from ElemOpEmitter. r=arai https://hg.mozilla.org/integration/autoland/rev/c4c9cea546f9 Part 19: Emit DeclarationKind::PrivateName declarations and use all the optimized paths in PrivateOpEmitter. r=arai https://hg.mozilla.org/integration/autoland/rev/bc1d34f55b6b Part 20: Tweak some comments in NameOpEmitter.h. r=arai
Regressions: 1706763
Regressions: 1706923
Blocks: 1708249
Regressions: 1759826
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: