PPC/s390: [builtins] Introduce CallProxy builtin based on CSA
Port7f50476b83
Port1769f892ce
Original Commit Message: - Add more conformance tests for proxy call and calling undetectable - This improves the performance of calling a proxy by ~5x R=mslekova@google.com, adamk@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com BUG= LOG=N Change-Id: If5e66093aee815225053c1d3d2a99cfac270aea4 Reviewed-on: https://chromium-review.googlesource.com/587228 Reviewed-by: Junliang Yan <jyan@ca.ibm.com> Commit-Queue: Jaideep Bajwa <bjaideep@ca.ibm.com> Cr-Commit-Position: refs/heads/master@{#46912}
This commit is contained in:
parent
e017463189
commit
c28d39f093
@ -1328,7 +1328,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
||||
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
|
||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
||||
InterpreterPushArgsMode mode) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : the number of arguments (not including the receiver)
|
||||
// -- r5 : the address of the first argument to be pushed. Subsequent
|
||||
@ -1359,15 +1359,14 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
||||
|
||||
// Call the target.
|
||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||
__ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
|
||||
tail_call_mode),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Jump(
|
||||
masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
|
||||
__ Jump(masm->isolate()->builtins()->CallWithSpread(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
__ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
|
||||
tail_call_mode),
|
||||
__ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
@ -2290,104 +2289,9 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
__ Jump(code, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Drops top JavaScript frame and an arguments adaptor frame below it (if
|
||||
// present) preserving all the arguments prepared for current call.
|
||||
// Does nothing if debugger is currently active.
|
||||
// ES6 14.6.3. PrepareForTailCall
|
||||
//
|
||||
// Stack structure for the function g() tail calling f():
|
||||
//
|
||||
// ------- Caller frame: -------
|
||||
// | ...
|
||||
// | g()'s arg M
|
||||
// | ...
|
||||
// | g()'s arg 1
|
||||
// | g()'s receiver arg
|
||||
// | g()'s caller pc
|
||||
// ------- g()'s frame: -------
|
||||
// | g()'s caller fp <- fp
|
||||
// | g()'s context
|
||||
// | function pointer: g
|
||||
// | -------------------------
|
||||
// | ...
|
||||
// | ...
|
||||
// | f()'s arg N
|
||||
// | ...
|
||||
// | f()'s arg 1
|
||||
// | f()'s receiver arg <- sp (f()'s caller pc is not on the stack yet!)
|
||||
// ----------------------
|
||||
//
|
||||
void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
Register scratch1, Register scratch2,
|
||||
Register scratch3) {
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is enabled.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ mov(scratch1, Operand(is_tail_call_elimination_enabled));
|
||||
__ lbz(scratch1, MemOperand(scratch1));
|
||||
__ cmpi(scratch1, Operand::Zero());
|
||||
__ beq(&done);
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
__ LoadP(scratch3,
|
||||
MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ cmpi(scratch3, Operand(StackFrame::TypeToMarker(StackFrame::STUB)));
|
||||
__ bne(&no_interpreter_frame);
|
||||
__ LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ bind(&no_interpreter_frame);
|
||||
}
|
||||
|
||||
// Check if next frame is an arguments adaptor frame.
|
||||
Register caller_args_count_reg = scratch1;
|
||||
Label no_arguments_adaptor, formal_parameter_count_loaded;
|
||||
__ LoadP(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ LoadP(
|
||||
scratch3,
|
||||
MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ cmpi(scratch3,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ bne(&no_arguments_adaptor);
|
||||
|
||||
// Drop current frame and load arguments count from arguments adaptor frame.
|
||||
__ mr(fp, scratch2);
|
||||
__ LoadP(caller_args_count_reg,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(caller_args_count_reg);
|
||||
__ b(&formal_parameter_count_loaded);
|
||||
|
||||
__ bind(&no_arguments_adaptor);
|
||||
// Load caller's formal parameter count
|
||||
__ LoadP(scratch1,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kFunctionOffset));
|
||||
__ LoadP(scratch1,
|
||||
FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ LoadWordArith(
|
||||
caller_args_count_reg,
|
||||
FieldMemOperand(scratch1,
|
||||
SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
|
||||
__ bind(&formal_parameter_count_loaded);
|
||||
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
ConvertReceiverMode mode,
|
||||
TailCallMode tail_call_mode) {
|
||||
ConvertReceiverMode mode) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : the number of arguments (not including the receiver)
|
||||
// -- r4 : the function to call (checked to be a JSFunction)
|
||||
@ -2475,10 +2379,6 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
// -- cp : the function context.
|
||||
// -----------------------------------
|
||||
|
||||
if (tail_call_mode == TailCallMode::kAllow) {
|
||||
PrepareForTailCall(masm, r3, r6, r7, r8);
|
||||
}
|
||||
|
||||
__ LoadWordArith(
|
||||
r5, FieldMemOperand(r5, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
ParameterCount actual(r3);
|
||||
@ -2577,18 +2477,13 @@ void Generate_PushBoundArguments(MacroAssembler* masm) {
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm,
|
||||
TailCallMode tail_call_mode) {
|
||||
void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : the number of arguments (not including the receiver)
|
||||
// -- r4 : the function to call (checked to be a JSBoundFunction)
|
||||
// -----------------------------------
|
||||
__ AssertBoundFunction(r4);
|
||||
|
||||
if (tail_call_mode == TailCallMode::kAllow) {
|
||||
PrepareForTailCall(masm, r3, r6, r7, r8);
|
||||
}
|
||||
|
||||
// Patch the receiver to [[BoundThis]].
|
||||
__ LoadP(ip, FieldMemOperand(r4, JSBoundFunction::kBoundThisOffset));
|
||||
__ ShiftLeftImm(r0, r3, Operand(kPointerSizeLog2));
|
||||
@ -2608,8 +2503,7 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
|
||||
TailCallMode tail_call_mode) {
|
||||
void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r3 : the number of arguments (not including the receiver)
|
||||
// -- r4 : the target to call (can be any Object).
|
||||
@ -2619,10 +2513,10 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
|
||||
__ JumpIfSmi(r4, &non_callable);
|
||||
__ bind(&non_smi);
|
||||
__ CompareObjectType(r4, r7, r8, JS_FUNCTION_TYPE);
|
||||
__ Jump(masm->isolate()->builtins()->CallFunction(mode, tail_call_mode),
|
||||
__ Jump(masm->isolate()->builtins()->CallFunction(mode),
|
||||
RelocInfo::CODE_TARGET, eq);
|
||||
__ cmpi(r8, Operand(JS_BOUND_FUNCTION_TYPE));
|
||||
__ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode),
|
||||
__ Jump(masm->isolate()->builtins()->CallBoundFunction(),
|
||||
RelocInfo::CODE_TARGET, eq);
|
||||
|
||||
// Check if target has a [[Call]] internal method.
|
||||
@ -2632,9 +2526,11 @@ 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, Code::kHeaderSize - kHeapObjectTag);
|
||||
__ addi(r8, r8, Operand(Code::kHeaderSize - kHeapObjectTag));
|
||||
__ JumpToJSEntry(r8);
|
||||
|
||||
// 2. Call to something else, which might have a [[Call]] internal method (if
|
||||
@ -2646,7 +2542,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
|
||||
// Let the "call_as_function_delegate" take care of the rest.
|
||||
__ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r4);
|
||||
__ Jump(masm->isolate()->builtins()->CallFunction(
|
||||
ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode),
|
||||
ConvertReceiverMode::kNotNullOrUndefined),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// 3. Call to something that is not callable.
|
||||
|
@ -1323,7 +1323,7 @@ static void Generate_InterpreterPushArgs(MacroAssembler* masm,
|
||||
// static
|
||||
void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
||||
MacroAssembler* masm, ConvertReceiverMode receiver_mode,
|
||||
TailCallMode tail_call_mode, InterpreterPushArgsMode mode) {
|
||||
InterpreterPushArgsMode mode) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r2 : the number of arguments (not including the receiver)
|
||||
// -- r4 : the address of the first argument to be pushed. Subsequent
|
||||
@ -1352,15 +1352,14 @@ void Builtins::Generate_InterpreterPushArgsThenCallImpl(
|
||||
|
||||
// Call the target.
|
||||
if (mode == InterpreterPushArgsMode::kJSFunction) {
|
||||
__ Jump(masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny,
|
||||
tail_call_mode),
|
||||
RelocInfo::CODE_TARGET);
|
||||
__ Jump(
|
||||
masm->isolate()->builtins()->CallFunction(ConvertReceiverMode::kAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else if (mode == InterpreterPushArgsMode::kWithFinalSpread) {
|
||||
__ Jump(masm->isolate()->builtins()->CallWithSpread(),
|
||||
RelocInfo::CODE_TARGET);
|
||||
} else {
|
||||
__ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny,
|
||||
tail_call_mode),
|
||||
__ Jump(masm->isolate()->builtins()->Call(ConvertReceiverMode::kAny),
|
||||
RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
@ -2288,103 +2287,9 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
|
||||
__ Jump(code, RelocInfo::CODE_TARGET);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Drops top JavaScript frame and an arguments adaptor frame below it (if
|
||||
// present) preserving all the arguments prepared for current call.
|
||||
// Does nothing if debugger is currently active.
|
||||
// ES6 14.6.3. PrepareForTailCall
|
||||
//
|
||||
// Stack structure for the function g() tail calling f():
|
||||
//
|
||||
// ------- Caller frame: -------
|
||||
// | ...
|
||||
// | g()'s arg M
|
||||
// | ...
|
||||
// | g()'s arg 1
|
||||
// | g()'s receiver arg
|
||||
// | g()'s caller pc
|
||||
// ------- g()'s frame: -------
|
||||
// | g()'s caller fp <- fp
|
||||
// | g()'s context
|
||||
// | function pointer: g
|
||||
// | -------------------------
|
||||
// | ...
|
||||
// | ...
|
||||
// | f()'s arg N
|
||||
// | ...
|
||||
// | f()'s arg 1
|
||||
// | f()'s receiver arg <- sp (f()'s caller pc is not on the stack yet!)
|
||||
// ----------------------
|
||||
//
|
||||
void PrepareForTailCall(MacroAssembler* masm, Register args_reg,
|
||||
Register scratch1, Register scratch2,
|
||||
Register scratch3) {
|
||||
DCHECK(!AreAliased(args_reg, scratch1, scratch2, scratch3));
|
||||
Comment cmnt(masm, "[ PrepareForTailCall");
|
||||
|
||||
// Prepare for tail call only if ES2015 tail call elimination is active.
|
||||
Label done;
|
||||
ExternalReference is_tail_call_elimination_enabled =
|
||||
ExternalReference::is_tail_call_elimination_enabled_address(
|
||||
masm->isolate());
|
||||
__ mov(scratch1, Operand(is_tail_call_elimination_enabled));
|
||||
__ LoadlB(scratch1, MemOperand(scratch1));
|
||||
__ CmpP(scratch1, Operand::Zero());
|
||||
__ beq(&done);
|
||||
|
||||
// Drop possible interpreter handler/stub frame.
|
||||
{
|
||||
Label no_interpreter_frame;
|
||||
__ LoadP(scratch3,
|
||||
MemOperand(fp, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ CmpP(scratch3, Operand(StackFrame::TypeToMarker(StackFrame::STUB)));
|
||||
__ bne(&no_interpreter_frame);
|
||||
__ LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ bind(&no_interpreter_frame);
|
||||
}
|
||||
|
||||
// Check if next frame is an arguments adaptor frame.
|
||||
Register caller_args_count_reg = scratch1;
|
||||
Label no_arguments_adaptor, formal_parameter_count_loaded;
|
||||
__ LoadP(scratch2, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
|
||||
__ LoadP(
|
||||
scratch3,
|
||||
MemOperand(scratch2, CommonFrameConstants::kContextOrFrameTypeOffset));
|
||||
__ CmpP(scratch3,
|
||||
Operand(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
|
||||
__ bne(&no_arguments_adaptor);
|
||||
|
||||
// Drop current frame and load arguments count from arguments adaptor frame.
|
||||
__ LoadRR(fp, scratch2);
|
||||
__ LoadP(caller_args_count_reg,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
||||
__ SmiUntag(caller_args_count_reg);
|
||||
__ b(&formal_parameter_count_loaded);
|
||||
|
||||
__ bind(&no_arguments_adaptor);
|
||||
// Load caller's formal parameter count
|
||||
__ LoadP(scratch1,
|
||||
MemOperand(fp, ArgumentsAdaptorFrameConstants::kFunctionOffset));
|
||||
__ LoadP(scratch1,
|
||||
FieldMemOperand(scratch1, JSFunction::kSharedFunctionInfoOffset));
|
||||
__ LoadW(caller_args_count_reg,
|
||||
FieldMemOperand(scratch1,
|
||||
SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
|
||||
__ bind(&formal_parameter_count_loaded);
|
||||
|
||||
ParameterCount callee_args_count(args_reg);
|
||||
__ PrepareForTailCall(callee_args_count, caller_args_count_reg, scratch2,
|
||||
scratch3);
|
||||
__ bind(&done);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
ConvertReceiverMode mode,
|
||||
TailCallMode tail_call_mode) {
|
||||
ConvertReceiverMode mode) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r2 : the number of arguments (not including the receiver)
|
||||
// -- r3 : the function to call (checked to be a JSFunction)
|
||||
@ -2472,10 +2377,6 @@ void Builtins::Generate_CallFunction(MacroAssembler* masm,
|
||||
// -- cp : the function context.
|
||||
// -----------------------------------
|
||||
|
||||
if (tail_call_mode == TailCallMode::kAllow) {
|
||||
PrepareForTailCall(masm, r2, r5, r6, r7);
|
||||
}
|
||||
|
||||
__ LoadW(
|
||||
r4, FieldMemOperand(r4, SharedFunctionInfo::kFormalParameterCountOffset));
|
||||
ParameterCount actual(r2);
|
||||
@ -2576,18 +2477,13 @@ void Generate_PushBoundArguments(MacroAssembler* masm) {
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm,
|
||||
TailCallMode tail_call_mode) {
|
||||
void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r2 : the number of arguments (not including the receiver)
|
||||
// -- r3 : the function to call (checked to be a JSBoundFunction)
|
||||
// -----------------------------------
|
||||
__ AssertBoundFunction(r3);
|
||||
|
||||
if (tail_call_mode == TailCallMode::kAllow) {
|
||||
PrepareForTailCall(masm, r2, r5, r6, r7);
|
||||
}
|
||||
|
||||
// Patch the receiver to [[BoundThis]].
|
||||
__ LoadP(ip, FieldMemOperand(r3, JSBoundFunction::kBoundThisOffset));
|
||||
__ ShiftLeftP(r1, r2, Operand(kPointerSizeLog2));
|
||||
@ -2607,8 +2503,7 @@ void Builtins::Generate_CallBoundFunctionImpl(MacroAssembler* masm,
|
||||
}
|
||||
|
||||
// static
|
||||
void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
|
||||
TailCallMode tail_call_mode) {
|
||||
void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode) {
|
||||
// ----------- S t a t e -------------
|
||||
// -- r2 : the number of arguments (not including the receiver)
|
||||
// -- r3 : the target to call (can be any Object).
|
||||
@ -2618,10 +2513,10 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
|
||||
__ JumpIfSmi(r3, &non_callable);
|
||||
__ bind(&non_smi);
|
||||
__ CompareObjectType(r3, r6, r7, JS_FUNCTION_TYPE);
|
||||
__ Jump(masm->isolate()->builtins()->CallFunction(mode, tail_call_mode),
|
||||
__ Jump(masm->isolate()->builtins()->CallFunction(mode),
|
||||
RelocInfo::CODE_TARGET, eq);
|
||||
__ CmpP(r7, Operand(JS_BOUND_FUNCTION_TYPE));
|
||||
__ Jump(masm->isolate()->builtins()->CallBoundFunction(tail_call_mode),
|
||||
__ Jump(masm->isolate()->builtins()->CallBoundFunction(),
|
||||
RelocInfo::CODE_TARGET, eq);
|
||||
|
||||
// Check if target has a [[Call]] internal method.
|
||||
@ -2629,23 +2524,14 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
|
||||
__ TestBit(r6, Map::kIsCallable);
|
||||
__ beq(&non_callable);
|
||||
|
||||
// Check if target is a proxy and call CallProxy external builtin
|
||||
__ CmpP(r7, Operand(JS_PROXY_TYPE));
|
||||
__ bne(&non_function);
|
||||
|
||||
// 0. Prepare for tail call if necessary.
|
||||
if (tail_call_mode == TailCallMode::kAllow) {
|
||||
PrepareForTailCall(masm, r2, r5, r6, r7);
|
||||
}
|
||||
|
||||
// 1. Runtime fallback for Proxy [[Call]].
|
||||
__ Push(r3);
|
||||
// Increase the arguments size to include the pushed function and the
|
||||
// existing receiver on the stack.
|
||||
__ AddP(r2, r2, Operand(2));
|
||||
// Tail-call to the runtime.
|
||||
// This used to be a call to JSProxyCall which is now a CSA builtin
|
||||
__ JumpToExternalReference(
|
||||
ExternalReference(Runtime::kAbort, masm->isolate()));
|
||||
__ 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
|
||||
// not we raise an exception).
|
||||
@ -2656,7 +2542,7 @@ void Builtins::Generate_Call(MacroAssembler* masm, ConvertReceiverMode mode,
|
||||
// Let the "call_as_function_delegate" take care of the rest.
|
||||
__ LoadNativeContextSlot(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, r3);
|
||||
__ Jump(masm->isolate()->builtins()->CallFunction(
|
||||
ConvertReceiverMode::kNotNullOrUndefined, tail_call_mode),
|
||||
ConvertReceiverMode::kNotNullOrUndefined),
|
||||
RelocInfo::CODE_TARGET);
|
||||
|
||||
// 3. Call to something that is not callable.
|
||||
|
@ -1642,18 +1642,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
SetCallPosition(expr, expr->tail_call_mode());
|
||||
if (expr->tail_call_mode() == TailCallMode::kAllow) {
|
||||
if (FLAG_trace) {
|
||||
__ CallRuntime(Runtime::kTraceTailCall);
|
||||
}
|
||||
// Update profiling counters before the tail call since we will
|
||||
// not return to this function.
|
||||
EmitProfilingCounterHandlingForReturnSequence(true);
|
||||
}
|
||||
Handle<Code> code =
|
||||
CodeFactory::CallICTrampoline(isolate(), mode, expr->tail_call_mode())
|
||||
.code();
|
||||
SetCallPosition(expr);
|
||||
Handle<Code> code = CodeFactory::CallICTrampoline(isolate(), mode).code();
|
||||
__ mov(r6, Operand(IntFromSlot(expr->CallFeedbackICSlot())));
|
||||
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
__ mov(r3, Operand(arg_count));
|
||||
|
@ -1600,19 +1600,8 @@ void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) {
|
||||
for (int i = 0; i < arg_count; i++) {
|
||||
VisitForStackValue(args->at(i));
|
||||
}
|
||||
|
||||
SetCallPosition(expr, expr->tail_call_mode());
|
||||
if (expr->tail_call_mode() == TailCallMode::kAllow) {
|
||||
if (FLAG_trace) {
|
||||
__ CallRuntime(Runtime::kTraceTailCall);
|
||||
}
|
||||
// Update profiling counters before the tail call since we will
|
||||
// not return to this function.
|
||||
EmitProfilingCounterHandlingForReturnSequence(true);
|
||||
}
|
||||
Handle<Code> code =
|
||||
CodeFactory::CallICTrampoline(isolate(), mode, expr->tail_call_mode())
|
||||
.code();
|
||||
SetCallPosition(expr);
|
||||
Handle<Code> code = CodeFactory::CallICTrampoline(isolate(), mode).code();
|
||||
__ Load(r5, Operand(IntFromSlot(expr->CallFeedbackICSlot())));
|
||||
__ LoadP(r3, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
|
||||
__ mov(r2, Operand(arg_count));
|
||||
|
Loading…
Reference in New Issue
Block a user