[crankshaft] HCallWithDescriptor is now able to pass arguments on the stack.

BUG=v8:5407

Review-Url: https://codereview.chromium.org/2353303002
Cr-Commit-Position: refs/heads/master@{#39613}
This commit is contained in:
ishell 2016-09-21 23:55:00 -07:00 committed by Commit bot
parent 5d693348f0
commit 0acde6f974
13 changed files with 179 additions and 84 deletions

View File

@ -126,8 +126,8 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
HParameter::STACK_PARAMETER, r);
} else {
param = Add<HParameter>(i, HParameter::REGISTER_PARAMETER, r);
start_environment->Bind(i, param);
}
start_environment->Bind(i, param);
parameters_[i] = param;
if (i < register_param_count && IsParameterCountRegister(i)) {
param->set_type(HType::Smi());

View File

@ -1001,6 +1001,9 @@ LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
LInstruction* LChunkBuilder::DoCallWithDescriptor(
HCallWithDescriptor* instr) {
CallInterfaceDescriptor descriptor = instr->descriptor();
DCHECK_EQ(descriptor.GetParameterCount() +
LCallWithDescriptor::kImplicitRegisterParameterCount,
instr->OperandCount());
LOperand* target = UseRegisterOrConstantAtStart(instr->target());
ZoneList<LOperand*> ops(instr->OperandCount(), zone());
@ -1009,15 +1012,20 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
// Context
LOperand* op = UseFixed(instr->OperandAt(1), cp);
ops.Add(op, zone());
// Other register parameters
for (int i = LCallWithDescriptor::kImplicitRegisterParameterCount;
i < instr->OperandCount(); i++) {
op =
UseFixed(instr->OperandAt(i),
descriptor.GetRegisterParameter(
i - LCallWithDescriptor::kImplicitRegisterParameterCount));
// Load register parameters.
int i = 0;
for (; i < descriptor.GetRegisterParameterCount(); i++) {
op = UseFixed(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount),
descriptor.GetRegisterParameter(i));
ops.Add(op, zone());
}
// Push stack parameters.
for (; i < descriptor.GetParameterCount(); i++) {
op = UseAny(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount));
AddInstruction(new (zone()) LPushArgument(op), instr);
}
LCallWithDescriptor* result = new(zone()) LCallWithDescriptor(
descriptor, ops, zone());

View File

@ -963,6 +963,9 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
LInstruction* LChunkBuilder::DoCallWithDescriptor(
HCallWithDescriptor* instr) {
CallInterfaceDescriptor descriptor = instr->descriptor();
DCHECK_EQ(descriptor.GetParameterCount() +
LCallWithDescriptor::kImplicitRegisterParameterCount,
instr->OperandCount());
LOperand* target = UseRegisterOrConstantAtStart(instr->target());
ZoneList<LOperand*> ops(instr->OperandCount(), zone());
@ -971,15 +974,30 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
// Context
LOperand* op = UseFixed(instr->OperandAt(1), cp);
ops.Add(op, zone());
// Other register parameters
for (int i = LCallWithDescriptor::kImplicitRegisterParameterCount;
i < instr->OperandCount(); i++) {
op =
UseFixed(instr->OperandAt(i),
descriptor.GetRegisterParameter(
i - LCallWithDescriptor::kImplicitRegisterParameterCount));
// Load register parameters.
int i = 0;
for (; i < descriptor.GetRegisterParameterCount(); i++) {
op = UseFixed(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount),
descriptor.GetRegisterParameter(i));
ops.Add(op, zone());
}
// Push stack parameters.
if (i < descriptor.GetParameterCount()) {
int argc = descriptor.GetParameterCount() - i;
AddInstruction(new (zone()) LPreparePushArguments(argc), instr);
LPushArguments* push_args = new (zone()) LPushArguments(zone());
for (; i < descriptor.GetParameterCount(); i++) {
if (push_args->ShouldSplitPush()) {
AddInstruction(push_args, instr);
push_args = new (zone()) LPushArguments(zone());
}
op = UseRegisterAtStart(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount));
push_args->AddArgument(op);
}
AddInstruction(push_args, instr);
}
LCallWithDescriptor* result = new(zone()) LCallWithDescriptor(descriptor,
ops,

View File

@ -1968,7 +1968,16 @@ void LCodeGen::DoCallWithDescriptor(LCallWithDescriptor* instr) {
generator.AfterCall();
}
RecordPushedArgumentsDelta(instr->hydrogen()->argument_delta());
HCallWithDescriptor* hinstr = instr->hydrogen();
RecordPushedArgumentsDelta(hinstr->argument_delta());
// HCallWithDescriptor instruction is translated to zero or more
// LPushArguments (they handle parameters passed on the stack) followed by
// a LCallWithDescriptor. Each LPushArguments instruction generated records
// the number of arguments pushed thus we need to offset them here.
// The |argument_delta()| used above "knows" only about JS parameters while
// we are dealing here with particular calling convention details.
RecordPushedArgumentsDelta(-hinstr->descriptor().GetStackParameterCount());
}

View File

@ -2215,7 +2215,7 @@ class HCallWithDescriptor final : public HInstruction {
TailCallMode syntactic_tail_call_mode,
TailCallMode tail_call_mode, Zone* zone)
: descriptor_(descriptor),
values_(GetParameterCount() + 1, zone),
values_(GetParameterCount() + 1, zone), // +1 here is for target.
argument_count_(argument_count),
bit_field_(
TailCallModeField::encode(tail_call_mode) |
@ -2237,7 +2237,7 @@ class HCallWithDescriptor final : public HInstruction {
}
int GetParameterCount() const {
return descriptor_.GetRegisterParameterCount() + 1;
return descriptor_.GetParameterCount() + 1; // +1 here is for context.
}
void InternalSetOperandAt(int index, HValue* value) final {

View File

@ -3492,8 +3492,8 @@ HGraph::HGraph(CompilationInfo* info, CallInterfaceDescriptor descriptor)
inlined_function_infos_(info->zone()) {
if (info->IsStub()) {
// For stubs, explicitly add the context to the environment.
start_environment_ = new (zone_)
HEnvironment(zone_, descriptor.GetRegisterParameterCount() + 1);
start_environment_ =
new (zone_) HEnvironment(zone_, descriptor.GetParameterCount() + 1);
} else {
start_environment_ =
new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
@ -9230,7 +9230,7 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(
HValue* api_function_address = Add<HConstant>(ExternalReference(ref));
HValue* op_vals[] = {context(), Add<HConstant>(function), call_data, holder,
api_function_address, nullptr};
api_function_address};
HInstruction* call = nullptr;
CHECK(argc <= CallApiCallbackStub::kArgMax);
@ -9241,16 +9241,14 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(
HConstant* code_value = Add<HConstant>(code);
call = New<HCallWithDescriptor>(
code_value, argc + 1, stub.GetCallInterfaceDescriptor(),
Vector<HValue*>(op_vals, arraysize(op_vals) - 1),
syntactic_tail_call_mode);
Vector<HValue*>(op_vals, arraysize(op_vals)), syntactic_tail_call_mode);
} else {
CallApiCallbackStub stub(isolate(), argc, call_data_undefined, false);
Handle<Code> code = stub.GetCode();
HConstant* code_value = Add<HConstant>(code);
call = New<HCallWithDescriptor>(
code_value, argc + 1, stub.GetCallInterfaceDescriptor(),
Vector<HValue*>(op_vals, arraysize(op_vals) - 1),
syntactic_tail_call_mode);
Vector<HValue*>(op_vals, arraysize(op_vals)), syntactic_tail_call_mode);
Drop(1); // Drop function.
}
@ -12318,13 +12316,14 @@ void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
DCHECK_EQ(3, call->arguments()->length());
CHECK_ALIVE(VisitExpressions(call->arguments()));
PushArgumentsFromEnvironment(call->arguments()->length());
Callable callable = CodeFactory::SubString(isolate());
HValue* stub = Add<HConstant>(callable.code());
HValue* values[] = {context()};
HInstruction* result =
New<HCallWithDescriptor>(stub, call->arguments()->length(),
callable.descriptor(), ArrayVector(values));
HValue* to = Pop();
HValue* from = Pop();
HValue* string = Pop();
HValue* values[] = {context(), string, from, to};
HInstruction* result = New<HCallWithDescriptor>(
stub, 0, callable.descriptor(), ArrayVector(values));
result->set_type(HType::String());
return ast_context()->ReturnInstruction(result, call->id());
}
@ -12346,13 +12345,16 @@ void HOptimizedGraphBuilder::GenerateNewObject(CallRuntime* call) {
void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
DCHECK_EQ(4, call->arguments()->length());
CHECK_ALIVE(VisitExpressions(call->arguments()));
PushArgumentsFromEnvironment(call->arguments()->length());
Callable callable = CodeFactory::RegExpExec(isolate());
HValue* last_match_info = Pop();
HValue* index = Pop();
HValue* subject = Pop();
HValue* regexp_object = Pop();
HValue* stub = Add<HConstant>(callable.code());
HValue* values[] = {context()};
HInstruction* result =
New<HCallWithDescriptor>(stub, call->arguments()->length(),
callable.descriptor(), ArrayVector(values));
HValue* values[] = {context(), regexp_object, subject, index,
last_match_info};
HInstruction* result = New<HCallWithDescriptor>(
stub, 0, callable.descriptor(), ArrayVector(values));
return ast_context()->ReturnInstruction(result, call->id());
}

View File

@ -1036,6 +1036,10 @@ LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
LInstruction* LChunkBuilder::DoCallWithDescriptor(
HCallWithDescriptor* instr) {
CallInterfaceDescriptor descriptor = instr->descriptor();
DCHECK_EQ(descriptor.GetParameterCount() +
LCallWithDescriptor::kImplicitRegisterParameterCount,
instr->OperandCount());
LOperand* target = UseRegisterOrConstantAtStart(instr->target());
ZoneList<LOperand*> ops(instr->OperandCount(), zone());
// Target
@ -1043,15 +1047,20 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
// Context
LOperand* op = UseFixed(instr->OperandAt(1), esi);
ops.Add(op, zone());
// Other register parameters
for (int i = LCallWithDescriptor::kImplicitRegisterParameterCount;
i < instr->OperandCount(); i++) {
op =
UseFixed(instr->OperandAt(i),
descriptor.GetRegisterParameter(
i - LCallWithDescriptor::kImplicitRegisterParameterCount));
// Load register parameters.
int i = 0;
for (; i < descriptor.GetRegisterParameterCount(); i++) {
op = UseFixed(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount),
descriptor.GetRegisterParameter(i));
ops.Add(op, zone());
}
// Push stack parameters.
for (; i < descriptor.GetParameterCount(); i++) {
op = UseAny(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount));
AddInstruction(new (zone()) LPushArgument(op), instr);
}
LCallWithDescriptor* result = new(zone()) LCallWithDescriptor(
descriptor, ops, zone());

View File

@ -1006,6 +1006,9 @@ LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
LInstruction* LChunkBuilder::DoCallWithDescriptor(
HCallWithDescriptor* instr) {
CallInterfaceDescriptor descriptor = instr->descriptor();
DCHECK_EQ(descriptor.GetParameterCount() +
LCallWithDescriptor::kImplicitRegisterParameterCount,
instr->OperandCount());
LOperand* target = UseRegisterOrConstantAtStart(instr->target());
ZoneList<LOperand*> ops(instr->OperandCount(), zone());
@ -1014,15 +1017,20 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
// Context
LOperand* op = UseFixed(instr->OperandAt(1), cp);
ops.Add(op, zone());
// Other register parameters
for (int i = LCallWithDescriptor::kImplicitRegisterParameterCount;
i < instr->OperandCount(); i++) {
op =
UseFixed(instr->OperandAt(i),
descriptor.GetRegisterParameter(
i - LCallWithDescriptor::kImplicitRegisterParameterCount));
// Load register parameters.
int i = 0;
for (; i < descriptor.GetRegisterParameterCount(); i++) {
op = UseFixed(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount),
descriptor.GetRegisterParameter(i));
ops.Add(op, zone());
}
// Push stack parameters.
for (; i < descriptor.GetParameterCount(); i++) {
op = UseAny(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount));
AddInstruction(new (zone()) LPushArgument(op), instr);
}
LCallWithDescriptor* result = new(zone()) LCallWithDescriptor(
descriptor, ops, zone());

View File

@ -1006,6 +1006,9 @@ LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
LInstruction* LChunkBuilder::DoCallWithDescriptor(
HCallWithDescriptor* instr) {
CallInterfaceDescriptor descriptor = instr->descriptor();
DCHECK_EQ(descriptor.GetParameterCount() +
LCallWithDescriptor::kImplicitRegisterParameterCount,
instr->OperandCount());
LOperand* target = UseRegisterOrConstantAtStart(instr->target());
ZoneList<LOperand*> ops(instr->OperandCount(), zone());
@ -1014,15 +1017,20 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
// Context
LOperand* op = UseFixed(instr->OperandAt(1), cp);
ops.Add(op, zone());
// Other register parameters
for (int i = LCallWithDescriptor::kImplicitRegisterParameterCount;
i < instr->OperandCount(); i++) {
op =
UseFixed(instr->OperandAt(i),
descriptor.GetRegisterParameter(
i - LCallWithDescriptor::kImplicitRegisterParameterCount));
// Load register parameters.
int i = 0;
for (; i < descriptor.GetRegisterParameterCount(); i++) {
op = UseFixed(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount),
descriptor.GetRegisterParameter(i));
ops.Add(op, zone());
}
// Push stack parameters.
for (; i < descriptor.GetParameterCount(); i++) {
op = UseAny(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount));
AddInstruction(new (zone()) LPushArgument(op), instr);
}
LCallWithDescriptor* result = new(zone()) LCallWithDescriptor(
descriptor, ops, zone());

View File

@ -1012,6 +1012,9 @@ LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
LInstruction* LChunkBuilder::DoCallWithDescriptor(HCallWithDescriptor* instr) {
CallInterfaceDescriptor descriptor = instr->descriptor();
DCHECK_EQ(descriptor.GetParameterCount() +
LCallWithDescriptor::kImplicitRegisterParameterCount,
instr->OperandCount());
LOperand* target = UseRegisterOrConstantAtStart(instr->target());
ZoneList<LOperand*> ops(instr->OperandCount(), zone());
@ -1020,15 +1023,20 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(HCallWithDescriptor* instr) {
// Context
LOperand* op = UseFixed(instr->OperandAt(1), cp);
ops.Add(op, zone());
// Other register parameters
for (int i = LCallWithDescriptor::kImplicitRegisterParameterCount;
i < instr->OperandCount(); i++) {
op =
UseFixed(instr->OperandAt(i),
descriptor.GetRegisterParameter(
i - LCallWithDescriptor::kImplicitRegisterParameterCount));
// Load register parameters.
int i = 0;
for (; i < descriptor.GetRegisterParameterCount(); i++) {
op = UseFixed(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount),
descriptor.GetRegisterParameter(i));
ops.Add(op, zone());
}
// Push stack parameters.
for (; i < descriptor.GetParameterCount(); i++) {
op = UseAny(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount));
AddInstruction(new (zone()) LPushArgument(op), instr);
}
LCallWithDescriptor* result =
new (zone()) LCallWithDescriptor(descriptor, ops, zone());

View File

@ -921,6 +921,9 @@ LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
LInstruction* LChunkBuilder::DoCallWithDescriptor(HCallWithDescriptor* instr) {
CallInterfaceDescriptor descriptor = instr->descriptor();
DCHECK_EQ(descriptor.GetParameterCount() +
LCallWithDescriptor::kImplicitRegisterParameterCount,
instr->OperandCount());
LOperand* target = UseRegisterOrConstantAtStart(instr->target());
ZoneList<LOperand*> ops(instr->OperandCount(), zone());
@ -929,15 +932,20 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(HCallWithDescriptor* instr) {
// Context
LOperand* op = UseFixed(instr->OperandAt(1), cp);
ops.Add(op, zone());
// Other register parameters
for (int i = LCallWithDescriptor::kImplicitRegisterParameterCount;
i < instr->OperandCount(); i++) {
op =
UseFixed(instr->OperandAt(i),
descriptor.GetRegisterParameter(
i - LCallWithDescriptor::kImplicitRegisterParameterCount));
// Load register parameters.
int i = 0;
for (; i < descriptor.GetRegisterParameterCount(); i++) {
op = UseFixed(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount),
descriptor.GetRegisterParameter(i));
ops.Add(op, zone());
}
// Push stack parameters.
for (; i < descriptor.GetParameterCount(); i++) {
op = UseAny(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount));
AddInstruction(new (zone()) LPushArgument(op), instr);
}
LCallWithDescriptor* result =
new (zone()) LCallWithDescriptor(descriptor, ops, zone());

View File

@ -1024,6 +1024,9 @@ LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
LInstruction* LChunkBuilder::DoCallWithDescriptor(
HCallWithDescriptor* instr) {
CallInterfaceDescriptor descriptor = instr->descriptor();
DCHECK_EQ(descriptor.GetParameterCount() +
LCallWithDescriptor::kImplicitRegisterParameterCount,
instr->OperandCount());
LOperand* target = UseRegisterOrConstantAtStart(instr->target());
ZoneList<LOperand*> ops(instr->OperandCount(), zone());
@ -1032,15 +1035,20 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
// Context
LOperand* op = UseFixed(instr->OperandAt(1), rsi);
ops.Add(op, zone());
// Other register parameters
for (int i = LCallWithDescriptor::kImplicitRegisterParameterCount;
i < instr->OperandCount(); i++) {
op =
UseFixed(instr->OperandAt(i),
descriptor.GetRegisterParameter(
i - LCallWithDescriptor::kImplicitRegisterParameterCount));
// Load register parameters.
int i = 0;
for (; i < descriptor.GetRegisterParameterCount(); i++) {
op = UseFixed(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount),
descriptor.GetRegisterParameter(i));
ops.Add(op, zone());
}
// Push stack parameters.
for (; i < descriptor.GetParameterCount(); i++) {
op = UseAny(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount));
AddInstruction(new (zone()) LPushArgument(op), instr);
}
LCallWithDescriptor* result = new(zone()) LCallWithDescriptor(
descriptor, ops, zone());

View File

@ -1053,6 +1053,10 @@ LInstruction* LChunkBuilder::DoDeclareGlobals(HDeclareGlobals* instr) {
LInstruction* LChunkBuilder::DoCallWithDescriptor(
HCallWithDescriptor* instr) {
CallInterfaceDescriptor descriptor = instr->descriptor();
DCHECK_EQ(descriptor.GetParameterCount() +
LCallWithDescriptor::kImplicitRegisterParameterCount,
instr->OperandCount());
LOperand* target = UseRegisterOrConstantAtStart(instr->target());
ZoneList<LOperand*> ops(instr->OperandCount(), zone());
// Target
@ -1060,15 +1064,20 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
// Context
LOperand* op = UseFixed(instr->OperandAt(1), esi);
ops.Add(op, zone());
// Other register parameters
for (int i = LCallWithDescriptor::kImplicitRegisterParameterCount;
i < instr->OperandCount(); i++) {
op =
UseFixed(instr->OperandAt(i),
descriptor.GetRegisterParameter(
i - LCallWithDescriptor::kImplicitRegisterParameterCount));
// Load register parameters.
int i = 0;
for (; i < descriptor.GetRegisterParameterCount(); i++) {
op = UseFixed(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount),
descriptor.GetRegisterParameter(i));
ops.Add(op, zone());
}
// Push stack parameters.
for (; i < descriptor.GetParameterCount(); i++) {
op = UseAny(instr->OperandAt(
i + LCallWithDescriptor::kImplicitRegisterParameterCount));
AddInstruction(new (zone()) LPushArgument(op), instr);
}
LCallWithDescriptor* result = new(zone()) LCallWithDescriptor(
descriptor, ops, zone());