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.
__ 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));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ 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);
} 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.
__ 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));
if (restrict_constructor_return) {
// Throw if constructor function is a class constructor
__ 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);
} 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.
__ 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
__ mov(ebx, Operand(ebp, ConstructFrameConstants::kConstructorOffset));
__ mov(ebx, FieldOperand(ebx, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(ebx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask));
__ 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.
__ 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
__ lw(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ lw(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask));
__ 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.
__ 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
__ Ld(a1, MemOperand(fp, ConstructFrameConstants::kConstructorOffset));
__ Ld(t2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lwu(t2, FieldMemOperand(t2, SharedFunctionInfo::kCompilerHintsOffset));
__ And(t2, t2, Operand(SharedFunctionInfo::kClassConstructorMask));
__ 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.
__ 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
__ movp(rbx, Operand(rbp, ConstructFrameConstants::kConstructorOffset));
__ movp(rbx, FieldOperand(rbx, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rbx, SharedFunctionInfo::kCompilerHintsOffset),
Immediate(SharedFunctionInfo::kClassConstructorMask));
__ 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) {
......
......@@ -287,55 +287,56 @@ namespace internal {
#define FOR_EACH_INTRINSIC_INTL(F)
#endif
#define FOR_EACH_INTRINSIC_INTERNAL(F) \
F(AllocateInNewSpace, 1, 1) \
F(AllocateInTargetSpace, 2, 1) \
F(AllocateSeqOneByteString, 1, 1) \
F(AllocateSeqTwoByteString, 1, 1) \
F(CheckIsBootstrapping, 0, 1) \
F(CreateAsyncFromSyncIterator, 1, 1) \
F(CreateListFromArrayLike, 1, 1) \
F(GetAndResetRuntimeCallStats, -1 /* <= 2 */, 1) \
F(ExportFromRuntime, 1, 1) \
F(IncrementUseCounter, 1, 1) \
F(InstallToContext, 1, 1) \
F(Interrupt, 0, 1) \
F(IS_VAR, 1, 1) \
F(NewReferenceError, 2, 1) \
F(NewSyntaxError, 2, 1) \
F(NewTypeError, 2, 1) \
F(OrdinaryHasInstance, 2, 1) \
F(PromoteScheduledException, 0, 1) \
F(ReThrow, 1, 1) \
F(RunMicrotasks, 0, 1) \
F(StackGuard, 0, 1) \
F(Throw, 1, 1) \
F(ThrowApplyNonFunction, 1, 1) \
F(ThrowCannotConvertToPrimitive, 0, 1) \
F(ThrowCalledNonCallable, 1, 1) \
F(ThrowCalledOnNullOrUndefined, 1, 1) \
F(ThrowConstructedNonConstructable, 1, 1) \
F(ThrowConstructorReturnedNonObject, 0, 1) \
F(ThrowGeneratorRunning, 0, 1) \
F(ThrowIllegalInvocation, 0, 1) \
F(ThrowIncompatibleMethodReceiver, 2, 1) \
F(ThrowInvalidHint, 1, 1) \
F(ThrowInvalidStringLength, 0, 1) \
F(ThrowInvalidTypedArrayAlignment, 2, 1) \
F(ThrowIteratorResultNotAnObject, 1, 1) \
F(ThrowThrowMethodMissing, 0, 1) \
F(ThrowSymbolIteratorInvalid, 0, 1) \
F(ThrowNonCallableInInstanceOfCheck, 0, 1) \
F(ThrowNonObjectInInstanceOfCheck, 0, 1) \
F(ThrowNotConstructor, 1, 1) \
F(ThrowRangeError, -1 /* >= 1 */, 1) \
F(ThrowReferenceError, 1, 1) \
F(ThrowStackOverflow, 0, 1) \
F(ThrowSymbolAsyncIteratorInvalid, 0, 1) \
F(ThrowTypeError, -1 /* >= 1 */, 1) \
F(ThrowUndefinedOrNullToObject, 1, 1) \
F(Typeof, 1, 1) \
F(UnwindAndFindExceptionHandler, 0, 1) \
#define FOR_EACH_INTRINSIC_INTERNAL(F) \
F(AllocateInNewSpace, 1, 1) \
F(AllocateInTargetSpace, 2, 1) \
F(AllocateSeqOneByteString, 1, 1) \
F(AllocateSeqTwoByteString, 1, 1) \
F(CheckIsBootstrapping, 0, 1) \
F(CreateAsyncFromSyncIterator, 1, 1) \
F(CreateListFromArrayLike, 1, 1) \
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) \
F(NewReferenceError, 2, 1) \
F(NewSyntaxError, 2, 1) \
F(NewTypeError, 2, 1) \
F(OrdinaryHasInstance, 2, 1) \
F(PromoteScheduledException, 0, 1) \
F(ReThrow, 1, 1) \
F(RunMicrotasks, 0, 1) \
F(StackGuard, 0, 1) \
F(Throw, 1, 1) \
F(ThrowApplyNonFunction, 1, 1) \
F(ThrowCannotConvertToPrimitive, 0, 1) \
F(ThrowCalledNonCallable, 1, 1) \
F(ThrowCalledOnNullOrUndefined, 1, 1) \
F(ThrowConstructedNonConstructable, 1, 1) \
F(ThrowConstructorReturnedNonObject, 0, 1) \
F(ThrowGeneratorRunning, 0, 1) \
F(ThrowIllegalInvocation, 0, 1) \
F(ThrowIncompatibleMethodReceiver, 2, 1) \
F(ThrowInvalidHint, 1, 1) \
F(ThrowInvalidStringLength, 0, 1) \
F(ThrowInvalidTypedArrayAlignment, 2, 1) \
F(ThrowIteratorResultNotAnObject, 1, 1) \
F(ThrowThrowMethodMissing, 0, 1) \
F(ThrowSymbolIteratorInvalid, 0, 1) \
F(ThrowNonCallableInInstanceOfCheck, 0, 1) \
F(ThrowNonObjectInInstanceOfCheck, 0, 1) \
F(ThrowNotConstructor, 1, 1) \
F(ThrowRangeError, -1 /* >= 1 */, 1) \
F(ThrowReferenceError, 1, 1) \
F(ThrowStackOverflow, 0, 1) \
F(ThrowSymbolAsyncIteratorInvalid, 0, 1) \
F(ThrowTypeError, -1 /* >= 1 */, 1) \
F(ThrowUndefinedOrNullToObject, 1, 1) \
F(Typeof, 1, 1) \
F(UnwindAndFindExceptionHandler, 0, 1) \
F(AllowDynamicFunction, 1, 1)
#define FOR_EACH_INTRINSIC_LITERALS(F) \
......
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