Commit a0e7456d authored by Jakob Gruber's avatar Jakob Gruber Committed by Commit Bot

[nci] Add Unary/Binary/Compare builtins with feedback

This CL adds the new _WithFeedback variant of unary, binary, and
compare operation builtins. Existing logic to do these operations is
refactored s.t. it can be used by both ignition bytecode handlers and
the new builtins.

Note that the new builtins are not yet used. Follow-up CLs will hook
them into generic lowering.

Bug: v8:8888
Change-Id: Id77dbe74bdf3b3806b2aefdf1abe52c3d165a3a3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2208862
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67956}
parent d4bb8208
......@@ -1683,6 +1683,8 @@ v8_source_set("v8_initializers") {
"src/ic/binary-op-assembler.h",
"src/ic/keyed-store-generic.cc",
"src/ic/keyed-store-generic.h",
"src/ic/unary-op-assembler.cc",
"src/ic/unary-op-assembler.h",
"src/interpreter/interpreter-assembler.cc",
"src/interpreter/interpreter-assembler.h",
"src/interpreter/interpreter-generator.cc",
......
......@@ -608,6 +608,34 @@ namespace internal {
TFC(SameValue, Compare) \
TFC(SameValueNumbersOnly, Compare) \
\
/* Binary ops with feedback collection */ \
TFC(Add_WithFeedback, BinaryOp_WithFeedback) \
TFC(Subtract_WithFeedback, BinaryOp_WithFeedback) \
TFC(Multiply_WithFeedback, BinaryOp_WithFeedback) \
TFC(Divide_WithFeedback, BinaryOp_WithFeedback) \
TFC(Modulus_WithFeedback, BinaryOp_WithFeedback) \
TFC(Exponentiate_WithFeedback, BinaryOp_WithFeedback) \
TFC(BitwiseAnd_WithFeedback, BinaryOp_WithFeedback) \
TFC(BitwiseOr_WithFeedback, BinaryOp_WithFeedback) \
TFC(BitwiseXor_WithFeedback, BinaryOp_WithFeedback) \
TFC(ShiftLeft_WithFeedback, BinaryOp_WithFeedback) \
TFC(ShiftRight_WithFeedback, BinaryOp_WithFeedback) \
TFC(ShiftRightLogical_WithFeedback, BinaryOp_WithFeedback) \
\
/* Compare ops with feedback collection */ \
TFC(Equal_WithFeedback, Compare_WithFeedback) \
TFC(StrictEqual_WithFeedback, Compare_WithFeedback) \
TFC(LessThan_WithFeedback, Compare_WithFeedback) \
TFC(GreaterThan_WithFeedback, Compare_WithFeedback) \
TFC(LessThanOrEqual_WithFeedback, Compare_WithFeedback) \
TFC(GreaterThanOrEqual_WithFeedback, Compare_WithFeedback) \
\
/* Unary ops with feedback collection */ \
TFC(BitwiseNot_WithFeedback, UnaryOp_WithFeedback) \
TFC(Decrement_WithFeedback, UnaryOp_WithFeedback) \
TFC(Increment_WithFeedback, UnaryOp_WithFeedback) \
TFC(Negate_WithFeedback, UnaryOp_WithFeedback) \
\
/* Object */ \
/* ES #sec-object-constructor */ \
TFJ(ObjectConstructor, kDontAdaptArgumentsSentinel) \
......
......@@ -6,6 +6,7 @@
#include "src/builtins/builtins.h"
#include "src/codegen/code-stub-assembler.h"
#include "src/ic/binary-op-assembler.h"
#include "src/ic/unary-op-assembler.h"
namespace v8 {
namespace internal {
......@@ -245,5 +246,109 @@ TF_BUILTIN(Add, AddStubAssembler) {
}
}
#define DEF_BINOP(Name, Generator) \
TF_BUILTIN(Name, CodeStubAssembler) { \
TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft)); \
TNode<Object> rhs = CAST(Parameter(Descriptor::kRight)); \
TNode<Context> context = CAST(Parameter(Descriptor::kContext)); \
TNode<HeapObject> maybe_feedback_vector = \
CAST(Parameter(Descriptor::kMaybeFeedbackVector)); \
TNode<UintPtrT> slot = \
UncheckedCast<UintPtrT>(Parameter(Descriptor::kSlot)); \
\
BinaryOpAssembler binop_asm(state()); \
TNode<Object> result = binop_asm.Generator(context, lhs, rhs, slot, \
maybe_feedback_vector, false); \
\
Return(result); \
}
DEF_BINOP(Add_WithFeedback, Generate_AddWithFeedback)
DEF_BINOP(Subtract_WithFeedback, Generate_SubtractWithFeedback)
DEF_BINOP(Multiply_WithFeedback, Generate_MultiplyWithFeedback)
DEF_BINOP(Divide_WithFeedback, Generate_DivideWithFeedback)
DEF_BINOP(Modulus_WithFeedback, Generate_ModulusWithFeedback)
DEF_BINOP(Exponentiate_WithFeedback, Generate_ExponentiateWithFeedback)
DEF_BINOP(BitwiseOr_WithFeedback, Generate_BitwiseOrWithFeedback)
DEF_BINOP(BitwiseXor_WithFeedback, Generate_BitwiseXorWithFeedback)
DEF_BINOP(BitwiseAnd_WithFeedback, Generate_BitwiseAndWithFeedback)
DEF_BINOP(ShiftLeft_WithFeedback, Generate_ShiftLeftWithFeedback)
DEF_BINOP(ShiftRight_WithFeedback, Generate_ShiftRightWithFeedback)
DEF_BINOP(ShiftRightLogical_WithFeedback,
Generate_ShiftRightLogicalWithFeedback)
#undef DEF_BINOP
#define DEF_UNOP(Name, Generator) \
TF_BUILTIN(Name, CodeStubAssembler) { \
TNode<Object> value = CAST(Parameter(Descriptor::kValue)); \
TNode<Context> context = CAST(Parameter(Descriptor::kContext)); \
TNode<HeapObject> maybe_feedback_vector = \
CAST(Parameter(Descriptor::kMaybeFeedbackVector)); \
TNode<UintPtrT> slot = \
UncheckedCast<UintPtrT>(Parameter(Descriptor::kSlot)); \
\
UnaryOpAssembler a(state()); \
TNode<Object> result = \
a.Generator(context, value, slot, maybe_feedback_vector); \
\
Return(result); \
}
DEF_UNOP(BitwiseNot_WithFeedback, Generate_BitwiseNotWithFeedback)
DEF_UNOP(Decrement_WithFeedback, Generate_DecrementWithFeedback)
DEF_UNOP(Increment_WithFeedback, Generate_IncrementWithFeedback)
DEF_UNOP(Negate_WithFeedback, Generate_NegateWithFeedback)
#undef DEF_UNOP
#define DEF_COMPARE(Name) \
TF_BUILTIN(Name##_WithFeedback, CodeStubAssembler) { \
TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft)); \
TNode<Object> rhs = CAST(Parameter(Descriptor::kRight)); \
TNode<Context> context = CAST(Parameter(Descriptor::kContext)); \
TNode<HeapObject> maybe_feedback_vector = \
CAST(Parameter(Descriptor::kMaybeFeedbackVector)); \
TNode<UintPtrT> slot = \
UncheckedCast<UintPtrT>(Parameter(Descriptor::kSlot)); \
\
TVARIABLE(Smi, var_type_feedback); \
TNode<Oddball> result = RelationalComparison(Operation::k##Name, lhs, rhs, \
context, &var_type_feedback); \
UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot); \
\
Return(result); \
}
DEF_COMPARE(LessThan)
DEF_COMPARE(LessThanOrEqual)
DEF_COMPARE(GreaterThan)
DEF_COMPARE(GreaterThanOrEqual)
#undef DEF_COMPARE
TF_BUILTIN(Equal_WithFeedback, CodeStubAssembler) {
TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft));
TNode<Object> rhs = CAST(Parameter(Descriptor::kRight));
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<HeapObject> maybe_feedback_vector =
CAST(Parameter(Descriptor::kMaybeFeedbackVector));
TNode<UintPtrT> slot = UncheckedCast<UintPtrT>(Parameter(Descriptor::kSlot));
TVARIABLE(Smi, var_type_feedback);
TNode<Oddball> result = Equal(lhs, rhs, context, &var_type_feedback);
UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot);
Return(result);
}
TF_BUILTIN(StrictEqual_WithFeedback, CodeStubAssembler) {
TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft));
TNode<Object> rhs = CAST(Parameter(Descriptor::kRight));
TNode<HeapObject> maybe_feedback_vector =
CAST(Parameter(Descriptor::kMaybeFeedbackVector));
TNode<UintPtrT> slot = UncheckedCast<UintPtrT>(Parameter(Descriptor::kSlot));
TVARIABLE(Smi, var_type_feedback);
TNode<Oddball> result = StrictEqual(lhs, rhs, &var_type_feedback);
UpdateFeedback(var_type_feedback.value(), maybe_feedback_vector, slot);
Return(result);
}
} // namespace internal
} // namespace v8
......@@ -946,6 +946,7 @@ class CallWithSpreadDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(CallWithSpreadDescriptor, CallInterfaceDescriptor)
};
// TODO(jgruber): Pass the slot as UintPtr.
class CallWithSpread_WithFeedbackDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kTarget, kArgumentsCount, kSpread, kSlot,
......@@ -967,6 +968,7 @@ class CallWithArrayLikeDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(CallWithArrayLikeDescriptor, CallInterfaceDescriptor)
};
// TODO(jgruber): Pass the slot as UintPtr.
class CallWithArrayLike_WithFeedbackDescriptor
: public CallInterfaceDescriptor {
public:
......@@ -1002,6 +1004,7 @@ class ConstructWithSpreadDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(ConstructWithSpreadDescriptor, CallInterfaceDescriptor)
};
// TODO(jgruber): Pass the slot as UintPtr.
class ConstructWithSpread_WithFeedbackDescriptor
: public CallInterfaceDescriptor {
public:
......@@ -1024,6 +1027,7 @@ class ConstructWithArrayLikeDescriptor : public CallInterfaceDescriptor {
DECLARE_DESCRIPTOR(ConstructWithArrayLikeDescriptor, CallInterfaceDescriptor)
};
// TODO(jgruber): Pass the slot as UintPtr.
class ConstructWithArrayLike_WithFeedbackDescriptor
: public CallInterfaceDescriptor {
public:
......@@ -1465,11 +1469,12 @@ class BinaryOp_WithFeedbackDescriptor : public CallInterfaceDescriptor {
DEFINE_PARAMETERS(kLeft, kRight, kSlot, kMaybeFeedbackVector)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kLeft
MachineType::AnyTagged(), // kRight
MachineType::Int32(), // kSlot
MachineType::UintPtr(), // kSlot
MachineType::AnyTagged()) // kMaybeFeedbackVector
DECLARE_DESCRIPTOR(BinaryOp_WithFeedbackDescriptor, CallInterfaceDescriptor)
};
// TODO(jgruber): Pass the slot as UintPtr.
class CallTrampoline_WithFeedbackDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_VARARGS(kFunction, kActualArgumentsCount, kSlot,
......@@ -1487,11 +1492,12 @@ class Compare_WithFeedbackDescriptor : public CallInterfaceDescriptor {
DEFINE_PARAMETERS(kLeft, kRight, kSlot, kMaybeFeedbackVector)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kLeft
MachineType::AnyTagged(), // kRight
MachineType::Int32(), // kSlot
MachineType::UintPtr(), // kSlot
MachineType::AnyTagged()) // kMaybeFeedbackVector
DECLARE_DESCRIPTOR(Compare_WithFeedbackDescriptor, CallInterfaceDescriptor)
};
// TODO(jgruber): Pass the slot as UintPtr.
class Construct_WithFeedbackDescriptor : public CallInterfaceDescriptor {
public:
// kSlot is passed in a register, kMaybeFeedbackVector on the stack.
......@@ -1506,7 +1512,7 @@ class UnaryOp_WithFeedbackDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kValue, kSlot, kMaybeFeedbackVector)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue
MachineType::Int32(), // kSlot
MachineType::UintPtr(), // kSlot
MachineType::AnyTagged()) // kMaybeFeedbackVector
DECLARE_DESCRIPTOR(UnaryOp_WithFeedbackDescriptor, CallInterfaceDescriptor)
};
......
......@@ -50,6 +50,72 @@ class BinaryOpAssembler : public CodeStubAssembler {
TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector,
bool rhs_known_smi);
TNode<Object> Generate_BitwiseOrWithFeedback(
TNode<Context> context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector,
bool /* unused */) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kBitwiseOr, left, right, context, &feedback);
UpdateFeedback(feedback.value(), maybe_feedback_vector, slot);
return result;
}
TNode<Object> Generate_BitwiseXorWithFeedback(
TNode<Context> context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector,
bool /* unused */) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kBitwiseXor, left, right, context, &feedback);
UpdateFeedback(feedback.value(), maybe_feedback_vector, slot);
return result;
}
TNode<Object> Generate_BitwiseAndWithFeedback(
TNode<Context> context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector,
bool /* unused */) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kBitwiseAnd, left, right, context, &feedback);
UpdateFeedback(feedback.value(), maybe_feedback_vector, slot);
return result;
}
TNode<Object> Generate_ShiftLeftWithFeedback(
TNode<Context> context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector,
bool /* unused */) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kShiftLeft, left, right, context, &feedback);
UpdateFeedback(feedback.value(), maybe_feedback_vector, slot);
return result;
}
TNode<Object> Generate_ShiftRightWithFeedback(
TNode<Context> context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector,
bool /* unused */) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kShiftRight, left, right, context, &feedback);
UpdateFeedback(feedback.value(), maybe_feedback_vector, slot);
return result;
}
TNode<Object> Generate_ShiftRightLogicalWithFeedback(
TNode<Context> context, TNode<Object> left, TNode<Object> right,
TNode<UintPtrT> slot, TNode<HeapObject> maybe_feedback_vector,
bool /* unused */) {
TVARIABLE(Smi, feedback);
TNode<Object> result = Generate_BitwiseBinaryOpWithFeedback(
Operation::kShiftRightLogical, left, right, context, &feedback);
UpdateFeedback(feedback.value(), maybe_feedback_vector, slot);
return result;
}
TNode<Object> Generate_BitwiseBinaryOpWithFeedback(Operation bitwise_op,
TNode<Object> left,
TNode<Object> right,
......
This diff is collapsed.
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_IC_UNARY_OP_ASSEMBLER_H_
#define V8_IC_UNARY_OP_ASSEMBLER_H_
#include "src/codegen/code-stub-assembler.h"
namespace v8 {
namespace internal {
namespace compiler {
class CodeAssemblerState;
}
class UnaryOpAssembler final {
public:
explicit UnaryOpAssembler(compiler::CodeAssemblerState* state)
: state_(state) {}
TNode<Object> Generate_BitwiseNotWithFeedback(
TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
TNode<HeapObject> maybe_feedback_vector);
TNode<Object> Generate_DecrementWithFeedback(
TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
TNode<HeapObject> maybe_feedback_vector);
TNode<Object> Generate_IncrementWithFeedback(
TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
TNode<HeapObject> maybe_feedback_vector);
TNode<Object> Generate_NegateWithFeedback(
TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
TNode<HeapObject> maybe_feedback_vector);
private:
compiler::CodeAssemblerState* const state_;
};
} // namespace internal
} // namespace v8
#endif // V8_IC_UNARY_OP_ASSEMBLER_H_
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