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,
__ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(r4, Operand(SharedFunctionInfo::kDerivedConstructorMask));
__ tst(r4, Operand(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ b(ne, &not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object.
......@@ -411,7 +411,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ ldr(r4, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ ldr(r4, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(r4, Operand(SharedFunctionInfo::kClassConstructorMask));
__ tst(r4, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -1995,7 +1995,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r3, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(r3, Operand(SharedFunctionInfo::kClassConstructorMask));
__ tst(r3, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
__ b(ne, &class_constructor);
// Enter the context of the function; ToObject has to run in the function
......
......@@ -326,7 +326,8 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(w4, FieldMemOperand(x4, SharedFunctionInfo::kCompilerHintsOffset));
__ TestAndBranchIfAnySet(w4, SharedFunctionInfo::kDerivedConstructorMask,
__ TestAndBranchIfAnySet(w4,
SharedFunctionInfo::IsDerivedConstructorBit::kMask,
&not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object.
......@@ -454,11 +455,11 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ TestAndBranchIfAllClear(w4, SharedFunctionInfo::kClassConstructorMask,
&use_receiver);
__ TestAndBranchIfAllClear(
w4, SharedFunctionInfo::IsClassConstructorBit::kMask, &use_receiver);
} else {
__ TestAndBranchIfAnySet(w4, SharedFunctionInfo::kClassConstructorMask,
&use_receiver);
__ TestAndBranchIfAnySet(
w4, SharedFunctionInfo::IsClassConstructorBit::kMask, &use_receiver);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ B(&use_receiver);
......@@ -2356,7 +2357,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ Ldr(x2, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(w3, FieldMemOperand(x2, SharedFunctionInfo::kCompilerHintsOffset));
__ TestAndBranchIfAnySet(w3, SharedFunctionInfo::kClassConstructorMask,
__ TestAndBranchIfAnySet(w3, SharedFunctionInfo::IsClassConstructorBit::kMask,
&class_constructor);
// Enter the context of the function; ToObject has to run in the function
......
......@@ -218,7 +218,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(ebx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kDerivedConstructorMask));
Immediate(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ j(not_zero, &not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object.
......@@ -339,7 +339,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ mov(ebx, Operand(ebp, ConstructFrameConstants::kConstructorOffset));
__ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(ebx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask));
Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -2112,7 +2112,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(edx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask));
Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
__ j(not_zero, &class_constructor);
// Enter the context of the function; ToObject has to run in the function
......
......@@ -281,7 +281,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ 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));
// If not derived class constructor: Allocate the new receiver object.
......@@ -402,7 +402,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ lw(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask));
__ And(t2, t2, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -2003,7 +2003,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ 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));
// Enter the context of the function; ToObject has to run in the function
......
......@@ -281,7 +281,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ 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));
// If not derived class constructor: Allocate the new receiver object.
......@@ -402,7 +402,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ld(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask));
__ And(t2, t2, Operand(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -2024,7 +2024,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ Ld(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ 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));
// Enter the context of the function; ToObject has to run in the function
......
......@@ -293,7 +293,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ LoadP(r7, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ lwz(r7, FieldMemOperand(r7, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r7, SharedFunctionInfo::kDerivedConstructorMask, r0);
__ TestBitMask(r7, SharedFunctionInfo::IsDerivedConstructorBit::kMask, r0);
__ bne(&not_create_implicit_receiver, cr0);
// If not derived class constructor: Allocate the new receiver object.
......@@ -420,7 +420,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ LoadP(r7, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ LoadP(r7, FieldMemOperand(r7, JSFunction::kSharedFunctionInfoOffset));
__ lwz(r7, FieldMemOperand(r7, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r7, SharedFunctionInfo::kClassConstructorMask, r0);
__ TestBitMask(r7, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ beq(&use_receiver, cr0);
} else {
......@@ -2069,7 +2069,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ LoadP(r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ lwz(r6, FieldMemOperand(r5, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r6, SharedFunctionInfo::kClassConstructorMask, r0);
__ TestBitMask(r6, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ bne(&class_constructor, cr0);
// Enter the context of the function; ToObject has to run in the function
......
......@@ -288,7 +288,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ LoadP(r6, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
__ LoadlW(r6,
FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r6, SharedFunctionInfo::kDerivedConstructorMask, r0);
__ TestBitMask(r6, SharedFunctionInfo::IsDerivedConstructorBit::kMask, r0);
__ bne(&not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object.
......@@ -414,7 +414,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ LoadP(r6, FieldMemOperand(r6, JSFunction::kSharedFunctionInfoOffset));
__ LoadlW(r6,
FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r6, SharedFunctionInfo::kClassConstructorMask, r0);
__ TestBitMask(r6, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ beq(&use_receiver);
} else {
__ b(&use_receiver);
......@@ -2066,7 +2066,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ LoadP(r4, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
__ LoadlW(r5, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r5, SharedFunctionInfo::kClassConstructorMask, r0);
__ TestBitMask(r5, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ bne(&class_constructor);
// Enter the context of the function; ToObject has to run in the function
......
......@@ -222,7 +222,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ movp(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rbx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kDerivedConstructorMask));
Immediate(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ j(not_zero, &not_create_implicit_receiver, Label::kNear);
// If not derived class constructor: Allocate the new receiver object.
......@@ -342,7 +342,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ movp(rbx, Operand(rbp, ConstructFrameConstants::kConstructorOffset));
__ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rbx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask));
Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -2215,7 +2215,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rdx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask));
Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
__ j(not_zero, &class_constructor);
// ----------- S t a t e -------------
......
......@@ -2504,7 +2504,6 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
MaybeHandle<String> name, FunctionKind kind, Handle<Code> code,
Handle<ScopeInfo> scope_info) {
DCHECK(IsValidFunctionKind(kind));
Handle<SharedFunctionInfo> shared =
NewSharedFunctionInfo(name, code, IsConstructable(kind), kind);
shared->set_scope_info(*scope_info);
......
......@@ -1026,83 +1026,55 @@ enum MaybeAssignedFlag : uint8_t { kNotAssigned, kMaybeAssigned };
// Serialized in PreparseData, so numeric values should not be changed.
enum ParseErrorType { kSyntaxError = 0, kReferenceError = 1 };
enum FunctionKind : uint16_t {
kNormalFunction = 0,
kArrowFunction = 1 << 0,
kGeneratorFunction = 1 << 1,
kConciseMethod = 1 << 2,
kDefaultConstructor = 1 << 3,
kDerivedConstructor = 1 << 4,
kBaseConstructor = 1 << 5,
kGetterFunction = 1 << 6,
kSetterFunction = 1 << 7,
kAsyncFunction = 1 << 8,
kModule = 1 << 9,
kClassFieldsInitializerFunction = 1 << 10 | kConciseMethod,
kLastFunctionKind = kClassFieldsInitializerFunction,
kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod,
kAccessorFunction = kGetterFunction | kSetterFunction,
kDefaultBaseConstructor = kDefaultConstructor | kBaseConstructor,
kDefaultDerivedConstructor = kDefaultConstructor | kDerivedConstructor,
kClassConstructor =
kBaseConstructor | kDerivedConstructor | kDefaultConstructor,
kAsyncArrowFunction = kArrowFunction | kAsyncFunction,
kAsyncConciseMethod = kAsyncFunction | kConciseMethod,
// https://tc39.github.io/proposal-async-iteration/
kAsyncConciseGeneratorMethod = kAsyncFunction | kConciseGeneratorMethod,
kAsyncGeneratorFunction = kAsyncFunction | kGeneratorFunction
enum FunctionKind : uint8_t {
kNormalFunction,
kArrowFunction,
kGeneratorFunction,
kConciseMethod,
kDerivedConstructor,
kBaseConstructor,
kGetterFunction,
kSetterFunction,
kAsyncFunction,
kModule,
kClassFieldsInitializerFunction,
kDefaultBaseConstructor,
kDefaultDerivedConstructor,
kAsyncArrowFunction,
kAsyncConciseMethod,
kConciseGeneratorMethod,
kAsyncConciseGeneratorMethod,
kAsyncGeneratorFunction,
kLastFunctionKind = kAsyncGeneratorFunction,
};
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) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kArrowFunction) != 0;
return kind == FunctionKind::kArrowFunction ||
kind == FunctionKind::kAsyncArrowFunction;
}
inline bool IsGeneratorFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kGeneratorFunction) != 0;
inline bool IsModule(FunctionKind kind) {
return kind == FunctionKind::kModule;
}
inline bool IsModule(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kModule) != 0;
inline bool IsAsyncGeneratorFunction(FunctionKind kind) {
return kind == FunctionKind::kAsyncGeneratorFunction ||
kind == FunctionKind::kAsyncConciseGeneratorMethod;
}
inline bool IsAsyncFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kAsyncFunction) != 0;
inline bool IsGeneratorFunction(FunctionKind kind) {
return kind == FunctionKind::kGeneratorFunction ||
kind == FunctionKind::kConciseGeneratorMethod ||
IsAsyncGeneratorFunction(kind);
}
inline bool IsAsyncGeneratorFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
const FunctionKind kMask = FunctionKind::kAsyncGeneratorFunction;
return (kind & kMask) == kMask;
inline bool IsAsyncFunction(FunctionKind kind) {
return kind == FunctionKind::kAsyncFunction ||
kind == FunctionKind::kAsyncArrowFunction ||
kind == FunctionKind::kAsyncConciseMethod ||
IsAsyncGeneratorFunction(kind);
}
inline bool IsResumableFunction(FunctionKind kind) {
......@@ -1110,50 +1082,47 @@ inline bool IsResumableFunction(FunctionKind kind) {
}
inline bool IsConciseMethod(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kConciseMethod) != 0;
return kind == FunctionKind::kConciseMethod ||
kind == FunctionKind::kConciseGeneratorMethod ||
kind == FunctionKind::kAsyncConciseMethod ||
kind == FunctionKind::kAsyncConciseGeneratorMethod ||
kind == FunctionKind::kClassFieldsInitializerFunction;
}
inline bool IsGetterFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kGetterFunction) != 0;
return kind == FunctionKind::kGetterFunction;
}
inline bool IsSetterFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kSetterFunction) != 0;
return kind == FunctionKind::kSetterFunction;
}
inline bool IsAccessorFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kAccessorFunction) != 0;
return kind == FunctionKind::kGetterFunction ||
kind == FunctionKind::kSetterFunction;
}
inline bool IsDefaultConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kDefaultConstructor) != 0;
return kind == FunctionKind::kDefaultBaseConstructor ||
kind == FunctionKind::kDefaultDerivedConstructor;
}
inline bool IsBaseConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kBaseConstructor) != 0;
return kind == FunctionKind::kBaseConstructor ||
kind == FunctionKind::kDefaultBaseConstructor;
}
inline bool IsDerivedConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kDerivedConstructor) != 0;
return kind == FunctionKind::kDerivedConstructor ||
kind == FunctionKind::kDefaultDerivedConstructor;
}
inline bool IsClassConstructor(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kClassConstructor) != 0;
return IsBaseConstructor(kind) || IsDerivedConstructor(kind);
}
inline bool IsClassFieldsInitializerFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return kind == FunctionKind::kClassFieldsInitializerFunction;
}
......@@ -1166,6 +1135,48 @@ inline bool IsConstructable(FunctionKind kind) {
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 {
kJSFunction,
kWithFinalSpread,
......
......@@ -1074,36 +1074,6 @@ void JSBoundFunction::JSBoundFunctionPrint(std::ostream& os) { // NOLINT
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
JSObjectPrintHeader(os, this, "Function");
os << "\n - function prototype: ";
......
......@@ -304,7 +304,7 @@ class ScopeInfo : public FixedArray {
class HasSimpleParametersField
: public BitField<bool, AsmModuleField::kNext, 1> {};
class FunctionKindField
: public BitField<FunctionKind, HasSimpleParametersField::kNext, 11> {};
: public BitField<FunctionKind, HasSimpleParametersField::kNext, 5> {};
class HasOuterScopeInfoField
: public BitField<bool, FunctionKindField::kNext, 1> {};
class IsDebugEvaluateScopeField
......
......@@ -125,9 +125,10 @@ FunctionKind SharedFunctionInfo::kind() const {
}
void SharedFunctionInfo::set_kind(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
int hints = compiler_hints();
hints = FunctionKindBits::update(hints, kind);
hints = IsClassConstructorBit::update(hints, IsClassConstructor(kind));
hints = IsDerivedConstructorBit::update(hints, IsDerivedConstructor(kind));
set_compiler_hints(hints);
UpdateFunctionMapIndex();
}
......
......@@ -469,7 +469,9 @@ class SharedFunctionInfo : public HeapObject {
V(IsNativeBit, bool, 1, _) \
V(IsStrictBit, 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(AllowLazyCompilationBit, bool, 1, _) \
V(NeedsHomeObjectBit, bool, 1, _) \
......@@ -487,12 +489,6 @@ class SharedFunctionInfo : public HeapObject {
DisabledOptimizationReasonBits::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|.
#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