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

Side by Side Diff: src/x64/macro-assembler-x64.cc

Issue 6677076: Merge up to bleeding_edge r7201 to isolates branch. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/isolates
Patch Set: Fix lint. Created 9 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/x64/macro-assembler-x64.h ('k') | test/benchmarks/testcfg.py » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 Heap::RootListIndex index) { 85 Heap::RootListIndex index) {
86 ASSERT(!with.AddressUsesRegister(kScratchRegister)); 86 ASSERT(!with.AddressUsesRegister(kScratchRegister));
87 LoadRoot(kScratchRegister, index); 87 LoadRoot(kScratchRegister, index);
88 cmpq(with, kScratchRegister); 88 cmpq(with, kScratchRegister);
89 } 89 }
90 90
91 91
92 void MacroAssembler::RecordWriteHelper(Register object, 92 void MacroAssembler::RecordWriteHelper(Register object,
93 Register addr, 93 Register addr,
94 Register scratch) { 94 Register scratch) {
95 if (FLAG_debug_code) { 95 if (emit_debug_code()) {
96 // Check that the object is not in new space. 96 // Check that the object is not in new space.
97 NearLabel not_in_new_space; 97 NearLabel not_in_new_space;
98 InNewSpace(object, scratch, not_equal, &not_in_new_space); 98 InNewSpace(object, scratch, not_equal, &not_in_new_space);
99 Abort("new-space object passed to RecordWriteHelper"); 99 Abort("new-space object passed to RecordWriteHelper");
100 bind(&not_in_new_space); 100 bind(&not_in_new_space);
101 } 101 }
102 102
103 // Compute the page start address from the heap object pointer, and reuse 103 // Compute the page start address from the heap object pointer, and reuse
104 // the 'object' register for it. 104 // the 'object' register for it.
105 and_(object, Immediate(~Page::kPageAlignmentMask)); 105 and_(object, Immediate(~Page::kPageAlignmentMask));
(...skipping 11 matching lines...) Expand all
117 void MacroAssembler::RecordWrite(Register object, 117 void MacroAssembler::RecordWrite(Register object,
118 int offset, 118 int offset,
119 Register value, 119 Register value,
120 Register index) { 120 Register index) {
121 // The compiled code assumes that record write doesn't change the 121 // The compiled code assumes that record write doesn't change the
122 // context register, so we check that none of the clobbered 122 // context register, so we check that none of the clobbered
123 // registers are rsi. 123 // registers are rsi.
124 ASSERT(!object.is(rsi) && !value.is(rsi) && !index.is(rsi)); 124 ASSERT(!object.is(rsi) && !value.is(rsi) && !index.is(rsi));
125 125
126 // First, check if a write barrier is even needed. The tests below 126 // First, check if a write barrier is even needed. The tests below
127 // catch stores of Smis and stores into young gen. 127 // catch stores of smis and stores into the young generation.
128 Label done; 128 Label done;
129 JumpIfSmi(value, &done); 129 JumpIfSmi(value, &done);
130 130
131 RecordWriteNonSmi(object, offset, value, index); 131 RecordWriteNonSmi(object, offset, value, index);
132 bind(&done); 132 bind(&done);
133 133
134 // Clobber all input registers when running with the debug-code flag 134 // Clobber all input registers when running with the debug-code flag
135 // turned on to provoke errors. This clobbering repeats the 135 // turned on to provoke errors. This clobbering repeats the
136 // clobbering done inside RecordWriteNonSmi but it's necessary to 136 // clobbering done inside RecordWriteNonSmi but it's necessary to
137 // avoid having the fast case for smis leave the registers 137 // avoid having the fast case for smis leave the registers
138 // unchanged. 138 // unchanged.
139 if (FLAG_debug_code) { 139 if (emit_debug_code()) {
140 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 140 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
141 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 141 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
142 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 142 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
143 } 143 }
144 } 144 }
145 145
146 146
147 void MacroAssembler::RecordWrite(Register object, 147 void MacroAssembler::RecordWrite(Register object,
148 Register address, 148 Register address,
149 Register value) { 149 Register value) {
150 // The compiled code assumes that record write doesn't change the 150 // The compiled code assumes that record write doesn't change the
151 // context register, so we check that none of the clobbered 151 // context register, so we check that none of the clobbered
152 // registers are rsi. 152 // registers are rsi.
153 ASSERT(!object.is(rsi) && !value.is(rsi) && !address.is(rsi)); 153 ASSERT(!object.is(rsi) && !value.is(rsi) && !address.is(rsi));
154 154
155 // First, check if a write barrier is even needed. The tests below 155 // First, check if a write barrier is even needed. The tests below
156 // catch stores of Smis and stores into young gen. 156 // catch stores of smis and stores into the young generation.
157 Label done; 157 Label done;
158 JumpIfSmi(value, &done); 158 JumpIfSmi(value, &done);
159 159
160 InNewSpace(object, value, equal, &done); 160 InNewSpace(object, value, equal, &done);
161 161
162 RecordWriteHelper(object, address, value); 162 RecordWriteHelper(object, address, value);
163 163
164 bind(&done); 164 bind(&done);
165 165
166 // Clobber all input registers when running with the debug-code flag 166 // Clobber all input registers when running with the debug-code flag
167 // turned on to provoke errors. 167 // turned on to provoke errors.
168 if (FLAG_debug_code) { 168 if (emit_debug_code()) {
169 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 169 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
170 movq(address, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 170 movq(address, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
171 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 171 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
172 } 172 }
173 } 173 }
174 174
175 175
176 void MacroAssembler::RecordWriteNonSmi(Register object, 176 void MacroAssembler::RecordWriteNonSmi(Register object,
177 int offset, 177 int offset,
178 Register scratch, 178 Register scratch,
179 Register index) { 179 Register index) {
180 Label done; 180 Label done;
181 181
182 if (FLAG_debug_code) { 182 if (emit_debug_code()) {
183 NearLabel okay; 183 NearLabel okay;
184 JumpIfNotSmi(object, &okay); 184 JumpIfNotSmi(object, &okay);
185 Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis"); 185 Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis");
186 bind(&okay); 186 bind(&okay);
187 187
188 if (offset == 0) { 188 if (offset == 0) {
189 // index must be int32. 189 // index must be int32.
190 Register tmp = index.is(rax) ? rbx : rax; 190 Register tmp = index.is(rax) ? rbx : rax;
191 push(tmp); 191 push(tmp);
192 movl(tmp, index); 192 movl(tmp, index);
(...skipping 23 matching lines...) Expand all
216 index, 216 index,
217 times_pointer_size, 217 times_pointer_size,
218 FixedArray::kHeaderSize)); 218 FixedArray::kHeaderSize));
219 } 219 }
220 RecordWriteHelper(object, dst, scratch); 220 RecordWriteHelper(object, dst, scratch);
221 221
222 bind(&done); 222 bind(&done);
223 223
224 // Clobber all input registers when running with the debug-code flag 224 // Clobber all input registers when running with the debug-code flag
225 // turned on to provoke errors. 225 // turned on to provoke errors.
226 if (FLAG_debug_code) { 226 if (emit_debug_code()) {
227 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 227 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
228 movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 228 movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
229 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 229 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
230 } 230 }
231 } 231 }
232 232
233 void MacroAssembler::Assert(Condition cc, const char* msg) { 233 void MacroAssembler::Assert(Condition cc, const char* msg) {
234 if (FLAG_debug_code) Check(cc, msg); 234 if (emit_debug_code()) Check(cc, msg);
235 } 235 }
236 236
237 237
238 void MacroAssembler::AssertFastElements(Register elements) { 238 void MacroAssembler::AssertFastElements(Register elements) {
239 if (FLAG_debug_code) { 239 if (emit_debug_code()) {
240 NearLabel ok; 240 NearLabel ok;
241 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 241 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
242 Heap::kFixedArrayMapRootIndex); 242 Heap::kFixedArrayMapRootIndex);
243 j(equal, &ok); 243 j(equal, &ok);
244 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 244 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
245 Heap::kFixedCOWArrayMapRootIndex); 245 Heap::kFixedCOWArrayMapRootIndex);
246 j(equal, &ok); 246 j(equal, &ok);
247 Abort("JSObject with fast elements map has slow elements"); 247 Abort("JSObject with fast elements map has slow elements");
248 bind(&ok); 248 bind(&ok);
249 } 249 }
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 return kScratchRegister; 706 return kScratchRegister;
707 } 707 }
708 if (value == 1) { 708 if (value == 1) {
709 return kSmiConstantRegister; 709 return kSmiConstantRegister;
710 } 710 }
711 LoadSmiConstant(kScratchRegister, source); 711 LoadSmiConstant(kScratchRegister, source);
712 return kScratchRegister; 712 return kScratchRegister;
713 } 713 }
714 714
715 void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { 715 void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) {
716 if (FLAG_debug_code) { 716 if (emit_debug_code()) {
717 movq(dst, 717 movq(dst,
718 reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)), 718 reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)),
719 RelocInfo::NONE); 719 RelocInfo::NONE);
720 cmpq(dst, kSmiConstantRegister); 720 cmpq(dst, kSmiConstantRegister);
721 if (allow_stub_calls()) { 721 if (allow_stub_calls()) {
722 Assert(equal, "Uninitialized kSmiConstantRegister"); 722 Assert(equal, "Uninitialized kSmiConstantRegister");
723 } else { 723 } else {
724 NearLabel ok; 724 NearLabel ok;
725 j(equal, &ok); 725 j(equal, &ok);
726 int3(); 726 int3();
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
775 void MacroAssembler::Integer32ToSmi(Register dst, Register src) { 775 void MacroAssembler::Integer32ToSmi(Register dst, Register src) {
776 ASSERT_EQ(0, kSmiTag); 776 ASSERT_EQ(0, kSmiTag);
777 if (!dst.is(src)) { 777 if (!dst.is(src)) {
778 movl(dst, src); 778 movl(dst, src);
779 } 779 }
780 shl(dst, Immediate(kSmiShift)); 780 shl(dst, Immediate(kSmiShift));
781 } 781 }
782 782
783 783
784 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { 784 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) {
785 if (FLAG_debug_code) { 785 if (emit_debug_code()) {
786 testb(dst, Immediate(0x01)); 786 testb(dst, Immediate(0x01));
787 NearLabel ok; 787 NearLabel ok;
788 j(zero, &ok); 788 j(zero, &ok);
789 if (allow_stub_calls()) { 789 if (allow_stub_calls()) {
790 Abort("Integer32ToSmiField writing to non-smi location"); 790 Abort("Integer32ToSmiField writing to non-smi location");
791 } else { 791 } else {
792 int3(); 792 int3();
793 } 793 }
794 bind(&ok); 794 bind(&ok);
795 } 795 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { 836 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) {
837 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); 837 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
838 } 838 }
839 839
840 840
841 void MacroAssembler::SmiTest(Register src) { 841 void MacroAssembler::SmiTest(Register src) {
842 testq(src, src); 842 testq(src, src);
843 } 843 }
844 844
845 845
846 void MacroAssembler::SmiCompare(Register dst, Register src) { 846 void MacroAssembler::SmiCompare(Register smi1, Register smi2) {
847 cmpq(dst, src); 847 if (emit_debug_code()) {
848 AbortIfNotSmi(smi1);
849 AbortIfNotSmi(smi2);
850 }
851 cmpq(smi1, smi2);
848 } 852 }
849 853
850 854
851 void MacroAssembler::SmiCompare(Register dst, Smi* src) { 855 void MacroAssembler::SmiCompare(Register dst, Smi* src) {
856 if (emit_debug_code()) {
857 AbortIfNotSmi(dst);
858 }
859 Cmp(dst, src);
860 }
861
862
863 void MacroAssembler::Cmp(Register dst, Smi* src) {
852 ASSERT(!dst.is(kScratchRegister)); 864 ASSERT(!dst.is(kScratchRegister));
853 if (src->value() == 0) { 865 if (src->value() == 0) {
854 testq(dst, dst); 866 testq(dst, dst);
855 } else { 867 } else {
856 Register constant_reg = GetSmiConstant(src); 868 Register constant_reg = GetSmiConstant(src);
857 cmpq(dst, constant_reg); 869 cmpq(dst, constant_reg);
858 } 870 }
859 } 871 }
860 872
861 873
862 void MacroAssembler::SmiCompare(Register dst, const Operand& src) { 874 void MacroAssembler::SmiCompare(Register dst, const Operand& src) {
875 if (emit_debug_code()) {
876 AbortIfNotSmi(dst);
877 AbortIfNotSmi(src);
878 }
863 cmpq(dst, src); 879 cmpq(dst, src);
864 } 880 }
865 881
866 882
867 void MacroAssembler::SmiCompare(const Operand& dst, Register src) { 883 void MacroAssembler::SmiCompare(const Operand& dst, Register src) {
884 if (emit_debug_code()) {
885 AbortIfNotSmi(dst);
886 AbortIfNotSmi(src);
887 }
868 cmpq(dst, src); 888 cmpq(dst, src);
869 } 889 }
870 890
871 891
872 void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) { 892 void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) {
893 if (emit_debug_code()) {
894 AbortIfNotSmi(dst);
895 }
873 cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value())); 896 cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value()));
874 } 897 }
875 898
876 899
900 void MacroAssembler::Cmp(const Operand& dst, Smi* src) {
901 // The Operand cannot use the smi register.
902 Register smi_reg = GetSmiConstant(src);
903 ASSERT(!dst.AddressUsesRegister(smi_reg));
904 cmpq(dst, smi_reg);
905 }
906
907
877 void MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) { 908 void MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) {
878 cmpl(Operand(dst, kSmiShift / kBitsPerByte), src); 909 cmpl(Operand(dst, kSmiShift / kBitsPerByte), src);
879 } 910 }
880 911
881 912
882 void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 913 void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
883 Register src, 914 Register src,
884 int power) { 915 int power) {
885 ASSERT(power >= 0); 916 ASSERT(power >= 0);
886 ASSERT(power < 64); 917 ASSERT(power < 64);
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 Move(dst, Smi::cast(*source)); 1382 Move(dst, Smi::cast(*source));
1352 } else { 1383 } else {
1353 movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT); 1384 movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT);
1354 movq(dst, kScratchRegister); 1385 movq(dst, kScratchRegister);
1355 } 1386 }
1356 } 1387 }
1357 1388
1358 1389
1359 void MacroAssembler::Cmp(Register dst, Handle<Object> source) { 1390 void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
1360 if (source->IsSmi()) { 1391 if (source->IsSmi()) {
1361 SmiCompare(dst, Smi::cast(*source)); 1392 Cmp(dst, Smi::cast(*source));
1362 } else { 1393 } else {
1363 Move(kScratchRegister, source); 1394 Move(kScratchRegister, source);
1364 cmpq(dst, kScratchRegister); 1395 cmpq(dst, kScratchRegister);
1365 } 1396 }
1366 } 1397 }
1367 1398
1368 1399
1369 void MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) { 1400 void MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) {
1370 if (source->IsSmi()) { 1401 if (source->IsSmi()) {
1371 SmiCompare(dst, Smi::cast(*source)); 1402 Cmp(dst, Smi::cast(*source));
1372 } else { 1403 } else {
1373 ASSERT(source->IsHeapObject()); 1404 ASSERT(source->IsHeapObject());
1374 movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT); 1405 movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT);
1375 cmpq(dst, kScratchRegister); 1406 cmpq(dst, kScratchRegister);
1376 } 1407 }
1377 } 1408 }
1378 1409
1379 1410
1380 void MacroAssembler::Push(Handle<Object> source) { 1411 void MacroAssembler::Push(Handle<Object> source) {
1381 if (source->IsSmi()) { 1412 if (source->IsSmi()) {
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 1784
1754 1785
1755 void MacroAssembler::AbortIfSmi(Register object) { 1786 void MacroAssembler::AbortIfSmi(Register object) {
1756 NearLabel ok; 1787 NearLabel ok;
1757 Condition is_smi = CheckSmi(object); 1788 Condition is_smi = CheckSmi(object);
1758 Assert(NegateCondition(is_smi), "Operand is a smi"); 1789 Assert(NegateCondition(is_smi), "Operand is a smi");
1759 } 1790 }
1760 1791
1761 1792
1762 void MacroAssembler::AbortIfNotSmi(Register object) { 1793 void MacroAssembler::AbortIfNotSmi(Register object) {
1763 NearLabel ok;
1764 Condition is_smi = CheckSmi(object); 1794 Condition is_smi = CheckSmi(object);
1765 Assert(is_smi, "Operand is not a smi"); 1795 Assert(is_smi, "Operand is not a smi");
1766 } 1796 }
1797
1798
1799 void MacroAssembler::AbortIfNotSmi(const Operand& object) {
1800 Condition is_smi = CheckSmi(object);
1801 Assert(is_smi, "Operand is not a smi");
1802 }
1767 1803
1768 1804
1769 void MacroAssembler::AbortIfNotString(Register object) { 1805 void MacroAssembler::AbortIfNotString(Register object) {
1770 testb(object, Immediate(kSmiTagMask)); 1806 testb(object, Immediate(kSmiTagMask));
1771 Assert(not_equal, "Operand is not a string"); 1807 Assert(not_equal, "Operand is not a string");
1772 push(object); 1808 push(object);
1773 movq(object, FieldOperand(object, HeapObject::kMapOffset)); 1809 movq(object, FieldOperand(object, HeapObject::kMapOffset));
1774 CmpInstanceType(object, FIRST_NONSTRING_TYPE); 1810 CmpInstanceType(object, FIRST_NONSTRING_TYPE);
1775 pop(object); 1811 pop(object);
1776 Assert(below, "Operand is not a string"); 1812 Assert(below, "Operand is not a string");
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1991 } 2027 }
1992 2028
1993 2029
1994 void MacroAssembler::EnterFrame(StackFrame::Type type) { 2030 void MacroAssembler::EnterFrame(StackFrame::Type type) {
1995 push(rbp); 2031 push(rbp);
1996 movq(rbp, rsp); 2032 movq(rbp, rsp);
1997 push(rsi); // Context. 2033 push(rsi); // Context.
1998 Push(Smi::FromInt(type)); 2034 Push(Smi::FromInt(type));
1999 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 2035 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
2000 push(kScratchRegister); 2036 push(kScratchRegister);
2001 if (FLAG_debug_code) { 2037 if (emit_debug_code()) {
2002 movq(kScratchRegister, 2038 movq(kScratchRegister,
2003 FACTORY->undefined_value(), 2039 FACTORY->undefined_value(),
2004 RelocInfo::EMBEDDED_OBJECT); 2040 RelocInfo::EMBEDDED_OBJECT);
2005 cmpq(Operand(rsp, 0), kScratchRegister); 2041 cmpq(Operand(rsp, 0), kScratchRegister);
2006 Check(not_equal, "code object not properly patched"); 2042 Check(not_equal, "code object not properly patched");
2007 } 2043 }
2008 } 2044 }
2009 2045
2010 2046
2011 void MacroAssembler::LeaveFrame(StackFrame::Type type) { 2047 void MacroAssembler::LeaveFrame(StackFrame::Type type) {
2012 if (FLAG_debug_code) { 2048 if (emit_debug_code()) {
2013 Move(kScratchRegister, Smi::FromInt(type)); 2049 Move(kScratchRegister, Smi::FromInt(type));
2014 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); 2050 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister);
2015 Check(equal, "stack frame types must match"); 2051 Check(equal, "stack frame types must match");
2016 } 2052 }
2017 movq(rsp, rbp); 2053 movq(rsp, rbp);
2018 pop(rbp); 2054 pop(rbp);
2019 } 2055 }
2020 2056
2021 2057
2022 void MacroAssembler::EnterExitFramePrologue(bool save_rax) { 2058 void MacroAssembler::EnterExitFramePrologue(bool save_rax) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2152 Register scratch, 2188 Register scratch,
2153 Label* miss) { 2189 Label* miss) {
2154 Label same_contexts; 2190 Label same_contexts;
2155 2191
2156 ASSERT(!holder_reg.is(scratch)); 2192 ASSERT(!holder_reg.is(scratch));
2157 ASSERT(!scratch.is(kScratchRegister)); 2193 ASSERT(!scratch.is(kScratchRegister));
2158 // Load current lexical context from the stack frame. 2194 // Load current lexical context from the stack frame.
2159 movq(scratch, Operand(rbp, StandardFrameConstants::kContextOffset)); 2195 movq(scratch, Operand(rbp, StandardFrameConstants::kContextOffset));
2160 2196
2161 // When generating debug code, make sure the lexical context is set. 2197 // When generating debug code, make sure the lexical context is set.
2162 if (FLAG_debug_code) { 2198 if (emit_debug_code()) {
2163 cmpq(scratch, Immediate(0)); 2199 cmpq(scratch, Immediate(0));
2164 Check(not_equal, "we should not have an empty lexical context"); 2200 Check(not_equal, "we should not have an empty lexical context");
2165 } 2201 }
2166 // Load the global context of the current context. 2202 // Load the global context of the current context.
2167 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; 2203 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
2168 movq(scratch, FieldOperand(scratch, offset)); 2204 movq(scratch, FieldOperand(scratch, offset));
2169 movq(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset)); 2205 movq(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
2170 2206
2171 // Check the context is a global context. 2207 // Check the context is a global context.
2172 if (FLAG_debug_code) { 2208 if (emit_debug_code()) {
2173 Cmp(FieldOperand(scratch, HeapObject::kMapOffset), 2209 Cmp(FieldOperand(scratch, HeapObject::kMapOffset),
2174 FACTORY->global_context_map()); 2210 FACTORY->global_context_map());
2175 Check(equal, "JSGlobalObject::global_context should be a global context."); 2211 Check(equal, "JSGlobalObject::global_context should be a global context.");
2176 } 2212 }
2177 2213
2178 // Check if both contexts are the same. 2214 // Check if both contexts are the same.
2179 cmpq(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); 2215 cmpq(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
2180 j(equal, &same_contexts); 2216 j(equal, &same_contexts);
2181 2217
2182 // Compare security tokens. 2218 // Compare security tokens.
2183 // Check that the security token in the calling global object is 2219 // Check that the security token in the calling global object is
2184 // compatible with the security token in the receiving global 2220 // compatible with the security token in the receiving global
2185 // object. 2221 // object.
2186 2222
2187 // Check the context is a global context. 2223 // Check the context is a global context.
2188 if (FLAG_debug_code) { 2224 if (emit_debug_code()) {
2189 // Preserve original value of holder_reg. 2225 // Preserve original value of holder_reg.
2190 push(holder_reg); 2226 push(holder_reg);
2191 movq(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); 2227 movq(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
2192 CompareRoot(holder_reg, Heap::kNullValueRootIndex); 2228 CompareRoot(holder_reg, Heap::kNullValueRootIndex);
2193 Check(not_equal, "JSGlobalProxy::context() should not be null."); 2229 Check(not_equal, "JSGlobalProxy::context() should not be null.");
2194 2230
2195 // Read the first word and compare to global_context_map(), 2231 // Read the first word and compare to global_context_map(),
2196 movq(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); 2232 movq(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
2197 CompareRoot(holder_reg, Heap::kGlobalContextMapRootIndex); 2233 CompareRoot(holder_reg, Heap::kGlobalContextMapRootIndex);
2198 Check(equal, "JSGlobalObject::global_context should be a global context."); 2234 Check(equal, "JSGlobalObject::global_context should be a global context.");
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2239 load_rax(new_space_allocation_top); 2275 load_rax(new_space_allocation_top);
2240 } else { 2276 } else {
2241 movq(kScratchRegister, new_space_allocation_top); 2277 movq(kScratchRegister, new_space_allocation_top);
2242 movq(result, Operand(kScratchRegister, 0)); 2278 movq(result, Operand(kScratchRegister, 0));
2243 } 2279 }
2244 } 2280 }
2245 2281
2246 2282
2247 void MacroAssembler::UpdateAllocationTopHelper(Register result_end, 2283 void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
2248 Register scratch) { 2284 Register scratch) {
2249 if (FLAG_debug_code) { 2285 if (emit_debug_code()) {
2250 testq(result_end, Immediate(kObjectAlignmentMask)); 2286 testq(result_end, Immediate(kObjectAlignmentMask));
2251 Check(zero, "Unaligned allocation in new space"); 2287 Check(zero, "Unaligned allocation in new space");
2252 } 2288 }
2253 2289
2254 ExternalReference new_space_allocation_top = 2290 ExternalReference new_space_allocation_top =
2255 ExternalReference::new_space_allocation_top_address(); 2291 ExternalReference::new_space_allocation_top_address();
2256 2292
2257 // Update new top. 2293 // Update new top.
2258 if (result_end.is(rax)) { 2294 if (result_end.is(rax)) {
2259 // rax can be stored directly to a memory location. 2295 // rax can be stored directly to a memory location.
(...skipping 10 matching lines...) Expand all
2270 } 2306 }
2271 2307
2272 2308
2273 void MacroAssembler::AllocateInNewSpace(int object_size, 2309 void MacroAssembler::AllocateInNewSpace(int object_size,
2274 Register result, 2310 Register result,
2275 Register result_end, 2311 Register result_end,
2276 Register scratch, 2312 Register scratch,
2277 Label* gc_required, 2313 Label* gc_required,
2278 AllocationFlags flags) { 2314 AllocationFlags flags) {
2279 if (!FLAG_inline_new) { 2315 if (!FLAG_inline_new) {
2280 if (FLAG_debug_code) { 2316 if (emit_debug_code()) {
2281 // Trash the registers to simulate an allocation failure. 2317 // Trash the registers to simulate an allocation failure.
2282 movl(result, Immediate(0x7091)); 2318 movl(result, Immediate(0x7091));
2283 if (result_end.is_valid()) { 2319 if (result_end.is_valid()) {
2284 movl(result_end, Immediate(0x7191)); 2320 movl(result_end, Immediate(0x7191));
2285 } 2321 }
2286 if (scratch.is_valid()) { 2322 if (scratch.is_valid()) {
2287 movl(scratch, Immediate(0x7291)); 2323 movl(scratch, Immediate(0x7291));
2288 } 2324 }
2289 } 2325 }
2290 jmp(gc_required); 2326 jmp(gc_required);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2328 2364
2329 void MacroAssembler::AllocateInNewSpace(int header_size, 2365 void MacroAssembler::AllocateInNewSpace(int header_size,
2330 ScaleFactor element_size, 2366 ScaleFactor element_size,
2331 Register element_count, 2367 Register element_count,
2332 Register result, 2368 Register result,
2333 Register result_end, 2369 Register result_end,
2334 Register scratch, 2370 Register scratch,
2335 Label* gc_required, 2371 Label* gc_required,
2336 AllocationFlags flags) { 2372 AllocationFlags flags) {
2337 if (!FLAG_inline_new) { 2373 if (!FLAG_inline_new) {
2338 if (FLAG_debug_code) { 2374 if (emit_debug_code()) {
2339 // Trash the registers to simulate an allocation failure. 2375 // Trash the registers to simulate an allocation failure.
2340 movl(result, Immediate(0x7091)); 2376 movl(result, Immediate(0x7091));
2341 movl(result_end, Immediate(0x7191)); 2377 movl(result_end, Immediate(0x7191));
2342 if (scratch.is_valid()) { 2378 if (scratch.is_valid()) {
2343 movl(scratch, Immediate(0x7291)); 2379 movl(scratch, Immediate(0x7291));
2344 } 2380 }
2345 // Register element_count is not modified by the function. 2381 // Register element_count is not modified by the function.
2346 } 2382 }
2347 jmp(gc_required); 2383 jmp(gc_required);
2348 return; 2384 return;
(...skipping 26 matching lines...) Expand all
2375 } 2411 }
2376 2412
2377 2413
2378 void MacroAssembler::AllocateInNewSpace(Register object_size, 2414 void MacroAssembler::AllocateInNewSpace(Register object_size,
2379 Register result, 2415 Register result,
2380 Register result_end, 2416 Register result_end,
2381 Register scratch, 2417 Register scratch,
2382 Label* gc_required, 2418 Label* gc_required,
2383 AllocationFlags flags) { 2419 AllocationFlags flags) {
2384 if (!FLAG_inline_new) { 2420 if (!FLAG_inline_new) {
2385 if (FLAG_debug_code) { 2421 if (emit_debug_code()) {
2386 // Trash the registers to simulate an allocation failure. 2422 // Trash the registers to simulate an allocation failure.
2387 movl(result, Immediate(0x7091)); 2423 movl(result, Immediate(0x7091));
2388 movl(result_end, Immediate(0x7191)); 2424 movl(result_end, Immediate(0x7191));
2389 if (scratch.is_valid()) { 2425 if (scratch.is_valid()) {
2390 movl(scratch, Immediate(0x7291)); 2426 movl(scratch, Immediate(0x7291));
2391 } 2427 }
2392 // object_size is left unchanged by this function. 2428 // object_size is left unchanged by this function.
2393 } 2429 }
2394 jmp(gc_required); 2430 jmp(gc_required);
2395 return; 2431 return;
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
2582 // Slot is in the current function context. Move it into the 2618 // Slot is in the current function context. Move it into the
2583 // destination register in case we store into it (the write barrier 2619 // destination register in case we store into it (the write barrier
2584 // cannot be allowed to destroy the context in rsi). 2620 // cannot be allowed to destroy the context in rsi).
2585 movq(dst, rsi); 2621 movq(dst, rsi);
2586 } 2622 }
2587 2623
2588 // We should not have found a 'with' context by walking the context chain 2624 // We should not have found a 'with' context by walking the context chain
2589 // (i.e., the static scope chain and runtime context chain do not agree). 2625 // (i.e., the static scope chain and runtime context chain do not agree).
2590 // A variable occurring in such a scope should have slot type LOOKUP and 2626 // A variable occurring in such a scope should have slot type LOOKUP and
2591 // not CONTEXT. 2627 // not CONTEXT.
2592 if (FLAG_debug_code) { 2628 if (emit_debug_code()) {
2593 cmpq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX))); 2629 cmpq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
2594 Check(equal, "Yo dawg, I heard you liked function contexts " 2630 Check(equal, "Yo dawg, I heard you liked function contexts "
2595 "so I put function contexts in all your contexts"); 2631 "so I put function contexts in all your contexts");
2596 } 2632 }
2597 } 2633 }
2598 2634
2599 #ifdef _WIN64 2635 #ifdef _WIN64
2600 static const int kRegisterPassedArguments = 4; 2636 static const int kRegisterPassedArguments = 4;
2601 #else 2637 #else
2602 static const int kRegisterPassedArguments = 6; 2638 static const int kRegisterPassedArguments = 6;
2603 #endif 2639 #endif
2604 2640
2605 void MacroAssembler::LoadGlobalFunction(int index, Register function) { 2641 void MacroAssembler::LoadGlobalFunction(int index, Register function) {
2606 // Load the global or builtins object from the current context. 2642 // Load the global or builtins object from the current context.
2607 movq(function, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); 2643 movq(function, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
2608 // Load the global context from the global or builtins object. 2644 // Load the global context from the global or builtins object.
2609 movq(function, FieldOperand(function, GlobalObject::kGlobalContextOffset)); 2645 movq(function, FieldOperand(function, GlobalObject::kGlobalContextOffset));
2610 // Load the function from the global context. 2646 // Load the function from the global context.
2611 movq(function, Operand(function, Context::SlotOffset(index))); 2647 movq(function, Operand(function, Context::SlotOffset(index)));
2612 } 2648 }
2613 2649
2614 2650
2615 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 2651 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
2616 Register map) { 2652 Register map) {
2617 // Load the initial map. The global functions all have initial maps. 2653 // Load the initial map. The global functions all have initial maps.
2618 movq(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2654 movq(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
2619 if (FLAG_debug_code) { 2655 if (emit_debug_code()) {
2620 Label ok, fail; 2656 Label ok, fail;
2621 CheckMap(map, FACTORY->meta_map(), &fail, false); 2657 CheckMap(map, FACTORY->meta_map(), &fail, false);
2622 jmp(&ok); 2658 jmp(&ok);
2623 bind(&fail); 2659 bind(&fail);
2624 Abort("Global functions must have initial map"); 2660 Abort("Global functions must have initial map");
2625 bind(&ok); 2661 bind(&ok);
2626 } 2662 }
2627 } 2663 }
2628 2664
2629 2665
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 } else { 2723 } else {
2688 // Push Isolate pointer after all parameters. 2724 // Push Isolate pointer after all parameters.
2689 int argument_slots_on_stack = 2725 int argument_slots_on_stack =
2690 ArgumentStackSlotsForCFunctionCall(num_arguments); 2726 ArgumentStackSlotsForCFunctionCall(num_arguments);
2691 movq(kScratchRegister, ExternalReference::isolate_address()); 2727 movq(kScratchRegister, ExternalReference::isolate_address());
2692 movq(Operand(rsp, argument_slots_on_stack * kPointerSize), 2728 movq(Operand(rsp, argument_slots_on_stack * kPointerSize),
2693 kScratchRegister); 2729 kScratchRegister);
2694 } 2730 }
2695 2731
2696 // Check stack alignment. 2732 // Check stack alignment.
2697 if (FLAG_debug_code) { 2733 if (emit_debug_code()) {
2698 CheckStackAlignment(); 2734 CheckStackAlignment();
2699 } 2735 }
2700 2736
2701 call(function); 2737 call(function);
2702 ASSERT(OS::ActivationFrameAlignment() != 0); 2738 ASSERT(OS::ActivationFrameAlignment() != 0);
2703 ASSERT(num_arguments >= 0); 2739 ASSERT(num_arguments >= 0);
2704 num_arguments += 1; 2740 num_arguments += 1;
2705 int argument_slots_on_stack = 2741 int argument_slots_on_stack =
2706 ArgumentStackSlotsForCFunctionCall(num_arguments); 2742 ArgumentStackSlotsForCFunctionCall(num_arguments);
2707 movq(rsp, Operand(rsp, argument_slots_on_stack * kPointerSize)); 2743 movq(rsp, Operand(rsp, argument_slots_on_stack * kPointerSize));
(...skipping 14 matching lines...) Expand all
2722 CPU::FlushICache(address_, size_); 2758 CPU::FlushICache(address_, size_);
2723 2759
2724 // Check that the code was patched as expected. 2760 // Check that the code was patched as expected.
2725 ASSERT(masm_.pc_ == address_ + size_); 2761 ASSERT(masm_.pc_ == address_ + size_);
2726 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2762 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2727 } 2763 }
2728 2764
2729 } } // namespace v8::internal 2765 } } // namespace v8::internal
2730 2766
2731 #endif // V8_TARGET_ARCH_X64 2767 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | test/benchmarks/testcfg.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698