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