1 // Copyright 2011 the V8 project authors. All rights reserved. 2 // Redistribution and use in source and binary forms, with or without 3 // modification, are permitted provided that the following conditions are 4 // met: 5 // 6 // * Redistributions of source code must retain the above copyright 7 // notice, this list of conditions and the following disclaimer. 8 // * Redistributions in binary form must reproduce the above 9 // copyright notice, this list of conditions and the following 10 // disclaimer in the documentation and/or other materials provided 11 // with the distribution. 12 // * Neither the name of Google Inc. nor the names of its 13 // contributors may be used to endorse or promote products derived 14 // from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28 #include "v8.h" 29 #include "lithium.h" 30 31 namespace v8 { 32 namespace internal { 33 34 35 void LOperand::PrintTo(StringStream* stream) { 36 LUnallocated* unalloc = NULL; 37 switch (kind()) { 38 case INVALID: 39 break; 40 case UNALLOCATED: 41 unalloc = LUnallocated::cast(this); 42 stream->Add("v%d", unalloc->virtual_register()); 43 switch (unalloc->policy()) { 44 case LUnallocated::NONE: 45 break; 46 case LUnallocated::FIXED_REGISTER: { 47 const char* register_name = 48 Register::AllocationIndexToString(unalloc->fixed_index()); 49 stream->Add("(=%s)", register_name); 50 break; 51 } 52 case LUnallocated::FIXED_DOUBLE_REGISTER: { 53 const char* double_register_name = 54 DoubleRegister::AllocationIndexToString(unalloc->fixed_index()); 55 stream->Add("(=%s)", double_register_name); 56 break; 57 } 58 case LUnallocated::FIXED_SLOT: 59 stream->Add("(=%dS)", unalloc->fixed_index()); 60 break; 61 case LUnallocated::MUST_HAVE_REGISTER: 62 stream->Add("(R)"); 63 break; 64 case LUnallocated::WRITABLE_REGISTER: 65 stream->Add("(WR)"); 66 break; 67 case LUnallocated::SAME_AS_FIRST_INPUT: 68 stream->Add("(1)"); 69 break; 70 case LUnallocated::ANY: 71 stream->Add("(-)"); 72 break; 73 case LUnallocated::IGNORE: 74 stream->Add("(0)"); 75 break; 76 } 77 break; 78 case CONSTANT_OPERAND: 79 stream->Add("[constant:%d]", index()); 80 break; 81 case STACK_SLOT: 82 stream->Add("[stack:%d]", index()); 83 break; 84 case DOUBLE_STACK_SLOT: 85 stream->Add("[double_stack:%d]", index()); 86 break; 87 case REGISTER: 88 stream->Add("[%s|R]", Register::AllocationIndexToString(index())); 89 break; 90 case DOUBLE_REGISTER: 91 stream->Add("[%s|R]", DoubleRegister::AllocationIndexToString(index())); 92 break; 93 case ARGUMENT: 94 stream->Add("[arg:%d]", index()); 95 break; 96 } 97 } 98 99 100 int LOperand::VirtualRegister() { 101 LUnallocated* unalloc = LUnallocated::cast(this); 102 return unalloc->virtual_register(); 103 } 104 105 106 bool LParallelMove::IsRedundant() const { 107 for (int i = 0; i < move_operands_.length(); ++i) { 108 if (!move_operands_[i].IsRedundant()) return false; 109 } 110 return true; 111 } 112 113 114 void LParallelMove::PrintDataTo(StringStream* stream) const { 115 bool first = true; 116 for (int i = 0; i < move_operands_.length(); ++i) { 117 if (!move_operands_[i].IsEliminated()) { 118 LOperand* source = move_operands_[i].source(); 119 LOperand* destination = move_operands_[i].destination(); 120 if (!first) stream->Add(" "); 121 first = false; 122 if (source->Equals(destination)) { 123 destination->PrintTo(stream); 124 } else { 125 destination->PrintTo(stream); 126 stream->Add(" = "); 127 source->PrintTo(stream); 128 } 129 stream->Add(";"); 130 } 131 } 132 } 133 134 135 void LEnvironment::PrintTo(StringStream* stream) { 136 stream->Add("[id=%d|", ast_id()); 137 stream->Add("[parameters=%d|", parameter_count()); 138 stream->Add("[arguments_stack_height=%d|", arguments_stack_height()); 139 for (int i = 0; i < values_.length(); ++i) { 140 if (i != 0) stream->Add(";"); 141 if (values_[i] == NULL) { 142 stream->Add("[hole]"); 143 } else { 144 values_[i]->PrintTo(stream); 145 } 146 } 147 stream->Add("]"); 148 } 149 150 151 void LPointerMap::RecordPointer(LOperand* op) { 152 // Do not record arguments as pointers. 153 if (op->IsStackSlot() && op->index() < 0) return; 154 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot()); 155 pointer_operands_.Add(op); 156 } 157 158 159 void LPointerMap::PrintTo(StringStream* stream) { 160 stream->Add("{"); 161 for (int i = 0; i < pointer_operands_.length(); ++i) { 162 if (i != 0) stream->Add(";"); 163 pointer_operands_[i]->PrintTo(stream); 164 } 165 stream->Add("} @%d", position()); 166 } 167 168 169 } } // namespace v8::internal 170