Commit 7245d2c1 authored by Milad Fa's avatar Milad Fa Committed by V8 LUCI CQ

PPC/s390: Create Instance Type for Class Constructors

Port: 1cd7a582

Original Commit Message:

Class Constructors are special, because they are callable but [[Call]]
raises an exception. Instead of checking if a JS function is a class
constructor for every JS function call, this CL adds a new instance
type for class constructors.
This way we can use a fast instance type range check for the common
case, and only check for class constructors in the uncommon case were
a class constructor is called and when we need to raise an exception.

Change-Id: I578fde90d00d1e80cf36ba28205ce9bfe6830afb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3192422Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/main@{#77147}
parent 8679a4e1
......@@ -2047,14 +2047,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
// -----------------------------------
__ AssertFunction(r4);
// See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
// Check that the function is not a "classConstructor".
Label class_constructor;
__ LoadTaggedPointerField(
r5, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset), r0);
__ lwz(r6, FieldMemOperand(r5, SharedFunctionInfo::kFlagsOffset));
__ TestBitMask(r6, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ bne(&class_constructor, cr0);
// Enter the context of the function; ToObject has to run in the function
// context, and we also need to take the global proxy from the function
......@@ -2063,6 +2057,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
r0);
// We need to convert the receiver for non-native sloppy mode functions.
Label done_convert;
__ lwz(r6, FieldMemOperand(r5, SharedFunctionInfo::kFlagsOffset));
__ andi(r0, r6,
Operand(SharedFunctionInfo::IsStrictBit::kMask |
SharedFunctionInfo::IsNativeBit::kMask));
......@@ -2131,14 +2126,6 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ LoadU16(
r5, FieldMemOperand(r5, SharedFunctionInfo::kFormalParameterCountOffset));
__ InvokeFunctionCode(r4, no_reg, r5, r3, InvokeType::kJump);
// The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor);
{
FrameAndConstantPoolScope frame(masm, StackFrame::INTERNAL);
__ push(r4);
__ CallRuntime(Runtime::kThrowConstructorNonCallableError);
}
}
namespace {
......@@ -2245,12 +2232,11 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
// -- r4 : the target to call (can be any Object).
// -----------------------------------
Label non_callable, non_smi;
Label non_callable, class_constructor;
__ JumpIfSmi(r4, &non_callable);
__ bind(&non_smi);
__ LoadMap(r7, r4);
__ CompareInstanceTypeRange(r7, r8, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
__ CompareInstanceTypeRange(r7, r8, FIRST_CALLABLE_JS_FUNCTION_TYPE,
LAST_CALLABLE_JS_FUNCTION_TYPE);
__ Jump(masm->isolate()->builtins()->CallFunction(mode),
RelocInfo::CODE_TARGET, le);
__ cmpi(r8, Operand(JS_BOUND_FUNCTION_TYPE));
......@@ -2266,6 +2252,11 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
__ cmpi(r8, Operand(JS_PROXY_TYPE));
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET, eq);
// ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
// Check that the function is not a "classConstructor".
__ cmpi(r8, Operand(JS_CLASS_CONSTRUCTOR_TYPE));
__ beq(&class_constructor);
// 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception).
// Overwrite the original receiver the (original) target.
......@@ -2283,6 +2274,15 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
__ Push(r4);
__ CallRuntime(Runtime::kThrowCalledNonCallable);
}
// 4. The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r4);
__ CallRuntime(Runtime::kThrowConstructorNonCallableError);
__ Trap(); // Unreachable.
}
}
// static
......
......@@ -2091,14 +2091,8 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
// -----------------------------------
__ AssertFunction(r3);
// See ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
// Check that the function is not a "classConstructor".
Label class_constructor;
__ LoadTaggedPointerField(
r4, FieldMemOperand(r3, JSFunction::kSharedFunctionInfoOffset));
__ LoadU32(r5, FieldMemOperand(r4, SharedFunctionInfo::kFlagsOffset));
__ TestBitMask(r5, SharedFunctionInfo::IsClassConstructorBit::kMask, r0);
__ bne(&class_constructor);
// Enter the context of the function; ToObject has to run in the function
// context, and we also need to take the global proxy from the function
......@@ -2107,6 +2101,7 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
FieldMemOperand(r3, JSFunction::kContextOffset));
// We need to convert the receiver for non-native sloppy mode functions.
Label done_convert;
__ LoadU32(r5, FieldMemOperand(r4, SharedFunctionInfo::kFlagsOffset));
__ AndP(r0, r5,
Operand(SharedFunctionInfo::IsStrictBit::kMask |
SharedFunctionInfo::IsNativeBit::kMask));
......@@ -2175,14 +2170,6 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
__ LoadU16(
r4, FieldMemOperand(r4, SharedFunctionInfo::kFormalParameterCountOffset));
__ InvokeFunctionCode(r3, no_reg, r4, r2, InvokeType::kJump);
// The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor);
{
FrameAndConstantPoolScope frame(masm, StackFrame::INTERNAL);
__ push(r3);
__ CallRuntime(Runtime::kThrowConstructorNonCallableError);
}
}
namespace {
......@@ -2287,12 +2274,11 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
// -- r3 : the target to call (can be any Object).
// -----------------------------------
Label non_callable, non_smi;
Label non_callable, class_constructor;
__ JumpIfSmi(r3, &non_callable);
__ bind(&non_smi);
__ LoadMap(r6, r3);
__ CompareInstanceTypeRange(r6, r7, FIRST_JS_FUNCTION_TYPE,
LAST_JS_FUNCTION_TYPE);
__ CompareInstanceTypeRange(r6, r7, FIRST_CALLABLE_JS_FUNCTION_TYPE,
LAST_CALLABLE_JS_FUNCTION_TYPE);
__ Jump(masm->isolate()->builtins()->CallFunction(mode),
RelocInfo::CODE_TARGET, le);
__ CmpS64(r7, Operand(JS_BOUND_FUNCTION_TYPE));
......@@ -2308,6 +2294,11 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
__ CmpS64(r7, Operand(JS_PROXY_TYPE));
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET, eq);
// ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList)
// Check that the function is not a "classConstructor".
__ CmpS64(r7, Operand(JS_CLASS_CONSTRUCTOR_TYPE));
__ beq(&class_constructor);
// 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception).
// Overwrite the original receiver the (original) target.
......@@ -2324,6 +2315,16 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r3);
__ CallRuntime(Runtime::kThrowCalledNonCallable);
__ Trap(); // Unreachable.
}
// 4. The function is a "classConstructor", need to raise an exception.
__ bind(&class_constructor);
{
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r3);
__ CallRuntime(Runtime::kThrowConstructorNonCallableError);
__ Trap(); // Unreachable.
}
}
......
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