Remove the obsolete OverwriteMode optimization.

R=jkummerow@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#26454}
This commit is contained in:
Benedikt Meurer 2015-02-05 11:38:41 +01:00
parent bfe7f4af14
commit 634b0f20f4
19 changed files with 160 additions and 379 deletions

View File

@ -2041,19 +2041,15 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ push(r0); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
? OVERWRITE_RIGHT
: NO_OVERWRITE;
SetSourcePosition(expr->position() + 1);
AccumulatorValueContext context(this);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
op,
mode,
expr->target(),
expr->value());
} else {
EmitBinaryOp(expr->binary_operation(), op, mode);
EmitBinaryOp(expr->binary_operation(), op);
}
// Deoptimization point in case the binary operation may have side effects.
@ -2444,7 +2440,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode,
Expression* left_expr,
Expression* right_expr) {
Label done, smi_case, stub_call;
@ -2464,7 +2459,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done);
@ -2596,11 +2591,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ pop(r1);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
@ -4846,8 +4839,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Record position before stub call.
SetSourcePosition(expr->position());
Handle<Code> code =
CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);

View File

@ -2184,8 +2184,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
DCHECK(ToRegister(instr->right()).is(r0));
DCHECK(ToRegister(instr->result()).is(r0));
Handle<Code> code =
CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), instr->op()).code();
// Block literal pool emission to ensure nop indicating no inlined smi code
// is in the correct position.
Assembler::BlockConstPoolScope block_const_pool(masm());

View File

@ -2018,19 +2018,15 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ Push(x0); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
? OVERWRITE_RIGHT
: NO_OVERWRITE;
SetSourcePosition(expr->position() + 1);
AccumulatorValueContext context(this);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
op,
mode,
expr->target(),
expr->value());
} else {
EmitBinaryOp(expr->binary_operation(), op, mode);
EmitBinaryOp(expr->binary_operation(), op);
}
// Deoptimization point in case the binary operation may have side effects.
@ -2120,7 +2116,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode,
Expression* left_expr,
Expression* right_expr) {
Label done, both_smis, stub_call;
@ -2138,7 +2133,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ Bind(&stub_call);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
{
Assembler::BlockPoolsScope scope(masm_);
CallIC(code, expr->BinaryOperationFeedbackId());
@ -2218,11 +2213,9 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ Pop(x1);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code.
{
Assembler::BlockPoolsScope scope(masm_);
@ -4530,8 +4523,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
{
Assembler::BlockPoolsScope scope(masm_);
Handle<Code> code =
CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
}

View File

@ -1803,8 +1803,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
DCHECK(ToRegister(instr->right()).is(x0));
DCHECK(ToRegister(instr->result()).is(x0));
Handle<Code> code =
CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), instr->op()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
}

View File

@ -456,31 +456,6 @@ void BinaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
}
bool BinaryOperation::ResultOverwriteAllowed() const {
switch (op()) {
case Token::COMMA:
case Token::OR:
case Token::AND:
return false;
case Token::BIT_OR:
case Token::BIT_XOR:
case Token::BIT_AND:
case Token::SHL:
case Token::SAR:
case Token::SHR:
case Token::ADD:
case Token::SUB:
case Token::MUL:
case Token::DIV:
case Token::MOD:
return true;
default:
UNREACHABLE();
}
return false;
}
static bool IsTypeof(Expression* expr) {
UnaryOperation* maybe_unary = expr->AsUnaryOperation();
return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF;

View File

@ -337,10 +337,6 @@ class Expression : public AstNode {
// names because [] for string objects is handled only by keyed ICs.
virtual bool IsPropertyName() const { return false; }
// True iff the result can be safely overwritten (to avoid allocation).
// False for operations that can return one of their operands.
virtual bool ResultOverwriteAllowed() const { return false; }
// True iff the expression is a literal represented as a smi.
bool IsSmiLiteral() const;
@ -2078,8 +2074,6 @@ class BinaryOperation FINAL : public Expression {
public:
DECLARE_NODE_TYPE(BinaryOperation)
bool ResultOverwriteAllowed() const OVERRIDE;
Token::Value op() const { return static_cast<Token::Value>(op_); }
Expression* left() const { return left_; }
Expression* right() const { return right_; }

View File

@ -90,9 +90,8 @@ Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op) {
// static
Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op,
OverwriteMode mode) {
BinaryOpICStub stub(isolate, op, mode);
Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op) {
BinaryOpICStub stub(isolate, op);
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}

View File

@ -45,8 +45,7 @@ class CodeFactory FINAL {
static Callable CompareIC(Isolate* isolate, Token::Value op);
static Callable BinaryOpIC(Isolate* isolate, Token::Value op,
OverwriteMode mode = NO_OVERWRITE);
static Callable BinaryOpIC(Isolate* isolate, Token::Value op);
// Code stubs. Add methods here as needed to reduce dependency on
// code-stubs.h.

View File

@ -1230,21 +1230,6 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
result = EnforceNumberType(result, result_type);
}
// Reuse the double box of one of the operands if we are allowed to (i.e.
// chained binops).
if (state.CanReuseDoubleBox()) {
HValue* operand = (state.mode() == OVERWRITE_LEFT) ? left : right;
IfBuilder if_heap_number(this);
if_heap_number.If<HHasInstanceTypeAndBranch>(operand, HEAP_NUMBER_TYPE);
if_heap_number.Then();
Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result);
Push(operand);
if_heap_number.Else();
Push(result);
if_heap_number.End();
result = Pop();
}
return result;
}

View File

@ -268,12 +268,8 @@ MaybeHandle<Code> CodeStub::GetCode(Isolate* isolate, uint32_t key) {
void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
// Generate the uninitialized versions of the stub.
for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
for (int mode = NO_OVERWRITE; mode <= OVERWRITE_RIGHT; ++mode) {
BinaryOpICStub stub(isolate,
static_cast<Token::Value>(op),
static_cast<OverwriteMode>(mode));
stub.GetCode();
}
BinaryOpICStub stub(isolate, static_cast<Token::Value>(op));
stub.GetCode();
}
// Generate special versions of the stub.

View File

@ -1229,10 +1229,9 @@ class CallApiGetterStub : public PlatformCodeStub {
class BinaryOpICStub : public HydrogenCodeStub {
public:
BinaryOpICStub(Isolate* isolate, Token::Value op,
OverwriteMode mode = NO_OVERWRITE)
BinaryOpICStub(Isolate* isolate, Token::Value op)
: HydrogenCodeStub(isolate, UNINITIALIZED) {
BinaryOpICState state(isolate, op, mode);
BinaryOpICState state(isolate, op);
set_sub_minor_key(state.GetExtraICState());
}
@ -1313,10 +1312,8 @@ class BinaryOpICWithAllocationSiteStub FINAL : public PlatformCodeStub {
class BinaryOpWithAllocationSiteStub FINAL : public BinaryOpICStub {
public:
BinaryOpWithAllocationSiteStub(Isolate* isolate,
Token::Value op,
OverwriteMode mode)
: BinaryOpICStub(isolate, op, mode) {}
BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op)
: BinaryOpICStub(isolate, op) {}
BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
: BinaryOpICStub(isolate, state) {}

View File

@ -1052,19 +1052,15 @@ void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
Comment cmnt(masm_, "[ ArithmeticExpression");
Expression* left = expr->left();
Expression* right = expr->right();
OverwriteMode mode =
left->ResultOverwriteAllowed()
? OVERWRITE_LEFT
: (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE);
VisitForStackValue(left);
VisitForAccumulatorValue(right);
SetSourcePosition(expr->position());
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr, op, mode, left, right);
EmitInlineSmiBinaryOp(expr, op, left, right);
} else {
EmitBinaryOp(expr, op, mode);
EmitBinaryOp(expr, op);
}
}

View File

@ -584,15 +584,12 @@ class FullCodeGenerator: public AstVisitor {
// Apply the compound assignment operator. Expects the left operand on top
// of the stack and the right one in the accumulator.
void EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode);
void EmitBinaryOp(BinaryOperation* expr, Token::Value op);
// Helper functions for generating inlined smi code for certain
// binary operations.
void EmitInlineSmiBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode,
Expression* left,
Expression* right);

View File

@ -1964,18 +1964,14 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ push(eax); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
? OVERWRITE_RIGHT
: NO_OVERWRITE;
SetSourcePosition(expr->position() + 1);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
op,
mode,
expr->target(),
expr->value());
} else {
EmitBinaryOp(expr->binary_operation(), op, mode);
EmitBinaryOp(expr->binary_operation(), op);
}
// Deoptimization point in case the binary operation may have side effects.
@ -2356,7 +2352,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode,
Expression* left,
Expression* right) {
// Do combined smi check of the operands. Left operand is on the
@ -2370,7 +2365,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
__ mov(eax, ecx);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
@ -2502,11 +2497,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ pop(edx);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
@ -4778,8 +4771,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ bind(&stub_call);
__ mov(edx, eax);
__ mov(eax, Immediate(Smi::FromInt(1)));
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
NO_OVERWRITE).code();
Handle<Code> code =
CodeFactory::BinaryOpIC(isolate(), expr->binary_op()).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);

View File

@ -2049,8 +2049,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
DCHECK(ToRegister(instr->right()).is(eax));
DCHECK(ToRegister(instr->result()).is(eax));
Handle<Code> code =
CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), instr->op()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
}

View File

@ -48,7 +48,6 @@ BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state)
: isolate_(isolate) {
op_ =
static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
mode_ = OverwriteModeField::decode(extra_ic_state);
fixed_right_arg_ =
Maybe<int>(HasFixedRightArgField::decode(extra_ic_state),
1 << FixedRightArgValueField::decode(extra_ic_state));
@ -66,8 +65,7 @@ BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state)
ExtraICState BinaryOpICState::GetExtraICState() const {
ExtraICState extra_ic_state =
OpField::encode(op_ - FIRST_TOKEN) | OverwriteModeField::encode(mode_) |
LeftKindField::encode(left_kind_) |
OpField::encode(op_ - FIRST_TOKEN) | LeftKindField::encode(left_kind_) |
ResultKindField::encode(result_kind_) |
HasFixedRightArgField::encode(fixed_right_arg_.has_value);
if (fixed_right_arg_.has_value) {
@ -87,218 +85,124 @@ void BinaryOpICState::GenerateAheadOfTime(
// expensive at runtime. When solved we should be able to add most binops to
// the snapshot instead of hand-picking them.
// Generated list of commonly used stubs
#define GENERATE(op, left_kind, right_kind, result_kind, mode) \
do { \
BinaryOpICState state(isolate, op, mode); \
state.left_kind_ = left_kind; \
state.fixed_right_arg_.has_value = false; \
state.right_kind_ = right_kind; \
state.result_kind_ = result_kind; \
Generate(isolate, state); \
#define GENERATE(op, left_kind, right_kind, result_kind) \
do { \
BinaryOpICState state(isolate, op); \
state.left_kind_ = left_kind; \
state.fixed_right_arg_.has_value = false; \
state.right_kind_ = right_kind; \
state.result_kind_ = result_kind; \
Generate(isolate, state); \
} while (false)
GENERATE(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT);
GENERATE(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT);
GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE);
GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT);
GENERATE(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT);
GENERATE(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT);
GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT);
GENERATE(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT);
GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT);
GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT);
GENERATE(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT);
GENERATE(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT);
GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT);
GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT);
GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT);
GENERATE(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT);
GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT);
GENERATE(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT);
GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT);
GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT);
GENERATE(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT);
GENERATE(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE);
GENERATE(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE);
GENERATE(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE);
GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT);
GENERATE(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE);
GENERATE(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE);
GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT);
GENERATE(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE);
GENERATE(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE);
GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT);
GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT);
GENERATE(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT);
GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT);
GENERATE(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE);
GENERATE(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE);
GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE);
GENERATE(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE);
GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
GENERATE(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE);
GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT);
GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT);
GENERATE(Token::ADD, INT32, INT32, INT32);
GENERATE(Token::ADD, INT32, INT32, NUMBER);
GENERATE(Token::ADD, INT32, NUMBER, NUMBER);
GENERATE(Token::ADD, INT32, SMI, INT32);
GENERATE(Token::ADD, NUMBER, INT32, NUMBER);
GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER);
GENERATE(Token::ADD, NUMBER, SMI, NUMBER);
GENERATE(Token::ADD, SMI, INT32, INT32);
GENERATE(Token::ADD, SMI, INT32, NUMBER);
GENERATE(Token::ADD, SMI, NUMBER, NUMBER);
GENERATE(Token::ADD, SMI, SMI, INT32);
GENERATE(Token::ADD, SMI, SMI, SMI);
GENERATE(Token::BIT_AND, INT32, INT32, INT32);
GENERATE(Token::BIT_AND, INT32, INT32, SMI);
GENERATE(Token::BIT_AND, INT32, SMI, INT32);
GENERATE(Token::BIT_AND, INT32, SMI, SMI);
GENERATE(Token::BIT_AND, NUMBER, INT32, INT32);
GENERATE(Token::BIT_AND, NUMBER, SMI, SMI);
GENERATE(Token::BIT_AND, SMI, INT32, INT32);
GENERATE(Token::BIT_AND, SMI, INT32, SMI);
GENERATE(Token::BIT_AND, SMI, NUMBER, SMI);
GENERATE(Token::BIT_AND, SMI, SMI, SMI);
GENERATE(Token::BIT_OR, INT32, INT32, INT32);
GENERATE(Token::BIT_OR, INT32, INT32, SMI);
GENERATE(Token::BIT_OR, INT32, SMI, INT32);
GENERATE(Token::BIT_OR, INT32, SMI, SMI);
GENERATE(Token::BIT_OR, NUMBER, SMI, INT32);
GENERATE(Token::BIT_OR, NUMBER, SMI, SMI);
GENERATE(Token::BIT_OR, SMI, INT32, INT32);
GENERATE(Token::BIT_OR, SMI, INT32, SMI);
GENERATE(Token::BIT_OR, SMI, SMI, SMI);
GENERATE(Token::BIT_XOR, INT32, INT32, INT32);
GENERATE(Token::BIT_XOR, INT32, INT32, SMI);
GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI);
GENERATE(Token::BIT_XOR, INT32, SMI, INT32);
GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32);
GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32);
GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI);
GENERATE(Token::BIT_XOR, SMI, INT32, INT32);
GENERATE(Token::BIT_XOR, SMI, INT32, SMI);
GENERATE(Token::BIT_XOR, SMI, SMI, SMI);
GENERATE(Token::DIV, INT32, INT32, INT32);
GENERATE(Token::DIV, INT32, INT32, NUMBER);
GENERATE(Token::DIV, INT32, NUMBER, NUMBER);
GENERATE(Token::DIV, INT32, SMI, INT32);
GENERATE(Token::DIV, INT32, SMI, NUMBER);
GENERATE(Token::DIV, NUMBER, INT32, NUMBER);
GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER);
GENERATE(Token::DIV, NUMBER, SMI, NUMBER);
GENERATE(Token::DIV, SMI, INT32, INT32);
GENERATE(Token::DIV, SMI, INT32, NUMBER);
GENERATE(Token::DIV, SMI, NUMBER, NUMBER);
GENERATE(Token::DIV, SMI, SMI, NUMBER);
GENERATE(Token::DIV, SMI, SMI, SMI);
GENERATE(Token::MOD, NUMBER, SMI, NUMBER);
GENERATE(Token::MOD, SMI, SMI, SMI);
GENERATE(Token::MUL, INT32, INT32, INT32);
GENERATE(Token::MUL, INT32, INT32, NUMBER);
GENERATE(Token::MUL, INT32, NUMBER, NUMBER);
GENERATE(Token::MUL, INT32, SMI, INT32);
GENERATE(Token::MUL, INT32, SMI, NUMBER);
GENERATE(Token::MUL, NUMBER, INT32, NUMBER);
GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER);
GENERATE(Token::MUL, NUMBER, SMI, NUMBER);
GENERATE(Token::MUL, SMI, INT32, INT32);
GENERATE(Token::MUL, SMI, INT32, NUMBER);
GENERATE(Token::MUL, SMI, NUMBER, NUMBER);
GENERATE(Token::MUL, SMI, SMI, INT32);
GENERATE(Token::MUL, SMI, SMI, NUMBER);
GENERATE(Token::MUL, SMI, SMI, SMI);
GENERATE(Token::SAR, INT32, SMI, INT32);
GENERATE(Token::SAR, INT32, SMI, SMI);
GENERATE(Token::SAR, NUMBER, SMI, SMI);
GENERATE(Token::SAR, SMI, SMI, SMI);
GENERATE(Token::SHL, INT32, SMI, INT32);
GENERATE(Token::SHL, INT32, SMI, SMI);
GENERATE(Token::SHL, NUMBER, SMI, SMI);
GENERATE(Token::SHL, SMI, SMI, INT32);
GENERATE(Token::SHL, SMI, SMI, SMI);
GENERATE(Token::SHR, INT32, SMI, SMI);
GENERATE(Token::SHR, NUMBER, SMI, INT32);
GENERATE(Token::SHR, NUMBER, SMI, SMI);
GENERATE(Token::SHR, SMI, SMI, SMI);
GENERATE(Token::SUB, INT32, INT32, INT32);
GENERATE(Token::SUB, INT32, NUMBER, NUMBER);
GENERATE(Token::SUB, INT32, SMI, INT32);
GENERATE(Token::SUB, NUMBER, INT32, NUMBER);
GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER);
GENERATE(Token::SUB, NUMBER, SMI, NUMBER);
GENERATE(Token::SUB, SMI, INT32, INT32);
GENERATE(Token::SUB, SMI, NUMBER, NUMBER);
GENERATE(Token::SUB, SMI, SMI, SMI);
#undef GENERATE
#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind, mode) \
do { \
BinaryOpICState state(isolate, op, mode); \
state.left_kind_ = left_kind; \
state.fixed_right_arg_.has_value = true; \
state.fixed_right_arg_.value = fixed_right_arg_value; \
state.right_kind_ = SMI; \
state.result_kind_ = result_kind; \
Generate(isolate, state); \
#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind) \
do { \
BinaryOpICState state(isolate, op); \
state.left_kind_ = left_kind; \
state.fixed_right_arg_.has_value = true; \
state.fixed_right_arg_.value = fixed_right_arg_value; \
state.right_kind_ = SMI; \
state.result_kind_ = result_kind; \
Generate(isolate, state); \
} while (false)
GENERATE(Token::MOD, SMI, 2, SMI, NO_OVERWRITE);
GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE);
GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT);
GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE);
GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT);
GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE);
GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE);
GENERATE(Token::MOD, SMI, 2, SMI);
GENERATE(Token::MOD, SMI, 4, SMI);
GENERATE(Token::MOD, SMI, 8, SMI);
GENERATE(Token::MOD, SMI, 16, SMI);
GENERATE(Token::MOD, SMI, 32, SMI);
GENERATE(Token::MOD, SMI, 2048, SMI);
#undef GENERATE
}
@ -319,10 +223,6 @@ Type* BinaryOpICState::GetResultType(Zone* zone) const {
std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s) {
os << "(" << Token::Name(s.op_);
if (s.mode_ == OVERWRITE_LEFT)
os << "_ReuseLeft";
else if (s.mode_ == OVERWRITE_RIGHT)
os << "_ReuseRight";
if (s.CouldCreateAllocationMementos()) os << "_CreateAllocationMementos";
os << ":" << BinaryOpICState::KindToString(s.left_kind_) << "*";
if (s.fixed_right_arg_.has_value) {
@ -372,14 +272,6 @@ void BinaryOpICState::Update(Handle<Object> left, Handle<Object> right,
left_kind_ = NUMBER;
}
// Reset overwrite mode unless we can actually make use of it, or may be able
// to make use of it at some point in the future.
if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) ||
(mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) ||
result_kind_ > NUMBER) {
mode_ = NO_OVERWRITE;
}
if (old_extra_ic_state == GetExtraICState()) {
// Tagged operations can lead to non-truncating HChanges
if (left->IsUndefined() || left->IsBoolean()) {

View File

@ -54,16 +54,12 @@ class CallICState FINAL BASE_EMBEDDED {
std::ostream& operator<<(std::ostream& os, const CallICState& s);
// Mode to overwrite BinaryExpression values.
enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
class BinaryOpICState FINAL BASE_EMBEDDED {
public:
BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
BinaryOpICState(Isolate* isolate, Token::Value op, OverwriteMode mode)
BinaryOpICState(Isolate* isolate, Token::Value op)
: op_(op),
mode_(mode),
left_kind_(NONE),
right_kind_(NONE),
result_kind_(NONE),
@ -91,14 +87,6 @@ class BinaryOpICState FINAL BASE_EMBEDDED {
void (*Generate)(Isolate*,
const BinaryOpICState&));
bool CanReuseDoubleBox() const {
return (result_kind_ > SMI && result_kind_ <= NUMBER) &&
((mode_ == OVERWRITE_LEFT && left_kind_ > SMI &&
left_kind_ <= NUMBER) ||
(mode_ == OVERWRITE_RIGHT && right_kind_ > SMI &&
right_kind_ <= NUMBER));
}
// Returns true if the IC _could_ create allocation mementos.
bool CouldCreateAllocationMementos() const {
if (left_kind_ == STRING || right_kind_ == STRING) {
@ -127,7 +115,6 @@ class BinaryOpICState FINAL BASE_EMBEDDED {
static const int LAST_TOKEN = Token::MOD;
Token::Value op() const { return op_; }
OverwriteMode mode() const { return mode_; }
Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
Type* GetLeftType(Zone* zone) const { return KindToType(left_kind_, zone); }
@ -154,17 +141,15 @@ class BinaryOpICState FINAL BASE_EMBEDDED {
// We truncate the last bit of the token.
STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
class OpField : public BitField<int, 0, 4> {};
class OverwriteModeField : public BitField<OverwriteMode, 4, 2> {};
class ResultKindField : public BitField<Kind, 6, 3> {};
class LeftKindField : public BitField<Kind, 9, 3> {};
class ResultKindField : public BitField<Kind, 4, 3> {};
class LeftKindField : public BitField<Kind, 7, 3> {};
// When fixed right arg is set, we don't need to store the right kind.
// Thus the two fields can overlap.
class HasFixedRightArgField : public BitField<bool, 12, 1> {};
class FixedRightArgValueField : public BitField<int, 13, 4> {};
class RightKindField : public BitField<Kind, 13, 3> {};
class HasFixedRightArgField : public BitField<bool, 10, 1> {};
class FixedRightArgValueField : public BitField<int, 11, 4> {};
class RightKindField : public BitField<Kind, 11, 3> {};
Token::Value op_;
OverwriteMode mode_;
Kind left_kind_;
Kind right_kind_;
Kind result_kind_;

View File

@ -1997,19 +1997,15 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ Push(rax); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
? OVERWRITE_RIGHT
: NO_OVERWRITE;
SetSourcePosition(expr->position() + 1);
AccumulatorValueContext context(this);
if (ShouldInlineSmiCase(op)) {
EmitInlineSmiBinaryOp(expr->binary_operation(),
op,
mode,
expr->target(),
expr->value());
} else {
EmitBinaryOp(expr->binary_operation(), op, mode);
EmitBinaryOp(expr->binary_operation(), op);
}
// Deoptimization point in case the binary operation may have side effects.
PrepareForBailout(expr->binary_operation(), TOS_REG);
@ -2389,7 +2385,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode,
Expression* left,
Expression* right) {
// Do combined smi check of the operands. Left operand is on the
@ -2404,7 +2399,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ bind(&stub_call);
__ movp(rax, rcx);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ jmp(&done, Label::kNear);
@ -2504,11 +2499,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
Token::Value op,
OverwriteMode mode) {
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ Pop(rdx);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
@ -4799,8 +4792,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ bind(&stub_call);
__ movp(rdx, rax);
__ Move(rax, Smi::FromInt(1));
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
NO_OVERWRITE).code();
Handle<Code> code =
CodeFactory::BinaryOpIC(isolate(), expr->binary_op()).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);

View File

@ -2065,8 +2065,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
DCHECK(ToRegister(instr->right()).is(rax));
DCHECK(ToRegister(instr->result()).is(rax));
Handle<Code> code =
CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), instr->op()).code();
CallCode(code, RelocInfo::CODE_TARGET, instr);
}