OLD | NEW |
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 957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
968 masm->CallRuntime(Runtime::kStoreContextSlot, 3); | 968 masm->CallRuntime(Runtime::kStoreContextSlot, 3); |
969 } | 969 } |
970 // Storing a variable must keep the (new) value on the expression | 970 // Storing a variable must keep the (new) value on the expression |
971 // stack. This is necessary for compiling assignment expressions. | 971 // stack. This is necessary for compiling assignment expressions. |
972 masm->push(eax); | 972 masm->push(eax); |
973 | 973 |
974 } else { | 974 } else { |
975 ASSERT(var()->mode() != Variable::DYNAMIC); | 975 ASSERT(var()->mode() != Variable::DYNAMIC); |
976 | 976 |
977 Label exit; | 977 Label exit; |
| 978 bool skipped_write = false; |
978 if (init_state == CONST_INIT) { | 979 if (init_state == CONST_INIT) { |
979 ASSERT(var()->mode() == Variable::CONST); | 980 ASSERT(var()->mode() == Variable::CONST); |
980 // Only the first const initialization must be executed (the slot | 981 // Only the first const initialization must be executed (the slot |
981 // still contains 'the hole' value). When the assignment is executed, | 982 // still contains 'the hole' value). When the assignment is executed, |
982 // the code is identical to a normal store (see below). | 983 // the code is identical to a normal store (see below). |
983 Comment cmnt(masm, "[ Init const"); | 984 Comment cmnt(masm, "[ Init const"); |
984 masm->mov(eax, Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx)); | 985 masm->mov(eax, Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx)); |
985 masm->cmp(eax, Factory::the_hole_value()); | 986 masm->cmp(eax, Factory::the_hole_value()); |
986 masm->j(not_equal, &exit); | 987 masm->j(not_equal, &exit); |
| 988 skipped_write = true; |
987 } | 989 } |
988 | 990 |
989 // We must execute the store. | 991 // We must execute the store. |
990 // Storing a variable must keep the (new) value on the stack. This is | 992 // Storing a variable must keep the (new) value on the stack. This is |
991 // necessary for compiling assignment expressions. ecx may be loaded | 993 // necessary for compiling assignment expressions. ecx may be loaded |
992 // with context; used below in RecordWrite. | 994 // with context; used below in RecordWrite. |
993 // | 995 // |
994 // Note: We will reach here even with node->var()->mode() == | 996 // Note: We will reach here even with node->var()->mode() == |
995 // Variable::CONST because of const declarations which will initialize | 997 // Variable::CONST because of const declarations which will initialize |
996 // consts to 'the hole' value and by doing so, end up calling this | 998 // consts to 'the hole' value and by doing so, end up calling this |
997 // code. | 999 // code. |
998 masm->pop(eax); | 1000 masm->pop(eax); |
999 masm->mov(Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx), eax); | 1001 masm->mov(Ia32CodeGenerator::SlotOperand(masm, scope, this, ecx), eax); |
1000 masm->push(eax); // RecordWrite may destroy the value in eax. | 1002 masm->push(eax); // RecordWrite may destroy the value in eax. |
1001 if (type() == Slot::CONTEXT) { | 1003 if (type() == Slot::CONTEXT) { |
1002 // ecx is loaded with context when calling SlotOperand above. | 1004 // ecx is loaded with context when calling SlotOperand above. |
1003 int offset = FixedArray::kHeaderSize + index() * kPointerSize; | 1005 int offset = FixedArray::kHeaderSize + index() * kPointerSize; |
1004 masm->RecordWrite(ecx, offset, eax, ebx); | 1006 masm->RecordWrite(ecx, offset, eax, ebx); |
1005 } | 1007 } |
1006 masm->bind(&exit); | 1008 // If we did not jump over the assignment, we do not need to bind the |
| 1009 // exit label. Doing so can defeat peephole optimization. |
| 1010 if (skipped_write) masm->bind(&exit); |
1007 } | 1011 } |
1008 } | 1012 } |
1009 | 1013 |
1010 | 1014 |
1011 #undef __ | 1015 #undef __ |
1012 #define __ masm-> | 1016 #define __ masm-> |
1013 | 1017 |
1014 class ToBooleanStub: public CodeStub { | 1018 class ToBooleanStub: public CodeStub { |
1015 public: | 1019 public: |
1016 ToBooleanStub() { } | 1020 ToBooleanStub() { } |
(...skipping 4427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5444 bool is_eval) { | 5448 bool is_eval) { |
5445 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); | 5449 Handle<Code> code = Ia32CodeGenerator::MakeCode(fun, script, is_eval); |
5446 if (!code.is_null()) { | 5450 if (!code.is_null()) { |
5447 Counters::total_compiled_code_size.Increment(code->instruction_size()); | 5451 Counters::total_compiled_code_size.Increment(code->instruction_size()); |
5448 } | 5452 } |
5449 return code; | 5453 return code; |
5450 } | 5454 } |
5451 | 5455 |
5452 | 5456 |
5453 } } // namespace v8::internal | 5457 } } // namespace v8::internal |
OLD | NEW |