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

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

Issue 339045: Rename the kinds of locations to be consistent with the (codegen)... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 1 month 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/location.h ('k') | no next file » | 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 for (int i = 0; i < kPadding; ++i) { 111 for (int i = 0; i < kPadding; ++i) {
112 masm_->int3(); 112 masm_->int3();
113 } 113 }
114 #endif 114 #endif
115 } 115 }
116 } 116 }
117 117
118 118
119 void FastCodeGenerator::Move(Location destination, Slot* source) { 119 void FastCodeGenerator::Move(Location destination, Slot* source) {
120 switch (destination.type()) { 120 switch (destination.type()) {
121 case Location::NOWHERE: 121 case Location::UNINITIALIZED:
122 UNREACHABLE();
123 case Location::EFFECT:
122 break; 124 break;
123 case Location::TEMP: 125 case Location::VALUE:
124 __ push(Operand(rbp, SlotOffset(source))); 126 __ push(Operand(rbp, SlotOffset(source)));
125 break; 127 break;
126 } 128 }
127 } 129 }
128 130
129 131
130 void FastCodeGenerator::Move(Location destination, Literal* expr) { 132 void FastCodeGenerator::Move(Location destination, Literal* expr) {
131 switch (destination.type()) { 133 switch (destination.type()) {
132 case Location::NOWHERE: 134 case Location::UNINITIALIZED:
135 UNREACHABLE();
136 case Location::EFFECT:
133 break; 137 break;
134 case Location::TEMP: 138 case Location::VALUE:
135 __ Push(expr->handle()); 139 __ Push(expr->handle());
136 break; 140 break;
137 } 141 }
138 } 142 }
139 143
140 144
141 void FastCodeGenerator::Move(Slot* destination, Location source) { 145 void FastCodeGenerator::Move(Slot* destination, Location source) {
142 switch (source.type()) { 146 switch (source.type()) {
143 case Location::NOWHERE: 147 case Location::UNINITIALIZED: // Fall through.
148 case Location::EFFECT:
144 UNREACHABLE(); 149 UNREACHABLE();
145 case Location::TEMP: 150 case Location::VALUE:
146 __ pop(Operand(rbp, SlotOffset(destination))); 151 __ pop(Operand(rbp, SlotOffset(destination)));
147 break; 152 break;
148 } 153 }
149 } 154 }
150 155
151 156
152 void FastCodeGenerator::DropAndMove(Location destination, Register source) { 157 void FastCodeGenerator::DropAndMove(Location destination, Register source) {
153 switch (destination.type()) { 158 switch (destination.type()) {
154 case Location::NOWHERE: 159 case Location::UNINITIALIZED:
160 UNREACHABLE();
161 case Location::EFFECT:
155 __ addq(rsp, Immediate(kPointerSize)); 162 __ addq(rsp, Immediate(kPointerSize));
156 break; 163 break;
157 case Location::TEMP: 164 case Location::VALUE:
158 __ movq(Operand(rsp, 0), source); 165 __ movq(Operand(rsp, 0), source);
159 break; 166 break;
160 } 167 }
161 } 168 }
162 169
163 170
164 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { 171 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
165 // Call the runtime to declare the globals. 172 // Call the runtime to declare the globals.
166 __ push(rsi); // The context is the first argument. 173 __ push(rsi); // The context is the first argument.
167 __ Push(pairs); 174 __ Push(pairs);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 // indicate that the inobject property case was inlined. Ensure there 246 // indicate that the inobject property case was inlined. Ensure there
240 // is no test rax instruction here. 247 // is no test rax instruction here.
241 DropAndMove(expr->location(), rax); 248 DropAndMove(expr->location(), rax);
242 } else { 249 } else {
243 Comment cmnt(masm_, "Stack slot"); 250 Comment cmnt(masm_, "Stack slot");
244 Move(expr->location(), rewrite->AsSlot()); 251 Move(expr->location(), rewrite->AsSlot());
245 } 252 }
246 } 253 }
247 254
248 255
256 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
257 Comment cmnt(masm_, "[ RegExp Literal");
258 Label done;
259 // Registers will be used as follows:
260 // rdi = JS function.
261 // rbx = literals array.
262 // rax = regexp literal.
263 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
264 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset));
265 int literal_offset =
266 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
267 __ movq(rax, FieldOperand(rbx, literal_offset));
268 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
269 __ j(not_equal, &done);
270 // Create regexp literal using runtime function
271 // Result will be in rax.
272 __ push(rbx);
273 __ Push(Smi::FromInt(expr->literal_index()));
274 __ Push(expr->pattern());
275 __ Push(expr->flags());
276 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
277 // Label done:
278 __ bind(&done);
279 Move(expr->location(), rax);
280 }
281
282
249 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 283 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
250 Comment cmnt(masm_, "[ ObjectLiteral"); 284 Comment cmnt(masm_, "[ ObjectLiteral");
251 Label boilerplate_exists; 285 Label boilerplate_exists;
252 286
253 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 287 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
254 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset)); 288 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset));
255 int literal_offset = 289 int literal_offset =
256 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; 290 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
257 __ movq(rax, FieldOperand(rbx, literal_offset)); 291 __ movq(rax, FieldOperand(rbx, literal_offset));
258 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); 292 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
(...skipping 29 matching lines...) Expand all
288 if (!result_saved) { 322 if (!result_saved) {
289 __ push(rax); // Save result on the stack 323 __ push(rax); // Save result on the stack
290 result_saved = true; 324 result_saved = true;
291 } 325 }
292 switch (property->kind()) { 326 switch (property->kind()) {
293 case ObjectLiteral::Property::MATERIALIZED_LITERAL: // fall through 327 case ObjectLiteral::Property::MATERIALIZED_LITERAL: // fall through
294 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 328 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
295 case ObjectLiteral::Property::COMPUTED: 329 case ObjectLiteral::Property::COMPUTED:
296 if (key->handle()->IsSymbol()) { 330 if (key->handle()->IsSymbol()) {
297 Visit(value); 331 Visit(value);
298 ASSERT(value->location().is_temporary()); 332 ASSERT(value->location().is_value());
299 __ pop(rax); 333 __ pop(rax);
300 __ Move(rcx, key->handle()); 334 __ Move(rcx, key->handle());
301 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 335 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
302 __ call(ic, RelocInfo::CODE_TARGET); 336 __ call(ic, RelocInfo::CODE_TARGET);
303 // StoreIC leaves the receiver on the stack. 337 // StoreIC leaves the receiver on the stack.
304 break; 338 break;
305 } 339 }
306 // fall through 340 // fall through
307 case ObjectLiteral::Property::PROTOTYPE: 341 case ObjectLiteral::Property::PROTOTYPE:
308 __ push(rax); 342 __ push(rax);
309 Visit(key); 343 Visit(key);
310 ASSERT(key->location().is_temporary()); 344 ASSERT(key->location().is_value());
311 Visit(value); 345 Visit(value);
312 ASSERT(value->location().is_temporary()); 346 ASSERT(value->location().is_value());
313 __ CallRuntime(Runtime::kSetProperty, 3); 347 __ CallRuntime(Runtime::kSetProperty, 3);
314 __ movq(rax, Operand(rsp, 0)); // Restore result into rax. 348 __ movq(rax, Operand(rsp, 0)); // Restore result into rax.
315 break; 349 break;
316 case ObjectLiteral::Property::SETTER: // fall through 350 case ObjectLiteral::Property::SETTER: // fall through
317 case ObjectLiteral::Property::GETTER: 351 case ObjectLiteral::Property::GETTER:
318 __ push(rax); 352 __ push(rax);
319 Visit(key); 353 Visit(key);
320 ASSERT(key->location().is_temporary()); 354 ASSERT(key->location().is_value());
321 __ Push(property->kind() == ObjectLiteral::Property::SETTER ? 355 __ Push(property->kind() == ObjectLiteral::Property::SETTER ?
322 Smi::FromInt(1) : 356 Smi::FromInt(1) :
323 Smi::FromInt(0)); 357 Smi::FromInt(0));
324 Visit(value); 358 Visit(value);
325 ASSERT(value->location().is_temporary()); 359 ASSERT(value->location().is_value());
326 __ CallRuntime(Runtime::kDefineAccessor, 4); 360 __ CallRuntime(Runtime::kDefineAccessor, 4);
327 __ movq(rax, Operand(rsp, 0)); // Restore result into rax. 361 __ movq(rax, Operand(rsp, 0)); // Restore result into rax.
328 break; 362 break;
329 default: UNREACHABLE(); 363 default: UNREACHABLE();
330 } 364 }
331 } 365 }
332 switch (expr->location().type()) { 366 switch (expr->location().type()) {
333 case Location::NOWHERE: 367 case Location::UNINITIALIZED:
368 UNREACHABLE();
369 case Location::EFFECT:
334 if (result_saved) __ addq(rsp, Immediate(kPointerSize)); 370 if (result_saved) __ addq(rsp, Immediate(kPointerSize));
335 break; 371 break;
336 case Location::TEMP: 372 case Location::VALUE:
337 if (!result_saved) __ push(rax); 373 if (!result_saved) __ push(rax);
338 break; 374 break;
339 } 375 }
340 } 376 }
341 377
342 378
343 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
344 Comment cmnt(masm_, "[ RegExp Literal");
345 Label done;
346 // Registers will be used as follows:
347 // rdi = JS function.
348 // rbx = literals array.
349 // rax = regexp literal.
350 __ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
351 __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset));
352 int literal_offset =
353 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
354 __ movq(rax, FieldOperand(rbx, literal_offset));
355 __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
356 __ j(not_equal, &done);
357 // Create regexp literal using runtime function
358 // Result will be in rax.
359 __ push(rbx);
360 __ Push(Smi::FromInt(expr->literal_index()));
361 __ Push(expr->pattern());
362 __ Push(expr->flags());
363 __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
364 // Label done:
365 __ bind(&done);
366 Move(expr->location(), rax);
367 }
368
369
370 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { 379 void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
371 Comment cmnt(masm_, "[ ArrayLiteral"); 380 Comment cmnt(masm_, "[ ArrayLiteral");
372 Label make_clone; 381 Label make_clone;
373 382
374 // Fetch the function's literals array. 383 // Fetch the function's literals array.
375 __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); 384 __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
376 __ movq(rbx, FieldOperand(rbx, JSFunction::kLiteralsOffset)); 385 __ movq(rbx, FieldOperand(rbx, JSFunction::kLiteralsOffset));
377 // Check if the literal's boilerplate has been instantiated. 386 // Check if the literal's boilerplate has been instantiated.
378 int offset = 387 int offset =
379 FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize); 388 FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize);
(...skipping 28 matching lines...) Expand all
408 if (subexpr->AsLiteral() != NULL || 417 if (subexpr->AsLiteral() != NULL ||
409 CompileTimeValue::IsCompileTimeValue(subexpr)) { 418 CompileTimeValue::IsCompileTimeValue(subexpr)) {
410 continue; 419 continue;
411 } 420 }
412 421
413 if (!result_saved) { 422 if (!result_saved) {
414 __ push(rax); 423 __ push(rax);
415 result_saved = true; 424 result_saved = true;
416 } 425 }
417 Visit(subexpr); 426 Visit(subexpr);
418 ASSERT(subexpr->location().is_temporary()); 427 ASSERT(subexpr->location().is_value());
419 428
420 // Store the subexpression value in the array's elements. 429 // Store the subexpression value in the array's elements.
421 __ pop(rax); // Subexpression value. 430 __ pop(rax); // Subexpression value.
422 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. 431 __ movq(rbx, Operand(rsp, 0)); // Copy of array literal.
423 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); 432 __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset));
424 int offset = FixedArray::kHeaderSize + (i * kPointerSize); 433 int offset = FixedArray::kHeaderSize + (i * kPointerSize);
425 __ movq(FieldOperand(rbx, offset), rax); 434 __ movq(FieldOperand(rbx, offset), rax);
426 435
427 // Update the write barrier for the array store. 436 // Update the write barrier for the array store.
428 __ RecordWrite(rbx, offset, rax, rcx); 437 __ RecordWrite(rbx, offset, rax, rcx);
429 } 438 }
430 439
431 switch (expr->location().type()) { 440 switch (expr->location().type()) {
432 case Location::NOWHERE: 441 case Location::UNINITIALIZED:
442 UNREACHABLE();
443 case Location::EFFECT:
433 if (result_saved) __ addq(rsp, Immediate(kPointerSize)); 444 if (result_saved) __ addq(rsp, Immediate(kPointerSize));
434 break; 445 break;
435 case Location::TEMP: 446 case Location::VALUE:
436 if (!result_saved) __ push(rax); 447 if (!result_saved) __ push(rax);
437 break; 448 break;
438 } 449 }
439 } 450 }
440 451
441 452
442 void FastCodeGenerator::VisitAssignment(Assignment* expr) { 453 void FastCodeGenerator::VisitAssignment(Assignment* expr) {
443 Comment cmnt(masm_, "[ Assignment"); 454 Comment cmnt(masm_, "[ Assignment");
444 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); 455 ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR);
445 456
446 // Left-hand side can only be a global or a (parameter or local) slot. 457 // Left-hand side can only be a global or a (parameter or local) slot.
447 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); 458 Variable* var = expr->target()->AsVariableProxy()->AsVariable();
448 ASSERT(var != NULL); 459 ASSERT(var != NULL);
449 ASSERT(var->is_global() || var->slot() != NULL); 460 ASSERT(var->is_global() || var->slot() != NULL);
450 461
451 Expression* rhs = expr->value(); 462 Expression* rhs = expr->value();
452 Location destination = expr->location(); 463 Location destination = expr->location();
453 if (var->is_global()) { 464 if (var->is_global()) {
454 // Assignment to a global variable, use inline caching. Right-hand-side 465 // Assignment to a global variable, use inline caching. Right-hand-side
455 // value is passed in rax, variable name in rcx, and the global object 466 // value is passed in rax, variable name in rcx, and the global object
456 // on the stack. 467 // on the stack.
457 468
458 // Code for the right-hand-side expression depends on its type. 469 // Code for the right-hand-side expression depends on its type.
459 if (rhs->AsLiteral() != NULL) { 470 if (rhs->AsLiteral() != NULL) {
460 __ Move(rax, rhs->AsLiteral()->handle()); 471 __ Move(rax, rhs->AsLiteral()->handle());
461 } else { 472 } else {
462 ASSERT(rhs->location().is_temporary()); 473 ASSERT(rhs->location().is_value());
463 Visit(rhs); 474 Visit(rhs);
464 __ pop(rax); 475 __ pop(rax);
465 } 476 }
466 __ Move(rcx, var->name()); 477 __ Move(rcx, var->name());
467 __ push(CodeGenerator::GlobalObject()); 478 __ push(CodeGenerator::GlobalObject());
468 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); 479 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
469 __ Call(ic, RelocInfo::CODE_TARGET); 480 __ Call(ic, RelocInfo::CODE_TARGET);
470 // Overwrite the global object on the stack with the result if needed. 481 // Overwrite the global object on the stack with the result if needed.
471 DropAndMove(expr->location(), rax); 482 DropAndMove(expr->location(), rax);
472 } else { 483 } else {
473 // Local or parameter assignment. 484 // Local or parameter assignment.
474 485
475 // Code for the right-hand-side expression depends on its type. 486 // Code for the right-hand-side expression depends on its type.
476 if (rhs->AsLiteral() != NULL) { 487 if (rhs->AsLiteral() != NULL) {
477 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a 488 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a
478 // discarded result. Always perform the assignment. 489 // discarded result. Always perform the assignment.
479 __ Move(kScratchRegister, rhs->AsLiteral()->handle()); 490 __ Move(kScratchRegister, rhs->AsLiteral()->handle());
480 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); 491 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
481 Move(expr->location(), kScratchRegister); 492 Move(expr->location(), kScratchRegister);
482 } else { 493 } else {
483 ASSERT(rhs->location().is_temporary()); 494 ASSERT(rhs->location().is_value());
484 Visit(rhs); 495 Visit(rhs);
485 switch (expr->location().type()) { 496 switch (expr->location().type()) {
486 case Location::NOWHERE: 497 case Location::UNINITIALIZED:
498 UNREACHABLE();
499 case Location::EFFECT:
487 // Case 'var = temp'. Discard right-hand-side temporary. 500 // Case 'var = temp'. Discard right-hand-side temporary.
488 Move(var->slot(), rhs->location()); 501 Move(var->slot(), rhs->location());
489 break; 502 break;
490 case Location::TEMP: 503 case Location::VALUE:
491 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side 504 // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
492 // temporary on the stack. 505 // temporary on the stack.
493 __ movq(kScratchRegister, Operand(rsp, 0)); 506 __ movq(kScratchRegister, Operand(rsp, 0));
494 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); 507 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
495 break; 508 break;
496 } 509 }
497 } 510 }
498 } 511 }
499 } 512 }
500 513
(...skipping 24 matching lines...) Expand all
525 Visit(expr->key()); 538 Visit(expr->key());
526 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 539 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
527 __ call(ic, RelocInfo::CODE_TARGET); 540 __ call(ic, RelocInfo::CODE_TARGET);
528 // By emitting a nop we make sure that we do not have a "test ..." 541 // By emitting a nop we make sure that we do not have a "test ..."
529 // instruction after the call it is treated specially by the LoadIC code. 542 // instruction after the call it is treated specially by the LoadIC code.
530 __ nop(); 543 __ nop();
531 // Drop key left on the stack by IC. 544 // Drop key left on the stack by IC.
532 __ addq(rsp, Immediate(kPointerSize)); 545 __ addq(rsp, Immediate(kPointerSize));
533 } 546 }
534 switch (expr->location().type()) { 547 switch (expr->location().type()) {
535 case Location::TEMP: 548 case Location::UNINITIALIZED:
549 UNREACHABLE();
550 case Location::VALUE:
536 __ movq(Operand(rsp, 0), rax); 551 __ movq(Operand(rsp, 0), rax);
537 break; 552 break;
538 case Location::NOWHERE: 553 case Location::EFFECT:
539 __ addq(rsp, Immediate(kPointerSize)); 554 __ addq(rsp, Immediate(kPointerSize));
540 break; 555 break;
541 } 556 }
542 } 557 }
543 558
544 559
545 void FastCodeGenerator::VisitCall(Call* expr) { 560 void FastCodeGenerator::VisitCall(Call* expr) {
546 Expression* fun = expr->expression(); 561 Expression* fun = expr->expression();
547 ZoneList<Expression*>* args = expr->arguments(); 562 ZoneList<Expression*>* args = expr->arguments();
548 Variable* var = fun->AsVariableProxy()->AsVariable(); 563 Variable* var = fun->AsVariableProxy()->AsVariable();
549 ASSERT(var != NULL && !var->is_this() && var->is_global()); 564 ASSERT(var != NULL && !var->is_this() && var->is_global());
550 ASSERT(!var->is_possibly_eval()); 565 ASSERT(!var->is_possibly_eval());
551 566
552 __ Push(var->name()); 567 __ Push(var->name());
553 // Push global object (receiver). 568 // Push global object (receiver).
554 __ push(CodeGenerator::GlobalObject()); 569 __ push(CodeGenerator::GlobalObject());
555 int arg_count = args->length(); 570 int arg_count = args->length();
556 for (int i = 0; i < arg_count; i++) { 571 for (int i = 0; i < arg_count; i++) {
557 Visit(args->at(i)); 572 Visit(args->at(i));
558 ASSERT(args->at(i)->location().is_temporary()); 573 ASSERT(args->at(i)->location().is_value());
559 } 574 }
560 // Record source position for debugger 575 // Record source position for debugger
561 SetSourcePosition(expr->position()); 576 SetSourcePosition(expr->position());
562 // Call the IC initialization code. 577 // Call the IC initialization code.
563 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, 578 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count,
564 NOT_IN_LOOP); 579 NOT_IN_LOOP);
565 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); 580 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT);
566 // Restore context register. 581 // Restore context register.
567 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 582 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
568 // Discard the function left on TOS. 583 // Discard the function left on TOS.
569 DropAndMove(expr->location(), rax); 584 DropAndMove(expr->location(), rax);
570 } 585 }
571 586
572 587
573 void FastCodeGenerator::VisitCallNew(CallNew* node) { 588 void FastCodeGenerator::VisitCallNew(CallNew* node) {
574 Comment cmnt(masm_, "[ CallNew"); 589 Comment cmnt(masm_, "[ CallNew");
575 // According to ECMA-262, section 11.2.2, page 44, the function 590 // According to ECMA-262, section 11.2.2, page 44, the function
576 // expression in new calls must be evaluated before the 591 // expression in new calls must be evaluated before the
577 // arguments. 592 // arguments.
578 // Push function on the stack. 593 // Push function on the stack.
579 Visit(node->expression()); 594 Visit(node->expression());
580 ASSERT(node->expression()->location().is_temporary()); 595 ASSERT(node->expression()->location().is_value());
581 // If location is temporary, already on the stack, 596 // If location is temporary, already on the stack,
582 597
583 // Push global object (receiver). 598 // Push global object (receiver).
584 __ push(CodeGenerator::GlobalObject()); 599 __ push(CodeGenerator::GlobalObject());
585 600
586 // Push the arguments ("left-to-right") on the stack. 601 // Push the arguments ("left-to-right") on the stack.
587 ZoneList<Expression*>* args = node->arguments(); 602 ZoneList<Expression*>* args = node->arguments();
588 int arg_count = args->length(); 603 int arg_count = args->length();
589 for (int i = 0; i < arg_count; i++) { 604 for (int i = 0; i < arg_count; i++) {
590 Visit(args->at(i)); 605 Visit(args->at(i));
591 ASSERT(args->at(i)->location().is_temporary()); 606 ASSERT(args->at(i)->location().is_value());
592 // If location is temporary, it is already on the stack, 607 // If location is temporary, it is already on the stack,
593 // so nothing to do here. 608 // so nothing to do here.
594 } 609 }
595 610
596 // Call the construct call builtin that handles allocation and 611 // Call the construct call builtin that handles allocation and
597 // constructor invocation. 612 // constructor invocation.
598 SetSourcePosition(node->position()); 613 SetSourcePosition(node->position());
599 614
600 // Load function, arg_count into rdi and rax. 615 // Load function, arg_count into rdi and rax.
601 __ Set(rax, arg_count); 616 __ Set(rax, arg_count);
(...skipping 12 matching lines...) Expand all
614 Comment cmnt(masm_, "[ CallRuntime"); 629 Comment cmnt(masm_, "[ CallRuntime");
615 ZoneList<Expression*>* args = expr->arguments(); 630 ZoneList<Expression*>* args = expr->arguments();
616 Runtime::Function* function = expr->function(); 631 Runtime::Function* function = expr->function();
617 632
618 ASSERT(function != NULL); 633 ASSERT(function != NULL);
619 634
620 // Push the arguments ("left-to-right"). 635 // Push the arguments ("left-to-right").
621 int arg_count = args->length(); 636 int arg_count = args->length();
622 for (int i = 0; i < arg_count; i++) { 637 for (int i = 0; i < arg_count; i++) {
623 Visit(args->at(i)); 638 Visit(args->at(i));
624 ASSERT(args->at(i)->location().is_temporary()); 639 ASSERT(args->at(i)->location().is_value());
625 } 640 }
626 641
627 __ CallRuntime(function, arg_count); 642 __ CallRuntime(function, arg_count);
628 Move(expr->location(), rax); 643 Move(expr->location(), rax);
629 } 644 }
630 645
631 646
632 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { 647 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) {
633 // Compile a short-circuited boolean or operation in a non-test 648 // Compile a short-circuited boolean or operation in a non-test
634 // context. 649 // context.
635 ASSERT(expr->op() == Token::OR); 650 ASSERT(expr->op() == Token::OR);
636 // Compile (e0 || e1) as if it were 651 // Compile (e0 || e1) as if it were
637 // (let (temp = e0) temp ? temp : e1). 652 // (let (temp = e0) temp ? temp : e1).
638 653
639 Label eval_right, done; 654 Label eval_right, done;
640 Location destination = expr->location(); 655 Location destination = expr->location();
641 Expression* left = expr->left(); 656 Expression* left = expr->left();
642 Expression* right = expr->right(); 657 Expression* right = expr->right();
643 658
644 // Use the shared ToBoolean stub to find the boolean value of the 659 // Use the shared ToBoolean stub to find the boolean value of the
645 // left-hand subexpression. Load the value into rax to perform some 660 // left-hand subexpression. Load the value into rax to perform some
646 // inlined checks assumed by the stub. 661 // inlined checks assumed by the stub.
647 662
648 // Compile the left-hand value into rax. Put it on the stack if we may 663 // Compile the left-hand value into rax. Put it on the stack if we may
649 // need it as the value of the whole expression. 664 // need it as the value of the whole expression.
650 if (left->AsLiteral() != NULL) { 665 if (left->AsLiteral() != NULL) {
651 __ Move(rax, left->AsLiteral()->handle()); 666 __ Move(rax, left->AsLiteral()->handle());
652 if (destination.is_temporary()) __ push(rax); 667 if (destination.is_value()) __ push(rax);
653 } else { 668 } else {
654 Visit(left); 669 Visit(left);
655 ASSERT(left->location().is_temporary()); 670 ASSERT(left->location().is_value());
656 switch (destination.type()) { 671 switch (destination.type()) {
657 case Location::NOWHERE: 672 case Location::UNINITIALIZED:
673 UNREACHABLE();
674 case Location::EFFECT:
658 // Pop the left-hand value into rax because we will not need it as the 675 // Pop the left-hand value into rax because we will not need it as the
659 // final result. 676 // final result.
660 __ pop(rax); 677 __ pop(rax);
661 break; 678 break;
662 case Location::TEMP: 679 case Location::VALUE:
663 // Copy the left-hand value into rax because we may need it as the 680 // Copy the left-hand value into rax because we may need it as the
664 // final result. 681 // final result.
665 __ movq(rax, Operand(rsp, 0)); 682 __ movq(rax, Operand(rsp, 0));
666 break; 683 break;
667 } 684 }
668 } 685 }
669 // The left-hand value is in rax. It is also on the stack iff the 686 // The left-hand value is in rax. It is also on the stack iff the
670 // destination location is temporary. 687 // destination location is temporary.
671 688
672 // Perform fast checks assumed by the stub. 689 // Perform fast checks assumed by the stub.
(...skipping 12 matching lines...) Expand all
685 702
686 // Call the stub for all other cases. 703 // Call the stub for all other cases.
687 __ push(rax); 704 __ push(rax);
688 ToBooleanStub stub; 705 ToBooleanStub stub;
689 __ CallStub(&stub); 706 __ CallStub(&stub);
690 __ testq(rax, rax); // The stub returns nonzero for true. 707 __ testq(rax, rax); // The stub returns nonzero for true.
691 __ j(not_zero, &done); 708 __ j(not_zero, &done);
692 709
693 __ bind(&eval_right); 710 __ bind(&eval_right);
694 // Discard the left-hand value if present on the stack. 711 // Discard the left-hand value if present on the stack.
695 if (destination.is_temporary()) { 712 if (destination.is_value()) {
696 __ addq(rsp, Immediate(kPointerSize)); 713 __ addq(rsp, Immediate(kPointerSize));
697 } 714 }
698 // Save or discard the right-hand value as needed. 715 // Save or discard the right-hand value as needed.
699 if (right->AsLiteral() != NULL) { 716 if (right->AsLiteral() != NULL) {
700 Move(destination, right->AsLiteral()); 717 Move(destination, right->AsLiteral());
701 } else { 718 } else {
702 Visit(right); 719 Visit(right);
703 Move(destination, right->location()); 720 Move(destination, right->location());
704 } 721 }
705 722
706 __ bind(&done); 723 __ bind(&done);
707 } 724 }
708 725
709 726
710 } } // namespace v8::internal 727 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/location.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698