// Change context.
__ ldr(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset));
- // Set r0 to arguments count if adaption is not needed. Assumes that r0
- // is available to write to at this point.
- if (dont_adapt_arguments) {
- __ mov(r0, Operand(arity));
- }
+ // Always initialize r0 to the number of actual arguments.
+ __ mov(r0, Operand(arity));
// Invoke function.
__ ldr(ip, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset));
DCHECK(ToRegister(instr->function()).is(r1));
DCHECK(ToRegister(instr->result()).is(r0));
- if (instr->hydrogen()->pass_argument_count()) {
- __ mov(r0, Operand(instr->arity()));
- }
+ __ mov(r0, Operand(instr->arity()));
// Change context.
__ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
+ mov(r0, Operand(actual.immediate()));
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
- mov(r0, Operand(actual.immediate()));
const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
if (expected.immediate() == sentinel) {
// Don't worry about adapting arguments for builtins that
}
} else {
if (actual.is_immediate()) {
+ mov(r0, Operand(actual.immediate()));
cmp(expected.reg(), Operand(actual.immediate()));
b(eq, ®ular_invoke);
- mov(r0, Operand(actual.immediate()));
} else {
cmp(expected.reg(), Operand(actual.reg()));
b(eq, ®ular_invoke);
// Change context.
__ Ldr(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset));
- // Set the arguments count if adaption is not needed. Assumes that x0 is
- // available to write to at this point.
- if (dont_adapt_arguments) {
- __ Mov(arity_reg, arity);
- }
+ // Always initialize x0 to the number of actual arguments.
+ __ Mov(arity_reg, arity);
// Invoke function.
__ Ldr(x10, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset));
DCHECK(instr->IsMarkedAsCall());
DCHECK(ToRegister(instr->function()).is(x1));
- if (instr->hydrogen()->pass_argument_count()) {
- __ Mov(x0, Operand(instr->arity()));
- }
+ __ Mov(x0, Operand(instr->arity()));
// Change context.
__ Ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset));
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
+ Mov(x0, actual.immediate());
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
- Mov(x0, actual.immediate());
if (expected.immediate() ==
SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
// Don't worry about adapting arguments for builtins that
} else { // expected is a register.
Operand actual_op = actual.is_immediate() ? Operand(actual.immediate())
: Operand(actual.reg());
+ Mov(x0, actual_op);
// If actual == expected perform a regular invocation.
Cmp(expected.reg(), actual_op);
B(eq, ®ular_invoke);
- // Otherwise set up x0 for the argument adaptor.
- Mov(x0, actual_op);
}
// If the argument counts may mismatch, generate a call to the argument
HCallJSFunction* HCallJSFunction::New(Isolate* isolate, Zone* zone,
HValue* context, HValue* function,
- int argument_count,
- bool pass_argument_count) {
+ int argument_count) {
bool has_stack_check = false;
if (function->IsConstant()) {
HConstant* fun_const = HConstant::cast(function);
jsfun->code()->kind() == Code::OPTIMIZED_FUNCTION);
}
- return new(zone) HCallJSFunction(
- function, argument_count, pass_argument_count,
- has_stack_check);
+ return new (zone) HCallJSFunction(function, argument_count, has_stack_check);
}
class HCallJSFunction final : public HCall<1> {
public:
static HCallJSFunction* New(Isolate* isolate, Zone* zone, HValue* context,
- HValue* function, int argument_count,
- bool pass_argument_count);
+ HValue* function, int argument_count);
HValue* function() const { return OperandAt(0); }
return Representation::Tagged();
}
- bool pass_argument_count() const { return pass_argument_count_; }
-
bool HasStackCheck() final { return has_stack_check_; }
DECLARE_CONCRETE_INSTRUCTION(CallJSFunction)
// The argument count includes the receiver.
HCallJSFunction(HValue* function,
int argument_count,
- bool pass_argument_count,
bool has_stack_check)
: HCall<1>(argument_count),
- pass_argument_count_(pass_argument_count),
has_stack_check_(has_stack_check) {
SetOperandAt(0, function);
}
- bool pass_argument_count_;
bool has_stack_check_;
};
}
-HInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall(
- HValue* fun, int argument_count, bool pass_argument_count) {
- return New<HCallJSFunction>(fun, argument_count, pass_argument_count);
+HInstruction* HOptimizedGraphBuilder::NewPlainFunctionCall(HValue* fun,
+ int argument_count) {
+ return New<HCallJSFunction>(fun, argument_count);
}
if (jsfun.is_identical_to(current_info()->closure())) {
graph()->MarkRecursive();
}
- return NewPlainFunctionCall(target, argument_count, dont_adapt_arguments);
+ return NewPlainFunctionCall(target, argument_count);
} else {
HValue* param_count_value = Add<HConstant>(formal_parameter_count);
HValue* context = Add<HLoadNamedField>(
if_inline.Else();
{
Add<HPushArguments>(receiver);
- result = Add<HCallJSFunction>(function, 1, true);
+ result = Add<HCallJSFunction>(function, 1);
if (!ast_context()->IsEffect()) Push(result);
}
if_inline.End();
void AddCheckPrototypeMaps(Handle<JSObject> holder,
Handle<Map> receiver_map);
- HInstruction* NewPlainFunctionCall(HValue* fun,
- int argument_count,
- bool pass_argument_count);
+ HInstruction* NewPlainFunctionCall(HValue* fun, int argument_count);
HInstruction* NewArgumentAdaptorCall(HValue* fun, HValue* context,
int argument_count,
// Change context.
__ mov(esi, FieldOperand(function_reg, JSFunction::kContextOffset));
- // Set eax to arguments count if adaption is not needed. Assumes that eax
- // is available to write to at this point.
- if (dont_adapt_arguments) {
- __ mov(eax, arity);
- }
+ // Always initialize eax to the number of actual arguments.
+ __ mov(eax, arity);
// Invoke function directly.
if (function.is_identical_to(info()->closure())) {
DCHECK(ToRegister(instr->function()).is(edi));
DCHECK(ToRegister(instr->result()).is(eax));
- if (instr->hydrogen()->pass_argument_count()) {
- __ mov(eax, instr->arity());
- }
+ __ mov(eax, instr->arity());
// Change context.
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
Label invoke;
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
+ mov(eax, actual.immediate());
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
- mov(eax, actual.immediate());
const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
if (expected.immediate() == sentinel) {
// Don't worry about adapting arguments for builtins that
// Expected is in register, actual is immediate. This is the
// case when we invoke function values without going through the
// IC mechanism.
+ mov(eax, actual.immediate());
cmp(expected.reg(), actual.immediate());
j(equal, &invoke);
DCHECK(expected.reg().is(ebx));
- mov(eax, actual.immediate());
} else if (!expected.reg().is(actual.reg())) {
// Both expected and actual are in (different) registers. This
// is the case when we invoke functions using call and apply.
j(equal, &invoke);
DCHECK(actual.reg().is(eax));
DCHECK(expected.reg().is(ebx));
+ } else {
+ Move(eax, actual.reg());
}
}
// Change context.
__ lw(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset));
- // Set r0 to arguments count if adaption is not needed. Assumes that r0
- // is available to write to at this point.
- if (dont_adapt_arguments) {
- __ li(a0, Operand(arity));
- }
+ // Always initialize a0 to the number of actual arguments.
+ __ li(a0, Operand(arity));
// Invoke function.
__ lw(at, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset));
DCHECK(ToRegister(instr->function()).is(a1));
DCHECK(ToRegister(instr->result()).is(v0));
- if (instr->hydrogen()->pass_argument_count()) {
- __ li(a0, Operand(instr->arity()));
- }
+ __ li(a0, Operand(instr->arity()));
// Change context.
__ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
+ li(a0, Operand(actual.immediate()));
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
- li(a0, Operand(actual.immediate()));
const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
if (expected.immediate() == sentinel) {
// Don't worry about adapting arguments for builtins that
}
}
} else if (actual.is_immediate()) {
- Branch(®ular_invoke, eq, expected.reg(), Operand(actual.immediate()));
li(a0, Operand(actual.immediate()));
+ Branch(®ular_invoke, eq, expected.reg(), Operand(a0));
} else {
Branch(®ular_invoke, eq, expected.reg(), Operand(actual.reg()));
}
// Change context.
__ ld(cp, FieldMemOperand(function_reg, JSFunction::kContextOffset));
- // Set r0 to arguments count if adaption is not needed. Assumes that r0
- // is available to write to at this point.
- if (dont_adapt_arguments) {
- __ li(a0, Operand(arity));
- }
+ // Always initialize a0 to the number of actual arguments.
+ __ li(a0, Operand(arity));
// Invoke function.
__ ld(at, FieldMemOperand(function_reg, JSFunction::kCodeEntryOffset));
DCHECK(ToRegister(instr->function()).is(a1));
DCHECK(ToRegister(instr->result()).is(v0));
- if (instr->hydrogen()->pass_argument_count()) {
- __ li(a0, Operand(instr->arity()));
- }
+ __ li(a0, Operand(instr->arity()));
// Change context.
__ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
+ li(a0, Operand(actual.immediate()));
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
- li(a0, Operand(actual.immediate()));
const int sentinel = SharedFunctionInfo::kDontAdaptArgumentsSentinel;
if (expected.immediate() == sentinel) {
// Don't worry about adapting arguments for builtins that
}
}
} else if (actual.is_immediate()) {
- Branch(®ular_invoke, eq, expected.reg(), Operand(actual.immediate()));
li(a0, Operand(actual.immediate()));
+ Branch(®ular_invoke, eq, expected.reg(), Operand(a0));
} else {
Branch(®ular_invoke, eq, expected.reg(), Operand(actual.reg()));
}
// Change context.
__ movp(rsi, FieldOperand(function_reg, JSFunction::kContextOffset));
- // Set rax to arguments count if adaption is not needed. Assumes that rax
- // is available to write to at this point.
- if (dont_adapt_arguments) {
- __ Set(rax, arity);
- }
+ // Always initialize rax to the number of actual arguments.
+ __ Set(rax, arity);
// Invoke function.
if (function.is_identical_to(info()->closure())) {
DCHECK(ToRegister(instr->function()).is(rdi));
DCHECK(ToRegister(instr->result()).is(rax));
- if (instr->hydrogen()->pass_argument_count()) {
- __ Set(rax, instr->arity());
- }
+ __ Set(rax, instr->arity());
// Change context.
__ movp(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
Label invoke;
if (expected.is_immediate()) {
DCHECK(actual.is_immediate());
+ Set(rax, actual.immediate());
if (expected.immediate() == actual.immediate()) {
definitely_matches = true;
} else {
- Set(rax, actual.immediate());
if (expected.immediate() ==
SharedFunctionInfo::kDontAdaptArgumentsSentinel) {
// Don't worry about adapting arguments for built-ins that
// Expected is in register, actual is immediate. This is the
// case when we invoke function values without going through the
// IC mechanism.
+ Set(rax, actual.immediate());
cmpp(expected.reg(), Immediate(actual.immediate()));
j(equal, &invoke, Label::kNear);
DCHECK(expected.reg().is(rbx));
- Set(rax, actual.immediate());
} else if (!expected.reg().is(actual.reg())) {
// Both expected and actual are in (different) registers. This
// is the case when we invoke functions using call and apply.
j(equal, &invoke, Label::kNear);
DCHECK(actual.reg().is(rax));
DCHECK(expected.reg().is(rbx));
+ } else {
+ Move(rax, actual.reg());
}
}