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

Side by Side Diff: src/x64/virtual-frame-x64.cc

Issue 660095: Merge revision 3813 to 3930 from bleeding_edge to partial snapshots branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: '' Created 10 years, 10 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/virtual-frame-x64.h ('k') | test/cctest/test-api.cc » ('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 2010 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 27 matching lines...) Expand all
38 38
39 // ------------------------------------------------------------------------- 39 // -------------------------------------------------------------------------
40 // VirtualFrame implementation. 40 // VirtualFrame implementation.
41 41
42 // On entry to a function, the virtual frame already contains the receiver, 42 // On entry to a function, the virtual frame already contains the receiver,
43 // the parameters, and a return address. All frame elements are in memory. 43 // the parameters, and a return address. All frame elements are in memory.
44 VirtualFrame::VirtualFrame() 44 VirtualFrame::VirtualFrame()
45 : elements_(parameter_count() + local_count() + kPreallocatedElements), 45 : elements_(parameter_count() + local_count() + kPreallocatedElements),
46 stack_pointer_(parameter_count() + 1) { // 0-based index of TOS. 46 stack_pointer_(parameter_count() + 1) { // 0-based index of TOS.
47 for (int i = 0; i <= stack_pointer_; i++) { 47 for (int i = 0; i <= stack_pointer_; i++) {
48 elements_.Add(FrameElement::MemoryElement()); 48 elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown));
49 } 49 }
50 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) { 50 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
51 register_locations_[i] = kIllegalIndex; 51 register_locations_[i] = kIllegalIndex;
52 } 52 }
53 } 53 }
54 54
55 55
56 void VirtualFrame::Enter() { 56 void VirtualFrame::Enter() {
57 // Registers live on entry to a JS frame: 57 // Registers live on entry to a JS frame:
58 // rsp: stack pointer, points to return address from this function. 58 // rsp: stack pointer, points to return address from this function.
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 186
187 187
188 void VirtualFrame::EmitPop(const Operand& operand) { 188 void VirtualFrame::EmitPop(const Operand& operand) {
189 ASSERT(stack_pointer_ == element_count() - 1); 189 ASSERT(stack_pointer_ == element_count() - 1);
190 stack_pointer_--; 190 stack_pointer_--;
191 elements_.RemoveLast(); 191 elements_.RemoveLast();
192 __ pop(operand); 192 __ pop(operand);
193 } 193 }
194 194
195 195
196 void VirtualFrame::EmitPush(Register reg) { 196 void VirtualFrame::EmitPush(Register reg, NumberInfo::Type info) {
197 ASSERT(stack_pointer_ == element_count() - 1); 197 ASSERT(stack_pointer_ == element_count() - 1);
198 elements_.Add(FrameElement::MemoryElement()); 198 elements_.Add(FrameElement::MemoryElement(info));
199 stack_pointer_++; 199 stack_pointer_++;
200 __ push(reg); 200 __ push(reg);
201 } 201 }
202 202
203 203
204 void VirtualFrame::EmitPush(const Operand& operand) { 204 void VirtualFrame::EmitPush(const Operand& operand, NumberInfo::Type info) {
205 ASSERT(stack_pointer_ == element_count() - 1); 205 ASSERT(stack_pointer_ == element_count() - 1);
206 elements_.Add(FrameElement::MemoryElement()); 206 elements_.Add(FrameElement::MemoryElement(info));
207 stack_pointer_++; 207 stack_pointer_++;
208 __ push(operand); 208 __ push(operand);
209 } 209 }
210 210
211 211
212 void VirtualFrame::EmitPush(Immediate immediate) { 212 void VirtualFrame::EmitPush(Immediate immediate, NumberInfo::Type info) {
213 ASSERT(stack_pointer_ == element_count() - 1); 213 ASSERT(stack_pointer_ == element_count() - 1);
214 elements_.Add(FrameElement::MemoryElement()); 214 elements_.Add(FrameElement::MemoryElement(info));
215 stack_pointer_++; 215 stack_pointer_++;
216 __ push(immediate); 216 __ push(immediate);
217 } 217 }
218 218
219 219
220 void VirtualFrame::EmitPush(Smi* smi_value) { 220 void VirtualFrame::EmitPush(Smi* smi_value) {
221 ASSERT(stack_pointer_ == element_count() - 1); 221 ASSERT(stack_pointer_ == element_count() - 1);
222 elements_.Add(FrameElement::MemoryElement()); 222 elements_.Add(FrameElement::MemoryElement(NumberInfo::kSmi));
223 stack_pointer_++; 223 stack_pointer_++;
224 __ Push(smi_value); 224 __ Push(smi_value);
225 } 225 }
226 226
227 227
228 void VirtualFrame::EmitPush(Handle<Object> value) { 228 void VirtualFrame::EmitPush(Handle<Object> value) {
229 ASSERT(stack_pointer_ == element_count() - 1); 229 ASSERT(stack_pointer_ == element_count() - 1);
230 elements_.Add(FrameElement::MemoryElement()); 230 NumberInfo::Type info = NumberInfo::kUnknown;
231 if (value->IsSmi()) {
232 info = NumberInfo::kSmi;
233 } else if (value->IsHeapNumber()) {
234 info = NumberInfo::kHeapNumber;
235 }
236 elements_.Add(FrameElement::MemoryElement(info));
231 stack_pointer_++; 237 stack_pointer_++;
232 __ Push(value); 238 __ Push(value);
233 } 239 }
234 240
235 241
236 void VirtualFrame::EmitPush(Heap::RootListIndex index) { 242 void VirtualFrame::EmitPush(Heap::RootListIndex index, NumberInfo::Type info) {
237 ASSERT(stack_pointer_ == element_count() - 1); 243 ASSERT(stack_pointer_ == element_count() - 1);
238 elements_.Add(FrameElement::MemoryElement()); 244 elements_.Add(FrameElement::MemoryElement(info));
239 stack_pointer_++; 245 stack_pointer_++;
240 __ PushRoot(index); 246 __ PushRoot(index);
241 } 247 }
242 248
243 249
244 void VirtualFrame::Drop(int count) { 250 void VirtualFrame::Drop(int count) {
245 ASSERT(count >= 0); 251 ASSERT(count >= 0);
246 ASSERT(height() >= count); 252 ASSERT(height() >= count);
247 int num_virtual_elements = (element_count() - 1) - stack_pointer_; 253 int num_virtual_elements = (element_count() - 1) - stack_pointer_;
248 254
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 } else { 304 } else {
299 // The original was in a register. 305 // The original was in a register.
300 backing_reg = original.reg(); 306 backing_reg = original.reg();
301 set_register_location(backing_reg, new_backing_index); 307 set_register_location(backing_reg, new_backing_index);
302 } 308 }
303 // Invalidate the element at index. 309 // Invalidate the element at index.
304 elements_[index] = FrameElement::InvalidElement(); 310 elements_[index] = FrameElement::InvalidElement();
305 // Set the new backing element. 311 // Set the new backing element.
306 if (elements_[new_backing_index].is_synced()) { 312 if (elements_[new_backing_index].is_synced()) {
307 elements_[new_backing_index] = 313 elements_[new_backing_index] =
308 FrameElement::RegisterElement(backing_reg, FrameElement::SYNCED); 314 FrameElement::RegisterElement(backing_reg,
315 FrameElement::SYNCED,
316 original.number_info());
309 } else { 317 } else {
310 elements_[new_backing_index] = 318 elements_[new_backing_index] =
311 FrameElement::RegisterElement(backing_reg, FrameElement::NOT_SYNCED); 319 FrameElement::RegisterElement(backing_reg,
320 FrameElement::NOT_SYNCED,
321 original.number_info());
312 } 322 }
313 // Update the other copies. 323 // Update the other copies.
314 for (int i = new_backing_index + 1; i < element_count(); i++) { 324 for (int i = new_backing_index + 1; i < element_count(); i++) {
315 if (elements_[i].is_copy() && elements_[i].index() == index) { 325 if (elements_[i].is_copy() && elements_[i].index() == index) {
316 elements_[i].set_index(new_backing_index); 326 elements_[i].set_index(new_backing_index);
317 elements_[new_backing_index].set_copied(); 327 elements_[new_backing_index].set_copied();
318 } 328 }
319 } 329 }
320 return new_backing_index; 330 return new_backing_index;
321 } 331 }
(...skipping 10 matching lines...) Expand all
332 } 342 }
333 343
334 switch (original.type()) { 344 switch (original.type()) {
335 case FrameElement::MEMORY: { 345 case FrameElement::MEMORY: {
336 // Emit code to load the original element's data into a register. 346 // Emit code to load the original element's data into a register.
337 // Push that register as a FrameElement on top of the frame. 347 // Push that register as a FrameElement on top of the frame.
338 Result fresh = cgen()->allocator()->Allocate(); 348 Result fresh = cgen()->allocator()->Allocate();
339 ASSERT(fresh.is_valid()); 349 ASSERT(fresh.is_valid());
340 FrameElement new_element = 350 FrameElement new_element =
341 FrameElement::RegisterElement(fresh.reg(), 351 FrameElement::RegisterElement(fresh.reg(),
342 FrameElement::NOT_SYNCED); 352 FrameElement::NOT_SYNCED,
353 original.number_info());
343 Use(fresh.reg(), element_count()); 354 Use(fresh.reg(), element_count());
344 elements_.Add(new_element); 355 elements_.Add(new_element);
345 __ movq(fresh.reg(), Operand(rbp, fp_relative(index))); 356 __ movq(fresh.reg(), Operand(rbp, fp_relative(index)));
346 break; 357 break;
347 } 358 }
348 case FrameElement::REGISTER: 359 case FrameElement::REGISTER:
349 Use(original.reg(), element_count()); 360 Use(original.reg(), element_count());
350 // Fall through. 361 // Fall through.
351 case FrameElement::CONSTANT: 362 case FrameElement::CONSTANT:
352 case FrameElement::COPY: 363 case FrameElement::COPY:
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
473 ASSERT(top.is_constant()); 484 ASSERT(top.is_constant());
474 elements_[index].clear_sync(); 485 elements_[index].clear_sync();
475 } 486 }
476 } 487 }
477 488
478 489
479 void VirtualFrame::MakeMergable() { 490 void VirtualFrame::MakeMergable() {
480 for (int i = 0; i < element_count(); i++) { 491 for (int i = 0; i < element_count(); i++) {
481 FrameElement element = elements_[i]; 492 FrameElement element = elements_[i];
482 493
494 // In all cases we have to reset the number type information
495 // to unknown for a mergable frame because of incoming back edges.
483 if (element.is_constant() || element.is_copy()) { 496 if (element.is_constant() || element.is_copy()) {
484 if (element.is_synced()) { 497 if (element.is_synced()) {
485 // Just spill. 498 // Just spill.
486 elements_[i] = FrameElement::MemoryElement(); 499 elements_[i] = FrameElement::MemoryElement(NumberInfo::kUnknown);
487 } else { 500 } else {
488 // Allocate to a register. 501 // Allocate to a register.
489 FrameElement backing_element; // Invalid if not a copy. 502 FrameElement backing_element; // Invalid if not a copy.
490 if (element.is_copy()) { 503 if (element.is_copy()) {
491 backing_element = elements_[element.index()]; 504 backing_element = elements_[element.index()];
492 } 505 }
493 Result fresh = cgen()->allocator()->Allocate(); 506 Result fresh = cgen()->allocator()->Allocate();
494 ASSERT(fresh.is_valid()); // A register was spilled if all were in use. 507 ASSERT(fresh.is_valid()); // A register was spilled if all were in use.
495 elements_[i] = 508 elements_[i] =
496 FrameElement::RegisterElement(fresh.reg(), 509 FrameElement::RegisterElement(fresh.reg(),
497 FrameElement::NOT_SYNCED); 510 FrameElement::NOT_SYNCED,
511 NumberInfo::kUnknown);
498 Use(fresh.reg(), i); 512 Use(fresh.reg(), i);
499 513
500 // Emit a move. 514 // Emit a move.
501 if (element.is_constant()) { 515 if (element.is_constant()) {
502 __ Move(fresh.reg(), element.handle()); 516 __ Move(fresh.reg(), element.handle());
503 } else { 517 } else {
504 ASSERT(element.is_copy()); 518 ASSERT(element.is_copy());
505 // Copies are only backed by register or memory locations. 519 // Copies are only backed by register or memory locations.
506 if (backing_element.is_register()) { 520 if (backing_element.is_register()) {
507 // The backing store may have been spilled by allocating, 521 // The backing store may have been spilled by allocating,
508 // but that's OK. If it was, the value is right where we 522 // but that's OK. If it was, the value is right where we
509 // want it. 523 // want it.
510 if (!fresh.reg().is(backing_element.reg())) { 524 if (!fresh.reg().is(backing_element.reg())) {
511 __ movq(fresh.reg(), backing_element.reg()); 525 __ movq(fresh.reg(), backing_element.reg());
512 } 526 }
513 } else { 527 } else {
514 ASSERT(backing_element.is_memory()); 528 ASSERT(backing_element.is_memory());
515 __ movq(fresh.reg(), Operand(rbp, fp_relative(element.index()))); 529 __ movq(fresh.reg(), Operand(rbp, fp_relative(element.index())));
516 } 530 }
517 } 531 }
518 } 532 }
519 // No need to set the copied flag --- there are no copies. 533 // No need to set the copied flag --- there are no copies.
520 } else { 534 } else {
521 // Clear the copy flag of non-constant, non-copy elements. 535 // Clear the copy flag of non-constant, non-copy elements.
522 // They cannot be copied because copies are not allowed. 536 // They cannot be copied because copies are not allowed.
523 // The copy flag is not relied on before the end of this loop, 537 // The copy flag is not relied on before the end of this loop,
524 // including when registers are spilled. 538 // including when registers are spilled.
525 elements_[i].clear_copied(); 539 elements_[i].clear_copied();
540 elements_[i].set_number_info(NumberInfo::kUnknown);
526 } 541 }
527 } 542 }
528 } 543 }
529 544
530 545
531 void VirtualFrame::MergeTo(VirtualFrame* expected) { 546 void VirtualFrame::MergeTo(VirtualFrame* expected) {
532 Comment cmnt(masm(), "[ Merge frame"); 547 Comment cmnt(masm(), "[ Merge frame");
533 // We should always be merging the code generator's current frame to an 548 // We should always be merging the code generator's current frame to an
534 // expected frame. 549 // expected frame.
535 ASSERT(cgen()->frame() == this); 550 ASSERT(cgen()->frame() == this);
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 } 736 }
722 } 737 }
723 } 738 }
724 739
725 740
726 Result VirtualFrame::Pop() { 741 Result VirtualFrame::Pop() {
727 FrameElement element = elements_.RemoveLast(); 742 FrameElement element = elements_.RemoveLast();
728 int index = element_count(); 743 int index = element_count();
729 ASSERT(element.is_valid()); 744 ASSERT(element.is_valid());
730 745
746 // Get number type information of the result.
747 NumberInfo::Type info;
748 if (!element.is_copy()) {
749 info = element.number_info();
750 } else {
751 info = elements_[element.index()].number_info();
752 }
753
731 bool pop_needed = (stack_pointer_ == index); 754 bool pop_needed = (stack_pointer_ == index);
732 if (pop_needed) { 755 if (pop_needed) {
733 stack_pointer_--; 756 stack_pointer_--;
734 if (element.is_memory()) { 757 if (element.is_memory()) {
735 Result temp = cgen()->allocator()->Allocate(); 758 Result temp = cgen()->allocator()->Allocate();
736 ASSERT(temp.is_valid()); 759 ASSERT(temp.is_valid());
737 __ pop(temp.reg()); 760 __ pop(temp.reg());
761 temp.set_number_info(info);
738 return temp; 762 return temp;
739 } 763 }
740 764
741 __ addq(rsp, Immediate(kPointerSize)); 765 __ addq(rsp, Immediate(kPointerSize));
742 } 766 }
743 ASSERT(!element.is_memory()); 767 ASSERT(!element.is_memory());
744 768
745 // The top element is a register, constant, or a copy. Unuse 769 // The top element is a register, constant, or a copy. Unuse
746 // registers and follow copies to their backing store. 770 // registers and follow copies to their backing store.
747 if (element.is_register()) { 771 if (element.is_register()) {
748 Unuse(element.reg()); 772 Unuse(element.reg());
749 } else if (element.is_copy()) { 773 } else if (element.is_copy()) {
750 ASSERT(element.index() < index); 774 ASSERT(element.index() < index);
751 index = element.index(); 775 index = element.index();
752 element = elements_[index]; 776 element = elements_[index];
753 } 777 }
754 ASSERT(!element.is_copy()); 778 ASSERT(!element.is_copy());
755 779
756 // The element is memory, a register, or a constant. 780 // The element is memory, a register, or a constant.
757 if (element.is_memory()) { 781 if (element.is_memory()) {
758 // Memory elements could only be the backing store of a copy. 782 // Memory elements could only be the backing store of a copy.
759 // Allocate the original to a register. 783 // Allocate the original to a register.
760 ASSERT(index <= stack_pointer_); 784 ASSERT(index <= stack_pointer_);
761 Result temp = cgen()->allocator()->Allocate(); 785 Result temp = cgen()->allocator()->Allocate();
762 ASSERT(temp.is_valid()); 786 ASSERT(temp.is_valid());
763 Use(temp.reg(), index); 787 Use(temp.reg(), index);
764 FrameElement new_element = 788 FrameElement new_element =
765 FrameElement::RegisterElement(temp.reg(), FrameElement::SYNCED); 789 FrameElement::RegisterElement(temp.reg(),
790 FrameElement::SYNCED,
791 element.number_info());
766 // Preserve the copy flag on the element. 792 // Preserve the copy flag on the element.
767 if (element.is_copied()) new_element.set_copied(); 793 if (element.is_copied()) new_element.set_copied();
768 elements_[index] = new_element; 794 elements_[index] = new_element;
769 __ movq(temp.reg(), Operand(rbp, fp_relative(index))); 795 __ movq(temp.reg(), Operand(rbp, fp_relative(index)));
770 return Result(temp.reg()); 796 return Result(temp.reg(), info);
771 } else if (element.is_register()) { 797 } else if (element.is_register()) {
772 return Result(element.reg()); 798 return Result(element.reg(), info);
773 } else { 799 } else {
774 ASSERT(element.is_constant()); 800 ASSERT(element.is_constant());
775 return Result(element.handle()); 801 return Result(element.handle());
776 } 802 }
777 } 803 }
778 804
779 805
780 Result VirtualFrame::RawCallStub(CodeStub* stub) { 806 Result VirtualFrame::RawCallStub(CodeStub* stub) {
781 ASSERT(cgen()->HasValidEntryRegisters()); 807 ASSERT(cgen()->HasValidEntryRegisters());
782 __ CallStub(stub); 808 __ CallStub(stub);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
962 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { 988 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
963 PrepareForCall(arg_count, arg_count); 989 PrepareForCall(arg_count, arg_count);
964 ASSERT(cgen()->HasValidEntryRegisters()); 990 ASSERT(cgen()->HasValidEntryRegisters());
965 __ CallRuntime(id, arg_count); 991 __ CallRuntime(id, arg_count);
966 Result result = cgen()->allocator()->Allocate(rax); 992 Result result = cgen()->allocator()->Allocate(rax);
967 ASSERT(result.is_valid()); 993 ASSERT(result.is_valid());
968 return result; 994 return result;
969 } 995 }
970 996
971 997
998 #ifdef ENABLE_DEBUGGER_SUPPORT
999 void VirtualFrame::DebugBreak() {
1000 PrepareForCall(0, 0);
1001 ASSERT(cgen()->HasValidEntryRegisters());
1002 __ DebugBreak();
1003 Result result = cgen()->allocator()->Allocate(rax);
1004 ASSERT(result.is_valid());
1005 }
1006 #endif
1007
1008
972 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) { 1009 Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
973 // Name and receiver are on the top of the frame. The IC expects 1010 // Name and receiver are on the top of the frame. The IC expects
974 // name in rcx and receiver on the stack. It does not drop the 1011 // name in rcx and receiver on the stack. It does not drop the
975 // receiver. 1012 // receiver.
976 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 1013 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
977 Result name = Pop(); 1014 Result name = Pop();
978 PrepareForCall(1, 0); // One stack arg, not callee-dropped. 1015 PrepareForCall(1, 0); // One stack arg, not callee-dropped.
979 name.ToRegister(rcx); 1016 name.ToRegister(rcx);
980 name.Unuse(); 1017 name.Unuse();
981 return RawCallCodeObject(ic, mode); 1018 return RawCallCodeObject(ic, mode);
982 } 1019 }
983 1020
984 1021
985 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { 1022 Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
986 // Key and receiver are on top of the frame. The IC expects them on 1023 // Key and receiver are on top of the frame. The IC expects them on
987 // the stack. It does not drop them. 1024 // the stack. It does not drop them.
988 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); 1025 Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
989 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. 1026 PrepareForCall(2, 0); // Two stack args, neither callee-dropped.
990 return RawCallCodeObject(ic, mode); 1027 return RawCallCodeObject(ic, mode);
991 } 1028 }
992 1029
993 1030
994 Result VirtualFrame::CallKeyedStoreIC() { 1031 Result VirtualFrame::CallKeyedStoreIC() {
995 // Value, key, and receiver are on the top of the frame. The IC 1032 // Value, key, and receiver are on the top of the frame. The IC
996 // expects value in rax and key and receiver on the stack. It does 1033 // expects value in rax and key and receiver on the stack. It does
997 // not drop the key and receiver. 1034 // not drop the key and receiver.
998 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); 1035 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
999 // TODO(1222589): Make the IC grab the values from the stack.
1000 Result value = Pop(); 1036 Result value = Pop();
1001 PrepareForCall(2, 0); // Two stack args, neither callee-dropped. 1037 PrepareForCall(2, 0); // Two stack args, neither callee-dropped.
1002 value.ToRegister(rax); 1038 value.ToRegister(rax);
1003 value.Unuse(); 1039 value.Unuse();
1004 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET); 1040 return RawCallCodeObject(ic, RelocInfo::CODE_TARGET);
1005 } 1041 }
1006 1042
1007 1043
1008 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, 1044 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode,
1009 int arg_count, 1045 int arg_count,
1010 int loop_nesting) { 1046 int loop_nesting) {
1011 // Arguments, receiver, and function name are on top of the frame. 1047 // Function name, arguments, and receiver are found on top of the frame
1012 // The IC expects them on the stack. It does not drop the function 1048 // and dropped by the call. The IC expects the name in rcx and the rest
1013 // name slot (but it does drop the rest). 1049 // on the stack, and drops them all.
1014 InLoopFlag in_loop = loop_nesting > 0 ? IN_LOOP : NOT_IN_LOOP; 1050 InLoopFlag in_loop = loop_nesting > 0 ? IN_LOOP : NOT_IN_LOOP;
1015 Handle<Code> ic = cgen()->ComputeCallInitialize(arg_count, in_loop); 1051 Handle<Code> ic = cgen()->ComputeCallInitialize(arg_count, in_loop);
1052 Result name = Pop();
1016 // Spill args, receiver, and function. The call will drop args and 1053 // Spill args, receiver, and function. The call will drop args and
1017 // receiver. 1054 // receiver.
1018 PrepareForCall(arg_count + 2, arg_count + 1); 1055 PrepareForCall(arg_count + 1, arg_count + 1);
1056 name.ToRegister(rcx);
1057 name.Unuse();
1019 return RawCallCodeObject(ic, mode); 1058 return RawCallCodeObject(ic, mode);
1020 } 1059 }
1021 1060
1022 1061
1023 Result VirtualFrame::CallConstructor(int arg_count) { 1062 Result VirtualFrame::CallConstructor(int arg_count) {
1024 // Arguments, receiver, and function are on top of the frame. The 1063 // Arguments, receiver, and function are on top of the frame. The
1025 // IC expects arg count in rax, function in rdi, and the arguments 1064 // IC expects arg count in rax, function in rdi, and the arguments
1026 // and receiver on the stack. 1065 // and receiver on the stack.
1027 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall)); 1066 Handle<Code> ic(Builtins::builtin(Builtins::JSConstructCall));
1028 // Duplicate the function before preparing the frame. 1067 // Duplicate the function before preparing the frame.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1094 // Grow the expression stack by handler size less one (the return 1133 // Grow the expression stack by handler size less one (the return
1095 // address is already pushed by a call instruction). 1134 // address is already pushed by a call instruction).
1096 Adjust(kHandlerSize - 1); 1135 Adjust(kHandlerSize - 1);
1097 __ PushTryHandler(IN_JAVASCRIPT, type); 1136 __ PushTryHandler(IN_JAVASCRIPT, type);
1098 } 1137 }
1099 1138
1100 1139
1101 #undef __ 1140 #undef __
1102 1141
1103 } } // namespace v8::internal 1142 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/virtual-frame-x64.h ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698