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 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 } | 416 } |
417 return !is_aborted(); | 417 return !is_aborted(); |
418 } | 418 } |
419 | 419 |
420 | 420 |
421 bool LCodeGen::GenerateDeferredCode() { | 421 bool LCodeGen::GenerateDeferredCode() { |
422 ASSERT(is_generating()); | 422 ASSERT(is_generating()); |
423 if (deferred_.length() > 0) { | 423 if (deferred_.length() > 0) { |
424 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { | 424 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { |
425 LDeferredCode* code = deferred_[i]; | 425 LDeferredCode* code = deferred_[i]; |
| 426 x87_stack_ = X87Stack(code->x87_stack()); |
426 | 427 |
427 int pos = instructions_->at(code->instruction_index())->position(); | 428 int pos = instructions_->at(code->instruction_index())->position(); |
428 RecordAndUpdatePosition(pos); | 429 RecordAndUpdatePosition(pos); |
429 | 430 |
430 Comment(";;; <@%d,#%d> " | 431 Comment(";;; <@%d,#%d> " |
431 "-------------------- Deferred %s --------------------", | 432 "-------------------- Deferred %s --------------------", |
432 code->instruction_index(), | 433 code->instruction_index(), |
433 code->instr()->hydrogen_value()->id(), | 434 code->instr()->hydrogen_value()->id(), |
434 code->instr()->Mnemonic()); | 435 code->instr()->Mnemonic()); |
435 __ bind(code->entry()); | 436 __ bind(code->entry()); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 | 497 |
497 | 498 |
498 void LCodeGen::X87LoadForUsage(X87Register reg) { | 499 void LCodeGen::X87LoadForUsage(X87Register reg) { |
499 ASSERT(x87_stack_.Contains(reg)); | 500 ASSERT(x87_stack_.Contains(reg)); |
500 x87_stack_.Fxch(reg); | 501 x87_stack_.Fxch(reg); |
501 x87_stack_.pop(); | 502 x87_stack_.pop(); |
502 } | 503 } |
503 | 504 |
504 | 505 |
505 void LCodeGen::X87Stack::Fxch(X87Register reg, int other_slot) { | 506 void LCodeGen::X87Stack::Fxch(X87Register reg, int other_slot) { |
| 507 ASSERT(is_mutable_); |
506 ASSERT(Contains(reg) && stack_depth_ > other_slot); | 508 ASSERT(Contains(reg) && stack_depth_ > other_slot); |
507 int i = ArrayIndex(reg); | 509 int i = ArrayIndex(reg); |
508 int st = st2idx(i); | 510 int st = st2idx(i); |
509 if (st != other_slot) { | 511 if (st != other_slot) { |
510 int other_i = st2idx(other_slot); | 512 int other_i = st2idx(other_slot); |
511 X87Register other = stack_[other_i]; | 513 X87Register other = stack_[other_i]; |
512 stack_[other_i] = reg; | 514 stack_[other_i] = reg; |
513 stack_[i] = other; | 515 stack_[i] = other; |
514 if (st == 0) { | 516 if (st == 0) { |
515 __ fxch(other_slot); | 517 __ fxch(other_slot); |
(...skipping 24 matching lines...) Expand all Loading... |
540 | 542 |
541 bool LCodeGen::X87Stack::Contains(X87Register reg) { | 543 bool LCodeGen::X87Stack::Contains(X87Register reg) { |
542 for (int i = 0; i < stack_depth_; i++) { | 544 for (int i = 0; i < stack_depth_; i++) { |
543 if (stack_[i].is(reg)) return true; | 545 if (stack_[i].is(reg)) return true; |
544 } | 546 } |
545 return false; | 547 return false; |
546 } | 548 } |
547 | 549 |
548 | 550 |
549 void LCodeGen::X87Stack::Free(X87Register reg) { | 551 void LCodeGen::X87Stack::Free(X87Register reg) { |
| 552 ASSERT(is_mutable_); |
550 ASSERT(Contains(reg)); | 553 ASSERT(Contains(reg)); |
551 int i = ArrayIndex(reg); | 554 int i = ArrayIndex(reg); |
552 int st = st2idx(i); | 555 int st = st2idx(i); |
553 if (st > 0) { | 556 if (st > 0) { |
554 // keep track of how fstp(i) changes the order of elements | 557 // keep track of how fstp(i) changes the order of elements |
555 int tos_i = st2idx(0); | 558 int tos_i = st2idx(0); |
556 stack_[i] = stack_[tos_i]; | 559 stack_[i] = stack_[tos_i]; |
557 } | 560 } |
558 pop(); | 561 pop(); |
559 __ fstp(st); | 562 __ fstp(st); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 case kX87IntOperand: | 602 case kX87IntOperand: |
600 __ fist_s(dst); | 603 __ fist_s(dst); |
601 break; | 604 break; |
602 default: | 605 default: |
603 UNREACHABLE(); | 606 UNREACHABLE(); |
604 } | 607 } |
605 } | 608 } |
606 | 609 |
607 | 610 |
608 void LCodeGen::X87Stack::PrepareToWrite(X87Register reg) { | 611 void LCodeGen::X87Stack::PrepareToWrite(X87Register reg) { |
| 612 ASSERT(is_mutable_); |
609 if (Contains(reg)) { | 613 if (Contains(reg)) { |
610 Free(reg); | 614 Free(reg); |
611 } | 615 } |
612 // Mark this register as the next register to write to | 616 // Mark this register as the next register to write to |
613 stack_[stack_depth_] = reg; | 617 stack_[stack_depth_] = reg; |
614 } | 618 } |
615 | 619 |
616 | 620 |
617 void LCodeGen::X87Stack::CommitWrite(X87Register reg) { | 621 void LCodeGen::X87Stack::CommitWrite(X87Register reg) { |
| 622 ASSERT(is_mutable_); |
618 // Assert the reg is prepared to write, but not on the virtual stack yet | 623 // Assert the reg is prepared to write, but not on the virtual stack yet |
619 ASSERT(!Contains(reg) && stack_[stack_depth_].is(reg) && | 624 ASSERT(!Contains(reg) && stack_[stack_depth_].is(reg) && |
620 stack_depth_ < X87Register::kNumAllocatableRegisters); | 625 stack_depth_ < X87Register::kNumAllocatableRegisters); |
621 stack_depth_++; | 626 stack_depth_++; |
622 } | 627 } |
623 | 628 |
624 | 629 |
625 void LCodeGen::X87PrepareBinaryOp( | 630 void LCodeGen::X87PrepareBinaryOp( |
626 X87Register left, X87Register right, X87Register result) { | 631 X87Register left, X87Register right, X87Register result) { |
627 // You need to use DefineSameAsFirst for x87 instructions | 632 // You need to use DefineSameAsFirst for x87 instructions |
(...skipping 2206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2834 __ bind(&true_value); | 2839 __ bind(&true_value); |
2835 __ mov(ToRegister(instr->result()), factory()->true_value()); | 2840 __ mov(ToRegister(instr->result()), factory()->true_value()); |
2836 __ bind(&done); | 2841 __ bind(&done); |
2837 } | 2842 } |
2838 | 2843 |
2839 | 2844 |
2840 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { | 2845 void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { |
2841 class DeferredInstanceOfKnownGlobal V8_FINAL : public LDeferredCode { | 2846 class DeferredInstanceOfKnownGlobal V8_FINAL : public LDeferredCode { |
2842 public: | 2847 public: |
2843 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, | 2848 DeferredInstanceOfKnownGlobal(LCodeGen* codegen, |
2844 LInstanceOfKnownGlobal* instr) | 2849 LInstanceOfKnownGlobal* instr, |
2845 : LDeferredCode(codegen), instr_(instr) { } | 2850 const X87Stack& x87_stack) |
| 2851 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
2846 virtual void Generate() V8_OVERRIDE { | 2852 virtual void Generate() V8_OVERRIDE { |
2847 codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); | 2853 codegen()->DoDeferredInstanceOfKnownGlobal(instr_, &map_check_); |
2848 } | 2854 } |
2849 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 2855 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
2850 Label* map_check() { return &map_check_; } | 2856 Label* map_check() { return &map_check_; } |
2851 private: | 2857 private: |
2852 LInstanceOfKnownGlobal* instr_; | 2858 LInstanceOfKnownGlobal* instr_; |
2853 Label map_check_; | 2859 Label map_check_; |
2854 }; | 2860 }; |
2855 | 2861 |
2856 DeferredInstanceOfKnownGlobal* deferred; | 2862 DeferredInstanceOfKnownGlobal* deferred; |
2857 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr); | 2863 deferred = new(zone()) DeferredInstanceOfKnownGlobal(this, instr, x87_stack_); |
2858 | 2864 |
2859 Label done, false_result; | 2865 Label done, false_result; |
2860 Register object = ToRegister(instr->value()); | 2866 Register object = ToRegister(instr->value()); |
2861 Register temp = ToRegister(instr->temp()); | 2867 Register temp = ToRegister(instr->temp()); |
2862 | 2868 |
2863 // A Smi is not an instance of anything. | 2869 // A Smi is not an instance of anything. |
2864 __ JumpIfSmi(object, &false_result); | 2870 __ JumpIfSmi(object, &false_result); |
2865 | 2871 |
2866 // This is the inlined call site instanceof cache. The two occurences of the | 2872 // This is the inlined call site instanceof cache. The two occurences of the |
2867 // hole value will be patched to the last map/result pair generated by the | 2873 // hole value will be patched to the last map/result pair generated by the |
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3801 __ neg(input_reg); // Sets flags. | 3807 __ neg(input_reg); // Sets flags. |
3802 DeoptimizeIf(negative, instr->environment()); | 3808 DeoptimizeIf(negative, instr->environment()); |
3803 __ bind(&is_positive); | 3809 __ bind(&is_positive); |
3804 } | 3810 } |
3805 | 3811 |
3806 | 3812 |
3807 void LCodeGen::DoMathAbs(LMathAbs* instr) { | 3813 void LCodeGen::DoMathAbs(LMathAbs* instr) { |
3808 // Class for deferred case. | 3814 // Class for deferred case. |
3809 class DeferredMathAbsTaggedHeapNumber V8_FINAL : public LDeferredCode { | 3815 class DeferredMathAbsTaggedHeapNumber V8_FINAL : public LDeferredCode { |
3810 public: | 3816 public: |
3811 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, LMathAbs* instr) | 3817 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
3812 : LDeferredCode(codegen), instr_(instr) { } | 3818 LMathAbs* instr, |
| 3819 const X87Stack& x87_stack) |
| 3820 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
3813 virtual void Generate() V8_OVERRIDE { | 3821 virtual void Generate() V8_OVERRIDE { |
3814 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 3822 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
3815 } | 3823 } |
3816 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 3824 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
3817 private: | 3825 private: |
3818 LMathAbs* instr_; | 3826 LMathAbs* instr_; |
3819 }; | 3827 }; |
3820 | 3828 |
3821 ASSERT(instr->value()->Equals(instr->result())); | 3829 ASSERT(instr->value()->Equals(instr->result())); |
3822 Representation r = instr->hydrogen()->value()->representation(); | 3830 Representation r = instr->hydrogen()->value()->representation(); |
3823 | 3831 |
3824 CpuFeatureScope scope(masm(), SSE2); | 3832 CpuFeatureScope scope(masm(), SSE2); |
3825 if (r.IsDouble()) { | 3833 if (r.IsDouble()) { |
3826 XMMRegister scratch = xmm0; | 3834 XMMRegister scratch = xmm0; |
3827 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3835 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
3828 __ xorps(scratch, scratch); | 3836 __ xorps(scratch, scratch); |
3829 __ subsd(scratch, input_reg); | 3837 __ subsd(scratch, input_reg); |
3830 __ pand(input_reg, scratch); | 3838 __ pand(input_reg, scratch); |
3831 } else if (r.IsSmiOrInteger32()) { | 3839 } else if (r.IsSmiOrInteger32()) { |
3832 EmitIntegerMathAbs(instr); | 3840 EmitIntegerMathAbs(instr); |
3833 } else { // Tagged case. | 3841 } else { // Tagged case. |
3834 DeferredMathAbsTaggedHeapNumber* deferred = | 3842 DeferredMathAbsTaggedHeapNumber* deferred = |
3835 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr); | 3843 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_); |
3836 Register input_reg = ToRegister(instr->value()); | 3844 Register input_reg = ToRegister(instr->value()); |
3837 // Smi check. | 3845 // Smi check. |
3838 __ JumpIfNotSmi(input_reg, deferred->entry()); | 3846 __ JumpIfNotSmi(input_reg, deferred->entry()); |
3839 EmitIntegerMathAbs(instr); | 3847 EmitIntegerMathAbs(instr); |
3840 __ bind(deferred->exit()); | 3848 __ bind(deferred->exit()); |
3841 } | 3849 } |
3842 } | 3850 } |
3843 | 3851 |
3844 | 3852 |
3845 void LCodeGen::DoMathFloor(LMathFloor* instr) { | 3853 void LCodeGen::DoMathFloor(LMathFloor* instr) { |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4041 ASSERT(exponent_type.IsDouble()); | 4049 ASSERT(exponent_type.IsDouble()); |
4042 MathPowStub stub(MathPowStub::DOUBLE); | 4050 MathPowStub stub(MathPowStub::DOUBLE); |
4043 __ CallStub(&stub); | 4051 __ CallStub(&stub); |
4044 } | 4052 } |
4045 } | 4053 } |
4046 | 4054 |
4047 | 4055 |
4048 void LCodeGen::DoRandom(LRandom* instr) { | 4056 void LCodeGen::DoRandom(LRandom* instr) { |
4049 class DeferredDoRandom V8_FINAL : public LDeferredCode { | 4057 class DeferredDoRandom V8_FINAL : public LDeferredCode { |
4050 public: | 4058 public: |
4051 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) | 4059 DeferredDoRandom(LCodeGen* codegen, |
4052 : LDeferredCode(codegen), instr_(instr) { } | 4060 LRandom* instr, |
| 4061 const X87Stack& x87_stack) |
| 4062 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
4053 virtual void Generate() V8_OVERRIDE { codegen()->DoDeferredRandom(instr_); } | 4063 virtual void Generate() V8_OVERRIDE { codegen()->DoDeferredRandom(instr_); } |
4054 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4064 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
4055 private: | 4065 private: |
4056 LRandom* instr_; | 4066 LRandom* instr_; |
4057 }; | 4067 }; |
4058 | 4068 |
4059 DeferredDoRandom* deferred = new(zone()) DeferredDoRandom(this, instr); | 4069 DeferredDoRandom* deferred = |
| 4070 new(zone()) DeferredDoRandom(this, instr, x87_stack_); |
4060 | 4071 |
4061 CpuFeatureScope scope(masm(), SSE2); | 4072 CpuFeatureScope scope(masm(), SSE2); |
4062 // Having marked this instruction as a call we can use any | 4073 // Having marked this instruction as a call we can use any |
4063 // registers. | 4074 // registers. |
4064 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); | 4075 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
4065 ASSERT(ToRegister(instr->global_object()).is(eax)); | 4076 ASSERT(ToRegister(instr->global_object()).is(eax)); |
4066 // Assert that the register size is indeed the size of each seed. | 4077 // Assert that the register size is indeed the size of each seed. |
4067 static const int kSeedSize = sizeof(uint32_t); | 4078 static const int kSeedSize = sizeof(uint32_t); |
4068 STATIC_ASSERT(kPointerSize == kSeedSize); | 4079 STATIC_ASSERT(kPointerSize == kSeedSize); |
4069 | 4080 |
(...skipping 706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4776 RecordSafepointWithRegisters( | 4787 RecordSafepointWithRegisters( |
4777 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 4788 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
4778 } | 4789 } |
4779 __ bind(¬_applicable); | 4790 __ bind(¬_applicable); |
4780 } | 4791 } |
4781 | 4792 |
4782 | 4793 |
4783 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { | 4794 void LCodeGen::DoStringCharCodeAt(LStringCharCodeAt* instr) { |
4784 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { | 4795 class DeferredStringCharCodeAt V8_FINAL : public LDeferredCode { |
4785 public: | 4796 public: |
4786 DeferredStringCharCodeAt(LCodeGen* codegen, LStringCharCodeAt* instr) | 4797 DeferredStringCharCodeAt(LCodeGen* codegen, |
4787 : LDeferredCode(codegen), instr_(instr) { } | 4798 LStringCharCodeAt* instr, |
| 4799 const X87Stack& x87_stack) |
| 4800 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
4788 virtual void Generate() V8_OVERRIDE { | 4801 virtual void Generate() V8_OVERRIDE { |
4789 codegen()->DoDeferredStringCharCodeAt(instr_); | 4802 codegen()->DoDeferredStringCharCodeAt(instr_); |
4790 } | 4803 } |
4791 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4804 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
4792 private: | 4805 private: |
4793 LStringCharCodeAt* instr_; | 4806 LStringCharCodeAt* instr_; |
4794 }; | 4807 }; |
4795 | 4808 |
4796 DeferredStringCharCodeAt* deferred = | 4809 DeferredStringCharCodeAt* deferred = |
4797 new(zone()) DeferredStringCharCodeAt(this, instr); | 4810 new(zone()) DeferredStringCharCodeAt(this, instr, x87_stack_); |
4798 | 4811 |
4799 StringCharLoadGenerator::Generate(masm(), | 4812 StringCharLoadGenerator::Generate(masm(), |
4800 factory(), | 4813 factory(), |
4801 ToRegister(instr->string()), | 4814 ToRegister(instr->string()), |
4802 ToRegister(instr->index()), | 4815 ToRegister(instr->index()), |
4803 ToRegister(instr->result()), | 4816 ToRegister(instr->result()), |
4804 deferred->entry()); | 4817 deferred->entry()); |
4805 __ bind(deferred->exit()); | 4818 __ bind(deferred->exit()); |
4806 } | 4819 } |
4807 | 4820 |
(...skipping 25 matching lines...) Expand all Loading... |
4833 instr, instr->context()); | 4846 instr, instr->context()); |
4834 __ AssertSmi(eax); | 4847 __ AssertSmi(eax); |
4835 __ SmiUntag(eax); | 4848 __ SmiUntag(eax); |
4836 __ StoreToSafepointRegisterSlot(result, eax); | 4849 __ StoreToSafepointRegisterSlot(result, eax); |
4837 } | 4850 } |
4838 | 4851 |
4839 | 4852 |
4840 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { | 4853 void LCodeGen::DoStringCharFromCode(LStringCharFromCode* instr) { |
4841 class DeferredStringCharFromCode V8_FINAL : public LDeferredCode { | 4854 class DeferredStringCharFromCode V8_FINAL : public LDeferredCode { |
4842 public: | 4855 public: |
4843 DeferredStringCharFromCode(LCodeGen* codegen, LStringCharFromCode* instr) | 4856 DeferredStringCharFromCode(LCodeGen* codegen, |
4844 : LDeferredCode(codegen), instr_(instr) { } | 4857 LStringCharFromCode* instr, |
| 4858 const X87Stack& x87_stack) |
| 4859 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
4845 virtual void Generate() V8_OVERRIDE { | 4860 virtual void Generate() V8_OVERRIDE { |
4846 codegen()->DoDeferredStringCharFromCode(instr_); | 4861 codegen()->DoDeferredStringCharFromCode(instr_); |
4847 } | 4862 } |
4848 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4863 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
4849 private: | 4864 private: |
4850 LStringCharFromCode* instr_; | 4865 LStringCharFromCode* instr_; |
4851 }; | 4866 }; |
4852 | 4867 |
4853 DeferredStringCharFromCode* deferred = | 4868 DeferredStringCharFromCode* deferred = |
4854 new(zone()) DeferredStringCharFromCode(this, instr); | 4869 new(zone()) DeferredStringCharFromCode(this, instr, x87_stack_); |
4855 | 4870 |
4856 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); | 4871 ASSERT(instr->hydrogen()->value()->representation().IsInteger32()); |
4857 Register char_code = ToRegister(instr->char_code()); | 4872 Register char_code = ToRegister(instr->char_code()); |
4858 Register result = ToRegister(instr->result()); | 4873 Register result = ToRegister(instr->result()); |
4859 ASSERT(!char_code.is(result)); | 4874 ASSERT(!char_code.is(result)); |
4860 | 4875 |
4861 __ cmp(char_code, String::kMaxOneByteCharCode); | 4876 __ cmp(char_code, String::kMaxOneByteCharCode); |
4862 __ j(above, deferred->entry()); | 4877 __ j(above, deferred->entry()); |
4863 __ Set(result, Immediate(factory()->single_character_string_cache())); | 4878 __ Set(result, Immediate(factory()->single_character_string_cache())); |
4864 __ mov(result, FieldOperand(result, | 4879 __ mov(result, FieldOperand(result, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4932 | 4947 |
4933 __ LoadUint32(ToDoubleRegister(output), | 4948 __ LoadUint32(ToDoubleRegister(output), |
4934 ToRegister(input), | 4949 ToRegister(input), |
4935 ToDoubleRegister(temp)); | 4950 ToDoubleRegister(temp)); |
4936 } | 4951 } |
4937 | 4952 |
4938 | 4953 |
4939 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 4954 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { |
4940 class DeferredNumberTagI V8_FINAL : public LDeferredCode { | 4955 class DeferredNumberTagI V8_FINAL : public LDeferredCode { |
4941 public: | 4956 public: |
4942 DeferredNumberTagI(LCodeGen* codegen, LNumberTagI* instr) | 4957 DeferredNumberTagI(LCodeGen* codegen, |
4943 : LDeferredCode(codegen), instr_(instr) { } | 4958 LNumberTagI* instr, |
| 4959 const X87Stack& x87_stack) |
| 4960 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
4944 virtual void Generate() V8_OVERRIDE { | 4961 virtual void Generate() V8_OVERRIDE { |
4945 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32); | 4962 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32); |
4946 } | 4963 } |
4947 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4964 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
4948 private: | 4965 private: |
4949 LNumberTagI* instr_; | 4966 LNumberTagI* instr_; |
4950 }; | 4967 }; |
4951 | 4968 |
4952 LOperand* input = instr->value(); | 4969 LOperand* input = instr->value(); |
4953 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 4970 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
4954 Register reg = ToRegister(input); | 4971 Register reg = ToRegister(input); |
4955 | 4972 |
4956 DeferredNumberTagI* deferred = new(zone()) DeferredNumberTagI(this, instr); | 4973 DeferredNumberTagI* deferred = |
| 4974 new(zone()) DeferredNumberTagI(this, instr, x87_stack_); |
4957 __ SmiTag(reg); | 4975 __ SmiTag(reg); |
4958 __ j(overflow, deferred->entry()); | 4976 __ j(overflow, deferred->entry()); |
4959 __ bind(deferred->exit()); | 4977 __ bind(deferred->exit()); |
4960 } | 4978 } |
4961 | 4979 |
4962 | 4980 |
4963 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { | 4981 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { |
4964 class DeferredNumberTagU V8_FINAL : public LDeferredCode { | 4982 class DeferredNumberTagU V8_FINAL : public LDeferredCode { |
4965 public: | 4983 public: |
4966 DeferredNumberTagU(LCodeGen* codegen, LNumberTagU* instr) | 4984 DeferredNumberTagU(LCodeGen* codegen, |
4967 : LDeferredCode(codegen), instr_(instr) { } | 4985 LNumberTagU* instr, |
| 4986 const X87Stack& x87_stack) |
| 4987 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
4968 virtual void Generate() V8_OVERRIDE { | 4988 virtual void Generate() V8_OVERRIDE { |
4969 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), UNSIGNED_INT32); | 4989 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), UNSIGNED_INT32); |
4970 } | 4990 } |
4971 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 4991 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
4972 private: | 4992 private: |
4973 LNumberTagU* instr_; | 4993 LNumberTagU* instr_; |
4974 }; | 4994 }; |
4975 | 4995 |
4976 LOperand* input = instr->value(); | 4996 LOperand* input = instr->value(); |
4977 ASSERT(input->IsRegister() && input->Equals(instr->result())); | 4997 ASSERT(input->IsRegister() && input->Equals(instr->result())); |
4978 Register reg = ToRegister(input); | 4998 Register reg = ToRegister(input); |
4979 | 4999 |
4980 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); | 5000 DeferredNumberTagU* deferred = |
| 5001 new(zone()) DeferredNumberTagU(this, instr, x87_stack_); |
4981 __ cmp(reg, Immediate(Smi::kMaxValue)); | 5002 __ cmp(reg, Immediate(Smi::kMaxValue)); |
4982 __ j(above, deferred->entry()); | 5003 __ j(above, deferred->entry()); |
4983 __ SmiTag(reg); | 5004 __ SmiTag(reg); |
4984 __ bind(deferred->exit()); | 5005 __ bind(deferred->exit()); |
4985 } | 5006 } |
4986 | 5007 |
4987 | 5008 |
4988 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, | 5009 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, |
4989 LOperand* value, | 5010 LOperand* value, |
4990 IntegerSignedness signedness) { | 5011 IntegerSignedness signedness) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5059 } else { | 5080 } else { |
5060 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 5081 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
5061 } | 5082 } |
5062 __ StoreToSafepointRegisterSlot(reg, reg); | 5083 __ StoreToSafepointRegisterSlot(reg, reg); |
5063 } | 5084 } |
5064 | 5085 |
5065 | 5086 |
5066 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 5087 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
5067 class DeferredNumberTagD V8_FINAL : public LDeferredCode { | 5088 class DeferredNumberTagD V8_FINAL : public LDeferredCode { |
5068 public: | 5089 public: |
5069 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) | 5090 DeferredNumberTagD(LCodeGen* codegen, |
5070 : LDeferredCode(codegen), instr_(instr) { } | 5091 LNumberTagD* instr, |
| 5092 const X87Stack& x87_stack) |
| 5093 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
5071 virtual void Generate() V8_OVERRIDE { | 5094 virtual void Generate() V8_OVERRIDE { |
5072 codegen()->DoDeferredNumberTagD(instr_); | 5095 codegen()->DoDeferredNumberTagD(instr_); |
5073 } | 5096 } |
5074 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 5097 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
5075 private: | 5098 private: |
5076 LNumberTagD* instr_; | 5099 LNumberTagD* instr_; |
5077 }; | 5100 }; |
5078 | 5101 |
5079 Register reg = ToRegister(instr->result()); | 5102 Register reg = ToRegister(instr->result()); |
5080 | 5103 |
5081 bool use_sse2 = CpuFeatures::IsSupported(SSE2); | 5104 bool use_sse2 = CpuFeatures::IsSupported(SSE2); |
5082 if (!use_sse2) { | 5105 if (!use_sse2) { |
5083 // Put the value to the top of stack | 5106 // Put the value to the top of stack |
5084 X87Register src = ToX87Register(instr->value()); | 5107 X87Register src = ToX87Register(instr->value()); |
5085 X87LoadForUsage(src); | 5108 X87LoadForUsage(src); |
5086 } | 5109 } |
5087 | 5110 |
5088 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); | 5111 DeferredNumberTagD* deferred = |
| 5112 new(zone()) DeferredNumberTagD(this, instr, x87_stack_); |
5089 if (FLAG_inline_new) { | 5113 if (FLAG_inline_new) { |
5090 Register tmp = ToRegister(instr->temp()); | 5114 Register tmp = ToRegister(instr->temp()); |
5091 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); | 5115 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); |
5092 } else { | 5116 } else { |
5093 __ jmp(deferred->entry()); | 5117 __ jmp(deferred->entry()); |
5094 } | 5118 } |
5095 __ bind(deferred->exit()); | 5119 __ bind(deferred->exit()); |
5096 if (use_sse2) { | 5120 if (use_sse2) { |
5097 CpuFeatureScope scope(masm(), SSE2); | 5121 CpuFeatureScope scope(masm(), SSE2); |
5098 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 5122 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5360 } else { | 5384 } else { |
5361 UNREACHABLE(); | 5385 UNREACHABLE(); |
5362 } | 5386 } |
5363 __ bind(&done); | 5387 __ bind(&done); |
5364 } | 5388 } |
5365 | 5389 |
5366 | 5390 |
5367 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { | 5391 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { |
5368 class DeferredTaggedToI V8_FINAL : public LDeferredCode { | 5392 class DeferredTaggedToI V8_FINAL : public LDeferredCode { |
5369 public: | 5393 public: |
5370 DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr) | 5394 DeferredTaggedToI(LCodeGen* codegen, |
5371 : LDeferredCode(codegen), instr_(instr) { } | 5395 LTaggedToI* instr, |
| 5396 const X87Stack& x87_stack) |
| 5397 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
5372 virtual void Generate() V8_OVERRIDE { | 5398 virtual void Generate() V8_OVERRIDE { |
5373 codegen()->DoDeferredTaggedToI(instr_); | 5399 codegen()->DoDeferredTaggedToI(instr_); |
5374 } | 5400 } |
5375 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 5401 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
5376 private: | 5402 private: |
5377 LTaggedToI* instr_; | 5403 LTaggedToI* instr_; |
5378 }; | 5404 }; |
5379 | 5405 |
5380 LOperand* input = instr->value(); | 5406 LOperand* input = instr->value(); |
5381 ASSERT(input->IsRegister()); | 5407 ASSERT(input->IsRegister()); |
5382 Register input_reg = ToRegister(input); | 5408 Register input_reg = ToRegister(input); |
5383 ASSERT(input_reg.is(ToRegister(instr->result()))); | 5409 ASSERT(input_reg.is(ToRegister(instr->result()))); |
5384 | 5410 |
5385 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); | 5411 DeferredTaggedToI* deferred = |
| 5412 new(zone()) DeferredTaggedToI(this, instr, x87_stack_); |
5386 | 5413 |
5387 __ JumpIfNotSmi(input_reg, deferred->entry()); | 5414 __ JumpIfNotSmi(input_reg, deferred->entry()); |
5388 __ SmiUntag(input_reg); | 5415 __ SmiUntag(input_reg); |
5389 __ bind(deferred->exit()); | 5416 __ bind(deferred->exit()); |
5390 } | 5417 } |
5391 | 5418 |
5392 | 5419 |
5393 void LCodeGen::DoDeferredTaggedToINoSSE2(LTaggedToINoSSE2* instr) { | 5420 void LCodeGen::DoDeferredTaggedToINoSSE2(LTaggedToINoSSE2* instr) { |
5394 Label done, heap_number; | 5421 Label done, heap_number; |
5395 Register result_reg = ToRegister(instr->result()); | 5422 Register result_reg = ToRegister(instr->result()); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5521 // If the negative subtraction overflows into a positive number, there was an | 5548 // If the negative subtraction overflows into a positive number, there was an |
5522 // overflow --> deopt. | 5549 // overflow --> deopt. |
5523 DeoptimizeIf(positive, instr->environment()); | 5550 DeoptimizeIf(positive, instr->environment()); |
5524 __ bind(&done); | 5551 __ bind(&done); |
5525 } | 5552 } |
5526 | 5553 |
5527 | 5554 |
5528 void LCodeGen::DoTaggedToINoSSE2(LTaggedToINoSSE2* instr) { | 5555 void LCodeGen::DoTaggedToINoSSE2(LTaggedToINoSSE2* instr) { |
5529 class DeferredTaggedToINoSSE2 V8_FINAL : public LDeferredCode { | 5556 class DeferredTaggedToINoSSE2 V8_FINAL : public LDeferredCode { |
5530 public: | 5557 public: |
5531 DeferredTaggedToINoSSE2(LCodeGen* codegen, LTaggedToINoSSE2* instr) | 5558 DeferredTaggedToINoSSE2(LCodeGen* codegen, |
5532 : LDeferredCode(codegen), instr_(instr) { } | 5559 LTaggedToINoSSE2* instr, |
| 5560 const X87Stack& x87_stack) |
| 5561 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
5533 virtual void Generate() V8_OVERRIDE { | 5562 virtual void Generate() V8_OVERRIDE { |
5534 codegen()->DoDeferredTaggedToINoSSE2(instr_); | 5563 codegen()->DoDeferredTaggedToINoSSE2(instr_); |
5535 } | 5564 } |
5536 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 5565 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
5537 private: | 5566 private: |
5538 LTaggedToINoSSE2* instr_; | 5567 LTaggedToINoSSE2* instr_; |
5539 }; | 5568 }; |
5540 | 5569 |
5541 LOperand* input = instr->value(); | 5570 LOperand* input = instr->value(); |
5542 ASSERT(input->IsRegister()); | 5571 ASSERT(input->IsRegister()); |
5543 Register input_reg = ToRegister(input); | 5572 Register input_reg = ToRegister(input); |
5544 ASSERT(input_reg.is(ToRegister(instr->result()))); | 5573 ASSERT(input_reg.is(ToRegister(instr->result()))); |
5545 | 5574 |
5546 DeferredTaggedToINoSSE2* deferred = | 5575 DeferredTaggedToINoSSE2* deferred = |
5547 new(zone()) DeferredTaggedToINoSSE2(this, instr); | 5576 new(zone()) DeferredTaggedToINoSSE2(this, instr, x87_stack_); |
5548 | 5577 |
5549 // Smi check. | 5578 // Smi check. |
5550 __ JumpIfNotSmi(input_reg, deferred->entry()); | 5579 __ JumpIfNotSmi(input_reg, deferred->entry()); |
5551 __ SmiUntag(input_reg); // Untag smi. | 5580 __ SmiUntag(input_reg); // Untag smi. |
5552 __ bind(deferred->exit()); | 5581 __ bind(deferred->exit()); |
5553 } | 5582 } |
5554 | 5583 |
5555 | 5584 |
5556 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { | 5585 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { |
5557 LOperand* input = instr->value(); | 5586 LOperand* input = instr->value(); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5817 | 5846 |
5818 __ test(eax, Immediate(kSmiTagMask)); | 5847 __ test(eax, Immediate(kSmiTagMask)); |
5819 } | 5848 } |
5820 DeoptimizeIf(zero, instr->environment()); | 5849 DeoptimizeIf(zero, instr->environment()); |
5821 } | 5850 } |
5822 | 5851 |
5823 | 5852 |
5824 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { | 5853 void LCodeGen::DoCheckMaps(LCheckMaps* instr) { |
5825 class DeferredCheckMaps V8_FINAL : public LDeferredCode { | 5854 class DeferredCheckMaps V8_FINAL : public LDeferredCode { |
5826 public: | 5855 public: |
5827 DeferredCheckMaps(LCodeGen* codegen, LCheckMaps* instr, Register object) | 5856 DeferredCheckMaps(LCodeGen* codegen, |
5828 : LDeferredCode(codegen), instr_(instr), object_(object) { | 5857 LCheckMaps* instr, |
| 5858 Register object, |
| 5859 const X87Stack& x87_stack) |
| 5860 : LDeferredCode(codegen, x87_stack), instr_(instr), object_(object) { |
5829 SetExit(check_maps()); | 5861 SetExit(check_maps()); |
5830 } | 5862 } |
5831 virtual void Generate() V8_OVERRIDE { | 5863 virtual void Generate() V8_OVERRIDE { |
5832 codegen()->DoDeferredInstanceMigration(instr_, object_); | 5864 codegen()->DoDeferredInstanceMigration(instr_, object_); |
5833 } | 5865 } |
5834 Label* check_maps() { return &check_maps_; } | 5866 Label* check_maps() { return &check_maps_; } |
5835 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 5867 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
5836 private: | 5868 private: |
5837 LCheckMaps* instr_; | 5869 LCheckMaps* instr_; |
5838 Label check_maps_; | 5870 Label check_maps_; |
5839 Register object_; | 5871 Register object_; |
5840 }; | 5872 }; |
5841 | 5873 |
5842 if (instr->hydrogen()->CanOmitMapChecks()) return; | 5874 if (instr->hydrogen()->CanOmitMapChecks()) return; |
5843 | 5875 |
5844 LOperand* input = instr->value(); | 5876 LOperand* input = instr->value(); |
5845 ASSERT(input->IsRegister()); | 5877 ASSERT(input->IsRegister()); |
5846 Register reg = ToRegister(input); | 5878 Register reg = ToRegister(input); |
5847 | 5879 |
5848 SmallMapList* map_set = instr->hydrogen()->map_set(); | 5880 SmallMapList* map_set = instr->hydrogen()->map_set(); |
5849 | 5881 |
5850 DeferredCheckMaps* deferred = NULL; | 5882 DeferredCheckMaps* deferred = NULL; |
5851 if (instr->hydrogen()->has_migration_target()) { | 5883 if (instr->hydrogen()->has_migration_target()) { |
5852 deferred = new(zone()) DeferredCheckMaps(this, instr, reg); | 5884 deferred = new(zone()) DeferredCheckMaps(this, instr, reg, x87_stack_); |
5853 __ bind(deferred->check_maps()); | 5885 __ bind(deferred->check_maps()); |
5854 } | 5886 } |
5855 | 5887 |
5856 Label success; | 5888 Label success; |
5857 for (int i = 0; i < map_set->length() - 1; i++) { | 5889 for (int i = 0; i < map_set->length() - 1; i++) { |
5858 Handle<Map> map = map_set->at(i); | 5890 Handle<Map> map = map_set->at(i); |
5859 __ CompareMap(reg, map, &success); | 5891 __ CompareMap(reg, map, &success); |
5860 __ j(equal, &success); | 5892 __ j(equal, &success); |
5861 } | 5893 } |
5862 | 5894 |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6040 } | 6072 } |
6041 __ SmiUntag(result_reg); | 6073 __ SmiUntag(result_reg); |
6042 __ ClampUint8(result_reg); | 6074 __ ClampUint8(result_reg); |
6043 __ bind(&done); | 6075 __ bind(&done); |
6044 } | 6076 } |
6045 | 6077 |
6046 | 6078 |
6047 void LCodeGen::DoAllocate(LAllocate* instr) { | 6079 void LCodeGen::DoAllocate(LAllocate* instr) { |
6048 class DeferredAllocate V8_FINAL : public LDeferredCode { | 6080 class DeferredAllocate V8_FINAL : public LDeferredCode { |
6049 public: | 6081 public: |
6050 DeferredAllocate(LCodeGen* codegen, LAllocate* instr) | 6082 DeferredAllocate(LCodeGen* codegen, |
6051 : LDeferredCode(codegen), instr_(instr) { } | 6083 LAllocate* instr, |
| 6084 const X87Stack& x87_stack) |
| 6085 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
6052 virtual void Generate() V8_OVERRIDE { | 6086 virtual void Generate() V8_OVERRIDE { |
6053 codegen()->DoDeferredAllocate(instr_); | 6087 codegen()->DoDeferredAllocate(instr_); |
6054 } | 6088 } |
6055 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 6089 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
6056 private: | 6090 private: |
6057 LAllocate* instr_; | 6091 LAllocate* instr_; |
6058 }; | 6092 }; |
6059 | 6093 |
6060 DeferredAllocate* deferred = | 6094 DeferredAllocate* deferred = |
6061 new(zone()) DeferredAllocate(this, instr); | 6095 new(zone()) DeferredAllocate(this, instr, x87_stack_); |
6062 | 6096 |
6063 Register result = ToRegister(instr->result()); | 6097 Register result = ToRegister(instr->result()); |
6064 Register temp = ToRegister(instr->temp()); | 6098 Register temp = ToRegister(instr->temp()); |
6065 | 6099 |
6066 // Allocate memory for the object. | 6100 // Allocate memory for the object. |
6067 AllocationFlags flags = TAG_OBJECT; | 6101 AllocationFlags flags = TAG_OBJECT; |
6068 if (instr->hydrogen()->MustAllocateDoubleAligned()) { | 6102 if (instr->hydrogen()->MustAllocateDoubleAligned()) { |
6069 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); | 6103 flags = static_cast<AllocationFlags>(flags | DOUBLE_ALIGNMENT); |
6070 } | 6104 } |
6071 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { | 6105 if (instr->hydrogen()->IsOldPointerSpaceAllocation()) { |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6391 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); | 6425 instr, RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS); |
6392 ASSERT(instr->HasEnvironment()); | 6426 ASSERT(instr->HasEnvironment()); |
6393 LEnvironment* env = instr->environment(); | 6427 LEnvironment* env = instr->environment(); |
6394 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 6428 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
6395 } | 6429 } |
6396 | 6430 |
6397 | 6431 |
6398 void LCodeGen::DoStackCheck(LStackCheck* instr) { | 6432 void LCodeGen::DoStackCheck(LStackCheck* instr) { |
6399 class DeferredStackCheck V8_FINAL : public LDeferredCode { | 6433 class DeferredStackCheck V8_FINAL : public LDeferredCode { |
6400 public: | 6434 public: |
6401 DeferredStackCheck(LCodeGen* codegen, LStackCheck* instr) | 6435 DeferredStackCheck(LCodeGen* codegen, |
6402 : LDeferredCode(codegen), instr_(instr) { } | 6436 LStackCheck* instr, |
| 6437 const X87Stack& x87_stack) |
| 6438 : LDeferredCode(codegen, x87_stack), instr_(instr) { } |
6403 virtual void Generate() V8_OVERRIDE { | 6439 virtual void Generate() V8_OVERRIDE { |
6404 codegen()->DoDeferredStackCheck(instr_); | 6440 codegen()->DoDeferredStackCheck(instr_); |
6405 } | 6441 } |
6406 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 6442 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
6407 private: | 6443 private: |
6408 LStackCheck* instr_; | 6444 LStackCheck* instr_; |
6409 }; | 6445 }; |
6410 | 6446 |
6411 ASSERT(instr->HasEnvironment()); | 6447 ASSERT(instr->HasEnvironment()); |
6412 LEnvironment* env = instr->environment(); | 6448 LEnvironment* env = instr->environment(); |
(...skipping 12 matching lines...) Expand all Loading... |
6425 StackCheckStub stub; | 6461 StackCheckStub stub; |
6426 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); | 6462 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); |
6427 EnsureSpaceForLazyDeopt(); | 6463 EnsureSpaceForLazyDeopt(); |
6428 __ bind(&done); | 6464 __ bind(&done); |
6429 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); | 6465 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); |
6430 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); | 6466 safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index()); |
6431 } else { | 6467 } else { |
6432 ASSERT(instr->hydrogen()->is_backwards_branch()); | 6468 ASSERT(instr->hydrogen()->is_backwards_branch()); |
6433 // Perform stack overflow check if this goto needs it before jumping. | 6469 // Perform stack overflow check if this goto needs it before jumping. |
6434 DeferredStackCheck* deferred_stack_check = | 6470 DeferredStackCheck* deferred_stack_check = |
6435 new(zone()) DeferredStackCheck(this, instr); | 6471 new(zone()) DeferredStackCheck(this, instr, x87_stack_); |
6436 ExternalReference stack_limit = | 6472 ExternalReference stack_limit = |
6437 ExternalReference::address_of_stack_limit(isolate()); | 6473 ExternalReference::address_of_stack_limit(isolate()); |
6438 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 6474 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
6439 __ j(below, deferred_stack_check->entry()); | 6475 __ j(below, deferred_stack_check->entry()); |
6440 EnsureSpaceForLazyDeopt(); | 6476 EnsureSpaceForLazyDeopt(); |
6441 __ bind(instr->done_label()); | 6477 __ bind(instr->done_label()); |
6442 deferred_stack_check->SetExit(instr->done_label()); | 6478 deferred_stack_check->SetExit(instr->done_label()); |
6443 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); | 6479 RegisterEnvironmentForDeoptimization(env, Safepoint::kLazyDeopt); |
6444 // Don't record a deoptimization index for the safepoint here. | 6480 // Don't record a deoptimization index for the safepoint here. |
6445 // This will be done explicitly when emitting call and the safepoint in | 6481 // This will be done explicitly when emitting call and the safepoint in |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6550 FixedArray::kHeaderSize - kPointerSize)); | 6586 FixedArray::kHeaderSize - kPointerSize)); |
6551 __ bind(&done); | 6587 __ bind(&done); |
6552 } | 6588 } |
6553 | 6589 |
6554 | 6590 |
6555 #undef __ | 6591 #undef __ |
6556 | 6592 |
6557 } } // namespace v8::internal | 6593 } } // namespace v8::internal |
6558 | 6594 |
6559 #endif // V8_TARGET_ARCH_IA32 | 6595 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |