OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/hydrogen-osr.h" | 10 #include "src/hydrogen-osr.h" |
11 #include "src/x64/lithium-codegen-x64.h" | 11 #include "src/x64/lithium-codegen-x64.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 | 16 |
17 // When invoking builtins, we need to record the safepoint in the middle of | 17 // When invoking builtins, we need to record the safepoint in the middle of |
18 // the invoke instruction sequence generated by the macro assembler. | 18 // the invoke instruction sequence generated by the macro assembler. |
19 class SafepointGenerator V8_FINAL : public CallWrapper { | 19 class SafepointGenerator FINAL : public CallWrapper { |
20 public: | 20 public: |
21 SafepointGenerator(LCodeGen* codegen, | 21 SafepointGenerator(LCodeGen* codegen, |
22 LPointerMap* pointers, | 22 LPointerMap* pointers, |
23 Safepoint::DeoptMode mode) | 23 Safepoint::DeoptMode mode) |
24 : codegen_(codegen), | 24 : codegen_(codegen), |
25 pointers_(pointers), | 25 pointers_(pointers), |
26 deopt_mode_(mode) { } | 26 deopt_mode_(mode) { } |
27 virtual ~SafepointGenerator() {} | 27 virtual ~SafepointGenerator() {} |
28 | 28 |
29 virtual void BeforeCall(int call_size) const V8_OVERRIDE {} | 29 virtual void BeforeCall(int call_size) const OVERRIDE {} |
30 | 30 |
31 virtual void AfterCall() const V8_OVERRIDE { | 31 virtual void AfterCall() const OVERRIDE { |
32 codegen_->RecordSafepoint(pointers_, deopt_mode_); | 32 codegen_->RecordSafepoint(pointers_, deopt_mode_); |
33 } | 33 } |
34 | 34 |
35 private: | 35 private: |
36 LCodeGen* codegen_; | 36 LCodeGen* codegen_; |
37 LPointerMap* pointers_; | 37 LPointerMap* pointers_; |
38 Safepoint::DeoptMode deopt_mode_; | 38 Safepoint::DeoptMode deopt_mode_; |
39 }; | 39 }; |
40 | 40 |
41 | 41 |
(...skipping 2621 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2663 __ j(zero, &true_value, Label::kNear); | 2663 __ j(zero, &true_value, Label::kNear); |
2664 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); | 2664 __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); |
2665 __ jmp(&done, Label::kNear); | 2665 __ jmp(&done, Label::kNear); |
2666 __ bind(&true_value); | 2666 __ bind(&true_value); |
2667 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); | 2667 __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); |
2668 __ bind(&done); | 2668 __ bind(&done); |
2669 } | 2669 } |
2670 | 2670 |
2671 | 2671 |
2672 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { | 2672 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { |
2673 class DeferredInstanceOfKnownGlobal V8_FINAL : public LDeferredCode { | 2673 class DeferredInstanceOfKnownGlobal FINAL : public LDeferredCode { |
2674 public: | 2674 public: |
2675 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, | 2675 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, |
2676 LInstanceOfKnownGlobal* instr) | 2676 LInstanceOfKnownGlobal* instr) |
2677 : LDeferredCode(codegen), instr_(instr) { } | 2677 : LDeferredCode(codegen), instr_(instr) { } |
2678 virtual void Generate() V8_OVERRIDE { | 2678 virtual void Generate() OVERRIDE { |
2679 codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); | 2679 codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); |
2680 } | 2680 } |
2681 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 2681 virtual LInstruction* instr() OVERRIDE { return instr_; } |
2682 Label* map_check() { return &map_check_; } | 2682 Label* map_check() { return &map_check_; } |
2683 private: | 2683 private: |
2684 LInstanceOfKnownGlobal* instr_; | 2684 LInstanceOfKnownGlobal* instr_; |
2685 Label map_check_; | 2685 Label map_check_; |
2686 }; | 2686 }; |
2687 | 2687 |
2688 DCHECK(ToRegister(instr->context()).is(rsi)); | 2688 DCHECK(ToRegister(instr->context()).is(rsi)); |
2689 DeferredInstanceOfKnownGlobal* deferred; | 2689 DeferredInstanceOfKnownGlobal* deferred; |
2690 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); | 2690 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); |
2691 | 2691 |
(...skipping 954 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3646 Label is_positive; | 3646 Label is_positive; |
3647 __ j(not_sign, &is_positive, Label::kNear); | 3647 __ j(not_sign, &is_positive, Label::kNear); |
3648 __ negp(input_reg); // Sets flags. | 3648 __ negp(input_reg); // Sets flags. |
3649 DeoptimizeIf(negative, instr->environment()); | 3649 DeoptimizeIf(negative, instr->environment()); |
3650 __ bind(&is_positive); | 3650 __ bind(&is_positive); |
3651 } | 3651 } |
3652 | 3652 |
3653 | 3653 |
3654 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 3654 void LCodeGen::DoMathAbs(LMathAbs* instr) { |
3655 // Class for deferred case. | 3655 // Class for deferred case. |
3656 class DeferredMathAbsTaggedHeapNumber V8_FINAL : public LDeferredCode { | 3656 class DeferredMathAbsTaggedHeapNumber FINAL : public LDeferredCode { |
3657 public: | 3657 public: |
3658 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) | 3658 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) |
3659 : LDeferredCode(codegen), instr_(instr) { } | 3659 : LDeferredCode(codegen), instr_(instr) { } |
3660 virtual void Generate() V8_OVERRIDE { | 3660 virtual void Generate() OVERRIDE { |
3661 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3661 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
3662 } | 3662 } |
3663 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 3663 virtual LInstruction* instr() OVERRIDE { return instr_; } |
3664 private: | 3664 private: |
3665 LMathAbs* instr_; | 3665 LMathAbs* instr_; |
3666 }; | 3666 }; |
3667 | 3667 |
3668 DCHECK(instr->value()->Equals(instr->result())); | 3668 DCHECK(instr->value()->Equals(instr->result())); |
3669 Representation r = instr->hydrogen()->value()->representation(); | 3669 Representation r = instr->hydrogen()->value()->representation(); |
3670 | 3670 |
3671 if (r.IsDouble()) { | 3671 if (r.IsDouble()) { |
3672 XMMRegister scratch = double_scratch0(); | 3672 XMMRegister scratch = double_scratch0(); |
3673 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3673 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4512 DCHECK(ToRegister(instr->left()).is(rdx)); | 4512 DCHECK(ToRegister(instr->left()).is(rdx)); |
4513 DCHECK(ToRegister(instr->right()).is(rax)); | 4513 DCHECK(ToRegister(instr->right()).is(rax)); |
4514 StringAddStub stub(isolate(), | 4514 StringAddStub stub(isolate(), |
4515 instr->hydrogen()->flags(), | 4515 instr->hydrogen()->flags(), |
4516 instr->hydrogen()->pretenure_flag()); | 4516 instr->hydrogen()->pretenure_flag()); |
4517 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); | 4517 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); |
4518 } | 4518 } |
4519 | 4519 |
4520 | 4520 |
4521 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4521 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
4522 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { | 4522 class DeferredStringCharCodeAt FINAL : public LDeferredCode { |
4523 public: | 4523 public: |
4524 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 4524 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) |
4525 : LDeferredCode(codegen), instr_(instr) { } | 4525 : LDeferredCode(codegen), instr_(instr) { } |
4526 virtual void Generate() V8_OVERRIDE { | 4526 virtual void Generate() OVERRIDE { |
4527 codegen()->DoDeferredStringCharCodeAt(instr_); | 4527 codegen()->DoDeferredStringCharCodeAt(instr_); |
4528 } | 4528 } |
4529 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4529 virtual LInstruction* instr() OVERRIDE { return instr_; } |
4530 private: | 4530 private: |
4531 LStringCharCodeAt* instr_; | 4531 LStringCharCodeAt* instr_; |
4532 }; | 4532 }; |
4533 | 4533 |
4534 DeferredStringCharCodeAt* deferred = | 4534 DeferredStringCharCodeAt* deferred = |
4535 new(zone()) DeferredStringCharCodeAt(this, instr); | 4535 new(zone()) DeferredStringCharCodeAt(this, instr); |
4536 | 4536 |
4537 StringCharLoadGenerator::Generate(masm(), | 4537 StringCharLoadGenerator::Generate(masm(), |
4538 ToRegister(instr->string()), | 4538 ToRegister(instr->string()), |
4539 ToRegister(instr->index()), | 4539 ToRegister(instr->index()), |
(...skipping 27 matching lines...) Expand all Loading... |
4567 } | 4567 } |
4568 CallRuntimeFromDeferred( | 4568 CallRuntimeFromDeferred( |
4569 Runtime::kStringCharCodeAtRT, 2, instr, instr->context()); | 4569 Runtime::kStringCharCodeAtRT, 2, instr, instr->context()); |
4570 __ AssertSmi(rax); | 4570 __ AssertSmi(rax); |
4571 __ SmiToInteger32(rax, rax); | 4571 __ SmiToInteger32(rax, rax); |
4572 __ StoreToSafepointRegisterSlot(result, rax); | 4572 __ StoreToSafepointRegisterSlot(result, rax); |
4573 } | 4573 } |
4574 | 4574 |
4575 | 4575 |
4576 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { | 4576 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { |
4577 class DeferredStringCharFromCode V8_FINAL : public LDeferredCode { | 4577 class DeferredStringCharFromCode FINAL : public LDeferredCode { |
4578 public: | 4578 public: |
4579 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) | 4579 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) |
4580 : LDeferredCode(codegen), instr_(instr) { } | 4580 : LDeferredCode(codegen), instr_(instr) { } |
4581 virtual void Generate() V8_OVERRIDE { | 4581 virtual void Generate() OVERRIDE { |
4582 codegen()->DoDeferredStringCharFromCode(instr_); | 4582 codegen()->DoDeferredStringCharFromCode(instr_); |
4583 } | 4583 } |
4584 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4584 virtual LInstruction* instr() OVERRIDE { return instr_; } |
4585 private: | 4585 private: |
4586 LStringCharFromCode* instr_; | 4586 LStringCharFromCode* instr_; |
4587 }; | 4587 }; |
4588 | 4588 |
4589 DeferredStringCharFromCode* deferred = | 4589 DeferredStringCharFromCode* deferred = |
4590 new(zone()) DeferredStringCharFromCode(this, instr); | 4590 new(zone()) DeferredStringCharFromCode(this, instr); |
4591 | 4591 |
4592 DCHECK(instr->hydrogen()->value()->representation().IsInteger32()); | 4592 DCHECK(instr->hydrogen()->value()->representation().IsInteger32()); |
4593 Register char_code = ToRegister(instr->char_code()); | 4593 Register char_code = ToRegister(instr->char_code()); |
4594 Register result = ToRegister(instr->result()); | 4594 Register result = ToRegister(instr->result()); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4639 | 4639 |
4640 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4640 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
4641 LOperand* input = instr->value(); | 4641 LOperand* input = instr->value(); |
4642 LOperand* output = instr->result(); | 4642 LOperand* output = instr->result(); |
4643 | 4643 |
4644 __ LoadUint32(ToDoubleRegister(output), ToRegister(input)); | 4644 __ LoadUint32(ToDoubleRegister(output), ToRegister(input)); |
4645 } | 4645 } |
4646 | 4646 |
4647 | 4647 |
4648 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4648 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
4649 class DeferredNumberTagI V8_FINAL : public LDeferredCode { | 4649 class DeferredNumberTagI FINAL : public LDeferredCode { |
4650 public: | 4650 public: |
4651 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) | 4651 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) |
4652 : LDeferredCode(codegen), instr_(instr) { } | 4652 : LDeferredCode(codegen), instr_(instr) { } |
4653 virtual void Generate() V8_OVERRIDE { | 4653 virtual void Generate() OVERRIDE { |
4654 codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), | 4654 codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), |
4655 instr_->temp2(), SIGNED_INT32); | 4655 instr_->temp2(), SIGNED_INT32); |
4656 } | 4656 } |
4657 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4657 virtual LInstruction* instr() OVERRIDE { return instr_; } |
4658 private: | 4658 private: |
4659 LNumberTagI* instr_; | 4659 LNumberTagI* instr_; |
4660 }; | 4660 }; |
4661 | 4661 |
4662 LOperand* input = instr->value(); | 4662 LOperand* input = instr->value(); |
4663 DCHECK(input->IsRegister() && input->Equals(instr->result())); | 4663 DCHECK(input->IsRegister() && input->Equals(instr->result())); |
4664 Register reg = ToRegister(input); | 4664 Register reg = ToRegister(input); |
4665 | 4665 |
4666 if (SmiValuesAre32Bits()) { | 4666 if (SmiValuesAre32Bits()) { |
4667 __ Integer32ToSmi(reg, reg); | 4667 __ Integer32ToSmi(reg, reg); |
4668 } else { | 4668 } else { |
4669 DCHECK(SmiValuesAre31Bits()); | 4669 DCHECK(SmiValuesAre31Bits()); |
4670 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); | 4670 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); |
4671 __ Integer32ToSmi(reg, reg); | 4671 __ Integer32ToSmi(reg, reg); |
4672 __ j(overflow, deferred->entry()); | 4672 __ j(overflow, deferred->entry()); |
4673 __ bind(deferred->exit()); | 4673 __ bind(deferred->exit()); |
4674 } | 4674 } |
4675 } | 4675 } |
4676 | 4676 |
4677 | 4677 |
4678 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { | 4678 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
4679 class DeferredNumberTagU V8_FINAL : public LDeferredCode { | 4679 class DeferredNumberTagU FINAL : public LDeferredCode { |
4680 public: | 4680 public: |
4681 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) | 4681 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) |
4682 : LDeferredCode(codegen), instr_(instr) { } | 4682 : LDeferredCode(codegen), instr_(instr) { } |
4683 virtual void Generate() V8_OVERRIDE { | 4683 virtual void Generate() OVERRIDE { |
4684 codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), | 4684 codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(), |
4685 instr_->temp2(), UNSIGNED_INT32); | 4685 instr_->temp2(), UNSIGNED_INT32); |
4686 } | 4686 } |
4687 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4687 virtual LInstruction* instr() OVERRIDE { return instr_; } |
4688 private: | 4688 private: |
4689 LNumberTagU* instr_; | 4689 LNumberTagU* instr_; |
4690 }; | 4690 }; |
4691 | 4691 |
4692 LOperand* input = instr->value(); | 4692 LOperand* input = instr->value(); |
4693 DCHECK(input->IsRegister() && input->Equals(instr->result())); | 4693 DCHECK(input->IsRegister() && input->Equals(instr->result())); |
4694 Register reg = ToRegister(input); | 4694 Register reg = ToRegister(input); |
4695 | 4695 |
4696 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); | 4696 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); |
4697 __ cmpl(reg, Immediate(Smi::kMaxValue)); | 4697 __ cmpl(reg, Immediate(Smi::kMaxValue)); |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4756 } | 4756 } |
4757 | 4757 |
4758 // Done. Put the value in temp_xmm into the value of the allocated heap | 4758 // Done. Put the value in temp_xmm into the value of the allocated heap |
4759 // number. | 4759 // number. |
4760 __ bind(&done); | 4760 __ bind(&done); |
4761 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm); | 4761 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), temp_xmm); |
4762 } | 4762 } |
4763 | 4763 |
4764 | 4764 |
4765 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 4765 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
4766 class DeferredNumberTagD V8_FINAL : public LDeferredCode { | 4766 class DeferredNumberTagD FINAL : public LDeferredCode { |
4767 public: | 4767 public: |
4768 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 4768 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) |
4769 : LDeferredCode(codegen), instr_(instr) { } | 4769 : LDeferredCode(codegen), instr_(instr) { } |
4770 virtual void Generate() V8_OVERRIDE { | 4770 virtual void Generate() OVERRIDE { |
4771 codegen()->DoDeferredNumberTagD(instr_); | 4771 codegen()->DoDeferredNumberTagD(instr_); |
4772 } | 4772 } |
4773 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4773 virtual LInstruction* instr() OVERRIDE { return instr_; } |
4774 private: | 4774 private: |
4775 LNumberTagD* instr_; | 4775 LNumberTagD* instr_; |
4776 }; | 4776 }; |
4777 | 4777 |
4778 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4778 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
4779 Register reg = ToRegister(instr->result()); | 4779 Register reg = ToRegister(instr->result()); |
4780 Register tmp = ToRegister(instr->temp()); | 4780 Register tmp = ToRegister(instr->temp()); |
4781 | 4781 |
4782 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); | 4782 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); |
4783 if (FLAG_inline_new) { | 4783 if (FLAG_inline_new) { |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4944 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); | 4944 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); |
4945 | 4945 |
4946 __ jmp(done); | 4946 __ jmp(done); |
4947 __ bind(&bailout); | 4947 __ bind(&bailout); |
4948 DeoptimizeIf(no_condition, instr->environment()); | 4948 DeoptimizeIf(no_condition, instr->environment()); |
4949 } | 4949 } |
4950 } | 4950 } |
4951 | 4951 |
4952 | 4952 |
4953 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { | 4953 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { |
4954 class DeferredTaggedToI V8_FINAL : public LDeferredCode { | 4954 class DeferredTaggedToI FINAL : public LDeferredCode { |
4955 public: | 4955 public: |
4956 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | 4956 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) |
4957 : LDeferredCode(codegen), instr_(instr) { } | 4957 : LDeferredCode(codegen), instr_(instr) { } |
4958 virtual void Generate() V8_OVERRIDE { | 4958 virtual void Generate() OVERRIDE { |
4959 codegen()->DoDeferredTaggedToI(instr_, done()); | 4959 codegen()->DoDeferredTaggedToI(instr_, done()); |
4960 } | 4960 } |
4961 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4961 virtual LInstruction* instr() OVERRIDE { return instr_; } |
4962 private: | 4962 private: |
4963 LTaggedToI* instr_; | 4963 LTaggedToI* instr_; |
4964 }; | 4964 }; |
4965 | 4965 |
4966 LOperand* input = instr->value(); | 4966 LOperand* input = instr->value(); |
4967 DCHECK(input->IsRegister()); | 4967 DCHECK(input->IsRegister()); |
4968 DCHECK(input->Equals(instr->result())); | 4968 DCHECK(input->Equals(instr->result())); |
4969 Register input_reg = ToRegister(input); | 4969 Register input_reg = ToRegister(input); |
4970 | 4970 |
4971 if (instr->hydrogen()->value()->representation().IsSmi()) { | 4971 if (instr->hydrogen()->value()->representation().IsSmi()) { |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5127 RecordSafepointWithRegisters( | 5127 RecordSafepointWithRegisters( |
5128 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); | 5128 instr->pointer_map(), 1, Safepoint::kNoLazyDeopt); |
5129 | 5129 |
5130 __ testp(rax, Immediate(kSmiTagMask)); | 5130 __ testp(rax, Immediate(kSmiTagMask)); |
5131 } | 5131 } |
5132 DeoptimizeIf(zero, instr->environment()); | 5132 DeoptimizeIf(zero, instr->environment()); |
5133 } | 5133 } |
5134 | 5134 |
5135 | 5135 |
5136 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { | 5136 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { |
5137 class DeferredCheckMaps V8_FINAL : public LDeferredCode { | 5137 class DeferredCheckMaps FINAL : public LDeferredCode { |
5138 public: | 5138 public: |
5139 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) | 5139 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) |
5140 : LDeferredCode(codegen), instr_(instr), object_(object) { | 5140 : LDeferredCode(codegen), instr_(instr), object_(object) { |
5141 SetExit(check_maps()); | 5141 SetExit(check_maps()); |
5142 } | 5142 } |
5143 virtual void Generate() V8_OVERRIDE { | 5143 virtual void Generate() OVERRIDE { |
5144 codegen()->DoDeferredInstanceMigration(instr_, object_); | 5144 codegen()->DoDeferredInstanceMigration(instr_, object_); |
5145 } | 5145 } |
5146 Label* check_maps() { return &check_maps_; } | 5146 Label* check_maps() { return &check_maps_; } |
5147 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 5147 virtual LInstruction* instr() OVERRIDE { return instr_; } |
5148 private: | 5148 private: |
5149 LCheckMaps* instr_; | 5149 LCheckMaps* instr_; |
5150 Label check_maps_; | 5150 Label check_maps_; |
5151 Register object_; | 5151 Register object_; |
5152 }; | 5152 }; |
5153 | 5153 |
5154 if (instr->hydrogen()->IsStabilityCheck()) { | 5154 if (instr->hydrogen()->IsStabilityCheck()) { |
5155 const UniqueSet<Map>* maps = instr->hydrogen()->maps(); | 5155 const UniqueSet<Map>* maps = instr->hydrogen()->maps(); |
5156 for (int i = 0; i < maps->size(); ++i) { | 5156 for (int i = 0; i < maps->size(); ++i) { |
5157 AddStabilityDependency(maps->at(i).handle()); | 5157 AddStabilityDependency(maps->at(i).handle()); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5258 XMMRegister result_reg = ToDoubleRegister(instr->result()); | 5258 XMMRegister result_reg = ToDoubleRegister(instr->result()); |
5259 XMMRegister xmm_scratch = double_scratch0(); | 5259 XMMRegister xmm_scratch = double_scratch0(); |
5260 __ movd(result_reg, hi_reg); | 5260 __ movd(result_reg, hi_reg); |
5261 __ psllq(result_reg, 32); | 5261 __ psllq(result_reg, 32); |
5262 __ movd(xmm_scratch, lo_reg); | 5262 __ movd(xmm_scratch, lo_reg); |
5263 __ orps(result_reg, xmm_scratch); | 5263 __ orps(result_reg, xmm_scratch); |
5264 } | 5264 } |
5265 | 5265 |
5266 | 5266 |
5267 void LCodeGen::DoAllocate(LAllocate* instr) { | 5267 void LCodeGen::DoAllocate(LAllocate* instr) { |
5268 class DeferredAllocate V8_FINAL : public LDeferredCode { | 5268 class DeferredAllocate FINAL : public LDeferredCode { |
5269 public: | 5269 public: |
5270 DeferredAllocate(LCodeGen* codegen, LAllocate* instr) | 5270 DeferredAllocate(LCodeGen* codegen, LAllocate* instr) |
5271 : LDeferredCode(codegen), instr_(instr) { } | 5271 : LDeferredCode(codegen), instr_(instr) { } |
5272 virtual void Generate() V8_OVERRIDE { | 5272 virtual void Generate() OVERRIDE { |
5273 codegen()->DoDeferredAllocate(instr_); | 5273 codegen()->DoDeferredAllocate(instr_); |
5274 } | 5274 } |
5275 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 5275 virtual LInstruction* instr() OVERRIDE { return instr_; } |
5276 private: | 5276 private: |
5277 LAllocate* instr_; | 5277 LAllocate* instr_; |
5278 }; | 5278 }; |
5279 | 5279 |
5280 DeferredAllocate* deferred = | 5280 DeferredAllocate* deferred = |
5281 new(zone()) DeferredAllocate(this, instr); | 5281 new(zone()) DeferredAllocate(this, instr); |
5282 | 5282 |
5283 Register result = ToRegister(instr->result()); | 5283 Register result = ToRegister(instr->result()); |
5284 Register temp = ToRegister(instr->temp()); | 5284 Register temp = ToRegister(instr->temp()); |
5285 | 5285 |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5634 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 5634 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
5635 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); | 5635 __ CallRuntimeSaveDoubles(Runtime::kStackGuard); |
5636 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); | 5636 RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0); |
5637 DCHECK(instr->HasEnvironment()); | 5637 DCHECK(instr->HasEnvironment()); |
5638 LEnvironment* env = instr->environment(); | 5638 LEnvironment* env = instr->environment(); |
5639 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 5639 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
5640 } | 5640 } |
5641 | 5641 |
5642 | 5642 |
5643 void LCodeGen::DoStackCheck(LStackCheck* instr) { | 5643 void LCodeGen::DoStackCheck(LStackCheck* instr) { |
5644 class DeferredStackCheck V8_FINAL : public LDeferredCode { | 5644 class DeferredStackCheck FINAL : public LDeferredCode { |
5645 public: | 5645 public: |
5646 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) | 5646 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) |
5647 : LDeferredCode(codegen), instr_(instr) { } | 5647 : LDeferredCode(codegen), instr_(instr) { } |
5648 virtual void Generate() V8_OVERRIDE { | 5648 virtual void Generate() OVERRIDE { |
5649 codegen()->DoDeferredStackCheck(instr_); | 5649 codegen()->DoDeferredStackCheck(instr_); |
5650 } | 5650 } |
5651 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 5651 virtual LInstruction* instr() OVERRIDE { return instr_; } |
5652 private: | 5652 private: |
5653 LStackCheck* instr_; | 5653 LStackCheck* instr_; |
5654 }; | 5654 }; |
5655 | 5655 |
5656 DCHECK(instr->HasEnvironment()); | 5656 DCHECK(instr->HasEnvironment()); |
5657 LEnvironment* env = instr->environment(); | 5657 LEnvironment* env = instr->environment(); |
5658 // There is no LLazyBailout instruction for stack-checks. We have to | 5658 // There is no LLazyBailout instruction for stack-checks. We have to |
5659 // prepare for lazy deoptimization explicitly here. | 5659 // prepare for lazy deoptimization explicitly here. |
5660 if (instr->hydrogen()->is_function_entry()) { | 5660 if (instr->hydrogen()->is_function_entry()) { |
5661 // Perform stack overflow check. | 5661 // Perform stack overflow check. |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5774 __ Push(index); | 5774 __ Push(index); |
5775 __ xorp(rsi, rsi); | 5775 __ xorp(rsi, rsi); |
5776 __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble); | 5776 __ CallRuntimeSaveDoubles(Runtime::kLoadMutableDouble); |
5777 RecordSafepointWithRegisters( | 5777 RecordSafepointWithRegisters( |
5778 instr->pointer_map(), 2, Safepoint::kNoLazyDeopt); | 5778 instr->pointer_map(), 2, Safepoint::kNoLazyDeopt); |
5779 __ StoreToSafepointRegisterSlot(object, rax); | 5779 __ StoreToSafepointRegisterSlot(object, rax); |
5780 } | 5780 } |
5781 | 5781 |
5782 | 5782 |
5783 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { | 5783 void LCodeGen::DoLoadFieldByIndex(LLoadFieldByIndex* instr) { |
5784 class DeferredLoadMutableDouble V8_FINAL : public LDeferredCode { | 5784 class DeferredLoadMutableDouble FINAL : public LDeferredCode { |
5785 public: | 5785 public: |
5786 DeferredLoadMutableDouble(LCodeGen* codegen, | 5786 DeferredLoadMutableDouble(LCodeGen* codegen, |
5787 LLoadFieldByIndex* instr, | 5787 LLoadFieldByIndex* instr, |
5788 Register object, | 5788 Register object, |
5789 Register index) | 5789 Register index) |
5790 : LDeferredCode(codegen), | 5790 : LDeferredCode(codegen), |
5791 instr_(instr), | 5791 instr_(instr), |
5792 object_(object), | 5792 object_(object), |
5793 index_(index) { | 5793 index_(index) { |
5794 } | 5794 } |
5795 virtual void Generate() V8_OVERRIDE { | 5795 virtual void Generate() OVERRIDE { |
5796 codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_); | 5796 codegen()->DoDeferredLoadMutableDouble(instr_, object_, index_); |
5797 } | 5797 } |
5798 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 5798 virtual LInstruction* instr() OVERRIDE { return instr_; } |
5799 private: | 5799 private: |
5800 LLoadFieldByIndex* instr_; | 5800 LLoadFieldByIndex* instr_; |
5801 Register object_; | 5801 Register object_; |
5802 Register index_; | 5802 Register index_; |
5803 }; | 5803 }; |
5804 | 5804 |
5805 Register object = ToRegister(instr->object()); | 5805 Register object = ToRegister(instr->object()); |
5806 Register index = ToRegister(instr->index()); | 5806 Register index = ToRegister(instr->index()); |
5807 | 5807 |
5808 DeferredLoadMutableDouble* deferred; | 5808 DeferredLoadMutableDouble* deferred; |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5850 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 5850 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
5851 RecordSafepoint(Safepoint::kNoLazyDeopt); | 5851 RecordSafepoint(Safepoint::kNoLazyDeopt); |
5852 } | 5852 } |
5853 | 5853 |
5854 | 5854 |
5855 #undef __ | 5855 #undef __ |
5856 | 5856 |
5857 } } // namespace v8::internal | 5857 } } // namespace v8::internal |
5858 | 5858 |
5859 #endif // V8_TARGET_ARCH_X64 | 5859 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |