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

Side by Side Diff: src/x64/fast-codegen-x64.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/x64/codegen-x64.cc ('k') | test/mjsunit/compiler/literals.js » ('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 12 matching lines...) Expand all
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 "debug.h" 31 #include "debug.h"
32 #include "fast-codegen.h" 32 #include "fast-codegen.h"
33 #include "parser.h"
33 34
34 namespace v8 { 35 namespace v8 {
35 namespace internal { 36 namespace internal {
36 37
37 #define __ ACCESS_MASM(masm_) 38 #define __ ACCESS_MASM(masm_)
38 39
39 // Generate code for a JS function. On entry to the function the receiver 40 // Generate code for a JS function. On entry to the function the receiver
40 // and arguments have been pushed on the stack left to right, with the 41 // and arguments have been pushed on the stack left to right, with the
41 // return address on top of them. The actual argument count matches the 42 // return address on top of them. The actual argument count matches the
42 // formal parameter count expected by the function. 43 // formal parameter count expected by the function.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 for (int i = 0; i < kPadding; ++i) { 102 for (int i = 0; i < kPadding; ++i) {
102 masm_->int3(); 103 masm_->int3();
103 } 104 }
104 #endif 105 #endif
105 } 106 }
106 } 107 }
107 108
108 109
109 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 110 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
110 // Call the runtime to declare the globals. 111 // Call the runtime to declare the globals.
112 __ push(rsi); // The context is the first argument.
111 __ Push(pairs); 113 __ Push(pairs);
112 __ push(rsi); // The context is the second argument.
113 __ Push(Smi::FromInt(is_eval_ ? 1 : 0)); 114 __ Push(Smi::FromInt(is_eval_ ? 1 : 0));
114 __ CallRuntime(Runtime::kDeclareGlobals, 3); 115 __ CallRuntime(Runtime::kDeclareGlobals, 3);
115 // Return value is ignored. 116 // Return value is ignored.
116 } 117 }
117 118
118 119
119 void FastCodeGenerator::VisitBlock(Block* stmt) { 120 void FastCodeGenerator::VisitBlock(Block* stmt) {
120 Comment cmnt(masm_, "[ Block"); 121 Comment cmnt(masm_, "[ Block");
121 SetStatementPosition(stmt); 122 SetStatementPosition(stmt);
122 VisitStatements(stmt->statements()); 123 VisitStatements(stmt->statements());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { 168 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
168 Comment cmnt(masm_, "[ FunctionLiteral"); 169 Comment cmnt(masm_, "[ FunctionLiteral");
169 170
170 // Build the function boilerplate and instantiate it. 171 // Build the function boilerplate and instantiate it.
171 Handle<JSFunction> boilerplate = BuildBoilerplate(expr); 172 Handle<JSFunction> boilerplate = BuildBoilerplate(expr);
172 if (HasStackOverflow()) return; 173 if (HasStackOverflow()) return;
173 174
174 ASSERT(boilerplate->IsBoilerplate()); 175 ASSERT(boilerplate->IsBoilerplate());
175 176
176 // Create a new closure. 177 // Create a new closure.
178 __ push(rsi);
177 __ Push(boilerplate); 179 __ Push(boilerplate);
178 __ push(rsi);
179 __ CallRuntime(Runtime::kNewClosure, 2); 180 __ CallRuntime(Runtime::kNewClosure, 2);
180 181
181 if (expr->location().is_temporary()) { 182 if (expr->location().is_temporary()) {
182 __ push(rax); 183 __ push(rax);
183 } else { 184 } else {
184 ASSERT(expr->location().is_nowhere()); 185 ASSERT(expr->location().is_nowhere());
185 } 186 }
186 } 187 }
187 188
188 189
(...skipping 10 matching lines...) Expand all
199 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); 200 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
200 201
201 // A test rax instruction following the call is used by the IC to 202 // A test rax instruction following the call is used by the IC to
202 // indicate that the inobject property case was inlined. Ensure there 203 // indicate that the inobject property case was inlined. Ensure there
203 // is no test rax instruction here. 204 // is no test rax instruction here.
204 if (expr->location().is_temporary()) { 205 if (expr->location().is_temporary()) {
205 // Replace the global object with the result. 206 // Replace the global object with the result.
206 __ movq(Operand(rsp, 0), rax); 207 __ movq(Operand(rsp, 0), rax);
207 } else { 208 } else {
208 ASSERT(expr->location().is_nowhere()); 209 ASSERT(expr->location().is_nowhere());
209 __ pop(rax); 210 __ addq(rsp, Immediate(kPointerSize));
210 } 211 }
211 212
212 } else { 213 } else {
213 Comment cmnt(masm_, "Stack slot"); 214 Comment cmnt(masm_, "Stack slot");
214 Slot* slot = rewrite->AsSlot(); 215 Slot* slot = rewrite->AsSlot();
215 ASSERT(slot != NULL); 216 ASSERT(slot != NULL);
216 if (expr->location().is_temporary()) { 217 if (expr->location().is_temporary()) {
217 __ push(Operand(rbp, SlotOffset(slot))); 218 __ push(Operand(rbp, SlotOffset(slot)));
218 } else { 219 } else {
219 ASSERT(expr->location().is_nowhere()); 220 ASSERT(expr->location().is_nowhere());
220 } 221 }
221 } 222 }
222 } 223 }
223 224
224 225
226 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
227 Comment cmnt(masm_, "[ ArrayLiteral");
228 Label make_clone;
229
230 // Fetch the function's literals array.
231 __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
232 __ movq(rbx, FieldOperand(rbx, JSFunction::kLiteralsOffset));
233 // Check if the literal's boilerplate has been instantiated.
234 int offset =
235 FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize);
236 __ movq(rax, FieldOperand(rbx, offset));
237 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
238 __ j(not_equal, &make_clone);
239
240 // Instantiate the boilerplate.
241 __ push(rbx);
242 __ Push(Smi::FromInt(expr->literal_index()));
243 __ Push(expr->literals());
244 __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
245
246 __ bind(&make_clone);
247 // Clone the boilerplate.
248 __ push(rax);
249 if (expr->depth() > 1) {
250 __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
251 } else {
252 __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
253 }
254
255 bool result_saved = false; // Is the result saved to the stack?
256
257 // Emit code to evaluate all the non-constant subexpressions and to store
258 // them into the newly cloned array.
259 ZoneList<Expression*>* subexprs = expr->values();
260 for (int i = 0, len = subexprs->length(); i < len; i++) {
261 Expression* subexpr = subexprs->at(i);
262 // If the subexpression is a literal or a simple materialized literal it
263 // is already set in the cloned array.
264 if (subexpr->AsLiteral() != NULL ||
265 CompileTimeValue::IsCompileTimeValue(subexpr)) {
266 continue;
267 }
268
269 if (!result_saved) {
270 __ push(rax);
271 result_saved = true;
272 }
273 Visit(subexpr);
274 ASSERT(subexpr->location().is_temporary());
275
276 // Store the subexpression value in the array's elements.
277 __ pop(rax); // Subexpression value.
278 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal.
279 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset));
280 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
281 __ movq(FieldOperand(rbx, offset), rax);
282
283 // Update the write barrier for the array store.
284 __ RecordWrite(rbx, offset, rax, rcx);
285 }
286
287 Location destination = expr->location();
288 if (destination.is_nowhere() && result_saved) {
289 __ addq(rsp, Immediate(kPointerSize));
290 } else if (destination.is_temporary() && !result_saved) {
291 __ push(rax);
292 }
293 }
294
295
225 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 296 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
226 Comment cmnt(masm_, "[ Assignment"); 297 Comment cmnt(masm_, "[ Assignment");
227 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); 298 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR);
228 Expression* rhs = expr->value(); 299 Expression* rhs = expr->value();
229 Visit(rhs); 300 Visit(rhs);
230 301
231 // Left-hand side can only be a global or a (parameter or local) slot. 302 // Left-hand side can only be a global or a (parameter or local) slot.
232 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 303 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
233 ASSERT(var != NULL); 304 ASSERT(var != NULL);
234 ASSERT(var->is_global() || var->slot() != NULL); 305 ASSERT(var->is_global() || var->slot() != NULL);
(...skipping 17 matching lines...) Expand all
252 __ Move(rax, rhs->AsLiteral()->handle()); 323 __ Move(rax, rhs->AsLiteral()->handle());
253 } 324 }
254 __ Move(rcx, var->name()); 325 __ Move(rcx, var->name());
255 __ push(CodeGenerator::GlobalObject()); 326 __ push(CodeGenerator::GlobalObject());
256 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 327 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
257 __ Call(ic, RelocInfo::CODE_TARGET); 328 __ Call(ic, RelocInfo::CODE_TARGET);
258 // Overwrite the global object on the stack with the result if needed. 329 // Overwrite the global object on the stack with the result if needed.
259 if (destination.is_temporary()) { 330 if (destination.is_temporary()) {
260 __ movq(Operand(rsp, 0), rax); 331 __ movq(Operand(rsp, 0), rax);
261 } else { 332 } else {
262 __ pop(rax); 333 __ addq(rsp, Immediate(kPointerSize));
263 } 334 }
264 } else { 335 } else {
265 if (source.is_temporary()) { 336 if (source.is_temporary()) {
266 if (destination.is_temporary()) { 337 if (destination.is_temporary()) {
267 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary 338 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary
268 // on the stack. 339 // on the stack.
269 __ movq(kScratchRegister, Operand(rsp, 0)); 340 __ movq(kScratchRegister, Operand(rsp, 0));
270 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); 341 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
271 } else { 342 } else {
272 ASSERT(destination.is_nowhere()); 343 ASSERT(destination.is_nowhere());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 385 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
315 NOT_IN_LOOP); 386 NOT_IN_LOOP);
316 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 387 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
317 // Restore context register. 388 // Restore context register.
318 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 389 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
319 // Discard the function left on TOS. 390 // Discard the function left on TOS.
320 if (expr->location().is_temporary()) { 391 if (expr->location().is_temporary()) {
321 __ movq(Operand(rsp, 0), rax); 392 __ movq(Operand(rsp, 0), rax);
322 } else { 393 } else {
323 ASSERT(expr->location().is_nowhere()); 394 ASSERT(expr->location().is_nowhere());
324 __ pop(rax); 395 __ addq(rsp, Immediate(kPointerSize));
325 } 396 }
326 } 397 }
327 398
328 399
329 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { 400 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
330 Comment cmnt(masm_, "[ CallRuntime"); 401 Comment cmnt(masm_, "[ CallRuntime");
331 ZoneList<Expression*>* args = expr->arguments(); 402 ZoneList<Expression*>* args = expr->arguments();
332 Runtime::Function* function = expr->function(); 403 Runtime::Function* function = expr->function();
333 404
334 ASSERT(function != NULL); 405 ASSERT(function != NULL);
(...skipping 12 matching lines...) Expand all
347 __ CallRuntime(function, arg_count); 418 __ CallRuntime(function, arg_count);
348 if (expr->location().is_temporary()) { 419 if (expr->location().is_temporary()) {
349 __ push(rax); 420 __ push(rax);
350 } else { 421 } else {
351 ASSERT(expr->location().is_nowhere()); 422 ASSERT(expr->location().is_nowhere());
352 } 423 }
353 } 424 }
354 425
355 426
356 } } // namespace v8::internal 427 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.cc ('k') | test/mjsunit/compiler/literals.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698