Commit 44fcc2e7 authored by mbrandy's avatar mbrandy Committed by Commit bot

PPC: Remove CallFunctionStub, always call through the Call builtin (also from CallIC).

Port 44c44521

Original commit message:
    This fixes receiver conversion since the Call builtin does it correctly.

R=verwaest@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, dstence@us.ibm.com
BUG=v8:4526
LOG=n

Review URL: https://codereview.chromium.org/1423973006

Cr-Commit-Position: refs/heads/master@{#31901}
parent aca03dfc
...@@ -4051,7 +4051,6 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { ...@@ -4051,7 +4051,6 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
DCHECK(ToRegister(instr->result()).is(r3)); DCHECK(ToRegister(instr->result()).is(r3));
int arity = instr->arity(); int arity = instr->arity();
CallFunctionFlags flags = instr->hydrogen()->function_flags();
if (instr->hydrogen()->HasVectorAndSlot()) { if (instr->hydrogen()->HasVectorAndSlot()) {
Register slot_register = ToRegister(instr->temp_slot()); Register slot_register = ToRegister(instr->temp_slot());
Register vector_register = ToRegister(instr->temp_vector()); Register vector_register = ToRegister(instr->temp_vector());
...@@ -4065,15 +4064,12 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) { ...@@ -4065,15 +4064,12 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
__ Move(vector_register, vector); __ Move(vector_register, vector);
__ LoadSmiLiteral(slot_register, Smi::FromInt(index)); __ LoadSmiLiteral(slot_register, Smi::FromInt(index));
CallICState::CallType call_type =
(flags & CALL_AS_METHOD) ? CallICState::METHOD : CallICState::FUNCTION;
Handle<Code> ic = Handle<Code> ic =
CodeFactory::CallICInOptimizedCode(isolate(), arity, call_type).code(); CodeFactory::CallICInOptimizedCode(isolate(), arity).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
} else { } else {
CallFunctionStub stub(isolate(), arity, flags); __ mov(r3, Operand(arity));
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); CallCode(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, instr);
} }
} }
......
...@@ -2088,8 +2088,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) { ...@@ -2088,8 +2088,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ mr(r4, r3); __ mr(r4, r3);
__ StoreP(r4, MemOperand(sp, 2 * kPointerSize)); __ StoreP(r4, MemOperand(sp, 2 * kPointerSize));
SetCallPosition(expr, 1); SetCallPosition(expr, 1);
CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD); __ li(r3, Operand(1));
__ CallStub(&stub); __ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ Drop(1); // The function is still on the stack; drop it. __ Drop(1); // The function is still on the stack; drop it.
...@@ -2814,11 +2814,8 @@ void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) { ...@@ -2814,11 +2814,8 @@ void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) {
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression(); Expression* callee = expr->expression();
CallICState::CallType call_type =
callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
// Get the target function. // Get the target function.
if (call_type == CallICState::FUNCTION) { if (callee->IsVariableProxy()) {
{ {
StackValueContext context(this); StackValueContext context(this);
EmitVariableLoad(callee->AsVariableProxy()); EmitVariableLoad(callee->AsVariableProxy());
...@@ -2841,7 +2838,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) { ...@@ -2841,7 +2838,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
__ StoreP(r3, MemOperand(sp, kPointerSize)); __ StoreP(r3, MemOperand(sp, kPointerSize));
} }
EmitCall(expr, call_type); EmitCall(expr);
} }
...@@ -2879,7 +2876,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { ...@@ -2879,7 +2876,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
// Stack here: // Stack here:
// - target function // - target function
// - this (receiver) // - this (receiver)
EmitCall(expr, CallICState::METHOD); EmitCall(expr);
} }
...@@ -2902,7 +2899,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) { ...@@ -2902,7 +2899,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) {
__ push(ip); __ push(ip);
__ StoreP(r3, MemOperand(sp, kPointerSize)); __ StoreP(r3, MemOperand(sp, kPointerSize));
EmitCall(expr, CallICState::METHOD); EmitCall(expr);
} }
...@@ -2938,11 +2935,11 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { ...@@ -2938,11 +2935,11 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
// Stack here: // Stack here:
// - target function // - target function
// - this (receiver) // - this (receiver)
EmitCall(expr, CallICState::METHOD); EmitCall(expr);
} }
void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { void FullCodeGenerator::EmitCall(Call* expr) {
// Load the arguments. // Load the arguments.
ZoneList<Expression*>* args = expr->arguments(); ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length(); int arg_count = args->length();
...@@ -2952,7 +2949,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { ...@@ -2952,7 +2949,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS); PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
SetCallPosition(expr, arg_count); SetCallPosition(expr, arg_count);
Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count).code();
__ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot())); __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot()));
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
// Don't assign a type feedback id to the IC, since type feedback is provided // Don't assign a type feedback id to the IC, since type feedback is provided
...@@ -3060,9 +3057,9 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) { ...@@ -3060,9 +3057,9 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
// Record source position for debugger. // Record source position for debugger.
SetCallPosition(expr, arg_count); SetCallPosition(expr, arg_count);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
__ CallStub(&stub); __ mov(r3, Operand(arg_count));
__ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
// Restore context register. // Restore context register.
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
...@@ -4259,9 +4256,9 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { ...@@ -4259,9 +4256,9 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
int arg_count = args->length(); int arg_count = args->length();
SetCallPosition(expr, arg_count); SetCallPosition(expr, arg_count);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0); __ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
__ CallStub(&stub); __ mov(r3, Operand(arg_count));
__ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
} }
......
...@@ -2529,119 +2529,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) { ...@@ -2529,119 +2529,6 @@ static void GenerateRecordCallTarget(MacroAssembler* masm, bool is_super) {
} }
static void EmitContinueIfStrictOrNative(MacroAssembler* masm, Label* cont) {
// ----------- S t a t e -------------
// -- r4 : the function to call
// -- r6 : the function's shared function info
// -----------------------------------
// Do not transform the receiver for strict mode functions and natives.
__ lwz(r7, FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset));
__ andi(r0, r7, Operand((1 << SharedFunctionInfo::kStrictModeBit) |
(1 << SharedFunctionInfo::kNativeBit)));
__ bne(cont, cr0);
}
static void EmitSlowCase(MacroAssembler* masm, int argc) {
__ mov(r3, Operand(argc));
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
}
static void EmitWrapCase(MacroAssembler* masm, int argc, Label* cont) {
// Wrap the receiver and patch it back onto the stack.
{
FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
__ push(r4);
__ mr(r3, r6);
ToObjectStub stub(masm->isolate());
__ CallStub(&stub);
__ pop(r4);
}
__ StoreP(r3, MemOperand(sp, argc * kPointerSize), r0);
__ b(cont);
}
static void EmitClassConstructorCallCheck(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- r4 : the function to call
// -- r6 : the function's shared function info
// -----------------------------------
// ClassConstructor Check: ES6 section 9.2.1 [[Call]]
Label non_class_constructor;
// Check whether the current function is a classConstructor.
__ lwz(r7, FieldMemOperand(r6, SharedFunctionInfo::kCompilerHintsOffset));
__ TestBitMask(r7, SharedFunctionInfo::kClassConstructorBits, r0);
__ beq(&non_class_constructor, cr0);
// If we call a classConstructor Function throw a TypeError
// indirectly via the CallFunction builtin.
__ Jump(masm->isolate()->builtins()->CallFunction(), RelocInfo::CODE_TARGET);
__ bind(&non_class_constructor);
}
static void CallFunctionNoFeedback(MacroAssembler* masm, int argc,
bool needs_checks, bool call_as_method) {
// r4 : the function to call
Label slow, wrap, cont;
if (needs_checks) {
// Check that the function is really a JavaScript function.
// r4: pushed function (to be verified)
__ JumpIfSmi(r4, &slow);
// Goto slow case if we do not have a function.
__ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE);
__ bne(&slow);
}
__ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
EmitClassConstructorCallCheck(masm);
// Fast-case: Invoke the function now.
// r4: pushed function
ParameterCount actual(argc);
if (call_as_method) {
if (needs_checks) {
EmitContinueIfStrictOrNative(masm, &cont);
}
// Compute the receiver in sloppy mode.
__ LoadP(r6, MemOperand(sp, argc * kPointerSize), r0);
if (needs_checks) {
__ JumpIfSmi(r6, &wrap);
__ CompareObjectType(r6, r7, r7, FIRST_SPEC_OBJECT_TYPE);
__ blt(&wrap);
} else {
__ b(&wrap);
}
__ bind(&cont);
}
__ InvokeFunction(r4, actual, JUMP_FUNCTION, NullCallWrapper());
if (needs_checks) {
// Slow-case: Non-function called.
__ bind(&slow);
EmitSlowCase(masm, argc);
}
if (call_as_method) {
__ bind(&wrap);
EmitWrapCase(masm, argc, &cont);
}
}
void CallFunctionStub::Generate(MacroAssembler* masm) {
CallFunctionNoFeedback(masm, argc(), NeedsChecks(), CallAsMethod());
}
void CallConstructStub::Generate(MacroAssembler* masm) { void CallConstructStub::Generate(MacroAssembler* masm) {
// r3 : number of arguments // r3 : number of arguments
// r4 : the function to call // r4 : the function to call
...@@ -2732,9 +2619,7 @@ void CallICStub::Generate(MacroAssembler* masm) { ...@@ -2732,9 +2619,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex); FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
const int generic_offset = const int generic_offset =
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex); FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
Label extra_checks_or_miss, slow_start; Label extra_checks_or_miss, call;
Label slow, wrap, cont;
Label have_js_function;
int argc = arg_count(); int argc = arg_count();
ParameterCount actual(argc); ParameterCount actual(argc);
...@@ -2771,38 +2656,15 @@ void CallICStub::Generate(MacroAssembler* masm) { ...@@ -2771,38 +2656,15 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ AddSmiLiteral(r6, r6, Smi::FromInt(CallICNexus::kCallCountIncrement), r0); __ AddSmiLiteral(r6, r6, Smi::FromInt(CallICNexus::kCallCountIncrement), r0);
__ StoreP(r6, FieldMemOperand(r9, count_offset), r0); __ StoreP(r6, FieldMemOperand(r9, count_offset), r0);
__ bind(&have_js_function); __ bind(&call);
__ mov(r3, Operand(argc));
__ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
EmitClassConstructorCallCheck(masm);
if (CallAsMethod()) {
EmitContinueIfStrictOrNative(masm, &cont);
// Compute the receiver in sloppy mode.
__ LoadP(r6, MemOperand(sp, argc * kPointerSize), r0);
__ JumpIfSmi(r6, &wrap);
__ CompareObjectType(r6, r7, r7, FIRST_SPEC_OBJECT_TYPE);
__ blt(&wrap);
__ bind(&cont);
}
__ InvokeFunction(r4, actual, JUMP_FUNCTION, NullCallWrapper());
__ bind(&slow);
EmitSlowCase(masm, argc);
if (CallAsMethod()) {
__ bind(&wrap);
EmitWrapCase(masm, argc, &cont);
}
__ bind(&extra_checks_or_miss); __ bind(&extra_checks_or_miss);
Label uninitialized, miss, not_allocation_site; Label uninitialized, miss, not_allocation_site;
__ CompareRoot(r7, Heap::kmegamorphic_symbolRootIndex); __ CompareRoot(r7, Heap::kmegamorphic_symbolRootIndex);
__ beq(&slow_start); __ beq(&call);
// Verify that r7 contains an AllocationSite // Verify that r7 contains an AllocationSite
__ LoadP(r8, FieldMemOperand(r7, HeapObject::kMapOffset)); __ LoadP(r8, FieldMemOperand(r7, HeapObject::kMapOffset));
...@@ -2837,7 +2699,7 @@ void CallICStub::Generate(MacroAssembler* masm) { ...@@ -2837,7 +2699,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ LoadP(r7, FieldMemOperand(r5, generic_offset)); __ LoadP(r7, FieldMemOperand(r5, generic_offset));
__ AddSmiLiteral(r7, r7, Smi::FromInt(1), r0); __ AddSmiLiteral(r7, r7, Smi::FromInt(1), r0);
__ StoreP(r7, FieldMemOperand(r5, generic_offset), r0); __ StoreP(r7, FieldMemOperand(r5, generic_offset), r0);
__ b(&slow_start); __ b(&call);
__ bind(&uninitialized); __ bind(&uninitialized);
...@@ -2875,23 +2737,14 @@ void CallICStub::Generate(MacroAssembler* masm) { ...@@ -2875,23 +2737,14 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ Pop(r4); __ Pop(r4);
} }
__ b(&have_js_function); __ b(&call);
// We are here because tracing is on or we encountered a MISS case we can't // We are here because tracing is on or we encountered a MISS case we can't
// handle here. // handle here.
__ bind(&miss); __ bind(&miss);
GenerateMiss(masm); GenerateMiss(masm);
// the slow case __ b(&call);
__ bind(&slow_start);
// Check that the function is really a JavaScript function.
// r4: pushed function (to be verified)
__ JumpIfSmi(r4, &slow);
// Goto slow case if we do not have a function.
__ CompareObjectType(r4, r7, r7, JS_FUNCTION_TYPE);
__ bne(&slow);
__ b(&have_js_function);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment