Commit 6949acab authored by epertoso's avatar epertoso Committed by Commit bot

[interpreter] Record type feedback in the handlers for Inc and Dec.

BUG=v8:5273
R=rmcilroy@chromium.org

Review-Url: https://codereview.chromium.org/2250513005
Cr-Commit-Position: refs/heads/master@{#38751}
parent 870763f5
......@@ -2382,7 +2382,9 @@ compiler::Node* BitwiseXorStub::Generate(CodeStubAssembler* assembler,
// static
compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
compiler::Node* value,
compiler::Node* context) {
compiler::Node* context,
compiler::Node* type_feedback_vector,
compiler::Node* slot_id) {
typedef CodeStubAssembler::Label Label;
typedef compiler::Node Node;
typedef CodeStubAssembler::Variable Variable;
......@@ -2394,8 +2396,12 @@ compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
// We might need to try again due to ToNumber conversion.
Variable value_var(assembler, MachineRepresentation::kTagged);
Variable result_var(assembler, MachineRepresentation::kTagged);
Label start(assembler, &value_var);
Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
Variable* loop_vars[] = {&value_var, &var_type_feedback};
Label start(assembler, 2, loop_vars);
value_var.Bind(value);
var_type_feedback.Bind(
assembler->Int32Constant(BinaryOperationFeedback::kNone));
assembler->Goto(&start);
assembler->Bind(&start);
{
......@@ -2416,6 +2422,9 @@ compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
assembler->Branch(overflow, &if_overflow, &if_notoverflow);
assembler->Bind(&if_notoverflow);
var_type_feedback.Bind(assembler->Word32Or(
var_type_feedback.value(),
assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)));
result_var.Bind(assembler->Projection(0, pair));
assembler->Goto(&end);
......@@ -2448,6 +2457,8 @@ compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
// Convert to a Number first and try again.
Callable callable =
CodeFactory::NonNumberToNumber(assembler->isolate());
var_type_feedback.Bind(
assembler->Int32Constant(BinaryOperationFeedback::kAny));
value_var.Bind(assembler->CallStub(callable, context, value));
assembler->Goto(&start);
}
......@@ -2459,18 +2470,25 @@ compiler::Node* IncStub::Generate(CodeStubAssembler* assembler,
Node* finc_value = var_finc_value.value();
Node* one = assembler->Float64Constant(1.0);
Node* finc_result = assembler->Float64Add(finc_value, one);
var_type_feedback.Bind(assembler->Word32Or(
var_type_feedback.value(),
assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
result_var.Bind(assembler->ChangeFloat64ToTagged(finc_result));
assembler->Goto(&end);
}
assembler->Bind(&end);
assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
slot_id);
return result_var.value();
}
// static
compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
compiler::Node* value,
compiler::Node* context) {
compiler::Node* context,
compiler::Node* type_feedback_vector,
compiler::Node* slot_id) {
typedef CodeStubAssembler::Label Label;
typedef compiler::Node Node;
typedef CodeStubAssembler::Variable Variable;
......@@ -2482,7 +2500,11 @@ compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
// We might need to try again due to ToNumber conversion.
Variable value_var(assembler, MachineRepresentation::kTagged);
Variable result_var(assembler, MachineRepresentation::kTagged);
Label start(assembler, &value_var);
Variable var_type_feedback(assembler, MachineRepresentation::kWord32);
Variable* loop_vars[] = {&value_var, &var_type_feedback};
Label start(assembler, 2, loop_vars);
var_type_feedback.Bind(
assembler->Int32Constant(BinaryOperationFeedback::kNone));
value_var.Bind(value);
assembler->Goto(&start);
assembler->Bind(&start);
......@@ -2504,6 +2526,9 @@ compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
assembler->Branch(overflow, &if_overflow, &if_notoverflow);
assembler->Bind(&if_notoverflow);
var_type_feedback.Bind(assembler->Word32Or(
var_type_feedback.value(),
assembler->Int32Constant(BinaryOperationFeedback::kSignedSmall)));
result_var.Bind(assembler->Projection(0, pair));
assembler->Goto(&end);
......@@ -2536,6 +2561,8 @@ compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
// Convert to a Number first and try again.
Callable callable =
CodeFactory::NonNumberToNumber(assembler->isolate());
var_type_feedback.Bind(
assembler->Int32Constant(BinaryOperationFeedback::kAny));
value_var.Bind(assembler->CallStub(callable, context, value));
assembler->Goto(&start);
}
......@@ -2547,11 +2574,16 @@ compiler::Node* DecStub::Generate(CodeStubAssembler* assembler,
Node* fdec_value = var_fdec_value.value();
Node* one = assembler->Float64Constant(1.0);
Node* fdec_result = assembler->Float64Sub(fdec_value, one);
var_type_feedback.Bind(assembler->Word32Or(
var_type_feedback.value(),
assembler->Int32Constant(BinaryOperationFeedback::kNumber)));
result_var.Bind(assembler->ChangeFloat64ToTagged(fdec_result));
assembler->Goto(&end);
}
assembler->Bind(&end);
assembler->UpdateFeedback(var_type_feedback.value(), type_feedback_vector,
slot_id);
return result_var.value();
}
......
......@@ -462,6 +462,19 @@ class CodeStub BASE_EMBEDDED {
} \
DEFINE_CODE_STUB(NAME, SUPER)
#define DEFINE_TURBOFAN_UNARY_OP_CODE_STUB_WITH_FEEDBACK(NAME, SUPER) \
public: \
static compiler::Node* Generate( \
CodeStubAssembler* assembler, compiler::Node* value, \
compiler::Node* context, compiler::Node* type_feedback_vector, \
compiler::Node* slot_id); \
void GenerateAssembly(CodeStubAssembler* assembler) const override { \
assembler->Return( \
Generate(assembler, assembler->Parameter(0), assembler->Parameter(1), \
assembler->Parameter(2), assembler->Parameter(3))); \
} \
DEFINE_CODE_STUB(NAME, SUPER)
#define DEFINE_HANDLER_CODE_STUB(NAME, SUPER) \
public: \
Handle<Code> GenerateCode() override; \
......@@ -895,7 +908,7 @@ class IncStub final : public TurboFanCodeStub {
explicit IncStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(CountOp);
DEFINE_TURBOFAN_UNARY_OP_CODE_STUB(Inc, TurboFanCodeStub);
DEFINE_TURBOFAN_UNARY_OP_CODE_STUB_WITH_FEEDBACK(Inc, TurboFanCodeStub);
};
class DecStub final : public TurboFanCodeStub {
......@@ -903,7 +916,7 @@ class DecStub final : public TurboFanCodeStub {
explicit DecStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(CountOp);
DEFINE_TURBOFAN_UNARY_OP_CODE_STUB(Dec, TurboFanCodeStub);
DEFINE_TURBOFAN_UNARY_OP_CODE_STUB_WITH_FEEDBACK(Dec, TurboFanCodeStub);
};
class InstanceOfStub final : public TurboFanCodeStub {
......
......@@ -1215,6 +1215,18 @@ BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHint() {
return hint;
}
BinaryOperationHint BytecodeGraphBuilder::GetBinaryOperationHintForIncDec() {
FeedbackVectorSlot slot =
feedback_vector()->ToSlot(bytecode_iterator().GetIndexOperand(0));
DCHECK_EQ(FeedbackVectorSlotKind::GENERAL, feedback_vector()->GetKind(slot));
Object* feedback = feedback_vector()->Get(slot);
BinaryOperationHint hint = BinaryOperationHint::kAny;
if (feedback->IsSmi()) {
hint = BinaryOperationHintFromFeedback((Smi::cast(feedback))->value());
}
return hint;
}
void BytecodeGraphBuilder::VisitAdd() {
BuildBinaryOp(javascript()->Add(GetBinaryOperationHint()));
}
......@@ -1302,15 +1314,17 @@ void BytecodeGraphBuilder::VisitInc() {
FrameStateBeforeAndAfter states(this);
// Note: Use subtract -1 here instead of add 1 to ensure we always convert to
// a number, not a string.
const Operator* js_op = javascript()->Subtract(BinaryOperationHint::kAny);
const Operator* js_op =
javascript()->Subtract(GetBinaryOperationHintForIncDec());
Node* node = NewNode(js_op, environment()->LookupAccumulator(),
jsgraph()->Constant(-1.0));
jsgraph()->Constant(-1));
environment()->BindAccumulator(node, &states);
}
void BytecodeGraphBuilder::VisitDec() {
FrameStateBeforeAndAfter states(this);
const Operator* js_op = javascript()->Subtract(BinaryOperationHint::kAny);
const Operator* js_op =
javascript()->Subtract(GetBinaryOperationHintForIncDec());
Node* node = NewNode(js_op, environment()->LookupAccumulator(),
jsgraph()->OneConstant());
environment()->BindAccumulator(node, &states);
......
......@@ -139,6 +139,10 @@ class BytecodeGraphBuilder {
// type feedback.
BinaryOperationHint GetBinaryOperationHint();
// Helper function to create an binary operation hint from the recorded
// type feedback in Inc/Dec handlers.
BinaryOperationHint GetBinaryOperationHintForIncDec();
// Control flow plumbing.
void BuildJump();
void BuildConditionalJump(Node* condition);
......
......@@ -1119,6 +1119,18 @@ void Interpreter::DoUnaryOp(InterpreterAssembler* assembler) {
__ Dispatch();
}
template <class Generator>
void Interpreter::DoUnaryOpWithFeedback(InterpreterAssembler* assembler) {
Node* value = __ GetAccumulator();
Node* context = __ GetContext();
Node* slot_index = __ BytecodeOperandIdx(0);
Node* type_feedback_vector = __ LoadTypeFeedbackVector();
Node* result = Generator::Generate(assembler, value, context,
type_feedback_vector, slot_index);
__ SetAccumulator(result);
__ Dispatch();
}
// ToName
//
// Cast the object referenced by the accumulator to a name.
......@@ -1150,14 +1162,14 @@ void Interpreter::DoToObject(InterpreterAssembler* assembler) {
//
// Increments value in the accumulator by one.
void Interpreter::DoInc(InterpreterAssembler* assembler) {
DoUnaryOp<IncStub>(assembler);
DoUnaryOpWithFeedback<IncStub>(assembler);
}
// Dec
//
// Decrements value in the accumulator by one.
void Interpreter::DoDec(InterpreterAssembler* assembler) {
DoUnaryOp<DecStub>(assembler);
DoUnaryOpWithFeedback<DecStub>(assembler);
}
// LogicalNot
......
......@@ -97,6 +97,11 @@ class Interpreter {
template <class Generator>
void DoUnaryOp(InterpreterAssembler* assembler);
// Generates code to perform the unary operation via |Generator| while
// gatering type feedback.
template <class Generator>
void DoUnaryOpWithFeedback(InterpreterAssembler* assembler);
// Generates code to perform the comparison operation associated with
// |compare_op|.
void DoCompareOp(Token::Value compare_op, InterpreterAssembler* assembler);
......
This diff is collapsed.
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