| 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 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 | 587 |
| 588 void CodeGenerator::StoreArgumentsObject(bool initial) { | 588 void CodeGenerator::StoreArgumentsObject(bool initial) { |
| 589 ArgumentsAllocationMode mode = ArgumentsMode(); | 589 ArgumentsAllocationMode mode = ArgumentsMode(); |
| 590 ASSERT(mode != NO_ARGUMENTS_ALLOCATION); | 590 ASSERT(mode != NO_ARGUMENTS_ALLOCATION); |
| 591 | 591 |
| 592 Comment cmnt(masm_, "[ store arguments object"); | 592 Comment cmnt(masm_, "[ store arguments object"); |
| 593 if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) { | 593 if (mode == LAZY_ARGUMENTS_ALLOCATION && initial) { |
| 594 // When using lazy arguments allocation, we store the hole value | 594 // When using lazy arguments allocation, we store the hole value |
| 595 // as a sentinel indicating that the arguments object hasn't been | 595 // as a sentinel indicating that the arguments object hasn't been |
| 596 // allocated yet. | 596 // allocated yet. |
| 597 frame_->EmitPushRoot(Heap::kTheHoleValueRootIndex); | 597 frame_->EmitPushRoot(Heap::kArgumentsMarkerRootIndex); |
| 598 } else { | 598 } else { |
| 599 frame_->SpillAll(); | 599 frame_->SpillAll(); |
| 600 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); | 600 ArgumentsAccessStub stub(ArgumentsAccessStub::NEW_OBJECT); |
| 601 __ ldr(r2, frame_->Function()); | 601 __ ldr(r2, frame_->Function()); |
| 602 // The receiver is below the arguments, the return address, and the | 602 // The receiver is below the arguments, the return address, and the |
| 603 // frame pointer on the stack. | 603 // frame pointer on the stack. |
| 604 const int kReceiverDisplacement = 2 + scope()->num_parameters(); | 604 const int kReceiverDisplacement = 2 + scope()->num_parameters(); |
| 605 __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize)); | 605 __ add(r1, fp, Operand(kReceiverDisplacement * kPointerSize)); |
| 606 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); | 606 __ mov(r0, Operand(Smi::FromInt(scope()->num_parameters()))); |
| 607 frame_->Adjust(3); | 607 frame_->Adjust(3); |
| 608 __ Push(r2, r1, r0); | 608 __ Push(r2, r1, r0); |
| 609 frame_->CallStub(&stub, 3); | 609 frame_->CallStub(&stub, 3); |
| 610 frame_->EmitPush(r0); | 610 frame_->EmitPush(r0); |
| 611 } | 611 } |
| 612 | 612 |
| 613 Variable* arguments = scope()->arguments(); | 613 Variable* arguments = scope()->arguments(); |
| 614 Variable* shadow = scope()->arguments_shadow(); | 614 Variable* shadow = scope()->arguments_shadow(); |
| 615 ASSERT(arguments != NULL && arguments->AsSlot() != NULL); | 615 ASSERT(arguments != NULL && arguments->AsSlot() != NULL); |
| 616 ASSERT(shadow != NULL && shadow->AsSlot() != NULL); | 616 ASSERT(shadow != NULL && shadow->AsSlot() != NULL); |
| 617 JumpTarget done; | 617 JumpTarget done; |
| 618 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { | 618 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { |
| 619 // We have to skip storing into the arguments slot if it has | 619 // We have to skip storing into the arguments slot if it has |
| 620 // already been written to. This can happen if the a function | 620 // already been written to. This can happen if the a function |
| 621 // has a local variable named 'arguments'. | 621 // has a local variable named 'arguments'. |
| 622 LoadFromSlot(scope()->arguments()->AsSlot(), NOT_INSIDE_TYPEOF); | 622 LoadFromSlot(scope()->arguments()->AsSlot(), NOT_INSIDE_TYPEOF); |
| 623 Register arguments = frame_->PopToRegister(); | 623 Register arguments = frame_->PopToRegister(); |
| 624 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 624 __ LoadRoot(ip, Heap::kArgumentsMarkerRootIndex); |
| 625 __ cmp(arguments, ip); | 625 __ cmp(arguments, ip); |
| 626 done.Branch(ne); | 626 done.Branch(ne); |
| 627 } | 627 } |
| 628 StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT); | 628 StoreToSlot(arguments->AsSlot(), NOT_CONST_INIT); |
| 629 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); | 629 if (mode == LAZY_ARGUMENTS_ALLOCATION) done.Bind(); |
| 630 StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT); | 630 StoreToSlot(shadow->AsSlot(), NOT_CONST_INIT); |
| 631 } | 631 } |
| 632 | 632 |
| 633 | 633 |
| 634 void CodeGenerator::LoadTypeofExpression(Expression* expr) { | 634 void CodeGenerator::LoadTypeofExpression(Expression* expr) { |
| (...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1740 // sp[1]: receiver | 1740 // sp[1]: receiver |
| 1741 // sp[2]: applicand.apply | 1741 // sp[2]: applicand.apply |
| 1742 // sp[3]: applicand. | 1742 // sp[3]: applicand. |
| 1743 | 1743 |
| 1744 // Check if the arguments object has been lazily allocated | 1744 // Check if the arguments object has been lazily allocated |
| 1745 // already. If so, just use that instead of copying the arguments | 1745 // already. If so, just use that instead of copying the arguments |
| 1746 // from the stack. This also deals with cases where a local variable | 1746 // from the stack. This also deals with cases where a local variable |
| 1747 // named 'arguments' has been introduced. | 1747 // named 'arguments' has been introduced. |
| 1748 JumpTarget slow; | 1748 JumpTarget slow; |
| 1749 Label done; | 1749 Label done; |
| 1750 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 1750 __ LoadRoot(ip, Heap::kArgumentsMarkerRootIndex); |
| 1751 __ cmp(ip, arguments_reg); | 1751 __ cmp(ip, arguments_reg); |
| 1752 slow.Branch(ne); | 1752 slow.Branch(ne); |
| 1753 | 1753 |
| 1754 Label build_args; | 1754 Label build_args; |
| 1755 // Get rid of the arguments object probe. | 1755 // Get rid of the arguments object probe. |
| 1756 frame_->Drop(); | 1756 frame_->Drop(); |
| 1757 // Stack now has 3 elements on it. | 1757 // Stack now has 3 elements on it. |
| 1758 // Contents of stack at this point: | 1758 // Contents of stack at this point: |
| 1759 // sp[0]: receiver - in the receiver_reg register. | 1759 // sp[0]: receiver - in the receiver_reg register. |
| 1760 // sp[1]: applicand.apply | 1760 // sp[1]: applicand.apply |
| (...skipping 1487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3248 // ... or if the slot isn't a non-parameter arguments slot. | 3248 // ... or if the slot isn't a non-parameter arguments slot. |
| 3249 if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return; | 3249 if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return; |
| 3250 | 3250 |
| 3251 // Load the loaded value from the stack into a register but leave it on the | 3251 // Load the loaded value from the stack into a register but leave it on the |
| 3252 // stack. | 3252 // stack. |
| 3253 Register tos = frame_->Peek(); | 3253 Register tos = frame_->Peek(); |
| 3254 | 3254 |
| 3255 // If the loaded value is the sentinel that indicates that we | 3255 // If the loaded value is the sentinel that indicates that we |
| 3256 // haven't loaded the arguments object yet, we need to do it now. | 3256 // haven't loaded the arguments object yet, we need to do it now. |
| 3257 JumpTarget exit; | 3257 JumpTarget exit; |
| 3258 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); | 3258 __ LoadRoot(ip, Heap::kArgumentsMarkerRootIndex); |
| 3259 __ cmp(tos, ip); | 3259 __ cmp(tos, ip); |
| 3260 exit.Branch(ne); | 3260 exit.Branch(ne); |
| 3261 frame_->Drop(); | 3261 frame_->Drop(); |
| 3262 StoreArgumentsObject(false); | 3262 StoreArgumentsObject(false); |
| 3263 exit.Bind(); | 3263 exit.Bind(); |
| 3264 } | 3264 } |
| 3265 | 3265 |
| 3266 | 3266 |
| 3267 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { | 3267 void CodeGenerator::StoreToSlot(Slot* slot, InitState init_state) { |
| 3268 ASSERT(slot != NULL); | 3268 ASSERT(slot != NULL); |
| (...skipping 1395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4664 // If exponent is positive we are done. | 4664 // If exponent is positive we are done. |
| 4665 __ cmp(exponent, Operand(0, RelocInfo::NONE)); | 4665 __ cmp(exponent, Operand(0, RelocInfo::NONE)); |
| 4666 __ b(ge, &allocate_return); | 4666 __ b(ge, &allocate_return); |
| 4667 | 4667 |
| 4668 // If exponent is negative result is 1/result (d2 already holds 1.0 in that | 4668 // If exponent is negative result is 1/result (d2 already holds 1.0 in that |
| 4669 // case). However if d0 has reached infinity this will not provide the | 4669 // case). However if d0 has reached infinity this will not provide the |
| 4670 // correct result, so call runtime if that is the case. | 4670 // correct result, so call runtime if that is the case. |
| 4671 __ mov(scratch2, Operand(0x7FF00000)); | 4671 __ mov(scratch2, Operand(0x7FF00000)); |
| 4672 __ mov(scratch1, Operand(0, RelocInfo::NONE)); | 4672 __ mov(scratch1, Operand(0, RelocInfo::NONE)); |
| 4673 __ vmov(d1, scratch1, scratch2); // Load infinity into d1. | 4673 __ vmov(d1, scratch1, scratch2); // Load infinity into d1. |
| 4674 __ vcmp(d0, d1); | 4674 __ VFPCompareAndSetFlags(d0, d1); |
| 4675 __ vmrs(pc); | |
| 4676 runtime.Branch(eq); // d0 reached infinity. | 4675 runtime.Branch(eq); // d0 reached infinity. |
| 4677 __ vdiv(d0, d2, d0); | 4676 __ vdiv(d0, d2, d0); |
| 4678 __ b(&allocate_return); | 4677 __ b(&allocate_return); |
| 4679 | 4678 |
| 4680 __ bind(&exponent_nonsmi); | 4679 __ bind(&exponent_nonsmi); |
| 4681 // Special handling of raising to the power of -0.5 and 0.5. First check | 4680 // Special handling of raising to the power of -0.5 and 0.5. First check |
| 4682 // that the value is a heap number and that the lower bits (which for both | 4681 // that the value is a heap number and that the lower bits (which for both |
| 4683 // values are zero). | 4682 // values are zero). |
| 4684 heap_number_map = r6; | 4683 heap_number_map = r6; |
| 4685 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); | 4684 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); |
| (...skipping 929 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5615 __ ldr(tmp2, MemOperand(tmp1, index2)); | 5614 __ ldr(tmp2, MemOperand(tmp1, index2)); |
| 5616 __ str(tmp3, MemOperand(tmp1, index2)); | 5615 __ str(tmp3, MemOperand(tmp1, index2)); |
| 5617 __ str(tmp2, MemOperand(tmp1, index1)); | 5616 __ str(tmp2, MemOperand(tmp1, index1)); |
| 5618 | 5617 |
| 5619 Label done; | 5618 Label done; |
| 5620 __ InNewSpace(tmp1, tmp2, eq, &done); | 5619 __ InNewSpace(tmp1, tmp2, eq, &done); |
| 5621 // Possible optimization: do a check that both values are Smis | 5620 // Possible optimization: do a check that both values are Smis |
| 5622 // (or them and test against Smi mask.) | 5621 // (or them and test against Smi mask.) |
| 5623 | 5622 |
| 5624 __ mov(tmp2, tmp1); | 5623 __ mov(tmp2, tmp1); |
| 5625 RecordWriteStub recordWrite1(tmp1, index1, tmp3); | 5624 __ add(index1, index1, tmp1); |
| 5626 __ CallStub(&recordWrite1); | 5625 __ add(index2, index2, tmp1); |
| 5627 | 5626 __ RecordWriteHelper(tmp1, index1, tmp3); |
| 5628 RecordWriteStub recordWrite2(tmp2, index2, tmp3); | 5627 __ RecordWriteHelper(tmp2, index2, tmp3); |
| 5629 __ CallStub(&recordWrite2); | |
| 5630 | |
| 5631 __ bind(&done); | 5628 __ bind(&done); |
| 5632 | 5629 |
| 5633 deferred->BindExit(); | 5630 deferred->BindExit(); |
| 5634 __ LoadRoot(tmp1, Heap::kUndefinedValueRootIndex); | 5631 __ LoadRoot(tmp1, Heap::kUndefinedValueRootIndex); |
| 5635 frame_->EmitPush(tmp1); | 5632 frame_->EmitPush(tmp1); |
| 5636 } | 5633 } |
| 5637 | 5634 |
| 5638 | 5635 |
| 5639 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { | 5636 void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) { |
| 5640 Comment cmnt(masm_, "[ GenerateCallFunction"); | 5637 Comment cmnt(masm_, "[ GenerateCallFunction"); |
| (...skipping 1739 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7380 specialized_on_rhs_ ? "_ConstantRhs" : "", | 7377 specialized_on_rhs_ ? "_ConstantRhs" : "", |
| 7381 BinaryOpIC::GetName(runtime_operands_type_)); | 7378 BinaryOpIC::GetName(runtime_operands_type_)); |
| 7382 return name_; | 7379 return name_; |
| 7383 } | 7380 } |
| 7384 | 7381 |
| 7385 #undef __ | 7382 #undef __ |
| 7386 | 7383 |
| 7387 } } // namespace v8::internal | 7384 } } // namespace v8::internal |
| 7388 | 7385 |
| 7389 #endif // V8_TARGET_ARCH_ARM | 7386 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |