v8/test/cctest/interpreter/bytecode_expectations/PrivateClassFields.golden

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

262 lines
8.0 KiB
Plaintext
Raw Normal View History

[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
#
# Autogenerated by generate-bytecode-expectations.
#
---
wrap: yes
---
snippet: "
{
class A {
#a;
constructor() {
this.#a = 1;
}
}
class B {
#a = 1;
}
new A;
new B;
}
"
frame size: 7
parameter count: 1
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
bytecode array length: 131
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(PushContext), R(2),
B(LdaConstant), U8(2),
B(Star), R(4),
B(LdaConstant), U8(2),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1),
Reland x3 "[runtime] Remove extension slots from context objects" Original change's description: > [runtime] Remove extension slots from context objects > > Context objects have an extension slot, which contains further > additional data that depends on the type of the context. > > This CL removes the extension slot from contexts that don't need > them, hence reducing memory. > > The following contexts will still have an extension slot: native, > module, await, block and with contexts. See objects/contexts.h for > what the slot is used for. > The following contexts will not have an extension slot anymore (they > were not used before): script, catch and builtin contexts. > Eval and function contexts only have the extension slot if they > contain a sloppy eval. > > Bug: v8:9744 > Change-Id: I8ca56c22fa02437bbac392ea72174ebfca80e030 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1863191 > Commit-Queue: Victor Gomes <victorgomes@google.com> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Peter Marshall <petermarshall@chromium.org> > Auto-Submit: Victor Gomes <victorgomes@google.com> > Cr-Commit-Position: refs/heads/master@{#64372} TBR=verwaest@chromium.org,jgruber@chromium.org,ulan@chromium.org,leszeks@chromium.org,petermarshall@chromium.org Bug: v8:9744 Change-Id: I8700ed2fa62c89e86c39bb16ac3167f38ea8d63f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1873695 Commit-Queue: Victor Gomes <victorgomes@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#64477}
2019-10-22 12:59:24 +00:00
B(StaCurrentContextSlot), U8(2),
B(LdaTheHole),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(6),
B(CreateClosure), U8(3), U8(0), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(3),
B(LdaConstant), U8(1),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(CreateClosure), U8(4), U8(1), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(5),
B(StaNamedProperty), R(3), U8(5), U8(0),
B(PopContext), R(2),
B(Mov), R(3), R(0),
/* 38 E> */ B(CreateBlockContext), U8(6),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(PushContext), R(2),
B(LdaConstant), U8(2),
B(Star), R(4),
B(LdaConstant), U8(2),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(4), U8(1),
Reland x3 "[runtime] Remove extension slots from context objects" Original change's description: > [runtime] Remove extension slots from context objects > > Context objects have an extension slot, which contains further > additional data that depends on the type of the context. > > This CL removes the extension slot from contexts that don't need > them, hence reducing memory. > > The following contexts will still have an extension slot: native, > module, await, block and with contexts. See objects/contexts.h for > what the slot is used for. > The following contexts will not have an extension slot anymore (they > were not used before): script, catch and builtin contexts. > Eval and function contexts only have the extension slot if they > contain a sloppy eval. > > Bug: v8:9744 > Change-Id: I8ca56c22fa02437bbac392ea72174ebfca80e030 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1863191 > Commit-Queue: Victor Gomes <victorgomes@google.com> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Peter Marshall <petermarshall@chromium.org> > Auto-Submit: Victor Gomes <victorgomes@google.com> > Cr-Commit-Position: refs/heads/master@{#64372} TBR=verwaest@chromium.org,jgruber@chromium.org,ulan@chromium.org,leszeks@chromium.org,petermarshall@chromium.org Bug: v8:9744 Change-Id: I8700ed2fa62c89e86c39bb16ac3167f38ea8d63f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1873695 Commit-Queue: Victor Gomes <victorgomes@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#64477}
2019-10-22 12:59:24 +00:00
B(StaCurrentContextSlot), U8(2),
B(LdaTheHole),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(6),
B(CreateClosure), U8(8), U8(2), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(3),
B(LdaConstant), U8(7),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(CreateClosure), U8(9), U8(3), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(5),
B(StaNamedProperty), R(3), U8(5), U8(2),
B(PopContext), R(2),
B(Mov), R(3), R(1),
/* 136 S> */ B(Ldar), R(0),
/* 136 E> */ B(Construct), R(0), R(0), U8(0), U8(4),
/* 145 S> */ B(Ldar), R(1),
/* 145 E> */ B(Construct), R(1), R(0), U8(0), U8(6),
B(LdaUndefined),
/* 154 S> */ B(Return),
]
constant pool: [
SCOPE_INFO_TYPE,
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"],
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SYMBOL_TYPE,
SCOPE_INFO_TYPE,
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
]
handlers: [
]
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
---
snippet: "
{
class A extends class {} {
#a;
constructor() {
super();
this.#a = 1;
}
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
}
class B extends class {} {
#a = 1;
#b = this.#a;
foo() { return this.#a; }
bar(v) { this.#b = v; }
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
constructor() {
super();
this.foo();
this.bar(3);
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
}
}
class C extends B {
#a = 2;
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
constructor() {
(() => super())();
}
}
new A;
new B;
new C;
};
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
"
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
frame size: 12
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
parameter count: 1
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
bytecode array length: 268
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(PushContext), R(3),
B(LdaConstant), U8(2),
B(Star), R(5),
B(LdaConstant), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
Reland x3 "[runtime] Remove extension slots from context objects" Original change's description: > [runtime] Remove extension slots from context objects > > Context objects have an extension slot, which contains further > additional data that depends on the type of the context. > > This CL removes the extension slot from contexts that don't need > them, hence reducing memory. > > The following contexts will still have an extension slot: native, > module, await, block and with contexts. See objects/contexts.h for > what the slot is used for. > The following contexts will not have an extension slot anymore (they > were not used before): script, catch and builtin contexts. > Eval and function contexts only have the extension slot if they > contain a sloppy eval. > > Bug: v8:9744 > Change-Id: I8ca56c22fa02437bbac392ea72174ebfca80e030 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1863191 > Commit-Queue: Victor Gomes <victorgomes@google.com> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Peter Marshall <petermarshall@chromium.org> > Auto-Submit: Victor Gomes <victorgomes@google.com> > Cr-Commit-Position: refs/heads/master@{#64372} TBR=verwaest@chromium.org,jgruber@chromium.org,ulan@chromium.org,leszeks@chromium.org,petermarshall@chromium.org Bug: v8:9744 Change-Id: I8700ed2fa62c89e86c39bb16ac3167f38ea8d63f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1873695 Commit-Queue: Victor Gomes <victorgomes@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#64477}
2019-10-22 12:59:24 +00:00
B(StaCurrentContextSlot), U8(2),
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
B(LdaTheHole),
B(Star), R(11),
B(CreateClosure), U8(4), U8(0), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(8),
B(LdaConstant), U8(3),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(9),
B(Mov), R(8), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(9),
B(CreateClosure), U8(5), U8(1), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(4),
B(LdaConstant), U8(1),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(5),
B(Mov), R(4), R(6),
B(Mov), R(10), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3),
B(Star), R(5),
B(CreateClosure), U8(6), U8(2), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(6),
B(StaNamedProperty), R(4), U8(7), U8(0),
B(PopContext), R(3),
B(Mov), R(4), R(0),
/* 38 E> */ B(CreateBlockContext), U8(8),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(PushContext), R(3),
B(LdaConstant), U8(2),
B(Star), R(5),
B(LdaConstant), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
Reland x3 "[runtime] Remove extension slots from context objects" Original change's description: > [runtime] Remove extension slots from context objects > > Context objects have an extension slot, which contains further > additional data that depends on the type of the context. > > This CL removes the extension slot from contexts that don't need > them, hence reducing memory. > > The following contexts will still have an extension slot: native, > module, await, block and with contexts. See objects/contexts.h for > what the slot is used for. > The following contexts will not have an extension slot anymore (they > were not used before): script, catch and builtin contexts. > Eval and function contexts only have the extension slot if they > contain a sloppy eval. > > Bug: v8:9744 > Change-Id: I8ca56c22fa02437bbac392ea72174ebfca80e030 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1863191 > Commit-Queue: Victor Gomes <victorgomes@google.com> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Peter Marshall <petermarshall@chromium.org> > Auto-Submit: Victor Gomes <victorgomes@google.com> > Cr-Commit-Position: refs/heads/master@{#64372} TBR=verwaest@chromium.org,jgruber@chromium.org,ulan@chromium.org,leszeks@chromium.org,petermarshall@chromium.org Bug: v8:9744 Change-Id: I8700ed2fa62c89e86c39bb16ac3167f38ea8d63f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1873695 Commit-Queue: Victor Gomes <victorgomes@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#64477}
2019-10-22 12:59:24 +00:00
B(StaCurrentContextSlot), U8(2),
B(LdaConstant), U8(10),
B(Star), R(5),
B(LdaConstant), U8(10),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
Reland x3 "[runtime] Remove extension slots from context objects" Original change's description: > [runtime] Remove extension slots from context objects > > Context objects have an extension slot, which contains further > additional data that depends on the type of the context. > > This CL removes the extension slot from contexts that don't need > them, hence reducing memory. > > The following contexts will still have an extension slot: native, > module, await, block and with contexts. See objects/contexts.h for > what the slot is used for. > The following contexts will not have an extension slot anymore (they > were not used before): script, catch and builtin contexts. > Eval and function contexts only have the extension slot if they > contain a sloppy eval. > > Bug: v8:9744 > Change-Id: I8ca56c22fa02437bbac392ea72174ebfca80e030 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1863191 > Commit-Queue: Victor Gomes <victorgomes@google.com> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Peter Marshall <petermarshall@chromium.org> > Auto-Submit: Victor Gomes <victorgomes@google.com> > Cr-Commit-Position: refs/heads/master@{#64372} TBR=verwaest@chromium.org,jgruber@chromium.org,ulan@chromium.org,leszeks@chromium.org,petermarshall@chromium.org Bug: v8:9744 Change-Id: I8700ed2fa62c89e86c39bb16ac3167f38ea8d63f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1873695 Commit-Queue: Victor Gomes <victorgomes@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#64477}
2019-10-22 12:59:24 +00:00
B(StaCurrentContextSlot), U8(3),
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
B(LdaTheHole),
B(Star), R(11),
B(CreateClosure), U8(12), U8(3), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(8),
B(LdaConstant), U8(11),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(9),
B(Mov), R(8), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(9),
B(CreateClosure), U8(13), U8(4), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(4),
B(LdaConstant), U8(9),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(5),
B(CreateClosure), U8(14), U8(5), U8(2),
B(Star), R(8),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(CreateClosure), U8(15), U8(6), U8(2),
B(Star), R(9),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Mov), R(4), R(6),
B(Mov), R(10), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(5),
B(Star), R(5),
B(CreateClosure), U8(16), U8(7), U8(2),
B(Star), R(6),
B(StaNamedProperty), R(4), U8(7), U8(2),
B(PopContext), R(3),
B(Mov), R(4), R(1),
/* 140 E> */ B(CreateBlockContext), U8(17),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(PushContext), R(3),
B(LdaConstant), U8(2),
B(Star), R(5),
B(LdaConstant), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kCreatePrivateNameSymbol), R(5), U8(1),
Reland x3 "[runtime] Remove extension slots from context objects" Original change's description: > [runtime] Remove extension slots from context objects > > Context objects have an extension slot, which contains further > additional data that depends on the type of the context. > > This CL removes the extension slot from contexts that don't need > them, hence reducing memory. > > The following contexts will still have an extension slot: native, > module, await, block and with contexts. See objects/contexts.h for > what the slot is used for. > The following contexts will not have an extension slot anymore (they > were not used before): script, catch and builtin contexts. > Eval and function contexts only have the extension slot if they > contain a sloppy eval. > > Bug: v8:9744 > Change-Id: I8ca56c22fa02437bbac392ea72174ebfca80e030 > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1863191 > Commit-Queue: Victor Gomes <victorgomes@google.com> > Reviewed-by: Toon Verwaest <verwaest@chromium.org> > Reviewed-by: Jakob Gruber <jgruber@chromium.org> > Reviewed-by: Ulan Degenbaev <ulan@chromium.org> > Reviewed-by: Leszek Swirski <leszeks@chromium.org> > Reviewed-by: Peter Marshall <petermarshall@chromium.org> > Auto-Submit: Victor Gomes <victorgomes@google.com> > Cr-Commit-Position: refs/heads/master@{#64372} TBR=verwaest@chromium.org,jgruber@chromium.org,ulan@chromium.org,leszeks@chromium.org,petermarshall@chromium.org Bug: v8:9744 Change-Id: I8700ed2fa62c89e86c39bb16ac3167f38ea8d63f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1873695 Commit-Queue: Victor Gomes <victorgomes@chromium.org> Reviewed-by: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#64477}
2019-10-22 12:59:24 +00:00
B(StaCurrentContextSlot), U8(2),
/* 356 E> */ B(CreateClosure), U8(19), U8(8), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(4),
B(LdaConstant), U8(18),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(5),
B(Mov), R(4), R(6),
B(Mov), R(1), R(7),
B(CallRuntime), U16(Runtime::kDefineClass), R(5), U8(3),
B(Star), R(5),
B(CreateClosure), U8(20), U8(9), U8(2),
[class] implement static private methods This patch refactors the declaration and allocation of the class variable, and implements static private methods: - The class variable is declared in the class scope with an explicit reference through class_scope->class_variable(). Anonymous classes whose class variable may be accessed transitively through static private method access use the dot string as the class name. Whether the class variable is allocated depending on whether it is used. Other references of the class variable in the ClassLiteral AST node and the ClassInfo structure are removed in favor of the reference through the class scope. - Previously the class variable was always (stack- or context-) allocated if the class is named. Now if the class variable is only referenced by name, it's stack allocated. If it's used transitively by access to static private methods, or may be used through eval, it's context allocated. Therefore we now use 1 less context slots in the class context if it's a named class without anyone referencing it by name in inner scopes. - Explicit access to static private methods or potential access to static private methods through eval results in forced context allocation of the class variables. In those cases, we save its index in context locals in the ScopeInfo and deserialize it later, so that we can check that the receiver of static private methods is the class constructor at run time. This flag is recorded as HasSavedClassVariableIndexField in the scope info. - Classes that need the class variable to be saved due to access to static private methods now save a ShouldSaveClassVariableIndexField in the preparse data so that the bits on the variables can be updated during a reparse. In the case of anonymous classes that need the class variables to be saved, we also re-declare the class variable after the reparse since the inner functions are skipped and we need to rely on the preparse data flags to remember declaring it. Design doc: https://docs.google.com/document/d/1rgGRw5RdzaRrM-GrIMhsn-DLULtADV2dmIdh_iIZxlc/edit Bug: v8:8330 Change-Id: Idd07803f47614e97ad202de3b7faa9f71105eac5 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1781011 Commit-Queue: Joyee Cheung <joyee@igalia.com> Reviewed-by: Mythri Alle <mythria@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Cr-Commit-Position: refs/heads/master@{#64219}
2019-10-10 14:33:02 +00:00
B(Star), R(6),
B(StaNamedProperty), R(4), U8(7), U8(4),
B(PopContext), R(3),
B(Mov), R(4), R(2),
/* 430 S> */ B(Ldar), R(0),
/* 430 E> */ B(Construct), R(0), R(0), U8(0), U8(6),
/* 439 S> */ B(Ldar), R(1),
/* 439 E> */ B(Construct), R(1), R(0), U8(0), U8(8),
/* 448 S> */ B(Ldar), R(2),
/* 448 E> */ B(Construct), R(2), R(0), U8(0), U8(10),
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
B(LdaUndefined),
/* 458 S> */ B(Return),
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
]
constant pool: [
SCOPE_INFO_TYPE,
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#a"],
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SYMBOL_TYPE,
SCOPE_INFO_TYPE,
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
FIXED_ARRAY_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["#b"],
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SCOPE_INFO_TYPE,
[class] Store class fields initializer on the constructor Previously, the class fields initializer function was stored on a synthetic context allocated variable. This approach had sevaral problems: - We didn't know that class literal had fields until after we had completely parsed the class literal. This meant that we had to go back and fix up the scope of the constructor to have this synthetic variable. This resulted in mismatch between parser and preparsed scope data. - This synthetic variable could potentially resolve to an initializer of an outer class. For ex: class X extends Object { c = 1; constructor() { var t = () => { class P extends Object { constructor() { var t = () => { super(); }; t(); } } super(); } t(); } } In this the inner class P could access the outer class X's initiliazer function. We would have to maintain extra metadata to make sure this doesn't happen. Instead this new approach uses a private symbol to store the initializer function on the class constructor itself. For the base constructor case, we can simply check for a bit on the constructor function literal to see if we need to emit code that loads and calls this initializer function. Therefore, we don't pay the cost of loading this function in case there are no class fields. For the derived constructor case, there are two possiblities: (a) We are in a super() call directly in the derived constructor: In this case we can do a check similar to the base constructor check, we can check for a bit on the derived constructor and emit code for loading and calling the initializer function. This is usually the common case and we don't pay any cost for not using class fields. (b) We are in a super() call inside an arrow function in the derived constructor: In this case, we /always/ emit code to load and call the initializer function. If the function doesn't exist then we have undefined and we don't call anything. Otherwise we call the function. super() can't be called twice so even if we emit code to load and call the initializer function multiple times, it doesn't matter because it would have already been an error. Bug: v8:5367 Change-Id: I7f77cd6493ff84cf0e430a8c1039bc9ac6941a88 Reviewed-on: https://chromium-review.googlesource.com/781660 Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Cr-Commit-Position: refs/heads/master@{#49628}
2017-11-27 09:56:36 +00:00
FIXED_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE,
SHARED_FUNCTION_INFO_TYPE,
]
handlers: [
]