Commit bb7138f6 authored by Michael Achenbach's avatar Michael Achenbach Committed by Commit Bot

Revert "Simplify FunctionKind, saving 4 bits in SharedFunctionInfo"

This reverts commit 42667bab.

Reason for revert: Breaks msvc compile:
https://build.chromium.org/p/client.v8/builders/V8%20Win64%20-%20msvc/builds/908

Original change's description:
> 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).
> 
> Change-Id: Iebb3214f564ea8bd7b21e78fda33517d63247124
> Reviewed-on: https://chromium-review.googlesource.com/860896
> Commit-Queue: Adam Klein <adamk@chromium.org>
> Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#50559}

TBR=adamk@chromium.org,gsathya@chromium.org

Change-Id: I8e1faa0ca6213d1e70a00fcb417b1bfa35ebd643
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/866310Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50561}
parent 292ef57c
......@@ -297,7 +297,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(r4, Operand(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ tst(r4, Operand(SharedFunctionInfo::kDerivedConstructorMask));
__ b(ne, &not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object.
......@@ -417,7 +417,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::IsClassConstructorBit::kMask));
__ tst(r4, Operand(SharedFunctionInfo::kClassConstructorMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -1978,7 +1978,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::IsClassConstructorBit::kMask));
__ tst(r3, Operand(SharedFunctionInfo::kClassConstructorMask));
__ b(ne, &class_constructor);
// Enter the context of the function; ToObject has to run in the function
......
......@@ -332,8 +332,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(w4, FieldMemOperand(x4, SharedFunctionInfo::kCompilerHintsOffset));
__ TestAndBranchIfAnySet(w4,
SharedFunctionInfo::IsDerivedConstructorBit::kMask,
__ TestAndBranchIfAnySet(w4, SharedFunctionInfo::kDerivedConstructorMask,
&not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object.
......@@ -461,11 +460,11 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ TestAndBranchIfAllClear(
w4, SharedFunctionInfo::IsClassConstructorBit::kMask, &use_receiver);
__ TestAndBranchIfAllClear(w4, SharedFunctionInfo::kClassConstructorMask,
&use_receiver);
} else {
__ TestAndBranchIfAnySet(
w4, SharedFunctionInfo::IsClassConstructorBit::kMask, &use_receiver);
__ TestAndBranchIfAnySet(w4, SharedFunctionInfo::kClassConstructorMask,
&use_receiver);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ B(&use_receiver);
......@@ -2343,7 +2342,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::IsClassConstructorBit::kMask,
__ TestAndBranchIfAnySet(w3, SharedFunctionInfo::kClassConstructorMask,
&class_constructor);
// Enter the context of the function; ToObject has to run in the function
......
......@@ -224,7 +224,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(ebx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
Immediate(SharedFunctionInfo::kDerivedConstructorMask));
__ j(not_zero, &not_create_implicit_receiver);
// If not derived class constructor: Allocate the new receiver object.
......@@ -345,7 +345,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::IsClassConstructorBit::kMask));
Immediate(SharedFunctionInfo::kClassConstructorMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -2093,7 +2093,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(edx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
Immediate(SharedFunctionInfo::kClassConstructorMask));
__ j(not_zero, &class_constructor);
// Enter the context of the function; ToObject has to run in the function
......
......@@ -285,7 +285,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ And(t2, t2, Operand(SharedFunctionInfo::kDerivedConstructorMask));
__ Branch(&not_create_implicit_receiver, ne, t2, Operand(zero_reg));
// If not derived class constructor: Allocate the new receiver object.
......@@ -406,7 +406,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::IsClassConstructorBit::kMask));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -1984,7 +1984,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::IsClassConstructorBit::kMask));
__ And(at, a3, Operand(SharedFunctionInfo::kClassConstructorMask));
__ Branch(&class_constructor, ne, at, Operand(zero_reg));
// Enter the context of the function; ToObject has to run in the function
......
......@@ -287,7 +287,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
__ And(t2, t2, Operand(SharedFunctionInfo::kDerivedConstructorMask));
__ Branch(&not_create_implicit_receiver, ne, t2, Operand(zero_reg));
// If not derived class constructor: Allocate the new receiver object.
......@@ -408,7 +408,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::IsClassConstructorBit::kMask));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -2008,7 +2008,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::IsClassConstructorBit::kMask));
__ And(at, a3, Operand(SharedFunctionInfo::kClassConstructorMask));
__ 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::IsDerivedConstructorBit::kMask, r0);
__ TestBitMask(r7, SharedFunctionInfo::kDerivedConstructorMask, 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::IsClassConstructorBit::kMask, r0);
__ TestBitMask(r7, SharedFunctionInfo::kClassConstructorMask, r0);
__ beq(&use_receiver, cr0);
} else {
......@@ -2051,7 +2051,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::IsClassConstructorBit::kMask, r0);
__ TestBitMask(r6, SharedFunctionInfo::kClassConstructorMask, 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::IsDerivedConstructorBit::kMask, r0);
__ TestBitMask(r6, SharedFunctionInfo::kDerivedConstructorMask, 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::IsClassConstructorBit::kMask, r0);
__ TestBitMask(r6, SharedFunctionInfo::kClassConstructorMask, r0);
__ beq(&use_receiver);
} else {
__ b(&use_receiver);
......@@ -2048,7 +2048,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::IsClassConstructorBit::kMask, r0);
__ TestBitMask(r5, SharedFunctionInfo::kClassConstructorMask, r0);
__ bne(&class_constructor);
// Enter the context of the function; ToObject has to run in the function
......
......@@ -230,7 +230,7 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ movp(rbx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rbx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::IsDerivedConstructorBit::kMask));
Immediate(SharedFunctionInfo::kDerivedConstructorMask));
__ j(not_zero, &not_create_implicit_receiver, Label::kNear);
// If not derived class constructor: Allocate the new receiver object.
......@@ -350,7 +350,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::IsClassConstructorBit::kMask));
Immediate(SharedFunctionInfo::kClassConstructorMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
......@@ -2196,7 +2196,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
Label class_constructor;
__ movp(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rdx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::IsClassConstructorBit::kMask));
Immediate(SharedFunctionInfo::kClassConstructorMask));
__ j(not_zero, &class_constructor);
// ----------- S t a t e -------------
......
......@@ -2453,6 +2453,7 @@ 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);
......
......@@ -1083,55 +1083,83 @@ enum MinusZeroMode {
enum Signedness { kSigned, kUnsigned };
enum FunctionKind : uint8_t {
kNormalFunction,
kArrowFunction,
kGeneratorFunction,
kConciseMethod,
kDerivedConstructor,
kBaseConstructor,
kGetterFunction,
kSetterFunction,
kAsyncFunction,
kModule,
kClassFieldsInitializerFunction,
kDefaultBaseConstructor,
kDefaultDerivedConstructor,
kAsyncArrowFunction,
kAsyncConciseMethod,
kConciseGeneratorMethod,
kAsyncConciseGeneratorMethod,
kAsyncGeneratorFunction,
kLastFunctionKind,
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
};
inline bool IsArrowFunction(FunctionKind kind) {
return kind == FunctionKind::kArrowFunction ||
kind == FunctionKind::kAsyncArrowFunction;
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 IsModule(FunctionKind kind) {
return kind == FunctionKind::kModule;
}
inline bool IsAsyncGeneratorFunction(FunctionKind kind) {
return kind == FunctionKind::kAsyncGeneratorFunction ||
kind == FunctionKind::kAsyncConciseGeneratorMethod;
inline bool IsArrowFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kArrowFunction) != 0;
}
inline bool IsGeneratorFunction(FunctionKind kind) {
return kind == FunctionKind::kGeneratorFunction ||
kind == FunctionKind::kConciseGeneratorMethod ||
IsAsyncGeneratorFunction(kind);
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kGeneratorFunction) != 0;
}
inline bool IsModule(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kModule) != 0;
}
inline bool IsAsyncFunction(FunctionKind kind) {
return kind == FunctionKind::kAsyncFunction ||
kind == FunctionKind::kAsyncArrowFunction ||
kind == FunctionKind::kAsyncConciseMethod ||
IsAsyncGeneratorFunction(kind);
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kAsyncFunction) != 0;
}
inline bool IsAsyncGeneratorFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
const FunctionKind kMask = FunctionKind::kAsyncGeneratorFunction;
return (kind & kMask) == kMask;
}
inline bool IsResumableFunction(FunctionKind kind) {
......@@ -1139,47 +1167,50 @@ inline bool IsResumableFunction(FunctionKind kind) {
}
inline bool IsConciseMethod(FunctionKind kind) {
return kind == FunctionKind::kConciseMethod ||
kind == FunctionKind::kConciseGeneratorMethod ||
kind == FunctionKind::kAsyncConciseMethod ||
kind == FunctionKind::kAsyncConciseGeneratorMethod ||
kind == FunctionKind::kClassFieldsInitializerFunction;
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kConciseMethod) != 0;
}
inline bool IsGetterFunction(FunctionKind kind) {
return kind == FunctionKind::kGetterFunction;
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kGetterFunction) != 0;
}
inline bool IsSetterFunction(FunctionKind kind) {
return kind == FunctionKind::kSetterFunction;
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kSetterFunction) != 0;
}
inline bool IsAccessorFunction(FunctionKind kind) {
return kind == FunctionKind::kGetterFunction ||
kind == FunctionKind::kSetterFunction;
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kAccessorFunction) != 0;
}
inline bool IsDefaultConstructor(FunctionKind kind) {
return kind == FunctionKind::kDefaultBaseConstructor ||
kind == FunctionKind::kDefaultDerivedConstructor;
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kDefaultConstructor) != 0;
}
inline bool IsBaseConstructor(FunctionKind kind) {
return kind == FunctionKind::kBaseConstructor ||
kind == FunctionKind::kDefaultBaseConstructor;
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kBaseConstructor) != 0;
}
inline bool IsDerivedConstructor(FunctionKind kind) {
return kind == FunctionKind::kDerivedConstructor ||
kind == FunctionKind::kDefaultDerivedConstructor;
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kDerivedConstructor) != 0;
}
inline bool IsClassConstructor(FunctionKind kind) {
return IsBaseConstructor(kind) || IsDerivedConstructor(kind);
DCHECK(IsValidFunctionKind(kind));
return (kind & FunctionKind::kClassConstructor) != 0;
}
inline bool IsClassFieldsInitializerFunction(FunctionKind kind) {
DCHECK(IsValidFunctionKind(kind));
return kind == FunctionKind::kClassFieldsInitializerFunction;
}
......@@ -1192,50 +1223,6 @@ 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";
case FunctionKind::kLastFunctionKind:
UNREACHABLE();
}
UNREACHABLE();
}
enum class InterpreterPushArgsMode : unsigned {
kJSFunction,
kWithFinalSpread,
......
......@@ -1073,6 +1073,36 @@ 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 = ";
......
......@@ -127,10 +127,9 @@ 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,9 +469,7 @@ class SharedFunctionInfo : public HeapObject {
V(IsNativeBit, bool, 1, _) \
V(IsStrictBit, bool, 1, _) \
V(IsWrappedBit, bool, 1, _) \
V(IsClassConstructorBit, bool, 1, _) \
V(IsDerivedConstructorBit, bool, 1, _) \
V(FunctionKindBits, FunctionKind, 5, _) \
V(FunctionKindBits, FunctionKind, 11, _) \
V(HasDuplicateParametersBit, bool, 1, _) \
V(AllowLazyCompilationBit, bool, 1, _) \
V(NeedsHomeObjectBit, bool, 1, _) \
......@@ -489,6 +487,12 @@ 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