OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 __ movq(kScratchRegister, undefined, RelocInfo::EMBEDDED_OBJECT); | 130 __ movq(kScratchRegister, undefined, RelocInfo::EMBEDDED_OBJECT); |
131 for (int i = 0; i < count; i++) { | 131 for (int i = 0; i < count; i++) { |
132 elements_.Add(initial_value); | 132 elements_.Add(initial_value); |
133 stack_pointer_++; | 133 stack_pointer_++; |
134 __ push(kScratchRegister); | 134 __ push(kScratchRegister); |
135 } | 135 } |
136 } | 136 } |
137 } | 137 } |
138 | 138 |
139 | 139 |
| 140 void VirtualFrame::SaveContextRegister() { |
| 141 ASSERT(elements_[context_index()].is_memory()); |
| 142 __ movq(Operand(rbp, fp_relative(context_index())), rsi); |
| 143 } |
| 144 |
| 145 |
| 146 void VirtualFrame::RestoreContextRegister() { |
| 147 ASSERT(elements_[context_index()].is_memory()); |
| 148 __ movq(rsi, Operand(rbp, fp_relative(context_index()))); |
| 149 } |
| 150 |
| 151 |
| 152 void VirtualFrame::PushReceiverSlotAddress() { |
| 153 Result temp = cgen()->allocator()->Allocate(); |
| 154 ASSERT(temp.is_valid()); |
| 155 __ lea(temp.reg(), ParameterAt(-1)); |
| 156 Push(&temp); |
| 157 } |
| 158 |
| 159 |
140 void VirtualFrame::EmitPop(Register reg) { | 160 void VirtualFrame::EmitPop(Register reg) { |
141 ASSERT(stack_pointer_ == element_count() - 1); | 161 ASSERT(stack_pointer_ == element_count() - 1); |
142 stack_pointer_--; | 162 stack_pointer_--; |
143 elements_.RemoveLast(); | 163 elements_.RemoveLast(); |
144 __ pop(reg); | 164 __ pop(reg); |
145 } | 165 } |
146 | 166 |
147 | 167 |
148 void VirtualFrame::EmitPop(const Operand& operand) { | 168 void VirtualFrame::EmitPop(const Operand& operand) { |
149 ASSERT(stack_pointer_ == element_count() - 1); | 169 ASSERT(stack_pointer_ == element_count() - 1); |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 return Result(temp.reg(), element.static_type()); | 446 return Result(temp.reg(), element.static_type()); |
427 } else if (element.is_register()) { | 447 } else if (element.is_register()) { |
428 return Result(element.reg(), element.static_type()); | 448 return Result(element.reg(), element.static_type()); |
429 } else { | 449 } else { |
430 ASSERT(element.is_constant()); | 450 ASSERT(element.is_constant()); |
431 return Result(element.handle()); | 451 return Result(element.handle()); |
432 } | 452 } |
433 } | 453 } |
434 | 454 |
435 | 455 |
436 Result VirtualFrame::RawCallStub(CodeStub* a) { | 456 Result VirtualFrame::RawCallStub(CodeStub* stub) { |
437 UNIMPLEMENTED(); | 457 ASSERT(cgen()->HasValidEntryRegisters()); |
438 return Result(NULL); | 458 __ CallStub(stub); |
439 } | 459 Result result = cgen()->allocator()->Allocate(rax); |
440 | 460 ASSERT(result.is_valid()); |
441 void VirtualFrame::SyncElementBelowStackPointer(int a) { | 461 return result; |
442 UNIMPLEMENTED(); | |
443 } | 462 } |
444 | 463 |
445 | 464 |
| 465 void VirtualFrame::SyncElementBelowStackPointer(int index) { |
| 466 // Emit code to write elements below the stack pointer to their |
| 467 // (already allocated) stack address. |
| 468 ASSERT(index <= stack_pointer_); |
| 469 FrameElement element = elements_[index]; |
| 470 ASSERT(!element.is_synced()); |
| 471 switch (element.type()) { |
| 472 case FrameElement::INVALID: |
| 473 break; |
| 474 |
| 475 case FrameElement::MEMORY: |
| 476 // This function should not be called with synced elements. |
| 477 // (memory elements are always synced). |
| 478 UNREACHABLE(); |
| 479 break; |
| 480 |
| 481 case FrameElement::REGISTER: |
| 482 __ movq(Operand(rbp, fp_relative(index)), element.reg()); |
| 483 break; |
| 484 |
| 485 case FrameElement::CONSTANT: |
| 486 if (element.handle()->IsSmi()) { |
| 487 if (CodeGeneratorScope::Current()->IsUnsafeSmi(element.handle())) { |
| 488 CodeGeneratorScope::Current()->LoadUnsafeSmi(kScratchRegister, |
| 489 element.handle()); |
| 490 } else { |
| 491 __ movq(kScratchRegister, element.handle(), RelocInfo::NONE); |
| 492 } |
| 493 } else { |
| 494 __ movq(kScratchRegister, |
| 495 element.handle(), |
| 496 RelocInfo::EMBEDDED_OBJECT); |
| 497 } |
| 498 __ movq(Operand(rbp, fp_relative(index)), kScratchRegister); |
| 499 break; |
| 500 |
| 501 case FrameElement::COPY: { |
| 502 int backing_index = element.index(); |
| 503 FrameElement backing_element = elements_[backing_index]; |
| 504 if (backing_element.is_memory()) { |
| 505 __ movq(kScratchRegister, Operand(rbp, fp_relative(backing_index))); |
| 506 __ movq(Operand(rbp, fp_relative(index)), kScratchRegister); |
| 507 } else { |
| 508 ASSERT(backing_element.is_register()); |
| 509 __ movq(Operand(rbp, fp_relative(index)), backing_element.reg()); |
| 510 } |
| 511 break; |
| 512 } |
| 513 } |
| 514 elements_[index].set_sync(); |
| 515 } |
| 516 |
| 517 |
446 void VirtualFrame::SyncElementByPushing(int index) { | 518 void VirtualFrame::SyncElementByPushing(int index) { |
447 // Sync an element of the frame that is just above the stack pointer | 519 // Sync an element of the frame that is just above the stack pointer |
448 // by pushing it. | 520 // by pushing it. |
449 ASSERT(index == stack_pointer_ + 1); | 521 ASSERT(index == stack_pointer_ + 1); |
450 stack_pointer_++; | 522 stack_pointer_++; |
451 FrameElement element = elements_[index]; | 523 FrameElement element = elements_[index]; |
452 | 524 |
453 switch (element.type()) { | 525 switch (element.type()) { |
454 case FrameElement::INVALID: | 526 case FrameElement::INVALID: |
455 __ push(Immediate(Smi::FromInt(0))); | 527 __ push(Immediate(Smi::FromInt(0))); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 if (delta > 0) { | 584 if (delta > 0) { |
513 stack_pointer_ = end; | 585 stack_pointer_ = end; |
514 __ subq(rsp, Immediate(delta * kPointerSize)); | 586 __ subq(rsp, Immediate(delta * kPointerSize)); |
515 } | 587 } |
516 | 588 |
517 for (int i = start; i <= end; i++) { | 589 for (int i = start; i <= end; i++) { |
518 if (!elements_[i].is_synced()) SyncElementBelowStackPointer(i); | 590 if (!elements_[i].is_synced()) SyncElementBelowStackPointer(i); |
519 } | 591 } |
520 } | 592 } |
521 | 593 |
| 594 //------------------------------------------------------------------------------ |
| 595 // Virtual frame stub and IC calling functions. |
| 596 |
| 597 Result VirtualFrame::RawCallCodeObject(Handle<Code> code, |
| 598 RelocInfo::Mode rmode) { |
| 599 ASSERT(cgen()->HasValidEntryRegisters()); |
| 600 __ Call(code, rmode); |
| 601 Result result = cgen()->allocator()->Allocate(rax); |
| 602 ASSERT(result.is_valid()); |
| 603 return result; |
| 604 } |
| 605 |
| 606 |
| 607 Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) { |
| 608 PrepareForCall(arg_count, arg_count); |
| 609 ASSERT(cgen()->HasValidEntryRegisters()); |
| 610 __ CallRuntime(f, arg_count); |
| 611 Result result = cgen()->allocator()->Allocate(rax); |
| 612 ASSERT(result.is_valid()); |
| 613 return result; |
| 614 } |
| 615 |
| 616 |
| 617 Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) { |
| 618 PrepareForCall(arg_count, arg_count); |
| 619 ASSERT(cgen()->HasValidEntryRegisters()); |
| 620 __ CallRuntime(id, arg_count); |
| 621 Result result = cgen()->allocator()->Allocate(rax); |
| 622 ASSERT(result.is_valid()); |
| 623 return result; |
| 624 } |
| 625 |
| 626 |
| 627 Result VirtualFrame::CallCallIC(RelocInfo::Mode mode, |
| 628 int arg_count, |
| 629 int loop_nesting) { |
| 630 // Arguments, receiver, and function name are on top of the frame. |
| 631 // The IC expects them on the stack. It does not drop the function |
| 632 // name slot (but it does drop the rest). |
| 633 InLoopFlag in_loop = loop_nesting > 0 ? IN_LOOP : NOT_IN_LOOP; |
| 634 Handle<Code> ic = cgen()->ComputeCallInitialize(arg_count, in_loop); |
| 635 // Spill args, receiver, and function. The call will drop args and |
| 636 // receiver. |
| 637 PrepareForCall(arg_count + 2, arg_count + 1); |
| 638 return RawCallCodeObject(ic, mode); |
| 639 } |
| 640 |
| 641 |
| 642 |
522 | 643 |
523 #undef __ | 644 #undef __ |
524 | 645 |
525 } } // namespace v8::internal | 646 } } // namespace v8::internal |
OLD | NEW |