Support circular references between generated builtins.

Until now, when generating a builtin, it can only embed builtins
(as call targets) that have already been generated. This is either
achieved by reordering the builtins list, or by loading the call
target at runtime from the builtins list (see
MacroAssembler::TailCallBuiltin).

This patch works around this issue by filling the builtins list
with dummy code objects, which are later replaced with the completed
actual builtins. In release mode, this adds around 3ms to 140ms we
previously needed to populate the builtins list. 

Change-Id: I7d451b3c09a1db4b9e755548102a80c7f0dfada2
Reviewed-on: https://chromium-review.googlesource.com/586531
Commit-Queue: Yang Guo <yangguo@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47062}
This commit is contained in:
Yang Guo 2017-08-01 15:11:36 +02:00 committed by Commit Bot
parent b4b32df0b4
commit 266be35b3b
39 changed files with 184 additions and 343 deletions

View File

@ -1079,18 +1079,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
// r3: argc // r3: argc
// r4: argv // r4: argv
if (type() == StackFrame::ENTRY_CONSTRUCT) { if (type() == StackFrame::ENTRY_CONSTRUCT) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline, __ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
isolate()); RelocInfo::CODE_TARGET);
__ mov(scratch, Operand(construct_entry));
} else { } else {
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate()); __ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
__ mov(scratch, Operand(entry));
} }
__ ldr(scratch, MemOperand(scratch)); // deref address
__ add(scratch, scratch, Operand(Code::kHeaderSize - kHeapObjectTag));
// Branch and link to JSEntryTrampoline.
__ Call(scratch);
// Unlink this frame from the handler chain. // Unlink this frame from the handler chain.
__ PopStackHandler(); __ PopStackHandler();

View File

@ -2104,13 +2104,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
} }
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
mov(r5, Operand(ExternalReference(Builtins::kConstructProxy, isolate())));
ldr(r5, MemOperand(r5));
add(pc, r5, Operand(Code::kHeaderSize - kHeapObjectTag));
}
bool TurboAssembler::AllowThisStubCall(CodeStub* stub) { bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
return has_frame() || !stub->SometimesSetsUpAFrame(); return has_frame() || !stub->SometimesSetsUpAFrame();
} }

View File

@ -1025,9 +1025,6 @@ class MacroAssembler : public TurboAssembler {
// Call a code stub. // Call a code stub.
void TailCallStub(CodeStub* stub, Condition cond = al); void TailCallStub(CodeStub* stub, Condition cond = al);
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
// Call a runtime routine. // Call a runtime routine.
void CallRuntime(const Runtime::Function* f, void CallRuntime(const Runtime::Function* f,
int num_arguments, int num_arguments,

View File

@ -1146,16 +1146,13 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
// x2: receiver. // x2: receiver.
// x3: argc. // x3: argc.
// x4: argv. // x4: argv.
ExternalReference entry(type() == StackFrame::ENTRY_CONSTRUCT
? Builtins::kJSConstructEntryTrampoline
: Builtins::kJSEntryTrampoline,
isolate());
__ Mov(x10, entry);
// Call the JSEntryTrampoline. if (type() == StackFrame::ENTRY_CONSTRUCT) {
__ Ldr(x11, MemOperand(x10)); // Dereference the address. __ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
__ Add(x12, x11, Code::kHeaderSize - kHeapObjectTag); RelocInfo::CODE_TARGET);
__ Blr(x12); } else {
__ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
}
// Unlink this frame from the handler chain. // Unlink this frame from the handler chain.
__ PopStackHandler(); __ PopStackHandler();

View File

@ -1778,14 +1778,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub) {
Jump(stub->GetCode(), RelocInfo::CODE_TARGET); Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
} }
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
Mov(x5, ExternalReference(Builtins::kConstructProxy, isolate()));
Ldr(x5, MemOperand(x5));
Add(x6, x5, Code::kHeaderSize - kHeapObjectTag);
Br(x6);
}
void TurboAssembler::CallRuntimeDelayed(Zone* zone, Runtime::FunctionId fid, void TurboAssembler::CallRuntimeDelayed(Zone* zone, Runtime::FunctionId fid,
SaveFPRegsMode save_doubles) { SaveFPRegsMode save_doubles) {
const Runtime::Function* f = Runtime::FunctionForId(fid); const Runtime::Function* f = Runtime::FunctionForId(fid);

View File

@ -1834,9 +1834,6 @@ class MacroAssembler : public TurboAssembler {
void CallStub(CodeStub* stub); void CallStub(CodeStub* stub);
void TailCallStub(CodeStub* stub); void TailCallStub(CodeStub* stub);
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
void CallRuntime(const Runtime::Function* f, void CallRuntime(const Runtime::Function* f,
int num_arguments, int num_arguments,
SaveFPRegsMode save_doubles = kDontSaveFPRegs); SaveFPRegsMode save_doubles = kDontSaveFPRegs);

View File

@ -837,10 +837,6 @@ ExternalReference::ExternalReference(
: address_(Redirect(isolate, fun->address(), type)) {} : address_(Redirect(isolate, fun->address(), type)) {}
ExternalReference::ExternalReference(Builtins::Name name, Isolate* isolate)
: address_(isolate->builtins()->builtin_address(name)) {}
ExternalReference::ExternalReference(Runtime::FunctionId id, Isolate* isolate) ExternalReference::ExternalReference(Runtime::FunctionId id, Isolate* isolate)
: ExternalReference(Runtime::FunctionForId(id), isolate) {} : ExternalReference(Runtime::FunctionForId(id), isolate) {}

View File

@ -823,8 +823,6 @@ class ExternalReference BASE_EMBEDDED {
ExternalReference(ApiFunction* ptr, Type type, Isolate* isolate); ExternalReference(ApiFunction* ptr, Type type, Isolate* isolate);
ExternalReference(Builtins::Name name, Isolate* isolate);
ExternalReference(Runtime::FunctionId id, Isolate* isolate); ExternalReference(Runtime::FunctionId id, Isolate* isolate);
ExternalReference(const Runtime::Function* f, Isolate* isolate); ExternalReference(const Runtime::Function* f, Isolate* isolate);

View File

@ -2394,11 +2394,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
// Call the [[BoundTargetFunction]] via the Call builtin. // Call the [[BoundTargetFunction]] via the Call builtin.
__ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset)); __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
__ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
__ mov(r3, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, RelocInfo::CODE_TARGET);
masm->isolate())));
__ ldr(r3, MemOperand(r3));
__ add(pc, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
} }
// static // static
@ -2426,10 +2423,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
// Check if target is a proxy and call CallProxy external builtin // Check if target is a proxy and call CallProxy external builtin
__ cmp(r5, Operand(JS_PROXY_TYPE)); __ cmp(r5, Operand(JS_PROXY_TYPE));
__ b(ne, &non_function); __ b(ne, &non_function);
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
__ mov(r5, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate())));
__ ldr(r5, MemOperand(r5));
__ add(pc, r5, Operand(Code::kHeaderSize - kHeapObjectTag));
// 2. Call to something else, which might have a [[Call]] internal method (if // 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception). // not we raise an exception).
@ -2490,10 +2484,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
// Construct the [[BoundTargetFunction]] via the Construct builtin. // Construct the [[BoundTargetFunction]] via the Construct builtin.
__ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset)); __ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
__ mov(r2, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
__ ldr(r2, MemOperand(r2));
__ add(pc, r2, Operand(Code::kHeaderSize - kHeapObjectTag));
} }
// static // static
@ -2528,8 +2519,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors. // Only dispatch to proxies after checking whether they are constructors.
__ cmp(r5, Operand(JS_PROXY_TYPE)); __ cmp(r5, Operand(JS_PROXY_TYPE));
__ b(ne, &non_proxy); __ b(ne, &non_proxy);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
__ TailCallBuiltin(Builtins::kConstructProxy); RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method. // Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy); __ bind(&non_proxy);

View File

@ -2489,11 +2489,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
// Call the [[BoundTargetFunction]] via the Call builtin. // Call the [[BoundTargetFunction]] via the Call builtin.
__ Ldr(x1, FieldMemOperand(x1, JSBoundFunction::kBoundTargetFunctionOffset)); __ Ldr(x1, FieldMemOperand(x1, JSBoundFunction::kBoundTargetFunctionOffset));
__ Mov(x10, __ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate())); RelocInfo::CODE_TARGET);
__ Ldr(x11, MemOperand(x10));
__ Add(x12, x11, Code::kHeaderSize - kHeapObjectTag);
__ Br(x12);
} }
// static // static
@ -2520,11 +2517,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
// Check if target is a proxy and call CallProxy external builtin // Check if target is a proxy and call CallProxy external builtin
__ Cmp(x5, JS_PROXY_TYPE); __ Cmp(x5, JS_PROXY_TYPE);
__ B(ne, &non_function); __ B(ne, &non_function);
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
__ Mov(x5, ExternalReference(Builtins::kCallProxy, masm->isolate()));
__ Ldr(x5, MemOperand(x5));
__ Add(x6, x5, Code::kHeaderSize - kHeapObjectTag);
__ Br(x6);
// 2. Call to something else, which might have a [[Call]] internal method (if // 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception). // not we raise an exception).
@ -2591,10 +2584,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
// Construct the [[BoundTargetFunction]] via the Construct builtin. // Construct the [[BoundTargetFunction]] via the Construct builtin.
__ Ldr(x1, FieldMemOperand(x1, JSBoundFunction::kBoundTargetFunctionOffset)); __ Ldr(x1, FieldMemOperand(x1, JSBoundFunction::kBoundTargetFunctionOffset));
__ Mov(x10, ExternalReference(Builtins::kConstruct, masm->isolate())); __ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
__ Ldr(x11, MemOperand(x10));
__ Add(x12, x11, Code::kHeaderSize - kHeapObjectTag);
__ Br(x12);
} }
// static // static
@ -2628,8 +2618,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors. // Only dispatch to proxies after checking whether they are constructors.
__ Cmp(x5, JS_PROXY_TYPE); __ Cmp(x5, JS_PROXY_TYPE);
__ B(ne, &non_proxy); __ B(ne, &non_proxy);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
__ TailCallBuiltin(Builtins::kConstructProxy); RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method. // Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy); __ bind(&non_proxy);

View File

@ -46,16 +46,9 @@ namespace internal {
// Args: name // Args: name
#define BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM, DBG) \ #define BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM, DBG) \
ASM(Abort) \
/* Code aging */ \ /* Code aging */ \
CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, ASM) \ CODE_AGE_LIST_WITH_ARG(DECLARE_CODE_AGE_BUILTIN, ASM) \
\ \
/* Declared first for dependency reasons */ \
ASM(CompileLazy) \
TFC(ToObject, TypeConversion, 1) \
TFC(FastNewObject, FastNewObject, 1) \
TFS(HasProperty, kKey, kObject) \
\
/* Calls */ \ /* Calls */ \
ASM(ArgumentsAdaptorTrampoline) \ ASM(ArgumentsAdaptorTrampoline) \
/* ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) */ \ /* ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) */ \
@ -94,6 +87,7 @@ namespace internal {
ASM(JSConstructStubGenericRestrictedReturn) \ ASM(JSConstructStubGenericRestrictedReturn) \
ASM(JSConstructStubGenericUnrestrictedReturn) \ ASM(JSConstructStubGenericUnrestrictedReturn) \
ASM(JSBuiltinsConstructStub) \ ASM(JSBuiltinsConstructStub) \
TFC(FastNewObject, FastNewObject, 1) \
TFC(FastNewClosure, FastNewClosure, 1) \ TFC(FastNewClosure, FastNewClosure, 1) \
TFC(FastNewFunctionContextEval, FastNewFunctionContext, 1) \ TFC(FastNewFunctionContextEval, FastNewFunctionContext, 1) \
TFC(FastNewFunctionContextFunction, FastNewFunctionContext, 1) \ TFC(FastNewFunctionContextFunction, FastNewFunctionContext, 1) \
@ -146,6 +140,7 @@ namespace internal {
ASM(InterpreterOnStackReplacement) \ ASM(InterpreterOnStackReplacement) \
\ \
/* Code life-cycle */ \ /* Code life-cycle */ \
ASM(CompileLazy) \
ASM(CheckOptimizationMarker) \ ASM(CheckOptimizationMarker) \
ASM(InstantiateAsmJs) \ ASM(InstantiateAsmJs) \
ASM(MarkCodeAsToBeExecutedOnce) \ ASM(MarkCodeAsToBeExecutedOnce) \
@ -205,6 +200,7 @@ namespace internal {
DBG(Slot_DebugBreak) \ DBG(Slot_DebugBreak) \
\ \
/* Type conversions */ \ /* Type conversions */ \
TFC(ToObject, TypeConversion, 1) \
TFC(ToBoolean, TypeConversion, 1) \ TFC(ToBoolean, TypeConversion, 1) \
TFC(OrdinaryToPrimitive_Number, TypeConversion, 1) \ TFC(OrdinaryToPrimitive_Number, TypeConversion, 1) \
TFC(OrdinaryToPrimitive_String, TypeConversion, 1) \ TFC(OrdinaryToPrimitive_String, TypeConversion, 1) \
@ -251,11 +247,19 @@ namespace internal {
TFH(StoreIC_Uninitialized, BUILTIN, kNoExtraICState, StoreWithVector) \ TFH(StoreIC_Uninitialized, BUILTIN, kNoExtraICState, StoreWithVector) \
TFH(StoreICStrict_Uninitialized, BUILTIN, kNoExtraICState, StoreWithVector) \ TFH(StoreICStrict_Uninitialized, BUILTIN, kNoExtraICState, StoreWithVector) \
\ \
/* Promise helpers */ \
TFS(ResolveNativePromise, kPromise, kValue) \ TFS(ResolveNativePromise, kPromise, kValue) \
TFS(RejectNativePromise, kPromise, kValue, kDebugEvent) \ TFS(RejectNativePromise, kPromise, kValue, kDebugEvent) \
TFS(PerformNativePromiseThen, kPromise, kResolveReaction, kRejectReaction, \ TFS(PerformNativePromiseThen, kPromise, kResolveReaction, kRejectReaction, \
kResultPromise) \ kResultPromise) \
\ \
/* Object property helpers */ \
TFS(HasProperty, kKey, kObject) \
TFS(DeleteProperty, kObject, kKey, kLanguageMode) \
\
/* Abort */ \
ASM(Abort) \
\
/* Built-in functions for Javascript */ \ /* Built-in functions for Javascript */ \
/* Special internal builtins */ \ /* Special internal builtins */ \
CPP(EmptyFunction) \ CPP(EmptyFunction) \
@ -264,8 +268,6 @@ namespace internal {
CPP(UnsupportedThrower) \ CPP(UnsupportedThrower) \
TFJ(ReturnReceiver, 0) \ TFJ(ReturnReceiver, 0) \
\ \
TFS(DeleteProperty, kObject, kKey, kLanguageMode) \
\
/* Array */ \ /* Array */ \
ASM(ArrayCode) \ ASM(ArrayCode) \
ASM(InternalArrayCode) \ ASM(InternalArrayCode) \
@ -815,9 +817,6 @@ namespace internal {
CPP(ReflectSetPrototypeOf) \ CPP(ReflectSetPrototypeOf) \
\ \
/* RegExp */ \ /* RegExp */ \
TFS(RegExpExecAtom, kRegExp, kString, kLastIndex, kMatchInfo) \
TFS(RegExpPrototypeExecSlow, kReceiver, kString) \
\
CPP(RegExpCapture1Getter) \ CPP(RegExpCapture1Getter) \
CPP(RegExpCapture2Getter) \ CPP(RegExpCapture2Getter) \
CPP(RegExpCapture3Getter) \ CPP(RegExpCapture3Getter) \
@ -864,13 +863,15 @@ namespace internal {
TFJ(RegExpPrototypeUnicodeGetter, 0) \ TFJ(RegExpPrototypeUnicodeGetter, 0) \
CPP(RegExpRightContextGetter) \ CPP(RegExpRightContextGetter) \
\ \
TFS(RegExpReplace, kRegExp, kString, kReplaceValue) \
/* ES #sec-regexp.prototype-@@replace */ \ /* ES #sec-regexp.prototype-@@replace */ \
TFJ(RegExpPrototypeReplace, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ TFJ(RegExpPrototypeReplace, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
\
TFS(RegExpSplit, kRegExp, kString, kLimit) \
/* ES #sec-regexp.prototype-@@split */ \ /* ES #sec-regexp.prototype-@@split */ \
TFJ(RegExpPrototypeSplit, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ TFJ(RegExpPrototypeSplit, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
/* RegExp helpers */ \
TFS(RegExpExecAtom, kRegExp, kString, kLastIndex, kMatchInfo) \
TFS(RegExpPrototypeExecSlow, kReceiver, kString) \
TFS(RegExpReplace, kRegExp, kString, kReplaceValue) \
TFS(RegExpSplit, kRegExp, kString, kLimit) \
\ \
/* Set */ \ /* Set */ \
TFJ(SetConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ TFJ(SetConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \

View File

@ -2567,10 +2567,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
// Call the [[BoundTargetFunction]] via the Call builtin. // Call the [[BoundTargetFunction]] via the Call builtin.
__ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
__ mov(ecx, Operand::StaticVariable(ExternalReference( __ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
Builtins::kCall_ReceiverIsAny, masm->isolate()))); RelocInfo::CODE_TARGET);
__ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
__ jmp(ecx);
} }
// static // static
@ -2598,11 +2596,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
// Call CallProxy external builtin // Call CallProxy external builtin
__ CmpInstanceType(ecx, JS_PROXY_TYPE); __ CmpInstanceType(ecx, JS_PROXY_TYPE);
__ j(not_equal, &non_function); __ j(not_equal, &non_function);
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
__ mov(ecx, Operand::StaticVariable(
ExternalReference(Builtins::kCallProxy, masm->isolate())));
__ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
__ jmp(ecx);
// 2. Call to something else, which might have a [[Call]] internal method (if // 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception). // not we raise an exception).
@ -2668,10 +2662,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
// Construct the [[BoundTargetFunction]] via the Construct builtin. // Construct the [[BoundTargetFunction]] via the Construct builtin.
__ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset)); __ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
__ mov(ecx, Operand::StaticVariable( __ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
ExternalReference(Builtins::kConstruct, masm->isolate())));
__ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
__ jmp(ecx);
} }
// static // static
@ -2706,8 +2697,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors. // Only dispatch to proxies after checking whether they are constructors.
__ CmpInstanceType(ecx, JS_PROXY_TYPE); __ CmpInstanceType(ecx, JS_PROXY_TYPE);
__ j(not_equal, &non_proxy); __ j(not_equal, &non_proxy);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
__ TailCallBuiltin(Builtins::kConstructProxy); RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method. // Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy); __ bind(&non_proxy);

View File

@ -2376,10 +2376,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
// Call the [[BoundTargetFunction]] via the Call builtin. // Call the [[BoundTargetFunction]] via the Call builtin.
__ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); __ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
__ li(at, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, __ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
masm->isolate()))); RelocInfo::CODE_TARGET);
__ lw(at, MemOperand(at));
__ Jump(at, Code::kHeaderSize - kHeapObjectTag);
} }
// static // static
@ -2405,9 +2403,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
// Check if target is a proxy and call CallProxy external builtin // Check if target is a proxy and call CallProxy external builtin
__ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE)); __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE));
__ li(t2, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate()))); __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
__ lw(t2, MemOperand(t2));
__ Jump(t2, Operand(Code::kHeaderSize - kHeapObjectTag));
// 2. Call to something else, which might have a [[Call]] internal method (if // 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception). // not we raise an exception).
@ -2535,9 +2531,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
// Construct the [[BoundTargetFunction]] via the Construct builtin. // Construct the [[BoundTargetFunction]] via the Construct builtin.
__ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); __ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
__ li(at, Operand(ExternalReference(Builtins::kConstruct, masm->isolate()))); __ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
__ lw(at, MemOperand(at));
__ Jump(at, Code::kHeaderSize - kHeapObjectTag);
} }
// static // static
@ -2571,8 +2565,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors. // Only dispatch to proxies after checking whether they are constructors.
__ Branch(&non_proxy, ne, t2, Operand(JS_PROXY_TYPE)); __ Branch(&non_proxy, ne, t2, Operand(JS_PROXY_TYPE));
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
__ TailCallBuiltin(Builtins::kConstructProxy); RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method. // Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy); __ bind(&non_proxy);

View File

@ -2404,11 +2404,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
// Call the [[BoundTargetFunction]] via the Call builtin. // Call the [[BoundTargetFunction]] via the Call builtin.
__ Ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); __ Ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
__ li(at, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, __ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
masm->isolate()))); RelocInfo::CODE_TARGET);
__ Ld(at, MemOperand(at));
__ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(at);
} }
// static // static
@ -2433,10 +2430,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
__ Branch(&non_callable, eq, t1, Operand(zero_reg)); __ Branch(&non_callable, eq, t1, Operand(zero_reg));
__ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE)); __ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE));
__ li(t2, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate()))); __ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
__ Ld(t2, MemOperand(t2));
__ Daddu(t2, t2, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(t2);
// 2. Call to something else, which might have a [[Call]] internal method (if // 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception). // not we raise an exception).
@ -2562,10 +2556,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
// Construct the [[BoundTargetFunction]] via the Construct builtin. // Construct the [[BoundTargetFunction]] via the Construct builtin.
__ Ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset)); __ Ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
__ li(at, Operand(ExternalReference(Builtins::kConstruct, masm->isolate()))); __ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
__ Ld(at, MemOperand(at));
__ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
__ Jump(at);
} }
// static // static
@ -2599,8 +2590,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors. // Only dispatch to proxies after checking whether they are constructors.
__ Branch(&non_proxy, ne, t2, Operand(JS_PROXY_TYPE)); __ Branch(&non_proxy, ne, t2, Operand(JS_PROXY_TYPE));
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
__ TailCallBuiltin(Builtins::kConstructProxy); RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method. // Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy); __ bind(&non_proxy);

View File

@ -2479,11 +2479,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
// Call the [[BoundTargetFunction]] via the Call builtin. // Call the [[BoundTargetFunction]] via the Call builtin.
__ LoadP(r4, __ LoadP(r4,
FieldMemOperand(r4, JSBoundFunction::kBoundTargetFunctionOffset)); FieldMemOperand(r4, JSBoundFunction::kBoundTargetFunctionOffset));
__ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, __ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
masm->isolate()))); RelocInfo::CODE_TARGET);
__ LoadP(ip, MemOperand(ip));
__ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
__ JumpToJSEntry(ip);
} }
// static // static
@ -2511,11 +2508,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
// Check if target is a proxy and call CallProxy external builtin // Check if target is a proxy and call CallProxy external builtin
__ cmpi(r8, Operand(JS_PROXY_TYPE)); __ cmpi(r8, Operand(JS_PROXY_TYPE));
__ bne(&non_function); __ bne(&non_function);
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
__ mov(r8, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate())));
__ LoadP(r8, MemOperand(r8));
__ addi(r8, r8, Operand(Code::kHeaderSize - kHeapObjectTag));
__ JumpToJSEntry(r8);
// 2. Call to something else, which might have a [[Call]] internal method (if // 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception). // not we raise an exception).
@ -2582,10 +2575,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
// Construct the [[BoundTargetFunction]] via the Construct builtin. // Construct the [[BoundTargetFunction]] via the Construct builtin.
__ LoadP(r4, __ LoadP(r4,
FieldMemOperand(r4, JSBoundFunction::kBoundTargetFunctionOffset)); FieldMemOperand(r4, JSBoundFunction::kBoundTargetFunctionOffset));
__ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate()))); __ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
__ LoadP(ip, MemOperand(ip));
__ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
__ JumpToJSEntry(ip);
} }
// static // static
@ -2620,8 +2610,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors. // Only dispatch to proxies after checking whether they are constructors.
__ cmpi(r8, Operand(JS_PROXY_TYPE)); __ cmpi(r8, Operand(JS_PROXY_TYPE));
__ bne(&non_proxy); __ bne(&non_proxy);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
__ TailCallBuiltin(Builtins::kConstructProxy); RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method. // Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy); __ bind(&non_proxy);

View File

@ -2480,11 +2480,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
// Call the [[BoundTargetFunction]] via the Call builtin. // Call the [[BoundTargetFunction]] via the Call builtin.
__ LoadP(r3, __ LoadP(r3,
FieldMemOperand(r3, JSBoundFunction::kBoundTargetFunctionOffset)); FieldMemOperand(r3, JSBoundFunction::kBoundTargetFunctionOffset));
__ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny, __ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
masm->isolate()))); RelocInfo::CODE_TARGET);
__ LoadP(ip, MemOperand(ip));
__ AddP(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
__ JumpToJSEntry(ip);
} }
// static // static
@ -2512,11 +2509,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
// Check if target is a proxy and call CallProxy external builtin // Check if target is a proxy and call CallProxy external builtin
__ CmpP(r7, Operand(JS_PROXY_TYPE)); __ CmpP(r7, Operand(JS_PROXY_TYPE));
__ bne(&non_function); __ bne(&non_function);
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
__ mov(r7, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate())));
__ LoadP(r7, MemOperand(r7));
__ AddP(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag));
__ JumpToJSEntry(r7);
// 2. Call to something else, which might have a [[Call]] internal method (if // 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception). // not we raise an exception).
@ -2583,10 +2576,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
// Construct the [[BoundTargetFunction]] via the Construct builtin. // Construct the [[BoundTargetFunction]] via the Construct builtin.
__ LoadP(r3, __ LoadP(r3,
FieldMemOperand(r3, JSBoundFunction::kBoundTargetFunctionOffset)); FieldMemOperand(r3, JSBoundFunction::kBoundTargetFunctionOffset));
__ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate()))); __ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
__ LoadP(ip, MemOperand(ip));
__ AddP(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
__ JumpToJSEntry(ip);
} }
// static // static
@ -2621,8 +2611,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors. // Only dispatch to proxies after checking whether they are constructors.
__ CmpP(r7, Operand(JS_PROXY_TYPE)); __ CmpP(r7, Operand(JS_PROXY_TYPE));
__ bne(&non_proxy); __ bne(&non_proxy);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
__ TailCallBuiltin(Builtins::kConstructProxy); RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method. // Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy); __ bind(&non_proxy);

View File

@ -37,6 +37,27 @@ void PostBuildProfileAndTracing(Isolate* isolate, Code* code,
typedef void (*MacroAssemblerGenerator)(MacroAssembler*); typedef void (*MacroAssemblerGenerator)(MacroAssembler*);
typedef void (*CodeAssemblerGenerator)(compiler::CodeAssemblerState*); typedef void (*CodeAssemblerGenerator)(compiler::CodeAssemblerState*);
static const ExtraICState kPlaceholderState = 1;
Handle<Code> BuildPlaceholder(Isolate* isolate) {
HandleScope scope(isolate);
const size_t buffer_size = 1 * KB;
byte buffer[buffer_size]; // NOLINT(runtime/arrays)
MacroAssembler masm(isolate, buffer, buffer_size, CodeObjectRequired::kYes);
DCHECK(!masm.has_frame());
{
FrameScope scope(&masm, StackFrame::NONE);
masm.CallRuntime(Runtime::kSystemBreak);
}
CodeDesc desc;
masm.GetCode(isolate, &desc);
const Code::Flags kPlaceholderFlags =
Code::ComputeFlags(Code::BUILTIN, kPlaceholderState);
Handle<Code> code =
isolate->factory()->NewCode(desc, kPlaceholderFlags, masm.CodeObject());
return scope.CloseAndEscape(code);
}
Code* BuildWithMacroAssembler(Isolate* isolate, Code* BuildWithMacroAssembler(Isolate* isolate,
MacroAssemblerGenerator generator, MacroAssemblerGenerator generator,
Code::Flags flags, const char* s_name) { Code::Flags flags, const char* s_name) {
@ -127,10 +148,77 @@ void SetupIsolateDelegate::AddBuiltin(Builtins* builtins, int index,
code->set_builtin_index(index); code->set_builtin_index(index);
} }
void SetupIsolateDelegate::PopulateWithPlaceholders(Isolate* isolate) {
// Fill the builtins list with placeholders. References to these placeholder
// builtins are eventually replaced by the actual builtins. This is to
// support circular references between builtins.
Builtins* builtins = isolate->builtins();
HandleScope scope(isolate);
Handle<Code> placeholder = BuildPlaceholder(isolate);
AddBuiltin(builtins, 0, *placeholder);
for (int i = 1; i < Builtins::builtin_count; i++) {
AddBuiltin(builtins, i, *isolate->factory()->CopyCode(placeholder));
}
}
void SetupIsolateDelegate::ReplacePlaceholders(Isolate* isolate) {
// Replace references from all code objects to placeholders.
Builtins* builtins = isolate->builtins();
DisallowHeapAllocation no_gc;
static const int kRelocMask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET) |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
const Code::Flags kPlaceholderFlags =
Code::ComputeFlags(Code::BUILTIN, kPlaceholderState);
HeapIterator iterator(isolate->heap());
while (HeapObject* obj = iterator.next()) {
if (!obj->IsCode()) continue;
Code* code = Code::cast(obj);
bool flush_icache = false;
for (RelocIterator it(code, kRelocMask); !it.done(); it.next()) {
RelocInfo* rinfo = it.rinfo();
if (RelocInfo::IsCodeTarget(rinfo->rmode())) {
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
if (target->flags() != kPlaceholderFlags) continue;
Code* new_target =
Code::cast(builtins->builtins_[target->builtin_index()]);
rinfo->set_target_address(isolate, new_target->instruction_start(),
UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
} else {
DCHECK(RelocInfo::IsEmbeddedObject(rinfo->rmode()));
Object* object = rinfo->target_object();
if (!object->IsCode()) continue;
Code* target = Code::cast(object);
if (target->flags() != kPlaceholderFlags) continue;
Code* new_target =
Code::cast(builtins->builtins_[target->builtin_index()]);
rinfo->set_target_object(new_target, UPDATE_WRITE_BARRIER,
SKIP_ICACHE_FLUSH);
}
flush_icache = true;
}
if (flush_icache) {
Assembler::FlushICache(isolate, code->instruction_start(),
code->instruction_size());
}
}
#ifdef DEBUG
// Verify that references to all placeholder builtins have been replaced.
// Skip this check for non-snapshot builds.
if (isolate->serializer_enabled()) {
HeapIterator iterator(isolate->heap(), HeapIterator::kFilterUnreachable);
while (HeapObject* obj = iterator.next()) {
if (obj->IsCode()) CHECK_NE(kPlaceholderFlags, Code::cast(obj)->flags());
}
}
#endif
}
void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) { void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) {
Builtins* builtins = isolate->builtins(); Builtins* builtins = isolate->builtins();
DCHECK(!builtins->initialized_); DCHECK(!builtins->initialized_);
PopulateWithPlaceholders(isolate);
// Create a scope for the handles in the builtins. // Create a scope for the handles in the builtins.
HandleScope scope(isolate); HandleScope scope(isolate);
@ -186,6 +274,8 @@ void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) {
#undef BUILD_ASM #undef BUILD_ASM
CHECK_EQ(Builtins::builtin_count, index); CHECK_EQ(Builtins::builtin_count, index);
ReplacePlaceholders(isolate);
#define SET_PROMISE_REJECTION_PREDICTION(Name) \ #define SET_PROMISE_REJECTION_PREDICTION(Name) \
Code::cast(builtins->builtins_[Builtins::k##Name]) \ Code::cast(builtins->builtins_[Builtins::k##Name]) \
->set_is_promise_rejection(true); ->set_is_promise_rejection(true);
@ -207,7 +297,7 @@ void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) {
BUILTINS_WITH_UNTAGGED_PARAMS(SET_CODE_NON_TAGGED_PARAMS) BUILTINS_WITH_UNTAGGED_PARAMS(SET_CODE_NON_TAGGED_PARAMS)
#undef SET_CODE_NON_TAGGED_PARAMS #undef SET_CODE_NON_TAGGED_PARAMS
isolate->builtins()->MarkInitialized(); builtins->MarkInitialized();
} }
} // namespace internal } // namespace internal

View File

@ -2663,10 +2663,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
// Call the [[BoundTargetFunction]] via the Call builtin. // Call the [[BoundTargetFunction]] via the Call builtin.
__ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
__ Load(rcx, __ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate())); RelocInfo::CODE_TARGET);
__ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
__ jmp(rcx);
} }
// static // static
@ -2695,10 +2693,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
// Check if target is a proxy and call CallProxy external builtin // Check if target is a proxy and call CallProxy external builtin
__ CmpInstanceType(rcx, JS_PROXY_TYPE); __ CmpInstanceType(rcx, JS_PROXY_TYPE);
__ j(not_equal, &non_function); __ j(not_equal, &non_function);
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
__ Load(rcx, ExternalReference(Builtins::kCallProxy, masm->isolate()));
__ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
__ jmp(rcx);
// 2. Call to something else, which might have a [[Call]] internal method (if // 2. Call to something else, which might have a [[Call]] internal method (if
// not we raise an exception). // not we raise an exception).
@ -2765,9 +2760,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
// Construct the [[BoundTargetFunction]] via the Construct builtin. // Construct the [[BoundTargetFunction]] via the Construct builtin.
__ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset)); __ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
__ Load(rcx, ExternalReference(Builtins::kConstruct, masm->isolate())); __ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
__ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
__ jmp(rcx);
} }
// static // static
@ -2803,8 +2796,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
// Only dispatch to proxies after checking whether they are constructors. // Only dispatch to proxies after checking whether they are constructors.
__ CmpInstanceType(rcx, JS_PROXY_TYPE); __ CmpInstanceType(rcx, JS_PROXY_TYPE);
__ j(not_equal, &non_proxy); __ j(not_equal, &non_proxy);
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
__ TailCallBuiltin(Builtins::kConstructProxy); RelocInfo::CODE_TARGET);
// Called Construct on an exotic Object with a [[Construct]] internal method. // Called Construct on an exotic Object with a [[Construct]] internal method.
__ bind(&non_proxy); __ bind(&non_proxy);

View File

@ -345,12 +345,6 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) {
"StoreBuffer::StoreBufferOverflow"); "StoreBuffer::StoreBufferOverflow");
} }
#define BUILTIN_LIST_EXTERNAL_REFS(DEF) \
BUILTIN_LIST_C(DEF) \
BUILTIN_LIST_A(DEF) \
DEF(CallProxy) \
DEF(ConstructProxy)
void ExternalReferenceTable::AddBuiltins(Isolate* isolate) { void ExternalReferenceTable::AddBuiltins(Isolate* isolate) {
struct CBuiltinEntry { struct CBuiltinEntry {
Address address; Address address;
@ -365,36 +359,8 @@ void ExternalReferenceTable::AddBuiltins(Isolate* isolate) {
Add(ExternalReference(c_builtins[i].address, isolate).address(), Add(ExternalReference(c_builtins[i].address, isolate).address(),
c_builtins[i].name); c_builtins[i].name);
} }
struct BuiltinEntry {
Builtins::Name id;
const char* name;
};
static const BuiltinEntry builtins[] = {
#define DEF_ENTRY(Name, ...) {Builtins::k##Name, "Builtin_" #Name},
BUILTIN_LIST_EXTERNAL_REFS(DEF_ENTRY)
#undef DEF_ENTRY
};
for (unsigned i = 0; i < arraysize(builtins); ++i) {
Add(isolate->builtins()->builtin_address(builtins[i].id), builtins[i].name);
}
} }
bool ExternalReferenceTable::HasBuiltin(Builtins::Name name) {
switch (name) {
#define CASE_FOUND(Name) \
case Builtins::k##Name: \
return true;
BUILTIN_LIST_EXTERNAL_REFS(CASE_FOUND)
#undef CASE_FOUND
default:
return false;
}
UNREACHABLE();
}
#undef BUILTIN_LIST_EXTERNAL_REFS
void ExternalReferenceTable::AddRuntimeFunctions(Isolate* isolate) { void ExternalReferenceTable::AddRuntimeFunctions(Isolate* isolate) {
struct RuntimeEntry { struct RuntimeEntry {
Runtime::FunctionId id; Runtime::FunctionId id;

View File

@ -39,8 +39,6 @@ class ExternalReferenceTable {
static const char* ResolveSymbol(void* address, static const char* ResolveSymbol(void* address,
std::vector<char**>* = nullptr); std::vector<char**>* = nullptr);
static bool HasBuiltin(Builtins::Name name);
private: private:
struct ExternalReferenceEntry { struct ExternalReferenceEntry {
Address address; Address address;

View File

@ -1155,16 +1155,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
// reference to the trampoline code directly in this stub, because the // reference to the trampoline code directly in this stub, because the
// builtin stubs may not have been generated yet. // builtin stubs may not have been generated yet.
if (type() == StackFrame::ENTRY_CONSTRUCT) { if (type() == StackFrame::ENTRY_CONSTRUCT) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline, __ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
isolate()); RelocInfo::CODE_TARGET);
__ mov(edx, Immediate(construct_entry));
} else { } else {
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate()); __ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
__ mov(edx, Immediate(entry));
} }
__ mov(edx, Operand(edx, 0)); // deref address
__ lea(edx, FieldOperand(edx, Code::kHeaderSize));
__ call(edx);
// Unlink this frame from the handler chain. // Unlink this frame from the handler chain.
__ PopStackHandler(); __ PopStackHandler();

View File

@ -1308,14 +1308,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub) {
jmp(stub->GetCode(), RelocInfo::CODE_TARGET); jmp(stub->GetCode(), RelocInfo::CODE_TARGET);
} }
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
mov(ecx, Operand::StaticVariable(
ExternalReference(Builtins::kConstructProxy, isolate())));
lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
jmp(ecx);
}
bool TurboAssembler::AllowThisStubCall(CodeStub* stub) { bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
return has_frame() || !stub->SometimesSetsUpAFrame(); return has_frame() || !stub->SometimesSetsUpAFrame();
} }

View File

@ -749,9 +749,6 @@ class MacroAssembler : public TurboAssembler {
// Tail call a code stub (jump). Generate the code if necessary. // Tail call a code stub (jump). Generate the code if necessary.
void TailCallStub(CodeStub* stub); void TailCallStub(CodeStub* stub);
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
// Call a runtime routine. // Call a runtime routine.
void CallRuntime(const Runtime::Function* f, int num_arguments, void CallRuntime(const Runtime::Function* f, int num_arguments,
SaveFPRegsMode save_doubles = kDontSaveFPRegs); SaveFPRegsMode save_doubles = kDontSaveFPRegs);

View File

@ -1199,17 +1199,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
// args // args
if (type() == StackFrame::ENTRY_CONSTRUCT) { if (type() == StackFrame::ENTRY_CONSTRUCT) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline, __ Call(BUILTIN_CODE(isolate, JSConstructEntryTrampoline),
isolate); RelocInfo::CODE_TARGET);
__ li(t0, Operand(construct_entry));
} else { } else {
ExternalReference entry(Builtins::kJSEntryTrampoline, masm->isolate()); __ Call(BUILTIN_CODE(isolate, JSEntryTrampoline), RelocInfo::CODE_TARGET);
__ li(t0, Operand(entry));
} }
__ lw(t9, MemOperand(t0)); // Deref address.
// Call JSEntryTrampoline.
__ Call(t9, Code::kHeaderSize - kHeapObjectTag);
// Unlink this frame from the handler chain. // Unlink this frame from the handler chain.
__ PopStackHandler(); __ PopStackHandler();

View File

@ -4582,13 +4582,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub,
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2, bd); Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2, bd);
} }
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
li(t2, Operand(ExternalReference(Builtins::kConstructProxy, isolate())));
lw(t2, MemOperand(t2));
Jump(t2, Operand(Code::kHeaderSize - kHeapObjectTag));
}
bool TurboAssembler::AllowThisStubCall(CodeStub* stub) { bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
return has_frame() || !stub->SometimesSetsUpAFrame(); return has_frame() || !stub->SometimesSetsUpAFrame();
} }

View File

@ -1343,9 +1343,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
#undef COND_ARGS #undef COND_ARGS
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
void CallJSExitStub(CodeStub* stub); void CallJSExitStub(CodeStub* stub);
// Call a runtime routine. // Call a runtime routine.

View File

@ -1196,17 +1196,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
// args // args
if (type() == StackFrame::ENTRY_CONSTRUCT) { if (type() == StackFrame::ENTRY_CONSTRUCT) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline, __ Call(BUILTIN_CODE(isolate, JSConstructEntryTrampoline),
isolate); RelocInfo::CODE_TARGET);
__ li(a4, Operand(construct_entry));
} else { } else {
ExternalReference entry(Builtins::kJSEntryTrampoline, masm->isolate()); __ Call(BUILTIN_CODE(isolate, JSEntryTrampoline), RelocInfo::CODE_TARGET);
__ li(a4, Operand(entry));
} }
__ Ld(t9, MemOperand(a4)); // Deref address.
// Call JSEntryTrampoline.
__ daddiu(t9, t9, Code::kHeaderSize - kHeapObjectTag);
__ Call(t9);
// Unlink this frame from the handler chain. // Unlink this frame from the handler chain.
__ PopStackHandler(); __ PopStackHandler();

View File

@ -4924,14 +4924,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub,
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2, bd); Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond, r1, r2, bd);
} }
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
li(t2, Operand(ExternalReference(Builtins::kConstructProxy, isolate())));
Ld(t2, MemOperand(t2));
Daddu(t2, t2, Operand(Code::kHeaderSize - kHeapObjectTag));
Jump(t2);
}
bool TurboAssembler::AllowThisStubCall(CodeStub* stub) { bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
return has_frame() || !stub->SometimesSetsUpAFrame(); return has_frame() || !stub->SometimesSetsUpAFrame();
} }

View File

@ -1507,9 +1507,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
#undef COND_ARGS #undef COND_ARGS
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
void CallJSExitStub(CodeStub* stub); void CallJSExitStub(CodeStub* stub);
// Call a runtime routine. // Call a runtime routine.

View File

@ -1143,20 +1143,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
// r6: argc // r6: argc
// r7: argv // r7: argv
if (type() == StackFrame::ENTRY_CONSTRUCT) { if (type() == StackFrame::ENTRY_CONSTRUCT) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline, __ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
isolate()); RelocInfo::CODE_TARGET);
__ mov(ip, Operand(construct_entry));
} else { } else {
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate()); __ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
__ mov(ip, Operand(entry));
} }
__ LoadP(ip, MemOperand(ip)); // deref address
// Branch and link to JSEntryTrampoline.
// the address points to the start of the code object, skip the header
__ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
__ mtctr(ip);
__ bctrl(); // make the call
// Unlink this frame from the handler chain. // Unlink this frame from the handler chain.
__ PopStackHandler(); __ PopStackHandler();

View File

@ -1848,14 +1848,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
} }
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
mov(ip, Operand(ExternalReference(Builtins::kConstructProxy, isolate())));
LoadP(ip, MemOperand(ip));
addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
Jump(ip);
}
bool TurboAssembler::AllowThisStubCall(CodeStub* stub) { bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
return has_frame_ || !stub->SometimesSetsUpAFrame(); return has_frame_ || !stub->SometimesSetsUpAFrame();
} }

View File

@ -1072,9 +1072,6 @@ class MacroAssembler : public TurboAssembler {
void CallStub(CodeStub* stub, Condition cond = al); void CallStub(CodeStub* stub, Condition cond = al);
void TailCallStub(CodeStub* stub, Condition cond = al); void TailCallStub(CodeStub* stub, Condition cond = al);
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
// Call a runtime routine. // Call a runtime routine.
void CallRuntime(const Runtime::Function* f, int num_arguments, void CallRuntime(const Runtime::Function* f, int num_arguments,
SaveFPRegsMode save_doubles = kDontSaveFPRegs); SaveFPRegsMode save_doubles = kDontSaveFPRegs);

View File

@ -1116,26 +1116,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
// r5: argc // r5: argc
// r6: argv // r6: argv
if (type() == StackFrame::ENTRY_CONSTRUCT) { if (type() == StackFrame::ENTRY_CONSTRUCT) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline, __ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
isolate()); RelocInfo::CODE_TARGET);
__ mov(ip, Operand(construct_entry));
} else { } else {
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate()); __ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
__ mov(ip, Operand(entry));
} }
__ LoadP(ip, MemOperand(ip)); // deref address
// Branch and link to JSEntryTrampoline.
// the address points to the start of the code object, skip the header
__ AddP(ip, Operand(Code::kHeaderSize - kHeapObjectTag));
Label return_addr;
// __ basr(r14, ip);
__ larl(r14, &return_addr);
__ b(ip);
__ bind(&return_addr);
// Unlink this frame from the handler chain.
__ PopStackHandler();
__ bind(&exit); // r2 holds result __ bind(&exit); // r2 holds result
// Check if the current stack frame is marked as the outermost JS frame. // Check if the current stack frame is marked as the outermost JS frame.

View File

@ -1708,14 +1708,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub, Condition cond) {
Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond); Jump(stub->GetCode(), RelocInfo::CODE_TARGET, cond);
} }
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
mov(ip, Operand(ExternalReference(Builtins::kConstructProxy, isolate())));
LoadP(ip, MemOperand(ip));
AddP(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
Jump(ip);
}
bool TurboAssembler::AllowThisStubCall(CodeStub* stub) { bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
return has_frame_ || !stub->SometimesSetsUpAFrame(); return has_frame_ || !stub->SometimesSetsUpAFrame();
} }

View File

@ -1000,9 +1000,6 @@ class MacroAssembler : public TurboAssembler {
// Call a code stub. // Call a code stub.
void TailCallStub(CodeStub* stub, Condition cond = al); void TailCallStub(CodeStub* stub, Condition cond = al);
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
void CallStub(CodeStub* stub, Condition cond = al); void CallStub(CodeStub* stub, Condition cond = al);
void CallRuntime(const Runtime::Function* f, int num_arguments, void CallRuntime(const Runtime::Function* f, int num_arguments,
SaveFPRegsMode save_doubles = kDontSaveFPRegs); SaveFPRegsMode save_doubles = kDontSaveFPRegs);

View File

@ -39,6 +39,8 @@ class SetupIsolateDelegate {
protected: protected:
static void SetupBuiltinsInternal(Isolate* isolate); static void SetupBuiltinsInternal(Isolate* isolate);
static void AddBuiltin(Builtins* builtins, int index, Code* code); static void AddBuiltin(Builtins* builtins, int index, Code* code);
static void PopulateWithPlaceholders(Isolate* isolate);
static void ReplacePlaceholders(Isolate* isolate);
}; };
} // namespace internal } // namespace internal

View File

@ -1093,15 +1093,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
// in the code, because the builtin stubs may not have been generated yet // in the code, because the builtin stubs may not have been generated yet
// at the time this code is generated. // at the time this code is generated.
if (type() == StackFrame::ENTRY_CONSTRUCT) { if (type() == StackFrame::ENTRY_CONSTRUCT) {
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline, __ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
isolate()); RelocInfo::CODE_TARGET);
__ Load(rax, construct_entry);
} else { } else {
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate()); __ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
__ Load(rax, entry);
} }
__ leap(kScratchRegister, FieldOperand(rax, Code::kHeaderSize));
__ call(kScratchRegister);
// Unlink this frame from the handler chain. // Unlink this frame from the handler chain.
__ PopStackHandler(); __ PopStackHandler();

View File

@ -506,13 +506,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub) {
Jump(stub->GetCode(), RelocInfo::CODE_TARGET); Jump(stub->GetCode(), RelocInfo::CODE_TARGET);
} }
void MacroAssembler::TailCallBuiltin(Builtins::Name name) {
DCHECK(ExternalReferenceTable::HasBuiltin(name));
Load(rcx, ExternalReference(name, isolate()));
leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
jmp(rcx);
}
bool TurboAssembler::AllowThisStubCall(CodeStub* stub) { bool TurboAssembler::AllowThisStubCall(CodeStub* stub) {
return has_frame() || !stub->SometimesSetsUpAFrame(); return has_frame() || !stub->SometimesSetsUpAFrame();
} }

View File

@ -1352,9 +1352,6 @@ class MacroAssembler : public TurboAssembler {
// Tail call a code stub (jump). // Tail call a code stub (jump).
void TailCallStub(CodeStub* stub); void TailCallStub(CodeStub* stub);
// Tail call a code builtin (jump).
void TailCallBuiltin(Builtins::Name name);
// Call a runtime routine. // Call a runtime routine.
void CallRuntime(const Runtime::Function* f, void CallRuntime(const Runtime::Function* f,
int num_arguments, int num_arguments,