Commit b957128b authored by balazs.kilvady's avatar balazs.kilvady Committed by Commit bot

MIPS: Continue learning for calls in crankshaft.

Port 7d363783

Original commit message:
The type feedback vector makes this easy to do.
This is a re-land of https://codereview.chromium.org/868453005/
with a fix for the DCHECK failure.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#26311}
parent 52840146
......@@ -4053,8 +4053,30 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
DCHECK(ToRegister(instr->result()).is(v0));
int arity = instr->arity();
CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
CallFunctionFlags flags = instr->hydrogen()->function_flags();
if (instr->hydrogen()->HasVectorAndSlot()) {
Register slot_register = ToRegister(instr->temp_slot());
Register vector_register = ToRegister(instr->temp_vector());
DCHECK(slot_register.is(a3));
DCHECK(vector_register.is(a2));
AllowDeferredHandleDereference vector_structure_check;
Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
int index = vector->GetIndex(instr->hydrogen()->slot());
__ li(vector_register, vector);
__ li(slot_register, Operand(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();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
} else {
CallFunctionStub stub(isolate(), arity, flags);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
}
......
......@@ -262,6 +262,20 @@ void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
}
void LCallFunction::PrintDataTo(StringStream* stream) {
context()->PrintTo(stream);
stream->Add(" ");
function()->PrintTo(stream);
if (hydrogen()->HasVectorAndSlot()) {
stream->Add(" (type-feedback-vector ");
temp_vector()->PrintTo(stream);
stream->Add(" ");
temp_slot()->PrintTo(stream);
stream->Add(")");
}
}
void LCallJSFunction::PrintDataTo(StringStream* stream) {
stream->Add("= ");
function()->PrintTo(stream);
......@@ -1251,7 +1265,15 @@ LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* function = UseFixed(instr->function(), a1);
LCallFunction* call = new(zone()) LCallFunction(context, function);
LOperand* slot = NULL;
LOperand* vector = NULL;
if (instr->HasVectorAndSlot()) {
slot = FixedTemp(a3);
vector = FixedTemp(a2);
}
LCallFunction* call =
new (zone()) LCallFunction(context, function, slot, vector);
return MarkAsCall(DefineFixed(call, v0), instr);
}
......
......@@ -1902,20 +1902,26 @@ class LInvokeFunction FINAL : public LTemplateInstruction<1, 2, 0> {
};
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> {
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 2> {
public:
LCallFunction(LOperand* context, LOperand* function) {
LCallFunction(LOperand* context, LOperand* function, LOperand* slot,
LOperand* vector) {
inputs_[0] = context;
inputs_[1] = function;
temps_[0] = slot;
temps_[1] = vector;
}
LOperand* context() { return inputs_[0]; }
LOperand* function() { return inputs_[1]; }
LOperand* temp_slot() { return temps_[0]; }
LOperand* temp_vector() { return temps_[1]; }
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
DECLARE_HYDROGEN_ACCESSOR(CallFunction)
int arity() const { return hydrogen()->argument_count() - 1; }
void PrintDataTo(StringStream* stream) OVERRIDE;
};
......
......@@ -4071,8 +4071,30 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
DCHECK(ToRegister(instr->result()).is(v0));
int arity = instr->arity();
CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
CallFunctionFlags flags = instr->hydrogen()->function_flags();
if (instr->hydrogen()->HasVectorAndSlot()) {
Register slot_register = ToRegister(instr->temp_slot());
Register vector_register = ToRegister(instr->temp_vector());
DCHECK(slot_register.is(a3));
DCHECK(vector_register.is(a2));
AllowDeferredHandleDereference vector_structure_check;
Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
int index = vector->GetIndex(instr->hydrogen()->slot());
__ li(vector_register, vector);
__ li(slot_register, Operand(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();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
} else {
CallFunctionStub stub(isolate(), arity, flags);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
}
......
......@@ -262,6 +262,20 @@ void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
}
void LCallFunction::PrintDataTo(StringStream* stream) {
context()->PrintTo(stream);
stream->Add(" ");
function()->PrintTo(stream);
if (hydrogen()->HasVectorAndSlot()) {
stream->Add(" (type-feedback-vector ");
temp_vector()->PrintTo(stream);
stream->Add(" ");
temp_slot()->PrintTo(stream);
stream->Add(")");
}
}
void LCallJSFunction::PrintDataTo(StringStream* stream) {
stream->Add("= ");
function()->PrintTo(stream);
......@@ -1251,7 +1265,15 @@ LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* function = UseFixed(instr->function(), a1);
LCallFunction* call = new(zone()) LCallFunction(context, function);
LOperand* slot = NULL;
LOperand* vector = NULL;
if (instr->HasVectorAndSlot()) {
slot = FixedTemp(a3);
vector = FixedTemp(a2);
}
LCallFunction* call =
new (zone()) LCallFunction(context, function, slot, vector);
return MarkAsCall(DefineFixed(call, v0), instr);
}
......
......@@ -1901,20 +1901,26 @@ class LInvokeFunction FINAL : public LTemplateInstruction<1, 2, 0> {
};
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> {
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 2> {
public:
LCallFunction(LOperand* context, LOperand* function) {
LCallFunction(LOperand* context, LOperand* function, LOperand* slot,
LOperand* vector) {
inputs_[0] = context;
inputs_[1] = function;
temps_[0] = slot;
temps_[1] = vector;
}
LOperand* context() { return inputs_[0]; }
LOperand* function() { return inputs_[1]; }
LOperand* temp_slot() { return temps_[0]; }
LOperand* temp_vector() { return temps_[1]; }
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
DECLARE_HYDROGEN_ACCESSOR(CallFunction)
int arity() const { return hydrogen()->argument_count() - 1; }
void PrintDataTo(StringStream* stream) OVERRIDE;
};
......
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