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