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 switch (source.type()) { | 142 switch (source.type()) { |
143 case Location::NOWHERE: | 143 case Location::NOWHERE: |
144 UNREACHABLE(); | 144 UNREACHABLE(); |
145 case Location::TEMP: | 145 case Location::TEMP: |
146 __ pop(Operand(rbp, SlotOffset(destination))); | 146 __ pop(Operand(rbp, SlotOffset(destination))); |
147 break; | 147 break; |
148 } | 148 } |
149 } | 149 } |
150 | 150 |
151 | 151 |
| 152 void FastCodeGenerator::DropAndMove(Location destination, Register source) { |
| 153 switch (destination.type()) { |
| 154 case Location::NOWHERE: |
| 155 __ addq(rsp, Immediate(kPointerSize)); |
| 156 break; |
| 157 case Location::TEMP: |
| 158 __ movq(Operand(rsp, 0), source); |
| 159 break; |
| 160 } |
| 161 } |
| 162 |
| 163 |
152 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 164 void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
153 // Call the runtime to declare the globals. | 165 // Call the runtime to declare the globals. |
154 __ push(rsi); // The context is the first argument. | 166 __ push(rsi); // The context is the first argument. |
155 __ Push(pairs); | 167 __ Push(pairs); |
156 __ Push(Smi::FromInt(is_eval_ ? 1 : 0)); | 168 __ Push(Smi::FromInt(is_eval_ ? 1 : 0)); |
157 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 169 __ CallRuntime(Runtime::kDeclareGlobals, 3); |
158 // Return value is ignored. | 170 // Return value is ignored. |
159 } | 171 } |
160 | 172 |
161 | 173 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 // Use inline caching. Variable name is passed in rcx and the global | 231 // Use inline caching. Variable name is passed in rcx and the global |
220 // object on the stack. | 232 // object on the stack. |
221 __ push(CodeGenerator::GlobalObject()); | 233 __ push(CodeGenerator::GlobalObject()); |
222 __ Move(rcx, expr->name()); | 234 __ Move(rcx, expr->name()); |
223 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 235 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
224 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 236 __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
225 | 237 |
226 // A test rax instruction following the call is used by the IC to | 238 // A test rax instruction following the call is used by the IC to |
227 // indicate that the inobject property case was inlined. Ensure there | 239 // indicate that the inobject property case was inlined. Ensure there |
228 // is no test rax instruction here. | 240 // is no test rax instruction here. |
229 switch (expr->location().type()) { | 241 DropAndMove(expr->location(), rax); |
230 case Location::NOWHERE: | |
231 __ addq(rsp, Immediate(kPointerSize)); | |
232 break; | |
233 case Location::TEMP: | |
234 // Replace the global object with the result. | |
235 __ movq(Operand(rsp, 0), rax); | |
236 break; | |
237 } | |
238 | |
239 } else { | 242 } else { |
240 Comment cmnt(masm_, "Stack slot"); | 243 Comment cmnt(masm_, "Stack slot"); |
241 Move(expr->location(), rewrite->AsSlot()); | 244 Move(expr->location(), rewrite->AsSlot()); |
242 } | 245 } |
243 } | 246 } |
244 | 247 |
245 | 248 |
246 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { | 249 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
247 Comment cmnt(masm_, "[ ObjectLiteral"); | 250 Comment cmnt(masm_, "[ ObjectLiteral"); |
248 Label boilerplate_exists; | 251 Label boilerplate_exists; |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
461 } else { | 464 } else { |
462 ASSERT(rhs->location().is_temporary()); | 465 ASSERT(rhs->location().is_temporary()); |
463 Visit(rhs); | 466 Visit(rhs); |
464 __ pop(rax); | 467 __ pop(rax); |
465 } | 468 } |
466 __ Move(rcx, var->name()); | 469 __ Move(rcx, var->name()); |
467 __ push(CodeGenerator::GlobalObject()); | 470 __ push(CodeGenerator::GlobalObject()); |
468 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 471 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
469 __ Call(ic, RelocInfo::CODE_TARGET); | 472 __ Call(ic, RelocInfo::CODE_TARGET); |
470 // Overwrite the global object on the stack with the result if needed. | 473 // Overwrite the global object on the stack with the result if needed. |
471 switch (expr->location().type()) { | 474 DropAndMove(expr->location(), rax); |
472 case Location::NOWHERE: | |
473 __ addq(rsp, Immediate(kPointerSize)); | |
474 break; | |
475 case Location::TEMP: | |
476 __ movq(Operand(rsp, 0), rax); | |
477 break; | |
478 } | |
479 } else { | 475 } else { |
480 // Local or parameter assignment. | 476 // Local or parameter assignment. |
481 | 477 |
482 // Code for the right-hand-side expression depends on its type. | 478 // Code for the right-hand-side expression depends on its type. |
483 if (rhs->AsLiteral() != NULL) { | 479 if (rhs->AsLiteral() != NULL) { |
484 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a | 480 // Two cases: 'temp <- (var = constant)', or 'var = constant' with a |
485 // discarded result. Always perform the assignment. | 481 // discarded result. Always perform the assignment. |
486 __ Move(kScratchRegister, rhs->AsLiteral()->handle()); | 482 __ Move(kScratchRegister, rhs->AsLiteral()->handle()); |
487 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); | 483 __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister); |
488 Move(expr->location(), kScratchRegister); | 484 Move(expr->location(), kScratchRegister); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
563 } | 559 } |
564 // Record source position for debugger | 560 // Record source position for debugger |
565 SetSourcePosition(expr->position()); | 561 SetSourcePosition(expr->position()); |
566 // Call the IC initialization code. | 562 // Call the IC initialization code. |
567 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, | 563 Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, |
568 NOT_IN_LOOP); | 564 NOT_IN_LOOP); |
569 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); | 565 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
570 // Restore context register. | 566 // Restore context register. |
571 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 567 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
572 // Discard the function left on TOS. | 568 // Discard the function left on TOS. |
573 switch (expr->location().type()) { | 569 DropAndMove(expr->location(), rax); |
574 case Location::NOWHERE: | |
575 __ addq(rsp, Immediate(kPointerSize)); | |
576 break; | |
577 case Location::TEMP: | |
578 __ movq(Operand(rsp, 0), rax); | |
579 break; | |
580 } | |
581 } | 570 } |
582 | 571 |
583 | 572 |
584 void FastCodeGenerator::VisitCallNew(CallNew* node) { | 573 void FastCodeGenerator::VisitCallNew(CallNew* node) { |
585 Comment cmnt(masm_, "[ CallNew"); | 574 Comment cmnt(masm_, "[ CallNew"); |
586 // According to ECMA-262, section 11.2.2, page 44, the function | 575 // According to ECMA-262, section 11.2.2, page 44, the function |
587 // expression in new calls must be evaluated before the | 576 // expression in new calls must be evaluated before the |
588 // arguments. | 577 // arguments. |
589 // Push function on the stack. | 578 // Push function on the stack. |
590 Visit(node->expression()); | 579 Visit(node->expression()); |
(...skipping 19 matching lines...) Expand all Loading... |
610 | 599 |
611 // Load function, arg_count into rdi and rax. | 600 // Load function, arg_count into rdi and rax. |
612 __ Set(rax, arg_count); | 601 __ Set(rax, arg_count); |
613 // Function is in rsp[arg_count + 1]. | 602 // Function is in rsp[arg_count + 1]. |
614 __ movq(rdi, Operand(rsp, rax, times_pointer_size, kPointerSize)); | 603 __ movq(rdi, Operand(rsp, rax, times_pointer_size, kPointerSize)); |
615 | 604 |
616 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); | 605 Handle<Code> construct_builtin(Builtins::builtin(Builtins::JSConstructCall)); |
617 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); | 606 __ Call(construct_builtin, RelocInfo::CONSTRUCT_CALL); |
618 | 607 |
619 // Replace function on TOS with result in rax, or pop it. | 608 // Replace function on TOS with result in rax, or pop it. |
620 switch (node->location().type()) { | 609 DropAndMove(node->location(), rax); |
621 case Location::TEMP: | |
622 __ movq(Operand(rsp, 0), rax); | |
623 break; | |
624 case Location::NOWHERE: | |
625 __ addq(rsp, Immediate(kPointerSize)); | |
626 break; | |
627 } | |
628 } | 610 } |
629 | 611 |
630 | 612 |
631 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 613 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
632 Comment cmnt(masm_, "[ CallRuntime"); | 614 Comment cmnt(masm_, "[ CallRuntime"); |
633 ZoneList<Expression*>* args = expr->arguments(); | 615 ZoneList<Expression*>* args = expr->arguments(); |
634 Runtime::Function* function = expr->function(); | 616 Runtime::Function* function = expr->function(); |
635 | 617 |
636 ASSERT(function != NULL); | 618 ASSERT(function != NULL); |
637 | 619 |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
719 } else { | 701 } else { |
720 Visit(right); | 702 Visit(right); |
721 Move(destination, right->location()); | 703 Move(destination, right->location()); |
722 } | 704 } |
723 | 705 |
724 __ bind(&done); | 706 __ bind(&done); |
725 } | 707 } |
726 | 708 |
727 | 709 |
728 } } // namespace v8::internal | 710 } } // namespace v8::internal |
OLD | NEW |