blob: 09c0f4405f5472b550ebb963f82603d1fb3c51f2 [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());
61 switch (unalloc->policy()) {
62 case LUnallocated::NONE:
63 break;
64 case LUnallocated::FIXED_REGISTER: {
65 const char* register_name =
66 Register::AllocationIndexToString(unalloc->fixed_index());
67 stream->Add("(=%s)", register_name);
68 break;
69 }
70 case LUnallocated::FIXED_DOUBLE_REGISTER: {
71 const char* double_register_name =
72 DoubleRegister::AllocationIndexToString(unalloc->fixed_index());
73 stream->Add("(=%s)", double_register_name);
74 break;
75 }
76 case LUnallocated::FIXED_SLOT:
77 stream->Add("(=%dS)", unalloc->fixed_index());
78 break;
79 case LUnallocated::MUST_HAVE_REGISTER:
80 stream->Add("(R)");
81 break;
82 case LUnallocated::WRITABLE_REGISTER:
83 stream->Add("(WR)");
84 break;
85 case LUnallocated::SAME_AS_FIRST_INPUT:
86 stream->Add("(1)");
87 break;
88 case LUnallocated::ANY:
89 stream->Add("(-)");
90 break;
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +000091 }
92 break;
93 case CONSTANT_OPERAND:
94 stream->Add("[constant:%d]", index());
95 break;
96 case STACK_SLOT:
97 stream->Add("[stack:%d]", index());
98 break;
99 case DOUBLE_STACK_SLOT:
100 stream->Add("[double_stack:%d]", index());
101 break;
102 case REGISTER:
103 stream->Add("[%s|R]", Register::AllocationIndexToString(index()));
104 break;
105 case DOUBLE_REGISTER:
106 stream->Add("[%s|R]", DoubleRegister::AllocationIndexToString(index()));
107 break;
108 case ARGUMENT:
109 stream->Add("[arg:%d]", index());
110 break;
111 }
112}
113
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000114#define DEFINE_OPERAND_CACHE(name, type) \
115 L##name* L##name::cache = NULL; \
116 \
117 void L##name::SetUpCache() { \
118 if (cache) return; \
119 cache = new L##name[kNumCachedOperands]; \
120 for (int i = 0; i < kNumCachedOperands; i++) { \
121 cache[i].ConvertTo(type, i); \
122 } \
123 } \
124 \
125 void L##name::TearDownCache() { \
126 delete[] cache; \
127 }
128
129LITHIUM_OPERAND_LIST(DEFINE_OPERAND_CACHE)
130#undef DEFINE_OPERAND_CACHE
131
132void LOperand::SetUpCaches() {
133#define LITHIUM_OPERAND_SETUP(name, type) L##name::SetUpCache();
134 LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_SETUP)
135#undef LITHIUM_OPERAND_SETUP
136}
137
138
139void LOperand::TearDownCaches() {
140#define LITHIUM_OPERAND_TEARDOWN(name, type) L##name::TearDownCache();
141 LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_TEARDOWN)
142#undef LITHIUM_OPERAND_TEARDOWN
143}
144
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000145
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000146bool LParallelMove::IsRedundant() const {
147 for (int i = 0; i < move_operands_.length(); ++i) {
148 if (!move_operands_[i].IsRedundant()) return false;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000149 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000150 return true;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000151}
152
153
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000154void LParallelMove::PrintDataTo(StringStream* stream) const {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000155 bool first = true;
156 for (int i = 0; i < move_operands_.length(); ++i) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000157 if (!move_operands_[i].IsEliminated()) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000158 LOperand* source = move_operands_[i].source();
159 LOperand* destination = move_operands_[i].destination();
160 if (!first) stream->Add(" ");
161 first = false;
162 if (source->Equals(destination)) {
163 destination->PrintTo(stream);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000164 } else {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000165 destination->PrintTo(stream);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000166 stream->Add(" = ");
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000167 source->PrintTo(stream);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000168 }
erik.corry@gmail.com0511e242011-01-19 11:11:08 +0000169 stream->Add(";");
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000170 }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000171 }
172}
173
174
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000175void LEnvironment::PrintTo(StringStream* stream) {
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000176 stream->Add("[id=%d|", ast_id().ToInt());
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000177 if (deoptimization_index() != Safepoint::kNoDeoptimizationIndex) {
178 stream->Add("deopt_id=%d|", deoptimization_index());
179 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000180 stream->Add("[parameters=%d|", parameter_count());
181 stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
182 for (int i = 0; i < values_.length(); ++i) {
183 if (i != 0) stream->Add(";");
184 if (values_[i] == NULL) {
185 stream->Add("[hole]");
186 } else {
187 values_[i]->PrintTo(stream);
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000188 }
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000189 }
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000190 stream->Add("]");
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000191}
192
193
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000194void LPointerMap::RecordPointer(LOperand* op, Zone* zone) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000195 // Do not record arguments as pointers.
196 if (op->IsStackSlot() && op->index() < 0) return;
197 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000198 pointer_operands_.Add(op, zone);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000199}
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000200
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000201
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000202void LPointerMap::RemovePointer(LOperand* op) {
203 // Do not record arguments as pointers.
204 if (op->IsStackSlot() && op->index() < 0) return;
205 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
206 for (int i = 0; i < pointer_operands_.length(); ++i) {
207 if (pointer_operands_[i]->Equals(op)) {
208 pointer_operands_.Remove(i);
209 --i;
210 }
211 }
212}
213
214
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000215void LPointerMap::RecordUntagged(LOperand* op, Zone* zone) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000216 // Do not record arguments as pointers.
217 if (op->IsStackSlot() && op->index() < 0) return;
218 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000219 untagged_operands_.Add(op, zone);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000220}
221
222
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000223void LPointerMap::PrintTo(StringStream* stream) {
224 stream->Add("{");
225 for (int i = 0; i < pointer_operands_.length(); ++i) {
226 if (i != 0) stream->Add(";");
227 pointer_operands_[i]->PrintTo(stream);
228 }
229 stream->Add("} @%d", position());
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000230}
231
232
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000233int ElementsKindToShiftSize(ElementsKind elements_kind) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000234 switch (elements_kind) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000235 case EXTERNAL_BYTE_ELEMENTS:
236 case EXTERNAL_PIXEL_ELEMENTS:
237 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000238 return 0;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000239 case EXTERNAL_SHORT_ELEMENTS:
240 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000241 return 1;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000242 case EXTERNAL_INT_ELEMENTS:
243 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
244 case EXTERNAL_FLOAT_ELEMENTS:
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000245 return 2;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000246 case EXTERNAL_DOUBLE_ELEMENTS:
247 case FAST_DOUBLE_ELEMENTS:
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000248 case FAST_HOLEY_DOUBLE_ELEMENTS:
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000249 return 3;
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000250 case FAST_SMI_ELEMENTS:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000251 case FAST_ELEMENTS:
svenpanne@chromium.org830d30c2012-05-29 13:20:14 +0000252 case FAST_HOLEY_SMI_ELEMENTS:
253 case FAST_HOLEY_ELEMENTS:
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000254 case DICTIONARY_ELEMENTS:
255 case NON_STRICT_ARGUMENTS_ELEMENTS:
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000256 return kPointerSizeLog2;
karlklose@chromium.org83a47282011-05-11 11:54:09 +0000257 }
258 UNREACHABLE();
259 return 0;
260}
261
262
jkummerow@chromium.orgac360712013-02-11 09:00:07 +0000263int StackSlotOffset(int index) {
264 if (index >= 0) {
265 // Local or spill slot. Skip the frame pointer, function, and
266 // context in the fixed part of the frame.
267 return -(index + 3) * kPointerSize;
268 } else {
269 // Incoming parameter. Skip the return address.
270 return -(index - 1) * kPointerSize;
271 }
272}
273
274
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000275LChunk::LChunk(CompilationInfo* info, HGraph* graph)
276 : spill_slot_count_(0),
277 info_(info),
278 graph_(graph),
279 instructions_(32, graph->zone()),
280 pointer_maps_(8, graph->zone()),
281 inlined_closures_(1, graph->zone()) {
282}
283
284
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000285LLabel* LChunk::GetLabel(int block_id) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000286 HBasicBlock* block = graph_->blocks()->at(block_id);
287 int first_instruction = block->first_instruction_index();
288 return LLabel::cast(instructions_[first_instruction]);
289}
290
291
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000292int LChunk::LookupDestination(int block_id) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000293 LLabel* cur = GetLabel(block_id);
294 while (cur->replacement() != NULL) {
295 cur = cur->replacement();
296 }
297 return cur->block_id();
298}
299
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000300Label* LChunk::GetAssemblyLabel(int block_id) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000301 LLabel* label = GetLabel(block_id);
302 ASSERT(!label->HasReplacement());
303 return label->label();
304}
305
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000306void LChunk::MarkEmptyBlocks() {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000307 HPhase phase("L_Mark empty blocks", this);
308 for (int i = 0; i < graph()->blocks()->length(); ++i) {
309 HBasicBlock* block = graph()->blocks()->at(i);
310 int first = block->first_instruction_index();
311 int last = block->last_instruction_index();
312 LInstruction* first_instr = instructions()->at(first);
313 LInstruction* last_instr = instructions()->at(last);
314
315 LLabel* label = LLabel::cast(first_instr);
316 if (last_instr->IsGoto()) {
317 LGoto* goto_instr = LGoto::cast(last_instr);
318 if (label->IsRedundant() &&
319 !label->is_loop_header()) {
320 bool can_eliminate = true;
321 for (int i = first + 1; i < last && can_eliminate; ++i) {
322 LInstruction* cur = instructions()->at(i);
323 if (cur->IsGap()) {
324 LGap* gap = LGap::cast(cur);
325 if (!gap->IsRedundant()) {
326 can_eliminate = false;
327 }
328 } else {
329 can_eliminate = false;
330 }
331 }
332
333 if (can_eliminate) {
334 label->set_replacement(GetLabel(goto_instr->block_id()));
335 }
336 }
337 }
338 }
339}
340
341
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000342void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000343 LInstructionGap* gap = new(graph_->zone()) LInstructionGap(block);
344 int index = -1;
345 if (instr->IsControl()) {
346 instructions_.Add(gap, zone());
347 index = instructions_.length();
348 instructions_.Add(instr, zone());
349 } else {
350 index = instructions_.length();
351 instructions_.Add(instr, zone());
352 instructions_.Add(gap, zone());
353 }
354 if (instr->HasPointerMap()) {
355 pointer_maps_.Add(instr->pointer_map(), zone());
356 instr->pointer_map()->set_lithium_position(index);
357 }
358}
359
360
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000361LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000362 return LConstantOperand::Create(constant->id(), zone());
363}
364
365
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000366int LChunk::GetParameterStackSlot(int index) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000367 // The receiver is at index 0, the first parameter at index 1, so we
368 // shift all parameter indexes down by the number of parameters, and
369 // make sure they end up negative so they are distinguishable from
370 // spill slots.
371 int result = index - info()->scope()->num_parameters() - 1;
372 ASSERT(result < 0);
373 return result;
374}
375
376
377// A parameter relative to ebp in the arguments stub.
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000378int LChunk::ParameterAt(int index) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000379 ASSERT(-1 <= index); // -1 is the receiver.
380 return (1 + info()->scope()->num_parameters() - index) *
381 kPointerSize;
382}
383
384
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000385LGap* LChunk::GetGapAt(int index) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000386 return LGap::cast(instructions_[index]);
387}
388
389
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000390bool LChunk::IsGapAt(int index) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000391 return instructions_[index]->IsGap();
392}
393
394
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000395int LChunk::NearestGapPos(int index) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000396 while (!IsGapAt(index)) index--;
397 return index;
398}
399
400
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000401void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000402 GetGapAt(index)->GetOrCreateParallelMove(
403 LGap::START, zone())->AddMove(from, to, zone());
404}
405
406
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000407HConstant* LChunk::LookupConstant(LConstantOperand* operand) const {
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000408 return HConstant::cast(graph_->LookupValue(operand->index()));
409}
410
411
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000412Representation LChunk::LookupLiteralRepresentation(
rossberg@chromium.org657d53b2012-07-12 11:06:03 +0000413 LConstantOperand* operand) const {
414 return graph_->LookupValue(operand->index())->representation();
415}
416
417
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000418LChunk* LChunk::NewChunk(HGraph* graph) {
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000419 NoHandleAllocation no_handles(graph->isolate());
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000420 AssertNoAllocation no_gc;
421
422 int values = graph->GetMaximumValueID();
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000423 CompilationInfo* info = graph->info();
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000424 if (values > LUnallocated::kMaxVirtualRegisters) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000425 info->set_bailout_reason("not enough virtual registers for values");
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000426 return NULL;
427 }
428 LAllocator allocator(values, graph);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000429 LChunkBuilder builder(info, graph, &allocator);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000430 LChunk* chunk = builder.Build();
431 if (chunk == NULL) return NULL;
432
433 if (!allocator.Allocate(chunk)) {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000434 info->set_bailout_reason("not enough virtual registers (regalloc)");
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000435 return NULL;
436 }
437
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000438 chunk->set_allocated_double_registers(
439 allocator.assigned_double_registers());
440
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000441 return chunk;
442}
443
444
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000445Handle<Code> LChunk::Codegen(Code::Kind kind) {
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000446 MacroAssembler assembler(info()->isolate(), NULL, 0);
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000447 LOG_CODE_EVENT(info()->isolate(),
448 CodeStartLinePosInfoRecordEvent(
449 assembler.positions_recorder()));
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000450 LCodeGen generator(this, &assembler, info());
451
452 MarkEmptyBlocks();
453
454 if (generator.GenerateCode()) {
455 if (FLAG_trace_codegen) {
456 PrintF("Crankshaft Compiler - ");
457 }
458 CodeGenerator::MakeCodePrologue(info());
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000459 Code::Flags flags = Code::ComputeFlags(kind);
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000460 Handle<Code> code =
461 CodeGenerator::MakeCodeEpilogue(&assembler, flags, info());
462 generator.FinishCode(code);
yangguo@chromium.orgc03a1922013-02-19 13:55:47 +0000463
464 if (!code.is_null()) {
465 void* jit_handler_data =
466 assembler.positions_recorder()->DetachJITHandlerData();
467 LOG_CODE_EVENT(info()->isolate(),
468 CodeEndLinePosInfoRecordEvent(*code, jit_handler_data));
469 }
470
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000471 CodeGenerator::PrintCode(code, info());
472 return code;
473 }
474 return Handle<Code>::null();
475}
476
477
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000478void LChunk::set_allocated_double_registers(BitVector* allocated_registers) {
479 allocated_double_registers_ = allocated_registers;
480 BitVector* doubles = allocated_double_registers();
481 BitVector::Iterator iterator(doubles);
482 while (!iterator.Done()) {
483 if (info()->saves_caller_doubles()) {
484 if (kDoubleSize == kPointerSize * 2) {
485 spill_slot_count_ += 2;
486 } else {
487 spill_slot_count_++;
488 }
489 }
490 iterator.Advance();
491 }
492}
493
494
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000495} } // namespace v8::internal