| 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 |