OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 4583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4594 | 4594 |
4595 | 4595 |
4596 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4596 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
4597 class DeferredNumberTagI V8_FINAL : public LDeferredCode { | 4597 class DeferredNumberTagI V8_FINAL : public LDeferredCode { |
4598 public: | 4598 public: |
4599 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) | 4599 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) |
4600 : LDeferredCode(codegen), instr_(instr) { } | 4600 : LDeferredCode(codegen), instr_(instr) { } |
4601 virtual void Generate() V8_OVERRIDE { | 4601 virtual void Generate() V8_OVERRIDE { |
4602 codegen()->DoDeferredNumberTagI(instr_, | 4602 codegen()->DoDeferredNumberTagI(instr_, |
4603 instr_->value(), | 4603 instr_->value(), |
4604 instr_->temp1(), | |
4605 instr_->temp2(), | |
4604 SIGNED_INT32); | 4606 SIGNED_INT32); |
4605 } | 4607 } |
4606 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4608 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
4607 private: | 4609 private: |
4608 LNumberTagI* instr_; | 4610 LNumberTagI* instr_; |
4609 }; | 4611 }; |
4610 | 4612 |
4611 Register src = ToRegister(instr->value()); | 4613 Register src = ToRegister(instr->value()); |
4612 Register dst = ToRegister(instr->result()); | 4614 Register dst = ToRegister(instr->result()); |
4613 | 4615 |
4614 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); | 4616 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); |
4615 __ SmiTag(dst, src, SetCC); | 4617 __ SmiTag(dst, src, SetCC); |
4616 __ b(vs, deferred->entry()); | 4618 __ b(vs, deferred->entry()); |
4617 __ bind(deferred->exit()); | 4619 __ bind(deferred->exit()); |
4618 } | 4620 } |
4619 | 4621 |
4620 | 4622 |
4621 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { | 4623 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
4622 class DeferredNumberTagU V8_FINAL : public LDeferredCode { | 4624 class DeferredNumberTagU V8_FINAL : public LDeferredCode { |
4623 public: | 4625 public: |
4624 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) | 4626 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) |
4625 : LDeferredCode(codegen), instr_(instr) { } | 4627 : LDeferredCode(codegen), instr_(instr) { } |
4626 virtual void Generate() V8_OVERRIDE { | 4628 virtual void Generate() V8_OVERRIDE { |
4627 codegen()->DoDeferredNumberTagI(instr_, | 4629 codegen()->DoDeferredNumberTagI(instr_, |
4628 instr_->value(), | 4630 instr_->value(), |
4631 instr_->temp1(), | |
4632 instr_->temp2(), | |
4629 UNSIGNED_INT32); | 4633 UNSIGNED_INT32); |
4630 } | 4634 } |
4631 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4635 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
4632 private: | 4636 private: |
4633 LNumberTagU* instr_; | 4637 LNumberTagU* instr_; |
4634 }; | 4638 }; |
4635 | 4639 |
4636 Register input = ToRegister(instr->value()); | 4640 Register input = ToRegister(instr->value()); |
4637 Register result = ToRegister(instr->result()); | 4641 Register result = ToRegister(instr->result()); |
4638 | 4642 |
4639 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); | 4643 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); |
4640 __ cmp(input, Operand(Smi::kMaxValue)); | 4644 __ cmp(input, Operand(Smi::kMaxValue)); |
4641 __ b(hi, deferred->entry()); | 4645 __ b(hi, deferred->entry()); |
4642 __ SmiTag(result, input); | 4646 __ SmiTag(result, input); |
4643 __ bind(deferred->exit()); | 4647 __ bind(deferred->exit()); |
4644 } | 4648 } |
4645 | 4649 |
4646 | 4650 |
4647 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, | 4651 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, |
Sven Panne
2014/02/27 13:52:36
Not really part of this CL, but can we rename this
Benedikt Meurer
2014/02/28 06:14:52
Done.
| |
4648 LOperand* value, | 4652 LOperand* value, |
4653 LOperand* temp1, | |
4654 LOperand* temp2, | |
4649 IntegerSignedness signedness) { | 4655 IntegerSignedness signedness) { |
4650 Label slow; | 4656 Label done, slow; |
4651 Register src = ToRegister(value); | 4657 Register src = ToRegister(value); |
4652 Register dst = ToRegister(instr->result()); | 4658 Register dst = ToRegister(instr->result()); |
4659 Register tmp1 = scratch0(); | |
4660 Register tmp2 = ToRegister(temp1); | |
4661 Register tmp3 = ToRegister(temp2); | |
4653 LowDwVfpRegister dbl_scratch = double_scratch0(); | 4662 LowDwVfpRegister dbl_scratch = double_scratch0(); |
4654 | 4663 |
4655 // Preserve the value of all registers. | |
4656 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | |
4657 | |
4658 Label done; | |
4659 if (signedness == SIGNED_INT32) { | 4664 if (signedness == SIGNED_INT32) { |
4660 // There was overflow, so bits 30 and 31 of the original integer | 4665 // There was overflow, so bits 30 and 31 of the original integer |
4661 // disagree. Try to allocate a heap number in new space and store | 4666 // disagree. Try to allocate a heap number in new space and store |
4662 // the value in there. If that fails, call the runtime system. | 4667 // the value in there. If that fails, call the runtime system. |
4663 if (dst.is(src)) { | 4668 if (dst.is(src)) { |
4664 __ SmiUntag(src, dst); | 4669 __ SmiUntag(src, dst); |
4665 __ eor(src, src, Operand(0x80000000)); | 4670 __ eor(src, src, Operand(0x80000000)); |
4666 } | 4671 } |
4667 __ vmov(dbl_scratch.low(), src); | 4672 __ vmov(dbl_scratch.low(), src); |
4668 __ vcvt_f64_s32(dbl_scratch, dbl_scratch.low()); | 4673 __ vcvt_f64_s32(dbl_scratch, dbl_scratch.low()); |
4669 } else { | 4674 } else { |
4670 __ vmov(dbl_scratch.low(), src); | 4675 __ vmov(dbl_scratch.low(), src); |
4671 __ vcvt_f64_u32(dbl_scratch, dbl_scratch.low()); | 4676 __ vcvt_f64_u32(dbl_scratch, dbl_scratch.low()); |
4672 } | 4677 } |
4673 | 4678 |
4674 if (FLAG_inline_new) { | 4679 if (FLAG_inline_new) { |
4675 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); | 4680 __ LoadRoot(tmp3, Heap::kHeapNumberMapRootIndex); |
4676 __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT); | 4681 __ AllocateHeapNumber(dst, tmp1, tmp2, tmp3, &slow, DONT_TAG_RESULT); |
4677 __ Move(dst, r5); | |
4678 __ b(&done); | 4682 __ b(&done); |
4679 } | 4683 } |
4680 | 4684 |
4681 // Slow case: Call the runtime system to do the number allocation. | 4685 // Slow case: Call the runtime system to do the number allocation. |
4682 __ bind(&slow); | 4686 __ bind(&slow); |
4687 { | |
4688 // TODO(3095996): Put a valid pointer value in the stack slot where the | |
4689 // result register is stored, as this register is in the pointer map, but | |
4690 // contains an integer value. | |
4691 __ mov(dst, Operand::Zero()); | |
4683 | 4692 |
4684 // TODO(3095996): Put a valid pointer value in the stack slot where the result | 4693 // Preserve the value of all registers. |
4685 // register is stored, as this register is in the pointer map, but contains an | 4694 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); |
4686 // integer value. | 4695 |
4687 __ mov(ip, Operand::Zero()); | 4696 // NumberTagI and NumberTagD use the context from the frame, rather than |
4688 __ StoreToSafepointRegisterSlot(ip, dst); | 4697 // the environment's HContext or HInlinedContext value. |
4689 // NumberTagI and NumberTagD use the context from the frame, rather than | 4698 // They only call Runtime::kAllocateHeapNumber. |
4690 // the environment's HContext or HInlinedContext value. | 4699 // The corresponding HChange instructions are added in a phase that does |
4691 // They only call Runtime::kAllocateHeapNumber. | 4700 // not have easy access to the local context. |
4692 // The corresponding HChange instructions are added in a phase that does | 4701 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4693 // not have easy access to the local context. | 4702 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
4694 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4703 RecordSafepointWithRegisters( |
4695 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 4704 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
4696 RecordSafepointWithRegisters( | 4705 __ sub(r0, r0, Operand(kHeapObjectTag)); |
4697 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4706 __ StoreToSafepointRegisterSlot(r0, dst); |
4698 __ Move(dst, r0); | 4707 } |
4699 __ sub(dst, dst, Operand(kHeapObjectTag)); | |
4700 | 4708 |
4701 // Done. Put the value in dbl_scratch into the value of the allocated heap | 4709 // Done. Put the value in dbl_scratch into the value of the allocated heap |
4702 // number. | 4710 // number. |
4703 __ bind(&done); | 4711 __ bind(&done); |
4704 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); | 4712 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset); |
4705 __ add(dst, dst, Operand(kHeapObjectTag)); | 4713 __ add(dst, dst, Operand(kHeapObjectTag)); |
4706 __ StoreToSafepointRegisterSlot(dst, dst); | |
4707 } | 4714 } |
4708 | 4715 |
4709 | 4716 |
4710 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 4717 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
4711 class DeferredNumberTagD V8_FINAL : public LDeferredCode { | 4718 class DeferredNumberTagD V8_FINAL : public LDeferredCode { |
4712 public: | 4719 public: |
4713 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 4720 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
4714 : LDeferredCode(codegen), instr_(instr) { } | 4721 : LDeferredCode(codegen), instr_(instr) { } |
4715 virtual void Generate() V8_OVERRIDE { | 4722 virtual void Generate() V8_OVERRIDE { |
4716 codegen()->DoDeferredNumberTagD(instr_); | 4723 codegen()->DoDeferredNumberTagD(instr_); |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5742 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); | 5749 __ sub(scratch, result, Operand::PointerOffsetFromSmiKey(index)); |
5743 __ ldr(result, FieldMemOperand(scratch, | 5750 __ ldr(result, FieldMemOperand(scratch, |
5744 FixedArray::kHeaderSize - kPointerSize)); | 5751 FixedArray::kHeaderSize - kPointerSize)); |
5745 __ bind(&done); | 5752 __ bind(&done); |
5746 } | 5753 } |
5747 | 5754 |
5748 | 5755 |
5749 #undef __ | 5756 #undef __ |
5750 | 5757 |
5751 } } // namespace v8::internal | 5758 } } // namespace v8::internal |
OLD | NEW |