blob: 539f4eefba5bd635d2a41b2a64193c570b1ca181 [file] [log] [blame]
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +00001// Copyright 2012 the V8 project authors. All rights reserved.
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +00002// 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
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000028#include "v8.h"
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000029#include "lithium.h"
rossberg@chromium.org657d53b2012-07-12 11:06:03 +000030#include "scopes.h"
31
32#if V8_TARGET_ARCH_IA32
33#include "ia32/lithium-ia32.h"
jkummerow@chromium.org28583c92012-07-16 11:31:55 +000034#include "ia32/lithium-codegen-ia32.h"
rossberg@chromium.org657d53b2012-07-12 11:06:03 +000035#elif V8_TARGET_ARCH_X64
36#include "x64/lithium-x64.h"
jkummerow@chromium.org28583c92012-07-16 11:31:55 +000037#include "x64/lithium-codegen-x64.h"
rossberg@chromium.org657d53b2012-07-12 11:06:03 +000038#elif V8_TARGET_ARCH_ARM
39#include "arm/lithium-arm.h"
jkummerow@chromium.org28583c92012-07-16 11:31:55 +000040#include "arm/lithium-codegen-arm.h"
rossberg@chromium.org657d53b2012-07-12 11:06:03 +000041#elif V8_TARGET_ARCH_MIPS
42#include "mips/lithium-mips.h"
jkummerow@chromium.org28583c92012-07-16 11:31:55 +000043#include "mips/lithium-codegen-mips.h"
rossberg@chromium.org657d53b2012-07-12 11:06:03 +000044#else
45#error "Unknown architecture."
46#endif
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +000047
48namespace v8 {
49namespace internal {
50
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000051
52void LOperand::PrintTo(StringStream* stream) {
53 LUnallocated* unalloc = NULL;
54 switch (kind()) {
55 case INVALID:
yangguo@chromium.org659ceec2012-01-26 07:37:54 +000056 stream->Add("(0)");
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000057 break;
58 case UNALLOCATED:
59 unalloc = LUnallocated::cast(this);
60 stream->Add("v%d", unalloc->virtual_register());
ulan@chromium.org57ff8812013-05-10 08:16:55 +000061 if (unalloc->basic_policy() == LUnallocated::FIXED_SLOT) {
62 stream->Add("(=%dS)", unalloc->fixed_slot_index());
63 break;
64 }
65 switch (unalloc->extended_policy()) {
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000066 case LUnallocated::NONE:
67 break;
68 case LUnallocated::FIXED_REGISTER: {
ulan@chromium.org57ff8812013-05-10 08:16:55 +000069 int reg_index = unalloc->fixed_register_index();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000070 const char* register_name =
ulan@chromium.org57ff8812013-05-10 08:16:55 +000071 Register::AllocationIndexToString(reg_index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000072 stream->Add("(=%s)", register_name);
73 break;
74 }
75 case LUnallocated::FIXED_DOUBLE_REGISTER: {
ulan@chromium.org57ff8812013-05-10 08:16:55 +000076 int reg_index = unalloc->fixed_register_index();
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000077 const char* double_register_name =
ulan@chromium.org57ff8812013-05-10 08:16:55 +000078 DoubleRegister::AllocationIndexToString(reg_index);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000079 stream->Add("(=%s)", double_register_name);
80 break;
81 }
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000082 case LUnallocated::MUST_HAVE_REGISTER:
83 stream->Add("(R)");
84 break;
85 case LUnallocated::WRITABLE_REGISTER:
86 stream->Add("(WR)");
87 break;
88 case LUnallocated::SAME_AS_FIRST_INPUT:
89 stream->Add("(1)");
90 break;
91 case LUnallocated::ANY:
92 stream->Add("(-)");
93 break;
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000094 }
95 break;
96 case CONSTANT_OPERAND:
97 stream->Add("[constant:%d]", index());
98 break;
99 case STACK_SLOT:
100 stream->Add("[stack:%d]", index());
101 break;
102 case DOUBLE_STACK_SLOT:
103 stream->Add("[double_stack:%d]", index());
104 break;
105 case REGISTER:
106 stream->Add("[%s|R]", Register::AllocationIndexToString(index()));
107 break;
108 case DOUBLE_REGISTER:
109 stream->Add("[%s|R]", DoubleRegister::AllocationIndexToString(index()));
110 break;
111 case ARGUMENT:
112 stream->Add("[arg:%d]", index());
113 break;
114 }
115}
116
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000117#define DEFINE_OPERAND_CACHE(name, type) \
118 L##name* L##name::cache = NULL; \
119 \
120 void L##name::SetUpCache() { \
121 if (cache) return; \
122 cache = new L##name[kNumCachedOperands]; \
123 for (int i = 0; i < kNumCachedOperands; i++) { \
124 cache[i].ConvertTo(type, i); \
125 } \
126 } \
127 \
128 void L##name::TearDownCache() { \
129 delete[] cache; \
130 }
131
132LITHIUM_OPERAND_LIST(DEFINE_OPERAND_CACHE)
133#undef DEFINE_OPERAND_CACHE
134
135void LOperand::SetUpCaches() {
136#define LITHIUM_OPERAND_SETUP(name, type) L##name::SetUpCache();
137 LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_SETUP)
138#undef LITHIUM_OPERAND_SETUP
139}
140
141
142void LOperand::TearDownCaches() {
143#define LITHIUM_OPERAND_TEARDOWN(name, type) L##name::TearDownCache();
144 LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_TEARDOWN)
145#undef LITHIUM_OPERAND_TEARDOWN
146}
147
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000148
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000149bool LParallelMove::IsRedundant() const {
150 for (int i = 0; i < move_operands_.length(); ++i) {
151 if (!move_operands_[i].IsRedundant()) return false;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000152 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000153 return true;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000154}
155
156
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000157void LParallelMove::PrintDataTo(StringStream* stream) const {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000158 bool first = true;
159 for (int i = 0; i < move_operands_.length(); ++i) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000160 if (!move_operands_[i].IsEliminated()) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000161 LOperand* source = move_operands_[i].source();
162 LOperand* destination = move_operands_[i].destination();
163 if (!first) stream->Add(" ");
164 first = false;
165 if (source->Equals(destination)) {
166 destination->PrintTo(stream);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000167 } else {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000168 destination->PrintTo(stream);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000169 stream->Add(" = ");
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000170 source->PrintTo(stream);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000171 }
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000172 stream->Add(";");
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000173 }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000174 }
175}
176
177
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000178void LEnvironment::PrintTo(StringStream* stream) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000179 stream->Add("[id=%d|", ast_id().ToInt());
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000180 if (deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
181 stream->Add("deopt_id=%d|", deoptimization_index());
182 }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000183 stream->Add("parameters=%d|", parameter_count());
184 stream->Add("arguments_stack_height=%d|", arguments_stack_height());
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000185 for (int i = 0; i < values_.length(); ++i) {
186 if (i != 0) stream->Add(";");
187 if (values_[i] == NULL) {
188 stream->Add("[hole]");
189 } else {
190 values_[i]->PrintTo(stream);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000191 }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000192 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000193 stream->Add("]");
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000194}
195
196
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000197void LPointerMap::RecordPointer(LOperand* op, Zone* zone) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000198 // Do not record arguments as pointers.
199 if (op->IsStackSlot() && op->index() < 0) return;
200 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000201 pointer_operands_.Add(op, zone);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000202}
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000203
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000204
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000205void LPointerMap::RemovePointer(LOperand* op) {
206 // Do not record arguments as pointers.
207 if (op->IsStackSlot() && op->index() < 0) return;
208 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
209 for (int i = 0; i < pointer_operands_.length(); ++i) {
210 if (pointer_operands_[i]->Equals(op)) {
211 pointer_operands_.Remove(i);
212 --i;
213 }
214 }
215}
216
217
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000218void LPointerMap::RecordUntagged(LOperand* op, Zone* zone) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000219 // Do not record arguments as pointers.
220 if (op->IsStackSlot() && op->index() < 0) return;
221 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000222 untagged_operands_.Add(op, zone);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000223}
224
225
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000226void LPointerMap::PrintTo(StringStream* stream) {
227 stream->Add("{");
228 for (int i = 0; i < pointer_operands_.length(); ++i) {
229 if (i != 0) stream->Add(";");
230 pointer_operands_[i]->PrintTo(stream);
231 }
232 stream->Add("} @%d", position());
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000233}
234
235
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000236int ElementsKindToShiftSize(ElementsKind elements_kind) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000237 switch (elements_kind) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000238 case EXTERNAL_BYTE_ELEMENTS:
239 case EXTERNAL_PIXEL_ELEMENTS:
240 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000241 return 0;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000242 case EXTERNAL_SHORT_ELEMENTS:
243 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000244 return 1;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000245 case EXTERNAL_INT_ELEMENTS:
246 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
247 case EXTERNAL_FLOAT_ELEMENTS:
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000248 return 2;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000249 case EXTERNAL_DOUBLE_ELEMENTS:
250 case FAST_DOUBLE_ELEMENTS:
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000251 case FAST_HOLEY_DOUBLE_ELEMENTS:
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000252 return 3;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000253 case FAST_SMI_ELEMENTS:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000254 case FAST_ELEMENTS:
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000255 case FAST_HOLEY_SMI_ELEMENTS:
256 case FAST_HOLEY_ELEMENTS:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000257 case DICTIONARY_ELEMENTS:
258 case NON_STRICT_ARGUMENTS_ELEMENTS:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000259 return kPointerSizeLog2;
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000260 }
261 UNREACHABLE();
262 return 0;
263}
264
265
jkummerow@chromium.orgac360712013-02-11 09:00:07 +0000266int StackSlotOffset(int index) {
267 if (index >= 0) {
268 // Local or spill slot. Skip the frame pointer, function, and
269 // context in the fixed part of the frame.
270 return -(index + 3) * kPointerSize;
271 } else {
272 // Incoming parameter. Skip the return address.
273 return -(index - 1) * kPointerSize;
274 }
275}
276
277
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000278LChunk::LChunk(CompilationInfo* info, HGraph* graph)
279 : spill_slot_count_(0),
280 info_(info),
281 graph_(graph),
282 instructions_(32, graph->zone()),
283 pointer_maps_(8, graph->zone()),
284 inlined_closures_(1, graph->zone()) {
285}
286
287
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000288LLabel* LChunk::GetLabel(int block_id) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000289 HBasicBlock* block = graph_->blocks()->at(block_id);
290 int first_instruction = block->first_instruction_index();
291 return LLabel::cast(instructions_[first_instruction]);
292}
293
294
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000295int LChunk::LookupDestination(int block_id) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000296 LLabel* cur = GetLabel(block_id);
297 while (cur->replacement() != NULL) {
298 cur = cur->replacement();
299 }
300 return cur->block_id();
301}
302
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000303Label* LChunk::GetAssemblyLabel(int block_id) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000304 LLabel* label = GetLabel(block_id);
305 ASSERT(!label->HasReplacement());
306 return label->label();
307}
308
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000309void LChunk::MarkEmptyBlocks() {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000310 HPhase phase("L_Mark empty blocks", this);
311 for (int i = 0; i < graph()->blocks()->length(); ++i) {
312 HBasicBlock* block = graph()->blocks()->at(i);
313 int first = block->first_instruction_index();
314 int last = block->last_instruction_index();
315 LInstruction* first_instr = instructions()->at(first);
316 LInstruction* last_instr = instructions()->at(last);
317
318 LLabel* label = LLabel::cast(first_instr);
319 if (last_instr->IsGoto()) {
320 LGoto* goto_instr = LGoto::cast(last_instr);
321 if (label->IsRedundant() &&
322 !label->is_loop_header()) {
323 bool can_eliminate = true;
324 for (int i = first + 1; i < last && can_eliminate; ++i) {
325 LInstruction* cur = instructions()->at(i);
326 if (cur->IsGap()) {
327 LGap* gap = LGap::cast(cur);
328 if (!gap->IsRedundant()) {
329 can_eliminate = false;
330 }
331 } else {
332 can_eliminate = false;
333 }
334 }
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000335 if (can_eliminate) {
336 label->set_replacement(GetLabel(goto_instr->block_id()));
337 }
338 }
339 }
340 }
341}
342
343
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000344void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000345 LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000346 gap->set_hydrogen_value(instr->hydrogen_value());
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000347 int index = -1;
348 if (instr->IsControl()) {
349 instructions_.Add(gap, zone());
350 index = instructions_.length();
351 instructions_.Add(instr, zone());
352 } else {
353 index = instructions_.length();
354 instructions_.Add(instr, zone());
355 instructions_.Add(gap, zone());
356 }
357 if (instr->HasPointerMap()) {
358 pointer_maps_.Add(instr->pointer_map(), zone());
359 instr->pointer_map()->set_lithium_position(index);
360 }
361}
362
363
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000364LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000365 return LConstantOperand::Create(constant->id(), zone());
366}
367
368
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000369int LChunk::GetParameterStackSlot(int index) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000370 // The receiver is at index 0, the first parameter at index 1, so we
371 // shift all parameter indexes down by the number of parameters, and
372 // make sure they end up negative so they are distinguishable from
373 // spill slots.
374 int result = index - info()->scope()->num_parameters() - 1;
375 ASSERT(result < 0);
376 return result;
377}
378
379
380// A parameter relative to ebp in the arguments stub.
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000381int LChunk::ParameterAt(int index) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000382 ASSERT(-1 <= index); // -1 is the receiver.
383 return (1 + info()->scope()->num_parameters() - index) *
384 kPointerSize;
385}
386
387
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000388LGap* LChunk::GetGapAt(int index) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000389 return LGap::cast(instructions_[index]);
390}
391
392
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000393bool LChunk::IsGapAt(int index) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000394 return instructions_[index]->IsGap();
395}
396
397
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000398int LChunk::NearestGapPos(int index) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000399 while (!IsGapAt(index)) index--;
400 return index;
401}
402
403
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000404void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000405 GetGapAt(index)->GetOrCreateParallelMove(
406 LGap::START, zone())->AddMove(from, to, zone());
407}
408
409
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000410HConstant* LChunk::LookupConstant(LConstantOperand* operand) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000411 return HConstant::cast(graph_->LookupValue(operand->index()));
412}
413
414
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000415Representation LChunk::LookupLiteralRepresentation(
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000416 LConstantOperand* operand) const {
417 return graph_->LookupValue(operand->index())->representation();
418}
419
420
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000421LChunk* LChunk::NewChunk(HGraph* graph) {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000422 NoHandleAllocation no_handles(graph->isolate());
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000423 AssertNoAllocation no_gc;
424
425 int values = graph->GetMaximumValueID();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000426 CompilationInfo* info = graph->info();
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000427 if (values > LUnallocated::kMaxVirtualRegisters) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000428 info->set_bailout_reason("not enough virtual registers for values");
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000429 return NULL;
430 }
431 LAllocator allocator(values, graph);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000432 LChunkBuilder builder(info, graph, &allocator);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000433 LChunk* chunk = builder.Build();
434 if (chunk == NULL) return NULL;
435
436 if (!allocator.Allocate(chunk)) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000437 info->set_bailout_reason("not enough virtual registers (regalloc)");
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000438 return NULL;
439 }
440
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000441 chunk->set_allocated_double_registers(
442 allocator.assigned_double_registers());
443
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000444 return chunk;
445}
446
447
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000448Handle<Code> LChunk::Codegen() {
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000449 MacroAssembler assembler(info()->isolate(), NULL, 0);
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000450 LOG_CODE_EVENT(info()->isolate(),
451 CodeStartLinePosInfoRecordEvent(
452 assembler.positions_recorder()));
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000453 LCodeGen generator(this, &assembler, info());
454
455 MarkEmptyBlocks();
456
457 if (generator.GenerateCode()) {
458 if (FLAG_trace_codegen) {
459 PrintF("Crankshaft Compiler - ");
460 }
461 CodeGenerator::MakeCodePrologue(info());
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000462 Code::Flags flags = info()->flags();
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000463 Handle<Code> code =
464 CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
465 generator.FinishCode(code);
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000466 code->set_is_crankshafted(true);
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000467 if (!code.is_null()) {
468 void* jit_handler_data =
469 assembler.positions_recorder()->DetachJITHandlerData();
470 LOG_CODE_EVENT(info()->isolate(),
471 CodeEndLinePosInfoRecordEvent(*code, jit_handler_data));
472 }
473
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000474 CodeGenerator::PrintCode(code, info());
475 return code;
476 }
477 return Handle<Code>::null();
478}
479
480
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000481void LChunk::set_allocated_double_registers(BitVector* allocated_registers) {
482 allocated_double_registers_ = allocated_registers;
483 BitVector* doubles = allocated_double_registers();
484 BitVector::Iterator iterator(doubles);
485 while (!iterator.Done()) {
486 if (info()->saves_caller_doubles()) {
487 if (kDoubleSize == kPointerSize * 2) {
488 spill_slot_count_ += 2;
489 } else {
490 spill_slot_count_++;
491 }
492 }
493 iterator.Advance();
494 }
495}
496
497
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000498} } // namespace v8::internal