Revert of Continue learning for calls in optimized code when we have no type feedback. (patchset #4 id:60001 of https://codereview.chromium.org/868453005/)

Reason for revert:
Serializer tests broke. Need to debug and fix.

Original issue's description:
> Continue learning for calls in optimized code when we have no type feedback.
>
> Based on CL https://codereview.chromium.org/871063002/ which needs to land first.
>
> BUG=
>
> Committed: https://crrev.com/f5f2692b5ff70ac3cd06a903b7846174b97a2e55
> Cr-Commit-Position: refs/heads/master@{#26292}

TBR=verwaest@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=

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

Cr-Commit-Position: refs/heads/master@{#26293}
This commit is contained in:
mvstanton 2015-01-27 05:06:57 -08:00 committed by Commit bot
parent f5f2692b5f
commit f605f1c223
17 changed files with 33 additions and 291 deletions

View File

@ -255,20 +255,6 @@ 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);
@ -1257,15 +1243,7 @@ LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* function = UseFixed(instr->function(), r1);
LOperand* slot = NULL;
LOperand* vector = NULL;
if (instr->HasVectorAndSlot()) {
slot = FixedTemp(r3);
vector = FixedTemp(r2);
}
LCallFunction* call =
new (zone()) LCallFunction(context, function, slot, vector);
LCallFunction* call = new(zone()) LCallFunction(context, function);
return MarkAsCall(DefineFixed(call, r0), instr);
}

View File

@ -1939,26 +1939,20 @@ class LInvokeFunction FINAL : public LTemplateInstruction<1, 2, 0> {
};
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 2> {
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LCallFunction(LOperand* context, LOperand* function, LOperand* slot,
LOperand* vector) {
LCallFunction(LOperand* context, LOperand* function) {
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;
};

View File

@ -4109,30 +4109,9 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
DCHECK(ToRegister(instr->result()).is(r0));
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());
DCHECK(slot_register.is(r3));
DCHECK(vector_register.is(r2));
Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
int index = vector->GetIndex(instr->hydrogen()->slot());
__ Move(vector_register, vector);
__ mov(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);
CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
}
void LCodeGen::DoCallNew(LCallNew* instr) {

View File

@ -142,20 +142,6 @@ 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 LInvokeFunction::PrintDataTo(StringStream* stream) {
stream->Add("= ");
function()->PrintTo(stream);
@ -1067,15 +1053,7 @@ LInstruction* LChunkBuilder::DoCallWithDescriptor(
LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
LOperand* context = UseFixed(instr->context(), cp);
LOperand* function = UseFixed(instr->function(), x1);
LOperand* slot = NULL;
LOperand* vector = NULL;
if (instr->HasVectorAndSlot()) {
slot = FixedTemp(x3);
vector = FixedTemp(x2);
}
LCallFunction* call =
new (zone()) LCallFunction(context, function, slot, vector);
LCallFunction* call = new(zone()) LCallFunction(context, function);
return MarkAsCall(DefineFixed(call, x0), instr);
}

View File

@ -847,26 +847,20 @@ class LCallJSFunction FINAL : public LTemplateInstruction<1, 1, 0> {
};
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 2> {
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LCallFunction(LOperand* context, LOperand* function, LOperand* slot,
LOperand* vector) {
LCallFunction(LOperand* context, LOperand* function) {
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;
};

View File

@ -410,29 +410,8 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
DCHECK(ToRegister(instr->result()).Is(x0));
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());
DCHECK(slot_register.is(x3));
DCHECK(vector_register.is(x2));
Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
int index = vector->GetIndex(instr->hydrogen()->slot());
__ Mov(vector_register, vector);
__ Mov(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);
CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
after_push_argument_ = false;
}

View File

@ -968,15 +968,6 @@ std::ostream& HBinaryCall::PrintDataTo(std::ostream& os) const { // NOLINT
}
std::ostream& HCallFunction::PrintDataTo(std::ostream& os) const { // NOLINT
os << NameOf(context()) << " " << NameOf(function());
if (HasVectorAndSlot()) {
os << " (type-feedback-vector icslot " << slot().ToInt() << ")";
}
return os;
}
void HBoundsCheck::ApplyIndexChange() {
if (skip_check()) return;

View File

@ -2434,36 +2434,22 @@ class HCallFunction FINAL : public HBinaryCall {
DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P3(
HCallFunction, HValue*, int, CallFunctionFlags);
HValue* context() const { return first(); }
HValue* function() const { return second(); }
HValue* context() { return first(); }
HValue* function() { return second(); }
CallFunctionFlags function_flags() const { return function_flags_; }
FeedbackVectorICSlot slot() const { return slot_; }
Handle<TypeFeedbackVector> feedback_vector() const {
return feedback_vector_;
}
bool HasVectorAndSlot() const { return !feedback_vector_.is_null(); }
void SetVectorAndSlot(Handle<TypeFeedbackVector> vector,
FeedbackVectorICSlot slot) {
feedback_vector_ = vector;
slot_ = slot;
}
DECLARE_CONCRETE_INSTRUCTION(CallFunction)
std::ostream& PrintDataTo(std::ostream& os) const OVERRIDE; // NOLINT
int argument_delta() const OVERRIDE { return -argument_count(); }
private:
HCallFunction(HValue* context, HValue* function, int argument_count,
HCallFunction(HValue* context,
HValue* function,
int argument_count,
CallFunctionFlags flags = NO_CALL_FUNCTION_FLAGS)
: HBinaryCall(context, function, argument_count),
function_flags_(flags),
slot_(FeedbackVectorICSlot::Invalid()) {}
: HBinaryCall(context, function, argument_count), function_flags_(flags) {
}
CallFunctionFlags function_flags_;
Handle<TypeFeedbackVector> feedback_vector_;
FeedbackVectorICSlot slot_;
};

View File

@ -9348,19 +9348,7 @@ void HOptimizedGraphBuilder::VisitCall(Call* expr) {
Push(graph()->GetConstantUndefined());
CHECK_ALIVE(VisitExpressions(expr->arguments()));
PushArgumentsFromEnvironment(argument_count);
HCallFunction* call_function =
New<HCallFunction>(function, argument_count);
call = call_function;
if (expr->is_uninitialized() && expr->HasCallFeedbackSlot()) {
// We've never seen this call before, so let's have Crankshaft learn
// through the type vector.
Handle<SharedFunctionInfo> current_shared =
function_state()->compilation_info()->shared_info();
Handle<TypeFeedbackVector> vector =
handle(current_shared->feedback_vector(), isolate());
FeedbackVectorICSlot slot = expr->CallFeedbackSlot();
call_function->SetVectorAndSlot(vector, slot);
}
call = New<HCallFunction>(function, argument_count);
}
}

View File

@ -3964,30 +3964,9 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
DCHECK(ToRegister(instr->result()).is(eax));
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());
DCHECK(slot_register.is(edx));
DCHECK(vector_register.is(ebx));
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);
CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
}
void LCodeGen::DoCallNew(LCallNew* instr) {

View File

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

View File

@ -1949,25 +1949,19 @@ class LInvokeFunction FINAL : public LTemplateInstruction<1, 2, 0> {
};
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 2> {
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LCallFunction(LOperand* context, LOperand* function, LOperand* slot,
LOperand* vector) {
explicit LCallFunction(LOperand* context, LOperand* function) {
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; }
};

View File

@ -223,17 +223,6 @@ Code* IC::GetOriginalCode() const {
}
bool IC::AddressIsOptimizedCode() const {
Object* maybe_function =
Memory::Object_at(fp() + JavaScriptFrameConstants::kFunctionOffset);
if (maybe_function->IsJSFunction()) {
JSFunction* function = JSFunction::cast(maybe_function);
return function->IsOptimized();
}
return false;
}
static void LookupForRead(LookupIterator* it) {
for (; it->IsFound(); it->Next()) {
switch (it->state()) {
@ -2155,16 +2144,8 @@ bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
CallICNexus* nexus = casted_nexus<CallICNexus>();
nexus->ConfigureMonomorphicArray();
// Vector-based ICs have a different calling convention in optimized code
// than full code so the correct stub has to be chosen.
if (AddressIsOptimizedCode()) {
CallIC_ArrayStub stub(isolate(), callic_state);
set_target(*stub.GetCode());
} else {
CallIC_ArrayTrampolineStub stub(isolate(), callic_state);
set_target(*stub.GetCode());
}
Handle<String> name;
if (array_function->shared()->name()->IsString()) {
name = Handle<String>(String::cast(array_function->shared()->name()),
@ -2186,15 +2167,9 @@ void CallIC::PatchMegamorphic(Handle<Object> function) {
CallICNexus* nexus = casted_nexus<CallICNexus>();
nexus->ConfigureGeneric();
// Vector-based ICs have a different calling convention in optimized code
// than full code so the correct stub has to be chosen.
if (AddressIsOptimizedCode()) {
CallICStub stub(isolate(), callic_state);
set_target(*stub.GetCode());
} else {
CallICTrampolineStub stub(isolate(), callic_state);
set_target(*stub.GetCode());
}
Handle<Code> code = stub.GetCode();
set_target(*code);
Handle<Object> name = isolate()->factory()->empty_string();
if (function->IsJSFunction()) {

View File

@ -146,8 +146,6 @@ class IC {
// Get the original (non-breakpointed) code object of the caller.
Code* GetOriginalCode() const;
bool AddressIsOptimizedCode() const;
// Set the call-site target.
inline void set_target(Code* code);
bool is_target_set() { return target_set_; }

View File

@ -4033,30 +4033,9 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
DCHECK(ToRegister(instr->result()).is(rax));
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());
DCHECK(slot_register.is(rdx));
DCHECK(vector_register.is(rbx));
Handle<TypeFeedbackVector> vector = instr->hydrogen()->feedback_vector();
int index = vector->GetIndex(instr->hydrogen()->slot());
__ Move(vector_register, vector);
__ Move(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();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
} else {
CallFunctionStub stub(isolate(), arity, flags);
CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
}
void LCodeGen::DoCallNew(LCallNew* instr) {

View File

@ -268,20 +268,6 @@ 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);
@ -1274,14 +1260,7 @@ LInstruction* LChunkBuilder::DoCallNewArray(HCallNewArray* instr) {
LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
LOperand* context = UseFixed(instr->context(), rsi);
LOperand* function = UseFixed(instr->function(), rdi);
LOperand* slot = NULL;
LOperand* vector = NULL;
if (instr->HasVectorAndSlot()) {
slot = FixedTemp(rdx);
vector = FixedTemp(rbx);
}
LCallFunction* call =
new (zone()) LCallFunction(context, function, slot, vector);
LCallFunction* call = new(zone()) LCallFunction(context, function);
return MarkAsCall(DefineFixed(call, rax), instr);
}

View File

@ -1928,14 +1928,11 @@ class LInvokeFunction FINAL : public LTemplateInstruction<1, 2, 0> {
};
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 2> {
class LCallFunction FINAL : public LTemplateInstruction<1, 2, 0> {
public:
LCallFunction(LOperand* context, LOperand* function, LOperand* slot,
LOperand* vector) {
LCallFunction(LOperand* context, LOperand* function) {
inputs_[0] = context;
inputs_[1] = function;
temps_[0] = slot;
temps_[1] = vector;
}
DECLARE_CONCRETE_INSTRUCTION(CallFunction, "call-function")
@ -1943,11 +1940,7 @@ class LCallFunction FINAL : public LTemplateInstruction<1, 2, 2> {
LOperand* context() { return inputs_[0]; }
LOperand* function() { return inputs_[1]; }
LOperand* temp_slot() { return temps_[0]; }
LOperand* temp_vector() { return temps_[1]; }
int arity() const { return hydrogen()->argument_count() - 1; }
void PrintDataTo(StringStream* stream) OVERRIDE;
};