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:
parent
b4b32df0b4
commit
266be35b3b
@ -1079,18 +1079,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// r3: argc
|
||||
// r4: argv
|
||||
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
||||
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
|
||||
isolate());
|
||||
__ mov(scratch, Operand(construct_entry));
|
||||
__ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
|
||||
__ mov(scratch, Operand(entry));
|
||||
__ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
__ 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.
|
||||
__ PopStackHandler();
|
||||
|
@ -2104,13 +2104,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub, Condition 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) {
|
||||
return has_frame() || !stub->SometimesSetsUpAFrame();
|
||||
}
|
||||
|
@ -1025,9 +1025,6 @@ class MacroAssembler : public TurboAssembler {
|
||||
// Call a code stub.
|
||||
void TailCallStub(CodeStub* stub, Condition cond = al);
|
||||
|
||||
// Tail call a code builtin (jump).
|
||||
void TailCallBuiltin(Builtins::Name name);
|
||||
|
||||
// Call a runtime routine.
|
||||
void CallRuntime(const Runtime::Function* f,
|
||||
int num_arguments,
|
||||
|
@ -1146,16 +1146,13 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// x2: receiver.
|
||||
// x3: argc.
|
||||
// x4: argv.
|
||||
ExternalReference entry(type() == StackFrame::ENTRY_CONSTRUCT
|
||||
? Builtins::kJSConstructEntryTrampoline
|
||||
: Builtins::kJSEntryTrampoline,
|
||||
isolate());
|
||||
__ Mov(x10, entry);
|
||||
|
||||
// Call the JSEntryTrampoline.
|
||||
__ Ldr(x11, MemOperand(x10)); // Dereference the address.
|
||||
__ Add(x12, x11, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Blr(x12);
|
||||
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
||||
__ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
__ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// Unlink this frame from the handler chain.
|
||||
__ PopStackHandler();
|
||||
|
@ -1778,14 +1778,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub) {
|
||||
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,
|
||||
SaveFPRegsMode save_doubles) {
|
||||
const Runtime::Function* f = Runtime::FunctionForId(fid);
|
||||
|
@ -1834,9 +1834,6 @@ class MacroAssembler : public TurboAssembler {
|
||||
void CallStub(CodeStub* stub);
|
||||
void TailCallStub(CodeStub* stub);
|
||||
|
||||
// Tail call a code builtin (jump).
|
||||
void TailCallBuiltin(Builtins::Name name);
|
||||
|
||||
void CallRuntime(const Runtime::Function* f,
|
||||
int num_arguments,
|
||||
SaveFPRegsMode save_doubles = kDontSaveFPRegs);
|
||||
|
@ -837,10 +837,6 @@ ExternalReference::ExternalReference(
|
||||
: 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(Runtime::FunctionForId(id), isolate) {}
|
||||
|
||||
|
@ -823,8 +823,6 @@ class ExternalReference BASE_EMBEDDED {
|
||||
|
||||
ExternalReference(ApiFunction* ptr, Type type, Isolate* isolate);
|
||||
|
||||
ExternalReference(Builtins::Name name, Isolate* isolate);
|
||||
|
||||
ExternalReference(Runtime::FunctionId id, Isolate* isolate);
|
||||
|
||||
ExternalReference(const Runtime::Function* f, Isolate* isolate);
|
||||
|
@ -2394,11 +2394,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
|
||||
// Call the [[BoundTargetFunction]] via the Call builtin.
|
||||
__ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
|
||||
__ mov(r3, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
|
||||
masm->isolate())));
|
||||
__ ldr(r3, MemOperand(r3));
|
||||
__ add(pc, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2426,10 +2423,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
// Check if target is a proxy and call CallProxy external builtin
|
||||
__ cmp(r5, Operand(JS_PROXY_TYPE));
|
||||
__ b(ne, &non_function);
|
||||
|
||||
__ mov(r5, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate())));
|
||||
__ ldr(r5, MemOperand(r5));
|
||||
__ add(pc, r5, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
|
||||
|
||||
// 2. Call to something else, which might have a [[Call]] internal method (if
|
||||
// not we raise an exception).
|
||||
@ -2490,10 +2484,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
|
||||
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
||||
__ ldr(r1, FieldMemOperand(r1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
|
||||
__ mov(r2, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
|
||||
__ ldr(r2, MemOperand(r2));
|
||||
__ add(pc, r2, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2528,8 +2519,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Only dispatch to proxies after checking whether they are constructors.
|
||||
__ cmp(r5, Operand(JS_PROXY_TYPE));
|
||||
__ b(ne, &non_proxy);
|
||||
|
||||
__ TailCallBuiltin(Builtins::kConstructProxy);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Called Construct on an exotic Object with a [[Construct]] internal method.
|
||||
__ bind(&non_proxy);
|
||||
|
@ -2489,11 +2489,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
|
||||
// Call the [[BoundTargetFunction]] via the Call builtin.
|
||||
__ Ldr(x1, FieldMemOperand(x1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ Mov(x10,
|
||||
ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate()));
|
||||
__ Ldr(x11, MemOperand(x10));
|
||||
__ Add(x12, x11, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Br(x12);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2520,11 +2517,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
// Check if target is a proxy and call CallProxy external builtin
|
||||
__ Cmp(x5, JS_PROXY_TYPE);
|
||||
__ B(ne, &non_function);
|
||||
|
||||
__ Mov(x5, ExternalReference(Builtins::kCallProxy, masm->isolate()));
|
||||
__ Ldr(x5, MemOperand(x5));
|
||||
__ Add(x6, x5, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Br(x6);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
|
||||
|
||||
// 2. Call to something else, which might have a [[Call]] internal method (if
|
||||
// not we raise an exception).
|
||||
@ -2591,10 +2584,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
|
||||
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
||||
__ Ldr(x1, FieldMemOperand(x1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ Mov(x10, ExternalReference(Builtins::kConstruct, masm->isolate()));
|
||||
__ Ldr(x11, MemOperand(x10));
|
||||
__ Add(x12, x11, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Br(x12);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2628,8 +2618,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Only dispatch to proxies after checking whether they are constructors.
|
||||
__ Cmp(x5, JS_PROXY_TYPE);
|
||||
__ B(ne, &non_proxy);
|
||||
|
||||
__ TailCallBuiltin(Builtins::kConstructProxy);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Called Construct on an exotic Object with a [[Construct]] internal method.
|
||||
__ bind(&non_proxy);
|
||||
|
@ -46,16 +46,9 @@ namespace internal {
|
||||
// Args: name
|
||||
|
||||
#define BUILTIN_LIST_BASE(CPP, API, TFJ, TFC, TFS, TFH, ASM, DBG) \
|
||||
ASM(Abort) \
|
||||
/* Code aging */ \
|
||||
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 */ \
|
||||
ASM(ArgumentsAdaptorTrampoline) \
|
||||
/* ES6 section 9.2.1 [[Call]] ( thisArgument, argumentsList) */ \
|
||||
@ -94,6 +87,7 @@ namespace internal {
|
||||
ASM(JSConstructStubGenericRestrictedReturn) \
|
||||
ASM(JSConstructStubGenericUnrestrictedReturn) \
|
||||
ASM(JSBuiltinsConstructStub) \
|
||||
TFC(FastNewObject, FastNewObject, 1) \
|
||||
TFC(FastNewClosure, FastNewClosure, 1) \
|
||||
TFC(FastNewFunctionContextEval, FastNewFunctionContext, 1) \
|
||||
TFC(FastNewFunctionContextFunction, FastNewFunctionContext, 1) \
|
||||
@ -146,6 +140,7 @@ namespace internal {
|
||||
ASM(InterpreterOnStackReplacement) \
|
||||
\
|
||||
/* Code life-cycle */ \
|
||||
ASM(CompileLazy) \
|
||||
ASM(CheckOptimizationMarker) \
|
||||
ASM(InstantiateAsmJs) \
|
||||
ASM(MarkCodeAsToBeExecutedOnce) \
|
||||
@ -205,6 +200,7 @@ namespace internal {
|
||||
DBG(Slot_DebugBreak) \
|
||||
\
|
||||
/* Type conversions */ \
|
||||
TFC(ToObject, TypeConversion, 1) \
|
||||
TFC(ToBoolean, TypeConversion, 1) \
|
||||
TFC(OrdinaryToPrimitive_Number, TypeConversion, 1) \
|
||||
TFC(OrdinaryToPrimitive_String, TypeConversion, 1) \
|
||||
@ -251,11 +247,19 @@ namespace internal {
|
||||
TFH(StoreIC_Uninitialized, BUILTIN, kNoExtraICState, StoreWithVector) \
|
||||
TFH(StoreICStrict_Uninitialized, BUILTIN, kNoExtraICState, StoreWithVector) \
|
||||
\
|
||||
/* Promise helpers */ \
|
||||
TFS(ResolveNativePromise, kPromise, kValue) \
|
||||
TFS(RejectNativePromise, kPromise, kValue, kDebugEvent) \
|
||||
TFS(PerformNativePromiseThen, kPromise, kResolveReaction, kRejectReaction, \
|
||||
kResultPromise) \
|
||||
\
|
||||
/* Object property helpers */ \
|
||||
TFS(HasProperty, kKey, kObject) \
|
||||
TFS(DeleteProperty, kObject, kKey, kLanguageMode) \
|
||||
\
|
||||
/* Abort */ \
|
||||
ASM(Abort) \
|
||||
\
|
||||
/* Built-in functions for Javascript */ \
|
||||
/* Special internal builtins */ \
|
||||
CPP(EmptyFunction) \
|
||||
@ -264,8 +268,6 @@ namespace internal {
|
||||
CPP(UnsupportedThrower) \
|
||||
TFJ(ReturnReceiver, 0) \
|
||||
\
|
||||
TFS(DeleteProperty, kObject, kKey, kLanguageMode) \
|
||||
\
|
||||
/* Array */ \
|
||||
ASM(ArrayCode) \
|
||||
ASM(InternalArrayCode) \
|
||||
@ -815,9 +817,6 @@ namespace internal {
|
||||
CPP(ReflectSetPrototypeOf) \
|
||||
\
|
||||
/* RegExp */ \
|
||||
TFS(RegExpExecAtom, kRegExp, kString, kLastIndex, kMatchInfo) \
|
||||
TFS(RegExpPrototypeExecSlow, kReceiver, kString) \
|
||||
\
|
||||
CPP(RegExpCapture1Getter) \
|
||||
CPP(RegExpCapture2Getter) \
|
||||
CPP(RegExpCapture3Getter) \
|
||||
@ -864,13 +863,15 @@ namespace internal {
|
||||
TFJ(RegExpPrototypeUnicodeGetter, 0) \
|
||||
CPP(RegExpRightContextGetter) \
|
||||
\
|
||||
TFS(RegExpReplace, kRegExp, kString, kReplaceValue) \
|
||||
/* ES #sec-regexp.prototype-@@replace */ \
|
||||
TFJ(RegExpPrototypeReplace, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||
\
|
||||
TFS(RegExpSplit, kRegExp, kString, kLimit) \
|
||||
/* ES #sec-regexp.prototype-@@split */ \
|
||||
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 */ \
|
||||
TFJ(SetConstructor, SharedFunctionInfo::kDontAdaptArgumentsSentinel) \
|
||||
|
@ -2567,10 +2567,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
|
||||
// Call the [[BoundTargetFunction]] via the Call builtin.
|
||||
__ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ mov(ecx, Operand::StaticVariable(ExternalReference(
|
||||
Builtins::kCall_ReceiverIsAny, masm->isolate())));
|
||||
__ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
|
||||
__ jmp(ecx);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2598,11 +2596,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
// Call CallProxy external builtin
|
||||
__ CmpInstanceType(ecx, JS_PROXY_TYPE);
|
||||
__ j(not_equal, &non_function);
|
||||
|
||||
__ mov(ecx, Operand::StaticVariable(
|
||||
ExternalReference(Builtins::kCallProxy, masm->isolate())));
|
||||
__ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
|
||||
__ jmp(ecx);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
|
||||
|
||||
// 2. Call to something else, which might have a [[Call]] internal method (if
|
||||
// not we raise an exception).
|
||||
@ -2668,10 +2662,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
|
||||
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
||||
__ mov(edi, FieldOperand(edi, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ mov(ecx, Operand::StaticVariable(
|
||||
ExternalReference(Builtins::kConstruct, masm->isolate())));
|
||||
__ lea(ecx, FieldOperand(ecx, Code::kHeaderSize));
|
||||
__ jmp(ecx);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2706,8 +2697,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Only dispatch to proxies after checking whether they are constructors.
|
||||
__ CmpInstanceType(ecx, JS_PROXY_TYPE);
|
||||
__ j(not_equal, &non_proxy);
|
||||
|
||||
__ TailCallBuiltin(Builtins::kConstructProxy);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Called Construct on an exotic Object with a [[Construct]] internal method.
|
||||
__ bind(&non_proxy);
|
||||
|
@ -2376,10 +2376,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
|
||||
// Call the [[BoundTargetFunction]] via the Call builtin.
|
||||
__ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ li(at, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
|
||||
masm->isolate())));
|
||||
__ lw(at, MemOperand(at));
|
||||
__ Jump(at, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2405,9 +2403,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
|
||||
// Check if target is a proxy and call CallProxy external builtin
|
||||
__ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE));
|
||||
__ li(t2, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate())));
|
||||
__ lw(t2, MemOperand(t2));
|
||||
__ Jump(t2, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
|
||||
|
||||
// 2. Call to something else, which might have a [[Call]] internal method (if
|
||||
// not we raise an exception).
|
||||
@ -2535,9 +2531,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
|
||||
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
||||
__ lw(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ li(at, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
|
||||
__ lw(at, MemOperand(at));
|
||||
__ Jump(at, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2571,8 +2565,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
|
||||
// Only dispatch to proxies after checking whether they are constructors.
|
||||
__ Branch(&non_proxy, ne, t2, Operand(JS_PROXY_TYPE));
|
||||
|
||||
__ TailCallBuiltin(Builtins::kConstructProxy);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Called Construct on an exotic Object with a [[Construct]] internal method.
|
||||
__ bind(&non_proxy);
|
||||
|
@ -2404,11 +2404,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
|
||||
// Call the [[BoundTargetFunction]] via the Call builtin.
|
||||
__ Ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ li(at, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
|
||||
masm->isolate())));
|
||||
__ Ld(at, MemOperand(at));
|
||||
__ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(at);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2433,10 +2430,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
__ Branch(&non_callable, eq, t1, Operand(zero_reg));
|
||||
|
||||
__ Branch(&non_function, ne, t2, Operand(JS_PROXY_TYPE));
|
||||
__ li(t2, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate())));
|
||||
__ Ld(t2, MemOperand(t2));
|
||||
__ Daddu(t2, t2, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(t2);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
|
||||
|
||||
// 2. Call to something else, which might have a [[Call]] internal method (if
|
||||
// not we raise an exception).
|
||||
@ -2562,10 +2556,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
|
||||
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
||||
__ Ld(a1, FieldMemOperand(a1, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ li(at, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
|
||||
__ Ld(at, MemOperand(at));
|
||||
__ Daddu(at, at, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ Jump(at);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2599,8 +2590,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
|
||||
// Only dispatch to proxies after checking whether they are constructors.
|
||||
__ Branch(&non_proxy, ne, t2, Operand(JS_PROXY_TYPE));
|
||||
|
||||
__ TailCallBuiltin(Builtins::kConstructProxy);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Called Construct on an exotic Object with a [[Construct]] internal method.
|
||||
__ bind(&non_proxy);
|
||||
|
@ -2479,11 +2479,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
// Call the [[BoundTargetFunction]] via the Call builtin.
|
||||
__ LoadP(r4,
|
||||
FieldMemOperand(r4, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
|
||||
masm->isolate())));
|
||||
__ LoadP(ip, MemOperand(ip));
|
||||
__ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ JumpToJSEntry(ip);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2511,11 +2508,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
// Check if target is a proxy and call CallProxy external builtin
|
||||
__ cmpi(r8, Operand(JS_PROXY_TYPE));
|
||||
__ bne(&non_function);
|
||||
|
||||
__ mov(r8, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate())));
|
||||
__ LoadP(r8, MemOperand(r8));
|
||||
__ addi(r8, r8, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ JumpToJSEntry(r8);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
|
||||
|
||||
// 2. Call to something else, which might have a [[Call]] internal method (if
|
||||
// not we raise an exception).
|
||||
@ -2582,10 +2575,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
||||
__ LoadP(r4,
|
||||
FieldMemOperand(r4, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
|
||||
__ LoadP(ip, MemOperand(ip));
|
||||
__ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ JumpToJSEntry(ip);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2620,8 +2610,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Only dispatch to proxies after checking whether they are constructors.
|
||||
__ cmpi(r8, Operand(JS_PROXY_TYPE));
|
||||
__ bne(&non_proxy);
|
||||
|
||||
__ TailCallBuiltin(Builtins::kConstructProxy);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Called Construct on an exotic Object with a [[Construct]] internal method.
|
||||
__ bind(&non_proxy);
|
||||
|
@ -2480,11 +2480,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
// Call the [[BoundTargetFunction]] via the Call builtin.
|
||||
__ LoadP(r3,
|
||||
FieldMemOperand(r3, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ mov(ip, Operand(ExternalReference(Builtins::kCall_ReceiverIsAny,
|
||||
masm->isolate())));
|
||||
__ LoadP(ip, MemOperand(ip));
|
||||
__ AddP(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ JumpToJSEntry(ip);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2512,11 +2509,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
// Check if target is a proxy and call CallProxy external builtin
|
||||
__ CmpP(r7, Operand(JS_PROXY_TYPE));
|
||||
__ bne(&non_function);
|
||||
|
||||
__ mov(r7, Operand(ExternalReference(Builtins::kCallProxy, masm->isolate())));
|
||||
__ LoadP(r7, MemOperand(r7));
|
||||
__ AddP(r7, r7, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ JumpToJSEntry(r7);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
|
||||
|
||||
// 2. Call to something else, which might have a [[Call]] internal method (if
|
||||
// not we raise an exception).
|
||||
@ -2583,10 +2576,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
||||
__ LoadP(r3,
|
||||
FieldMemOperand(r3, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ mov(ip, Operand(ExternalReference(Builtins::kConstruct, masm->isolate())));
|
||||
__ LoadP(ip, MemOperand(ip));
|
||||
__ AddP(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ JumpToJSEntry(ip);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2621,8 +2611,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Only dispatch to proxies after checking whether they are constructors.
|
||||
__ CmpP(r7, Operand(JS_PROXY_TYPE));
|
||||
__ bne(&non_proxy);
|
||||
|
||||
__ TailCallBuiltin(Builtins::kConstructProxy);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Called Construct on an exotic Object with a [[Construct]] internal method.
|
||||
__ bind(&non_proxy);
|
||||
|
@ -37,6 +37,27 @@ void PostBuildProfileAndTracing(Isolate* isolate, Code* code,
|
||||
typedef void (*MacroAssemblerGenerator)(MacroAssembler*);
|
||||
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,
|
||||
MacroAssemblerGenerator generator,
|
||||
Code::Flags flags, const char* s_name) {
|
||||
@ -127,10 +148,77 @@ void SetupIsolateDelegate::AddBuiltin(Builtins* builtins, int 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) {
|
||||
Builtins* builtins = isolate->builtins();
|
||||
DCHECK(!builtins->initialized_);
|
||||
|
||||
PopulateWithPlaceholders(isolate);
|
||||
|
||||
// Create a scope for the handles in the builtins.
|
||||
HandleScope scope(isolate);
|
||||
|
||||
@ -186,6 +274,8 @@ void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) {
|
||||
#undef BUILD_ASM
|
||||
CHECK_EQ(Builtins::builtin_count, index);
|
||||
|
||||
ReplacePlaceholders(isolate);
|
||||
|
||||
#define SET_PROMISE_REJECTION_PREDICTION(Name) \
|
||||
Code::cast(builtins->builtins_[Builtins::k##Name]) \
|
||||
->set_is_promise_rejection(true);
|
||||
@ -207,7 +297,7 @@ void SetupIsolateDelegate::SetupBuiltinsInternal(Isolate* isolate) {
|
||||
BUILTINS_WITH_UNTAGGED_PARAMS(SET_CODE_NON_TAGGED_PARAMS)
|
||||
#undef SET_CODE_NON_TAGGED_PARAMS
|
||||
|
||||
isolate->builtins()->MarkInitialized();
|
||||
builtins->MarkInitialized();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -2663,10 +2663,8 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
|
||||
// Call the [[BoundTargetFunction]] via the Call builtin.
|
||||
__ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ Load(rcx,
|
||||
ExternalReference(Builtins::kCall_ReceiverIsAny, masm->isolate()));
|
||||
__ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
|
||||
__ jmp(rcx);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Call_ReceiverIsAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2695,10 +2693,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
// Check if target is a proxy and call CallProxy external builtin
|
||||
__ CmpInstanceType(rcx, JS_PROXY_TYPE);
|
||||
__ j(not_equal, &non_function);
|
||||
|
||||
__ Load(rcx, ExternalReference(Builtins::kCallProxy, masm->isolate()));
|
||||
__ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
|
||||
__ jmp(rcx);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), CallProxy), RelocInfo::CODE_TARGET);
|
||||
|
||||
// 2. Call to something else, which might have a [[Call]] internal method (if
|
||||
// not we raise an exception).
|
||||
@ -2765,9 +2760,7 @@ void Builtins::Generate_ConstructBoundFunction(MacroAssembler* masm) {
|
||||
|
||||
// Construct the [[BoundTargetFunction]] via the Construct builtin.
|
||||
__ movp(rdi, FieldOperand(rdi, JSBoundFunction::kBoundTargetFunctionOffset));
|
||||
__ Load(rcx, ExternalReference(Builtins::kConstruct, masm->isolate()));
|
||||
__ leap(rcx, FieldOperand(rcx, Code::kHeaderSize));
|
||||
__ jmp(rcx);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), Construct), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
// static
|
||||
@ -2803,8 +2796,8 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
|
||||
// Only dispatch to proxies after checking whether they are constructors.
|
||||
__ CmpInstanceType(rcx, JS_PROXY_TYPE);
|
||||
__ j(not_equal, &non_proxy);
|
||||
|
||||
__ TailCallBuiltin(Builtins::kConstructProxy);
|
||||
__ Jump(BUILTIN_CODE(masm->isolate(), ConstructProxy),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// Called Construct on an exotic Object with a [[Construct]] internal method.
|
||||
__ bind(&non_proxy);
|
||||
|
@ -345,12 +345,6 @@ void ExternalReferenceTable::AddReferences(Isolate* isolate) {
|
||||
"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) {
|
||||
struct CBuiltinEntry {
|
||||
Address address;
|
||||
@ -365,36 +359,8 @@ void ExternalReferenceTable::AddBuiltins(Isolate* isolate) {
|
||||
Add(ExternalReference(c_builtins[i].address, isolate).address(),
|
||||
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) {
|
||||
struct RuntimeEntry {
|
||||
Runtime::FunctionId id;
|
||||
|
@ -39,8 +39,6 @@ class ExternalReferenceTable {
|
||||
static const char* ResolveSymbol(void* address,
|
||||
std::vector<char**>* = nullptr);
|
||||
|
||||
static bool HasBuiltin(Builtins::Name name);
|
||||
|
||||
private:
|
||||
struct ExternalReferenceEntry {
|
||||
Address address;
|
||||
|
@ -1155,16 +1155,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// reference to the trampoline code directly in this stub, because the
|
||||
// builtin stubs may not have been generated yet.
|
||||
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
||||
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
|
||||
isolate());
|
||||
__ mov(edx, Immediate(construct_entry));
|
||||
__ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
|
||||
__ mov(edx, Immediate(entry));
|
||||
__ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
__ mov(edx, Operand(edx, 0)); // deref address
|
||||
__ lea(edx, FieldOperand(edx, Code::kHeaderSize));
|
||||
__ call(edx);
|
||||
|
||||
// Unlink this frame from the handler chain.
|
||||
__ PopStackHandler();
|
||||
|
@ -1308,14 +1308,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub) {
|
||||
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) {
|
||||
return has_frame() || !stub->SometimesSetsUpAFrame();
|
||||
}
|
||||
|
@ -749,9 +749,6 @@ class MacroAssembler : public TurboAssembler {
|
||||
// Tail call a code stub (jump). Generate the code if necessary.
|
||||
void TailCallStub(CodeStub* stub);
|
||||
|
||||
// Tail call a code builtin (jump).
|
||||
void TailCallBuiltin(Builtins::Name name);
|
||||
|
||||
// Call a runtime routine.
|
||||
void CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles = kDontSaveFPRegs);
|
||||
|
@ -1199,17 +1199,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// args
|
||||
|
||||
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
||||
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
|
||||
isolate);
|
||||
__ li(t0, Operand(construct_entry));
|
||||
__ Call(BUILTIN_CODE(isolate, JSConstructEntryTrampoline),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
ExternalReference entry(Builtins::kJSEntryTrampoline, masm->isolate());
|
||||
__ li(t0, Operand(entry));
|
||||
__ Call(BUILTIN_CODE(isolate, JSEntryTrampoline), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
__ lw(t9, MemOperand(t0)); // Deref address.
|
||||
|
||||
// Call JSEntryTrampoline.
|
||||
__ Call(t9, Code::kHeaderSize - kHeapObjectTag);
|
||||
|
||||
// Unlink this frame from the handler chain.
|
||||
__ PopStackHandler();
|
||||
|
@ -4582,13 +4582,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub,
|
||||
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) {
|
||||
return has_frame() || !stub->SometimesSetsUpAFrame();
|
||||
}
|
||||
|
@ -1343,9 +1343,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
|
||||
|
||||
#undef COND_ARGS
|
||||
|
||||
// Tail call a code builtin (jump).
|
||||
void TailCallBuiltin(Builtins::Name name);
|
||||
|
||||
void CallJSExitStub(CodeStub* stub);
|
||||
|
||||
// Call a runtime routine.
|
||||
|
@ -1196,17 +1196,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// args
|
||||
|
||||
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
||||
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
|
||||
isolate);
|
||||
__ li(a4, Operand(construct_entry));
|
||||
__ Call(BUILTIN_CODE(isolate, JSConstructEntryTrampoline),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
ExternalReference entry(Builtins::kJSEntryTrampoline, masm->isolate());
|
||||
__ li(a4, Operand(entry));
|
||||
__ Call(BUILTIN_CODE(isolate, JSEntryTrampoline), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
__ Ld(t9, MemOperand(a4)); // Deref address.
|
||||
// Call JSEntryTrampoline.
|
||||
__ daddiu(t9, t9, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ Call(t9);
|
||||
|
||||
// Unlink this frame from the handler chain.
|
||||
__ PopStackHandler();
|
||||
|
@ -4924,14 +4924,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub,
|
||||
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) {
|
||||
return has_frame() || !stub->SometimesSetsUpAFrame();
|
||||
}
|
||||
|
@ -1507,9 +1507,6 @@ const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT
|
||||
|
||||
#undef COND_ARGS
|
||||
|
||||
// Tail call a code builtin (jump).
|
||||
void TailCallBuiltin(Builtins::Name name);
|
||||
|
||||
void CallJSExitStub(CodeStub* stub);
|
||||
|
||||
// Call a runtime routine.
|
||||
|
@ -1143,20 +1143,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// r6: argc
|
||||
// r7: argv
|
||||
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
||||
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
|
||||
isolate());
|
||||
__ mov(ip, Operand(construct_entry));
|
||||
__ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
|
||||
__ mov(ip, Operand(entry));
|
||||
__ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
__ 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.
|
||||
__ PopStackHandler();
|
||||
|
@ -1848,14 +1848,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub, Condition 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) {
|
||||
return has_frame_ || !stub->SometimesSetsUpAFrame();
|
||||
}
|
||||
|
@ -1072,9 +1072,6 @@ class MacroAssembler : public TurboAssembler {
|
||||
void CallStub(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.
|
||||
void CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles = kDontSaveFPRegs);
|
||||
|
@ -1116,26 +1116,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// r5: argc
|
||||
// r6: argv
|
||||
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
||||
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
|
||||
isolate());
|
||||
__ mov(ip, Operand(construct_entry));
|
||||
__ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
|
||||
__ mov(ip, Operand(entry));
|
||||
__ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
__ 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
|
||||
// Check if the current stack frame is marked as the outermost JS frame.
|
||||
|
@ -1708,14 +1708,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub, Condition 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) {
|
||||
return has_frame_ || !stub->SometimesSetsUpAFrame();
|
||||
}
|
||||
|
@ -1000,9 +1000,6 @@ class MacroAssembler : public TurboAssembler {
|
||||
// Call a code stub.
|
||||
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 CallRuntime(const Runtime::Function* f, int num_arguments,
|
||||
SaveFPRegsMode save_doubles = kDontSaveFPRegs);
|
||||
|
@ -39,6 +39,8 @@ class SetupIsolateDelegate {
|
||||
protected:
|
||||
static void SetupBuiltinsInternal(Isolate* isolate);
|
||||
static void AddBuiltin(Builtins* builtins, int index, Code* code);
|
||||
static void PopulateWithPlaceholders(Isolate* isolate);
|
||||
static void ReplacePlaceholders(Isolate* isolate);
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
@ -1093,15 +1093,11 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// in the code, because the builtin stubs may not have been generated yet
|
||||
// at the time this code is generated.
|
||||
if (type() == StackFrame::ENTRY_CONSTRUCT) {
|
||||
ExternalReference construct_entry(Builtins::kJSConstructEntryTrampoline,
|
||||
isolate());
|
||||
__ Load(rax, construct_entry);
|
||||
__ Call(BUILTIN_CODE(isolate(), JSConstructEntryTrampoline),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
ExternalReference entry(Builtins::kJSEntryTrampoline, isolate());
|
||||
__ Load(rax, entry);
|
||||
__ Call(BUILTIN_CODE(isolate(), JSEntryTrampoline), RelocInfo::CODE_TARGET);
|
||||
}
|
||||
__ leap(kScratchRegister, FieldOperand(rax, Code::kHeaderSize));
|
||||
__ call(kScratchRegister);
|
||||
|
||||
// Unlink this frame from the handler chain.
|
||||
__ PopStackHandler();
|
||||
|
@ -506,13 +506,6 @@ void MacroAssembler::TailCallStub(CodeStub* stub) {
|
||||
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) {
|
||||
return has_frame() || !stub->SometimesSetsUpAFrame();
|
||||
}
|
||||
|
@ -1352,9 +1352,6 @@ class MacroAssembler : public TurboAssembler {
|
||||
// Tail call a code stub (jump).
|
||||
void TailCallStub(CodeStub* stub);
|
||||
|
||||
// Tail call a code builtin (jump).
|
||||
void TailCallBuiltin(Builtins::Name name);
|
||||
|
||||
// Call a runtime routine.
|
||||
void CallRuntime(const Runtime::Function* f,
|
||||
int num_arguments,
|
||||
|
Loading…
Reference in New Issue
Block a user