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

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

Issue 303021: Added support for array literals to the toplevel compiler. They are... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 2 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/runtime.cc » ('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 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 11 matching lines...) Expand all
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "codegen-inl.h" 30 #include "codegen-inl.h"
31 #include "fast-codegen.h" 31 #include "fast-codegen.h"
32 #include "parser.h"
32 33
33 namespace v8 { 34 namespace v8 {
34 namespace internal { 35 namespace internal {
35 36
36 #define __ ACCESS_MASM(masm_) 37 #define __ ACCESS_MASM(masm_)
37 38
38 // Generate code for a JS function. On entry to the function the receiver 39 // Generate code for a JS function. On entry to the function the receiver
39 // and arguments have been pushed on the stack left to right, with the 40 // and arguments have been pushed on the stack left to right, with the
40 // return address on top of them. The actual argument count matches the 41 // return address on top of them. The actual argument count matches the
41 // formal parameter count expected by the function. 42 // formal parameter count expected by the function.
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 // patch with the code required by the debugger. 94 // patch with the code required by the debugger.
94 __ mov(esp, ebp); 95 __ mov(esp, ebp);
95 __ pop(ebp); 96 __ pop(ebp);
96 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize); 97 __ ret((fun->scope()->num_parameters() + 1) * kPointerSize);
97 } 98 }
98 } 99 }
99 100
100 101
101 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 102 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
102 // Call the runtime to declare the globals. 103 // Call the runtime to declare the globals.
104 __ push(esi); // The context is the first argument.
103 __ push(Immediate(pairs)); 105 __ push(Immediate(pairs));
104 __ push(esi); // The context is the second argument.
105 __ push(Immediate(Smi::FromInt(is_eval_ ? 1 : 0))); 106 __ push(Immediate(Smi::FromInt(is_eval_ ? 1 : 0)));
106 __ CallRuntime(Runtime::kDeclareGlobals, 3); 107 __ CallRuntime(Runtime::kDeclareGlobals, 3);
107 // Return value is ignored. 108 // Return value is ignored.
108 } 109 }
109 110
110 111
111 void FastCodeGenerator::VisitBlock(Block* stmt) { 112 void FastCodeGenerator::VisitBlock(Block* stmt) {
112 Comment cmnt(masm_, "[ Block"); 113 Comment cmnt(masm_, "[ Block");
113 SetStatementPosition(stmt); 114 SetStatementPosition(stmt);
114 VisitStatements(stmt->statements()); 115 VisitStatements(stmt->statements());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 151 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
151 Comment cmnt(masm_, "[ FunctionLiteral"); 152 Comment cmnt(masm_, "[ FunctionLiteral");
152 153
153 // Build the function boilerplate and instantiate it. 154 // Build the function boilerplate and instantiate it.
154 Handle<JSFunction> boilerplate = BuildBoilerplate(expr); 155 Handle<JSFunction> boilerplate = BuildBoilerplate(expr);
155 if (HasStackOverflow()) return; 156 if (HasStackOverflow()) return;
156 157
157 ASSERT(boilerplate->IsBoilerplate()); 158 ASSERT(boilerplate->IsBoilerplate());
158 159
159 // Create a new closure. 160 // Create a new closure.
161 __ push(esi);
160 __ push(Immediate(boilerplate)); 162 __ push(Immediate(boilerplate));
161 __ push(esi);
162 __ CallRuntime(Runtime::kNewClosure, 2); 163 __ CallRuntime(Runtime::kNewClosure, 2);
163 164
164 if (expr->location().is_temporary()) { 165 if (expr->location().is_temporary()) {
165 __ push(eax); 166 __ push(eax);
166 } else { 167 } else {
167 ASSERT(expr->location().is_nowhere()); 168 ASSERT(expr->location().is_nowhere());
168 } 169 }
169 } 170 }
170 171
171 172
(...skipping 11 matching lines...) Expand all
183 184
184 // A test eax instruction following the call is used by the IC to 185 // A test eax instruction following the call is used by the IC to
185 // indicate that the inobject property case was inlined. Ensure there 186 // indicate that the inobject property case was inlined. Ensure there
186 // is no test eax instruction here. Remember that the assembler may 187 // is no test eax instruction here. Remember that the assembler may
187 // choose to do peephole optimization (eg, push/pop elimination). 188 // choose to do peephole optimization (eg, push/pop elimination).
188 if (expr->location().is_temporary()) { 189 if (expr->location().is_temporary()) {
189 // Replace the global object with the result. 190 // Replace the global object with the result.
190 __ mov(Operand(esp, 0), eax); 191 __ mov(Operand(esp, 0), eax);
191 } else { 192 } else {
192 ASSERT(expr->location().is_nowhere()); 193 ASSERT(expr->location().is_nowhere());
193 __ pop(eax); 194 __ add(Operand(esp), Immediate(kPointerSize));
194 } 195 }
195 196
196 } else { 197 } else {
197 Comment cmnt(masm_, "Stack slot"); 198 Comment cmnt(masm_, "Stack slot");
198 Slot* slot = rewrite->AsSlot(); 199 Slot* slot = rewrite->AsSlot();
199 ASSERT(slot != NULL); 200 ASSERT(slot != NULL);
200 if (expr->location().is_temporary()) { 201 if (expr->location().is_temporary()) {
201 __ push(Operand(ebp, SlotOffset(slot))); 202 __ push(Operand(ebp, SlotOffset(slot)));
202 } else { 203 } else {
203 ASSERT(expr->location().is_nowhere()); 204 ASSERT(expr->location().is_nowhere());
204 } 205 }
205 } 206 }
206 } 207 }
207 208
208 209
210 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
211 Comment cmnt(masm_, "[ ArrayLiteral");
212 Label make_clone;
213
214 // Fetch the function's literals array.
215 __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
216 __ mov(ebx, FieldOperand(ebx, JSFunction::kLiteralsOffset));
217 // Check if the literal's boilerplate has been instantiated.
218 int offset =
219 FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize);
220 __ mov(eax, FieldOperand(ebx, offset));
221 __ cmp(eax, Factory::undefined_value());
222 __ j(not_equal, &make_clone);
223
224 // Instantiate the boilerplate.
225 __ push(ebx);
226 __ push(Immediate(Smi::FromInt(expr->literal_index())));
227 __ push(Immediate(expr->literals()));
228 __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
229
230 __ bind(&make_clone);
231 // Clone the boilerplate.
232 __ push(eax);
233 if (expr->depth() > 1) {
234 __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
235 } else {
236 __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
237 }
238
239 bool result_saved = false; // Is the result saved to the stack?
240
241 // Emit code to evaluate all the non-constant subexpressions and to store
242 // them into the newly cloned array.
243 ZoneList<Expression*>* subexprs = expr->values();
244 for (int i = 0, len = subexprs->length(); i < len; i++) {
245 Expression* subexpr = subexprs->at(i);
246 // If the subexpression is a literal or a simple materialized literal it
247 // is already set in the cloned array.
248 if (subexpr->AsLiteral() != NULL ||
249 CompileTimeValue::IsCompileTimeValue(subexpr)) {
250 continue;
251 }
252
253 if (!result_saved) {
254 __ push(eax);
255 result_saved = true;
256 }
257 Visit(subexpr);
258 ASSERT(subexpr->location().is_temporary());
259
260 // Store the subexpression value in the array's elements.
261 __ pop(eax); // Subexpression value.
262 __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
263 __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
264 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
265 __ mov(FieldOperand(ebx, offset), eax);
266
267 // Update the write barrier for the array store.
268 __ RecordWrite(ebx, offset, eax, ecx);
269 }
270
271 Location destination = expr->location();
272 if (destination.is_nowhere() && result_saved) {
273 __ add(Operand(esp), Immediate(kPointerSize));
274 } else if (destination.is_temporary() && !result_saved) {
275 __ push(eax);
276 }
277 }
278
279
209 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 280 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
210 Comment cmnt(masm_, "[ Assignment"); 281 Comment cmnt(masm_, "[ Assignment");
211 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); 282 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR);
212 Expression* rhs = expr->value(); 283 Expression* rhs = expr->value();
213 Visit(rhs); 284 Visit(rhs);
214 285
215 // Left-hand side can only be a global or a (parameter or local) slot. 286 // Left-hand side can only be a global or a (parameter or local) slot.
216 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 287 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
217 ASSERT(var != NULL); 288 ASSERT(var != NULL);
218 ASSERT(var->is_global() || var->slot() != NULL); 289 ASSERT(var->is_global() || var->slot() != NULL);
(...skipping 18 matching lines...) Expand all
237 } 308 }
238 __ mov(ecx, var->name()); 309 __ mov(ecx, var->name());
239 __ push(CodeGenerator::GlobalObject()); 310 __ push(CodeGenerator::GlobalObject());
240 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 311 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
241 __ call(ic, RelocInfo::CODE_TARGET); 312 __ call(ic, RelocInfo::CODE_TARGET);
242 // Overwrite the global object on the stack with the result if needed. 313 // Overwrite the global object on the stack with the result if needed.
243 if (destination.is_temporary()) { 314 if (destination.is_temporary()) {
244 __ mov(Operand(esp, 0), eax); 315 __ mov(Operand(esp, 0), eax);
245 } else { 316 } else {
246 ASSERT(destination.is_nowhere()); 317 ASSERT(destination.is_nowhere());
247 __ pop(eax); 318 __ add(Operand(esp), Immediate(kPointerSize));
248 } 319 }
249 320
250 } else { 321 } else {
251 // Local or parameter assignment. 322 // Local or parameter assignment.
252 if (source.is_temporary()) { 323 if (source.is_temporary()) {
253 if (destination.is_temporary()) { 324 if (destination.is_temporary()) {
254 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side 325 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
255 // temporary on the stack. 326 // temporary on the stack.
256 __ mov(eax, Operand(esp, 0)); 327 __ mov(eax, Operand(esp, 0));
257 __ mov(Operand(ebp, SlotOffset(var->slot())), eax); 328 __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 372 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
302 NOT_IN_LOOP); 373 NOT_IN_LOOP);
303 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 374 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
304 // Restore context register. 375 // Restore context register.
305 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 376 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
306 // Discard the function left on TOS. 377 // Discard the function left on TOS.
307 if (expr->location().is_temporary()) { 378 if (expr->location().is_temporary()) {
308 __ mov(Operand(esp, 0), eax); 379 __ mov(Operand(esp, 0), eax);
309 } else { 380 } else {
310 ASSERT(expr->location().is_nowhere()); 381 ASSERT(expr->location().is_nowhere());
311 __ pop(eax); 382 __ add(Operand(esp), Immediate(kPointerSize));
312 } 383 }
313 } 384 }
314 385
315 386
316 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 387 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
317 Comment cmnt(masm_, "[ CallRuntime"); 388 Comment cmnt(masm_, "[ CallRuntime");
318 ZoneList<Expression*>* args = expr->arguments(); 389 ZoneList<Expression*>* args = expr->arguments();
319 Runtime::Function* function = expr->function(); 390 Runtime::Function* function = expr->function();
320 391
321 ASSERT(function != NULL); 392 ASSERT(function != NULL);
(...skipping 12 matching lines...) Expand all
334 __ CallRuntime(function, arg_count); 405 __ CallRuntime(function, arg_count);
335 if (expr->location().is_temporary()) { 406 if (expr->location().is_temporary()) {
336 __ push(eax); 407 __ push(eax);
337 } else { 408 } else {
338 ASSERT(expr->location().is_nowhere()); 409 ASSERT(expr->location().is_nowhere());
339 } 410 }
340 } 411 }
341 412
342 413
343 } } // namespace v8::internal 414 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698