Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Side by Side Diff: src/ia32/full-codegen-ia32.cc

Issue 3203005: Start using the overwrite mode from the full codegens to generate... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/x64/code-stubs-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after
1207 } 1207 }
1208 1208
1209 // Evaluate RHS expression. 1209 // Evaluate RHS expression.
1210 Expression* rhs = expr->value(); 1210 Expression* rhs = expr->value();
1211 VisitForValue(rhs, kAccumulator); 1211 VisitForValue(rhs, kAccumulator);
1212 1212
1213 // If we have a compound assignment: Apply operator. 1213 // If we have a compound assignment: Apply operator.
1214 if (expr->is_compound()) { 1214 if (expr->is_compound()) {
1215 Location saved_location = location_; 1215 Location saved_location = location_;
1216 location_ = kAccumulator; 1216 location_ = kAccumulator;
1217 EmitBinaryOp(expr->binary_op(), Expression::kValue); 1217 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1218 ? OVERWRITE_RIGHT
1219 : NO_OVERWRITE;
1220 EmitBinaryOp(expr->binary_op(), Expression::kValue, mode);
1218 location_ = saved_location; 1221 location_ = saved_location;
1219 } 1222 }
1220 1223
1221 // Record source position before possible IC call. 1224 // Record source position before possible IC call.
1222 SetSourcePosition(expr->position()); 1225 SetSourcePosition(expr->position());
1223 1226
1224 // Store the value. 1227 // Store the value.
1225 switch (assign_type) { 1228 switch (assign_type) {
1226 case VARIABLE: 1229 case VARIABLE:
1227 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 1230 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
(...skipping 22 matching lines...) Expand all
1250 1253
1251 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1254 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1252 SetSourcePosition(prop->position()); 1255 SetSourcePosition(prop->position());
1253 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1256 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
1254 __ call(ic, RelocInfo::CODE_TARGET); 1257 __ call(ic, RelocInfo::CODE_TARGET);
1255 __ nop(); 1258 __ nop();
1256 } 1259 }
1257 1260
1258 1261
1259 void FullCodeGenerator::EmitBinaryOp(Token::Value op, 1262 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
1260 Expression::Context context) { 1263 Expression::Context context,
1261 __ push(result_register()); 1264 OverwriteMode mode) {
1262 GenericBinaryOpStub stub(op, 1265 TypeInfo type = TypeInfo::Unknown();
1263 NO_OVERWRITE, 1266 GenericBinaryOpStub stub(op, mode, NO_GENERIC_BINARY_FLAGS, type);
1264 NO_GENERIC_BINARY_FLAGS, 1267 if (stub.ArgsInRegistersSupported()) {
1265 TypeInfo::Unknown()); 1268 __ pop(edx);
1266 __ CallStub(&stub); 1269 stub.GenerateCall(masm_, edx, eax);
1270 } else {
1271 __ push(result_register());
1272 __ CallStub(&stub);
1273 }
1267 Apply(context, eax); 1274 Apply(context, eax);
1268 } 1275 }
1269 1276
1270 1277
1271 void FullCodeGenerator::EmitAssignment(Expression* expr) { 1278 void FullCodeGenerator::EmitAssignment(Expression* expr) {
1272 // Invalid left-hand sides are rewritten to have a 'throw 1279 // Invalid left-hand sides are rewritten to have a 'throw
1273 // ReferenceError' on the left-hand side. 1280 // ReferenceError' on the left-hand side.
1274 if (!expr->IsValidLeftHandSide()) { 1281 if (!expr->IsValidLeftHandSide()) {
1275 VisitForEffect(expr); 1282 VisitForEffect(expr);
1276 return; 1283 return;
(...skipping 1367 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 __ j(zero, &no_conversion); 2651 __ j(zero, &no_conversion);
2645 __ push(result_register()); 2652 __ push(result_register());
2646 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); 2653 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
2647 __ bind(&no_conversion); 2654 __ bind(&no_conversion);
2648 Apply(context_, result_register()); 2655 Apply(context_, result_register());
2649 break; 2656 break;
2650 } 2657 }
2651 2658
2652 case Token::SUB: { 2659 case Token::SUB: {
2653 Comment cmt(masm_, "[ UnaryOperation (SUB)"); 2660 Comment cmt(masm_, "[ UnaryOperation (SUB)");
2654 bool can_overwrite = 2661 bool can_overwrite = expr->expression()->ResultOverwriteAllowed();
2655 (expr->expression()->AsBinaryOperation() != NULL &&
2656 expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
2657 UnaryOverwriteMode overwrite = 2662 UnaryOverwriteMode overwrite =
2658 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; 2663 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
2659 GenericUnaryOpStub stub(Token::SUB, overwrite); 2664 GenericUnaryOpStub stub(Token::SUB, overwrite);
2660 // GenericUnaryOpStub expects the argument to be in the 2665 // GenericUnaryOpStub expects the argument to be in the
2661 // accumulator register eax. 2666 // accumulator register eax.
2662 VisitForValue(expr->expression(), kAccumulator); 2667 VisitForValue(expr->expression(), kAccumulator);
2663 __ CallStub(&stub); 2668 __ CallStub(&stub);
2664 Apply(context_, eax); 2669 Apply(context_, eax);
2665 break; 2670 break;
2666 } 2671 }
2667 2672
2668 case Token::BIT_NOT: { 2673 case Token::BIT_NOT: {
2669 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)"); 2674 Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)");
2670 bool can_overwrite = 2675 bool can_overwrite = expr->expression()->ResultOverwriteAllowed();
2671 (expr->expression()->AsBinaryOperation() != NULL &&
2672 expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
2673 UnaryOverwriteMode overwrite = 2676 UnaryOverwriteMode overwrite =
2674 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; 2677 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
2675 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); 2678 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
2676 // GenericUnaryOpStub expects the argument to be in the 2679 // GenericUnaryOpStub expects the argument to be in the
2677 // accumulator register eax. 2680 // accumulator register eax.
2678 VisitForValue(expr->expression(), kAccumulator); 2681 VisitForValue(expr->expression(), kAccumulator);
2679 // Avoid calling the stub for Smis. 2682 // Avoid calling the stub for Smis.
2680 Label smi, done; 2683 Label smi, done;
2681 __ test(result_register(), Immediate(kSmiTagMask)); 2684 __ test(result_register(), Immediate(kSmiTagMask));
2682 __ j(zero, &smi); 2685 __ j(zero, &smi);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2743 VisitForValue(prop->obj(), kStack); 2746 VisitForValue(prop->obj(), kStack);
2744 VisitForValue(prop->key(), kAccumulator); 2747 VisitForValue(prop->key(), kAccumulator);
2745 __ mov(edx, Operand(esp, 0)); 2748 __ mov(edx, Operand(esp, 0));
2746 __ push(eax); 2749 __ push(eax);
2747 EmitKeyedPropertyLoad(prop); 2750 EmitKeyedPropertyLoad(prop);
2748 } 2751 }
2749 } 2752 }
2750 2753
2751 // Call ToNumber only if operand is not a smi. 2754 // Call ToNumber only if operand is not a smi.
2752 Label no_conversion; 2755 Label no_conversion;
2753 __ test(eax, Immediate(kSmiTagMask)); 2756 if (ShouldInlineSmiCase(expr->op())) {
2754 __ j(zero, &no_conversion); 2757 __ test(eax, Immediate(kSmiTagMask));
2758 __ j(zero, &no_conversion);
2759 }
2755 __ push(eax); 2760 __ push(eax);
2756 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION); 2761 __ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
2757 __ bind(&no_conversion); 2762 __ bind(&no_conversion);
2758 2763
2759 // Save result for postfix expressions. 2764 // Save result for postfix expressions.
2760 if (expr->is_postfix()) { 2765 if (expr->is_postfix()) {
2761 switch (context_) { 2766 switch (context_) {
2762 case Expression::kUninitialized: 2767 case Expression::kUninitialized:
2763 UNREACHABLE(); 2768 UNREACHABLE();
2764 case Expression::kEffect: 2769 case Expression::kEffect:
(...skipping 14 matching lines...) Expand all
2779 case KEYED_PROPERTY: 2784 case KEYED_PROPERTY:
2780 __ mov(Operand(esp, 2 * kPointerSize), eax); 2785 __ mov(Operand(esp, 2 * kPointerSize), eax);
2781 break; 2786 break;
2782 } 2787 }
2783 break; 2788 break;
2784 } 2789 }
2785 } 2790 }
2786 2791
2787 // Inline smi case if we are in a loop. 2792 // Inline smi case if we are in a loop.
2788 Label stub_call, done; 2793 Label stub_call, done;
2789 if (loop_depth() > 0) { 2794 if (ShouldInlineSmiCase(expr->op())) {
2790 if (expr->op() == Token::INC) { 2795 if (expr->op() == Token::INC) {
2791 __ add(Operand(eax), Immediate(Smi::FromInt(1))); 2796 __ add(Operand(eax), Immediate(Smi::FromInt(1)));
2792 } else { 2797 } else {
2793 __ sub(Operand(eax), Immediate(Smi::FromInt(1))); 2798 __ sub(Operand(eax), Immediate(Smi::FromInt(1)));
2794 } 2799 }
2795 __ j(overflow, &stub_call); 2800 __ j(overflow, &stub_call);
2796 // We could eliminate this smi check if we split the code at 2801 // We could eliminate this smi check if we split the code at
2797 // the first smi check before calling ToNumber. 2802 // the first smi check before calling ToNumber.
2798 __ test(eax, Immediate(kSmiTagMask)); 2803 __ test(eax, Immediate(kSmiTagMask));
2799 __ j(zero, &done); 2804 __ j(zero, &done);
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
3020 __ test(eax, Operand(eax)); 3025 __ test(eax, Operand(eax));
3021 // The stub returns 0 for true. 3026 // The stub returns 0 for true.
3022 Split(zero, if_true, if_false, fall_through); 3027 Split(zero, if_true, if_false, fall_through);
3023 break; 3028 break;
3024 } 3029 }
3025 3030
3026 default: { 3031 default: {
3027 VisitForValue(expr->right(), kAccumulator); 3032 VisitForValue(expr->right(), kAccumulator);
3028 Condition cc = no_condition; 3033 Condition cc = no_condition;
3029 bool strict = false; 3034 bool strict = false;
3030 switch (expr->op()) { 3035 switch (op) {
3031 case Token::EQ_STRICT: 3036 case Token::EQ_STRICT:
3032 strict = true; 3037 strict = true;
3033 // Fall through 3038 // Fall through
3034 case Token::EQ: 3039 case Token::EQ:
3035 cc = equal; 3040 cc = equal;
3036 __ pop(edx); 3041 __ pop(edx);
3037 break; 3042 break;
3038 case Token::LT: 3043 case Token::LT:
3039 cc = less; 3044 cc = less;
3040 __ pop(edx); 3045 __ pop(edx);
(...skipping 13 matching lines...) Expand all
3054 case Token::GTE: 3059 case Token::GTE:
3055 cc = greater_equal; 3060 cc = greater_equal;
3056 __ pop(edx); 3061 __ pop(edx);
3057 break; 3062 break;
3058 case Token::IN: 3063 case Token::IN:
3059 case Token::INSTANCEOF: 3064 case Token::INSTANCEOF:
3060 default: 3065 default:
3061 UNREACHABLE(); 3066 UNREACHABLE();
3062 } 3067 }
3063 3068
3064 // The comparison stub expects the smi vs. smi case to be handled 3069 // The comparison stub expects the smi vs. smi case to be
3065 // before it is called. 3070 // handled before it is called.
3066 Label slow_case; 3071 Label slow_case;
3067 __ mov(ecx, Operand(edx)); 3072 __ mov(ecx, Operand(edx));
3068 __ or_(ecx, Operand(eax)); 3073 __ or_(ecx, Operand(eax));
3069 __ test(ecx, Immediate(kSmiTagMask)); 3074 __ test(ecx, Immediate(kSmiTagMask));
3070 __ j(not_zero, &slow_case, not_taken); 3075 __ j(not_zero, &slow_case, not_taken);
3071 __ cmp(edx, Operand(eax)); 3076 __ cmp(edx, Operand(eax));
3072 __ j(cc, if_true); 3077 __ j(cc, if_true);
3073 __ jmp(if_false); 3078 __ jmp(if_false);
3074 3079
3075 __ bind(&slow_case); 3080 __ bind(&slow_case);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
3166 // And return. 3171 // And return.
3167 __ ret(0); 3172 __ ret(0);
3168 } 3173 }
3169 3174
3170 3175
3171 #undef __ 3176 #undef __
3172 3177
3173 } } // namespace v8::internal 3178 } } // namespace v8::internal
3174 3179
3175 #endif // V8_TARGET_ARCH_IA32 3180 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/x64/code-stubs-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698