| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 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 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 403 | 403 |
| 404 // Mergable frames have all elements in locations, either memory or | 404 // Mergable frames have all elements in locations, either memory or |
| 405 // register. We thus have a series of to-memory and to-register moves. | 405 // register. We thus have a series of to-memory and to-register moves. |
| 406 // First perform all to-memory moves, register-to-memory moves because | 406 // First perform all to-memory moves, register-to-memory moves because |
| 407 // they can free registers and constant-to-memory moves because they do | 407 // they can free registers and constant-to-memory moves because they do |
| 408 // not use registers. | 408 // not use registers. |
| 409 MergeMoveRegistersToMemory(expected); | 409 MergeMoveRegistersToMemory(expected); |
| 410 MergeMoveRegistersToRegisters(expected); | 410 MergeMoveRegistersToRegisters(expected); |
| 411 MergeMoveMemoryToRegisters(expected); | 411 MergeMoveMemoryToRegisters(expected); |
| 412 | 412 |
| 413 int height_difference = stack_pointer_ - expected->stack_pointer_; |
| 414 if (stack_pointer_ > expected->stack_pointer_) { |
| 415 #ifdef DEBUG |
| 416 for (int i = stack_pointer_; i > expected->stack_pointer_; i--) { |
| 417 ASSERT(!elements_[i].is_memory()); |
| 418 ASSERT(!elements_[i].is_synced()); |
| 419 } |
| 420 #endif |
| 421 __ add(Operand(esp), Immediate(height_difference * kPointerSize)); |
| 422 stack_pointer_ = expected->stack_pointer_; |
| 423 } else if (stack_pointer_ < expected->stack_pointer_) { |
| 424 // Put valid data on the stack, that will only be accessed by GC. |
| 425 while (stack_pointer_ < expected->stack_pointer_) { |
| 426 __ push(Immediate(Smi::FromInt(0))); |
| 427 stack_pointer_++; |
| 428 } |
| 429 } |
| 430 |
| 413 // At this point, the frames should be identical. | 431 // At this point, the frames should be identical. |
| 414 // TODO(): Consider an "equals" method for frames. | 432 // TODO(): Consider an "equals" method for frames. |
| 415 ASSERT(stack_pointer_ == expected->stack_pointer_); | 433 ASSERT(stack_pointer_ == expected->stack_pointer_); |
| 416 #ifdef DEBUG | 434 #ifdef DEBUG |
| 417 for (int i = 0; i < elements_.length(); i++) { | 435 for (int i = 0; i < elements_.length(); i++) { |
| 418 FrameElement expect = expected->elements_[i]; | 436 FrameElement expect = expected->elements_[i]; |
| 419 if (!expect.is_valid()) { | 437 if (!expect.is_valid()) { |
| 420 ASSERT(!elements_[i].is_valid()); | 438 ASSERT(!elements_[i].is_valid()); |
| 421 } else if (expect.is_memory()) { | 439 } else if (expect.is_memory()) { |
| 422 ASSERT(elements_[i].is_memory()); | 440 ASSERT(elements_[i].is_memory()); |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 } | 685 } |
| 668 } | 686 } |
| 669 } | 687 } |
| 670 | 688 |
| 671 | 689 |
| 672 void VirtualFrame::SetElementAt(int index, Result* value) { | 690 void VirtualFrame::SetElementAt(int index, Result* value) { |
| 673 int frame_index = elements_.length() - index - 1; | 691 int frame_index = elements_.length() - index - 1; |
| 674 ASSERT(frame_index >= 0); | 692 ASSERT(frame_index >= 0); |
| 675 ASSERT(frame_index < elements_.length()); | 693 ASSERT(frame_index < elements_.length()); |
| 676 ASSERT(value->is_valid()); | 694 ASSERT(value->is_valid()); |
| 695 FrameElement target = elements_[frame_index]; |
| 677 | 696 |
| 678 // TODO(): if the element is backed by the same register or the same | 697 if (target.is_register()) { |
| 679 // constant, consider preserving the sync bit. | 698 Unuse(target.reg()); |
| 680 if (elements_[frame_index].is_register()) { | |
| 681 Unuse(elements_[frame_index].reg()); | |
| 682 } | 699 } |
| 683 | 700 |
| 684 if (value->is_register()) { | 701 if (value->is_register()) { |
| 685 Use(value->reg()); | 702 Use(value->reg()); |
| 686 elements_[frame_index] = | 703 // Write the new value to the frame, if it is changed. |
| 687 FrameElement::RegisterElement(value->reg(), | 704 // Otherwise, if target equals value, keep its current sync state. |
| 688 FrameElement::NOT_SYNCED); | 705 if (!target.is_register() || |
| 706 !value->reg().is(target.reg())) { |
| 707 elements_[frame_index] = |
| 708 FrameElement::RegisterElement(value->reg(), |
| 709 FrameElement::NOT_SYNCED); |
| 710 } |
| 689 } else { | 711 } else { |
| 690 ASSERT(value->is_constant()); | 712 ASSERT(value->is_constant()); |
| 691 elements_[frame_index] = | 713 // Write the new value to the frame element, if it is a change. |
| 692 FrameElement::ConstantElement(value->handle(), | 714 // Otherwise, do nothing, and keep the current sync state. |
| 693 FrameElement::NOT_SYNCED); | 715 if (!target.is_constant() || |
| 716 !value->handle().is_identical_to(target.handle())) { |
| 717 elements_[frame_index] = |
| 718 FrameElement::ConstantElement(value->handle(), |
| 719 FrameElement::NOT_SYNCED); |
| 720 } |
| 694 } | 721 } |
| 695 | |
| 696 value->Unuse(); | 722 value->Unuse(); |
| 697 } | 723 } |
| 698 | 724 |
| 699 | 725 |
| 700 void VirtualFrame::SaveContextRegister() { | 726 void VirtualFrame::SaveContextRegister() { |
| 701 FrameElement current = elements_[context_index()]; | 727 FrameElement current = elements_[context_index()]; |
| 702 ASSERT(current.is_register() || current.is_memory()); | 728 ASSERT(current.is_register() || current.is_memory()); |
| 703 if (!current.is_register() || !current.reg().is(esi)) { | 729 if (!current.is_register() || !current.reg().is(esi)) { |
| 704 if (current.is_register()) { | 730 if (current.is_register()) { |
| 705 Unuse(current.reg()); | 731 Unuse(current.reg()); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1000 if (result->is_register()) { | 1026 if (result->is_register()) { |
| 1001 Push(result->reg()); | 1027 Push(result->reg()); |
| 1002 } else { | 1028 } else { |
| 1003 ASSERT(result->is_constant()); | 1029 ASSERT(result->is_constant()); |
| 1004 Push(result->handle()); | 1030 Push(result->handle()); |
| 1005 } | 1031 } |
| 1006 result->Unuse(); | 1032 result->Unuse(); |
| 1007 } | 1033 } |
| 1008 | 1034 |
| 1009 | 1035 |
| 1036 void VirtualFrame::Nip(int num_dropped) { |
| 1037 ASSERT(num_dropped >= 0); |
| 1038 if (num_dropped == 0) return; |
| 1039 Result tos = Pop(); |
| 1040 if (num_dropped > 1) { |
| 1041 Drop(num_dropped - 1); |
| 1042 } |
| 1043 SetElementAt(0, &tos); |
| 1044 } |
| 1045 |
| 1046 |
| 1010 #ifdef DEBUG | 1047 #ifdef DEBUG |
| 1011 bool VirtualFrame::IsSpilled() { | 1048 bool VirtualFrame::IsSpilled() { |
| 1012 for (int i = 0; i < elements_.length(); i++) { | 1049 for (int i = 0; i < elements_.length(); i++) { |
| 1013 if (!elements_[i].is_memory()) { | 1050 if (!elements_[i].is_memory()) { |
| 1014 return false; | 1051 return false; |
| 1015 } | 1052 } |
| 1016 } | 1053 } |
| 1017 return true; | 1054 return true; |
| 1018 } | 1055 } |
| 1019 #endif | 1056 #endif |
| 1020 | 1057 |
| 1021 #undef __ | 1058 #undef __ |
| 1022 | 1059 |
| 1023 } } // namespace v8::internal | 1060 } } // namespace v8::internal |
| OLD | NEW |