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

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

Issue 6697023: Merge 6800:7180 from the bleeding edge branch to the experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: 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') | src/x64/regexp-macro-assembler-x64.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 2010 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
11 // with the distribution. 11 // with the distribution.
(...skipping 30 matching lines...) Expand all
42 42
43 MacroAssembler::MacroAssembler(void* buffer, int size) 43 MacroAssembler::MacroAssembler(void* buffer, int size)
44 : Assembler(buffer, size), 44 : Assembler(buffer, size),
45 generating_stub_(false), 45 generating_stub_(false),
46 allow_stub_calls_(true), 46 allow_stub_calls_(true),
47 code_object_(Heap::undefined_value()) { 47 code_object_(Heap::undefined_value()) {
48 } 48 }
49 49
50 50
51 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) { 51 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index) {
52 movq(destination, Operand(kRootRegister, index << kPointerSizeLog2)); 52 movq(destination, Operand(kRootRegister,
53 (index << kPointerSizeLog2) - kRootRegisterBias));
54 }
55
56
57 void MacroAssembler::LoadRootIndexed(Register destination,
58 Register variable_offset,
59 int fixed_offset) {
60 movq(destination,
61 Operand(kRootRegister,
62 variable_offset, times_pointer_size,
63 (fixed_offset << kPointerSizeLog2) - kRootRegisterBias));
53 } 64 }
54 65
55 66
56 void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) { 67 void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index) {
57 movq(Operand(kRootRegister, index << kPointerSizeLog2), source); 68 movq(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias),
69 source);
58 } 70 }
59 71
60 72
61 void MacroAssembler::PushRoot(Heap::RootListIndex index) { 73 void MacroAssembler::PushRoot(Heap::RootListIndex index) {
62 push(Operand(kRootRegister, index << kPointerSizeLog2)); 74 push(Operand(kRootRegister, (index << kPointerSizeLog2) - kRootRegisterBias));
63 } 75 }
64 76
65 77
66 void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) { 78 void MacroAssembler::CompareRoot(Register with, Heap::RootListIndex index) {
67 cmpq(with, Operand(kRootRegister, index << kPointerSizeLog2)); 79 cmpq(with, Operand(kRootRegister,
80 (index << kPointerSizeLog2) - kRootRegisterBias));
68 } 81 }
69 82
70 83
71 void MacroAssembler::CompareRoot(const Operand& with, 84 void MacroAssembler::CompareRoot(const Operand& with,
72 Heap::RootListIndex index) { 85 Heap::RootListIndex index) {
73 ASSERT(!with.AddressUsesRegister(kScratchRegister)); 86 ASSERT(!with.AddressUsesRegister(kScratchRegister));
74 LoadRoot(kScratchRegister, index); 87 LoadRoot(kScratchRegister, index);
75 cmpq(with, kScratchRegister); 88 cmpq(with, kScratchRegister);
76 } 89 }
77 90
78 91
79 void MacroAssembler::RecordWriteHelper(Register object, 92 void MacroAssembler::RecordWriteHelper(Register object,
80 Register addr, 93 Register addr,
81 Register scratch, 94 Register scratch,
82 SaveFPRegsMode save_fp) { 95 SaveFPRegsMode save_fp) {
83 if (FLAG_debug_code) { 96 if (emit_debug_code()) {
84 // Check that the object is not in new space. 97 // Check that the object is not in new space.
85 NearLabel not_in_new_space; 98 NearLabel not_in_new_space;
86 InNewSpace(object, scratch, not_equal, &not_in_new_space); 99 InNewSpace(object, scratch, not_equal, &not_in_new_space);
87 Abort("new-space object passed to RecordWriteHelper"); 100 Abort("new-space object passed to RecordWriteHelper");
88 bind(&not_in_new_space); 101 bind(&not_in_new_space);
89 } 102 }
90 103
91 // Load store buffer top. 104 // Load store buffer top.
92 LoadRoot(scratch, Heap::kStoreBufferTopRootIndex); 105 LoadRoot(scratch, Heap::kStoreBufferTopRootIndex);
93 // Store pointer to buffer. 106 // Store pointer to buffer.
(...skipping 18 matching lines...) Expand all
112 int offset, 125 int offset,
113 Register value, 126 Register value,
114 Register index, 127 Register index,
115 SaveFPRegsMode save_fp) { 128 SaveFPRegsMode save_fp) {
116 // The compiled code assumes that record write doesn't change the 129 // The compiled code assumes that record write doesn't change the
117 // context register, so we check that none of the clobbered 130 // context register, so we check that none of the clobbered
118 // registers are rsi. 131 // registers are rsi.
119 ASSERT(!object.is(rsi) && !value.is(rsi) && !index.is(rsi)); 132 ASSERT(!object.is(rsi) && !value.is(rsi) && !index.is(rsi));
120 133
121 // First, check if a write barrier is even needed. The tests below 134 // First, check if a write barrier is even needed. The tests below
122 // catch stores of Smis and stores into young gen. 135 // catch stores of smis and stores into the young generation.
123 Label done; 136 Label done;
124 JumpIfSmi(value, &done); 137 JumpIfSmi(value, &done);
125 138
126 RecordWriteNonSmi(object, offset, value, index, save_fp); 139 RecordWriteNonSmi(object, offset, value, index, save_fp);
127 bind(&done); 140 bind(&done);
128 141
129 // Clobber all input registers when running with the debug-code flag 142 // Clobber all input registers when running with the debug-code flag
130 // turned on to provoke errors. This clobbering repeats the 143 // turned on to provoke errors. This clobbering repeats the
131 // clobbering done inside RecordWriteNonSmi but it's necessary to 144 // clobbering done inside RecordWriteNonSmi but it's necessary to
132 // avoid having the fast case for smis leave the registers 145 // avoid having the fast case for smis leave the registers
133 // unchanged. 146 // unchanged.
134 if (FLAG_debug_code) { 147 if (emit_debug_code()) {
135 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 148 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
136 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 149 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
137 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 150 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
138 } 151 }
139 } 152 }
140 153
141 154
142 void MacroAssembler::RecordWrite(Register object, 155 void MacroAssembler::RecordWrite(Register object,
143 Register address, 156 Register address,
144 Register value, 157 Register value,
145 SaveFPRegsMode save_fp) { 158 SaveFPRegsMode save_fp) {
146 // The compiled code assumes that record write doesn't change the 159 // The compiled code assumes that record write doesn't change the
147 // context register, so we check that none of the clobbered 160 // context register, so we check that none of the clobbered
148 // registers are esi. 161 // registers are rsi.
149 ASSERT(!object.is(rsi) && !value.is(rsi) && !address.is(rsi)); 162 ASSERT(!object.is(rsi) && !value.is(rsi) && !address.is(rsi));
150 163
151 // First, check if a write barrier is even needed. The tests below 164 // First, check if a write barrier is even needed. The tests below
152 // catch stores of Smis and stores into young gen. 165 // catch stores of smis and stores into the young generation.
153 Label done; 166 Label done;
154 JumpIfSmi(value, &done); 167 JumpIfSmi(value, &done);
155 168
156 InNewSpace(object, value, equal, &done); 169 InNewSpace(object, value, equal, &done);
157 170
158 RecordWriteHelper(object, address, value, save_fp); 171 RecordWriteHelper(object, address, value, save_fp);
159 172
160 bind(&done); 173 bind(&done);
161 174
162 // Clobber all input registers when running with the debug-code flag 175 // Clobber all input registers when running with the debug-code flag
163 // turned on to provoke errors. 176 // turned on to provoke errors.
164 if (FLAG_debug_code) { 177 if (emit_debug_code()) {
165 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 178 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
166 movq(address, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 179 movq(address, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
167 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 180 movq(value, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
168 } 181 }
169 } 182 }
170 183
171 184
172 void MacroAssembler::RecordWriteNonSmi(Register object, 185 void MacroAssembler::RecordWriteNonSmi(Register object,
173 int offset, 186 int offset,
174 Register scratch, 187 Register scratch,
175 Register index, 188 Register index,
176 SaveFPRegsMode save_fp) { 189 SaveFPRegsMode save_fp) {
177 Label done; 190 Label done;
178 191
179 if (FLAG_debug_code) { 192 if (emit_debug_code()) {
180 NearLabel okay; 193 NearLabel okay;
181 JumpIfNotSmi(object, &okay); 194 JumpIfNotSmi(object, &okay);
182 Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis"); 195 Abort("MacroAssembler::RecordWriteNonSmi cannot deal with smis");
183 bind(&okay); 196 bind(&okay);
184 197
185 if (offset == 0) { 198 if (offset == 0) {
186 // index must be int32. 199 // index must be int32.
187 Register tmp = index.is(rax) ? rbx : rax; 200 Register tmp = index.is(rax) ? rbx : rax;
188 push(tmp); 201 push(tmp);
189 movl(tmp, index); 202 movl(tmp, index);
(...skipping 23 matching lines...) Expand all
213 index, 226 index,
214 times_pointer_size, 227 times_pointer_size,
215 FixedArray::kHeaderSize)); 228 FixedArray::kHeaderSize));
216 } 229 }
217 RecordWriteHelper(object, dst, scratch, save_fp); 230 RecordWriteHelper(object, dst, scratch, save_fp);
218 231
219 bind(&done); 232 bind(&done);
220 233
221 // Clobber all input registers when running with the debug-code flag 234 // Clobber all input registers when running with the debug-code flag
222 // turned on to provoke errors. 235 // turned on to provoke errors.
223 if (FLAG_debug_code) { 236 if (emit_debug_code()) {
224 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 237 movq(object, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
225 movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 238 movq(scratch, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
226 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE); 239 movq(index, BitCast<int64_t>(kZapValue), RelocInfo::NONE);
227 } 240 }
228 } 241 }
229 242
230 243
231 void MacroAssembler::Assert(Condition cc, const char* msg) { 244 void MacroAssembler::Assert(Condition cc, const char* msg) {
232 if (FLAG_debug_code) Check(cc, msg); 245 if (emit_debug_code()) Check(cc, msg);
233 } 246 }
234 247
235 248
236 void MacroAssembler::AssertFastElements(Register elements) { 249 void MacroAssembler::AssertFastElements(Register elements) {
237 if (FLAG_debug_code) { 250 if (emit_debug_code()) {
238 NearLabel ok; 251 NearLabel ok;
239 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 252 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
240 Heap::kFixedArrayMapRootIndex); 253 Heap::kFixedArrayMapRootIndex);
241 j(equal, &ok); 254 j(equal, &ok);
242 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset), 255 CompareRoot(FieldOperand(elements, HeapObject::kMapOffset),
243 Heap::kFixedCOWArrayMapRootIndex); 256 Heap::kFixedCOWArrayMapRootIndex);
244 j(equal, &ok); 257 j(equal, &ok);
245 Abort("JSObject with fast elements map has slow elements"); 258 Abort("JSObject with fast elements map has slow elements");
246 bind(&ok); 259 bind(&ok);
247 } 260 }
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 next_address); 559 next_address);
547 const int kLevelOffset = Offset( 560 const int kLevelOffset = Offset(
548 ExternalReference::handle_scope_level_address(), 561 ExternalReference::handle_scope_level_address(),
549 next_address); 562 next_address);
550 ExternalReference scheduled_exception_address = 563 ExternalReference scheduled_exception_address =
551 ExternalReference::scheduled_exception_address(); 564 ExternalReference::scheduled_exception_address();
552 565
553 // Allocate HandleScope in callee-save registers. 566 // Allocate HandleScope in callee-save registers.
554 Register prev_next_address_reg = r14; 567 Register prev_next_address_reg = r14;
555 Register prev_limit_reg = rbx; 568 Register prev_limit_reg = rbx;
556 Register base_reg = r12; 569 Register base_reg = r15;
557 movq(base_reg, next_address); 570 movq(base_reg, next_address);
558 movq(prev_next_address_reg, Operand(base_reg, kNextOffset)); 571 movq(prev_next_address_reg, Operand(base_reg, kNextOffset));
559 movq(prev_limit_reg, Operand(base_reg, kLimitOffset)); 572 movq(prev_limit_reg, Operand(base_reg, kLimitOffset));
560 addl(Operand(base_reg, kLevelOffset), Immediate(1)); 573 addl(Operand(base_reg, kLevelOffset), Immediate(1));
561 // Call the api function! 574 // Call the api function!
562 movq(rax, 575 movq(rax,
563 reinterpret_cast<int64_t>(function->address()), 576 reinterpret_cast<int64_t>(function->address()),
564 RelocInfo::RUNTIME_ENTRY); 577 RelocInfo::RUNTIME_ENTRY);
565 call(rax); 578 call(rax);
566 579
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 640
628 MaybeObject* MacroAssembler::TryJumpToExternalReference( 641 MaybeObject* MacroAssembler::TryJumpToExternalReference(
629 const ExternalReference& ext, int result_size) { 642 const ExternalReference& ext, int result_size) {
630 // Set the entry point and jump to the C entry runtime stub. 643 // Set the entry point and jump to the C entry runtime stub.
631 movq(rbx, ext); 644 movq(rbx, ext);
632 CEntryStub ces(result_size); 645 CEntryStub ces(result_size);
633 return TryTailCallStub(&ces); 646 return TryTailCallStub(&ces);
634 } 647 }
635 648
636 649
637 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id, InvokeFlag flag) { 650 void MacroAssembler::InvokeBuiltin(Builtins::JavaScript id,
651 InvokeFlag flag,
652 CallWrapper* call_wrapper) {
638 // Calls are not allowed in some stubs. 653 // Calls are not allowed in some stubs.
639 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls()); 654 ASSERT(flag == JUMP_FUNCTION || allow_stub_calls());
640 655
641 // Rely on the assertion to check that the number of provided 656 // Rely on the assertion to check that the number of provided
642 // arguments match the expected number of arguments. Fake a 657 // arguments match the expected number of arguments. Fake a
643 // parameter count to avoid emitting code to do the check. 658 // parameter count to avoid emitting code to do the check.
644 ParameterCount expected(0); 659 ParameterCount expected(0);
645 GetBuiltinEntry(rdx, id); 660 GetBuiltinEntry(rdx, id);
646 InvokeCode(rdx, expected, expected, flag); 661 InvokeCode(rdx, expected, expected, flag, call_wrapper);
647 } 662 }
648 663
649 664
650 void MacroAssembler::GetBuiltinFunction(Register target, 665 void MacroAssembler::GetBuiltinFunction(Register target,
651 Builtins::JavaScript id) { 666 Builtins::JavaScript id) {
652 // Load the builtins object into target register. 667 // Load the builtins object into target register.
653 movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); 668 movq(target, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
654 movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset)); 669 movq(target, FieldOperand(target, GlobalObject::kBuiltinsOffset));
655 movq(target, FieldOperand(target, 670 movq(target, FieldOperand(target,
656 JSBuiltinsObject::OffsetOfFunctionWithId(id))); 671 JSBuiltinsObject::OffsetOfFunctionWithId(id)));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 return kScratchRegister; 711 return kScratchRegister;
697 } 712 }
698 if (value == 1) { 713 if (value == 1) {
699 return kSmiConstantRegister; 714 return kSmiConstantRegister;
700 } 715 }
701 LoadSmiConstant(kScratchRegister, source); 716 LoadSmiConstant(kScratchRegister, source);
702 return kScratchRegister; 717 return kScratchRegister;
703 } 718 }
704 719
705 void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) { 720 void MacroAssembler::LoadSmiConstant(Register dst, Smi* source) {
706 if (FLAG_debug_code) { 721 if (emit_debug_code()) {
707 movq(dst, 722 movq(dst,
708 reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)), 723 reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)),
709 RelocInfo::NONE); 724 RelocInfo::NONE);
710 cmpq(dst, kSmiConstantRegister); 725 cmpq(dst, kSmiConstantRegister);
711 if (allow_stub_calls()) { 726 if (allow_stub_calls()) {
712 Assert(equal, "Uninitialized kSmiConstantRegister"); 727 Assert(equal, "Uninitialized kSmiConstantRegister");
713 } else { 728 } else {
714 NearLabel ok; 729 NearLabel ok;
715 j(equal, &ok); 730 j(equal, &ok);
716 int3(); 731 int3();
717 bind(&ok); 732 bind(&ok);
718 } 733 }
719 } 734 }
720 if (source->value() == 0) { 735 int value = source->value();
736 if (value == 0) {
721 xorl(dst, dst); 737 xorl(dst, dst);
722 return; 738 return;
723 } 739 }
724 int value = source->value();
725 bool negative = value < 0; 740 bool negative = value < 0;
726 unsigned int uvalue = negative ? -value : value; 741 unsigned int uvalue = negative ? -value : value;
727 742
728 switch (uvalue) { 743 switch (uvalue) {
729 case 9: 744 case 9:
730 lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_8, 0)); 745 lea(dst, Operand(kSmiConstantRegister, kSmiConstantRegister, times_8, 0));
731 break; 746 break;
732 case 8: 747 case 8:
733 xorl(dst, dst); 748 xorl(dst, dst);
734 lea(dst, Operand(dst, kSmiConstantRegister, times_8, 0)); 749 lea(dst, Operand(dst, kSmiConstantRegister, times_8, 0));
(...skipping 30 matching lines...) Expand all
765 void MacroAssembler::Integer32ToSmi(Register dst, Register src) { 780 void MacroAssembler::Integer32ToSmi(Register dst, Register src) {
766 ASSERT_EQ(0, kSmiTag); 781 ASSERT_EQ(0, kSmiTag);
767 if (!dst.is(src)) { 782 if (!dst.is(src)) {
768 movl(dst, src); 783 movl(dst, src);
769 } 784 }
770 shl(dst, Immediate(kSmiShift)); 785 shl(dst, Immediate(kSmiShift));
771 } 786 }
772 787
773 788
774 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) { 789 void MacroAssembler::Integer32ToSmiField(const Operand& dst, Register src) {
775 if (FLAG_debug_code) { 790 if (emit_debug_code()) {
776 testb(dst, Immediate(0x01)); 791 testb(dst, Immediate(0x01));
777 NearLabel ok; 792 NearLabel ok;
778 j(zero, &ok); 793 j(zero, &ok);
779 if (allow_stub_calls()) { 794 if (allow_stub_calls()) {
780 Abort("Integer32ToSmiField writing to non-smi location"); 795 Abort("Integer32ToSmiField writing to non-smi location");
781 } else { 796 } else {
782 int3(); 797 int3();
783 } 798 }
784 bind(&ok); 799 bind(&ok);
785 } 800 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) { 841 void MacroAssembler::SmiToInteger64(Register dst, const Operand& src) {
827 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte)); 842 movsxlq(dst, Operand(src, kSmiShift / kBitsPerByte));
828 } 843 }
829 844
830 845
831 void MacroAssembler::SmiTest(Register src) { 846 void MacroAssembler::SmiTest(Register src) {
832 testq(src, src); 847 testq(src, src);
833 } 848 }
834 849
835 850
836 void MacroAssembler::SmiCompare(Register dst, Register src) { 851 void MacroAssembler::SmiCompare(Register smi1, Register smi2) {
837 cmpq(dst, src); 852 if (emit_debug_code()) {
853 AbortIfNotSmi(smi1);
854 AbortIfNotSmi(smi2);
855 }
856 cmpq(smi1, smi2);
838 } 857 }
839 858
840 859
841 void MacroAssembler::SmiCompare(Register dst, Smi* src) { 860 void MacroAssembler::SmiCompare(Register dst, Smi* src) {
861 if (emit_debug_code()) {
862 AbortIfNotSmi(dst);
863 }
864 Cmp(dst, src);
865 }
866
867
868 void MacroAssembler::Cmp(Register dst, Smi* src) {
842 ASSERT(!dst.is(kScratchRegister)); 869 ASSERT(!dst.is(kScratchRegister));
843 if (src->value() == 0) { 870 if (src->value() == 0) {
844 testq(dst, dst); 871 testq(dst, dst);
845 } else { 872 } else {
846 Register constant_reg = GetSmiConstant(src); 873 Register constant_reg = GetSmiConstant(src);
847 cmpq(dst, constant_reg); 874 cmpq(dst, constant_reg);
848 } 875 }
849 } 876 }
850 877
851 878
852 void MacroAssembler::SmiCompare(Register dst, const Operand& src) { 879 void MacroAssembler::SmiCompare(Register dst, const Operand& src) {
880 if (emit_debug_code()) {
881 AbortIfNotSmi(dst);
882 AbortIfNotSmi(src);
883 }
853 cmpq(dst, src); 884 cmpq(dst, src);
854 } 885 }
855 886
856 887
857 void MacroAssembler::SmiCompare(const Operand& dst, Register src) { 888 void MacroAssembler::SmiCompare(const Operand& dst, Register src) {
889 if (emit_debug_code()) {
890 AbortIfNotSmi(dst);
891 AbortIfNotSmi(src);
892 }
858 cmpq(dst, src); 893 cmpq(dst, src);
859 } 894 }
860 895
861 896
862 void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) { 897 void MacroAssembler::SmiCompare(const Operand& dst, Smi* src) {
898 if (emit_debug_code()) {
899 AbortIfNotSmi(dst);
900 }
863 cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value())); 901 cmpl(Operand(dst, kSmiShift / kBitsPerByte), Immediate(src->value()));
864 } 902 }
865 903
866 904
905 void MacroAssembler::Cmp(const Operand& dst, Smi* src) {
906 // The Operand cannot use the smi register.
907 Register smi_reg = GetSmiConstant(src);
908 ASSERT(!dst.AddressUsesRegister(smi_reg));
909 cmpq(dst, smi_reg);
910 }
911
912
867 void MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) { 913 void MacroAssembler::SmiCompareInteger32(const Operand& dst, Register src) {
868 cmpl(Operand(dst, kSmiShift / kBitsPerByte), src); 914 cmpl(Operand(dst, kSmiShift / kBitsPerByte), src);
869 } 915 }
870 916
871 917
872 void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst, 918 void MacroAssembler::PositiveSmiTimesPowerOfTwoToInteger64(Register dst,
873 Register src, 919 Register src,
874 int power) { 920 int power) {
875 ASSERT(power >= 0); 921 ASSERT(power >= 0);
876 ASSERT(power < 64); 922 ASSERT(power < 64);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
910 956
911 Condition MacroAssembler::CheckSmi(const Operand& src) { 957 Condition MacroAssembler::CheckSmi(const Operand& src) {
912 ASSERT_EQ(0, kSmiTag); 958 ASSERT_EQ(0, kSmiTag);
913 testb(src, Immediate(kSmiTagMask)); 959 testb(src, Immediate(kSmiTagMask));
914 return zero; 960 return zero;
915 } 961 }
916 962
917 963
918 Condition MacroAssembler::CheckNonNegativeSmi(Register src) { 964 Condition MacroAssembler::CheckNonNegativeSmi(Register src) {
919 ASSERT_EQ(0, kSmiTag); 965 ASSERT_EQ(0, kSmiTag);
920 // Make mask 0x8000000000000001 and test that both bits are zero. 966 // Test that both bits of the mask 0x8000000000000001 are zero.
921 movq(kScratchRegister, src); 967 movq(kScratchRegister, src);
922 rol(kScratchRegister, Immediate(1)); 968 rol(kScratchRegister, Immediate(1));
923 testb(kScratchRegister, Immediate(3)); 969 testb(kScratchRegister, Immediate(3));
924 return zero; 970 return zero;
925 } 971 }
926 972
927 973
928 Condition MacroAssembler::CheckBothSmi(Register first, Register second) { 974 Condition MacroAssembler::CheckBothSmi(Register first, Register second) {
929 if (first.is(second)) { 975 if (first.is(second)) {
930 return CheckSmi(first); 976 return CheckSmi(first);
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
1341 Move(dst, Smi::cast(*source)); 1387 Move(dst, Smi::cast(*source));
1342 } else { 1388 } else {
1343 movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT); 1389 movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT);
1344 movq(dst, kScratchRegister); 1390 movq(dst, kScratchRegister);
1345 } 1391 }
1346 } 1392 }
1347 1393
1348 1394
1349 void MacroAssembler::Cmp(Register dst, Handle<Object> source) { 1395 void MacroAssembler::Cmp(Register dst, Handle<Object> source) {
1350 if (source->IsSmi()) { 1396 if (source->IsSmi()) {
1351 SmiCompare(dst, Smi::cast(*source)); 1397 Cmp(dst, Smi::cast(*source));
1352 } else { 1398 } else {
1353 Move(kScratchRegister, source); 1399 Move(kScratchRegister, source);
1354 cmpq(dst, kScratchRegister); 1400 cmpq(dst, kScratchRegister);
1355 } 1401 }
1356 } 1402 }
1357 1403
1358 1404
1359 void MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) { 1405 void MacroAssembler::Cmp(const Operand& dst, Handle<Object> source) {
1360 if (source->IsSmi()) { 1406 if (source->IsSmi()) {
1361 SmiCompare(dst, Smi::cast(*source)); 1407 Cmp(dst, Smi::cast(*source));
1362 } else { 1408 } else {
1363 ASSERT(source->IsHeapObject()); 1409 ASSERT(source->IsHeapObject());
1364 movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT); 1410 movq(kScratchRegister, source, RelocInfo::EMBEDDED_OBJECT);
1365 cmpq(dst, kScratchRegister); 1411 cmpq(dst, kScratchRegister);
1366 } 1412 }
1367 } 1413 }
1368 1414
1369 1415
1370 void MacroAssembler::Push(Handle<Object> source) { 1416 void MacroAssembler::Push(Handle<Object> source) {
1371 if (source->IsSmi()) { 1417 if (source->IsSmi()) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 } 1459 }
1414 1460
1415 1461
1416 void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) { 1462 void MacroAssembler::Jump(Handle<Code> code_object, RelocInfo::Mode rmode) {
1417 // TODO(X64): Inline this 1463 // TODO(X64): Inline this
1418 jmp(code_object, rmode); 1464 jmp(code_object, rmode);
1419 } 1465 }
1420 1466
1421 1467
1422 void MacroAssembler::Call(ExternalReference ext) { 1468 void MacroAssembler::Call(ExternalReference ext) {
1469 #ifdef DEBUG
1470 int pre_position = pc_offset();
1471 #endif
1423 movq(kScratchRegister, ext); 1472 movq(kScratchRegister, ext);
1424 call(kScratchRegister); 1473 call(kScratchRegister);
1474 #ifdef DEBUG
1475 int post_position = pc_offset();
1476 CHECK_EQ(pre_position + CallSize(ext), post_position);
1477 #endif
1425 } 1478 }
1426 1479
1427 1480
1428 void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) { 1481 void MacroAssembler::Call(Address destination, RelocInfo::Mode rmode) {
1482 #ifdef DEBUG
1483 int pre_position = pc_offset();
1484 #endif
1429 movq(kScratchRegister, destination, rmode); 1485 movq(kScratchRegister, destination, rmode);
1430 call(kScratchRegister); 1486 call(kScratchRegister);
1487 #ifdef DEBUG
1488 int post_position = pc_offset();
1489 CHECK_EQ(pre_position + CallSize(destination, rmode), post_position);
1490 #endif
1431 } 1491 }
1432 1492
1433 1493
1434 void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) { 1494 void MacroAssembler::Call(Handle<Code> code_object, RelocInfo::Mode rmode) {
1495 #ifdef DEBUG
1496 int pre_position = pc_offset();
1497 #endif
1435 ASSERT(RelocInfo::IsCodeTarget(rmode)); 1498 ASSERT(RelocInfo::IsCodeTarget(rmode));
1436 call(code_object, rmode); 1499 call(code_object, rmode);
1500 #ifdef DEBUG
1501 int post_position = pc_offset();
1502 CHECK_EQ(pre_position + CallSize(code_object), post_position);
1503 #endif
1437 } 1504 }
1438 1505
1439 1506
1440 void MacroAssembler::Pushad() { 1507 void MacroAssembler::Pushad() {
1441 push(rax); 1508 push(rax);
1442 push(rcx); 1509 push(rcx);
1443 push(rdx); 1510 push(rdx);
1444 push(rbx); 1511 push(rbx);
1445 // Not pushing rsp or rbp. 1512 // Not pushing rsp or rbp.
1446 push(rsi); 1513 push(rsi);
1447 push(rdi); 1514 push(rdi);
1448 push(r8); 1515 push(r8);
1449 push(r9); 1516 push(r9);
1450 // r10 is kScratchRegister. 1517 // r10 is kScratchRegister.
1451 push(r11); 1518 push(r11);
1452 push(r12); 1519 // r12 is kSmiConstantRegister.
1453 // r13 is kRootRegister. 1520 // r13 is kRootRegister.
1454 push(r14); 1521 push(r14);
1455 // r15 is kSmiConstantRegister 1522 push(r15);
1456 STATIC_ASSERT(11 == kNumSafepointSavedRegisters); 1523 STATIC_ASSERT(11 == kNumSafepointSavedRegisters);
1457 // Use lea for symmetry with Popad. 1524 // Use lea for symmetry with Popad.
1458 lea(rsp, Operand(rsp, 1525 int sp_delta =
1459 -(kNumSafepointRegisters-kNumSafepointSavedRegisters) * kPointerSize)); 1526 (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize;
1527 lea(rsp, Operand(rsp, -sp_delta));
1460 } 1528 }
1461 1529
1462 1530
1463 void MacroAssembler::Popad() { 1531 void MacroAssembler::Popad() {
1464 // Popad must not change the flags, so use lea instead of addq. 1532 // Popad must not change the flags, so use lea instead of addq.
1465 lea(rsp, Operand(rsp, 1533 int sp_delta =
1466 (kNumSafepointRegisters-kNumSafepointSavedRegisters) * kPointerSize)); 1534 (kNumSafepointRegisters - kNumSafepointSavedRegisters) * kPointerSize;
1535 lea(rsp, Operand(rsp, sp_delta));
1536 pop(r15);
1467 pop(r14); 1537 pop(r14);
1468 pop(r12);
1469 pop(r11); 1538 pop(r11);
1470 pop(r9); 1539 pop(r9);
1471 pop(r8); 1540 pop(r8);
1472 pop(rdi); 1541 pop(rdi);
1473 pop(rsi); 1542 pop(rsi);
1474 pop(rbx); 1543 pop(rbx);
1475 pop(rdx); 1544 pop(rdx);
1476 pop(rcx); 1545 pop(rcx);
1477 pop(rax); 1546 pop(rax);
1478 } 1547 }
1479 1548
1480 1549
1481 void MacroAssembler::Dropad() { 1550 void MacroAssembler::Dropad() {
1482 addq(rsp, Immediate(kNumSafepointRegisters * kPointerSize)); 1551 addq(rsp, Immediate(kNumSafepointRegisters * kPointerSize));
1483 } 1552 }
1484 1553
1485 1554
1486 // Order general registers are pushed by Pushad: 1555 // Order general registers are pushed by Pushad:
1487 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14. 1556 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r14, r15.
1488 int MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = { 1557 int MacroAssembler::kSafepointPushRegisterIndices[Register::kNumRegisters] = {
1489 0, 1558 0,
1490 1, 1559 1,
1491 2, 1560 2,
1492 3, 1561 3,
1493 -1, 1562 -1,
1494 -1, 1563 -1,
1495 4, 1564 4,
1496 5, 1565 5,
1497 6, 1566 6,
1498 7, 1567 7,
1499 -1, 1568 -1,
1500 8, 1569 8,
1570 -1,
1571 -1,
1501 9, 1572 9,
1502 -1, 1573 10
1503 10,
1504 -1
1505 }; 1574 };
1506 1575
1507 1576
1577 void MacroAssembler::StoreToSafepointRegisterSlot(Register dst, Register src) {
1578 movq(SafepointRegisterSlot(dst), src);
1579 }
1580
1581
1582 void MacroAssembler::LoadFromSafepointRegisterSlot(Register dst, Register src) {
1583 movq(dst, SafepointRegisterSlot(src));
1584 }
1585
1586
1587 Operand MacroAssembler::SafepointRegisterSlot(Register reg) {
1588 return Operand(rsp, SafepointRegisterStackIndex(reg.code()) * kPointerSize);
1589 }
1590
1591
1508 void MacroAssembler::PushTryHandler(CodeLocation try_location, 1592 void MacroAssembler::PushTryHandler(CodeLocation try_location,
1509 HandlerType type) { 1593 HandlerType type) {
1510 // Adjust this code if not the case. 1594 // Adjust this code if not the case.
1511 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize); 1595 ASSERT(StackHandlerConstants::kSize == 4 * kPointerSize);
1512 1596
1513 // The pc (return address) is already on TOS. This code pushes state, 1597 // The pc (return address) is already on TOS. This code pushes state,
1514 // frame pointer and current handler. Check that they are expected 1598 // frame pointer and current handler. Check that they are expected
1515 // next on the stack, in that order. 1599 // next on the stack, in that order.
1516 ASSERT_EQ(StackHandlerConstants::kStateOffset, 1600 ASSERT_EQ(StackHandlerConstants::kStateOffset,
1517 StackHandlerConstants::kPCOffset - kPointerSize); 1601 StackHandlerConstants::kPCOffset - kPointerSize);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1704 1788
1705 1789
1706 void MacroAssembler::AbortIfSmi(Register object) { 1790 void MacroAssembler::AbortIfSmi(Register object) {
1707 NearLabel ok; 1791 NearLabel ok;
1708 Condition is_smi = CheckSmi(object); 1792 Condition is_smi = CheckSmi(object);
1709 Assert(NegateCondition(is_smi), "Operand is a smi"); 1793 Assert(NegateCondition(is_smi), "Operand is a smi");
1710 } 1794 }
1711 1795
1712 1796
1713 void MacroAssembler::AbortIfNotSmi(Register object) { 1797 void MacroAssembler::AbortIfNotSmi(Register object) {
1714 NearLabel ok; 1798 Condition is_smi = CheckSmi(object);
1799 Assert(is_smi, "Operand is not a smi");
1800 }
1801
1802
1803 void MacroAssembler::AbortIfNotSmi(const Operand& object) {
1715 Condition is_smi = CheckSmi(object); 1804 Condition is_smi = CheckSmi(object);
1716 Assert(is_smi, "Operand is not a smi"); 1805 Assert(is_smi, "Operand is not a smi");
1717 } 1806 }
1718 1807
1719 1808
1720 void MacroAssembler::AbortIfNotString(Register object) { 1809 void MacroAssembler::AbortIfNotString(Register object) {
1721 testb(object, Immediate(kSmiTagMask)); 1810 testb(object, Immediate(kSmiTagMask));
1722 Assert(not_equal, "Operand is not a string"); 1811 Assert(not_equal, "Operand is not a string");
1723 push(object); 1812 push(object);
1724 movq(object, FieldOperand(object, HeapObject::kMapOffset)); 1813 movq(object, FieldOperand(object, HeapObject::kMapOffset));
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 movq(rbx, ExternalReference(Runtime::kDebugBreak)); 1928 movq(rbx, ExternalReference(Runtime::kDebugBreak));
1840 CEntryStub ces(1); 1929 CEntryStub ces(1);
1841 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); 1930 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK);
1842 } 1931 }
1843 #endif // ENABLE_DEBUGGER_SUPPORT 1932 #endif // ENABLE_DEBUGGER_SUPPORT
1844 1933
1845 1934
1846 void MacroAssembler::InvokeCode(Register code, 1935 void MacroAssembler::InvokeCode(Register code,
1847 const ParameterCount& expected, 1936 const ParameterCount& expected,
1848 const ParameterCount& actual, 1937 const ParameterCount& actual,
1849 InvokeFlag flag) { 1938 InvokeFlag flag,
1939 CallWrapper* call_wrapper) {
1850 NearLabel done; 1940 NearLabel done;
1851 InvokePrologue(expected, actual, Handle<Code>::null(), code, &done, flag); 1941 InvokePrologue(expected,
1942 actual,
1943 Handle<Code>::null(),
1944 code,
1945 &done,
1946 flag,
1947 call_wrapper);
1852 if (flag == CALL_FUNCTION) { 1948 if (flag == CALL_FUNCTION) {
1949 if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code));
1853 call(code); 1950 call(code);
1951 if (call_wrapper != NULL) call_wrapper->AfterCall();
1854 } else { 1952 } else {
1855 ASSERT(flag == JUMP_FUNCTION); 1953 ASSERT(flag == JUMP_FUNCTION);
1856 jmp(code); 1954 jmp(code);
1857 } 1955 }
1858 bind(&done); 1956 bind(&done);
1859 } 1957 }
1860 1958
1861 1959
1862 void MacroAssembler::InvokeCode(Handle<Code> code, 1960 void MacroAssembler::InvokeCode(Handle<Code> code,
1863 const ParameterCount& expected, 1961 const ParameterCount& expected,
1864 const ParameterCount& actual, 1962 const ParameterCount& actual,
1865 RelocInfo::Mode rmode, 1963 RelocInfo::Mode rmode,
1866 InvokeFlag flag) { 1964 InvokeFlag flag,
1965 CallWrapper* call_wrapper) {
1867 NearLabel done; 1966 NearLabel done;
1868 Register dummy = rax; 1967 Register dummy = rax;
1869 InvokePrologue(expected, actual, code, dummy, &done, flag); 1968 InvokePrologue(expected,
1969 actual,
1970 code,
1971 dummy,
1972 &done,
1973 flag,
1974 call_wrapper);
1870 if (flag == CALL_FUNCTION) { 1975 if (flag == CALL_FUNCTION) {
1976 if (call_wrapper != NULL) call_wrapper->BeforeCall(CallSize(code));
1871 Call(code, rmode); 1977 Call(code, rmode);
1978 if (call_wrapper != NULL) call_wrapper->AfterCall();
1872 } else { 1979 } else {
1873 ASSERT(flag == JUMP_FUNCTION); 1980 ASSERT(flag == JUMP_FUNCTION);
1874 Jump(code, rmode); 1981 Jump(code, rmode);
1875 } 1982 }
1876 bind(&done); 1983 bind(&done);
1877 } 1984 }
1878 1985
1879 1986
1880 void MacroAssembler::InvokeFunction(Register function, 1987 void MacroAssembler::InvokeFunction(Register function,
1881 const ParameterCount& actual, 1988 const ParameterCount& actual,
1882 InvokeFlag flag) { 1989 InvokeFlag flag,
1990 CallWrapper* call_wrapper) {
1883 ASSERT(function.is(rdi)); 1991 ASSERT(function.is(rdi));
1884 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset)); 1992 movq(rdx, FieldOperand(function, JSFunction::kSharedFunctionInfoOffset));
1885 movq(rsi, FieldOperand(function, JSFunction::kContextOffset)); 1993 movq(rsi, FieldOperand(function, JSFunction::kContextOffset));
1886 movsxlq(rbx, 1994 movsxlq(rbx,
1887 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset)); 1995 FieldOperand(rdx, SharedFunctionInfo::kFormalParameterCountOffset));
1888 // Advances rdx to the end of the Code object header, to the start of 1996 // Advances rdx to the end of the Code object header, to the start of
1889 // the executable code. 1997 // the executable code.
1890 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 1998 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
1891 1999
1892 ParameterCount expected(rbx); 2000 ParameterCount expected(rbx);
1893 InvokeCode(rdx, expected, actual, flag); 2001 InvokeCode(rdx, expected, actual, flag, call_wrapper);
1894 } 2002 }
1895 2003
1896 2004
1897 void MacroAssembler::InvokeFunction(JSFunction* function, 2005 void MacroAssembler::InvokeFunction(JSFunction* function,
1898 const ParameterCount& actual, 2006 const ParameterCount& actual,
1899 InvokeFlag flag) { 2007 InvokeFlag flag,
2008 CallWrapper* call_wrapper) {
1900 ASSERT(function->is_compiled()); 2009 ASSERT(function->is_compiled());
1901 // Get the function and setup the context. 2010 // Get the function and setup the context.
1902 Move(rdi, Handle<JSFunction>(function)); 2011 Move(rdi, Handle<JSFunction>(function));
1903 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); 2012 movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
1904 2013
1905 if (V8::UseCrankshaft()) { 2014 if (V8::UseCrankshaft()) {
1906 // Since Crankshaft can recompile a function, we need to load 2015 // Since Crankshaft can recompile a function, we need to load
1907 // the Code object every time we call the function. 2016 // the Code object every time we call the function.
1908 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset)); 2017 movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
1909 ParameterCount expected(function->shared()->formal_parameter_count()); 2018 ParameterCount expected(function->shared()->formal_parameter_count());
1910 InvokeCode(rdx, expected, actual, flag); 2019 InvokeCode(rdx, expected, actual, flag, call_wrapper);
1911 } else { 2020 } else {
1912 // Invoke the cached code. 2021 // Invoke the cached code.
1913 Handle<Code> code(function->code()); 2022 Handle<Code> code(function->code());
1914 ParameterCount expected(function->shared()->formal_parameter_count()); 2023 ParameterCount expected(function->shared()->formal_parameter_count());
1915 InvokeCode(code, expected, actual, RelocInfo::CODE_TARGET, flag); 2024 InvokeCode(code,
2025 expected,
2026 actual,
2027 RelocInfo::CODE_TARGET,
2028 flag,
2029 call_wrapper);
1916 } 2030 }
1917 } 2031 }
1918 2032
1919 2033
1920 void MacroAssembler::EnterFrame(StackFrame::Type type) { 2034 void MacroAssembler::EnterFrame(StackFrame::Type type) {
1921 push(rbp); 2035 push(rbp);
1922 movq(rbp, rsp); 2036 movq(rbp, rsp);
1923 push(rsi); // Context. 2037 push(rsi); // Context.
1924 Push(Smi::FromInt(type)); 2038 Push(Smi::FromInt(type));
1925 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 2039 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
1926 push(kScratchRegister); 2040 push(kScratchRegister);
1927 if (FLAG_debug_code) { 2041 if (emit_debug_code()) {
1928 movq(kScratchRegister, 2042 movq(kScratchRegister,
1929 Factory::undefined_value(), 2043 Factory::undefined_value(),
1930 RelocInfo::EMBEDDED_OBJECT); 2044 RelocInfo::EMBEDDED_OBJECT);
1931 cmpq(Operand(rsp, 0), kScratchRegister); 2045 cmpq(Operand(rsp, 0), kScratchRegister);
1932 Check(not_equal, "code object not properly patched"); 2046 Check(not_equal, "code object not properly patched");
1933 } 2047 }
1934 } 2048 }
1935 2049
1936 2050
1937 void MacroAssembler::LeaveFrame(StackFrame::Type type) { 2051 void MacroAssembler::LeaveFrame(StackFrame::Type type) {
1938 if (FLAG_debug_code) { 2052 if (emit_debug_code()) {
1939 Move(kScratchRegister, Smi::FromInt(type)); 2053 Move(kScratchRegister, Smi::FromInt(type));
1940 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister); 2054 cmpq(Operand(rbp, StandardFrameConstants::kMarkerOffset), kScratchRegister);
1941 Check(equal, "stack frame types must match"); 2055 Check(equal, "stack frame types must match");
1942 } 2056 }
1943 movq(rsp, rbp); 2057 movq(rsp, rbp);
1944 pop(rbp); 2058 pop(rbp);
1945 } 2059 }
1946 2060
1947 2061
1948 void MacroAssembler::EnterExitFramePrologue(bool save_rax) { 2062 void MacroAssembler::EnterExitFramePrologue(bool save_rax) {
1949 // Setup the frame structure on the stack. 2063 // Setup the frame structure on the stack.
1950 // All constants are relative to the frame pointer of the exit frame. 2064 // All constants are relative to the frame pointer of the exit frame.
1951 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize); 2065 ASSERT(ExitFrameConstants::kCallerSPDisplacement == +2 * kPointerSize);
1952 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize); 2066 ASSERT(ExitFrameConstants::kCallerPCOffset == +1 * kPointerSize);
1953 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize); 2067 ASSERT(ExitFrameConstants::kCallerFPOffset == 0 * kPointerSize);
1954 push(rbp); 2068 push(rbp);
1955 movq(rbp, rsp); 2069 movq(rbp, rsp);
1956 2070
1957 // Reserve room for entry stack pointer and push the code object. 2071 // Reserve room for entry stack pointer and push the code object.
1958 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize); 2072 ASSERT(ExitFrameConstants::kSPOffset == -1 * kPointerSize);
1959 push(Immediate(0)); // Saved entry sp, patched before call. 2073 push(Immediate(0)); // Saved entry sp, patched before call.
1960 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT); 2074 movq(kScratchRegister, CodeObject(), RelocInfo::EMBEDDED_OBJECT);
1961 push(kScratchRegister); // Accessed from EditFrame::code_slot. 2075 push(kScratchRegister); // Accessed from EditFrame::code_slot.
1962 2076
1963 // Save the frame pointer and the context in top. 2077 // Save the frame pointer and the context in top.
1964 ExternalReference c_entry_fp_address(Top::k_c_entry_fp_address);
1965 ExternalReference context_address(Top::k_context_address);
1966 if (save_rax) { 2078 if (save_rax) {
1967 movq(r14, rax); // Backup rax before we use it. 2079 movq(r14, rax); // Backup rax in callee-save register.
1968 } 2080 }
1969 2081
1970 movq(rax, rbp); 2082 movq(kScratchRegister, ExternalReference(Top::k_c_entry_fp_address));
1971 store_rax(c_entry_fp_address); 2083 movq(Operand(kScratchRegister, 0), rbp);
1972 movq(rax, rsi); 2084
1973 store_rax(context_address); 2085 movq(kScratchRegister, ExternalReference(Top::k_context_address));
2086 movq(Operand(kScratchRegister, 0), rsi);
1974 } 2087 }
1975 2088
1976 2089
1977 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, 2090 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space,
1978 bool save_doubles) { 2091 bool save_doubles) {
1979 #ifdef _WIN64 2092 #ifdef _WIN64
1980 const int kShadowSpace = 4; 2093 const int kShadowSpace = 4;
1981 arg_stack_space += kShadowSpace; 2094 arg_stack_space += kShadowSpace;
1982 #endif 2095 #endif
1983 // Optionally save all XMM registers. 2096 // Optionally save all XMM registers.
(...skipping 20 matching lines...) Expand all
2004 } 2117 }
2005 2118
2006 // Patch the saved entry sp. 2119 // Patch the saved entry sp.
2007 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp); 2120 movq(Operand(rbp, ExitFrameConstants::kSPOffset), rsp);
2008 } 2121 }
2009 2122
2010 2123
2011 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) { 2124 void MacroAssembler::EnterExitFrame(int arg_stack_space, bool save_doubles) {
2012 EnterExitFramePrologue(true); 2125 EnterExitFramePrologue(true);
2013 2126
2014 // Setup argv in callee-saved register r12. It is reused in LeaveExitFrame, 2127 // Setup argv in callee-saved register r15. It is reused in LeaveExitFrame,
2015 // so it must be retained across the C-call. 2128 // so it must be retained across the C-call.
2016 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; 2129 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize;
2017 lea(r12, Operand(rbp, r14, times_pointer_size, offset)); 2130 lea(r15, Operand(rbp, r14, times_pointer_size, offset));
2018 2131
2019 EnterExitFrameEpilogue(arg_stack_space, save_doubles); 2132 EnterExitFrameEpilogue(arg_stack_space, save_doubles);
2020 } 2133 }
2021 2134
2022 2135
2023 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) { 2136 void MacroAssembler::EnterApiExitFrame(int arg_stack_space) {
2024 EnterExitFramePrologue(false); 2137 EnterExitFramePrologue(false);
2025 EnterExitFrameEpilogue(arg_stack_space, false); 2138 EnterExitFrameEpilogue(arg_stack_space, false);
2026 } 2139 }
2027 2140
2028 2141
2029 void MacroAssembler::LeaveExitFrame(bool save_doubles) { 2142 void MacroAssembler::LeaveExitFrame(bool save_doubles) {
2030 // Registers: 2143 // Registers:
2031 // r12 : argv 2144 // r15 : argv
2032 if (save_doubles) { 2145 if (save_doubles) {
2033 int offset = -2 * kPointerSize; 2146 int offset = -2 * kPointerSize;
2034 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; i++) { 2147 for (int i = 0; i < XMMRegister::kNumAllocatableRegisters; i++) {
2035 XMMRegister reg = XMMRegister::FromAllocationIndex(i); 2148 XMMRegister reg = XMMRegister::FromAllocationIndex(i);
2036 movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); 2149 movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize)));
2037 } 2150 }
2038 } 2151 }
2039 // Get the return address from the stack and restore the frame pointer. 2152 // Get the return address from the stack and restore the frame pointer.
2040 movq(rcx, Operand(rbp, 1 * kPointerSize)); 2153 movq(rcx, Operand(rbp, 1 * kPointerSize));
2041 movq(rbp, Operand(rbp, 0 * kPointerSize)); 2154 movq(rbp, Operand(rbp, 0 * kPointerSize));
2042 2155
2043 // Drop everything up to and including the arguments and the receiver 2156 // Drop everything up to and including the arguments and the receiver
2044 // from the caller stack. 2157 // from the caller stack.
2045 lea(rsp, Operand(r12, 1 * kPointerSize)); 2158 lea(rsp, Operand(r15, 1 * kPointerSize));
2046 2159
2047 // Push the return address to get ready to return. 2160 // Push the return address to get ready to return.
2048 push(rcx); 2161 push(rcx);
2049 2162
2050 LeaveExitFrameEpilogue(); 2163 LeaveExitFrameEpilogue();
2051 } 2164 }
2052 2165
2053 2166
2054 void MacroAssembler::LeaveApiExitFrame() { 2167 void MacroAssembler::LeaveApiExitFrame() {
2055 movq(rsp, rbp); 2168 movq(rsp, rbp);
(...skipping 23 matching lines...) Expand all
2079 Register scratch, 2192 Register scratch,
2080 Label* miss) { 2193 Label* miss) {
2081 Label same_contexts; 2194 Label same_contexts;
2082 2195
2083 ASSERT(!holder_reg.is(scratch)); 2196 ASSERT(!holder_reg.is(scratch));
2084 ASSERT(!scratch.is(kScratchRegister)); 2197 ASSERT(!scratch.is(kScratchRegister));
2085 // Load current lexical context from the stack frame. 2198 // Load current lexical context from the stack frame.
2086 movq(scratch, Operand(rbp, StandardFrameConstants::kContextOffset)); 2199 movq(scratch, Operand(rbp, StandardFrameConstants::kContextOffset));
2087 2200
2088 // When generating debug code, make sure the lexical context is set. 2201 // When generating debug code, make sure the lexical context is set.
2089 if (FLAG_debug_code) { 2202 if (emit_debug_code()) {
2090 cmpq(scratch, Immediate(0)); 2203 cmpq(scratch, Immediate(0));
2091 Check(not_equal, "we should not have an empty lexical context"); 2204 Check(not_equal, "we should not have an empty lexical context");
2092 } 2205 }
2093 // Load the global context of the current context. 2206 // Load the global context of the current context.
2094 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize; 2207 int offset = Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
2095 movq(scratch, FieldOperand(scratch, offset)); 2208 movq(scratch, FieldOperand(scratch, offset));
2096 movq(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset)); 2209 movq(scratch, FieldOperand(scratch, GlobalObject::kGlobalContextOffset));
2097 2210
2098 // Check the context is a global context. 2211 // Check the context is a global context.
2099 if (FLAG_debug_code) { 2212 if (emit_debug_code()) {
2100 Cmp(FieldOperand(scratch, HeapObject::kMapOffset), 2213 Cmp(FieldOperand(scratch, HeapObject::kMapOffset),
2101 Factory::global_context_map()); 2214 Factory::global_context_map());
2102 Check(equal, "JSGlobalObject::global_context should be a global context."); 2215 Check(equal, "JSGlobalObject::global_context should be a global context.");
2103 } 2216 }
2104 2217
2105 // Check if both contexts are the same. 2218 // Check if both contexts are the same.
2106 cmpq(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); 2219 cmpq(scratch, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
2107 j(equal, &same_contexts); 2220 j(equal, &same_contexts);
2108 2221
2109 // Compare security tokens. 2222 // Compare security tokens.
2110 // Check that the security token in the calling global object is 2223 // Check that the security token in the calling global object is
2111 // compatible with the security token in the receiving global 2224 // compatible with the security token in the receiving global
2112 // object. 2225 // object.
2113 2226
2114 // Check the context is a global context. 2227 // Check the context is a global context.
2115 if (FLAG_debug_code) { 2228 if (emit_debug_code()) {
2116 // Preserve original value of holder_reg. 2229 // Preserve original value of holder_reg.
2117 push(holder_reg); 2230 push(holder_reg);
2118 movq(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset)); 2231 movq(holder_reg, FieldOperand(holder_reg, JSGlobalProxy::kContextOffset));
2119 CompareRoot(holder_reg, Heap::kNullValueRootIndex); 2232 CompareRoot(holder_reg, Heap::kNullValueRootIndex);
2120 Check(not_equal, "JSGlobalProxy::context() should not be null."); 2233 Check(not_equal, "JSGlobalProxy::context() should not be null.");
2121 2234
2122 // Read the first word and compare to global_context_map(), 2235 // Read the first word and compare to global_context_map(),
2123 movq(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset)); 2236 movq(holder_reg, FieldOperand(holder_reg, HeapObject::kMapOffset));
2124 CompareRoot(holder_reg, Heap::kGlobalContextMapRootIndex); 2237 CompareRoot(holder_reg, Heap::kGlobalContextMapRootIndex);
2125 Check(equal, "JSGlobalObject::global_context should be a global context."); 2238 Check(equal, "JSGlobalObject::global_context should be a global context.");
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2166 load_rax(new_space_allocation_top); 2279 load_rax(new_space_allocation_top);
2167 } else { 2280 } else {
2168 movq(kScratchRegister, new_space_allocation_top); 2281 movq(kScratchRegister, new_space_allocation_top);
2169 movq(result, Operand(kScratchRegister, 0)); 2282 movq(result, Operand(kScratchRegister, 0));
2170 } 2283 }
2171 } 2284 }
2172 2285
2173 2286
2174 void MacroAssembler::UpdateAllocationTopHelper(Register result_end, 2287 void MacroAssembler::UpdateAllocationTopHelper(Register result_end,
2175 Register scratch) { 2288 Register scratch) {
2176 if (FLAG_debug_code) { 2289 if (emit_debug_code()) {
2177 testq(result_end, Immediate(kObjectAlignmentMask)); 2290 testq(result_end, Immediate(kObjectAlignmentMask));
2178 Check(zero, "Unaligned allocation in new space"); 2291 Check(zero, "Unaligned allocation in new space");
2179 } 2292 }
2180 2293
2181 ExternalReference new_space_allocation_top = 2294 ExternalReference new_space_allocation_top =
2182 ExternalReference::new_space_allocation_top_address(); 2295 ExternalReference::new_space_allocation_top_address();
2183 2296
2184 // Update new top. 2297 // Update new top.
2185 if (result_end.is(rax)) { 2298 if (result_end.is(rax)) {
2186 // rax can be stored directly to a memory location. 2299 // rax can be stored directly to a memory location.
(...skipping 10 matching lines...) Expand all
2197 } 2310 }
2198 2311
2199 2312
2200 void MacroAssembler::AllocateInNewSpace(int object_size, 2313 void MacroAssembler::AllocateInNewSpace(int object_size,
2201 Register result, 2314 Register result,
2202 Register result_end, 2315 Register result_end,
2203 Register scratch, 2316 Register scratch,
2204 Label* gc_required, 2317 Label* gc_required,
2205 AllocationFlags flags) { 2318 AllocationFlags flags) {
2206 if (!FLAG_inline_new) { 2319 if (!FLAG_inline_new) {
2207 if (FLAG_debug_code) { 2320 if (emit_debug_code()) {
2208 // Trash the registers to simulate an allocation failure. 2321 // Trash the registers to simulate an allocation failure.
2209 movl(result, Immediate(0x7091)); 2322 movl(result, Immediate(0x7091));
2210 if (result_end.is_valid()) { 2323 if (result_end.is_valid()) {
2211 movl(result_end, Immediate(0x7191)); 2324 movl(result_end, Immediate(0x7191));
2212 } 2325 }
2213 if (scratch.is_valid()) { 2326 if (scratch.is_valid()) {
2214 movl(scratch, Immediate(0x7291)); 2327 movl(scratch, Immediate(0x7291));
2215 } 2328 }
2216 } 2329 }
2217 jmp(gc_required); 2330 jmp(gc_required);
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2255 2368
2256 void MacroAssembler::AllocateInNewSpace(int header_size, 2369 void MacroAssembler::AllocateInNewSpace(int header_size,
2257 ScaleFactor element_size, 2370 ScaleFactor element_size,
2258 Register element_count, 2371 Register element_count,
2259 Register result, 2372 Register result,
2260 Register result_end, 2373 Register result_end,
2261 Register scratch, 2374 Register scratch,
2262 Label* gc_required, 2375 Label* gc_required,
2263 AllocationFlags flags) { 2376 AllocationFlags flags) {
2264 if (!FLAG_inline_new) { 2377 if (!FLAG_inline_new) {
2265 if (FLAG_debug_code) { 2378 if (emit_debug_code()) {
2266 // Trash the registers to simulate an allocation failure. 2379 // Trash the registers to simulate an allocation failure.
2267 movl(result, Immediate(0x7091)); 2380 movl(result, Immediate(0x7091));
2268 movl(result_end, Immediate(0x7191)); 2381 movl(result_end, Immediate(0x7191));
2269 if (scratch.is_valid()) { 2382 if (scratch.is_valid()) {
2270 movl(scratch, Immediate(0x7291)); 2383 movl(scratch, Immediate(0x7291));
2271 } 2384 }
2272 // Register element_count is not modified by the function. 2385 // Register element_count is not modified by the function.
2273 } 2386 }
2274 jmp(gc_required); 2387 jmp(gc_required);
2275 return; 2388 return;
(...skipping 26 matching lines...) Expand all
2302 } 2415 }
2303 2416
2304 2417
2305 void MacroAssembler::AllocateInNewSpace(Register object_size, 2418 void MacroAssembler::AllocateInNewSpace(Register object_size,
2306 Register result, 2419 Register result,
2307 Register result_end, 2420 Register result_end,
2308 Register scratch, 2421 Register scratch,
2309 Label* gc_required, 2422 Label* gc_required,
2310 AllocationFlags flags) { 2423 AllocationFlags flags) {
2311 if (!FLAG_inline_new) { 2424 if (!FLAG_inline_new) {
2312 if (FLAG_debug_code) { 2425 if (emit_debug_code()) {
2313 // Trash the registers to simulate an allocation failure. 2426 // Trash the registers to simulate an allocation failure.
2314 movl(result, Immediate(0x7091)); 2427 movl(result, Immediate(0x7091));
2315 movl(result_end, Immediate(0x7191)); 2428 movl(result_end, Immediate(0x7191));
2316 if (scratch.is_valid()) { 2429 if (scratch.is_valid()) {
2317 movl(scratch, Immediate(0x7291)); 2430 movl(scratch, Immediate(0x7291));
2318 } 2431 }
2319 // object_size is left unchanged by this function. 2432 // object_size is left unchanged by this function.
2320 } 2433 }
2321 jmp(gc_required); 2434 jmp(gc_required);
2322 return; 2435 return;
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
2498 // Move up the chain of contexts to the context containing the slot. 2611 // Move up the chain of contexts to the context containing the slot.
2499 movq(dst, Operand(rsi, Context::SlotOffset(Context::CLOSURE_INDEX))); 2612 movq(dst, Operand(rsi, Context::SlotOffset(Context::CLOSURE_INDEX)));
2500 // Load the function context (which is the incoming, outer context). 2613 // Load the function context (which is the incoming, outer context).
2501 movq(dst, FieldOperand(dst, JSFunction::kContextOffset)); 2614 movq(dst, FieldOperand(dst, JSFunction::kContextOffset));
2502 for (int i = 1; i < context_chain_length; i++) { 2615 for (int i = 1; i < context_chain_length; i++) {
2503 movq(dst, Operand(dst, Context::SlotOffset(Context::CLOSURE_INDEX))); 2616 movq(dst, Operand(dst, Context::SlotOffset(Context::CLOSURE_INDEX)));
2504 movq(dst, FieldOperand(dst, JSFunction::kContextOffset)); 2617 movq(dst, FieldOperand(dst, JSFunction::kContextOffset));
2505 } 2618 }
2506 // The context may be an intermediate context, not a function context. 2619 // The context may be an intermediate context, not a function context.
2507 movq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX))); 2620 movq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
2508 } else { // context is the current function context. 2621 } else {
2509 // The context may be an intermediate context, not a function context. 2622 // Slot is in the current function context. Move it into the
2510 movq(dst, Operand(rsi, Context::SlotOffset(Context::FCONTEXT_INDEX))); 2623 // destination register in case we store into it (the write barrier
2624 // cannot be allowed to destroy the context in rsi).
2625 movq(dst, rsi);
2626 }
2627
2628 // We should not have found a 'with' context by walking the context chain
2629 // (i.e., the static scope chain and runtime context chain do not agree).
2630 // A variable occurring in such a scope should have slot type LOOKUP and
2631 // not CONTEXT.
2632 if (emit_debug_code()) {
2633 cmpq(dst, Operand(dst, Context::SlotOffset(Context::FCONTEXT_INDEX)));
2634 Check(equal, "Yo dawg, I heard you liked function contexts "
2635 "so I put function contexts in all your contexts");
2511 } 2636 }
2512 } 2637 }
2513 2638
2514 2639
2515 void MacroAssembler::LoadGlobalFunction(int index, Register function) { 2640 void MacroAssembler::LoadGlobalFunction(int index, Register function) {
2516 // Load the global or builtins object from the current context. 2641 // Load the global or builtins object from the current context.
2517 movq(function, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); 2642 movq(function, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX)));
2518 // Load the global context from the global or builtins object. 2643 // Load the global context from the global or builtins object.
2519 movq(function, FieldOperand(function, GlobalObject::kGlobalContextOffset)); 2644 movq(function, FieldOperand(function, GlobalObject::kGlobalContextOffset));
2520 // Load the function from the global context. 2645 // Load the function from the global context.
2521 movq(function, Operand(function, Context::SlotOffset(index))); 2646 movq(function, Operand(function, Context::SlotOffset(index)));
2522 } 2647 }
2523 2648
2524 2649
2525 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, 2650 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function,
2526 Register map) { 2651 Register map) {
2527 // Load the initial map. The global functions all have initial maps. 2652 // Load the initial map. The global functions all have initial maps.
2528 movq(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset)); 2653 movq(map, FieldOperand(function, JSFunction::kPrototypeOrInitialMapOffset));
2529 if (FLAG_debug_code) { 2654 if (emit_debug_code()) {
2530 Label ok, fail; 2655 Label ok, fail;
2531 CheckMap(map, Factory::meta_map(), &fail, false); 2656 CheckMap(map, Factory::meta_map(), &fail, false);
2532 jmp(&ok); 2657 jmp(&ok);
2533 bind(&fail); 2658 bind(&fail);
2534 Abort("Global functions must have initial map"); 2659 Abort("Global functions must have initial map");
2535 bind(&ok); 2660 bind(&ok);
2536 } 2661 }
2537 } 2662 }
2538 2663
2539 2664
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2574 2699
2575 void MacroAssembler::CallCFunction(ExternalReference function, 2700 void MacroAssembler::CallCFunction(ExternalReference function,
2576 int num_arguments) { 2701 int num_arguments) {
2577 movq(rax, function); 2702 movq(rax, function);
2578 CallCFunction(rax, num_arguments); 2703 CallCFunction(rax, num_arguments);
2579 } 2704 }
2580 2705
2581 2706
2582 void MacroAssembler::CallCFunction(Register function, int num_arguments) { 2707 void MacroAssembler::CallCFunction(Register function, int num_arguments) {
2583 // Check stack alignment. 2708 // Check stack alignment.
2584 if (FLAG_debug_code) { 2709 if (emit_debug_code()) {
2585 CheckStackAlignment(); 2710 CheckStackAlignment();
2586 } 2711 }
2587 2712
2588 call(function); 2713 call(function);
2589 ASSERT(OS::ActivationFrameAlignment() != 0); 2714 ASSERT(OS::ActivationFrameAlignment() != 0);
2590 ASSERT(num_arguments >= 0); 2715 ASSERT(num_arguments >= 0);
2591 int argument_slots_on_stack = 2716 int argument_slots_on_stack =
2592 ArgumentStackSlotsForCFunctionCall(num_arguments); 2717 ArgumentStackSlotsForCFunctionCall(num_arguments);
2593 movq(rsp, Operand(rsp, argument_slots_on_stack * kPointerSize)); 2718 movq(rsp, Operand(rsp, argument_slots_on_stack * kPointerSize));
2594 } 2719 }
(...skipping 13 matching lines...) Expand all
2608 CPU::FlushICache(address_, size_); 2733 CPU::FlushICache(address_, size_);
2609 2734
2610 // Check that the code was patched as expected. 2735 // Check that the code was patched as expected.
2611 ASSERT(masm_.pc_ == address_ + size_); 2736 ASSERT(masm_.pc_ == address_ + size_);
2612 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap); 2737 ASSERT(masm_.reloc_info_writer.pos() == address_ + size_ + Assembler::kGap);
2613 } 2738 }
2614 2739
2615 } } // namespace v8::internal 2740 } } // namespace v8::internal
2616 2741
2617 #endif // V8_TARGET_ARCH_X64 2742 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.h ('k') | src/x64/regexp-macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698