Commit f49a1a67 authored by Michael Achenbach's avatar Michael Achenbach Committed by Commit Bot

Revert "[runtime] Remove the construct_stub field of the SFI"

This reverts commit 63ecddc8.

Reason for revert:
https://build.chromium.org/p/client.v8/builders/V8%20Linux64%20-%20internal%20snapshot/builds/14773

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=petermarshall@chromium.org,leszeks@chromium.org,bmeurer@chromium.org

Change-Id: I2031913ab5a12018ad932f920792aa1f6faa5e22
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:7503
Reviewed-on: https://chromium-review.googlesource.com/995293Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52346}
parent 63ecddc8
This diff is collapsed.
...@@ -441,6 +441,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn( ...@@ -441,6 +441,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) { MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false); Generate_JSConstructStubGeneric(masm, false);
} }
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm); Generate_JSBuiltinsConstructStubHelper(masm);
} }
...@@ -2237,20 +2240,11 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { ...@@ -2237,20 +2240,11 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
// r2 to contain either an AllocationSite or undefined. // r2 to contain either an AllocationSite or undefined.
__ LoadRoot(r2, Heap::kUndefinedValueRootIndex); __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
Label call_generic_stub; // Tail call to the function-specific construct stub (still in the caller
// context at this point).
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
__ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); __ ldr(r4, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kFlagsOffset)); __ ldr(r4, FieldMemOperand(r4, SharedFunctionInfo::kConstructStubOffset));
__ tst(r4, Operand(SharedFunctionInfo::ConstructAsBuiltinBit::kMask)); __ add(pc, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
__ 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 // static
......
...@@ -483,6 +483,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn( ...@@ -483,6 +483,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) { MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false); Generate_JSConstructStubGeneric(masm, false);
} }
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm); Generate_JSBuiltinsConstructStubHelper(masm);
} }
...@@ -2641,20 +2644,12 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { ...@@ -2641,20 +2644,12 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
// x2 to contain either an AllocationSite or undefined. // x2 to contain either an AllocationSite or undefined.
__ LoadRoot(x2, Heap::kUndefinedValueRootIndex); __ LoadRoot(x2, Heap::kUndefinedValueRootIndex);
Label call_generic_stub; // Tail call to the function-specific construct stub (still in the caller
// context at this point).
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
__ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); __ Ldr(x4, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset));
__ Ldr(w4, FieldMemOperand(x4, SharedFunctionInfo::kFlagsOffset)); __ Ldr(x4, FieldMemOperand(x4, SharedFunctionInfo::kConstructStubOffset));
__ TestAndBranchIfAllClear( __ Add(x4, x4, Code::kHeaderSize - kHeapObjectTag);
w4, SharedFunctionInfo::ConstructAsBuiltinBit::kMask, &call_generic_stub); __ Br(x4);
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
RelocInfo::CODE_TARGET);
} }
// static // static
......
...@@ -65,6 +65,7 @@ namespace internal { ...@@ -65,6 +65,7 @@ namespace internal {
TFC(ConstructWithArrayLike, ConstructWithArrayLike, 1) \ TFC(ConstructWithArrayLike, ConstructWithArrayLike, 1) \
ASM(ConstructForwardVarargs) \ ASM(ConstructForwardVarargs) \
ASM(ConstructFunctionForwardVarargs) \ ASM(ConstructFunctionForwardVarargs) \
ASM(JSConstructStubApi) \
ASM(JSConstructStubGenericRestrictedReturn) \ ASM(JSConstructStubGenericRestrictedReturn) \
ASM(JSConstructStubGenericUnrestrictedReturn) \ ASM(JSConstructStubGenericUnrestrictedReturn) \
ASM(JSBuiltinsConstructStub) \ ASM(JSBuiltinsConstructStub) \
......
...@@ -382,6 +382,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn( ...@@ -382,6 +382,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) { MacroAssembler* masm) {
return Generate_JSConstructStubGeneric(masm, false); return Generate_JSConstructStubGeneric(masm, false);
} }
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm); Generate_JSBuiltinsConstructStubHelper(masm);
} }
...@@ -2381,20 +2384,12 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { ...@@ -2381,20 +2384,12 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
// ebx to contain either an AllocationSite or undefined. // ebx to contain either an AllocationSite or undefined.
__ LoadRoot(ebx, Heap::kUndefinedValueRootIndex); __ LoadRoot(ebx, Heap::kUndefinedValueRootIndex);
Label call_generic_stub; // Tail call to the function-specific construct stub (still in the caller
// context at this point).
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
__ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ test(FieldOperand(ecx, SharedFunctionInfo::kFlagsOffset), __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kConstructStubOffset));
Immediate(SharedFunctionInfo::ConstructAsBuiltinBit::kMask)); __ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
__ j(zero, &call_generic_stub, Label::kNear); __ jmp(ecx);
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
RelocInfo::CODE_TARGET);
} }
// static // static
......
...@@ -433,6 +433,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn( ...@@ -433,6 +433,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) { MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false); Generate_JSConstructStubGeneric(masm, false);
} }
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm); Generate_JSBuiltinsConstructStubHelper(masm);
} }
...@@ -2234,20 +2237,11 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { ...@@ -2234,20 +2237,11 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
// a2 to contain either an AllocationSite or undefined. // a2 to contain either an AllocationSite or undefined.
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex); __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
Label call_generic_stub; // Tail call to the function-specific construct stub (still in the caller
// context at this point).
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
__ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); __ lw(t0, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kFlagsOffset)); __ lw(t0, FieldMemOperand(t0, SharedFunctionInfo::kConstructStubOffset));
__ And(t0, t0, Operand(SharedFunctionInfo::ConstructAsBuiltinBit::kMask)); __ Jump(at, t0, Code::kHeaderSize - kHeapObjectTag);
__ 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 // static
......
...@@ -434,6 +434,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn( ...@@ -434,6 +434,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) { MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false); Generate_JSConstructStubGeneric(masm, false);
} }
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm); Generate_JSBuiltinsConstructStubHelper(masm);
} }
...@@ -2253,20 +2256,12 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { ...@@ -2253,20 +2256,12 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
// a2 to contain either an AllocationSite or undefined. // a2 to contain either an AllocationSite or undefined.
__ LoadRoot(a2, Heap::kUndefinedValueRootIndex); __ LoadRoot(a2, Heap::kUndefinedValueRootIndex);
Label call_generic_stub; // Tail call to the function-specific construct stub (still in the caller
// context at this point).
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
__ Ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); __ Ld(a4, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
__ lwu(a4, FieldMemOperand(a4, SharedFunctionInfo::kFlagsOffset)); __ Ld(a4, FieldMemOperand(a4, SharedFunctionInfo::kConstructStubOffset));
__ And(a4, a4, Operand(SharedFunctionInfo::ConstructAsBuiltinBit::kMask)); __ Daddu(at, a4, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Branch(&call_generic_stub, eq, a4, Operand(zero_reg)); __ Jump(at);
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
RelocInfo::CODE_TARGET);
} }
// static // static
......
...@@ -448,6 +448,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn( ...@@ -448,6 +448,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) { MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false); Generate_JSConstructStubGeneric(masm, false);
} }
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm); Generate_JSBuiltinsConstructStubHelper(masm);
} }
......
...@@ -446,6 +446,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn( ...@@ -446,6 +446,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) { MacroAssembler* masm) {
Generate_JSConstructStubGeneric(masm, false); Generate_JSConstructStubGeneric(masm, false);
} }
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm); Generate_JSBuiltinsConstructStubHelper(masm);
} }
......
...@@ -385,6 +385,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn( ...@@ -385,6 +385,9 @@ void Builtins::Generate_JSConstructStubGenericUnrestrictedReturn(
MacroAssembler* masm) { MacroAssembler* masm) {
return Generate_JSConstructStubGeneric(masm, false); return Generate_JSConstructStubGeneric(masm, false);
} }
void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm);
}
void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) {
Generate_JSBuiltinsConstructStubHelper(masm); Generate_JSBuiltinsConstructStubHelper(masm);
} }
...@@ -2488,20 +2491,12 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { ...@@ -2488,20 +2491,12 @@ void Builtins::Generate_ConstructFunction(MacroAssembler* masm) {
// rbx to contain either an AllocationSite or undefined. // rbx to contain either an AllocationSite or undefined.
__ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex);
Label call_generic_stub; // Tail call to the function-specific construct stub (still in the caller
// context at this point).
// Jump to JSBuiltinsConstructStub or JSConstructStubGeneric.
__ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset)); __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
__ testl(FieldOperand(rcx, SharedFunctionInfo::kFlagsOffset), __ movp(rcx, FieldOperand(rcx, SharedFunctionInfo::kConstructStubOffset));
Immediate(SharedFunctionInfo::ConstructAsBuiltinBit::kMask)); __ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
__ j(zero, &call_generic_stub, Label::kNear); __ jmp(rcx);
__ Jump(BUILTIN_CODE(masm->isolate(), JSBuiltinsConstructStub),
RelocInfo::CODE_TARGET);
__ bind(&call_generic_stub);
__ Jump(masm->isolate()->builtins()->JSConstructStubGeneric(),
RelocInfo::CODE_TARGET);
} }
// static // static
......
...@@ -261,7 +261,9 @@ namespace { ...@@ -261,7 +261,9 @@ namespace {
// TODO(mstarzinger,verwaest): Move this predicate onto SharedFunctionInfo? // TODO(mstarzinger,verwaest): Move this predicate onto SharedFunctionInfo?
bool NeedsImplicitReceiver(Handle<SharedFunctionInfo> shared_info) { bool NeedsImplicitReceiver(Handle<SharedFunctionInfo> shared_info) {
DisallowHeapAllocation no_gc; DisallowHeapAllocation no_gc;
if (!shared_info->construct_as_builtin()) { Isolate* const isolate = shared_info->GetIsolate();
Code* const construct_stub = shared_info->construct_stub();
if (construct_stub == *isolate->builtins()->JSConstructStubGeneric()) {
return !IsDerivedConstructor(shared_info->kind()); return !IsDerivedConstructor(shared_info->kind());
} else { } else {
return false; return false;
......
...@@ -1561,6 +1561,8 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) { ...@@ -1561,6 +1561,8 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
Node* target = NodeProperties::GetValueInput(node, 0); Node* target = NodeProperties::GetValueInput(node, 0);
Type* target_type = NodeProperties::GetType(target); Type* target_type = NodeProperties::GetType(target);
Node* new_target = NodeProperties::GetValueInput(node, arity + 1); 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. // Check if {target} is a known JSFunction.
if (target_type->IsHeapConstant() && if (target_type->IsHeapConstant() &&
...@@ -1568,31 +1570,44 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) { ...@@ -1568,31 +1570,44 @@ Reduction JSTypedLowering::ReduceJSConstruct(Node* node) {
Handle<JSFunction> function = Handle<JSFunction> function =
Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value()); Handle<JSFunction>::cast(target_type->AsHeapConstant()->Value());
Handle<SharedFunctionInfo> shared(function->shared(), isolate()); 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. // Only optimize [[Construct]] here if {function} is a Constructor.
if (!function->IsConstructor()) return NoChange(); if (!function->IsConstructor()) return NoChange();
CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
// Patch {node} to an indirect call via the {function}s construct stub. if (is_builtin && Builtins::HasCppImplementation(builtin_index) &&
bool use_builtin_construct_stub = shared->construct_as_builtin(); !NeedsArgumentAdaptorFrame(shared, arity)) {
// Patch {node} to a direct CEntryStub call.
Handle<Code> code = // Load the context from the {target}.
use_builtin_construct_stub Node* context = effect = graph()->NewNode(
? BUILTIN_CODE(isolate(), JSBuiltinsConstructStub) simplified()->LoadField(AccessBuilder::ForJSFunctionContext()),
: BUILTIN_CODE(isolate(), JSConstructStubGenericUnrestrictedReturn); target, effect, control);
NodeProperties::ReplaceContextInput(node, context);
node->RemoveInput(arity + 1); // Update the effect dependency for the {node}.
node->InsertInput(graph()->zone(), 0, jsgraph()->HeapConstant(code)); NodeProperties::ReplaceEffectInput(node, effect);
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); return Changed(node);
} }
......
...@@ -2623,6 +2623,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( ...@@ -2623,6 +2623,7 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
share->set_builtin_id(Builtins::kIllegal); share->set_builtin_id(Builtins::kIllegal);
} }
share->set_outer_scope_info(*the_hole_value()); share->set_outer_scope_info(*the_hole_value());
share->SetConstructStub(*isolate()->builtins()->JSConstructStubGeneric());
share->set_script(*undefined_value(), SKIP_WRITE_BARRIER); share->set_script(*undefined_value(), SKIP_WRITE_BARRIER);
share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER); share->set_debug_info(Smi::kZero, SKIP_WRITE_BARRIER);
share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER); share->set_function_identifier(*undefined_value(), SKIP_WRITE_BARRIER);
...@@ -2642,7 +2643,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( ...@@ -2642,7 +2643,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
share->set_function_token_position(0); share->set_function_token_position(0);
// All flags default to false or 0. // All flags default to false or 0.
share->set_flags(0); share->set_flags(0);
share->CalculateConstructAsBuiltin();
share->set_kind(kind); share->set_kind(kind);
share->clear_padding(); share->clear_padding();
......
...@@ -879,19 +879,6 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() { ...@@ -879,19 +879,6 @@ void SharedFunctionInfo::SharedFunctionInfoVerify() {
CHECK_EQ(raw_start_position(), info->StartPosition()); CHECK_EQ(raw_start_position(), info->StartPosition());
CHECK_EQ(raw_end_position(), info->EndPosition()); 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,15 +1209,21 @@ Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo( ...@@ -1209,15 +1209,21 @@ Handle<SharedFunctionInfo> FunctionTemplateInfo::GetOrCreateSharedFunctionInfo(
} else { } else {
name_string = isolate->factory()->empty_string(); name_string = isolate->factory()->empty_string();
} }
bool is_constructor;
FunctionKind function_kind; FunctionKind function_kind;
if (info->remove_prototype()) { if (info->remove_prototype()) {
is_constructor = false;
function_kind = kConciseMethod; function_kind = kConciseMethod;
} else { } else {
is_constructor = true;
function_kind = kNormalFunction; function_kind = kNormalFunction;
} }
Handle<SharedFunctionInfo> result = Handle<SharedFunctionInfo> result =
isolate->factory()->NewSharedFunctionInfoForApiFunction(name_string, info, isolate->factory()->NewSharedFunctionInfoForApiFunction(name_string, info,
function_kind); function_kind);
if (is_constructor) {
result->SetConstructStub(*BUILTIN_CODE(isolate, JSConstructStubApi));
}
result->set_length(info->length()); result->set_length(info->length());
result->DontAdaptArguments(); result->DontAdaptArguments();
...@@ -13872,6 +13878,8 @@ void SharedFunctionInfo::InitFromFunctionLiteral( ...@@ -13872,6 +13878,8 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
// shared_info->set_kind(lit->kind()); // shared_info->set_kind(lit->kind());
// FunctionKind must have already been set. // FunctionKind must have already been set.
DCHECK(lit->kind() == shared_info->kind()); 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_needs_home_object(lit->scope()->NeedsHomeObject());
shared_info->set_function_literal_id(lit->function_literal_id()); shared_info->set_function_literal_id(lit->function_literal_id());
DCHECK_IMPLIES(lit->requires_instance_fields_initializer(), DCHECK_IMPLIES(lit->requires_instance_fields_initializer(),
...@@ -13922,6 +13930,23 @@ void SharedFunctionInfo::SetExpectedNofPropertiesFromEstimate( ...@@ -13922,6 +13930,23 @@ void SharedFunctionInfo::SetExpectedNofPropertiesFromEstimate(
set_expected_nof_properties(estimate); 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() { void Map::StartInobjectSlackTracking() {
DCHECK(!IsInobjectSlackTrackingInProgress()); DCHECK(!IsInobjectSlackTrackingInProgress());
if (UnusedPropertyFields() == 0) return; if (UnusedPropertyFields() == 0) return;
......
...@@ -25,6 +25,7 @@ DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object) ...@@ -25,6 +25,7 @@ DEFINE_DEOPT_ELEMENT_ACCESSORS(SharedFunctionInfo, Object)
ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object, ACCESSORS(SharedFunctionInfo, name_or_scope_info, Object,
kNameOrScopeInfoOffset) kNameOrScopeInfoOffset)
ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
ACCESSORS(SharedFunctionInfo, feedback_metadata, FeedbackMetadata, ACCESSORS(SharedFunctionInfo, feedback_metadata, FeedbackMetadata,
kFeedbackMetadataOffset) kFeedbackMetadataOffset)
ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset) ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
...@@ -160,26 +161,6 @@ void SharedFunctionInfo::set_needs_home_object(bool value) { ...@@ -160,26 +161,6 @@ void SharedFunctionInfo::set_needs_home_object(bool value) {
UpdateFunctionMapIndex(); 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 { int SharedFunctionInfo::function_map_index() const {
// Note: Must be kept in sync with the FastNewClosure builtin. // Note: Must be kept in sync with the FastNewClosure builtin.
int index = int index =
......
...@@ -96,6 +96,13 @@ class SharedFunctionInfo : public HeapObject { ...@@ -96,6 +96,13 @@ class SharedFunctionInfo : public HeapObject {
// value if it isn't yet known. // value if it isn't yet known.
DECL_ACCESSORS(outer_scope_info, HeapObject) 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. // Returns if this function has been compiled to native code yet.
inline bool is_compiled() const; inline bool is_compiled() const;
...@@ -379,15 +386,6 @@ class SharedFunctionInfo : public HeapObject { ...@@ -379,15 +386,6 @@ class SharedFunctionInfo : public HeapObject {
// Sets the expected number of properties based on estimate from parser. // Sets the expected number of properties based on estimate from parser.
void SetExpectedNofPropertiesFromEstimate(FunctionLiteral* literal); 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. // Dispatched behavior.
DECL_PRINTER(SharedFunctionInfo) DECL_PRINTER(SharedFunctionInfo)
DECL_VERIFIER(SharedFunctionInfo) DECL_VERIFIER(SharedFunctionInfo)
...@@ -446,6 +444,7 @@ class SharedFunctionInfo : public HeapObject { ...@@ -446,6 +444,7 @@ class SharedFunctionInfo : public HeapObject {
V(kFunctionDataOffset, kPointerSize) \ V(kFunctionDataOffset, kPointerSize) \
V(kNameOrScopeInfoOffset, kPointerSize) \ V(kNameOrScopeInfoOffset, kPointerSize) \
V(kOuterScopeInfoOffset, kPointerSize) \ V(kOuterScopeInfoOffset, kPointerSize) \
V(kConstructStubOffset, kPointerSize) \
V(kScriptOffset, kPointerSize) \ V(kScriptOffset, kPointerSize) \
V(kDebugInfoOffset, kPointerSize) \ V(kDebugInfoOffset, kPointerSize) \
V(kFunctionIdentifierOffset, kPointerSize) \ V(kFunctionIdentifierOffset, kPointerSize) \
...@@ -500,8 +499,7 @@ class SharedFunctionInfo : public HeapObject { ...@@ -500,8 +499,7 @@ class SharedFunctionInfo : public HeapObject {
V(IsAsmWasmBrokenBit, bool, 1, _) \ V(IsAsmWasmBrokenBit, bool, 1, _) \
V(FunctionMapIndexBits, int, 5, _) \ V(FunctionMapIndexBits, int, 5, _) \
V(DisabledOptimizationReasonBits, BailoutReason, 4, _) \ V(DisabledOptimizationReasonBits, BailoutReason, 4, _) \
V(RequiresInstanceFieldsInitializer, bool, 1, _) \ V(RequiresInstanceFieldsInitializer, bool, 1, _)
V(ConstructAsBuiltinBit, bool, 1, _)
DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS) DEFINE_BIT_FIELDS(FLAGS_BIT_FIELDS)
#undef FLAGS_BIT_FIELDS #undef FLAGS_BIT_FIELDS
......
...@@ -1167,6 +1167,13 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences( ...@@ -1167,6 +1167,13 @@ void V8HeapExplorer::ExtractSharedFunctionInfoReferences(
SetInternalReference(obj, entry, SetInternalReference(obj, entry,
"script", shared->script(), "script", shared->script(),
SharedFunctionInfo::kScriptOffset); 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, SetInternalReference(obj, entry,
"function_data", shared->function_data(), "function_data", shared->function_data(),
SharedFunctionInfo::kFunctionDataOffset); SharedFunctionInfo::kFunctionDataOffset);
......
...@@ -139,16 +139,13 @@ TEST(StressJS) { ...@@ -139,16 +139,13 @@ TEST(StressJS) {
v8::HandleScope scope(CcTest::isolate()); v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::Context> env = v8::Context::New(CcTest::isolate()); v8::Local<v8::Context> env = v8::Context::New(CcTest::isolate());
env->Enter(); env->Enter();
Handle<JSFunction> function =
NewFunctionArgs args = NewFunctionArgs::ForBuiltin( factory->NewFunctionForTest(factory->function_string());
factory->function_string(), isolate->sloppy_function_map(), // Force the creation of an initial map and set the code to
Builtins::kEmptyFunction); // something empty.
Handle<JSFunction> function = factory->NewFunction(args);
CHECK(!function->shared()->construct_as_builtin());
// Force the creation of an initial map.
factory->NewJSObject(function); factory->NewJSObject(function);
function->set_code(
CcTest::i_isolate()->builtins()->builtin(Builtins::kEmptyFunction));
// Patch the map to have an accessor for "get". // Patch the map to have an accessor for "get".
Handle<Map> map(function->initial_map()); Handle<Map> map(function->initial_map());
Handle<DescriptorArray> instance_descriptors(map->instance_descriptors()); Handle<DescriptorArray> instance_descriptors(map->instance_descriptors());
......
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