}
-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);
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);
}
};
-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;
};
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);
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
- }
+ CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
}
-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);
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);
}
};
-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;
};
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);
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
- }
+ CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
after_push_argument_ = false;
}
}
-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;
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_;
};
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);
}
}
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);
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
- }
+ CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
}
-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);
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);
}
};
-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; }
};
}
-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()) {
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());
- }
-
+ 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()),
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());
- }
+ CallICTrampolineStub stub(isolate(), callic_state);
+ Handle<Code> code = stub.GetCode();
+ set_target(*code);
Handle<Object> name = isolate()->factory()->empty_string();
if (function->IsJSFunction()) {
// 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_; }
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);
- CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
- }
+ CallFunctionStub stub(isolate(), arity, instr->hydrogen()->function_flags());
+ CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
}
}
-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);
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);
}
};
-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")
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;
};