| 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 |