[V8] Introduce a QML compilation mode
[profile/ivi/qtjsbackend.git] / src / 3rdparty / v8 / src / lithium.cc
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       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   L##name* L##name::cache = NULL;                             \
99                                                               \
100   void L##name::SetUpCache() {                                \
101     if (cache) return;                                        \
102     cache = new L##name[kNumCachedOperands];                  \
103     for (int i = 0; i < kNumCachedOperands; i++) {            \
104       cache[i].ConvertTo(type, i);                            \
105     }                                                         \
106   }                                                           \
107                                                               \
108   void L##name::TearDownCache() {                             \
109     delete[] cache;                                           \
110   }
111
112 LITHIUM_OPERAND_LIST(DEFINE_OPERAND_CACHE)
113 #undef DEFINE_OPERAND_CACHE
114
115 void LOperand::SetUpCaches() {
116 #define LITHIUM_OPERAND_SETUP(name, type) L##name::SetUpCache();
117   LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_SETUP)
118 #undef LITHIUM_OPERAND_SETUP
119 }
120
121
122 void LOperand::TearDownCaches() {
123 #define LITHIUM_OPERAND_TEARDOWN(name, type) L##name::TearDownCache();
124   LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_TEARDOWN)
125 #undef LITHIUM_OPERAND_TEARDOWN
126 }
127
128
129 bool LParallelMove::IsRedundant() const {
130   for (int i = 0; i < move_operands_.length(); ++i) {
131     if (!move_operands_[i].IsRedundant()) return false;
132   }
133   return true;
134 }
135
136
137 void LParallelMove::PrintDataTo(StringStream* stream) const {
138   bool first = true;
139   for (int i = 0; i < move_operands_.length(); ++i) {
140     if (!move_operands_[i].IsEliminated()) {
141       LOperand* source = move_operands_[i].source();
142       LOperand* destination = move_operands_[i].destination();
143       if (!first) stream->Add(" ");
144       first = false;
145       if (source->Equals(destination)) {
146         destination->PrintTo(stream);
147       } else {
148         destination->PrintTo(stream);
149         stream->Add(" = ");
150         source->PrintTo(stream);
151       }
152       stream->Add(";");
153     }
154   }
155 }
156
157
158 void LEnvironment::PrintTo(StringStream* stream) {
159   stream->Add("[id=%d|", ast_id());
160   stream->Add("[parameters=%d|", parameter_count());
161   stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
162   for (int i = 0; i < values_.length(); ++i) {
163     if (i != 0) stream->Add(";");
164     if (values_[i] == NULL) {
165       stream->Add("[hole]");
166     } else {
167       values_[i]->PrintTo(stream);
168     }
169   }
170   stream->Add("]");
171 }
172
173
174 void LPointerMap::RecordPointer(LOperand* op) {
175   // Do not record arguments as pointers.
176   if (op->IsStackSlot() && op->index() < 0) return;
177   ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
178   pointer_operands_.Add(op);
179 }
180
181
182 void LPointerMap::RemovePointer(LOperand* op) {
183   // Do not record arguments as pointers.
184   if (op->IsStackSlot() && op->index() < 0) return;
185   ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
186   for (int i = 0; i < pointer_operands_.length(); ++i) {
187     if (pointer_operands_[i]->Equals(op)) {
188       pointer_operands_.Remove(i);
189       --i;
190     }
191   }
192 }
193
194
195 void LPointerMap::RecordUntagged(LOperand* op) {
196   // Do not record arguments as pointers.
197   if (op->IsStackSlot() && op->index() < 0) return;
198   ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
199   untagged_operands_.Add(op);
200 }
201
202
203 void LPointerMap::PrintTo(StringStream* stream) {
204   stream->Add("{");
205   for (int i = 0; i < pointer_operands_.length(); ++i) {
206     if (i != 0) stream->Add(";");
207     pointer_operands_[i]->PrintTo(stream);
208   }
209   stream->Add("} @%d", position());
210 }
211
212
213 int ElementsKindToShiftSize(ElementsKind elements_kind) {
214   switch (elements_kind) {
215     case EXTERNAL_BYTE_ELEMENTS:
216     case EXTERNAL_PIXEL_ELEMENTS:
217     case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
218       return 0;
219     case EXTERNAL_SHORT_ELEMENTS:
220     case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
221       return 1;
222     case EXTERNAL_INT_ELEMENTS:
223     case EXTERNAL_UNSIGNED_INT_ELEMENTS:
224     case EXTERNAL_FLOAT_ELEMENTS:
225       return 2;
226     case EXTERNAL_DOUBLE_ELEMENTS:
227     case FAST_DOUBLE_ELEMENTS:
228       return 3;
229     case FAST_SMI_ONLY_ELEMENTS:
230     case FAST_ELEMENTS:
231     case DICTIONARY_ELEMENTS:
232     case NON_STRICT_ARGUMENTS_ELEMENTS:
233       return kPointerSizeLog2;
234   }
235   UNREACHABLE();
236   return 0;
237 }
238
239
240 } }  // namespace v8::internal