Commit 9f9550ef authored by Adam Klein's avatar Adam Klein Committed by Commit Bot

Simplify FunctionKind, saving 4 bits in SharedFunctionInfo

Since we only need to store 18 different function kinds,
the bitfield approach was wasting space (requiring 11 bits).

This patch replaces the bitfield with a regular enum, and
updates all the FunctionKind predicates to use comparisons
instead of bitwise ops.

For the small amount of builtin code that depended upon being
able to do masking to determine whether something is a class
constructor, we still store two extra bits on FunctionKind,
which are computed when the SFI is initialized.

If this approach causes performance regressions (i.e., if it
turns out that other code was implicitly depending on masking
for fast checks), we can revert this or address it in
other ways (e.g., by doing similar caching of repeated checks
in the caller).

This is a reland of 42667bab.

Bug: v8:7310
Change-Id: I2ec54289ea687399c61d75b7aff2d849861a64f2
Reviewed-on: https://chromium-review.googlesource.com/934864Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Commit-Queue: Adam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51534}
parent 063ac044
...@@ -291,7 +291,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -291,7 +291,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset)); __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(r4, Operand(SharedFunctionInfo::kDerivedConstructorMask)); __ tst(r4, Operand(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ b(ne, &not_create_implicit_receiver); __ b(ne, &not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object. // If not derived class constructor: Allocate the new receiver object.
...@@ -411,7 +411,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -411,7 +411,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ ldr(r4, MemOperand(fp, ConstructFrameConstants::kConstructorOffset)); __ ldr(r4, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ ldr(r4, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); __ ldr(r4, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset)); __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(r4, Operand(SharedFunctionInfo::kClassConstructorMask)); __ tst(r4, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) { if (restrict_constructor_return) {
// Throw if constructor function is a class constructor // Throw if constructor function is a class constructor
...@@ -1995,7 +1995,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -1995,7 +1995,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor; Label class_constructor;
__ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r3, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset)); __ ldr(r3, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(r3, Operand(SharedFunctionInfo::kClassConstructorMask)); __ tst(r3, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
__ b(ne, &class_constructor); __ b(ne, &class_constructor);
// Enter the context of the function; ToObject has to run in the function // Enter the context of the function; ToObject has to run in the function
......
...@@ -326,7 +326,8 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -326,7 +326,8 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); __ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(w4, FieldMemOperand(x4, SharedFunctionInfo::kCompilerHintsOffset)); __ Ldr(w4, FieldMemOperand(x4, SharedFunctionInfo::kCompilerHintsOffset));
__ TestAndBranchIfAnySet(w4, SharedFunctionInfo::kDerivedConstructorMask, __ TestAndBranchIfAnySet(w4,
SharedFunctionInfo::IsDerivedConstructorBit::kMask,
&not_create_implicit_receiver); &not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object. // If not derived class constructor: Allocate the new receiver object.
...@@ -454,11 +455,11 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -454,11 +455,11 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
if (restrict_constructor_return) { if (restrict_constructor_return) {
// Throw if constructor function is a class constructor // Throw if constructor function is a class constructor
__ TestAndBranchIfAllClear(w4, SharedFunctionInfo::kClassConstructorMask, __ TestAndBranchIfAllClear(
&use_receiver); w4, SharedFunctionInfo::IsClassConstructorBit::kMask, &use_receiver);
} else { } else {
__ TestAndBranchIfAnySet(w4, SharedFunctionInfo::kClassConstructorMask, __ TestAndBranchIfAnySet(
&use_receiver); w4, SharedFunctionInfo::IsClassConstructorBit::kMask, &use_receiver);
__ CallRuntime( __ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive); Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ B(&use_receiver); __ B(&use_receiver);
...@@ -2356,7 +2357,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2356,7 +2357,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor; Label class_constructor;
__ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); __ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset)); __ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset));
__ TestAndBranchIfAnySet(w3, SharedFunctionInfo::kClassConstructorMask, __ TestAndBranchIfAnySet(w3, SharedFunctionInfo::IsClassConstructorBit::kMask,
&class_constructor); &class_constructor);
// Enter the context of the function; ToObject has to run in the function // Enter the context of the function; ToObject has to run in the function
......
...@@ -218,7 +218,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -218,7 +218,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(ebx, SharedFunctionInfo::kCompilerHintsOffset), __ test(FieldOperand(ebx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kDerivedConstructorMask)); Immediate(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ j(not_zero, &not_create_implicit_receiver); __ j(not_zero, &not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object. // If not derived class constructor: Allocate the new receiver object.
...@@ -339,7 +339,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -339,7 +339,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ mov(ebx, Operand(ebp, ConstructFrameConstants::kConstructorOffset)); __ mov(ebx, Operand(ebp, ConstructFrameConstants::kConstructorOffset));
__ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset)); __ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(ebx, SharedFunctionInfo::kCompilerHintsOffset), __ test(FieldOperand(ebx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask)); Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) { if (restrict_constructor_return) {
// Throw if constructor function is a class constructor // Throw if constructor function is a class constructor
...@@ -2112,7 +2112,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2112,7 +2112,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor; Label class_constructor;
__ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(edx, SharedFunctionInfo::kCompilerHintsOffset), __ test(FieldOperand(edx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask)); Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
__ j(not_zero, &class_constructor); __ j(not_zero, &class_constructor);
// Enter the context of the function; ToObject has to run in the function // Enter the context of the function; ToObject has to run in the function
......
...@@ -281,7 +281,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -281,7 +281,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); __ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset)); __ lw(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kDerivedConstructorMask)); __ And(t2, t2, Operand(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ Branch(&not_create_implicit_receiver, ne, t2, Operand(zero_reg)); __ Branch(&not_create_implicit_receiver, ne, t2, Operand(zero_reg));
// If not derived class constructor: Allocate the new receiver object. // If not derived class constructor: Allocate the new receiver object.
...@@ -402,7 +402,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -402,7 +402,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ lw(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset)); __ lw(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); __ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset)); __ lw(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask)); __ And(t2, t2, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) { if (restrict_constructor_return) {
// Throw if constructor function is a class constructor // Throw if constructor function is a class constructor
...@@ -2003,7 +2003,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2003,7 +2003,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor; Label class_constructor;
__ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(a3, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset)); __ lw(a3, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(at, a3, Operand(SharedFunctionInfo::kClassConstructorMask)); __ And(at, a3, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
__ Branch(&class_constructor, ne, at, Operand(zero_reg)); __ Branch(&class_constructor, ne, at, Operand(zero_reg));
// Enter the context of the function; ToObject has to run in the function // Enter the context of the function; ToObject has to run in the function
......
...@@ -281,7 +281,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -281,7 +281,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); __ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset)); __ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kDerivedConstructorMask)); __ And(t2, t2, Operand(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ Branch(&not_create_implicit_receiver, ne, t2, Operand(zero_reg)); __ Branch(&not_create_implicit_receiver, ne, t2, Operand(zero_reg));
// If not derived class constructor: Allocate the new receiver object. // If not derived class constructor: Allocate the new receiver object.
...@@ -402,7 +402,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -402,7 +402,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ld(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset)); __ Ld(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); __ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset)); __ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask)); __ And(t2, t2, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) { if (restrict_constructor_return) {
// Throw if constructor function is a class constructor // Throw if constructor function is a class constructor
...@@ -2024,7 +2024,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2024,7 +2024,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor; Label class_constructor;
__ Ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); __ Ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ Lwu(a3, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset)); __ Lwu(a3, FieldMemOperand(a2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(at, a3, Operand(SharedFunctionInfo::kClassConstructorMask)); __ And(at, a3, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
__ Branch(&class_constructor, ne, at, Operand(zero_reg)); __ Branch(&class_constructor, ne, at, Operand(zero_reg));
// Enter the context of the function; ToObject has to run in the function // Enter the context of the function; ToObject has to run in the function
......
...@@ -293,7 +293,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -293,7 +293,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); __ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ lwz(r7, FieldMemOperand(r7, SharedFunctionInfo::kCompilerHintsOffset)); __ lwz(r7, FieldMemOperand(r7, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r7, SharedFunctionInfo::kDerivedConstructorMask, r0); __ TestBitMask(r7, SharedFunctionInfo::IsDerivedConstructorBit::kMask, r0);
__ bne(&not_create_implicit_receiver, cr0); __ bne(&not_create_implicit_receiver, cr0);
// If not derived class constructor: Allocate the new receiver object. // If not derived class constructor: Allocate the new receiver object.
...@@ -420,7 +420,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -420,7 +420,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ LoadP(r7, MemOperand(fp, ConstructFrameConstants::kConstructorOffset)); __ LoadP(r7, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ LoadP(r7, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset)); __ LoadP(r7, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset));
__ lwz(r7, FieldMemOperand(r7, SharedFunctionInfo::kCompilerHintsOffset)); __ lwz(r7, FieldMemOperand(r7, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r7, SharedFunctionInfo::kClassConstructorMask, r0); __ TestBitMask(r7, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ beq(&use_receiver, cr0); __ beq(&use_receiver, cr0);
} else { } else {
...@@ -2069,7 +2069,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2069,7 +2069,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor; Label class_constructor;
__ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); __ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ lwz(r6, FieldMemOperand(r5, SharedFunctionInfo::kCompilerHintsOffset)); __ lwz(r6, FieldMemOperand(r5, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r6, SharedFunctionInfo::kClassConstructorMask, r0); __ TestBitMask(r6, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ bne(&class_constructor, cr0); __ bne(&class_constructor, cr0);
// Enter the context of the function; ToObject has to run in the function // Enter the context of the function; ToObject has to run in the function
......
...@@ -288,7 +288,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -288,7 +288,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ LoadP(r6, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset)); __ LoadP(r6, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
__ LoadlW(r6, __ LoadlW(r6,
FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset)); FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r6, SharedFunctionInfo::kDerivedConstructorMask, r0); __ TestBitMask(r6, SharedFunctionInfo::IsDerivedConstructorBit::kMask, r0);
__ bne(&not_create_implicit_receiver); __ bne(&not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object. // If not derived class constructor: Allocate the new receiver object.
...@@ -414,7 +414,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -414,7 +414,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ LoadP(r6, FieldMemOperand(r6, JSFunction::kSharedFunctionInfoOffset)); __ LoadP(r6, FieldMemOperand(r6, JSFunction::kSharedFunctionInfoOffset));
__ LoadlW(r6, __ LoadlW(r6,
FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset)); FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r6, SharedFunctionInfo::kClassConstructorMask, r0); __ TestBitMask(r6, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ beq(&use_receiver); __ beq(&use_receiver);
} else { } else {
__ b(&use_receiver); __ b(&use_receiver);
...@@ -2066,7 +2066,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2066,7 +2066,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor; Label class_constructor;
__ LoadP(r4, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset)); __ LoadP(r4, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
__ LoadlW(r5, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset)); __ LoadlW(r5, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r5, SharedFunctionInfo::kClassConstructorMask, r0); __ TestBitMask(r5, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ bne(&class_constructor); __ bne(&class_constructor);
// Enter the context of the function; ToObject has to run in the function // Enter the context of the function; ToObject has to run in the function
......
...@@ -222,7 +222,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -222,7 +222,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ movp(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); __ movp(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rbx, SharedFunctionInfo::kCompilerHintsOffset), __ testl(FieldOperand(rbx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kDerivedConstructorMask)); Immediate(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ j(not_zero, &not_create_implicit_receiver, Label::kNear); __ j(not_zero, &not_create_implicit_receiver, Label::kNear);
// If not derived class constructor: Allocate the new receiver object. // If not derived class constructor: Allocate the new receiver object.
...@@ -342,7 +342,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm, ...@@ -342,7 +342,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ movp(rbx, Operand(rbp, ConstructFrameConstants::kConstructorOffset)); __ movp(rbx, Operand(rbp, ConstructFrameConstants::kConstructorOffset));
__ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset)); __ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rbx, SharedFunctionInfo::kCompilerHintsOffset), __ testl(FieldOperand(rbx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask)); Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) { if (restrict_constructor_return) {
// Throw if constructor function is a class constructor // Throw if constructor function is a class constructor
...@@ -2215,7 +2215,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm, ...@@ -2215,7 +2215,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor; Label class_constructor;
__ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); __ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rdx, SharedFunctionInfo::kCompilerHintsOffset), __ testl(FieldOperand(rdx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask)); Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
__ j(not_zero, &class_constructor); __ j(not_zero, &class_constructor);
// ----------- S t a t e ------------- // ----------- S t a t e -------------
......
...@@ -2504,7 +2504,6 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, ...@@ -2504,7 +2504,6 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
MaybeHandle<String> name, FunctionKind kind, Handle<Code> code, MaybeHandle<String> name, FunctionKind kind, Handle<Code> code,
Handle<ScopeInfo> scope_info) { Handle<ScopeInfo> scope_info) {
DCHECK(IsValidFunctionKind(kind));
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
NewSharedFunctionInfo(name, code, IsConstructable(kind), kind); NewSharedFunctionInfo(name, code, IsConstructable(kind), kind);
shared->set_scope_info(*scope_info); shared->set_scope_info(*scope_info);
......
...@@ -1026,83 +1026,55 @@ enum MaybeAssignedFlag : uint8_t { kNotAssigned, kMaybeAssigned }; ...@@ -1026,83 +1026,55 @@ enum MaybeAssignedFlag : uint8_t { kNotAssigned, kMaybeAssigned };
// Serialized in PreparseData, so numeric values should not be changed. // Serialized in PreparseData, so numeric values should not be changed.
enum ParseErrorType { kSyntaxError = 0, kReferenceError = 1 }; enum ParseErrorType { kSyntaxError = 0, kReferenceError = 1 };
enum FunctionKind : uint16_t { enum FunctionKind : uint8_t {
kNormalFunction = 0, kNormalFunction,
kArrowFunction = 1 << 0, kArrowFunction,
kGeneratorFunction = 1 << 1, kGeneratorFunction,
kConciseMethod = 1 << 2, kConciseMethod,
kDefaultConstructor = 1 << 3, kDerivedConstructor,
kDerivedConstructor = 1 << 4, kBaseConstructor,
kBaseConstructor = 1 << 5, kGetterFunction,
kGetterFunction = 1 << 6, kSetterFunction,
kSetterFunction = 1 << 7, kAsyncFunction,
kAsyncFunction = 1 << 8, kModule,
kModule = 1 << 9, kClassFieldsInitializerFunction,
kClassFieldsInitializerFunction = 1 << 10 | kConciseMethod,
kLastFunctionKind = kClassFieldsInitializerFunction, kDefaultBaseConstructor,
kDefaultDerivedConstructor,
kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod, kAsyncArrowFunction,
kAccessorFunction = kGetterFunction | kSetterFunction, kAsyncConciseMethod,
kDefaultBaseConstructor = kDefaultConstructor | kBaseConstructor,
kDefaultDerivedConstructor = kDefaultConstructor | kDerivedConstructor, kConciseGeneratorMethod,
kClassConstructor = kAsyncConciseGeneratorMethod,
kBaseConstructor | kDerivedConstructor | kDefaultConstructor, kAsyncGeneratorFunction,
kAsyncArrowFunction = kArrowFunction | kAsyncFunction, kLastFunctionKind = kAsyncGeneratorFunction,
kAsyncConciseMethod = kAsyncFunction | kConciseMethod,
// https://tc39.github.io/proposal-async-iteration/
kAsyncConciseGeneratorMethod = kAsyncFunction | kConciseGeneratorMethod,
kAsyncGeneratorFunction = kAsyncFunction | kGeneratorFunction
}; };
inline bool IsValidFunctionKind(FunctionKind kind) {
return kind == FunctionKind::kNormalFunction ||
kind == FunctionKind::kArrowFunction ||
kind == FunctionKind::kGeneratorFunction ||
kind == FunctionKind::kModule ||
kind == FunctionKind::kConciseMethod ||
kind == FunctionKind::kConciseGeneratorMethod ||
kind == FunctionKind::kGetterFunction ||
kind == FunctionKind::kSetterFunction ||
kind == FunctionKind::kAccessorFunction ||
kind == FunctionKind::kDefaultBaseConstructor ||
kind == FunctionKind::kDefaultDerivedConstructor ||
kind == FunctionKind::kBaseConstructor ||
kind == FunctionKind::kDerivedConstructor ||
kind == FunctionKind::kAsyncFunction ||
kind == FunctionKind::kAsyncArrowFunction ||
kind == FunctionKind::kAsyncConciseMethod ||
kind == FunctionKind::kAsyncConciseGeneratorMethod ||
kind == FunctionKind::kAsyncGeneratorFunction ||
kind == FunctionKind::kClassFieldsInitializerFunction;
}
inline bool IsArrowFunction(FunctionKind kind) { inline bool IsArrowFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kArrowFunction ||
return (kind & FunctionKind::kArrowFunction) != 0; kind == FunctionKind::kAsyncArrowFunction;
} }
inline bool IsModule(FunctionKind kind) {
inline bool IsGeneratorFunction(FunctionKind kind) { return kind == FunctionKind::kModule;
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kGeneratorFunction) != 0;
} }
inline bool IsModule(FunctionKind kind) { inline bool IsAsyncGeneratorFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kAsyncGeneratorFunction ||
return (kind & FunctionKind::kModule) != 0; kind == FunctionKind::kAsyncConciseGeneratorMethod;
} }
inline bool IsAsyncFunction(FunctionKind kind) { inline bool IsGeneratorFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kGeneratorFunction ||
return (kind & FunctionKind::kAsyncFunction) != 0; kind == FunctionKind::kConciseGeneratorMethod ||
IsAsyncGeneratorFunction(kind);
} }
inline bool IsAsyncGeneratorFunction(FunctionKind kind) { inline bool IsAsyncFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kAsyncFunction ||
const FunctionKind kMask = FunctionKind::kAsyncGeneratorFunction; kind == FunctionKind::kAsyncArrowFunction ||
return (kind & kMask) == kMask; kind == FunctionKind::kAsyncConciseMethod ||
IsAsyncGeneratorFunction(kind);
} }
inline bool IsResumableFunction(FunctionKind kind) { inline bool IsResumableFunction(FunctionKind kind) {
...@@ -1110,50 +1082,47 @@ inline bool IsResumableFunction(FunctionKind kind) { ...@@ -1110,50 +1082,47 @@ inline bool IsResumableFunction(FunctionKind kind) {
} }
inline bool IsConciseMethod(FunctionKind kind) { inline bool IsConciseMethod(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kConciseMethod ||
return (kind & FunctionKind::kConciseMethod) != 0; kind == FunctionKind::kConciseGeneratorMethod ||
kind == FunctionKind::kAsyncConciseMethod ||
kind == FunctionKind::kAsyncConciseGeneratorMethod ||
kind == FunctionKind::kClassFieldsInitializerFunction;
} }
inline bool IsGetterFunction(FunctionKind kind) { inline bool IsGetterFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kGetterFunction;
return (kind & FunctionKind::kGetterFunction) != 0;
} }
inline bool IsSetterFunction(FunctionKind kind) { inline bool IsSetterFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kSetterFunction;
return (kind & FunctionKind::kSetterFunction) != 0;
} }
inline bool IsAccessorFunction(FunctionKind kind) { inline bool IsAccessorFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kGetterFunction ||
return (kind & FunctionKind::kAccessorFunction) != 0; kind == FunctionKind::kSetterFunction;
} }
inline bool IsDefaultConstructor(FunctionKind kind) { inline bool IsDefaultConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kDefaultBaseConstructor ||
return (kind & FunctionKind::kDefaultConstructor) != 0; kind == FunctionKind::kDefaultDerivedConstructor;
} }
inline bool IsBaseConstructor(FunctionKind kind) { inline bool IsBaseConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kBaseConstructor ||
return (kind & FunctionKind::kBaseConstructor) != 0; kind == FunctionKind::kDefaultBaseConstructor;
} }
inline bool IsDerivedConstructor(FunctionKind kind) { inline bool IsDerivedConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return kind == FunctionKind::kDerivedConstructor ||
return (kind & FunctionKind::kDerivedConstructor) != 0; kind == FunctionKind::kDefaultDerivedConstructor;
} }
inline bool IsClassConstructor(FunctionKind kind) { inline bool IsClassConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind)); return IsBaseConstructor(kind) || IsDerivedConstructor(kind);
return (kind & FunctionKind::kClassConstructor) != 0;
} }
inline bool IsClassFieldsInitializerFunction(FunctionKind kind) { inline bool IsClassFieldsInitializerFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return kind == FunctionKind::kClassFieldsInitializerFunction; return kind == FunctionKind::kClassFieldsInitializerFunction;
} }
...@@ -1166,6 +1135,48 @@ inline bool IsConstructable(FunctionKind kind) { ...@@ -1166,6 +1135,48 @@ inline bool IsConstructable(FunctionKind kind) {
return true; return true;
} }
inline std::ostream& operator<<(std::ostream& os, FunctionKind kind) {
switch (kind) {
case FunctionKind::kNormalFunction:
return os << "NormalFunction";
case FunctionKind::kArrowFunction:
return os << "ArrowFunction";
case FunctionKind::kGeneratorFunction:
return os << "GeneratorFunction";
case FunctionKind::kConciseMethod:
return os << "ConciseMethod";
case FunctionKind::kDerivedConstructor:
return os << "DerivedConstructor";
case FunctionKind::kBaseConstructor:
return os << "BaseConstructor";
case FunctionKind::kGetterFunction:
return os << "GetterFunction";
case FunctionKind::kSetterFunction:
return os << "SetterFunction";
case FunctionKind::kAsyncFunction:
return os << "AsyncFunction";
case FunctionKind::kModule:
return os << "Module";
case FunctionKind::kClassFieldsInitializerFunction:
return os << "ClassFieldsInitializerFunction";
case FunctionKind::kDefaultBaseConstructor:
return os << "DefaultBaseConstructor";
case FunctionKind::kDefaultDerivedConstructor:
return os << "DefaultDerivedConstructor";
case FunctionKind::kAsyncArrowFunction:
return os << "AsyncArrowFunction";
case FunctionKind::kAsyncConciseMethod:
return os << "AsyncConciseMethod";
case FunctionKind::kConciseGeneratorMethod:
return os << "ConciseGeneratorMethod";
case FunctionKind::kAsyncConciseGeneratorMethod:
return os << "AsyncConciseGeneratorMethod";
case FunctionKind::kAsyncGeneratorFunction:
return os << "AsyncGeneratorFunction";
}
UNREACHABLE();
}
enum class InterpreterPushArgsMode : unsigned { enum class InterpreterPushArgsMode : unsigned {
kJSFunction, kJSFunction,
kWithFinalSpread, kWithFinalSpread,
......
...@@ -1074,36 +1074,6 @@ void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) { // NOLINT ...@@ -1074,36 +1074,6 @@ void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) { // NOLINT
JSObjectPrintBody(os, this); JSObjectPrintBody(os, this);
} }
namespace {
std::ostream& operator<<(std::ostream& os, FunctionKind kind) {
os << "[";
if (kind == FunctionKind::kNormalFunction) {
os << " NormalFunction";
} else {
#define PRINT_FLAG(name) \
if (static_cast<int>(kind) & static_cast<int>(FunctionKind::k##name)) { \
os << " " << #name; \
}
PRINT_FLAG(ArrowFunction)
PRINT_FLAG(GeneratorFunction)
PRINT_FLAG(ConciseMethod)
PRINT_FLAG(DefaultConstructor)
PRINT_FLAG(DerivedConstructor)
PRINT_FLAG(BaseConstructor)
PRINT_FLAG(GetterFunction)
PRINT_FLAG(SetterFunction)
PRINT_FLAG(AsyncFunction)
PRINT_FLAG(Module)
#undef PRINT_FLAG
}
return os << " ]";
}
} // namespace
void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT
JSObjectPrintHeader(os, this, "Function"); JSObjectPrintHeader(os, this, "Function");
os << "\n - function prototype: "; os << "\n - function prototype: ";
......
...@@ -304,7 +304,7 @@ class ScopeInfo : public FixedArray { ...@@ -304,7 +304,7 @@ class ScopeInfo : public FixedArray {
class HasSimpleParametersField class HasSimpleParametersField
: public BitField<bool, AsmModuleField::kNext, 1> {}; : public BitField<bool, AsmModuleField::kNext, 1> {};
class FunctionKindField class FunctionKindField
: public BitField<FunctionKind, HasSimpleParametersField::kNext, 11> {}; : public BitField<FunctionKind, HasSimpleParametersField::kNext, 5> {};
class HasOuterScopeInfoField class HasOuterScopeInfoField
: public BitField<bool, FunctionKindField::kNext, 1> {}; : public BitField<bool, FunctionKindField::kNext, 1> {};
class IsDebugEvaluateScopeField class IsDebugEvaluateScopeField
......
...@@ -125,9 +125,10 @@ FunctionKind SharedFunctionInfo::kind() const { ...@@ -125,9 +125,10 @@ FunctionKind SharedFunctionInfo::kind() const {
} }
void SharedFunctionInfo::set_kind(FunctionKind kind) { void SharedFunctionInfo::set_kind(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
int hints = compiler_hints(); int hints = compiler_hints();
hints = FunctionKindBits::update(hints, kind); hints = FunctionKindBits::update(hints, kind);
hints = IsClassConstructorBit::update(hints, IsClassConstructor(kind));
hints = IsDerivedConstructorBit::update(hints, IsDerivedConstructor(kind));
set_compiler_hints(hints); set_compiler_hints(hints);
UpdateFunctionMapIndex(); UpdateFunctionMapIndex();
} }
......
...@@ -469,7 +469,9 @@ class SharedFunctionInfo : public HeapObject { ...@@ -469,7 +469,9 @@ class SharedFunctionInfo : public HeapObject {
V(IsNativeBit, bool, 1, _) \ V(IsNativeBit, bool, 1, _) \
V(IsStrictBit, bool, 1, _) \ V(IsStrictBit, bool, 1, _) \
V(IsWrappedBit, bool, 1, _) \ V(IsWrappedBit, bool, 1, _) \
V(FunctionKindBits, FunctionKind, 11, _) \ V(IsClassConstructorBit, bool, 1, _) \
V(IsDerivedConstructorBit, bool, 1, _) \
V(FunctionKindBits, FunctionKind, 5, _) \
V(HasDuplicateParametersBit, bool, 1, _) \ V(HasDuplicateParametersBit, bool, 1, _) \
V(AllowLazyCompilationBit, bool, 1, _) \ V(AllowLazyCompilationBit, bool, 1, _) \
V(NeedsHomeObjectBit, bool, 1, _) \ V(NeedsHomeObjectBit, bool, 1, _) \
...@@ -487,12 +489,6 @@ class SharedFunctionInfo : public HeapObject { ...@@ -487,12 +489,6 @@ class SharedFunctionInfo : public HeapObject {
DisabledOptimizationReasonBits::kMax); DisabledOptimizationReasonBits::kMax);
STATIC_ASSERT(kLastFunctionKind <= FunctionKindBits::kMax); STATIC_ASSERT(kLastFunctionKind <= FunctionKindBits::kMax);
// Masks for checking if certain FunctionKind bits are set without fully
// decoding of the FunctionKind bit field.
static const int kClassConstructorMask = FunctionKind::kClassConstructor
<< FunctionKindBits::kShift;
static const int kDerivedConstructorMask = FunctionKind::kDerivedConstructor
<< FunctionKindBits::kShift;
// Bit positions in |debugger_hints|. // Bit positions in |debugger_hints|.
#define DEBUGGER_HINTS_BIT_FIELDS(V, _) \ #define DEBUGGER_HINTS_BIT_FIELDS(V, _) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment