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) {
DCHECK(ToRegister(instr->result()).is(r3));
int arity = instr->arity();
CallFunctionFlags flags = instr->hydrogen()->function_flags();
if (instr->hydrogen()->HasVectorAndSlot()) {
Register slot_register = ToRegister(instr->temp_slot());
Register vector_register = ToRegister(instr->temp_vector());
......@@ -4065,15 +4064,12 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
__ Move(vector_register, vector);
__ LoadSmiLiteral(slot_register, Smi::FromInt(index));
CallICState::CallType call_type =
(flags & CALL_AS_METHOD) ? CallICState::METHOD : CallICState::FUNCTION;
Handle<Code> ic =
CodeFactory::CallICInOptimizedCode(isolate(), arity, call_type).code();
CodeFactory::CallICInOptimizedCode(isolate(), arity).code();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
} else {
CallFunctionStub stub(isolate(), arity, flags);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
__ mov(r3, Operand(arity));
CallCode(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET, instr);
}
}
......
......@@ -2088,8 +2088,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ mr(r4, r3);
__ StoreP(r4, MemOperand(sp, 2 * kPointerSize));
SetCallPosition(expr, 1);
CallFunctionStub stub(isolate(), 1, CALL_AS_METHOD);
__ CallStub(&stub);
__ li(r3, Operand(1));
__ Call(isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
__ Drop(1); // The function is still on the stack; drop it.
......@@ -2814,11 +2814,8 @@ void FullCodeGenerator::CallIC(Handle<Code> code, TypeFeedbackId ast_id) {
void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
Expression* callee = expr->expression();
CallICState::CallType call_type =
callee->IsVariableProxy() ? CallICState::FUNCTION : CallICState::METHOD;
// Get the target function.
if (call_type == CallICState::FUNCTION) {
if (callee->IsVariableProxy()) {
{
StackValueContext context(this);
EmitVariableLoad(callee->AsVariableProxy());
......@@ -2841,7 +2838,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
__ StoreP(r3, MemOperand(sp, kPointerSize));
}
EmitCall(expr, call_type);
EmitCall(expr);
}
......@@ -2879,7 +2876,7 @@ void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) {
// Stack here:
// - target function
// - this (receiver)
EmitCall(expr, CallICState::METHOD);
EmitCall(expr);
}
......@@ -2902,7 +2899,7 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, Expression* key) {
__ push(ip);
__ StoreP(r3, MemOperand(sp, kPointerSize));
EmitCall(expr, CallICState::METHOD);
EmitCall(expr);
}
......@@ -2938,11 +2935,11 @@ void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) {
// Stack here:
// - target function
// - 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.
ZoneList<Expression*>* args = expr->arguments();
int arg_count = args->length();
......@@ -2952,7 +2949,7 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
PrepareForBailoutForId(expr->CallId(), NO_REGISTERS);
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()));
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
// Don't assign a type feedback id to the IC, since type feedback is provided
......@@ -3060,9 +3057,9 @@ void FullCodeGenerator::EmitPossiblyEvalCall(Call* expr) {
// Record source position for debugger.
SetCallPosition(expr, arg_count);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ 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);
// Restore context register.
__ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
......@@ -4259,9 +4256,9 @@ void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) {
int arg_count = args->length();
SetCallPosition(expr, arg_count);
CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS);
__ 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) {
}
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) {
// r3 : number of arguments
// r4 : the function to call
......@@ -2732,9 +2619,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kWithTypesIndex);
const int generic_offset =
FixedArray::OffsetOfElementAt(TypeFeedbackVector::kGenericCountIndex);
Label extra_checks_or_miss, slow_start;
Label slow, wrap, cont;
Label have_js_function;
Label extra_checks_or_miss, call;
int argc = arg_count();
ParameterCount actual(argc);
......@@ -2771,38 +2656,15 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ AddSmiLiteral(r6, r6, Smi::FromInt(CallICNexus::kCallCountIncrement), r0);
__ StoreP(r6, FieldMemOperand(r9, count_offset), r0);
__ bind(&have_js_function);
__ LoadP(r6, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset));
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(&call);
__ mov(r3, Operand(argc));
__ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET);
__ bind(&extra_checks_or_miss);
Label uninitialized, miss, not_allocation_site;
__ CompareRoot(r7, Heap::kmegamorphic_symbolRootIndex);
__ beq(&slow_start);
__ beq(&call);
// Verify that r7 contains an AllocationSite
__ LoadP(r8, FieldMemOperand(r7, HeapObject::kMapOffset));
......@@ -2837,7 +2699,7 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ LoadP(r7, FieldMemOperand(r5, generic_offset));
__ AddSmiLiteral(r7, r7, Smi::FromInt(1), r0);
__ StoreP(r7, FieldMemOperand(r5, generic_offset), r0);
__ b(&slow_start);
__ b(&call);
__ bind(&uninitialized);
......@@ -2875,23 +2737,14 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ Pop(r4);
}
__ b(&have_js_function);
__ b(&call);
// We are here because tracing is on or we encountered a MISS case we can't
// handle here.
__ bind(&miss);
GenerateMiss(masm);
// the slow case
__ 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);
__ b(&call);
}
......
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