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

Side by Side Diff: src/arm/fast-codegen-arm.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/arm/codegen-arm.cc ('k') | src/compiler.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. The actual 40 // and arguments have been pushed on the stack left to right. The actual
40 // argument count matches the formal parameter count expected by the 41 // argument count matches the formal parameter count expected by the
41 // function. 42 // function.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 __ ldm(ia_w, sp, fp.bit() | lr.bit()); 104 __ ldm(ia_w, sp, fp.bit() | lr.bit());
104 int num_parameters = function_->scope()->num_parameters(); 105 int num_parameters = function_->scope()->num_parameters();
105 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize)); 106 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize));
106 __ Jump(lr); 107 __ Jump(lr);
107 } 108 }
108 } 109 }
109 110
110 111
111 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 112 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
112 // Call the runtime to declare the globals. 113 // Call the runtime to declare the globals.
113 __ mov(r0, Operand(pairs)); 114 // The context is the first argument.
114 __ push(r0); 115 __ mov(r1, Operand(pairs));
115 __ push(cp); // The context is the second argument.
116 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0))); 116 __ mov(r0, Operand(Smi::FromInt(is_eval_ ? 1 : 0)));
117 __ push(r0); 117 __ stm(db_w, sp, cp.bit() | r1.bit() | r0.bit());
118 __ CallRuntime(Runtime::kDeclareGlobals, 3); 118 __ CallRuntime(Runtime::kDeclareGlobals, 3);
119 // Return value is ignored. 119 // Return value is ignored.
120 } 120 }
121 121
122 122
123 void FastCodeGenerator::VisitBlock(Block* stmt) { 123 void FastCodeGenerator::VisitBlock(Block* stmt) {
124 Comment cmnt(masm_, "[ Block"); 124 Comment cmnt(masm_, "[ Block");
125 SetStatementPosition(stmt); 125 SetStatementPosition(stmt);
126 VisitStatements(stmt->statements()); 126 VisitStatements(stmt->statements());
127 } 127 }
(...skipping 18 matching lines...) Expand all
146 if (source.is_temporary()) { 146 if (source.is_temporary()) {
147 __ pop(r0); 147 __ pop(r0);
148 } else { 148 } else {
149 ASSERT(source.is_constant()); 149 ASSERT(source.is_constant());
150 ASSERT(expr->AsLiteral() != NULL); 150 ASSERT(expr->AsLiteral() != NULL);
151 __ mov(r0, Operand(expr->AsLiteral()->handle())); 151 __ mov(r0, Operand(expr->AsLiteral()->handle()));
152 } 152 }
153 __ RecordJSReturn(); 153 __ RecordJSReturn();
154 __ mov(sp, fp); 154 __ mov(sp, fp);
155 __ ldm(ia_w, sp, fp.bit() | lr.bit()); 155 __ ldm(ia_w, sp, fp.bit() | lr.bit());
156 int num_parameters = function_->scope()->num_parameters(); 156 int num_parameters = function_->scope()->num_parameters();
157 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize)); 157 __ add(sp, sp, Operand((num_parameters + 1) * kPointerSize));
158 __ Jump(lr); 158 __ Jump(lr);
159 } 159 }
160 160
161 161
162 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 162 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
163 Comment cmnt(masm_, "[ FunctionLiteral"); 163 Comment cmnt(masm_, "[ FunctionLiteral");
164 164
165 // Build the function boilerplate and instantiate it. 165 // Build the function boilerplate and instantiate it.
166 Handle<JSFunction> boilerplate = BuildBoilerplate(expr); 166 Handle<JSFunction> boilerplate = BuildBoilerplate(expr);
167 if (HasStackOverflow()) return; 167 if (HasStackOverflow()) return;
168 168
169 ASSERT(boilerplate->IsBoilerplate()); 169 ASSERT(boilerplate->IsBoilerplate());
170 170
171 // Create a new closure. 171 // Create a new closure.
172 __ mov(r0, Operand(boilerplate)); 172 __ mov(r0, Operand(boilerplate));
173 __ push(r0); 173 __ stm(db_w, sp, cp.bit() | r0.bit());
174 __ push(cp);
175 __ CallRuntime(Runtime::kNewClosure, 2); 174 __ CallRuntime(Runtime::kNewClosure, 2);
176 175
177 if (expr->location().is_temporary()) { 176 if (expr->location().is_temporary()) {
178 __ push(r0); 177 __ push(r0);
179 } else { 178 } else {
180 ASSERT(expr->location().is_nowhere()); 179 ASSERT(expr->location().is_nowhere());
181 } 180 }
182 } 181 }
183 182
184 183
(...skipping 24 matching lines...) Expand all
209 if (expr->location().is_temporary()) { 208 if (expr->location().is_temporary()) {
210 __ ldr(ip, MemOperand(fp, SlotOffset(slot))); 209 __ ldr(ip, MemOperand(fp, SlotOffset(slot)));
211 __ push(ip); 210 __ push(ip);
212 } else { 211 } else {
213 ASSERT(expr->location().is_nowhere()); 212 ASSERT(expr->location().is_nowhere());
214 } 213 }
215 } 214 }
216 } 215 }
217 216
218 217
218 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
219 Comment cmnt(masm_, "[ ArrayLiteral");
220 Label make_clone;
221
222 // Fetch the function's literals array.
223 __ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
224 __ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
225 // Check if the literal's boilerplate has been instantiated.
226 int offset =
227 FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize);
228 __ ldr(r0, FieldMemOperand(r3, offset));
229 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
230 __ cmp(r0, ip);
231 __ b(&make_clone, ne);
232
233 // Instantiate the boilerplate.
234 __ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
235 __ mov(r1, Operand(expr->literals()));
236 __ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit());
237 __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
238
239 __ bind(&make_clone);
240 // Clone the boilerplate.
241 __ push(r0);
242 if (expr->depth() > 1) {
243 __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
244 } else {
245 __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
246 }
247
248 bool result_saved = false; // Is the result saved to the stack?
249
250 // Emit code to evaluate all the non-constant subexpressions and to store
251 // them into the newly cloned array.
252 ZoneList<Expression*>* subexprs = expr->values();
253 for (int i = 0, len = subexprs->length(); i < len; i++) {
254 Expression* subexpr = subexprs->at(i);
255 // If the subexpression is a literal or a simple materialized literal it
256 // is already set in the cloned array.
257 if (subexpr->AsLiteral() != NULL ||
258 CompileTimeValue::IsCompileTimeValue(subexpr)) {
259 continue;
260 }
261
262 if (!result_saved) {
263 __ push(r0);
264 result_saved = true;
265 }
266 Visit(subexpr);
267 ASSERT(subexpr->location().is_temporary());
268
269 // Store the subexpression value in the array's elements.
270 __ pop(r0); // Subexpression value.
271 __ ldr(r1, MemOperand(sp)); // Copy of array literal.
272 __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset));
273 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
274 __ str(r0, FieldMemOperand(r1, offset));
275
276 // Update the write barrier for the array store with r0 as the scratch
277 // register.
278 __ mov(r2, Operand(offset));
279 __ RecordWrite(r1, r2, r0);
280 }
281
282 Location destination = expr->location();
283 if (destination.is_nowhere() && result_saved) {
284 __ pop();
285 } else if (destination.is_temporary() && !result_saved) {
286 __ push(r0);
287 }
288 }
289
290
219 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 291 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
220 Comment cmnt(masm_, "[ Assignment"); 292 Comment cmnt(masm_, "[ Assignment");
221 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); 293 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR);
222 Expression* rhs = expr->value(); 294 Expression* rhs = expr->value();
223 Visit(rhs); 295 Visit(rhs);
224 296
225 // Left-hand side can only be a global or a (parameter or local) slot. 297 // Left-hand side can only be a global or a (parameter or local) slot.
226 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 298 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
227 ASSERT(var != NULL); 299 ASSERT(var != NULL);
228 ASSERT(var->is_global() || var->slot() != NULL); 300 ASSERT(var->is_global() || var->slot() != NULL);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 359
288 360
289 void FastCodeGenerator::VisitCall(Call* expr) { 361 void FastCodeGenerator::VisitCall(Call* expr) {
290 Comment cmnt(masm_, "[ Call"); 362 Comment cmnt(masm_, "[ Call");
291 Expression* fun = expr->expression(); 363 Expression* fun = expr->expression();
292 ZoneList<Expression*>* args = expr->arguments(); 364 ZoneList<Expression*>* args = expr->arguments();
293 Variable* var = fun->AsVariableProxy()->AsVariable(); 365 Variable* var = fun->AsVariableProxy()->AsVariable();
294 ASSERT(var != NULL && !var->is_this() && var->is_global()); 366 ASSERT(var != NULL && !var->is_this() && var->is_global());
295 ASSERT(!var->is_possibly_eval()); 367 ASSERT(!var->is_possibly_eval());
296 368
297 __ mov(r0, Operand(var->name())); 369 __ mov(r1, Operand(var->name()));
298 __ push(r0); 370 // Push global object as receiver.
299 // Push global object (receiver)
300 __ ldr(r0, CodeGenerator::GlobalObject()); 371 __ ldr(r0, CodeGenerator::GlobalObject());
301 __ push(r0); 372 __ stm(db_w, sp, r1.bit() | r0.bit());
302 int arg_count = args->length(); 373 int arg_count = args->length();
303 for (int i = 0; i < arg_count; i++) { 374 for (int i = 0; i < arg_count; i++) {
304 Visit(args->at(i)); 375 Visit(args->at(i));
305 ASSERT(!args->at(i)->location().is_nowhere()); 376 ASSERT(!args->at(i)->location().is_nowhere());
306 if (args->at(i)->location().is_constant()) { 377 if (args->at(i)->location().is_constant()) {
307 ASSERT(args->at(i)->AsLiteral() != NULL); 378 ASSERT(args->at(i)->AsLiteral() != NULL);
308 __ mov(r0, Operand(args->at(i)->AsLiteral()->handle())); 379 __ mov(r0, Operand(args->at(i)->AsLiteral()->handle()));
309 __ push(r0); 380 __ push(r0);
310 } 381 }
311 } 382 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 __ CallRuntime(function, arg_count); 419 __ CallRuntime(function, arg_count);
349 if (expr->location().is_temporary()) { 420 if (expr->location().is_temporary()) {
350 __ push(r0); 421 __ push(r0);
351 } else { 422 } else {
352 ASSERT(expr->location().is_nowhere()); 423 ASSERT(expr->location().is_nowhere());
353 } 424 }
354 } 425 }
355 426
356 427
357 } } // namespace v8::internal 428 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/codegen-arm.cc ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698