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