Commit 28bc6998 authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[ESnext] Add use counter for non undefined primitive returning constructor

Bug: v8:5536
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng
Change-Id: Icec1f77c6073e1e89210e71ad20044e09594209e
Reviewed-on: https://chromium-review.googlesource.com/548987Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46451}
parent 8e17c151
......@@ -6894,6 +6894,7 @@ class V8_EXPORT Isolate {
kAssigmentExpressionLHSIsCallInSloppy = 36,
kAssigmentExpressionLHSIsCallInStrict = 37,
kPromiseConstructorReturnedUndefined = 38,
kConstructorNonUndefinedPrimitiveReturn = 39,
// If you add new values here, you'll also need to update Chromium's:
// UseCounter.h, V8PerIsolateData.cpp, histograms.xml
......
......@@ -642,17 +642,20 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ CompareObjectType(r0, r4, r5, FIRST_JS_RECEIVER_TYPE);
__ b(ge, &leave_frame);
__ bind(&other_result);
// The result is now neither undefined nor an object.
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ bind(&other_result);
__ ldr(r4, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ ldr(r4, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(r4, Operand(SharedFunctionInfo::kClassConstructorMask));
__ b(eq, &use_receiver);
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ b(eq, &use_receiver);
} else {
__ b(ne, &use_receiver);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ b(&use_receiver);
}
......
......@@ -660,17 +660,20 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ JumpIfObjectType(x0, x4, x5, FIRST_JS_RECEIVER_TYPE, &leave_frame, ge);
__ Bind(&other_result);
// The result is now neither undefined nor an object.
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ Bind(&other_result);
__ Ldr(x4, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ Ldr(x4, FieldMemOperand(x4, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(w4, FieldMemOperand(x4, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(w4, Operand(SharedFunctionInfo::kClassConstructorMask));
__ B(eq, &use_receiver);
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ B(eq, &use_receiver);
} else {
__ B(ne, &use_receiver);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ B(&use_receiver);
}
......
......@@ -307,16 +307,20 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ CmpObjectType(eax, FIRST_JS_RECEIVER_TYPE, ecx);
__ j(above_equal, &leave_frame, Label::kNear);
__ bind(&other_result);
// The result is now neither undefined nor an object.
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ bind(&other_result);
__ mov(ebx, Operand(ebp, ConstructFrameConstants::kConstructorOffset));
__ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(ebx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ j(Condition::zero, &use_receiver, Label::kNear);
} else {
__ j(not_zero, &use_receiver, Label::kNear);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ jmp(&use_receiver, Label::kNear);
}
......
......@@ -635,16 +635,20 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ Branch(&leave_frame, greater_equal, t2, Operand(FIRST_JS_RECEIVER_TYPE));
__ bind(&other_result);
// The result is now neither undefined nor an object.
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ bind(&other_result);
__ lw(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ Branch(&use_receiver, eq, t2, Operand(zero_reg));
} else {
__ Branch(&use_receiver, ne, t2, Operand(zero_reg));
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ Branch(&use_receiver);
}
......
......@@ -639,16 +639,20 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
__ Branch(&leave_frame, greater_equal, t2, Operand(FIRST_JS_RECEIVER_TYPE));
__ bind(&other_result);
// The result is now neither undefined nor an object.
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ bind(&other_result);
__ Ld(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ Branch(&use_receiver, eq, t2, Operand(zero_reg));
} else {
__ Branch(&use_receiver, ne, t2, Operand(zero_reg));
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ Branch(&use_receiver);
}
......
......@@ -312,16 +312,20 @@ void Generate_JSConstructStubGeneric(MacroAssembler* masm,
__ CmpObjectType(rax, FIRST_JS_RECEIVER_TYPE, rcx);
__ j(above_equal, &leave_frame, Label::kNear);
__ bind(&other_result);
// The result is now neither undefined nor an object.
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ bind(&other_result);
__ movp(rbx, Operand(rbp, ConstructFrameConstants::kConstructorOffset));
__ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rbx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ j(Condition::zero, &use_receiver, Label::kNear);
} else {
__ j(not_zero, &use_receiver, Label::kNear);
__ CallRuntime(
Runtime::kIncrementUseCounterConstructorReturnNonUndefinedPrimitive);
__ jmp(&use_receiver, Label::kNear);
}
......
......@@ -474,6 +474,15 @@ RUNTIME_FUNCTION(Runtime_IncrementUseCounter) {
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(
Runtime_IncrementUseCounterConstructorReturnNonUndefinedPrimitive) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
isolate->CountUsage(
v8::Isolate::UseCounterFeature::kConstructorNonUndefinedPrimitiveReturn);
return isolate->heap()->undefined_value();
}
RUNTIME_FUNCTION(Runtime_GetAndResetRuntimeCallStats) {
HandleScope scope(isolate);
if (args.length() == 0) {
......
......@@ -298,6 +298,7 @@ namespace internal {
F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \
F(ExportFromRuntime, 1, 1) \
F(IncrementUseCounter, 1, 1) \
F(IncrementUseCounterConstructorReturnNonUndefinedPrimitive, 0, 1) \
F(InstallToContext, 1, 1) \
F(Interrupt, 0, 1) \
F(IS_VAR, 1, 1) \
......
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