OLD | NEW |
---|---|
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 } | 142 } |
143 } | 143 } |
144 | 144 |
145 | 145 |
146 void FastCodeGenerator::VisitAssignment(Assignment* expr) { | 146 void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
147 Comment cmnt(masm_, "[ Assignment"); | 147 Comment cmnt(masm_, "[ Assignment"); |
148 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); | 148 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
149 Expression* rhs = expr->value(); | 149 Expression* rhs = expr->value(); |
150 Visit(rhs); | 150 Visit(rhs); |
151 | 151 |
152 // Left-hand side is always a (parameter or local) slot. | 152 // Left-hand side can only be a global or a (parameter or local) slot. |
153 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 153 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
154 ASSERT(var != NULL && var->slot() != NULL); | 154 ASSERT(var != NULL); |
155 ASSERT(var->is_global() || var->slot() != NULL); | |
155 | 156 |
156 // Complete the assignment based on the location of the right-hand-side | 157 // Complete the assignment based on the location of the right-hand-side |
157 // value and the desired location of the assignment value. | 158 // value and the desired location of the assignment value. |
158 Location destination = expr->location(); | 159 Location destination = expr->location(); |
159 Location source = rhs->location(); | 160 Location source = rhs->location(); |
160 ASSERT(!destination.is_constant()); | 161 ASSERT(!destination.is_constant()); |
161 ASSERT(!source.is_nowhere()); | 162 ASSERT(!source.is_nowhere()); |
162 | 163 |
163 if (source.is_temporary()) { | 164 if (var->is_global()) { |
165 // Assignment to a global variable, use inline caching. Right-hand-side | |
166 // value is passed in eax, variable name in ecx, and the global object | |
167 // on the stack. | |
168 if (source.is_temporary()) { | |
169 __ pop(eax); | |
170 } else { | |
171 ASSERT(source.is_constant()); | |
172 ASSERT(rhs->AsLiteral() != NULL); | |
173 __ mov(eax, rhs->AsLiteral()->handle()); | |
174 } | |
175 __ mov(ecx, var->name()); | |
176 __ push(CodeGenerator::GlobalObject()); | |
177 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | |
178 __ call(ic, RelocInfo::CODE_TARGET); | |
179 // Overwrite the global object on the stack with the result if needed. | |
164 if (destination.is_temporary()) { | 180 if (destination.is_temporary()) { |
165 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary | 181 __ mov(Operand(esp, 0), eax); |
166 // on the stack. | |
167 __ mov(eax, Operand(esp, 0)); | |
168 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | |
169 } else { | 182 } else { |
170 ASSERT(destination.is_nowhere()); | 183 ASSERT(destination.is_nowhere()); |
171 // Case 'var = temp'. Discard right-hand-side temporary. | 184 __ pop(eax); |
fschneider
2009/10/20 13:58:40
We may avoid a memory access when discarding the r
Kevin Millikin (Chromium)
2009/10/20 14:08:48
Yes. I didn't worry about it because:
Here we're
| |
172 __ pop(Operand(ebp, SlotOffset(var->slot()))); | |
173 } | 185 } |
186 | |
174 } else { | 187 } else { |
175 ASSERT(source.is_constant()); | 188 // Local or parameter assignment. |
176 ASSERT(rhs->AsLiteral() != NULL); | 189 if (source.is_temporary()) { |
177 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 190 if (destination.is_temporary()) { |
178 // discarded result. Always perform the assignment. | 191 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side |
179 __ mov(eax, rhs->AsLiteral()->handle()); | 192 // temporary on the stack. |
180 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | 193 __ mov(eax, Operand(esp, 0)); |
181 if (destination.is_temporary()) { | 194 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); |
182 // Case 'temp <- (var = constant)'. Save result. | 195 } else { |
183 __ push(eax); | 196 ASSERT(destination.is_nowhere()); |
197 // Case 'var = temp'. Discard right-hand-side temporary. | |
198 __ pop(Operand(ebp, SlotOffset(var->slot()))); | |
199 } | |
200 } else { | |
201 ASSERT(source.is_constant()); | |
202 ASSERT(rhs->AsLiteral() != NULL); | |
203 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | |
204 // discarded result. Always perform the assignment. | |
205 __ mov(eax, rhs->AsLiteral()->handle()); | |
206 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); | |
207 if (destination.is_temporary()) { | |
208 // Case 'temp <- (var = constant)'. Save result. | |
209 __ push(eax); | |
210 } | |
184 } | 211 } |
185 } | 212 } |
186 } | 213 } |
187 | 214 |
188 | 215 |
189 } } // namespace v8::internal | 216 } } // namespace v8::internal |
OLD | NEW |