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

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

Issue 13746: Experimental: thread live register references to deferred code.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 12 years 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
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 560
561 private: 561 private:
562 Major MajorKey() { return ToBoolean; } 562 Major MajorKey() { return ToBoolean; }
563 int MinorKey() { return 0; } 563 int MinorKey() { return 0; }
564 }; 564 };
565 565
566 566
567 // ECMA-262, section 9.2, page 30: ToBoolean(). Pop the top of stack and 567 // ECMA-262, section 9.2, page 30: ToBoolean(). Pop the top of stack and
568 // convert it to a boolean in the condition code register or jump to 568 // convert it to a boolean in the condition code register or jump to
569 // 'false_target'/'true_target' as appropriate. 569 // 'false_target'/'true_target' as appropriate.
570 void CodeGenerator::ToBoolean(JumpTarget* true_target, JumpTarget* false_target) { 570 void CodeGenerator::ToBoolean(JumpTarget* true_target,
571 JumpTarget* false_target) {
571 Comment cmnt(masm_, "[ ToBoolean"); 572 Comment cmnt(masm_, "[ ToBoolean");
572 573
573 // The value to convert should be popped from the stack. 574 // The value to convert should be popped from the stack.
574 frame_->EmitPop(eax); 575 frame_->EmitPop(eax);
575 576
576 // Fast case checks. 577 // Fast case checks.
577 578
578 // 'false' => false. 579 // 'false' => false.
579 __ cmp(eax, Factory::false_value()); 580 __ cmp(eax, Factory::false_value());
580 false_target->Branch(equal); 581 false_target->Branch(equal);
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 new DeferredInlineBinaryOperation(this, op, overwrite_mode, flags); 769 new DeferredInlineBinaryOperation(this, op, overwrite_mode, flags);
769 // Fetch the operands from the stack. 770 // Fetch the operands from the stack.
770 frame_->EmitPop(ebx); // get y 771 frame_->EmitPop(ebx); // get y
771 __ mov(eax, frame_->Top()); // get x 772 __ mov(eax, frame_->Top()); // get x
772 // Generate the inline part of the code. 773 // Generate the inline part of the code.
773 deferred->GenerateInlineCode(); 774 deferred->GenerateInlineCode();
774 // Put result back on the stack. It seems somewhat weird to let 775 // Put result back on the stack. It seems somewhat weird to let
775 // the deferred code jump back before the assignment to the frame 776 // the deferred code jump back before the assignment to the frame
776 // top, but this is just to let the peephole optimizer get rid of 777 // top, but this is just to let the peephole optimizer get rid of
777 // more code. 778 // more code.
778 deferred->exit()->Bind(); 779 deferred->BindExit();
779 __ mov(frame_->Top(), eax); 780 __ mov(frame_->Top(), eax);
780 } else { 781 } else {
781 // Call the stub and push the result to the stack. 782 // Call the stub and push the result to the stack.
782 GenericBinaryOpStub stub(op, overwrite_mode, flags); 783 GenericBinaryOpStub stub(op, overwrite_mode, flags);
783 frame_->CallStub(&stub, 2); 784 frame_->CallStub(&stub, 2);
784 frame_->EmitPush(eax); 785 frame_->EmitPush(eax);
785 } 786 }
786 } 787 }
787 788
788 789
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
953 case Token::ADD: { 954 case Token::ADD: {
954 DeferredCode* deferred = NULL; 955 DeferredCode* deferred = NULL;
955 if (!reversed) { 956 if (!reversed) {
956 deferred = new DeferredInlinedSmiAdd(this, int_value, overwrite_mode); 957 deferred = new DeferredInlinedSmiAdd(this, int_value, overwrite_mode);
957 } else { 958 } else {
958 deferred = new DeferredInlinedSmiAddReversed(this, int_value, 959 deferred = new DeferredInlinedSmiAddReversed(this, int_value,
959 overwrite_mode); 960 overwrite_mode);
960 } 961 }
961 frame_->EmitPop(eax); 962 frame_->EmitPop(eax);
962 __ add(Operand(eax), Immediate(value)); 963 __ add(Operand(eax), Immediate(value));
963 deferred->enter()->Branch(overflow, not_taken); 964 deferred->BranchTo(overflow);
964 __ test(eax, Immediate(kSmiTagMask)); 965 __ test(eax, Immediate(kSmiTagMask));
965 deferred->enter()->Branch(not_zero, not_taken); 966 deferred->BranchTo(not_zero);
966 deferred->exit()->Bind(); 967 deferred->BindExit();
967 frame_->EmitPush(eax); 968 frame_->EmitPush(eax);
968 break; 969 break;
969 } 970 }
970 971
971 case Token::SUB: { 972 case Token::SUB: {
972 DeferredCode* deferred = NULL; 973 DeferredCode* deferred = NULL;
973 frame_->EmitPop(eax); 974 frame_->EmitPop(eax);
974 if (!reversed) { 975 if (!reversed) {
975 deferred = new DeferredInlinedSmiSub(this, int_value, overwrite_mode); 976 deferred = new DeferredInlinedSmiSub(this, int_value, overwrite_mode);
976 __ sub(Operand(eax), Immediate(value)); 977 __ sub(Operand(eax), Immediate(value));
977 } else { 978 } else {
978 deferred = new DeferredInlinedSmiSubReversed(this, edx, overwrite_mode); 979 deferred = new DeferredInlinedSmiSubReversed(this, edx, overwrite_mode);
979 __ mov(edx, Operand(eax)); 980 __ mov(edx, Operand(eax));
980 __ mov(eax, Immediate(value)); 981 __ mov(eax, Immediate(value));
981 __ sub(eax, Operand(edx)); 982 __ sub(eax, Operand(edx));
982 } 983 }
983 deferred->enter()->Branch(overflow, not_taken); 984 deferred->BranchTo(overflow);
984 __ test(eax, Immediate(kSmiTagMask)); 985 __ test(eax, Immediate(kSmiTagMask));
985 deferred->enter()->Branch(not_zero, not_taken); 986 deferred->BranchTo(not_zero);
986 deferred->exit()->Bind(); 987 deferred->BindExit();
987 frame_->EmitPush(eax); 988 frame_->EmitPush(eax);
988 break; 989 break;
989 } 990 }
990 991
991 case Token::SAR: { 992 case Token::SAR: {
992 if (reversed) { 993 if (reversed) {
993 frame_->EmitPop(eax); 994 frame_->EmitPop(eax);
994 frame_->EmitPush(Immediate(value)); 995 frame_->EmitPush(Immediate(value));
995 frame_->EmitPush(eax); 996 frame_->EmitPush(eax);
996 GenericBinaryOperation(op, type, overwrite_mode); 997 GenericBinaryOperation(op, type, overwrite_mode);
997 } else { 998 } else {
998 int shift_value = int_value & 0x1f; // only least significant 5 bits 999 int shift_value = int_value & 0x1f; // only least significant 5 bits
999 DeferredCode* deferred = 1000 DeferredCode* deferred =
1000 new DeferredInlinedSmiOperation(this, Token::SAR, shift_value, 1001 new DeferredInlinedSmiOperation(this, Token::SAR, shift_value,
1001 overwrite_mode); 1002 overwrite_mode);
1002 frame_->EmitPop(eax); 1003 frame_->EmitPop(eax);
1003 __ test(eax, Immediate(kSmiTagMask)); 1004 __ test(eax, Immediate(kSmiTagMask));
1004 deferred->enter()->Branch(not_zero, not_taken); 1005 deferred->BranchTo(not_zero);
1005 __ sar(eax, shift_value); 1006 __ sar(eax, shift_value);
1006 __ and_(eax, ~kSmiTagMask); 1007 __ and_(eax, ~kSmiTagMask);
1007 deferred->exit()->Bind(); 1008 deferred->BindExit();
1008 frame_->EmitPush(eax); 1009 frame_->EmitPush(eax);
1009 } 1010 }
1010 break; 1011 break;
1011 } 1012 }
1012 1013
1013 case Token::SHR: { 1014 case Token::SHR: {
1014 if (reversed) { 1015 if (reversed) {
1015 frame_->EmitPop(eax); 1016 frame_->EmitPop(eax);
1016 frame_->EmitPush(Immediate(value)); 1017 frame_->EmitPush(Immediate(value));
1017 frame_->EmitPush(eax); 1018 frame_->EmitPush(eax);
1018 GenericBinaryOperation(op, type, overwrite_mode); 1019 GenericBinaryOperation(op, type, overwrite_mode);
1019 } else { 1020 } else {
1020 int shift_value = int_value & 0x1f; // only least significant 5 bits 1021 int shift_value = int_value & 0x1f; // only least significant 5 bits
1021 DeferredCode* deferred = 1022 DeferredCode* deferred =
1022 new DeferredInlinedSmiOperation(this, Token::SHR, shift_value, 1023 new DeferredInlinedSmiOperation(this, Token::SHR, shift_value,
1023 overwrite_mode); 1024 overwrite_mode);
1024 frame_->EmitPop(eax); 1025 frame_->EmitPop(eax);
1025 __ test(eax, Immediate(kSmiTagMask)); 1026 __ test(eax, Immediate(kSmiTagMask));
1026 __ mov(ebx, Operand(eax)); 1027 __ mov(ebx, Operand(eax));
1027 deferred->enter()->Branch(not_zero, not_taken); 1028 deferred->BranchTo(not_zero);
1028 __ sar(ebx, kSmiTagSize); 1029 __ sar(ebx, kSmiTagSize);
1029 __ shr(ebx, shift_value); 1030 __ shr(ebx, shift_value);
1030 __ test(ebx, Immediate(0xc0000000)); 1031 __ test(ebx, Immediate(0xc0000000));
1031 deferred->enter()->Branch(not_zero, not_taken); 1032 deferred->BranchTo(not_zero);
1032 // tag result and store it in TOS (eax) 1033 // tag result and store it in TOS (eax)
1033 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 1034 ASSERT(kSmiTagSize == times_2); // adjust code if not the case
1034 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag)); 1035 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag));
1035 deferred->exit()->Bind(); 1036 deferred->BindExit();
1036 frame_->EmitPush(eax); 1037 frame_->EmitPush(eax);
1037 } 1038 }
1038 break; 1039 break;
1039 } 1040 }
1040 1041
1041 case Token::SHL: { 1042 case Token::SHL: {
1042 if (reversed) { 1043 if (reversed) {
1043 frame_->EmitPop(eax); 1044 frame_->EmitPop(eax);
1044 frame_->EmitPush(Immediate(value)); 1045 frame_->EmitPush(Immediate(value));
1045 frame_->EmitPush(eax); 1046 frame_->EmitPush(eax);
1046 GenericBinaryOperation(op, type, overwrite_mode); 1047 GenericBinaryOperation(op, type, overwrite_mode);
1047 } else { 1048 } else {
1048 int shift_value = int_value & 0x1f; // only least significant 5 bits 1049 int shift_value = int_value & 0x1f; // only least significant 5 bits
1049 DeferredCode* deferred = 1050 DeferredCode* deferred =
1050 new DeferredInlinedSmiOperation(this, Token::SHL, shift_value, 1051 new DeferredInlinedSmiOperation(this, Token::SHL, shift_value,
1051 overwrite_mode); 1052 overwrite_mode);
1052 frame_->EmitPop(eax); 1053 frame_->EmitPop(eax);
1053 __ test(eax, Immediate(kSmiTagMask)); 1054 __ test(eax, Immediate(kSmiTagMask));
1054 __ mov(ebx, Operand(eax)); 1055 __ mov(ebx, Operand(eax));
1055 deferred->enter()->Branch(not_zero, not_taken); 1056 deferred->BranchTo(not_zero);
1056 __ sar(ebx, kSmiTagSize); 1057 __ sar(ebx, kSmiTagSize);
1057 __ shl(ebx, shift_value); 1058 __ shl(ebx, shift_value);
1058 __ lea(ecx, Operand(ebx, 0x40000000)); 1059 __ lea(ecx, Operand(ebx, 0x40000000));
1059 __ test(ecx, Immediate(0x80000000)); 1060 __ test(ecx, Immediate(0x80000000));
1060 deferred->enter()->Branch(not_zero, not_taken); 1061 deferred->BranchTo(not_zero);
1061 // tag result and store it in TOS (eax) 1062 // tag result and store it in TOS (eax)
1062 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 1063 ASSERT(kSmiTagSize == times_2); // adjust code if not the case
1063 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag)); 1064 __ lea(eax, Operand(ebx, ebx, times_1, kSmiTag));
1064 deferred->exit()->Bind(); 1065 deferred->BindExit();
1065 frame_->EmitPush(eax); 1066 frame_->EmitPush(eax);
1066 } 1067 }
1067 break; 1068 break;
1068 } 1069 }
1069 1070
1070 case Token::BIT_OR: 1071 case Token::BIT_OR:
1071 case Token::BIT_XOR: 1072 case Token::BIT_XOR:
1072 case Token::BIT_AND: { 1073 case Token::BIT_AND: {
1073 DeferredCode* deferred = NULL; 1074 DeferredCode* deferred = NULL;
1074 if (!reversed) { 1075 if (!reversed) {
1075 deferred = new DeferredInlinedSmiOperation(this, op, int_value, 1076 deferred = new DeferredInlinedSmiOperation(this, op, int_value,
1076 overwrite_mode); 1077 overwrite_mode);
1077 } else { 1078 } else {
1078 deferred = new DeferredInlinedSmiOperationReversed(this, op, int_value, 1079 deferred = new DeferredInlinedSmiOperationReversed(this, op, int_value,
1079 overwrite_mode); 1080 overwrite_mode);
1080 } 1081 }
1081 frame_->EmitPop(eax); 1082 frame_->EmitPop(eax);
1082 __ test(eax, Immediate(kSmiTagMask)); 1083 __ test(eax, Immediate(kSmiTagMask));
1083 deferred->enter()->Branch(not_zero, not_taken); 1084 deferred->BranchTo(not_zero);
1084 if (op == Token::BIT_AND) { 1085 if (op == Token::BIT_AND) {
1085 __ and_(Operand(eax), Immediate(value)); 1086 __ and_(Operand(eax), Immediate(value));
1086 } else if (op == Token::BIT_XOR) { 1087 } else if (op == Token::BIT_XOR) {
1087 __ xor_(Operand(eax), Immediate(value)); 1088 __ xor_(Operand(eax), Immediate(value));
1088 } else { 1089 } else {
1089 ASSERT(op == Token::BIT_OR); 1090 ASSERT(op == Token::BIT_OR);
1090 __ or_(Operand(eax), Immediate(value)); 1091 __ or_(Operand(eax), Immediate(value));
1091 } 1092 }
1092 deferred->exit()->Bind(); 1093 deferred->BindExit();
1093 frame_->EmitPush(eax); 1094 frame_->EmitPush(eax);
1094 break; 1095 break;
1095 } 1096 }
1096 1097
1097 default: { 1098 default: {
1098 if (!reversed) { 1099 if (!reversed) {
1099 frame_->EmitPush(Immediate(value)); 1100 frame_->EmitPush(Immediate(value));
1100 } else { 1101 } else {
1101 frame_->EmitPop(eax); 1102 frame_->EmitPop(eax);
1102 frame_->EmitPush(Immediate(value)); 1103 frame_->EmitPush(Immediate(value));
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1215 // Strict only makes sense for equality comparisons. 1216 // Strict only makes sense for equality comparisons.
1216 ASSERT(!strict || cc == equal); 1217 ASSERT(!strict || cc == equal);
1217 1218
1218 int int_value = Smi::cast(*value)->value(); 1219 int int_value = Smi::cast(*value)->value();
1219 ASSERT(is_intn(int_value, kMaxSmiInlinedBits)); 1220 ASSERT(is_intn(int_value, kMaxSmiInlinedBits));
1220 1221
1221 SmiComparisonDeferred* deferred = 1222 SmiComparisonDeferred* deferred =
1222 new SmiComparisonDeferred(this, cc, strict, int_value); 1223 new SmiComparisonDeferred(this, cc, strict, int_value);
1223 frame_->EmitPop(eax); 1224 frame_->EmitPop(eax);
1224 __ test(eax, Immediate(kSmiTagMask)); 1225 __ test(eax, Immediate(kSmiTagMask));
1225 deferred->enter()->Branch(not_zero, not_taken); 1226 deferred->BranchTo(not_zero);
William Hesse 2008/12/16 09:10:54 Will conflict with my changes, I think
1226 // Test smi equality by pointer comparison. 1227 // Test smi equality by pointer comparison.
1227 __ cmp(Operand(eax), Immediate(value)); 1228 __ cmp(Operand(eax), Immediate(value));
1228 deferred->exit()->Bind(); 1229 deferred->BindExit();
1229 cc_reg_ = cc; 1230 cc_reg_ = cc;
1230 } 1231 }
1231 1232
1232 1233
1233 class CallFunctionStub: public CodeStub { 1234 class CallFunctionStub: public CodeStub {
1234 public: 1235 public:
1235 explicit CallFunctionStub(int argc) : argc_(argc) { } 1236 explicit CallFunctionStub(int argc) : argc_(argc) { }
1236 1237
1237 void Generate(MacroAssembler* masm); 1238 void Generate(MacroAssembler* masm);
1238 1239
(...skipping 1463 matching lines...) Expand 10 before | Expand all | Expand 10 after
2702 __ mov(ecx, FieldOperand(ecx, JSFunction::kLiteralsOffset)); 2703 __ mov(ecx, FieldOperand(ecx, JSFunction::kLiteralsOffset));
2703 2704
2704 // Load the literal at the ast saved index. 2705 // Load the literal at the ast saved index.
2705 int literal_offset = 2706 int literal_offset =
2706 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; 2707 FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
2707 __ mov(ebx, FieldOperand(ecx, literal_offset)); 2708 __ mov(ebx, FieldOperand(ecx, literal_offset));
2708 2709
2709 // Check whether we need to materialize the RegExp object. 2710 // Check whether we need to materialize the RegExp object.
2710 // If so, jump to the deferred code. 2711 // If so, jump to the deferred code.
2711 __ cmp(ebx, Factory::undefined_value()); 2712 __ cmp(ebx, Factory::undefined_value());
2712 deferred->enter()->Branch(equal, not_taken); 2713 deferred->BranchTo(equal);
2713 deferred->exit()->Bind(); 2714 deferred->BindExit();
2714 2715
2715 // Push the literal. 2716 // Push the literal.
2716 frame_->EmitPush(ebx); 2717 frame_->EmitPush(ebx);
2717 } 2718 }
2718 2719
2719 2720
2720 // This deferred code stub will be used for creating the boilerplate 2721 // This deferred code stub will be used for creating the boilerplate
2721 // by calling Runtime_CreateObjectLiteral. 2722 // by calling Runtime_CreateObjectLiteral.
2722 // Each created boilerplate is stored in the JSFunction and they are 2723 // Each created boilerplate is stored in the JSFunction and they are
2723 // therefore context dependent. 2724 // therefore context dependent.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2763 __ mov(ecx, FieldOperand(ecx, JSFunction::kLiteralsOffset)); 2764 __ mov(ecx, FieldOperand(ecx, JSFunction::kLiteralsOffset));
2764 2765
2765 // Load the literal at the ast saved index. 2766 // Load the literal at the ast saved index.
2766 int literal_offset = 2767 int literal_offset =
2767 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; 2768 FixedArray::kHeaderSize + node->literal_index() * kPointerSize;
2768 __ mov(ebx, FieldOperand(ecx, literal_offset)); 2769 __ mov(ebx, FieldOperand(ecx, literal_offset));
2769 2770
2770 // Check whether we need to materialize the object literal boilerplate. 2771 // Check whether we need to materialize the object literal boilerplate.
2771 // If so, jump to the deferred code. 2772 // If so, jump to the deferred code.
2772 __ cmp(ebx, Factory::undefined_value()); 2773 __ cmp(ebx, Factory::undefined_value());
2773 deferred->enter()->Branch(equal, not_taken); 2774 deferred->BranchTo(equal);
2774 deferred->exit()->Bind(); 2775 deferred->BindExit();
2775 2776
2776 // Push the literal. 2777 // Push the literal.
2777 frame_->EmitPush(ebx); 2778 frame_->EmitPush(ebx);
2778 // Clone the boilerplate object. 2779 // Clone the boilerplate object.
2779 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1); 2780 frame_->CallRuntime(Runtime::kCloneObjectLiteralBoilerplate, 1);
2780 // Push the new cloned literal object as the result. 2781 // Push the new cloned literal object as the result.
2781 frame_->EmitPush(eax); 2782 frame_->EmitPush(eax);
2782 2783
2783 2784
2784 for (int i = 0; i < node->properties()->length(); i++) { 2785 for (int i = 0; i < node->properties()->length(); i++) {
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
3766 // Perform optimistic increment/decrement. 3767 // Perform optimistic increment/decrement.
3767 if (is_increment) { 3768 if (is_increment) {
3768 __ add(Operand(eax), Immediate(Smi::FromInt(1))); 3769 __ add(Operand(eax), Immediate(Smi::FromInt(1)));
3769 } else { 3770 } else {
3770 __ sub(Operand(eax), Immediate(Smi::FromInt(1))); 3771 __ sub(Operand(eax), Immediate(Smi::FromInt(1)));
3771 } 3772 }
3772 3773
3773 // If the count operation didn't overflow and the result is a 3774 // If the count operation didn't overflow and the result is a
3774 // valid smi, we're done. Otherwise, we jump to the deferred 3775 // valid smi, we're done. Otherwise, we jump to the deferred
3775 // slow-case code. 3776 // slow-case code.
3776 deferred->enter()->Branch(overflow, not_taken); 3777 deferred->BranchTo(overflow);
3777 __ test(eax, Immediate(kSmiTagMask)); 3778 __ test(eax, Immediate(kSmiTagMask));
3778 deferred->enter()->Branch(not_zero, not_taken); 3779 deferred->BranchTo(not_zero);
3779 3780
3780 // Store the new value in the target if not const. 3781 // Store the new value in the target if not const.
3781 deferred->exit()->Bind(); 3782 deferred->BindExit();
3782 frame_->EmitPush(eax); // Push the new value to TOS 3783 frame_->EmitPush(eax); // Push the new value to TOS
3783 if (!is_const) target.SetValue(NOT_CONST_INIT); 3784 if (!is_const) target.SetValue(NOT_CONST_INIT);
3784 } 3785 }
3785 3786
3786 // Postfix: Discard the new value and use the old. 3787 // Postfix: Discard the new value and use the old.
3787 if (is_postfix) { 3788 if (is_postfix) {
3788 frame_->Drop(); 3789 frame_->Drop();
3789 } 3790 }
3790 } 3791 }
3791 3792
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
4087 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 4088 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
4088 __ cmp(ecx, FIRST_JS_OBJECT_TYPE); 4089 __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
4089 false_target()->Branch(less); 4090 false_target()->Branch(less);
4090 __ cmp(ecx, LAST_JS_OBJECT_TYPE); 4091 __ cmp(ecx, LAST_JS_OBJECT_TYPE);
4091 cc_reg_ = less_equal; 4092 cc_reg_ = less_equal;
4092 4093
4093 } else { 4094 } else {
4094 // Uncommon case: typeof testing against a string literal that is 4095 // Uncommon case: typeof testing against a string literal that is
4095 // never returned from the typeof operator. 4096 // never returned from the typeof operator.
4096 false_target()->Jump(); 4097 false_target()->Jump();
4097 // TODO(): Can this cause a problem because it is an expression that
4098 // exits without a virtual frame in place?
4099 } 4098 }
4100 return; 4099 return;
4101 } 4100 }
4102 4101
4103 Condition cc = no_condition; 4102 Condition cc = no_condition;
4104 bool strict = false; 4103 bool strict = false;
4105 switch (op) { 4104 switch (op) {
4106 case Token::EQ_STRICT: 4105 case Token::EQ_STRICT:
4107 strict = true; 4106 strict = true;
4108 // Fall through 4107 // Fall through
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
4388 // leave result in register eax. 4387 // leave result in register eax.
4389 4388
4390 // Prepare the smi check of both operands by or'ing them together 4389 // Prepare the smi check of both operands by or'ing them together
4391 // before checking against the smi mask. 4390 // before checking against the smi mask.
4392 __ mov(ecx, Operand(ebx)); 4391 __ mov(ecx, Operand(ebx));
4393 __ or_(ecx, Operand(eax)); 4392 __ or_(ecx, Operand(eax));
4394 4393
4395 switch (op_) { 4394 switch (op_) {
4396 case Token::ADD: 4395 case Token::ADD:
4397 __ add(eax, Operand(ebx)); // add optimistically 4396 __ add(eax, Operand(ebx)); // add optimistically
4398 enter()->Branch(overflow, not_taken); 4397 BranchTo(overflow);
4399 break; 4398 break;
4400 4399
4401 case Token::SUB: 4400 case Token::SUB:
4402 __ sub(eax, Operand(ebx)); // subtract optimistically 4401 __ sub(eax, Operand(ebx)); // subtract optimistically
4403 enter()->Branch(overflow, not_taken); 4402 BranchTo(overflow);
4404 break; 4403 break;
4405 4404
4406 case Token::DIV: 4405 case Token::DIV:
4407 case Token::MOD: 4406 case Token::MOD:
4408 // Sign extend eax into edx:eax. 4407 // Sign extend eax into edx:eax.
4409 __ cdq(); 4408 __ cdq();
4410 // Check for 0 divisor. 4409 // Check for 0 divisor.
4411 __ test(ebx, Operand(ebx)); 4410 __ test(ebx, Operand(ebx));
4412 enter()->Branch(zero, not_taken); 4411 BranchTo(zero);
4413 break; 4412 break;
4414 4413
4415 default: 4414 default:
4416 // Fall-through to smi check. 4415 // Fall-through to smi check.
4417 break; 4416 break;
4418 } 4417 }
4419 4418
4420 // Perform the actual smi check. 4419 // Perform the actual smi check.
4421 ASSERT(kSmiTag == 0); // adjust zero check if not the case 4420 ASSERT(kSmiTag == 0); // adjust zero check if not the case
4422 __ test(ecx, Immediate(kSmiTagMask)); 4421 __ test(ecx, Immediate(kSmiTagMask));
4423 enter()->Branch(not_zero, not_taken); 4422 BranchTo(not_zero);
4424 4423
4425 switch (op_) { 4424 switch (op_) {
4426 case Token::ADD: 4425 case Token::ADD:
4427 case Token::SUB: 4426 case Token::SUB:
4428 // Do nothing here. 4427 // Do nothing here.
4429 break; 4428 break;
4430 4429
4431 case Token::MUL: 4430 case Token::MUL:
4432 // If the smi tag is 0 we can just leave the tag on one operand. 4431 // If the smi tag is 0 we can just leave the tag on one operand.
4433 ASSERT(kSmiTag == 0); // adjust code below if not the case 4432 ASSERT(kSmiTag == 0); // adjust code below if not the case
4434 // Remove tag from one of the operands (but keep sign). 4433 // Remove tag from one of the operands (but keep sign).
4435 __ sar(eax, kSmiTagSize); 4434 __ sar(eax, kSmiTagSize);
4436 // Do multiplication. 4435 // Do multiplication.
4437 __ imul(eax, Operand(ebx)); // multiplication of smis; result in eax 4436 __ imul(eax, Operand(ebx)); // multiplication of smis; result in eax
4438 // Go slow on overflows. 4437 // Go slow on overflows.
4439 enter()->Branch(overflow, not_taken); 4438 BranchTo(overflow);
4440 // Check for negative zero result. Use ecx = x | y. 4439 // Check for negative zero result. Use ecx = x | y. NegativeZeroTest
4441 __ NegativeZeroTest(generator(), eax, ecx, enter()); 4440 // must be called after the deferred code has already been branched to
4441 // via BranchTo, because NegativeZeroTest will not set the entry frame
4442 // or register file for the deferred code.
4443 __ NegativeZeroTest(eax, ecx, enter());
4442 break; 4444 break;
4443 4445
4444 case Token::DIV: 4446 case Token::DIV:
4445 // Divide edx:eax by ebx. 4447 // Divide edx:eax by ebx.
4446 __ idiv(ebx); 4448 __ idiv(ebx);
4447 // Check for the corner case of dividing the most negative smi 4449 // Check for the corner case of dividing the most negative smi
4448 // by -1. We cannot use the overflow flag, since it is not set 4450 // by -1. We cannot use the overflow flag, since it is not set
4449 // by idiv instruction. 4451 // by idiv instruction.
4450 ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 4452 ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
4451 __ cmp(eax, 0x40000000); 4453 __ cmp(eax, 0x40000000);
4452 enter()->Branch(equal); 4454 BranchTo(equal);
4453 // Check for negative zero result. Use ecx = x | y. 4455 // Check for negative zero result. Use ecx = x | y. NegativeZeroTest
4454 __ NegativeZeroTest(generator(), eax, ecx, enter()); 4456 // must be called after the deferred code has already been branched to
4457 // via BranchTo, because NegativeZeroTest will not set the entry frame
4458 // or register file for the deferred code.
4459 __ NegativeZeroTest(eax, ecx, enter());
4455 // Check that the remainder is zero. 4460 // Check that the remainder is zero.
4456 __ test(edx, Operand(edx)); 4461 __ test(edx, Operand(edx));
4457 enter()->Branch(not_zero); 4462 BranchTo(not_zero);
4458 // Tag the result and store it in register eax. 4463 // Tag the result and store it in register eax.
4459 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 4464 ASSERT(kSmiTagSize == times_2); // adjust code if not the case
4460 __ lea(eax, Operand(eax, eax, times_1, kSmiTag)); 4465 __ lea(eax, Operand(eax, eax, times_1, kSmiTag));
4461 break; 4466 break;
4462 4467
4463 case Token::MOD: 4468 case Token::MOD:
4464 // Divide edx:eax by ebx. 4469 // Divide edx:eax by ebx.
4465 __ idiv(ebx); 4470 __ idiv(ebx);
4466 // Check for negative zero result. Use ecx = x | y. 4471 // Check for negative zero result. Use ecx = x | y. NegativeZeroTest
4467 __ NegativeZeroTest(generator(), edx, ecx, enter()); 4472 // must be called after the deferred code has already been branched to
4473 // via BranchTo, because NegativeZeroTest will not set the entry frame
4474 // or register file for the deferred code.
4475 __ NegativeZeroTest(edx, ecx, enter());
4468 // Move remainder to register eax. 4476 // Move remainder to register eax.
4469 __ mov(eax, Operand(edx)); 4477 __ mov(eax, Operand(edx));
4470 break; 4478 break;
4471 4479
4472 case Token::BIT_OR: 4480 case Token::BIT_OR:
4473 __ or_(eax, Operand(ebx)); 4481 __ or_(eax, Operand(ebx));
4474 break; 4482 break;
4475 4483
4476 case Token::BIT_AND: 4484 case Token::BIT_AND:
4477 __ and_(eax, Operand(ebx)); 4485 __ and_(eax, Operand(ebx));
(...skipping 19 matching lines...) Expand all
4497 break; 4505 break;
4498 case Token::SHR: 4506 case Token::SHR:
4499 __ shr(eax); 4507 __ shr(eax);
4500 // Check that the *unsigned* result fits in a smi. 4508 // Check that the *unsigned* result fits in a smi.
4501 // Neither of the two high-order bits can be set: 4509 // Neither of the two high-order bits can be set:
4502 // - 0x80000000: high bit would be lost when smi tagging. 4510 // - 0x80000000: high bit would be lost when smi tagging.
4503 // - 0x40000000: this number would convert to negative when 4511 // - 0x40000000: this number would convert to negative when
4504 // Smi tagging these two cases can only happen with shifts 4512 // Smi tagging these two cases can only happen with shifts
4505 // by 0 or 1 when handed a valid smi. 4513 // by 0 or 1 when handed a valid smi.
4506 __ test(eax, Immediate(0xc0000000)); 4514 __ test(eax, Immediate(0xc0000000));
4507 enter()->Branch(not_zero, not_taken); 4515 BranchTo(not_zero);
4508 break; 4516 break;
4509 case Token::SHL: 4517 case Token::SHL:
4510 __ shl(eax); 4518 __ shl(eax);
4511 // Check that the *signed* result fits in a smi. 4519 // Check that the *signed* result fits in a smi.
4512 __ lea(ecx, Operand(eax, 0x40000000)); 4520 __ lea(ecx, Operand(eax, 0x40000000));
4513 __ test(ecx, Immediate(0x80000000)); 4521 __ test(ecx, Immediate(0x80000000));
4514 enter()->Branch(not_zero, not_taken); 4522 BranchTo(not_zero);
4515 break; 4523 break;
4516 default: 4524 default:
4517 UNREACHABLE(); 4525 UNREACHABLE();
4518 } 4526 }
4519 // Tag the result and store it in register eax. 4527 // Tag the result and store it in register eax.
4520 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 4528 ASSERT(kSmiTagSize == times_2); // adjust code if not the case
4521 __ lea(eax, Operand(eax, eax, times_1, kSmiTag)); 4529 __ lea(eax, Operand(eax, eax, times_1, kSmiTag));
4522 break; 4530 break;
4523 4531
4524 default: 4532 default:
(...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after
5692 5700
5693 // Slow-case: Go through the JavaScript implementation. 5701 // Slow-case: Go through the JavaScript implementation.
5694 __ bind(&slow); 5702 __ bind(&slow);
5695 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5703 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5696 } 5704 }
5697 5705
5698 5706
5699 #undef __ 5707 #undef __
5700 5708
5701 } } // namespace v8::internal 5709 } } // namespace v8::internal
OLDNEW
« src/codegen.cc ('K') | « src/codegen.cc ('k') | src/jump-target-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698