OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 : LAZY_ARGUMENTS_ALLOCATION; | 620 : LAZY_ARGUMENTS_ALLOCATION; |
621 } | 621 } |
622 | 622 |
623 | 623 |
624 Result CodeGenerator::StoreArgumentsObject(bool initial) { | 624 Result CodeGenerator::StoreArgumentsObject(bool initial) { |
625 ArgumentsAllocationMode mode = ArgumentsMode(); | 625 ArgumentsAllocationMode mode = ArgumentsMode(); |
626 ASSERT(mode != NO_ARGUMENTS_ALLOCATION); | 626 ASSERT(mode != NO_ARGUMENTS_ALLOCATION); |
627 | 627 |
628 Comment cmnt(masm_, "[ store arguments object"); | 628 Comment cmnt(masm_, "[ store arguments object"); |
629 if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) { | 629 if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) { |
630 // When using lazy arguments allocation, we store the hole value | 630 // When using lazy arguments allocation, we store the arguments marker value |
631 // as a sentinel indicating that the arguments object hasn't been | 631 // as a sentinel indicating that the arguments object hasn't been |
632 // allocated yet. | 632 // allocated yet. |
633 frame_->Push(Factory::the_hole_value()); | 633 frame_->Push(Factory::arguments_marker()); |
634 } else { | 634 } else { |
635 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); | 635 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
636 frame_->PushFunction(); | 636 frame_->PushFunction(); |
637 frame_->PushReceiverSlotAddress(); | 637 frame_->PushReceiverSlotAddress(); |
638 frame_->Push(Smi::FromInt(scope()->num_parameters())); | 638 frame_->Push(Smi::FromInt(scope()->num_parameters())); |
639 Result result = frame_->CallStub(&stub, 3); | 639 Result result = frame_->CallStub(&stub, 3); |
640 frame_->Push(&result); | 640 frame_->Push(&result); |
641 } | 641 } |
642 | 642 |
643 Variable* arguments = scope()->arguments(); | 643 Variable* arguments = scope()->arguments(); |
644 Variable* shadow = scope()->arguments_shadow(); | 644 Variable* shadow = scope()->arguments_shadow(); |
645 ASSERT(arguments != NULL && arguments->AsSlot() != NULL); | 645 ASSERT(arguments != NULL && arguments->AsSlot() != NULL); |
646 ASSERT(shadow != NULL && shadow->AsSlot() != NULL); | 646 ASSERT(shadow != NULL && shadow->AsSlot() != NULL); |
647 JumpTarget done; | 647 JumpTarget done; |
648 bool skip_arguments = false; | 648 bool skip_arguments = false; |
649 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { | 649 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { |
650 // We have to skip storing into the arguments slot if it has | 650 // We have to skip storing into the arguments slot if it has |
651 // already been written to. This can happen if the a function | 651 // already been written to. This can happen if the a function |
652 // has a local variable named 'arguments'. | 652 // has a local variable named 'arguments'. |
653 LoadFromSlot(arguments->AsSlot(), NOT_INSIDE_TYPEOF); | 653 LoadFromSlot(arguments->AsSlot(), NOT_INSIDE_TYPEOF); |
654 Result probe = frame_->Pop(); | 654 Result probe = frame_->Pop(); |
655 if (probe.is_constant()) { | 655 if (probe.is_constant()) { |
656 // We have to skip updating the arguments object if it has | 656 // We have to skip updating the arguments object if it has |
657 // been assigned a proper value. | 657 // been assigned a proper value. |
658 skip_arguments = !probe.handle()->IsTheHole(); | 658 skip_arguments = !probe.handle()->IsArgumentsMarker(); |
659 } else { | 659 } else { |
660 __ CompareRoot(probe.reg(), Heap::kTheHoleValueRootIndex); | 660 __ CompareRoot(probe.reg(), Heap::kArgumentsMarkerRootIndex); |
661 probe.Unuse(); | 661 probe.Unuse(); |
662 done.Branch(not_equal); | 662 done.Branch(not_equal); |
663 } | 663 } |
664 } | 664 } |
665 if (!skip_arguments) { | 665 if (!skip_arguments) { |
666 StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT); | 666 StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT); |
667 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); | 667 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); |
668 } | 668 } |
669 StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT); | 669 StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT); |
670 return frame_->Pop(); | 670 return frame_->Pop(); |
(...skipping 1838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2509 // Check if the arguments object has been lazily allocated | 2509 // Check if the arguments object has been lazily allocated |
2510 // already. If so, just use that instead of copying the arguments | 2510 // already. If so, just use that instead of copying the arguments |
2511 // from the stack. This also deals with cases where a local variable | 2511 // from the stack. This also deals with cases where a local variable |
2512 // named 'arguments' has been introduced. | 2512 // named 'arguments' has been introduced. |
2513 frame_->Dup(); | 2513 frame_->Dup(); |
2514 Result probe = frame_->Pop(); | 2514 Result probe = frame_->Pop(); |
2515 { VirtualFrame::SpilledScope spilled_scope; | 2515 { VirtualFrame::SpilledScope spilled_scope; |
2516 Label slow, done; | 2516 Label slow, done; |
2517 bool try_lazy = true; | 2517 bool try_lazy = true; |
2518 if (probe.is_constant()) { | 2518 if (probe.is_constant()) { |
2519 try_lazy = probe.handle()->IsTheHole(); | 2519 try_lazy = probe.handle()->IsArgumentsMarker(); |
2520 } else { | 2520 } else { |
2521 __ CompareRoot(probe.reg(), Heap::kTheHoleValueRootIndex); | 2521 __ CompareRoot(probe.reg(), Heap::kArgumentsMarkerRootIndex); |
2522 probe.Unuse(); | 2522 probe.Unuse(); |
2523 __ j(not_equal, &slow); | 2523 __ j(not_equal, &slow); |
2524 } | 2524 } |
2525 | 2525 |
2526 if (try_lazy) { | 2526 if (try_lazy) { |
2527 Label build_args; | 2527 Label build_args; |
2528 // Get rid of the arguments object probe. | 2528 // Get rid of the arguments object probe. |
2529 frame_->Drop(); // Can be called on a spilled frame. | 2529 frame_->Drop(); // Can be called on a spilled frame. |
2530 // Stack now has 3 elements on it. | 2530 // Stack now has 3 elements on it. |
2531 // Contents of stack at this point: | 2531 // Contents of stack at this point: |
(...skipping 1878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4410 | 4410 |
4411 // ... or if the slot isn't a non-parameter arguments slot. | 4411 // ... or if the slot isn't a non-parameter arguments slot. |
4412 if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return; | 4412 if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return; |
4413 | 4413 |
4414 // Pop the loaded value from the stack. | 4414 // Pop the loaded value from the stack. |
4415 Result value = frame_->Pop(); | 4415 Result value = frame_->Pop(); |
4416 | 4416 |
4417 // If the loaded value is a constant, we know if the arguments | 4417 // If the loaded value is a constant, we know if the arguments |
4418 // object has been lazily loaded yet. | 4418 // object has been lazily loaded yet. |
4419 if (value.is_constant()) { | 4419 if (value.is_constant()) { |
4420 if (value.handle()->IsTheHole()) { | 4420 if (value.handle()->IsArgumentsMarker()) { |
4421 Result arguments = StoreArgumentsObject(false); | 4421 Result arguments = StoreArgumentsObject(false); |
4422 frame_->Push(&arguments); | 4422 frame_->Push(&arguments); |
4423 } else { | 4423 } else { |
4424 frame_->Push(&value); | 4424 frame_->Push(&value); |
4425 } | 4425 } |
4426 return; | 4426 return; |
4427 } | 4427 } |
4428 | 4428 |
4429 // The loaded value is in a register. If it is the sentinel that | 4429 // The loaded value is in a register. If it is the sentinel that |
4430 // indicates that we haven't loaded the arguments object yet, we | 4430 // indicates that we haven't loaded the arguments object yet, we |
4431 // need to do it now. | 4431 // need to do it now. |
4432 JumpTarget exit; | 4432 JumpTarget exit; |
4433 __ CompareRoot(value.reg(), Heap::kTheHoleValueRootIndex); | 4433 __ CompareRoot(value.reg(), Heap::kArgumentsMarkerRootIndex); |
4434 frame_->Push(&value); | 4434 frame_->Push(&value); |
4435 exit.Branch(not_equal); | 4435 exit.Branch(not_equal); |
4436 Result arguments = StoreArgumentsObject(false); | 4436 Result arguments = StoreArgumentsObject(false); |
4437 frame_->SetElementAt(0, &arguments); | 4437 frame_->SetElementAt(0, &arguments); |
4438 exit.Bind(); | 4438 exit.Bind(); |
4439 } | 4439 } |
4440 | 4440 |
4441 | 4441 |
4442 Result CodeGenerator::LoadFromGlobalSlotCheckExtensions( | 4442 Result CodeGenerator::LoadFromGlobalSlotCheckExtensions( |
4443 Slot* slot, | 4443 Slot* slot, |
(...skipping 4360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8804 } | 8804 } |
8805 | 8805 |
8806 #endif | 8806 #endif |
8807 | 8807 |
8808 | 8808 |
8809 #undef __ | 8809 #undef __ |
8810 | 8810 |
8811 } } // namespace v8::internal | 8811 } } // namespace v8::internal |
8812 | 8812 |
8813 #endif // V8_TARGET_ARCH_X64 | 8813 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |