X87: Continue learning for calls in crankshaft.

port 7d363783e1.

original commit message:

  Continue learning for calls in crankshaft.

  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=
R=weiliang.lin@intel.com

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

Cr-Commit-Position: refs/heads/master@{#26506}
This commit is contained in:
cdai2 2015-02-09 13:18:28 +08:00
parent 6a66a78d70
commit f50a556bd0
3 changed files with 55 additions and 5 deletions

View File

@ -4364,8 +4364,30 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
DCHECK(ToRegister(instr->result()).is(eax));
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(edx));
DCHECK(vector_register.is(ebx));
AllowDeferredHandleDereference vector_structure_check;
Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
int index = vector->GetIndex(instr->hydrogen()->slot());
__ mov(vector_register, vector);
__ mov(slot_register, Immediate(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);
}
}

View File

@ -285,6 +285,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);
@ -1291,7 +1305,15 @@ LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
LOperand* context = UseFixed(instr->context(), esi);
LOperand* function = UseFixed(instr->function(), edi);
LCallFunction* call = new(zone()) LCallFunction(context, function);
LOperand* slot = NULL;
LOperand* vector = NULL;
if (instr->HasVectorAndSlot()) {
slot = FixedTemp(edx);
vector = FixedTemp(ebx);
}
LCallFunction* call =
new (zone()) LCallFunction(context, function, slot, vector);
return MarkAsCall(DefineFixed(call, eax), instr);
}

View File

@ -1957,19 +1957,25 @@ 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:
explicit 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)
void PrintDataTo(StringStream* stream) OVERRIDE;
int arity() const { return hydrogen()->argument_count() - 1; }
};