Reland "[runtime] Remove the construct_stub field of the SFI"
This is a reland of 63ecddc814
Original change's description:
> [runtime] Remove the construct_stub field of the SFI
>
> Don't dispatch based on the construct_stub field anymore. Rather than
> read it out and jump to the construct stub, we can switch on the
> builtin_id.
>
> Builtins will always have builtin_id as a Smi, so this signals we need
> to jump to JSBuiltinsConstructStub. The only exception is for uncompiled
> functions, which will have kCompileLazy as the builtin_id, but need to
> jump to the generic stub instead.
>
> API function calls will have a FunctionTemplateInfo in the SFI
> function_data field, and need to go to the builtins stub as well.
>
> The final case is everything else, which should go to the generic stub.
>
> Bug: v8:7503
> Change-Id: I14790a5f9784dc0d940bf10a05f5310026e1d482
> Reviewed-on: https://chromium-review.googlesource.com/980941
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
> Commit-Queue: Peter Marshall <petermarshall@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#52345}
TBR=bmeurer@chromium.org
Bug: v8:7503
Change-Id: Ie46bfb0af173ad7ac8cbdfeed1865e60f3f413f7
Reviewed-on: https://chromium-review.googlesource.com/997712
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52389}
This commit is contained in:
parent
eab5583aa9
commit
b158bfdc2f
@ -371,7 +371,6 @@ V8_NOINLINE Handle<SharedFunctionInfo> SimpleCreateBuiltinSharedFunctionInfo(
|
||||
Handle<SharedFunctionInfo> shared =
|
||||
isolate->factory()->NewSharedFunctionInfoForBuiltin(name, builtin_id,
|
||||
kNormalFunction);
|
||||
shared->SetConstructStub(*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
shared->set_internal_formal_parameter_count(len);
|
||||
shared->set_length(len);
|
||||
return shared;
|
||||
@ -751,8 +750,6 @@ void Genesis::CreateObjectFunction(Handle<JSFunction> empty_function) {
|
||||
inobject_properties, factory->null_value(), Builtins::kObjectConstructor);
|
||||
object_fun->shared()->set_length(1);
|
||||
object_fun->shared()->DontAdaptArguments();
|
||||
object_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate_, JSBuiltinsConstructStub));
|
||||
native_context()->set_object_function(*object_fun);
|
||||
|
||||
{
|
||||
@ -1331,8 +1328,6 @@ static void InstallError(Isolate* isolate, Handle<JSObject> global,
|
||||
global, name, JS_ERROR_TYPE, JSObject::kHeaderSize, 0,
|
||||
factory->the_hole_value(), Builtins::kErrorConstructor, DONT_ENUM);
|
||||
error_fun->shared()->DontAdaptArguments();
|
||||
error_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
error_fun->shared()->set_length(1);
|
||||
|
||||
if (context_index == Context::ERROR_FUNCTION_INDEX) {
|
||||
@ -1539,8 +1534,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
// Function instances are sloppy by default.
|
||||
function_fun->set_prototype_or_initial_map(*isolate->sloppy_function_map());
|
||||
function_fun->shared()->DontAdaptArguments();
|
||||
function_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
function_fun->shared()->set_length(1);
|
||||
InstallWithIntrinsicDefaultProto(isolate, function_fun,
|
||||
Context::FUNCTION_FUNCTION_INDEX);
|
||||
@ -1624,8 +1617,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
|
||||
// Cache the array maps, needed by ArrayConstructorStub
|
||||
CacheInitialJSArrayMaps(native_context(), initial_map);
|
||||
array_function->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
|
||||
// Set up %ArrayPrototype%.
|
||||
// The %ArrayPrototype% has TERMINAL_FAST_ELEMENTS_KIND in order to ensure
|
||||
@ -1716,8 +1707,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
isolate->initial_object_prototype(), Builtins::kNumberConstructor);
|
||||
number_fun->shared()->set_builtin_function_id(kNumberConstructor);
|
||||
number_fun->shared()->DontAdaptArguments();
|
||||
number_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
number_fun->shared()->set_length(1);
|
||||
InstallWithIntrinsicDefaultProto(isolate, number_fun,
|
||||
Context::NUMBER_FUNCTION_INDEX);
|
||||
@ -1832,8 +1821,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
global, "Boolean", JS_VALUE_TYPE, JSValue::kSize, 0,
|
||||
isolate->initial_object_prototype(), Builtins::kBooleanConstructor);
|
||||
boolean_fun->shared()->DontAdaptArguments();
|
||||
boolean_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
boolean_fun->shared()->set_length(1);
|
||||
InstallWithIntrinsicDefaultProto(isolate, boolean_fun,
|
||||
Context::BOOLEAN_FUNCTION_INDEX);
|
||||
@ -1860,8 +1847,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
global, "String", JS_VALUE_TYPE, JSValue::kSize, 0,
|
||||
isolate->initial_object_prototype(), Builtins::kStringConstructor);
|
||||
string_fun->shared()->set_builtin_function_id(kStringConstructor);
|
||||
string_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
string_fun->shared()->DontAdaptArguments();
|
||||
string_fun->shared()->set_length(1);
|
||||
InstallWithIntrinsicDefaultProto(isolate, string_fun,
|
||||
@ -2042,8 +2027,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
global, "Symbol", JS_VALUE_TYPE, JSValue::kSize, 0,
|
||||
factory->the_hole_value(), Builtins::kSymbolConstructor);
|
||||
symbol_fun->shared()->set_builtin_function_id(kSymbolConstructor);
|
||||
symbol_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
symbol_fun->shared()->set_length(0);
|
||||
symbol_fun->shared()->DontAdaptArguments();
|
||||
native_context()->set_symbol_function(*symbol_fun);
|
||||
@ -2110,8 +2093,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
factory->the_hole_value(), Builtins::kDateConstructor);
|
||||
InstallWithIntrinsicDefaultProto(isolate, date_fun,
|
||||
Context::DATE_FUNCTION_INDEX);
|
||||
date_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
date_fun->shared()->set_length(7);
|
||||
date_fun->shared()->DontAdaptArguments();
|
||||
|
||||
@ -2249,7 +2230,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Context::PROMISE_FUNCTION_INDEX);
|
||||
|
||||
Handle<SharedFunctionInfo> shared(promise_fun->shared(), isolate);
|
||||
shared->SetConstructStub(*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
shared->set_internal_formal_parameter_count(1);
|
||||
shared->set_length(1);
|
||||
|
||||
@ -2346,7 +2326,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Context::REGEXP_FUNCTION_INDEX);
|
||||
|
||||
Handle<SharedFunctionInfo> shared(regexp_fun->shared(), isolate);
|
||||
shared->SetConstructStub(*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
shared->set_internal_formal_parameter_count(2);
|
||||
shared->set_length(2);
|
||||
|
||||
@ -2957,8 +2936,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Builtins::kDataViewConstructor);
|
||||
InstallWithIntrinsicDefaultProto(isolate, data_view_fun,
|
||||
Context::DATA_VIEW_FUN_INDEX);
|
||||
data_view_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
data_view_fun->shared()->set_length(3);
|
||||
data_view_fun->shared()->DontAdaptArguments();
|
||||
|
||||
@ -3037,7 +3014,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Context::JS_MAP_FUN_INDEX);
|
||||
|
||||
Handle<SharedFunctionInfo> shared(js_map_fun->shared(), isolate);
|
||||
shared->SetConstructStub(*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
shared->DontAdaptArguments();
|
||||
shared->set_length(0);
|
||||
|
||||
@ -3095,7 +3071,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Context::JS_SET_FUN_INDEX);
|
||||
|
||||
Handle<SharedFunctionInfo> shared(js_set_fun->shared(), isolate);
|
||||
shared->SetConstructStub(*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
shared->DontAdaptArguments();
|
||||
shared->set_length(0);
|
||||
|
||||
@ -3191,7 +3166,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Context::JS_WEAK_MAP_FUN_INDEX);
|
||||
|
||||
Handle<SharedFunctionInfo> shared(cons->shared(), isolate);
|
||||
shared->SetConstructStub(*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
shared->DontAdaptArguments();
|
||||
shared->set_length(0);
|
||||
|
||||
@ -3222,7 +3196,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
Context::JS_WEAK_SET_FUN_INDEX);
|
||||
|
||||
Handle<SharedFunctionInfo> shared(cons->shared(), isolate);
|
||||
shared->SetConstructStub(*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
shared->DontAdaptArguments();
|
||||
shared->set_length(0);
|
||||
|
||||
@ -3271,8 +3244,6 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
JSFunction::SetInitialMap(proxy_function, isolate->proxy_map(),
|
||||
factory->null_value());
|
||||
|
||||
proxy_function->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
proxy_function->shared()->set_internal_formal_parameter_count(2);
|
||||
proxy_function->shared()->set_length(2);
|
||||
|
||||
@ -3499,8 +3470,6 @@ Handle<JSFunction> Genesis::InstallTypedArray(const char* name,
|
||||
|
||||
result->shared()->DontAdaptArguments();
|
||||
result->shared()->set_length(3);
|
||||
result->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate_, JSBuiltinsConstructStub));
|
||||
|
||||
CHECK(JSObject::SetPrototype(result, typed_array_function, false, kDontThrow)
|
||||
.FromJust());
|
||||
@ -3775,8 +3744,6 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
|
||||
generator_function_function->set_prototype_or_initial_map(
|
||||
native_context->generator_function_map());
|
||||
generator_function_function->shared()->DontAdaptArguments();
|
||||
generator_function_function->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
generator_function_function->shared()->set_length(1);
|
||||
InstallWithIntrinsicDefaultProto(
|
||||
isolate, generator_function_function,
|
||||
@ -3805,8 +3772,6 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
|
||||
async_generator_function_function->set_prototype_or_initial_map(
|
||||
native_context->async_generator_function_map());
|
||||
async_generator_function_function->shared()->DontAdaptArguments();
|
||||
async_generator_function_function->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
async_generator_function_function->shared()->set_length(1);
|
||||
InstallWithIntrinsicDefaultProto(
|
||||
isolate, async_generator_function_function,
|
||||
@ -4018,8 +3983,6 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
|
||||
async_function_constructor->set_prototype_or_initial_map(
|
||||
native_context->async_function_map());
|
||||
async_function_constructor->shared()->DontAdaptArguments();
|
||||
async_function_constructor->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate, JSBuiltinsConstructStub));
|
||||
async_function_constructor->shared()->set_length(1);
|
||||
native_context->set_async_function_constructor(*async_function_constructor);
|
||||
JSObject::ForceSetPrototype(async_function_constructor,
|
||||
@ -4304,8 +4267,6 @@ void Genesis::InitializeGlobal_harmony_bigint() {
|
||||
factory->the_hole_value(), Builtins::kBigIntConstructor);
|
||||
bigint_fun->shared()->set_builtin_function_id(kBigIntConstructor);
|
||||
bigint_fun->shared()->DontAdaptArguments();
|
||||
bigint_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate(), JSBuiltinsConstructStub));
|
||||
bigint_fun->shared()->set_length(1);
|
||||
InstallWithIntrinsicDefaultProto(isolate(), bigint_fun,
|
||||
Context::BIGINT_FUNCTION_INDEX);
|
||||
@ -4399,8 +4360,6 @@ Handle<JSFunction> Genesis::CreateArrayBuffer(
|
||||
CreateFunction(isolate(), name, JS_ARRAY_BUFFER_TYPE,
|
||||
JSArrayBuffer::kSizeWithEmbedderFields, 0, prototype,
|
||||
Builtins::kArrayBufferConstructor);
|
||||
array_buffer_fun->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate(), JSBuiltinsConstructStub));
|
||||
array_buffer_fun->shared()->DontAdaptArguments();
|
||||
array_buffer_fun->shared()->set_length(1);
|
||||
|
||||
@ -4455,8 +4414,6 @@ Handle<JSFunction> Genesis::InstallInternalArray(Handle<JSObject> target,
|
||||
InstallFunction(target, name, JS_ARRAY_TYPE, JSArray::kSize, 0, prototype,
|
||||
Builtins::kInternalArrayConstructor);
|
||||
|
||||
array_function->shared()->SetConstructStub(
|
||||
*BUILTIN_CODE(isolate_, JSBuiltinsConstructStub));
|
||||
array_function->shared()->DontAdaptArguments();
|
||||
|
||||
Handle<Map> original_map(array_function->initial_map());
|
||||
|
@ -441,9 +441,6 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
|
||||
MacroAssembler* masm) {
|
||||
Generate_JSConstructStubGeneric(masm, false);
|
||||
}
|
||||
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
@ -2260,11 +2257,20 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// r2 to contain either an AllocationSite or undefined.
|
||||
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
|
||||
|
||||
// Tail call to the function-specific construct stub (still in the caller
|
||||
// context at this point).
|
||||
Label call_generic_stub;
|
||||
|
||||
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
|
||||
__ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
|
||||
__ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kFlagsOffset));
|
||||
__ tst(r4, Operand(SharedFunctionInfo::ConstructAsBuiltinBit::kMask));
|
||||
__ b(eq, &call_generic_stub);
|
||||
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&call_generic_stub);
|
||||
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -483,9 +483,6 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
|
||||
MacroAssembler* masm) {
|
||||
Generate_JSConstructStubGeneric(masm, false);
|
||||
}
|
||||
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
@ -2658,12 +2655,20 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// x2 to contain either an AllocationSite or undefined.
|
||||
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
|
||||
|
||||
// Tail call to the function-specific construct stub (still in the caller
|
||||
// context at this point).
|
||||
Label call_generic_stub;
|
||||
|
||||
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
|
||||
__ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ldr(x4, FieldMemOperand(x4, SharedFunctionInfo::kConstructStubOffset));
|
||||
__ Add(x4, x4, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Br(x4);
|
||||
__ Ldr(w4, FieldMemOperand(x4, SharedFunctionInfo::kFlagsOffset));
|
||||
__ TestAndBranchIfAllClear(
|
||||
w4, SharedFunctionInfo::ConstructAsBuiltinBit::kMask, &call_generic_stub);
|
||||
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&call_generic_stub);
|
||||
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -65,7 +65,6 @@ namespace internal {
|
||||
TFC(ConstructWithArrayLike, ConstructWithArrayLike, 1) \
|
||||
ASM(ConstructForwardVarargs) \
|
||||
ASM(ConstructFunctionForwardVarargs) \
|
||||
ASM(JSConstructStubApi) \
|
||||
ASM(JSConstructStubGenericRestrictedReturn) \
|
||||
ASM(JSConstructStubGenericUnrestrictedReturn) \
|
||||
ASM(JSBuiltinsConstructStub) \
|
||||
|
@ -379,7 +379,6 @@ bool Builtins::IsIsolateIndependent(int index) {
|
||||
case kBitwiseNot:
|
||||
case kBooleanPrototypeToString:
|
||||
case kBooleanPrototypeValueOf:
|
||||
case kConstructFunction:
|
||||
case kContinueToCodeStubBuiltin:
|
||||
case kContinueToCodeStubBuiltinWithResult:
|
||||
case kContinueToJavaScriptBuiltin:
|
||||
|
@ -382,9 +382,6 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
|
||||
MacroAssembler* masm) {
|
||||
return Generate_JSConstructStubGeneric(masm, false);
|
||||
}
|
||||
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
@ -2399,12 +2396,20 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// ebx to contain either an AllocationSite or undefined.
|
||||
__ LoadRoot(ebx, Heap::kUndefinedValueRootIndex);
|
||||
|
||||
// Tail call to the function-specific construct stub (still in the caller
|
||||
// context at this point).
|
||||
Label call_generic_stub;
|
||||
|
||||
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
|
||||
__ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
|
||||
__ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
|
||||
__ jmp(ecx);
|
||||
__ test(FieldOperand(ecx, SharedFunctionInfo::kFlagsOffset),
|
||||
Immediate(SharedFunctionInfo::ConstructAsBuiltinBit::kMask));
|
||||
__ j(zero, &call_generic_stub, Label::kNear);
|
||||
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&call_generic_stub);
|
||||
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -433,9 +433,6 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
|
||||
MacroAssembler* masm) {
|
||||
Generate_JSConstructStubGeneric(masm, false);
|
||||
}
|
||||
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
@ -2255,11 +2252,20 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// a2 to contain either an AllocationSite or undefined.
|
||||
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
|
||||
|
||||
// Tail call to the function-specific construct stub (still in the caller
|
||||
// context at this point).
|
||||
Label call_generic_stub;
|
||||
|
||||
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
|
||||
__ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset));
|
||||
__ Jump(at, t0, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kFlagsOffset));
|
||||
__ And(t0, t0, Operand(SharedFunctionInfo::ConstructAsBuiltinBit::kMask));
|
||||
__ Branch(&call_generic_stub, eq, t0, Operand(zero_reg));
|
||||
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&call_generic_stub);
|
||||
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -434,9 +434,6 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
|
||||
MacroAssembler* masm) {
|
||||
Generate_JSConstructStubGeneric(masm, false);
|
||||
}
|
||||
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
@ -2274,12 +2271,20 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// a2 to contain either an AllocationSite or undefined.
|
||||
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
|
||||
|
||||
// Tail call to the function-specific construct stub (still in the caller
|
||||
// context at this point).
|
||||
Label call_generic_stub;
|
||||
|
||||
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
|
||||
__ Ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ Ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kConstructStubOffset));
|
||||
__ Daddu(at, a4, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(at);
|
||||
__ lwu(a4, FieldMemOperand(a4, SharedFunctionInfo::kFlagsOffset));
|
||||
__ And(a4, a4, Operand(SharedFunctionInfo::ConstructAsBuiltinBit::kMask));
|
||||
__ Branch(&call_generic_stub, eq, a4, Operand(zero_reg));
|
||||
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&call_generic_stub);
|
||||
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -448,9 +448,6 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
|
||||
MacroAssembler* masm) {
|
||||
Generate_JSConstructStubGeneric(masm, false);
|
||||
}
|
||||
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
|
@ -446,9 +446,6 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
|
||||
MacroAssembler* masm) {
|
||||
Generate_JSConstructStubGeneric(masm, false);
|
||||
}
|
||||
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
|
@ -385,9 +385,6 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
|
||||
MacroAssembler* masm) {
|
||||
return Generate_JSConstructStubGeneric(masm, false);
|
||||
}
|
||||
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
|
||||
Generate_JSBuiltinsConstructStubHelper(masm);
|
||||
}
|
||||
@ -2511,12 +2508,20 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
|
||||
// rbx to contain either an AllocationSite or undefined.
|
||||
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
|
||||
|
||||
// Tail call to the function-specific construct stub (still in the caller
|
||||
// context at this point).
|
||||
Label call_generic_stub;
|
||||
|
||||
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
|
||||
__ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
|
||||
__ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
|
||||
__ jmp(rcx);
|
||||
__ testl(FieldOperand(rcx, SharedFunctionInfo::kFlagsOffset),
|
||||
Immediate(SharedFunctionInfo::ConstructAsBuiltinBit::kMask));
|
||||
__ j(zero, &call_generic_stub, Label::kNear);
|
||||
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
__ bind(&call_generic_stub);
|
||||
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -261,9 +261,7 @@ namespace {
|
||||
// TODO(mstarzinger,verwaest): Move this predicate onto SharedFunctionInfo?
|
||||
bool NeedsImplicitReceiver(Handle<SharedFunctionInfo> shared_info) {
|
||||
DisallowHeapAllocation no_gc;
|
||||
Isolate* const isolate = shared_info->GetIsolate();
|
||||
Code* const construct_stub = shared_info->construct_stub();
|
||||
if (construct_stub == *isolate->builtins()->JSConstructStubGeneric()) {
|
||||
if (!shared_info->construct_as_builtin()) {
|
||||
return !IsDerivedConstructor(shared_info->kind());
|
||||
} else {
|
||||
return false;
|
||||
|
@ -1561,8 +1561,6 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
|
||||
Node* target = NodeProperties::GetValueInput(node, 0);
|
||||
Type* target_type = NodeProperties::GetType(target);
|
||||
Node* new_target = NodeProperties::GetValueInput(node, arity + 1);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
|
||||
// Check if {target} is a known JSFunction.
|
||||
if (target_type->IsHeapConstant() &&
|
||||
@ -1570,44 +1568,31 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
|
||||
Handle<JSFunction> function =
|
||||
Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
|
||||
Handle<SharedFunctionInfo> shared(function->shared(), isolate());
|
||||
const int builtin_index = shared->construct_stub()->builtin_index();
|
||||
const bool is_builtin = (builtin_index != -1);
|
||||
|
||||
// Only optimize [[Construct]] here if {function} is a Constructor.
|
||||
if (!function->IsConstructor()) return NoChange();
|
||||
|
||||
CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
|
||||
|
||||
if (is_builtin && Builtins::HasCppImplementation(builtin_index) &&
|
||||
!NeedsArgumentAdaptorFrame(shared, arity)) {
|
||||
// Patch {node} to a direct CEntryStub call.
|
||||
// Patch {node} to an indirect call via the {function}s construct stub.
|
||||
bool use_builtin_construct_stub = shared->construct_as_builtin();
|
||||
|
||||
// Load the context from the {target}.
|
||||
Node* context = effect = graph()->NewNode(
|
||||
simplified()->LoadField(AccessBuilder::ForJSFunctionContext()),
|
||||
target, effect, control);
|
||||
NodeProperties::ReplaceContextInput(node, context);
|
||||
Handle<Code> code =
|
||||
use_builtin_construct_stub
|
||||
? BUILTIN_CODE(isolate(), JSBuiltinsConstructStub)
|
||||
: BUILTIN_CODE(isolate(), JSConstructStubGenericUnrestrictedReturn);
|
||||
|
||||
// Update the effect dependency for the {node}.
|
||||
NodeProperties::ReplaceEffectInput(node, effect);
|
||||
node->RemoveInput(arity + 1);
|
||||
node->InsertInput(graph()->zone(), 0, jsgraph()->HeapConstant(code));
|
||||
node->InsertInput(graph()->zone(), 2, new_target);
|
||||
node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity));
|
||||
node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
|
||||
node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant());
|
||||
NodeProperties::ChangeOp(
|
||||
node, common()->Call(Linkage::GetStubCallDescriptor(
|
||||
isolate(), graph()->zone(),
|
||||
ConstructStubDescriptor(isolate()), 1 + arity, flags)));
|
||||
|
||||
ReduceBuiltin(isolate(), jsgraph(), node, builtin_index, arity, flags);
|
||||
} else {
|
||||
// Patch {node} to an indirect call via the {function}s construct stub.
|
||||
Callable callable(handle(shared->construct_stub(), isolate()),
|
||||
ConstructStubDescriptor(isolate()));
|
||||
node->RemoveInput(arity + 1);
|
||||
node->InsertInput(graph()->zone(), 0,
|
||||
jsgraph()->HeapConstant(callable.code()));
|
||||
node->InsertInput(graph()->zone(), 2, new_target);
|
||||
node->InsertInput(graph()->zone(), 3, jsgraph()->Constant(arity));
|
||||
node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant());
|
||||
node->InsertInput(graph()->zone(), 5, jsgraph()->UndefinedConstant());
|
||||
NodeProperties::ChangeOp(
|
||||
node, common()->Call(Linkage::GetStubCallDescriptor(
|
||||
isolate(), graph()->zone(), callable.descriptor(),
|
||||
1 + arity, flags)));
|
||||
}
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
|
@ -2623,7 +2623,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
share->set_builtin_id(Builtins::kIllegal);
|
||||
}
|
||||
share->set_outer_scope_info(*the_hole_value());
|
||||
share->SetConstructStub(*isolate()->builtins()->JSConstructStubGeneric());
|
||||
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER);
|
||||
share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
@ -2643,6 +2642,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||
share->set_function_token_position(0);
|
||||
// All flags default to false or 0.
|
||||
share->set_flags(0);
|
||||
share->CalculateConstructAsBuiltin();
|
||||
share->set_kind(kind);
|
||||
|
||||
share->clear_padding();
|
||||
|
@ -893,6 +893,19 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
|
||||
CHECK_EQ(raw_start_position(), info->StartPosition());
|
||||
CHECK_EQ(raw_end_position(), info->EndPosition());
|
||||
}
|
||||
|
||||
if (IsApiFunction()) {
|
||||
CHECK(construct_as_builtin());
|
||||
} else if (!HasBuiltinId()) {
|
||||
CHECK(!construct_as_builtin());
|
||||
} else {
|
||||
int id = builtin_id();
|
||||
if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
|
||||
CHECK(construct_as_builtin());
|
||||
} else {
|
||||
CHECK(!construct_as_builtin());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1209,21 +1209,15 @@ Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(
|
||||
} else {
|
||||
name_string = isolate->factory()->empty_string();
|
||||
}
|
||||
bool is_constructor;
|
||||
FunctionKind function_kind;
|
||||
if (info->remove_prototype()) {
|
||||
is_constructor = false;
|
||||
function_kind = kConciseMethod;
|
||||
} else {
|
||||
is_constructor = true;
|
||||
function_kind = kNormalFunction;
|
||||
}
|
||||
Handle<SharedFunctionInfo> result =
|
||||
isolate->factory()->NewSharedFunctionInfoForApiFunction(name_string, info,
|
||||
function_kind);
|
||||
if (is_constructor) {
|
||||
result->SetConstructStub(*BUILTIN_CODE(isolate, JSConstructStubApi));
|
||||
}
|
||||
|
||||
result->set_length(info->length());
|
||||
result->DontAdaptArguments();
|
||||
@ -13904,8 +13898,6 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
|
||||
// shared_info->set_kind(lit->kind());
|
||||
// FunctionKind must have already been set.
|
||||
DCHECK(lit->kind() == shared_info->kind());
|
||||
DCHECK_EQ(*shared_info->GetIsolate()->builtins()->JSConstructStubGeneric(),
|
||||
shared_info->construct_stub());
|
||||
shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
|
||||
shared_info->set_function_literal_id(lit->function_literal_id());
|
||||
DCHECK_IMPLIES(lit->requires_instance_fields_initializer(),
|
||||
@ -13956,23 +13948,6 @@ void SharedFunctionInfo::SetExpectedNofPropertiesFromEstimate(
|
||||
set_expected_nof_properties(estimate);
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::SetConstructStub(Code* code) {
|
||||
if (code->kind() == Code::BUILTIN) code->set_is_construct_stub(true);
|
||||
#ifdef DEBUG
|
||||
if (code->is_builtin()) {
|
||||
// See https://crbug.com/v8/6787. Lazy deserialization currently cannot
|
||||
// handle lazy construct stubs that differ from the code object.
|
||||
int builtin_id = code->builtin_index();
|
||||
DCHECK_NE(Builtins::kDeserializeLazy, builtin_id);
|
||||
DCHECK(builtin_id == Builtins::kJSBuiltinsConstructStub ||
|
||||
!Builtins::IsLazy(builtin_id));
|
||||
// Builtins should use JSBuiltinsConstructStub.
|
||||
DCHECK_NE(this->GetCode(), code);
|
||||
}
|
||||
#endif
|
||||
set_construct_stub(code);
|
||||
}
|
||||
|
||||
void Map::StartInobjectSlackTracking() {
|
||||
DCHECK(!IsInobjectSlackTrackingInProgress());
|
||||
if (UnusedPropertyFields() == 0) return;
|
||||
|
@ -25,7 +25,6 @@ DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
|
||||
|
||||
ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
|
||||
kNameOrScopeInfoOffset)
|
||||
ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
|
||||
ACCESSORS(SharedFunctionInfo, feedback_metadata, FeedbackMetadata,
|
||||
kFeedbackMetadataOffset)
|
||||
ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
|
||||
@ -161,6 +160,26 @@ void SharedFunctionInfo::set_needs_home_object(bool value) {
|
||||
UpdateFunctionMapIndex();
|
||||
}
|
||||
|
||||
bool SharedFunctionInfo::construct_as_builtin() const {
|
||||
return ConstructAsBuiltinBit::decode(flags());
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::CalculateConstructAsBuiltin() {
|
||||
bool uses_builtins_construct_stub = false;
|
||||
if (HasBuiltinId()) {
|
||||
int id = builtin_id();
|
||||
if (id != Builtins::kCompileLazy && id != Builtins::kEmptyFunction) {
|
||||
uses_builtins_construct_stub = true;
|
||||
}
|
||||
} else if (IsApiFunction()) {
|
||||
uses_builtins_construct_stub = true;
|
||||
}
|
||||
|
||||
int f = flags();
|
||||
f = ConstructAsBuiltinBit::update(f, uses_builtins_construct_stub);
|
||||
set_flags(f);
|
||||
}
|
||||
|
||||
int SharedFunctionInfo::function_map_index() const {
|
||||
// Note: Must be kept in sync with the FastNewClosure builtin.
|
||||
int index =
|
||||
|
@ -96,13 +96,6 @@ class SharedFunctionInfo : public HeapObject {
|
||||
// value if it isn't yet known.
|
||||
DECL_ACCESSORS(outer_scope_info, HeapObject)
|
||||
|
||||
// [construct stub]: Code stub for constructing instances of this function.
|
||||
DECL_ACCESSORS(construct_stub, Code)
|
||||
|
||||
// Sets the given code as the construct stub, and marks builtin code objects
|
||||
// as a construct stub.
|
||||
void SetConstructStub(Code* code);
|
||||
|
||||
// Returns if this function has been compiled to native code yet.
|
||||
inline bool is_compiled() const;
|
||||
|
||||
@ -389,6 +382,15 @@ class SharedFunctionInfo : public HeapObject {
|
||||
// Sets the expected number of properties based on estimate from parser.
|
||||
void SetExpectedNofPropertiesFromEstimate(FunctionLiteral* literal);
|
||||
|
||||
inline bool construct_as_builtin() const;
|
||||
|
||||
// Determines and sets the ConstructAsBuiltinBit in |flags|, based on the
|
||||
// |function_data|. Must be called when creating the SFI after other fields
|
||||
// are initialized. The ConstructAsBuiltinBit determines whether
|
||||
// JSBuiltinsConstructStub or JSConstructStubGeneric should be called to
|
||||
// construct this function.
|
||||
inline void CalculateConstructAsBuiltin();
|
||||
|
||||
// Dispatched behavior.
|
||||
DECL_PRINTER(SharedFunctionInfo)
|
||||
DECL_VERIFIER(SharedFunctionInfo)
|
||||
@ -447,7 +449,6 @@ class SharedFunctionInfo : public HeapObject {
|
||||
V(kFunctionDataOffset, kPointerSize) \
|
||||
V(kNameOrScopeInfoOffset, kPointerSize) \
|
||||
V(kOuterScopeInfoOffset, kPointerSize) \
|
||||
V(kConstructStubOffset, kPointerSize) \
|
||||
V(kScriptOffset, kPointerSize) \
|
||||
V(kDebugInfoOffset, kPointerSize) \
|
||||
V(kFunctionIdentifierOffset, kPointerSize) \
|
||||
@ -502,7 +503,8 @@ class SharedFunctionInfo : public HeapObject {
|
||||
V(IsAsmWasmBrokenBit, bool, 1, _) \
|
||||
V(FunctionMapIndexBits, int, 5, _) \
|
||||
V(DisabledOptimizationReasonBits, BailoutReason, 4, _) \
|
||||
V(RequiresInstanceFieldsInitializer, bool, 1, _)
|
||||
V(RequiresInstanceFieldsInitializer, bool, 1, _) \
|
||||
V(ConstructAsBuiltinBit, bool, 1, _)
|
||||
|
||||
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
|
||||
#undef FLAGS_BIT_FIELDS
|
||||
|
@ -1167,13 +1167,6 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
|
||||
SetInternalReference(obj, entry,
|
||||
"script", shared->script(),
|
||||
SharedFunctionInfo::kScriptOffset);
|
||||
const char* construct_stub_name = name ?
|
||||
names_->GetFormatted("(construct stub code for %s)", name) :
|
||||
"(construct stub code)";
|
||||
TagObject(shared->construct_stub(), construct_stub_name);
|
||||
SetInternalReference(obj, entry,
|
||||
"construct_stub", shared->construct_stub(),
|
||||
SharedFunctionInfo::kConstructStubOffset);
|
||||
SetInternalReference(obj, entry,
|
||||
"function_data", shared->function_data(),
|
||||
SharedFunctionInfo::kFunctionDataOffset);
|
||||
|
@ -139,13 +139,16 @@ TEST(StressJS) {
|
||||
v8::HandleScope scope(CcTest::isolate());
|
||||
v8::Local<v8::Context> env = v8::Context::New(CcTest::isolate());
|
||||
env->Enter();
|
||||
Handle<JSFunction> function =
|
||||
factory->NewFunctionForTest(factory->function_string());
|
||||
// Force the creation of an initial map and set the code to
|
||||
// something empty.
|
||||
|
||||
NewFunctionArgs args = NewFunctionArgs::ForBuiltin(
|
||||
factory->function_string(), isolate->sloppy_function_map(),
|
||||
Builtins::kEmptyFunction);
|
||||
Handle<JSFunction> function = factory->NewFunction(args);
|
||||
CHECK(!function->shared()->construct_as_builtin());
|
||||
|
||||
// Force the creation of an initial map.
|
||||
factory->NewJSObject(function);
|
||||
function->set_code(
|
||||
CcTest::i_isolate()->builtins()->builtin(Builtins::kEmptyFunction));
|
||||
|
||||
// Patch the map to have an accessor for "get".
|
||||
Handle<Map> map(function->initial_map());
|
||||
Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
|
||||
|
Loading…
Reference in New Issue
Block a user