Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(370)

Side by Side Diff: src/ia32/lithium-codegen-ia32.cc

Issue 181053005: Push safepoint registers in deferred number-to-i/u only on-demand. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Indentation Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 4879 matching lines...) Expand 10 before | Expand all | Expand 10 after
4890 4890
4891 4891
4892 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4892 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
4893 class DeferredNumberTagI V8_FINAL : public LDeferredCode { 4893 class DeferredNumberTagI V8_FINAL : public LDeferredCode {
4894 public: 4894 public:
4895 DeferredNumberTagI(LCodeGen* codegen, 4895 DeferredNumberTagI(LCodeGen* codegen,
4896 LNumberTagI* instr, 4896 LNumberTagI* instr,
4897 const X87Stack& x87_stack) 4897 const X87Stack& x87_stack)
4898 : LDeferredCode(codegen, x87_stack), instr_(instr) { } 4898 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
4899 virtual void Generate() V8_OVERRIDE { 4899 virtual void Generate() V8_OVERRIDE {
4900 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), SIGNED_INT32); 4900 codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp(),
4901 NULL, SIGNED_INT32);
4901 } 4902 }
4902 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 4903 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4903 private: 4904 private:
4904 LNumberTagI* instr_; 4905 LNumberTagI* instr_;
4905 }; 4906 };
4906 4907
4907 LOperand* input = instr->value(); 4908 LOperand* input = instr->value();
4908 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4909 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4909 Register reg = ToRegister(input); 4910 Register reg = ToRegister(input);
4910 4911
4911 DeferredNumberTagI* deferred = 4912 DeferredNumberTagI* deferred =
4912 new(zone()) DeferredNumberTagI(this, instr, x87_stack_); 4913 new(zone()) DeferredNumberTagI(this, instr, x87_stack_);
4913 __ SmiTag(reg); 4914 __ SmiTag(reg);
4914 __ j(overflow, deferred->entry()); 4915 __ j(overflow, deferred->entry());
4915 __ bind(deferred->exit()); 4916 __ bind(deferred->exit());
4916 } 4917 }
4917 4918
4918 4919
4919 void LCodeGen::DoNumberTagU(LNumberTagU* instr) { 4920 void LCodeGen::DoNumberTagU(LNumberTagU* instr) {
4920 class DeferredNumberTagU V8_FINAL : public LDeferredCode { 4921 class DeferredNumberTagU V8_FINAL : public LDeferredCode {
4921 public: 4922 public:
4922 DeferredNumberTagU(LCodeGen* codegen, 4923 DeferredNumberTagU(LCodeGen* codegen,
4923 LNumberTagU* instr, 4924 LNumberTagU* instr,
4924 const X87Stack& x87_stack) 4925 const X87Stack& x87_stack)
4925 : LDeferredCode(codegen, x87_stack), instr_(instr) { } 4926 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
4926 virtual void Generate() V8_OVERRIDE { 4927 virtual void Generate() V8_OVERRIDE {
4927 codegen()->DoDeferredNumberTagI(instr_, instr_->value(), UNSIGNED_INT32); 4928 codegen()->DoDeferredNumberTagIU(instr_, instr_->value(), instr_->temp1(),
4929 instr_->temp2(), UNSIGNED_INT32);
4928 } 4930 }
4929 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } 4931 virtual LInstruction* instr() V8_OVERRIDE { return instr_; }
4930 private: 4932 private:
4931 LNumberTagU* instr_; 4933 LNumberTagU* instr_;
4932 }; 4934 };
4933 4935
4934 LOperand* input = instr->value(); 4936 LOperand* input = instr->value();
4935 ASSERT(input->IsRegister() && input->Equals(instr->result())); 4937 ASSERT(input->IsRegister() && input->Equals(instr->result()));
4936 Register reg = ToRegister(input); 4938 Register reg = ToRegister(input);
4937 4939
4938 DeferredNumberTagU* deferred = 4940 DeferredNumberTagU* deferred =
4939 new(zone()) DeferredNumberTagU(this, instr, x87_stack_); 4941 new(zone()) DeferredNumberTagU(this, instr, x87_stack_);
4940 __ cmp(reg, Immediate(Smi::kMaxValue)); 4942 __ cmp(reg, Immediate(Smi::kMaxValue));
4941 __ j(above, deferred->entry()); 4943 __ j(above, deferred->entry());
4942 __ SmiTag(reg); 4944 __ SmiTag(reg);
4943 __ bind(deferred->exit()); 4945 __ bind(deferred->exit());
4944 } 4946 }
4945 4947
4946 4948
4947 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 4949 void LCodeGen::DoDeferredNumberTagIU(LInstruction* instr,
4948 LOperand* value, 4950 LOperand* value,
4949 IntegerSignedness signedness) { 4951 LOperand* temp1,
4950 Label slow; 4952 LOperand* temp2,
4953 IntegerSignedness signedness) {
4954 Label done, slow;
4951 Register reg = ToRegister(value); 4955 Register reg = ToRegister(value);
4952 Register tmp = reg.is(eax) ? ecx : eax; 4956 Register tmp = ToRegister(temp1);
4953 XMMRegister xmm_scratch = double_scratch0(); 4957 XMMRegister xmm_scratch = double_scratch0();
4954 4958
4955 // Preserve the value of all registers.
4956 PushSafepointRegistersScope scope(this);
4957
4958 Label done;
4959
4960 if (signedness == SIGNED_INT32) { 4959 if (signedness == SIGNED_INT32) {
4961 // There was overflow, so bits 30 and 31 of the original integer 4960 // There was overflow, so bits 30 and 31 of the original integer
4962 // disagree. Try to allocate a heap number in new space and store 4961 // disagree. Try to allocate a heap number in new space and store
4963 // the value in there. If that fails, call the runtime system. 4962 // the value in there. If that fails, call the runtime system.
4964 __ SmiUntag(reg); 4963 __ SmiUntag(reg);
4965 __ xor_(reg, 0x80000000); 4964 __ xor_(reg, 0x80000000);
4966 if (CpuFeatures::IsSupported(SSE2)) { 4965 if (CpuFeatures::IsSupported(SSE2)) {
4967 CpuFeatureScope feature_scope(masm(), SSE2); 4966 CpuFeatureScope feature_scope(masm(), SSE2);
4968 __ Cvtsi2sd(xmm_scratch, Operand(reg)); 4967 __ Cvtsi2sd(xmm_scratch, Operand(reg));
4969 } else { 4968 } else {
4970 __ push(reg); 4969 __ push(reg);
4971 __ fild_s(Operand(esp, 0)); 4970 __ fild_s(Operand(esp, 0));
4972 __ pop(reg); 4971 __ pop(reg);
4973 } 4972 }
4974 } else { 4973 } else {
4975 if (CpuFeatures::IsSupported(SSE2)) { 4974 if (CpuFeatures::IsSupported(SSE2)) {
4976 CpuFeatureScope feature_scope(masm(), SSE2); 4975 CpuFeatureScope feature_scope(masm(), SSE2);
4977 __ LoadUint32(xmm_scratch, reg, 4976 __ LoadUint32(xmm_scratch, reg, ToDoubleRegister(temp2));
4978 ToDoubleRegister(LNumberTagU::cast(instr)->temp()));
4979 } else { 4977 } else {
4980 // There's no fild variant for unsigned values, so zero-extend to a 64-bit 4978 // There's no fild variant for unsigned values, so zero-extend to a 64-bit
4981 // int manually. 4979 // int manually.
4982 __ push(Immediate(0)); 4980 __ push(Immediate(0));
4983 __ push(reg); 4981 __ push(reg);
4984 __ fild_d(Operand(esp, 0)); 4982 __ fild_d(Operand(esp, 0));
4985 __ pop(reg); 4983 __ pop(reg);
4986 __ pop(reg); 4984 __ pop(reg);
4987 } 4985 }
4988 } 4986 }
4989 4987
4990 if (FLAG_inline_new) { 4988 if (FLAG_inline_new) {
4991 __ AllocateHeapNumber(reg, tmp, no_reg, &slow); 4989 __ AllocateHeapNumber(reg, tmp, no_reg, &slow);
4992 __ jmp(&done, Label::kNear); 4990 __ jmp(&done, Label::kNear);
4993 } 4991 }
4994 4992
4995 // Slow case: Call the runtime system to do the number allocation. 4993 // Slow case: Call the runtime system to do the number allocation.
4996 __ bind(&slow); 4994 __ bind(&slow);
4995 {
4996 // TODO(3095996): Put a valid pointer value in the stack slot where the
4997 // result register is stored, as this register is in the pointer map, but
4998 // contains an integer value.
4999 __ Set(reg, Immediate(0));
4997 5000
4998 // TODO(3095996): Put a valid pointer value in the stack slot where the result 5001 // Preserve the value of all registers.
4999 // register is stored, as this register is in the pointer map, but contains an 5002 PushSafepointRegistersScope scope(this);
5000 // integer value. 5003
5001 __ StoreToSafepointRegisterSlot(reg, Immediate(0)); 5004 // NumberTagI and NumberTagD use the context from the frame, rather than
5002 // NumberTagI and NumberTagD use the context from the frame, rather than 5005 // the environment's HContext or HInlinedContext value.
5003 // the environment's HContext or HInlinedContext value. 5006 // They only call Runtime::kAllocateHeapNumber.
5004 // They only call Runtime::kAllocateHeapNumber. 5007 // The corresponding HChange instructions are added in a phase that does
5005 // The corresponding HChange instructions are added in a phase that does 5008 // not have easy access to the local context.
5006 // not have easy access to the local context. 5009 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
5007 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 5010 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
5008 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); 5011 RecordSafepointWithRegisters(
5009 RecordSafepointWithRegisters( 5012 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
5010 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); 5013 __ StoreToSafepointRegisterSlot(reg, eax);
5011 if (!reg.is(eax)) __ mov(reg, eax); 5014 }
5012 5015
5013 // Done. Put the value in xmm_scratch into the value of the allocated heap 5016 // Done. Put the value in xmm_scratch into the value of the allocated heap
5014 // number. 5017 // number.
5015 __ bind(&done); 5018 __ bind(&done);
5016 if (CpuFeatures::IsSupported(SSE2)) { 5019 if (CpuFeatures::IsSupported(SSE2)) {
5017 CpuFeatureScope feature_scope(masm(), SSE2); 5020 CpuFeatureScope feature_scope(masm(), SSE2);
5018 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch); 5021 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch);
5019 } else { 5022 } else {
5020 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); 5023 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset));
5021 } 5024 }
5022 __ StoreToSafepointRegisterSlot(reg, reg);
5023 } 5025 }
5024 5026
5025 5027
5026 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 5028 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
5027 class DeferredNumberTagD V8_FINAL : public LDeferredCode { 5029 class DeferredNumberTagD V8_FINAL : public LDeferredCode {
5028 public: 5030 public:
5029 DeferredNumberTagD(LCodeGen* codegen, 5031 DeferredNumberTagD(LCodeGen* codegen,
5030 LNumberTagD* instr, 5032 LNumberTagD* instr,
5031 const X87Stack& x87_stack) 5033 const X87Stack& x87_stack)
5032 : LDeferredCode(codegen, x87_stack), instr_(instr) { } 5034 : LDeferredCode(codegen, x87_stack), instr_(instr) { }
(...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after
6270 FixedArray::kHeaderSize - kPointerSize)); 6272 FixedArray::kHeaderSize - kPointerSize));
6271 __ bind(&done); 6273 __ bind(&done);
6272 } 6274 }
6273 6275
6274 6276
6275 #undef __ 6277 #undef __
6276 6278
6277 } } // namespace v8::internal 6279 } } // namespace v8::internal
6278 6280
6279 #endif // V8_TARGET_ARCH_IA32 6281 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698