| Index: src/codegen-ia32.cc
|
| ===================================================================
|
| --- src/codegen-ia32.cc (revision 1633)
|
| +++ src/codegen-ia32.cc (working copy)
|
| @@ -699,12 +699,10 @@
|
|
|
|
|
| // Flag that indicates whether or not the code that handles smi arguments
|
| -// should be inlined, placed in the stub, or omitted entirely.
|
| +// should be placed in the stub, inlined, or omitted entirely.
|
| enum GenericBinaryFlags {
|
| SMI_CODE_IN_STUB,
|
| - SMI_CODE_INLINED,
|
| - // It is known at compile time that at least one argument is not a smi.
|
| - NO_SMI_CODE
|
| + SMI_CODE_INLINED
|
| };
|
|
|
|
|
| @@ -713,7 +711,9 @@
|
| GenericBinaryOpStub(Token::Value op,
|
| OverwriteMode mode,
|
| GenericBinaryFlags flags)
|
| - : op_(op), mode_(mode), flags_(flags) { }
|
| + : op_(op), mode_(mode), flags_(flags) {
|
| + ASSERT(OpBits::is_valid(Token::NUM_TOKENS));
|
| + }
|
|
|
| void GenerateSmiCode(MacroAssembler* masm, Label* slow);
|
|
|
| @@ -735,8 +735,8 @@
|
|
|
| // Minor key encoding in 16 bits FOOOOOOOOOOOOOMM.
|
| class ModeBits: public BitField<OverwriteMode, 0, 2> {};
|
| - class OpBits: public BitField<Token::Value, 2, 12> {};
|
| - class FlagBits: public BitField<GenericBinaryFlags, 14, 2> {};
|
| + class OpBits: public BitField<Token::Value, 2, 13> {};
|
| + class FlagBits: public BitField<GenericBinaryFlags, 15, 1> {};
|
|
|
| Major MajorKey() { return GenericBinaryOp; }
|
| int MinorKey() {
|
| @@ -845,9 +845,10 @@
|
| bool left_is_non_smi = left.is_constant() && !left.handle()->IsSmi();
|
| bool right_is_smi = right.is_constant() && right.handle()->IsSmi();
|
| bool right_is_non_smi = right.is_constant() && !right.handle()->IsSmi();
|
| + bool generate_no_smi_code = false; // No smi code at all, inline or in stub.
|
|
|
| if (left_is_smi && right_is_smi) {
|
| - // Compute the result, and return that as a constant on the frame.
|
| + // Compute the constant result at compile time, and leave it on the frame.
|
| int left_int = Smi::cast(*left.handle())->value();
|
| int right_int = Smi::cast(*right.handle())->value();
|
| if (FoldConstantSmis(op, left_int, right_int)) return;
|
| @@ -855,18 +856,18 @@
|
|
|
| if (left_is_non_smi || right_is_non_smi) {
|
| // Set flag so that we go straight to the slow case, with no smi code.
|
| - flags = NO_SMI_CODE;
|
| + generate_no_smi_code = true;
|
| } else if (right_is_smi) {
|
| - ConstantSmiBinaryOperation(op, &left, right.handle(), type,
|
| - false, overwrite_mode);
|
| + ConstantSmiBinaryOperation(op, &left, right.handle(),
|
| + type, false, overwrite_mode);
|
| return;
|
| } else if (left_is_smi) {
|
| - ConstantSmiBinaryOperation(op, &right, left.handle(), type,
|
| - true, overwrite_mode);
|
| + ConstantSmiBinaryOperation(op, &right, left.handle(),
|
| + type, true, overwrite_mode);
|
| return;
|
| }
|
|
|
| - if (flags == SMI_CODE_INLINED) {
|
| + if (flags == SMI_CODE_INLINED && !generate_no_smi_code) {
|
| LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
|
| } else {
|
| frame_->Push(&left);
|
| @@ -874,7 +875,7 @@
|
| // If we know the arguments aren't smis, use the binary operation stub
|
| // that does not check for the fast smi case.
|
| // The same stub is used for NO_SMI_CODE and SMI_CODE_INLINED.
|
| - if (flags == NO_SMI_CODE) {
|
| + if (generate_no_smi_code) {
|
| flags = SMI_CODE_INLINED;
|
| }
|
| GenericBinaryOpStub stub(op, overwrite_mode, flags);
|
| @@ -969,8 +970,8 @@
|
| Result* left,
|
| Result* right,
|
| OverwriteMode overwrite_mode) {
|
| - // Create a new deferred code object that calls GenericBinaryOpStub
|
| - // in the slow case.
|
| + // Implements a binary operation using a deferred code object
|
| + // and some inline code to operate on smis quickly.
|
| DeferredInlineBinaryOperation* deferred =
|
| new DeferredInlineBinaryOperation(this, op, overwrite_mode,
|
| SMI_CODE_INLINED);
|
| @@ -1233,7 +1234,7 @@
|
|
|
| case Token::SUB: {
|
| DeferredCode* deferred = NULL;
|
| - Result answer(this); // Only allocated a new register if reversed.
|
| + Result answer(this); // Only allocate a new register if reversed.
|
| if (reversed) {
|
| answer = allocator()->Allocate();
|
| ASSERT(answer.is_valid());
|
| @@ -5570,10 +5571,14 @@
|
|
|
| ASSERT(answer.is_valid());
|
| // Perform the smi check.
|
| - __ mov(answer.reg(), left->reg());
|
| - __ or_(answer.reg(), Operand(right->reg()));
|
| - ASSERT(kSmiTag == 0); // adjust zero check if not the case
|
| - __ test(answer.reg(), Immediate(kSmiTagMask));
|
| + if (left->reg().is(right->reg())) {
|
| + __ test(left->reg(), Immediate(kSmiTagMask));
|
| + } else {
|
| + __ mov(answer.reg(), left->reg());
|
| + __ or_(answer.reg(), Operand(right->reg()));
|
| + ASSERT(kSmiTag == 0); // adjust zero check if not the case
|
| + __ test(answer.reg(), Immediate(kSmiTagMask));
|
| + }
|
| enter()->Branch(not_zero, left, right, not_taken);
|
|
|
| // All operations start by copying the left argument into answer.
|
|
|