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:
Peter Marshall 2018-04-05 13:28:45 +02:00 committed by Commit Bot
parent eab5583aa9
commit b158bfdc2f
20 changed files with 149 additions and 180 deletions

View File

@ -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());

View File

@ -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

View File

@ -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

View File

@ -65,7 +65,6 @@ namespace internal {
TFC(ConstructWithArrayLike, ConstructWithArrayLike, 1) \
ASM(ConstructForwardVarargs) \
ASM(ConstructFunctionForwardVarargs) \
ASM(JSConstructStubApi) \
ASM(JSConstructStubGenericRestrictedReturn) \
ASM(JSConstructStubGenericUnrestrictedReturn) \
ASM(JSBuiltinsConstructStub) \

View File

@ -379,7 +379,6 @@ bool Builtins::IsIsolateIndependent(int index) {
case kBitwiseNot:
case kBooleanPrototypeToString:
case kBooleanPrototypeValueOf:
case kConstructFunction:
case kContinueToCodeStubBuiltin:
case kContinueToCodeStubBuiltinWithResult:
case kContinueToJavaScriptBuiltin:

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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();

View File

@ -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());
}
}
}

View File

@ -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;

View File

@ -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 =

View File

@ -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

View File

@ -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);

View File

@ -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());