• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
PrintTo(StringStream * stream)35  void LOperand::PrintTo(StringStream* stream) {
36    LUnallocated* unalloc = NULL;
37    switch (kind()) {
38      case INVALID:
39        stream->Add("(0)");
40        break;
41      case UNALLOCATED:
42        unalloc = LUnallocated::cast(this);
43        stream->Add("v%d", unalloc->virtual_register());
44        switch (unalloc->policy()) {
45          case LUnallocated::NONE:
46            break;
47          case LUnallocated::FIXED_REGISTER: {
48            const char* register_name =
49                Register::AllocationIndexToString(unalloc->fixed_index());
50            stream->Add("(=%s)", register_name);
51            break;
52          }
53          case LUnallocated::FIXED_DOUBLE_REGISTER: {
54            const char* double_register_name =
55                DoubleRegister::AllocationIndexToString(unalloc->fixed_index());
56            stream->Add("(=%s)", double_register_name);
57            break;
58          }
59          case LUnallocated::FIXED_SLOT:
60            stream->Add("(=%dS)", unalloc->fixed_index());
61            break;
62          case LUnallocated::MUST_HAVE_REGISTER:
63            stream->Add("(R)");
64            break;
65          case LUnallocated::WRITABLE_REGISTER:
66            stream->Add("(WR)");
67            break;
68          case LUnallocated::SAME_AS_FIRST_INPUT:
69            stream->Add("(1)");
70            break;
71          case LUnallocated::ANY:
72            stream->Add("(-)");
73            break;
74        }
75        break;
76      case CONSTANT_OPERAND:
77        stream->Add("[constant:%d]", index());
78        break;
79      case STACK_SLOT:
80        stream->Add("[stack:%d]", index());
81        break;
82      case DOUBLE_STACK_SLOT:
83        stream->Add("[double_stack:%d]", index());
84        break;
85      case REGISTER:
86        stream->Add("[%s|R]", Register::AllocationIndexToString(index()));
87        break;
88      case DOUBLE_REGISTER:
89        stream->Add("[%s|R]", DoubleRegister::AllocationIndexToString(index()));
90        break;
91      case ARGUMENT:
92        stream->Add("[arg:%d]", index());
93        break;
94    }
95  }
96  
97  #define DEFINE_OPERAND_CACHE(name, type)                      \
98    name* name::cache = NULL;                                   \
99    void name::SetUpCache() {                                   \
100      if (cache) return;                                        \
101      cache = new name[kNumCachedOperands];                     \
102      for (int i = 0; i < kNumCachedOperands; i++) {            \
103        cache[i].ConvertTo(type, i);                            \
104      }                                                         \
105    }                                                           \
106  
DEFINE_OPERAND_CACHE(LConstantOperand,CONSTANT_OPERAND)107  DEFINE_OPERAND_CACHE(LConstantOperand, CONSTANT_OPERAND)
108  DEFINE_OPERAND_CACHE(LStackSlot,       STACK_SLOT)
109  DEFINE_OPERAND_CACHE(LDoubleStackSlot, DOUBLE_STACK_SLOT)
110  DEFINE_OPERAND_CACHE(LRegister,        REGISTER)
111  DEFINE_OPERAND_CACHE(LDoubleRegister,  DOUBLE_REGISTER)
112  
113  #undef DEFINE_OPERAND_CACHE
114  
115  void LOperand::SetUpCaches() {
116    LConstantOperand::SetUpCache();
117    LStackSlot::SetUpCache();
118    LDoubleStackSlot::SetUpCache();
119    LRegister::SetUpCache();
120    LDoubleRegister::SetUpCache();
121  }
122  
IsRedundant() const123  bool LParallelMove::IsRedundant() const {
124    for (int i = 0; i < move_operands_.length(); ++i) {
125      if (!move_operands_[i].IsRedundant()) return false;
126    }
127    return true;
128  }
129  
130  
PrintDataTo(StringStream * stream) const131  void LParallelMove::PrintDataTo(StringStream* stream) const {
132    bool first = true;
133    for (int i = 0; i < move_operands_.length(); ++i) {
134      if (!move_operands_[i].IsEliminated()) {
135        LOperand* source = move_operands_[i].source();
136        LOperand* destination = move_operands_[i].destination();
137        if (!first) stream->Add(" ");
138        first = false;
139        if (source->Equals(destination)) {
140          destination->PrintTo(stream);
141        } else {
142          destination->PrintTo(stream);
143          stream->Add(" = ");
144          source->PrintTo(stream);
145        }
146        stream->Add(";");
147      }
148    }
149  }
150  
151  
PrintTo(StringStream * stream)152  void LEnvironment::PrintTo(StringStream* stream) {
153    stream->Add("[id=%d|", ast_id());
154    stream->Add("[parameters=%d|", parameter_count());
155    stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
156    for (int i = 0; i < values_.length(); ++i) {
157      if (i != 0) stream->Add(";");
158      if (values_[i] == NULL) {
159        stream->Add("[hole]");
160      } else {
161        values_[i]->PrintTo(stream);
162      }
163    }
164    stream->Add("]");
165  }
166  
167  
RecordPointer(LOperand * op)168  void LPointerMap::RecordPointer(LOperand* op) {
169    // Do not record arguments as pointers.
170    if (op->IsStackSlot() && op->index() < 0) return;
171    ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
172    pointer_operands_.Add(op);
173  }
174  
175  
RemovePointer(LOperand * op)176  void LPointerMap::RemovePointer(LOperand* op) {
177    // Do not record arguments as pointers.
178    if (op->IsStackSlot() && op->index() < 0) return;
179    ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
180    for (int i = 0; i < pointer_operands_.length(); ++i) {
181      if (pointer_operands_[i]->Equals(op)) {
182        pointer_operands_.Remove(i);
183        --i;
184      }
185    }
186  }
187  
188  
RecordUntagged(LOperand * op)189  void LPointerMap::RecordUntagged(LOperand* op) {
190    // Do not record arguments as pointers.
191    if (op->IsStackSlot() && op->index() < 0) return;
192    ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
193    untagged_operands_.Add(op);
194  }
195  
196  
PrintTo(StringStream * stream)197  void LPointerMap::PrintTo(StringStream* stream) {
198    stream->Add("{");
199    for (int i = 0; i < pointer_operands_.length(); ++i) {
200      if (i != 0) stream->Add(";");
201      pointer_operands_[i]->PrintTo(stream);
202    }
203    stream->Add("} @%d", position());
204  }
205  
206  
ElementsKindToShiftSize(ElementsKind elements_kind)207  int ElementsKindToShiftSize(ElementsKind elements_kind) {
208    switch (elements_kind) {
209      case EXTERNAL_BYTE_ELEMENTS:
210      case EXTERNAL_PIXEL_ELEMENTS:
211      case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
212        return 0;
213      case EXTERNAL_SHORT_ELEMENTS:
214      case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
215        return 1;
216      case EXTERNAL_INT_ELEMENTS:
217      case EXTERNAL_UNSIGNED_INT_ELEMENTS:
218      case EXTERNAL_FLOAT_ELEMENTS:
219        return 2;
220      case EXTERNAL_DOUBLE_ELEMENTS:
221      case FAST_DOUBLE_ELEMENTS:
222        return 3;
223      case FAST_SMI_ONLY_ELEMENTS:
224      case FAST_ELEMENTS:
225      case DICTIONARY_ELEMENTS:
226      case NON_STRICT_ARGUMENTS_ELEMENTS:
227        return kPointerSizeLog2;
228    }
229    UNREACHABLE();
230    return 0;
231  }
232  
233  
234  } }  // namespace v8::internal
235