Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Side by Side Diff: src/arm/lithium-arm.cc

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "lithium-allocator-inl.h"
28 #include "arm/lithium-arm.h" 29 #include "arm/lithium-arm.h"
29 #include "arm/lithium-codegen-arm.h" 30 #include "arm/lithium-codegen-arm.h"
30 31
31 namespace v8 { 32 namespace v8 {
32 namespace internal { 33 namespace internal {
33 34
34 #define DEFINE_COMPILE(type) \ 35 #define DEFINE_COMPILE(type) \
35 void L##type::CompileToNative(LCodeGen* generator) { \ 36 void L##type::CompileToNative(LCodeGen* generator) { \
36 generator->Do##type(this); \ 37 generator->Do##type(this); \
37 } 38 }
(...skipping 11 matching lines...) Expand all
49 50
50 51
51 void LOsrEntry::MarkSpilledRegister(int allocation_index, 52 void LOsrEntry::MarkSpilledRegister(int allocation_index,
52 LOperand* spill_operand) { 53 LOperand* spill_operand) {
53 ASSERT(spill_operand->IsStackSlot()); 54 ASSERT(spill_operand->IsStackSlot());
54 ASSERT(register_spills_[allocation_index] == NULL); 55 ASSERT(register_spills_[allocation_index] == NULL);
55 register_spills_[allocation_index] = spill_operand; 56 register_spills_[allocation_index] = spill_operand;
56 } 57 }
57 58
58 59
60 #ifdef DEBUG
61 void LInstruction::VerifyCall() {
62 // Call instructions can use only fixed registers as
63 // temporaries and outputs because all registers
64 // are blocked by the calling convention.
65 // Inputs must use a fixed register.
66 ASSERT(Output() == NULL ||
67 LUnallocated::cast(Output())->HasFixedPolicy() ||
68 !LUnallocated::cast(Output())->HasRegisterPolicy());
69 for (UseIterator it(this); it.HasNext(); it.Advance()) {
70 LOperand* operand = it.Next();
71 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
72 !LUnallocated::cast(operand)->HasRegisterPolicy());
73 }
74 for (TempIterator it(this); it.HasNext(); it.Advance()) {
75 LOperand* operand = it.Next();
76 ASSERT(LUnallocated::cast(operand)->HasFixedPolicy() ||
77 !LUnallocated::cast(operand)->HasRegisterPolicy());
78 }
79 }
80 #endif
81
82
59 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, 83 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
60 LOperand* spill_operand) { 84 LOperand* spill_operand) {
61 ASSERT(spill_operand->IsDoubleStackSlot()); 85 ASSERT(spill_operand->IsDoubleStackSlot());
62 ASSERT(double_register_spills_[allocation_index] == NULL); 86 ASSERT(double_register_spills_[allocation_index] == NULL);
63 double_register_spills_[allocation_index] = spill_operand; 87 double_register_spills_[allocation_index] = spill_operand;
64 } 88 }
65 89
66 90
67 void LInstruction::PrintTo(StringStream* stream) const { 91 void LInstruction::PrintTo(StringStream* stream) {
68 stream->Add("%s ", this->Mnemonic()); 92 stream->Add("%s ", this->Mnemonic());
69 if (HasResult()) { 93
70 result()->PrintTo(stream); 94 PrintOutputOperandTo(stream);
71 stream->Add(" "); 95
72 }
73 PrintDataTo(stream); 96 PrintDataTo(stream);
74 97
75 if (HasEnvironment()) { 98 if (HasEnvironment()) {
76 stream->Add(" "); 99 stream->Add(" ");
77 environment()->PrintTo(stream); 100 environment()->PrintTo(stream);
78 } 101 }
79 102
80 if (HasPointerMap()) { 103 if (HasPointerMap()) {
81 stream->Add(" "); 104 stream->Add(" ");
82 pointer_map()->PrintTo(stream); 105 pointer_map()->PrintTo(stream);
83 } 106 }
84 } 107 }
85 108
86 109
87 void LLabel::PrintDataTo(StringStream* stream) const { 110 template<int R, int I, int T>
111 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
112 stream->Add("= ");
113 inputs_.PrintOperandsTo(stream);
114 }
115
116
117 template<int R, int I, int T>
118 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
119 results_.PrintOperandsTo(stream);
120 }
121
122
123 template<typename T, int N>
124 void OperandContainer<T, N>::PrintOperandsTo(StringStream* stream) {
125 for (int i = 0; i < N; i++) {
126 if (i > 0) stream->Add(" ");
127 elems_[i]->PrintTo(stream);
128 }
129 }
130
131
132 void LLabel::PrintDataTo(StringStream* stream) {
88 LGap::PrintDataTo(stream); 133 LGap::PrintDataTo(stream);
89 LLabel* rep = replacement(); 134 LLabel* rep = replacement();
90 if (rep != NULL) { 135 if (rep != NULL) {
91 stream->Add(" Dead block replaced with B%d", rep->block_id()); 136 stream->Add(" Dead block replaced with B%d", rep->block_id());
92 } 137 }
93 } 138 }
94 139
95
96 bool LParallelMove::IsRedundant() const {
97 for (int i = 0; i < move_operands_.length(); ++i) {
98 if (!move_operands_[i].IsRedundant()) return false;
99 }
100 return true;
101 }
102
103
104 void LParallelMove::PrintDataTo(StringStream* stream) const {
105 for (int i = move_operands_.length() - 1; i >= 0; --i) {
106 if (!move_operands_[i].IsEliminated()) {
107 LOperand* from = move_operands_[i].from();
108 LOperand* to = move_operands_[i].to();
109 if (from->Equals(to)) {
110 to->PrintTo(stream);
111 } else {
112 to->PrintTo(stream);
113 stream->Add(" = ");
114 from->PrintTo(stream);
115 }
116 stream->Add("; ");
117 }
118 }
119 }
120
121 140
122 bool LGap::IsRedundant() const { 141 bool LGap::IsRedundant() const {
123 for (int i = 0; i < 4; i++) { 142 for (int i = 0; i < 4; i++) {
124 if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) { 143 if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) {
125 return false; 144 return false;
126 } 145 }
127 } 146 }
128 147
129 return true; 148 return true;
130 } 149 }
(...skipping 24 matching lines...) Expand all
155 } 174 }
156 175
157 176
158 const char* LArithmeticT::Mnemonic() const { 177 const char* LArithmeticT::Mnemonic() const {
159 switch (op()) { 178 switch (op()) {
160 case Token::ADD: return "add-t"; 179 case Token::ADD: return "add-t";
161 case Token::SUB: return "sub-t"; 180 case Token::SUB: return "sub-t";
162 case Token::MUL: return "mul-t"; 181 case Token::MUL: return "mul-t";
163 case Token::MOD: return "mod-t"; 182 case Token::MOD: return "mod-t";
164 case Token::DIV: return "div-t"; 183 case Token::DIV: return "div-t";
184 case Token::BIT_AND: return "bit-and-t";
185 case Token::BIT_OR: return "bit-or-t";
186 case Token::BIT_XOR: return "bit-xor-t";
187 case Token::SHL: return "shl-t";
188 case Token::SAR: return "sar-t";
189 case Token::SHR: return "shr-t";
165 default: 190 default:
166 UNREACHABLE(); 191 UNREACHABLE();
167 return NULL; 192 return NULL;
168 } 193 }
169 } 194 }
170 195
171 196
172 197 void LGoto::PrintDataTo(StringStream* stream) {
173 void LBinaryOperation::PrintDataTo(StringStream* stream) const {
174 stream->Add("= ");
175 left()->PrintTo(stream);
176 stream->Add(" ");
177 right()->PrintTo(stream);
178 }
179
180
181 void LGoto::PrintDataTo(StringStream* stream) const {
182 stream->Add("B%d", block_id()); 198 stream->Add("B%d", block_id());
183 } 199 }
184 200
185 201
186 void LBranch::PrintDataTo(StringStream* stream) const { 202 void LBranch::PrintDataTo(StringStream* stream) {
187 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); 203 stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
188 input()->PrintTo(stream); 204 InputAt(0)->PrintTo(stream);
189 } 205 }
190 206
191 207
192 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) const { 208 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
193 stream->Add("if "); 209 stream->Add("if ");
194 left()->PrintTo(stream); 210 InputAt(0)->PrintTo(stream);
195 stream->Add(" %s ", Token::String(op())); 211 stream->Add(" %s ", Token::String(op()));
196 right()->PrintTo(stream); 212 InputAt(1)->PrintTo(stream);
197 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); 213 stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
198 } 214 }
199 215
200 216
201 void LIsNullAndBranch::PrintDataTo(StringStream* stream) const { 217 void LIsNullAndBranch::PrintDataTo(StringStream* stream) {
202 stream->Add("if "); 218 stream->Add("if ");
203 input()->PrintTo(stream); 219 InputAt(0)->PrintTo(stream);
204 stream->Add(is_strict() ? " === null" : " == null"); 220 stream->Add(is_strict() ? " === null" : " == null");
205 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); 221 stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
206 } 222 }
207 223
208 224
209 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) const { 225 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
210 stream->Add("if is_object("); 226 stream->Add("if is_object(");
211 input()->PrintTo(stream); 227 InputAt(0)->PrintTo(stream);
212 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 228 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
213 } 229 }
214 230
215 231
216 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) const { 232 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
217 stream->Add("if is_smi("); 233 stream->Add("if is_smi(");
218 input()->PrintTo(stream); 234 InputAt(0)->PrintTo(stream);
219 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 235 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
220 } 236 }
221 237
222 238
223 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) const { 239 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
224 stream->Add("if has_instance_type("); 240 stream->Add("if has_instance_type(");
225 input()->PrintTo(stream); 241 InputAt(0)->PrintTo(stream);
226 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 242 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
227 } 243 }
228 244
229 245
230 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) const { 246 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
231 stream->Add("if has_cached_array_index("); 247 stream->Add("if has_cached_array_index(");
232 input()->PrintTo(stream); 248 InputAt(0)->PrintTo(stream);
233 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 249 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
234 } 250 }
235 251
236 252
237 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) const { 253 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
238 stream->Add("if class_of_test("); 254 stream->Add("if class_of_test(");
239 input()->PrintTo(stream); 255 InputAt(0)->PrintTo(stream);
240 stream->Add(", \"%o\") then B%d else B%d", 256 stream->Add(", \"%o\") then B%d else B%d",
241 *hydrogen()->class_name(), 257 *hydrogen()->class_name(),
242 true_block_id(), 258 true_block_id(),
243 false_block_id()); 259 false_block_id());
244 } 260 }
245 261
246 262
247 void LTypeofIs::PrintDataTo(StringStream* stream) const { 263 void LTypeofIs::PrintDataTo(StringStream* stream) {
248 input()->PrintTo(stream); 264 InputAt(0)->PrintTo(stream);
249 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); 265 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
250 } 266 }
251 267
252 268
253 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) const { 269 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
254 stream->Add("if typeof "); 270 stream->Add("if typeof ");
255 input()->PrintTo(stream); 271 InputAt(0)->PrintTo(stream);
256 stream->Add(" == \"%s\" then B%d else B%d", 272 stream->Add(" == \"%s\" then B%d else B%d",
257 *hydrogen()->type_literal()->ToCString(), 273 *hydrogen()->type_literal()->ToCString(),
258 true_block_id(), false_block_id()); 274 true_block_id(), false_block_id());
259 } 275 }
260 276
261 277
262 void LCallConstantFunction::PrintDataTo(StringStream* stream) const { 278 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
263 stream->Add("#%d / ", arity()); 279 stream->Add("#%d / ", arity());
264 } 280 }
265 281
266 282
267 void LUnaryMathOperation::PrintDataTo(StringStream* stream) const { 283 void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
268 stream->Add("/%s ", hydrogen()->OpName()); 284 stream->Add("/%s ", hydrogen()->OpName());
269 input()->PrintTo(stream); 285 InputAt(0)->PrintTo(stream);
270 } 286 }
271 287
272 288
273 void LCallKeyed::PrintDataTo(StringStream* stream) const { 289 void LLoadContextSlot::PrintDataTo(StringStream* stream) {
290 InputAt(0)->PrintTo(stream);
291 stream->Add("[%d]", slot_index());
292 }
293
294
295 void LStoreContextSlot::PrintDataTo(StringStream* stream) {
296 InputAt(0)->PrintTo(stream);
297 stream->Add("[%d] <- ", slot_index());
298 InputAt(1)->PrintTo(stream);
299 }
300
301
302 void LCallKeyed::PrintDataTo(StringStream* stream) {
274 stream->Add("[r2] #%d / ", arity()); 303 stream->Add("[r2] #%d / ", arity());
275 } 304 }
276 305
277 306
278 void LCallNamed::PrintDataTo(StringStream* stream) const { 307 void LCallNamed::PrintDataTo(StringStream* stream) {
279 SmartPointer<char> name_string = name()->ToCString(); 308 SmartPointer<char> name_string = name()->ToCString();
280 stream->Add("%s #%d / ", *name_string, arity()); 309 stream->Add("%s #%d / ", *name_string, arity());
281 } 310 }
282 311
283 312
284 void LCallGlobal::PrintDataTo(StringStream* stream) const { 313 void LCallGlobal::PrintDataTo(StringStream* stream) {
285 SmartPointer<char> name_string = name()->ToCString(); 314 SmartPointer<char> name_string = name()->ToCString();
286 stream->Add("%s #%d / ", *name_string, arity()); 315 stream->Add("%s #%d / ", *name_string, arity());
287 } 316 }
288 317
289 318
290 void LCallKnownGlobal::PrintDataTo(StringStream* stream) const { 319 void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
291 stream->Add("#%d / ", arity()); 320 stream->Add("#%d / ", arity());
292 } 321 }
293 322
294 323
295 void LCallNew::PrintDataTo(StringStream* stream) const { 324 void LCallNew::PrintDataTo(StringStream* stream) {
296 LUnaryOperation::PrintDataTo(stream); 325 stream->Add("= ");
326 InputAt(0)->PrintTo(stream);
297 stream->Add(" #%d / ", arity()); 327 stream->Add(" #%d / ", arity());
298 } 328 }
299 329
300 330
301 void LClassOfTest::PrintDataTo(StringStream* stream) const { 331 void LClassOfTest::PrintDataTo(StringStream* stream) {
302 stream->Add("= class_of_test("); 332 stream->Add("= class_of_test(");
303 input()->PrintTo(stream); 333 InputAt(0)->PrintTo(stream);
304 stream->Add(", \"%o\")", *hydrogen()->class_name()); 334 stream->Add(", \"%o\")", *hydrogen()->class_name());
305 } 335 }
306 336
307 337
308 void LUnaryOperation::PrintDataTo(StringStream* stream) const { 338 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) {
309 stream->Add("= ");
310 input()->PrintTo(stream);
311 }
312
313
314 void LAccessArgumentsAt::PrintDataTo(StringStream* stream) const {
315 arguments()->PrintTo(stream); 339 arguments()->PrintTo(stream);
316 340
317 stream->Add(" length "); 341 stream->Add(" length ");
318 length()->PrintTo(stream); 342 length()->PrintTo(stream);
319 343
320 stream->Add(" index "); 344 stream->Add(" index ");
321 index()->PrintTo(stream); 345 index()->PrintTo(stream);
322 } 346 }
323 347
324 348
349 void LStoreNamed::PrintDataTo(StringStream* stream) {
350 object()->PrintTo(stream);
351 stream->Add(".");
352 stream->Add(*String::cast(*name())->ToCString());
353 stream->Add(" <- ");
354 value()->PrintTo(stream);
355 }
356
357
358 void LStoreKeyed::PrintDataTo(StringStream* stream) {
359 object()->PrintTo(stream);
360 stream->Add("[");
361 key()->PrintTo(stream);
362 stream->Add("] <- ");
363 value()->PrintTo(stream);
364 }
365
366
325 LChunk::LChunk(HGraph* graph) 367 LChunk::LChunk(HGraph* graph)
326 : spill_slot_count_(0), 368 : spill_slot_count_(0),
327 graph_(graph), 369 graph_(graph),
328 instructions_(32), 370 instructions_(32),
329 pointer_maps_(8), 371 pointer_maps_(8),
330 inlined_closures_(1) { 372 inlined_closures_(1) {
331 } 373 }
332 374
333 375
334 void LChunk::Verify() const {
335 // TODO(twuerthinger): Implement verification for chunk.
336 }
337
338
339 int LChunk::GetNextSpillIndex(bool is_double) { 376 int LChunk::GetNextSpillIndex(bool is_double) {
340 // Skip a slot if for a double-width slot. 377 // Skip a slot if for a double-width slot.
341 if (is_double) spill_slot_count_++; 378 if (is_double) spill_slot_count_++;
342 return spill_slot_count_++; 379 return spill_slot_count_++;
343 } 380 }
344 381
345 382
346 LOperand* LChunk::GetNextSpillSlot(bool is_double) { 383 LOperand* LChunk::GetNextSpillSlot(bool is_double) {
347 int index = GetNextSpillIndex(is_double); 384 int index = GetNextSpillIndex(is_double);
348 if (is_double) { 385 if (is_double) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 420
384 if (can_eliminate) { 421 if (can_eliminate) {
385 label->set_replacement(GetLabel(goto_instr->block_id())); 422 label->set_replacement(GetLabel(goto_instr->block_id()));
386 } 423 }
387 } 424 }
388 } 425 }
389 } 426 }
390 } 427 }
391 428
392 429
393 void LStoreNamed::PrintDataTo(StringStream* stream) const { 430 void LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
394 object()->PrintTo(stream);
395 stream->Add(".");
396 stream->Add(*String::cast(*name())->ToCString());
397 stream->Add(" <- ");
398 value()->PrintTo(stream);
399 }
400
401
402 void LStoreKeyed::PrintDataTo(StringStream* stream) const {
403 object()->PrintTo(stream);
404 stream->Add("[");
405 key()->PrintTo(stream);
406 stream->Add("] <- ");
407 value()->PrintTo(stream);
408 }
409
410
411 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
412 LGap* gap = new LGap(block); 431 LGap* gap = new LGap(block);
413 int index = -1; 432 int index = -1;
414 if (instr->IsControl()) { 433 if (instr->IsControl()) {
415 instructions_.Add(gap); 434 instructions_.Add(gap);
416 index = instructions_.length(); 435 index = instructions_.length();
417 instructions_.Add(instr); 436 instructions_.Add(instr);
418 } else { 437 } else {
419 index = instructions_.length(); 438 index = instructions_.length();
420 instructions_.Add(instr); 439 instructions_.Add(instr);
421 instructions_.Add(gap); 440 instructions_.Add(gap);
422 } 441 }
423 if (instr->HasPointerMap()) { 442 if (instr->HasPointerMap()) {
424 pointer_maps_.Add(instr->pointer_map()); 443 pointer_maps_.Add(instr->pointer_map());
425 instr->pointer_map()->set_lithium_position(index); 444 instr->pointer_map()->set_lithium_position(index);
426 } 445 }
427 return index;
428 } 446 }
429 447
430 448
431 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) { 449 LConstantOperand* LChunk::DefineConstantOperand(HConstant* constant) {
432 return LConstantOperand::Create(constant->id()); 450 return LConstantOperand::Create(constant->id());
433 } 451 }
434 452
435 453
436 int LChunk::GetParameterStackSlot(int index) const { 454 int LChunk::GetParameterStackSlot(int index) const {
437 // The receiver is at index 0, the first parameter at index 1, so we 455 // The receiver is at index 0, the first parameter at index 1, so we
(...skipping 27 matching lines...) Expand all
465 while (!IsGapAt(index)) index--; 483 while (!IsGapAt(index)) index--;
466 return index; 484 return index;
467 } 485 }
468 486
469 487
470 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) { 488 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
471 GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to); 489 GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to);
472 } 490 }
473 491
474 492
475 class LGapNode: public ZoneObject {
476 public:
477 explicit LGapNode(LOperand* operand)
478 : operand_(operand), resolved_(false), visited_id_(-1) { }
479
480 LOperand* operand() const { return operand_; }
481 bool IsResolved() const { return !IsAssigned() || resolved_; }
482 void MarkResolved() {
483 ASSERT(!IsResolved());
484 resolved_ = true;
485 }
486 int visited_id() const { return visited_id_; }
487 void set_visited_id(int id) {
488 ASSERT(id > visited_id_);
489 visited_id_ = id;
490 }
491
492 bool IsAssigned() const { return assigned_from_.is_set(); }
493 LGapNode* assigned_from() const { return assigned_from_.get(); }
494 void set_assigned_from(LGapNode* n) { assigned_from_.set(n); }
495
496 private:
497 LOperand* operand_;
498 SetOncePointer<LGapNode> assigned_from_;
499 bool resolved_;
500 int visited_id_;
501 };
502
503
504 LGapResolver::LGapResolver(const ZoneList<LMoveOperands>* moves,
505 LOperand* marker_operand)
506 : nodes_(4),
507 identified_cycles_(4),
508 result_(4),
509 marker_operand_(marker_operand),
510 next_visited_id_(0) {
511 for (int i = 0; i < moves->length(); ++i) {
512 LMoveOperands move = moves->at(i);
513 if (!move.IsRedundant()) RegisterMove(move);
514 }
515 }
516
517
518 const ZoneList<LMoveOperands>* LGapResolver::ResolveInReverseOrder() {
519 for (int i = 0; i < identified_cycles_.length(); ++i) {
520 ResolveCycle(identified_cycles_[i]);
521 }
522
523 int unresolved_nodes;
524 do {
525 unresolved_nodes = 0;
526 for (int j = 0; j < nodes_.length(); j++) {
527 LGapNode* node = nodes_[j];
528 if (!node->IsResolved() && node->assigned_from()->IsResolved()) {
529 AddResultMove(node->assigned_from(), node);
530 node->MarkResolved();
531 }
532 if (!node->IsResolved()) ++unresolved_nodes;
533 }
534 } while (unresolved_nodes > 0);
535 return &result_;
536 }
537
538
539 void LGapResolver::AddResultMove(LGapNode* from, LGapNode* to) {
540 AddResultMove(from->operand(), to->operand());
541 }
542
543
544 void LGapResolver::AddResultMove(LOperand* from, LOperand* to) {
545 result_.Add(LMoveOperands(from, to));
546 }
547
548
549 void LGapResolver::ResolveCycle(LGapNode* start) {
550 ZoneList<LOperand*> circle_operands(8);
551 circle_operands.Add(marker_operand_);
552 LGapNode* cur = start;
553 do {
554 cur->MarkResolved();
555 circle_operands.Add(cur->operand());
556 cur = cur->assigned_from();
557 } while (cur != start);
558 circle_operands.Add(marker_operand_);
559
560 for (int i = circle_operands.length() - 1; i > 0; --i) {
561 LOperand* from = circle_operands[i];
562 LOperand* to = circle_operands[i - 1];
563 AddResultMove(from, to);
564 }
565 }
566
567
568 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b, int visited_id) {
569 ASSERT(a != b);
570 LGapNode* cur = a;
571 while (cur != b && cur->visited_id() != visited_id && cur->IsAssigned()) {
572 cur->set_visited_id(visited_id);
573 cur = cur->assigned_from();
574 }
575
576 return cur == b;
577 }
578
579
580 bool LGapResolver::CanReach(LGapNode* a, LGapNode* b) {
581 ASSERT(a != b);
582 return CanReach(a, b, next_visited_id_++);
583 }
584
585
586 void LGapResolver::RegisterMove(LMoveOperands move) {
587 if (move.from()->IsConstantOperand()) {
588 // Constant moves should be last in the machine code. Therefore add them
589 // first to the result set.
590 AddResultMove(move.from(), move.to());
591 } else {
592 LGapNode* from = LookupNode(move.from());
593 LGapNode* to = LookupNode(move.to());
594 if (to->IsAssigned() && to->assigned_from() == from) {
595 move.Eliminate();
596 return;
597 }
598 ASSERT(!to->IsAssigned());
599 if (CanReach(from, to)) {
600 // This introduces a circle. Save.
601 identified_cycles_.Add(from);
602 }
603 to->set_assigned_from(from);
604 }
605 }
606
607
608 LGapNode* LGapResolver::LookupNode(LOperand* operand) {
609 for (int i = 0; i < nodes_.length(); ++i) {
610 if (nodes_[i]->operand()->Equals(operand)) return nodes_[i];
611 }
612
613 // No node found => create a new one.
614 LGapNode* result = new LGapNode(operand);
615 nodes_.Add(result);
616 return result;
617 }
618
619
620 Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const { 493 Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
621 return HConstant::cast(graph_->LookupValue(operand->index()))->handle(); 494 return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
622 } 495 }
623 496
624 497
625 Representation LChunk::LookupLiteralRepresentation( 498 Representation LChunk::LookupLiteralRepresentation(
626 LConstantOperand* operand) const { 499 LConstantOperand* operand) const {
627 return graph_->LookupValue(operand->index())->representation(); 500 return graph_->LookupValue(operand->index())->representation();
628 } 501 }
629 502
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 } 608 }
736 609
737 610
738 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) { 611 LOperand* LChunkBuilder::UseRegisterOrConstantAtStart(HValue* value) {
739 return value->IsConstant() 612 return value->IsConstant()
740 ? chunk_->DefineConstantOperand(HConstant::cast(value)) 613 ? chunk_->DefineConstantOperand(HConstant::cast(value))
741 : UseRegisterAtStart(value); 614 : UseRegisterAtStart(value);
742 } 615 }
743 616
744 617
618 LOperand* LChunkBuilder::UseAny(HValue* value) {
619 return value->IsConstant()
620 ? chunk_->DefineConstantOperand(HConstant::cast(value))
621 : Use(value, new LUnallocated(LUnallocated::ANY));
622 }
623
624
745 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { 625 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) {
746 if (value->EmitAtUses()) { 626 if (value->EmitAtUses()) {
747 HInstruction* instr = HInstruction::cast(value); 627 HInstruction* instr = HInstruction::cast(value);
748 VisitInstruction(instr); 628 VisitInstruction(instr);
749 } 629 }
750 allocator_->RecordUse(value, operand); 630 allocator_->RecordUse(value, operand);
751 return operand; 631 return operand;
752 } 632 }
753 633
754 634
755 LInstruction* LChunkBuilder::Define(LInstruction* instr) { 635 template<int I, int T>
636 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr,
637 LUnallocated* result) {
638 allocator_->RecordDefinition(current_instruction_, result);
639 instr->set_result(result);
640 return instr;
641 }
642
643
644 template<int I, int T>
645 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr) {
756 return Define(instr, new LUnallocated(LUnallocated::NONE)); 646 return Define(instr, new LUnallocated(LUnallocated::NONE));
757 } 647 }
758 648
759 649
760 LInstruction* LChunkBuilder::DefineAsRegister(LInstruction* instr) { 650 template<int I, int T>
651 LInstruction* LChunkBuilder::DefineAsRegister(
652 LTemplateInstruction<1, I, T>* instr) {
761 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); 653 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
762 } 654 }
763 655
764 656
765 LInstruction* LChunkBuilder::DefineAsSpilled(LInstruction* instr, int index) { 657 template<int I, int T>
658 LInstruction* LChunkBuilder::DefineAsSpilled(
659 LTemplateInstruction<1, I, T>* instr, int index) {
766 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); 660 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index));
767 } 661 }
768 662
769 663
770 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) { 664 template<int I, int T>
665 LInstruction* LChunkBuilder::DefineSameAsFirst(
666 LTemplateInstruction<1, I, T>* instr) {
771 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); 667 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
772 } 668 }
773 669
774 670
775 LInstruction* LChunkBuilder::DefineFixed(LInstruction* instr, Register reg) { 671 template<int I, int T>
672 LInstruction* LChunkBuilder::DefineFixed(
673 LTemplateInstruction<1, I, T>* instr, Register reg) {
776 return Define(instr, ToUnallocated(reg)); 674 return Define(instr, ToUnallocated(reg));
777 } 675 }
778 676
779 677
780 LInstruction* LChunkBuilder::DefineFixedDouble(LInstruction* instr, 678 template<int I, int T>
781 DoubleRegister reg) { 679 LInstruction* LChunkBuilder::DefineFixedDouble(
680 LTemplateInstruction<1, I, T>* instr, DoubleRegister reg) {
782 return Define(instr, ToUnallocated(reg)); 681 return Define(instr, ToUnallocated(reg));
783 } 682 }
784 683
785 684
786 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { 685 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
787 HEnvironment* hydrogen_env = current_block_->last_environment(); 686 HEnvironment* hydrogen_env = current_block_->last_environment();
788 instr->set_environment(CreateEnvironment(hydrogen_env)); 687 instr->set_environment(CreateEnvironment(hydrogen_env));
789 return instr; 688 return instr;
790 } 689 }
791 690
792 691
793 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment( 692 LInstruction* LChunkBuilder::SetInstructionPendingDeoptimizationEnvironment(
794 LInstruction* instr, int ast_id) { 693 LInstruction* instr, int ast_id) {
795 ASSERT(instructions_pending_deoptimization_environment_ == NULL); 694 ASSERT(instruction_pending_deoptimization_environment_ == NULL);
796 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber); 695 ASSERT(pending_deoptimization_ast_id_ == AstNode::kNoNumber);
797 instructions_pending_deoptimization_environment_ = instr; 696 instruction_pending_deoptimization_environment_ = instr;
798 pending_deoptimization_ast_id_ = ast_id; 697 pending_deoptimization_ast_id_ = ast_id;
799 return instr; 698 return instr;
800 } 699 }
801 700
802 701
803 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() { 702 void LChunkBuilder::ClearInstructionPendingDeoptimizationEnvironment() {
804 instructions_pending_deoptimization_environment_ = NULL; 703 instruction_pending_deoptimization_environment_ = NULL;
805 pending_deoptimization_ast_id_ = AstNode::kNoNumber; 704 pending_deoptimization_ast_id_ = AstNode::kNoNumber;
806 } 705 }
807 706
808 707
809 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, 708 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
810 HInstruction* hinstr, 709 HInstruction* hinstr,
811 CanDeoptimize can_deoptimize) { 710 CanDeoptimize can_deoptimize) {
812 allocator_->MarkAsCall(); 711 #ifdef DEBUG
712 instr->VerifyCall();
713 #endif
714 instr->MarkAsCall();
813 instr = AssignPointerMap(instr); 715 instr = AssignPointerMap(instr);
814 716
815 if (hinstr->HasSideEffects()) { 717 if (hinstr->HasSideEffects()) {
816 ASSERT(hinstr->next()->IsSimulate()); 718 ASSERT(hinstr->next()->IsSimulate());
817 HSimulate* sim = HSimulate::cast(hinstr->next()); 719 HSimulate* sim = HSimulate::cast(hinstr->next());
818 instr = SetInstructionPendingDeoptimizationEnvironment( 720 instr = SetInstructionPendingDeoptimizationEnvironment(
819 instr, sim->ast_id()); 721 instr, sim->ast_id());
820 } 722 }
821 723
822 // If instruction does not have side-effects lazy deoptimization 724 // If instruction does not have side-effects lazy deoptimization
823 // after the call will try to deoptimize to the point before the call. 725 // after the call will try to deoptimize to the point before the call.
824 // Thus we still need to attach environment to this call even if 726 // Thus we still need to attach environment to this call even if
825 // call sequence can not deoptimize eagerly. 727 // call sequence can not deoptimize eagerly.
826 bool needs_environment = 728 bool needs_environment =
827 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); 729 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects();
828 if (needs_environment && !instr->HasEnvironment()) { 730 if (needs_environment && !instr->HasEnvironment()) {
829 instr = AssignEnvironment(instr); 731 instr = AssignEnvironment(instr);
830 } 732 }
831 733
832 return instr; 734 return instr;
833 } 735 }
834 736
835 737
738 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
739 instr->MarkAsSaveDoubles();
740 return instr;
741 }
742
743
836 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { 744 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
837 ASSERT(!instr->HasPointerMap()); 745 ASSERT(!instr->HasPointerMap());
838 instr->set_pointer_map(new LPointerMap(position_)); 746 instr->set_pointer_map(new LPointerMap(position_));
839 return instr; 747 return instr;
840 } 748 }
841 749
842 750
843 LInstruction* LChunkBuilder::Define(LInstruction* instr, LUnallocated* result) {
844 allocator_->RecordDefinition(current_instruction_, result);
845 instr->set_result(result);
846 return instr;
847 }
848
849
850 LOperand* LChunkBuilder::Temp() {
851 LUnallocated* operand = new LUnallocated(LUnallocated::NONE);
852 allocator_->RecordTemporary(operand);
853 return operand;
854 }
855
856
857 LUnallocated* LChunkBuilder::TempRegister() { 751 LUnallocated* LChunkBuilder::TempRegister() {
858 LUnallocated* operand = new LUnallocated(LUnallocated::MUST_HAVE_REGISTER); 752 LUnallocated* operand = new LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
859 allocator_->RecordTemporary(operand); 753 allocator_->RecordTemporary(operand);
860 return operand; 754 return operand;
861 } 755 }
862 756
863 757
864 LOperand* LChunkBuilder::FixedTemp(Register reg) { 758 LOperand* LChunkBuilder::FixedTemp(Register reg) {
865 LUnallocated* operand = ToUnallocated(reg); 759 LUnallocated* operand = ToUnallocated(reg);
866 allocator_->RecordTemporary(operand); 760 allocator_->RecordTemporary(operand);
(...skipping 13 matching lines...) Expand all
880 } 774 }
881 775
882 776
883 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { 777 LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
884 return AssignEnvironment(new LDeoptimize); 778 return AssignEnvironment(new LDeoptimize);
885 } 779 }
886 780
887 781
888 LInstruction* LChunkBuilder::DoBit(Token::Value op, 782 LInstruction* LChunkBuilder::DoBit(Token::Value op,
889 HBitwiseBinaryOperation* instr) { 783 HBitwiseBinaryOperation* instr) {
890 ASSERT(instr->representation().IsInteger32()); 784 if (instr->representation().IsInteger32()) {
891 ASSERT(instr->left()->representation().IsInteger32()); 785 ASSERT(instr->left()->representation().IsInteger32());
892 ASSERT(instr->right()->representation().IsInteger32()); 786 ASSERT(instr->right()->representation().IsInteger32());
893 787
894 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 788 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
895 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); 789 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand());
896 return DefineSameAsFirst(new LBitI(op, left, right)); 790 return DefineSameAsFirst(new LBitI(op, left, right));
791 } else {
792 ASSERT(instr->representation().IsTagged());
793 ASSERT(instr->left()->representation().IsTagged());
794 ASSERT(instr->right()->representation().IsTagged());
795
796 LOperand* left = UseFixed(instr->left(), r1);
797 LOperand* right = UseFixed(instr->right(), r0);
798 LArithmeticT* result = new LArithmeticT(op, left, right);
799 return MarkAsCall(DefineFixed(result, r0), instr);
800 }
897 } 801 }
898 802
899 803
900 LInstruction* LChunkBuilder::DoShift(Token::Value op, 804 LInstruction* LChunkBuilder::DoShift(Token::Value op,
901 HBitwiseBinaryOperation* instr) { 805 HBitwiseBinaryOperation* instr) {
806 if (instr->representation().IsTagged()) {
807 ASSERT(instr->left()->representation().IsTagged());
808 ASSERT(instr->right()->representation().IsTagged());
809
810 LOperand* left = UseFixed(instr->left(), r1);
811 LOperand* right = UseFixed(instr->right(), r0);
812 LArithmeticT* result = new LArithmeticT(op, left, right);
813 return MarkAsCall(DefineFixed(result, r0), instr);
814 }
815
902 ASSERT(instr->representation().IsInteger32()); 816 ASSERT(instr->representation().IsInteger32());
903 ASSERT(instr->OperandAt(0)->representation().IsInteger32()); 817 ASSERT(instr->OperandAt(0)->representation().IsInteger32());
904 ASSERT(instr->OperandAt(1)->representation().IsInteger32()); 818 ASSERT(instr->OperandAt(1)->representation().IsInteger32());
905 LOperand* left = UseRegisterAtStart(instr->OperandAt(0)); 819 LOperand* left = UseRegisterAtStart(instr->OperandAt(0));
906 820
907 HValue* right_value = instr->OperandAt(1); 821 HValue* right_value = instr->OperandAt(1);
908 LOperand* right = NULL; 822 LOperand* right = NULL;
909 int constant_value = 0; 823 int constant_value = 0;
910 if (right_value->IsConstant()) { 824 if (right_value->IsConstant()) {
911 HConstant* constant = HConstant::cast(right_value); 825 HConstant* constant = HConstant::cast(right_value);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 op == Token::DIV || 868 op == Token::DIV ||
955 op == Token::MOD || 869 op == Token::MOD ||
956 op == Token::MUL || 870 op == Token::MUL ||
957 op == Token::SUB); 871 op == Token::SUB);
958 HValue* left = instr->left(); 872 HValue* left = instr->left();
959 HValue* right = instr->right(); 873 HValue* right = instr->right();
960 ASSERT(left->representation().IsTagged()); 874 ASSERT(left->representation().IsTagged());
961 ASSERT(right->representation().IsTagged()); 875 ASSERT(right->representation().IsTagged());
962 LOperand* left_operand = UseFixed(left, r1); 876 LOperand* left_operand = UseFixed(left, r1);
963 LOperand* right_operand = UseFixed(right, r0); 877 LOperand* right_operand = UseFixed(right, r0);
964 LInstruction* result = new LArithmeticT(op, left_operand, right_operand); 878 LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand);
965 return MarkAsCall(DefineFixed(result, r0), instr); 879 return MarkAsCall(DefineFixed(result, r0), instr);
966 } 880 }
967 881
882
968 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { 883 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
969 ASSERT(is_building()); 884 ASSERT(is_building());
970 current_block_ = block; 885 current_block_ = block;
971 next_block_ = next_block; 886 next_block_ = next_block;
972 if (block->IsStartBlock()) { 887 if (block->IsStartBlock()) {
973 block->UpdateEnvironment(graph_->start_environment()); 888 block->UpdateEnvironment(graph_->start_environment());
974 argument_count_ = 0; 889 argument_count_ = 0;
975 } else if (block->predecessors()->length() == 1) { 890 } else if (block->predecessors()->length() == 1) {
976 // We have a single predecessor => copy environment and outgoing 891 // We have a single predecessor => copy environment and outgoing
977 // argument count from the predecessor. 892 // argument count from the predecessor.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1024 } 939 }
1025 block->set_argument_count(argument_count_); 940 block->set_argument_count(argument_count_);
1026 next_block_ = NULL; 941 next_block_ = NULL;
1027 current_block_ = NULL; 942 current_block_ = NULL;
1028 } 943 }
1029 944
1030 945
1031 void LChunkBuilder::VisitInstruction(HInstruction* current) { 946 void LChunkBuilder::VisitInstruction(HInstruction* current) {
1032 HInstruction* old_current = current_instruction_; 947 HInstruction* old_current = current_instruction_;
1033 current_instruction_ = current; 948 current_instruction_ = current;
1034 allocator_->BeginInstruction();
1035 if (current->has_position()) position_ = current->position(); 949 if (current->has_position()) position_ = current->position();
1036 LInstruction* instr = current->CompileToLithium(this); 950 LInstruction* instr = current->CompileToLithium(this);
1037 951
1038 if (instr != NULL) { 952 if (instr != NULL) {
1039 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { 953 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) {
1040 instr = AssignPointerMap(instr); 954 instr = AssignPointerMap(instr);
1041 } 955 }
1042 if (FLAG_stress_environments && !instr->HasEnvironment()) { 956 if (FLAG_stress_environments && !instr->HasEnvironment()) {
1043 instr = AssignEnvironment(instr); 957 instr = AssignEnvironment(instr);
1044 } 958 }
1045 if (current->IsBranch()) { 959 if (current->IsTest() && !instr->IsGoto()) {
1046 instr->set_hydrogen_value(HBranch::cast(current)->value()); 960 ASSERT(instr->IsControl());
961 HTest* test = HTest::cast(current);
962 instr->set_hydrogen_value(test->value());
963 HBasicBlock* first = test->FirstSuccessor();
964 HBasicBlock* second = test->SecondSuccessor();
965 ASSERT(first != NULL && second != NULL);
966 instr->SetBranchTargets(first->block_id(), second->block_id());
1047 } else { 967 } else {
1048 instr->set_hydrogen_value(current); 968 instr->set_hydrogen_value(current);
1049 } 969 }
1050 970
1051 int index = chunk_->AddInstruction(instr, current_block_); 971 chunk_->AddInstruction(instr, current_block_);
1052 allocator_->SummarizeInstruction(index);
1053 } else {
1054 // This instruction should be omitted.
1055 allocator_->OmitInstruction();
1056 } 972 }
1057 current_instruction_ = old_current; 973 current_instruction_ = old_current;
1058 } 974 }
1059 975
1060 976
1061 void LEnvironment::WriteTranslation(LCodeGen* cgen,
1062 Translation* translation) const {
1063 if (this == NULL) return;
1064
1065 // The translation includes one command per value in the environment.
1066 int translation_size = values()->length();
1067 // The output frame height does not include the parameters.
1068 int height = translation_size - parameter_count();
1069
1070 outer()->WriteTranslation(cgen, translation);
1071 int closure_id = cgen->DefineDeoptimizationLiteral(closure());
1072 translation->BeginFrame(ast_id(), closure_id, height);
1073 for (int i = 0; i < translation_size; ++i) {
1074 LOperand* value = values()->at(i);
1075 // spilled_registers_ and spilled_double_registers_ are either
1076 // both NULL or both set.
1077 if (spilled_registers_ != NULL && value != NULL) {
1078 if (value->IsRegister() &&
1079 spilled_registers_[value->index()] != NULL) {
1080 translation->MarkDuplicate();
1081 cgen->AddToTranslation(translation,
1082 spilled_registers_[value->index()],
1083 HasTaggedValueAt(i));
1084 } else if (value->IsDoubleRegister() &&
1085 spilled_double_registers_[value->index()] != NULL) {
1086 translation->MarkDuplicate();
1087 cgen->AddToTranslation(translation,
1088 spilled_double_registers_[value->index()],
1089 false);
1090 }
1091 }
1092
1093 cgen->AddToTranslation(translation, value, HasTaggedValueAt(i));
1094 }
1095 }
1096
1097
1098 void LEnvironment::PrintTo(StringStream* stream) const {
1099 stream->Add("[id=%d|", ast_id());
1100 stream->Add("[parameters=%d|", parameter_count());
1101 stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
1102 for (int i = 0; i < values_.length(); ++i) {
1103 if (i != 0) stream->Add(";");
1104 if (values_[i] == NULL) {
1105 stream->Add("[hole]");
1106 } else {
1107 values_[i]->PrintTo(stream);
1108 }
1109 }
1110 stream->Add("]");
1111 }
1112
1113
1114 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { 977 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
1115 if (hydrogen_env == NULL) return NULL; 978 if (hydrogen_env == NULL) return NULL;
1116 979
1117 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); 980 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
1118 int ast_id = hydrogen_env->ast_id(); 981 int ast_id = hydrogen_env->ast_id();
1119 ASSERT(ast_id != AstNode::kNoNumber); 982 ASSERT(ast_id != AstNode::kNoNumber);
1120 int value_count = hydrogen_env->length(); 983 int value_count = hydrogen_env->length();
1121 LEnvironment* result = new LEnvironment(hydrogen_env->closure(), 984 LEnvironment* result = new LEnvironment(hydrogen_env->closure(),
1122 ast_id, 985 ast_id,
1123 hydrogen_env->parameter_count(), 986 hydrogen_env->parameter_count(),
1124 argument_count_, 987 argument_count_,
1125 value_count, 988 value_count,
1126 outer); 989 outer);
1127 int argument_index = 0; 990 int argument_index = 0;
1128 for (int i = 0; i < value_count; ++i) { 991 for (int i = 0; i < value_count; ++i) {
1129 HValue* value = hydrogen_env->values()->at(i); 992 HValue* value = hydrogen_env->values()->at(i);
1130 LOperand* op = NULL; 993 LOperand* op = NULL;
1131 if (value->IsArgumentsObject()) { 994 if (value->IsArgumentsObject()) {
1132 op = NULL; 995 op = NULL;
1133 } else if (value->IsPushArgument()) { 996 } else if (value->IsPushArgument()) {
1134 op = new LArgument(argument_index++); 997 op = new LArgument(argument_index++);
1135 } else { 998 } else {
1136 op = UseOrConstant(value); 999 op = UseAny(value);
1137 if (op->IsUnallocated()) {
1138 LUnallocated* unalloc = LUnallocated::cast(op);
1139 unalloc->set_policy(LUnallocated::ANY);
1140 }
1141 } 1000 }
1142 result->AddValue(op, value->representation()); 1001 result->AddValue(op, value->representation());
1143 } 1002 }
1144 1003
1145 return result; 1004 return result;
1146 } 1005 }
1147 1006
1148 1007
1149 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 1008 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1150 LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(), 1009 LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(),
1151 instr->include_stack_check()); 1010 instr->include_stack_check());
1152 if (instr->include_stack_check()) result = AssignPointerMap(result); 1011 if (instr->include_stack_check()) result = AssignPointerMap(result);
1153 return result; 1012 return result;
1154 } 1013 }
1155 1014
1156 1015
1157 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { 1016 LInstruction* LChunkBuilder::DoTest(HTest* instr) {
1158 HValue* v = instr->value(); 1017 HValue* v = instr->value();
1159 HBasicBlock* first = instr->FirstSuccessor();
1160 HBasicBlock* second = instr->SecondSuccessor();
1161 ASSERT(first != NULL && second != NULL);
1162 int first_id = first->block_id();
1163 int second_id = second->block_id();
1164
1165 if (v->EmitAtUses()) { 1018 if (v->EmitAtUses()) {
1166 if (v->IsClassOfTest()) { 1019 if (v->IsClassOfTest()) {
1167 HClassOfTest* compare = HClassOfTest::cast(v); 1020 HClassOfTest* compare = HClassOfTest::cast(v);
1168 ASSERT(compare->value()->representation().IsTagged()); 1021 ASSERT(compare->value()->representation().IsTagged());
1169 1022
1170 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), 1023 return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
1171 TempRegister(), 1024 TempRegister());
1172 TempRegister(),
1173 first_id,
1174 second_id);
1175 } else if (v->IsCompare()) { 1025 } else if (v->IsCompare()) {
1176 HCompare* compare = HCompare::cast(v); 1026 HCompare* compare = HCompare::cast(v);
1177 Token::Value op = compare->token(); 1027 Token::Value op = compare->token();
1178 HValue* left = compare->left(); 1028 HValue* left = compare->left();
1179 HValue* right = compare->right(); 1029 HValue* right = compare->right();
1180 if (left->representation().IsInteger32()) { 1030 Representation r = compare->GetInputRepresentation();
1031 if (r.IsInteger32()) {
1032 ASSERT(left->representation().IsInteger32());
1181 ASSERT(right->representation().IsInteger32()); 1033 ASSERT(right->representation().IsInteger32());
1182 return new LCmpIDAndBranch(op, 1034 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1183 UseRegisterAtStart(left), 1035 UseRegisterAtStart(right));
1184 UseOrConstantAtStart(right), 1036 } else if (r.IsDouble()) {
1185 first_id, 1037 ASSERT(left->representation().IsDouble());
1186 second_id,
1187 false);
1188 } else if (left->representation().IsDouble()) {
1189 ASSERT(right->representation().IsDouble()); 1038 ASSERT(right->representation().IsDouble());
1190 return new LCmpIDAndBranch(op, 1039 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1191 UseRegisterAtStart(left), 1040 UseRegisterAtStart(right));
1192 UseRegisterAtStart(right),
1193 first_id,
1194 second_id,
1195 true);
1196 } else { 1041 } else {
1197 ASSERT(left->representation().IsTagged()); 1042 ASSERT(left->representation().IsTagged());
1198 ASSERT(right->representation().IsTagged()); 1043 ASSERT(right->representation().IsTagged());
1199 bool reversed = op == Token::GT || op == Token::LTE; 1044 bool reversed = op == Token::GT || op == Token::LTE;
1200 LOperand* left_operand = UseFixed(left, reversed ? r0 : r1); 1045 LOperand* left_operand = UseFixed(left, reversed ? r0 : r1);
1201 LOperand* right_operand = UseFixed(right, reversed ? r1 : r0); 1046 LOperand* right_operand = UseFixed(right, reversed ? r1 : r0);
1202 LInstruction* result = new LCmpTAndBranch(left_operand, 1047 LInstruction* result = new LCmpTAndBranch(left_operand,
1203 right_operand, 1048 right_operand);
1204 first_id,
1205 second_id);
1206 return MarkAsCall(result, instr); 1049 return MarkAsCall(result, instr);
1207 } 1050 }
1208 } else if (v->IsIsSmi()) { 1051 } else if (v->IsIsSmi()) {
1209 HIsSmi* compare = HIsSmi::cast(v); 1052 HIsSmi* compare = HIsSmi::cast(v);
1210 ASSERT(compare->value()->representation().IsTagged()); 1053 ASSERT(compare->value()->representation().IsTagged());
1211 1054
1212 return new LIsSmiAndBranch(Use(compare->value()), 1055 return new LIsSmiAndBranch(Use(compare->value()));
1213 first_id,
1214 second_id);
1215 } else if (v->IsHasInstanceType()) { 1056 } else if (v->IsHasInstanceType()) {
1216 HHasInstanceType* compare = HHasInstanceType::cast(v); 1057 HHasInstanceType* compare = HHasInstanceType::cast(v);
1217 ASSERT(compare->value()->representation().IsTagged()); 1058 ASSERT(compare->value()->representation().IsTagged());
1218 1059 return new LHasInstanceTypeAndBranch(
1219 return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()), 1060 UseRegisterAtStart(compare->value()));
1220 first_id,
1221 second_id);
1222 } else if (v->IsHasCachedArrayIndex()) { 1061 } else if (v->IsHasCachedArrayIndex()) {
1223 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v); 1062 HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v);
1224 ASSERT(compare->value()->representation().IsTagged()); 1063 ASSERT(compare->value()->representation().IsTagged());
1225 1064
1226 return new LHasCachedArrayIndexAndBranch( 1065 return new LHasCachedArrayIndexAndBranch(
1227 UseRegisterAtStart(compare->value()), first_id, second_id); 1066 UseRegisterAtStart(compare->value()));
1228 } else if (v->IsIsNull()) { 1067 } else if (v->IsIsNull()) {
1229 HIsNull* compare = HIsNull::cast(v); 1068 HIsNull* compare = HIsNull::cast(v);
1230 ASSERT(compare->value()->representation().IsTagged()); 1069 ASSERT(compare->value()->representation().IsTagged());
1231 1070
1232 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), 1071 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()));
1233 compare->is_strict(),
1234 first_id,
1235 second_id);
1236 } else if (v->IsIsObject()) { 1072 } else if (v->IsIsObject()) {
1237 HIsObject* compare = HIsObject::cast(v); 1073 HIsObject* compare = HIsObject::cast(v);
1238 ASSERT(compare->value()->representation().IsTagged()); 1074 ASSERT(compare->value()->representation().IsTagged());
1239 1075
1240 LOperand* temp1 = TempRegister(); 1076 LOperand* temp = TempRegister();
1241 LOperand* temp2 = TempRegister(); 1077 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp);
1242 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()),
1243 temp1,
1244 temp2,
1245 first_id,
1246 second_id);
1247 } else if (v->IsCompareJSObjectEq()) { 1078 } else if (v->IsCompareJSObjectEq()) {
1248 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); 1079 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1249 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), 1080 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1250 UseRegisterAtStart(compare->right()), 1081 UseRegisterAtStart(compare->right()));
1251 first_id,
1252 second_id);
1253 } else if (v->IsInstanceOf()) { 1082 } else if (v->IsInstanceOf()) {
1254 HInstanceOf* instance_of = HInstanceOf::cast(v); 1083 HInstanceOf* instance_of = HInstanceOf::cast(v);
1255 LInstruction* result = 1084 LInstruction* result =
1256 new LInstanceOfAndBranch(Use(instance_of->left()), 1085 new LInstanceOfAndBranch(UseFixed(instance_of->left(), r0),
1257 Use(instance_of->right()), 1086 UseFixed(instance_of->right(), r1));
1258 first_id,
1259 second_id);
1260 return MarkAsCall(result, instr); 1087 return MarkAsCall(result, instr);
1261 } else if (v->IsTypeofIs()) { 1088 } else if (v->IsTypeofIs()) {
1262 HTypeofIs* typeof_is = HTypeofIs::cast(v); 1089 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1263 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), 1090 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()));
1264 first_id, 1091 } else if (v->IsIsConstructCall()) {
1265 second_id); 1092 return new LIsConstructCallAndBranch(TempRegister());
1266 } else { 1093 } else {
1267 if (v->IsConstant()) { 1094 if (v->IsConstant()) {
1268 if (HConstant::cast(v)->handle()->IsTrue()) { 1095 if (HConstant::cast(v)->handle()->IsTrue()) {
1269 return new LGoto(first_id); 1096 return new LGoto(instr->FirstSuccessor()->block_id());
1270 } else if (HConstant::cast(v)->handle()->IsFalse()) { 1097 } else if (HConstant::cast(v)->handle()->IsFalse()) {
1271 return new LGoto(second_id); 1098 return new LGoto(instr->SecondSuccessor()->block_id());
1272 } 1099 }
1273 } 1100 }
1274 Abort("Undefined compare before branch"); 1101 Abort("Undefined compare before branch");
1275 return NULL; 1102 return NULL;
1276 } 1103 }
1277 } 1104 }
1278 return new LBranch(UseRegisterAtStart(v), first_id, second_id); 1105 return new LBranch(UseRegisterAtStart(v));
1279 } 1106 }
1280 1107
1281 1108
1282 LInstruction* LChunkBuilder::DoCompareMapAndBranch( 1109 LInstruction* LChunkBuilder::DoCompareMap(HCompareMap* instr) {
1283 HCompareMapAndBranch* instr) {
1284 ASSERT(instr->value()->representation().IsTagged()); 1110 ASSERT(instr->value()->representation().IsTagged());
1285 LOperand* value = UseRegisterAtStart(instr->value()); 1111 LOperand* value = UseRegisterAtStart(instr->value());
1286 LOperand* temp = TempRegister(); 1112 LOperand* temp = TempRegister();
1287 return new LCmpMapAndBranch(value, temp); 1113 return new LCmpMapAndBranch(value, temp);
1288 } 1114 }
1289 1115
1290 1116
1291 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { 1117 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
1292 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); 1118 return DefineAsRegister(new LArgumentsLength(UseRegister(length->value())));
1293 } 1119 }
1294 1120
1295 1121
1296 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { 1122 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
1297 return DefineAsRegister(new LArgumentsElements); 1123 return DefineAsRegister(new LArgumentsElements);
1298 } 1124 }
1299 1125
1300 1126
1301 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { 1127 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1302 LInstruction* result = 1128 LInstanceOf* result =
1303 new LInstanceOf(UseFixed(instr->left(), r0), 1129 new LInstanceOf(UseFixed(instr->left(), r0),
1304 UseFixed(instr->right(), r1)); 1130 UseFixed(instr->right(), r1));
1305 return MarkAsCall(DefineFixed(result, r0), instr); 1131 return MarkAsCall(DefineFixed(result, r0), instr);
1306 } 1132 }
1307 1133
1308 1134
1135 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1136 HInstanceOfKnownGlobal* instr) {
1137 LInstanceOfKnownGlobal* result =
1138 new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0), FixedTemp(r4));
1139 MarkAsSaveDoubles(result);
1140 return AssignEnvironment(AssignPointerMap(DefineFixed(result, r0)));
1141 }
1142
1143
1309 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1144 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1310 LOperand* function = UseFixed(instr->function(), r1); 1145 LOperand* function = UseFixed(instr->function(), r1);
1311 LOperand* receiver = UseFixed(instr->receiver(), r0); 1146 LOperand* receiver = UseFixed(instr->receiver(), r0);
1312 LOperand* length = UseRegisterAtStart(instr->length()); 1147 LOperand* length = UseFixed(instr->length(), r2);
1313 LOperand* elements = UseRegisterAtStart(instr->elements()); 1148 LOperand* elements = UseFixed(instr->elements(), r3);
1314 LInstruction* result = new LApplyArguments(function, 1149 LApplyArguments* result = new LApplyArguments(function,
1315 receiver, 1150 receiver,
1316 length, 1151 length,
1317 elements); 1152 elements);
1318 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 1153 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
1319 } 1154 }
1320 1155
1321 1156
1322 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1157 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1323 ++argument_count_; 1158 ++argument_count_;
1324 LOperand* argument = Use(instr->argument()); 1159 LOperand* argument = Use(instr->argument());
1325 return new LPushArgument(argument); 1160 return new LPushArgument(argument);
1326 } 1161 }
1327 1162
1328 1163
1164 LInstruction* LChunkBuilder::DoContext(HContext* instr) {
1165 return DefineAsRegister(new LContext);
1166 }
1167
1168
1169 LInstruction* LChunkBuilder::DoOuterContext(HOuterContext* instr) {
1170 LOperand* context = UseRegisterAtStart(instr->value());
1171 return DefineAsRegister(new LOuterContext(context));
1172 }
1173
1174
1329 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) { 1175 LInstruction* LChunkBuilder::DoGlobalObject(HGlobalObject* instr) {
1330 return DefineAsRegister(new LGlobalObject); 1176 LOperand* context = UseRegisterAtStart(instr->value());
1177 return DefineAsRegister(new LGlobalObject(context));
1331 } 1178 }
1332 1179
1333 1180
1334 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) { 1181 LInstruction* LChunkBuilder::DoGlobalReceiver(HGlobalReceiver* instr) {
1335 return DefineAsRegister(new LGlobalReceiver); 1182 LOperand* global_object = UseRegisterAtStart(instr->value());
1183 return DefineAsRegister(new LGlobalReceiver(global_object));
1336 } 1184 }
1337 1185
1338 1186
1339 LInstruction* LChunkBuilder::DoCallConstantFunction( 1187 LInstruction* LChunkBuilder::DoCallConstantFunction(
1340 HCallConstantFunction* instr) { 1188 HCallConstantFunction* instr) {
1341 argument_count_ -= instr->argument_count(); 1189 argument_count_ -= instr->argument_count();
1342 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr); 1190 return MarkAsCall(DefineFixed(new LCallConstantFunction, r0), instr);
1343 } 1191 }
1344 1192
1345 1193
1346 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1194 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1347 BuiltinFunctionId op = instr->op(); 1195 BuiltinFunctionId op = instr->op();
1348 LOperand* input = UseRegisterAtStart(instr->value()); 1196 LOperand* input = UseRegisterAtStart(instr->value());
1349 LInstruction* result = new LUnaryMathOperation(input); 1197 LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
1198 LUnaryMathOperation* result = new LUnaryMathOperation(input, temp);
1350 switch (op) { 1199 switch (op) {
1351 case kMathAbs: 1200 case kMathAbs:
1352 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1201 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1353 case kMathFloor: 1202 case kMathFloor:
1354 return AssignEnvironment(DefineAsRegister(result)); 1203 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1355 case kMathSqrt: 1204 case kMathSqrt:
1356 return DefineSameAsFirst(result); 1205 return DefineSameAsFirst(result);
1357 case kMathRound: 1206 case kMathRound:
1358 Abort("MathRound LUnaryMathOperation not implemented"); 1207 Abort("MathRound LUnaryMathOperation not implemented");
1359 return NULL; 1208 return NULL;
1360 case kMathPowHalf: 1209 case kMathPowHalf:
1361 Abort("MathPowHalf LUnaryMathOperation not implemented"); 1210 Abort("MathPowHalf LUnaryMathOperation not implemented");
1362 return NULL; 1211 return NULL;
1363 case kMathLog: 1212 case kMathLog:
1364 Abort("MathLog LUnaryMathOperation not implemented"); 1213 Abort("MathLog LUnaryMathOperation not implemented");
1365 return NULL; 1214 return NULL;
1366 case kMathCos: 1215 case kMathCos:
1367 Abort("MathCos LUnaryMathOperation not implemented"); 1216 Abort("MathCos LUnaryMathOperation not implemented");
1368 return NULL; 1217 return NULL;
1369 case kMathSin: 1218 case kMathSin:
1370 Abort("MathSin LUnaryMathOperation not implemented"); 1219 Abort("MathSin LUnaryMathOperation not implemented");
1371 return NULL; 1220 return NULL;
1372 default: 1221 default:
1373 UNREACHABLE(); 1222 UNREACHABLE();
1374 return NULL; 1223 return NULL;
1375 } 1224 }
1376 } 1225 }
1377 1226
1378 1227
1379 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { 1228 LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) {
1380 ASSERT(instr->key()->representation().IsTagged()); 1229 ASSERT(instr->key()->representation().IsTagged());
1381 argument_count_ -= instr->argument_count(); 1230 argument_count_ -= instr->argument_count();
1382 UseFixed(instr->key(), r2); 1231 LOperand* key = UseFixed(instr->key(), r2);
1383 return MarkAsCall(DefineFixed(new LCallKeyed, r0), instr); 1232 return MarkAsCall(DefineFixed(new LCallKeyed(key), r0), instr);
1384 } 1233 }
1385 1234
1386 1235
1387 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) { 1236 LInstruction* LChunkBuilder::DoCallNamed(HCallNamed* instr) {
1388 argument_count_ -= instr->argument_count(); 1237 argument_count_ -= instr->argument_count();
1389 return MarkAsCall(DefineFixed(new LCallNamed, r0), instr); 1238 return MarkAsCall(DefineFixed(new LCallNamed, r0), instr);
1390 } 1239 }
1391 1240
1392 1241
1393 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) { 1242 LInstruction* LChunkBuilder::DoCallGlobal(HCallGlobal* instr) {
1394 argument_count_ -= instr->argument_count(); 1243 argument_count_ -= instr->argument_count();
1395 return MarkAsCall(DefineFixed(new LCallGlobal, r0), instr); 1244 return MarkAsCall(DefineFixed(new LCallGlobal, r0), instr);
1396 } 1245 }
1397 1246
1398 1247
1399 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { 1248 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
1400 argument_count_ -= instr->argument_count(); 1249 argument_count_ -= instr->argument_count();
1401 return MarkAsCall(DefineFixed(new LCallKnownGlobal, r0), instr); 1250 return MarkAsCall(DefineFixed(new LCallKnownGlobal, r0), instr);
1402 } 1251 }
1403 1252
1404 1253
1405 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { 1254 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1406 LOperand* constructor = UseFixed(instr->constructor(), r1); 1255 LOperand* constructor = UseFixed(instr->constructor(), r1);
1407 argument_count_ -= instr->argument_count(); 1256 argument_count_ -= instr->argument_count();
1408 LInstruction* result = new LCallNew(constructor); 1257 LCallNew* result = new LCallNew(constructor);
1409 return MarkAsCall(DefineFixed(result, r0), instr); 1258 return MarkAsCall(DefineFixed(result, r0), instr);
1410 } 1259 }
1411 1260
1412 1261
1413 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { 1262 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1414 argument_count_ -= instr->argument_count(); 1263 argument_count_ -= instr->argument_count();
1415 return MarkAsCall(DefineFixed(new LCallFunction, r0), instr); 1264 return MarkAsCall(DefineFixed(new LCallFunction, r0), instr);
1416 } 1265 }
1417 1266
1418 1267
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 1305
1457 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) { 1306 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) {
1458 return DoBit(Token::BIT_XOR, instr); 1307 return DoBit(Token::BIT_XOR, instr);
1459 } 1308 }
1460 1309
1461 1310
1462 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { 1311 LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
1463 if (instr->representation().IsDouble()) { 1312 if (instr->representation().IsDouble()) {
1464 return DoArithmeticD(Token::DIV, instr); 1313 return DoArithmeticD(Token::DIV, instr);
1465 } else if (instr->representation().IsInteger32()) { 1314 } else if (instr->representation().IsInteger32()) {
1466 // The temporary operand is necessary to ensure that right is not allocated 1315 // TODO(1042) The fixed register allocation
1467 // into edx. 1316 // is needed because we call GenericBinaryOpStub from
1468 FixedTemp(r1); 1317 // the generated code, which requires registers r0
1469 LOperand* value = UseFixed(instr->left(), r0); 1318 // and r1 to be used. We should remove that
1470 LOperand* divisor = UseRegister(instr->right()); 1319 // when we provide a native implementation.
1471 return AssignEnvironment(DefineFixed(new LDivI(value, divisor), r0)); 1320 LOperand* dividend = UseFixed(instr->left(), r0);
1321 LOperand* divisor = UseFixed(instr->right(), r1);
1322 return AssignEnvironment(AssignPointerMap(
1323 DefineFixed(new LDivI(dividend, divisor), r0)));
1472 } else { 1324 } else {
1473 return DoArithmeticT(Token::DIV, instr); 1325 return DoArithmeticT(Token::DIV, instr);
1474 } 1326 }
1475 } 1327 }
1476 1328
1477 1329
1478 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1330 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1479 if (instr->representation().IsInteger32()) { 1331 if (instr->representation().IsInteger32()) {
1332 // TODO(1042) The fixed register allocation
1333 // is needed because we call GenericBinaryOpStub from
1334 // the generated code, which requires registers r0
1335 // and r1 to be used. We should remove that
1336 // when we provide a native implementation.
1480 ASSERT(instr->left()->representation().IsInteger32()); 1337 ASSERT(instr->left()->representation().IsInteger32());
1481 ASSERT(instr->right()->representation().IsInteger32()); 1338 ASSERT(instr->right()->representation().IsInteger32());
1482 // The temporary operand is necessary to ensure that right is not allocated
1483 // into edx.
1484 FixedTemp(r1);
1485 LOperand* value = UseFixed(instr->left(), r0); 1339 LOperand* value = UseFixed(instr->left(), r0);
1486 LOperand* divisor = UseRegister(instr->right()); 1340 LOperand* divisor = UseFixed(instr->right(), r1);
1487 LInstruction* result = DefineFixed(new LModI(value, divisor), r1); 1341 LInstruction* result = DefineFixed(new LModI(value, divisor), r0);
1488 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) || 1342 result = AssignEnvironment(AssignPointerMap(result));
1489 instr->CheckFlag(HValue::kCanBeDivByZero)) {
1490 result = AssignEnvironment(result);
1491 }
1492 return result; 1343 return result;
1493 } else if (instr->representation().IsTagged()) { 1344 } else if (instr->representation().IsTagged()) {
1494 return DoArithmeticT(Token::MOD, instr); 1345 return DoArithmeticT(Token::MOD, instr);
1495 } else { 1346 } else {
1496 ASSERT(instr->representation().IsDouble()); 1347 ASSERT(instr->representation().IsDouble());
1497 // We call a C function for double modulo. It can't trigger a GC. 1348 // We call a C function for double modulo. It can't trigger a GC.
1498 // We need to use fixed result register for the call. 1349 // We need to use fixed result register for the call.
1499 // TODO(fschneider): Allow any register as input registers. 1350 // TODO(fschneider): Allow any register as input registers.
1500 LOperand* left = UseFixedDouble(instr->left(), d1); 1351 LOperand* left = UseFixedDouble(instr->left(), d1);
1501 LOperand* right = UseFixedDouble(instr->right(), d2); 1352 LOperand* right = UseFixedDouble(instr->right(), d2);
(...skipping 20 matching lines...) Expand all
1522 } else { 1373 } else {
1523 return DoArithmeticT(Token::MUL, instr); 1374 return DoArithmeticT(Token::MUL, instr);
1524 } 1375 }
1525 } 1376 }
1526 1377
1527 1378
1528 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 1379 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1529 if (instr->representation().IsInteger32()) { 1380 if (instr->representation().IsInteger32()) {
1530 ASSERT(instr->left()->representation().IsInteger32()); 1381 ASSERT(instr->left()->representation().IsInteger32());
1531 ASSERT(instr->right()->representation().IsInteger32()); 1382 ASSERT(instr->right()->representation().IsInteger32());
1532 LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand()); 1383 LOperand* left = UseRegisterAtStart(instr->left());
1533 LOperand* right = UseOrConstantAtStart(instr->MostConstantOperand()); 1384 LOperand* right = UseOrConstantAtStart(instr->right());
1534 LSubI* sub = new LSubI(left, right); 1385 LSubI* sub = new LSubI(left, right);
1535 LInstruction* result = DefineSameAsFirst(sub); 1386 LInstruction* result = DefineSameAsFirst(sub);
1536 if (instr->CheckFlag(HValue::kCanOverflow)) { 1387 if (instr->CheckFlag(HValue::kCanOverflow)) {
1537 result = AssignEnvironment(result); 1388 result = AssignEnvironment(result);
1538 } 1389 }
1539 return result; 1390 return result;
1540 } else if (instr->representation().IsDouble()) { 1391 } else if (instr->representation().IsDouble()) {
1541 return DoArithmeticD(Token::SUB, instr); 1392 return DoArithmeticD(Token::SUB, instr);
1542 } else { 1393 } else {
1543 return DoArithmeticT(Token::SUB, instr); 1394 return DoArithmeticT(Token::SUB, instr);
(...skipping 23 matching lines...) Expand all
1567 1418
1568 1419
1569 LInstruction* LChunkBuilder::DoPower(HPower* instr) { 1420 LInstruction* LChunkBuilder::DoPower(HPower* instr) {
1570 Abort("LPower instruction not implemented on ARM"); 1421 Abort("LPower instruction not implemented on ARM");
1571 return NULL; 1422 return NULL;
1572 } 1423 }
1573 1424
1574 1425
1575 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { 1426 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
1576 Token::Value op = instr->token(); 1427 Token::Value op = instr->token();
1577 if (instr->left()->representation().IsInteger32()) { 1428 Representation r = instr->GetInputRepresentation();
1429 if (r.IsInteger32()) {
1430 ASSERT(instr->left()->representation().IsInteger32());
1578 ASSERT(instr->right()->representation().IsInteger32()); 1431 ASSERT(instr->right()->representation().IsInteger32());
1579 LOperand* left = UseRegisterAtStart(instr->left()); 1432 LOperand* left = UseRegisterAtStart(instr->left());
1580 LOperand* right = UseOrConstantAtStart(instr->right()); 1433 LOperand* right = UseRegisterAtStart(instr->right());
1581 return DefineAsRegister(new LCmpID(op, left, right, false)); 1434 return DefineAsRegister(new LCmpID(left, right));
1582 } else if (instr->left()->representation().IsDouble()) { 1435 } else if (r.IsDouble()) {
1436 ASSERT(instr->left()->representation().IsDouble());
1583 ASSERT(instr->right()->representation().IsDouble()); 1437 ASSERT(instr->right()->representation().IsDouble());
1584 LOperand* left = UseRegisterAtStart(instr->left()); 1438 LOperand* left = UseRegisterAtStart(instr->left());
1585 LOperand* right = UseRegisterAtStart(instr->right()); 1439 LOperand* right = UseRegisterAtStart(instr->right());
1586 return DefineAsRegister(new LCmpID(op, left, right, true)); 1440 return DefineAsRegister(new LCmpID(left, right));
1587 } else { 1441 } else {
1442 ASSERT(instr->left()->representation().IsTagged());
1443 ASSERT(instr->right()->representation().IsTagged());
1588 bool reversed = (op == Token::GT || op == Token::LTE); 1444 bool reversed = (op == Token::GT || op == Token::LTE);
1589 LOperand* left = UseFixed(instr->left(), reversed ? r0 : r1); 1445 LOperand* left = UseFixed(instr->left(), reversed ? r0 : r1);
1590 LOperand* right = UseFixed(instr->right(), reversed ? r1 : r0); 1446 LOperand* right = UseFixed(instr->right(), reversed ? r1 : r0);
1591 LInstruction* result = new LCmpT(left, right); 1447 LCmpT* result = new LCmpT(left, right);
1592 return MarkAsCall(DefineFixed(result, r0), instr); 1448 return MarkAsCall(DefineFixed(result, r0), instr);
1593 } 1449 }
1594 } 1450 }
1595 1451
1596 1452
1597 LInstruction* LChunkBuilder::DoCompareJSObjectEq( 1453 LInstruction* LChunkBuilder::DoCompareJSObjectEq(
1598 HCompareJSObjectEq* instr) { 1454 HCompareJSObjectEq* instr) {
1599 LOperand* left = UseRegisterAtStart(instr->left()); 1455 LOperand* left = UseRegisterAtStart(instr->left());
1600 LOperand* right = UseRegisterAtStart(instr->right()); 1456 LOperand* right = UseRegisterAtStart(instr->right());
1601 LInstruction* result = new LCmpJSObjectEq(left, right); 1457 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right);
1602 return DefineAsRegister(result); 1458 return DefineAsRegister(result);
1603 } 1459 }
1604 1460
1605 1461
1606 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { 1462 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) {
1607 ASSERT(instr->value()->representation().IsTagged()); 1463 ASSERT(instr->value()->representation().IsTagged());
1608 LOperand* value = UseRegisterAtStart(instr->value()); 1464 LOperand* value = UseRegisterAtStart(instr->value());
1609 1465
1610 return DefineAsRegister(new LIsNull(value, 1466 return DefineAsRegister(new LIsNull(value));
1611 instr->is_strict()));
1612 } 1467 }
1613 1468
1614 1469
1615 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { 1470 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) {
1616 ASSERT(instr->value()->representation().IsTagged()); 1471 ASSERT(instr->value()->representation().IsTagged());
1617 LOperand* value = UseRegisterAtStart(instr->value()); 1472 LOperand* value = UseRegisterAtStart(instr->value());
1618 1473
1619 return DefineAsRegister(new LIsObject(value, TempRegister())); 1474 return DefineAsRegister(new LIsObject(value));
1620 } 1475 }
1621 1476
1622 1477
1623 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) { 1478 LInstruction* LChunkBuilder::DoIsSmi(HIsSmi* instr) {
1624 ASSERT(instr->value()->representation().IsTagged()); 1479 ASSERT(instr->value()->representation().IsTagged());
1625 LOperand* value = UseAtStart(instr->value()); 1480 LOperand* value = UseAtStart(instr->value());
1626 1481
1627 return DefineAsRegister(new LIsSmi(value)); 1482 return DefineAsRegister(new LIsSmi(value));
1628 } 1483 }
1629 1484
(...skipping 11 matching lines...) Expand all
1641 ASSERT(instr->value()->representation().IsTagged()); 1496 ASSERT(instr->value()->representation().IsTagged());
1642 LOperand* value = UseRegister(instr->value()); 1497 LOperand* value = UseRegister(instr->value());
1643 1498
1644 return DefineAsRegister(new LHasCachedArrayIndex(value)); 1499 return DefineAsRegister(new LHasCachedArrayIndex(value));
1645 } 1500 }
1646 1501
1647 1502
1648 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { 1503 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
1649 ASSERT(instr->value()->representation().IsTagged()); 1504 ASSERT(instr->value()->representation().IsTagged());
1650 LOperand* value = UseTempRegister(instr->value()); 1505 LOperand* value = UseTempRegister(instr->value());
1651 1506 return DefineSameAsFirst(new LClassOfTest(value));
1652 return DefineSameAsFirst(new LClassOfTest(value, TempRegister()));
1653 } 1507 }
1654 1508
1655 1509
1656 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) { 1510 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1657 LOperand* array = UseRegisterAtStart(instr->value()); 1511 LOperand* array = UseRegisterAtStart(instr->value());
1658 return DefineAsRegister(new LJSArrayLength(array)); 1512 return DefineAsRegister(new LJSArrayLength(array));
1659 } 1513 }
1660 1514
1661 1515
1516 LInstruction* LChunkBuilder::DoPixelArrayLength(HPixelArrayLength* instr) {
1517 LOperand* array = UseRegisterAtStart(instr->value());
1518 return DefineAsRegister(new LPixelArrayLength(array));
1519 }
1520
1521
1662 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) { 1522 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1663 LOperand* array = UseRegisterAtStart(instr->value()); 1523 LOperand* array = UseRegisterAtStart(instr->value());
1664 return DefineAsRegister(new LFixedArrayLength(array)); 1524 return DefineAsRegister(new LFixedArrayLength(array));
1665 } 1525 }
1666 1526
1667 1527
1668 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1528 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1669 LOperand* object = UseRegister(instr->value()); 1529 LOperand* object = UseRegister(instr->value());
1670 LInstruction* result = new LValueOf(object, TempRegister()); 1530 LValueOf* result = new LValueOf(object, TempRegister());
1671 return AssignEnvironment(DefineSameAsFirst(result)); 1531 return AssignEnvironment(DefineSameAsFirst(result));
1672 } 1532 }
1673 1533
1674 1534
1675 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1535 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1676 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1536 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1677 Use(instr->length()))); 1537 UseRegister(instr->length())));
1538 }
1539
1540
1541 LInstruction* LChunkBuilder::DoAbnormalExit(HAbnormalExit* instr) {
1542 // The control instruction marking the end of a block that completed
1543 // abruptly (e.g., threw an exception). There is nothing specific to do.
1544 return NULL;
1678 } 1545 }
1679 1546
1680 1547
1681 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1548 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1682 LOperand* value = UseFixed(instr->value(), r0); 1549 LOperand* value = UseFixed(instr->value(), r0);
1683 return MarkAsCall(new LThrow(value), instr); 1550 return MarkAsCall(new LThrow(value), instr);
1684 } 1551 }
1685 1552
1686 1553
1687 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1554 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1688 Representation from = instr->from(); 1555 Representation from = instr->from();
1689 Representation to = instr->to(); 1556 Representation to = instr->to();
1690 if (from.IsTagged()) { 1557 if (from.IsTagged()) {
1691 if (to.IsDouble()) { 1558 if (to.IsDouble()) {
1692 LOperand* value = UseRegister(instr->value()); 1559 LOperand* value = UseRegister(instr->value());
1693 LInstruction* res = new LNumberUntagD(value); 1560 LNumberUntagD* res = new LNumberUntagD(value);
1694 return AssignEnvironment(DefineAsRegister(res)); 1561 return AssignEnvironment(DefineAsRegister(res));
1695 } else { 1562 } else {
1696 ASSERT(to.IsInteger32()); 1563 ASSERT(to.IsInteger32());
1697 LOperand* value = UseRegister(instr->value()); 1564 LOperand* value = UseRegister(instr->value());
1698 bool needs_check = !instr->value()->type().IsSmi(); 1565 bool needs_check = !instr->value()->type().IsSmi();
1699 LInstruction* res = NULL; 1566 LInstruction* res = NULL;
1700 if (needs_check) { 1567 if (needs_check) {
1701 res = DefineSameAsFirst(new LTaggedToI(value, FixedTemp(d1))); 1568 res = DefineSameAsFirst(new LTaggedToI(value, FixedTemp(d1)));
1702 } else { 1569 } else {
1703 res = DefineSameAsFirst(new LSmiUntag(value, needs_check)); 1570 res = DefineSameAsFirst(new LSmiUntag(value, needs_check));
1704 } 1571 }
1705 if (needs_check) { 1572 if (needs_check) {
1706 res = AssignEnvironment(res); 1573 res = AssignEnvironment(res);
1707 } 1574 }
1708 return res; 1575 return res;
1709 } 1576 }
1710 } else if (from.IsDouble()) { 1577 } else if (from.IsDouble()) {
1711 if (to.IsTagged()) { 1578 if (to.IsTagged()) {
1712 LOperand* value = UseRegister(instr->value()); 1579 LOperand* value = UseRegister(instr->value());
1713 LOperand* temp1 = TempRegister(); 1580 LOperand* temp1 = TempRegister();
1714 LOperand* temp2 = TempRegister(); 1581 LOperand* temp2 = TempRegister();
1715 1582
1716 // Make sure that the temp and result_temp registers are 1583 // Make sure that the temp and result_temp registers are
1717 // different. 1584 // different.
1718 LUnallocated* result_temp = TempRegister(); 1585 LUnallocated* result_temp = TempRegister();
1719 LInstruction* result = new LNumberTagD(value, temp1, temp2); 1586 LNumberTagD* result = new LNumberTagD(value, temp1, temp2);
1720 Define(result, result_temp); 1587 Define(result, result_temp);
1721 return AssignPointerMap(result); 1588 return AssignPointerMap(result);
1722 } else { 1589 } else {
1723 ASSERT(to.IsInteger32()); 1590 ASSERT(to.IsInteger32());
1724 LOperand* value = UseRegister(instr->value()); 1591 LOperand* value = UseRegister(instr->value());
1725 LInstruction* res = new LDoubleToI(value); 1592 LDoubleToI* res = new LDoubleToI(value, TempRegister());
1726 return AssignEnvironment(DefineAsRegister(res)); 1593 return AssignEnvironment(DefineAsRegister(res));
1727 } 1594 }
1728 } else if (from.IsInteger32()) { 1595 } else if (from.IsInteger32()) {
1729 if (to.IsTagged()) { 1596 if (to.IsTagged()) {
1730 HValue* val = instr->value(); 1597 HValue* val = instr->value();
1731 LOperand* value = UseRegister(val); 1598 LOperand* value = UseRegister(val);
1732 if (val->HasRange() && val->range()->IsInSmiRange()) { 1599 if (val->HasRange() && val->range()->IsInSmiRange()) {
1733 return DefineSameAsFirst(new LSmiTag(value)); 1600 return DefineSameAsFirst(new LSmiTag(value));
1734 } else { 1601 } else {
1735 LInstruction* result = new LNumberTagI(value); 1602 LNumberTagI* result = new LNumberTagI(value);
1736 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1603 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1737 } 1604 }
1738 } else { 1605 } else {
1739 ASSERT(to.IsDouble()); 1606 ASSERT(to.IsDouble());
1740 LOperand* value = Use(instr->value()); 1607 LOperand* value = Use(instr->value());
1741 return DefineAsRegister(new LInteger32ToDouble(value)); 1608 return DefineAsRegister(new LInteger32ToDouble(value));
1742 } 1609 }
1743 } 1610 }
1744 UNREACHABLE(); 1611 UNREACHABLE();
1745 return NULL; 1612 return NULL;
1746 } 1613 }
1747 1614
1748 1615
1749 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { 1616 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
1750 LOperand* value = UseRegisterAtStart(instr->value()); 1617 LOperand* value = UseRegisterAtStart(instr->value());
1751 return AssignEnvironment(new LCheckSmi(value, eq)); 1618 return AssignEnvironment(new LCheckSmi(value, eq));
1752 } 1619 }
1753 1620
1754 1621
1755 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { 1622 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1756 LOperand* value = UseRegisterAtStart(instr->value()); 1623 LOperand* value = UseRegisterAtStart(instr->value());
1757 LOperand* temp = TempRegister(); 1624 LInstruction* result = new LCheckInstanceType(value);
1758 LInstruction* result = new LCheckInstanceType(value, temp);
1759 return AssignEnvironment(result); 1625 return AssignEnvironment(result);
1760 } 1626 }
1761 1627
1762 1628
1763 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { 1629 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) {
1764 LOperand* temp1 = TempRegister(); 1630 LOperand* temp1 = TempRegister();
1765 LOperand* temp2 = TempRegister(); 1631 LOperand* temp2 = TempRegister();
1766 LInstruction* result = 1632 LInstruction* result = new LCheckPrototypeMaps(temp1, temp2);
1767 new LCheckPrototypeMaps(temp1,
1768 temp2,
1769 instr->holder(),
1770 instr->receiver_map());
1771 return AssignEnvironment(result); 1633 return AssignEnvironment(result);
1772 } 1634 }
1773 1635
1774 1636
1775 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { 1637 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1776 LOperand* value = UseRegisterAtStart(instr->value()); 1638 LOperand* value = UseRegisterAtStart(instr->value());
1777 return AssignEnvironment(new LCheckSmi(value, ne)); 1639 return AssignEnvironment(new LCheckSmi(value, ne));
1778 } 1640 }
1779 1641
1780 1642
(...skipping 11 matching lines...) Expand all
1792 1654
1793 1655
1794 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1656 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1795 return new LReturn(UseFixed(instr->value(), r0)); 1657 return new LReturn(UseFixed(instr->value(), r0));
1796 } 1658 }
1797 1659
1798 1660
1799 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1661 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1800 Representation r = instr->representation(); 1662 Representation r = instr->representation();
1801 if (r.IsInteger32()) { 1663 if (r.IsInteger32()) {
1802 int32_t value = instr->Integer32Value(); 1664 return DefineAsRegister(new LConstantI);
1803 return DefineAsRegister(new LConstantI(value));
1804 } else if (r.IsDouble()) { 1665 } else if (r.IsDouble()) {
1805 double value = instr->DoubleValue(); 1666 return DefineAsRegister(new LConstantD);
1806 return DefineAsRegister(new LConstantD(value));
1807 } else if (r.IsTagged()) { 1667 } else if (r.IsTagged()) {
1808 return DefineAsRegister(new LConstantT(instr->handle())); 1668 return DefineAsRegister(new LConstantT);
1809 } else { 1669 } else {
1810 Abort("unsupported constant of type double"); 1670 UNREACHABLE();
1811 return NULL; 1671 return NULL;
1812 } 1672 }
1813 } 1673 }
1814 1674
1815 1675
1816 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { 1676 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) {
1817 LInstruction* result = new LLoadGlobal(); 1677 LLoadGlobal* result = new LLoadGlobal();
1818 return instr->check_hole_value() 1678 return instr->check_hole_value()
1819 ? AssignEnvironment(DefineAsRegister(result)) 1679 ? AssignEnvironment(DefineAsRegister(result))
1820 : DefineAsRegister(result); 1680 : DefineAsRegister(result);
1821 } 1681 }
1822 1682
1823 1683
1824 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { 1684 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) {
1825 return new LStoreGlobal(UseRegisterAtStart(instr->value())); 1685 if (instr->check_hole_value()) {
1686 LOperand* temp = TempRegister();
1687 LOperand* value = UseRegister(instr->value());
1688 return AssignEnvironment(new LStoreGlobal(value, temp));
1689 } else {
1690 LOperand* value = UseRegisterAtStart(instr->value());
1691 return new LStoreGlobal(value, NULL);
1692 }
1693 }
1694
1695
1696 LInstruction* LChunkBuilder::DoLoadContextSlot(HLoadContextSlot* instr) {
1697 LOperand* context = UseRegisterAtStart(instr->value());
1698 return DefineAsRegister(new LLoadContextSlot(context));
1699 }
1700
1701
1702 LInstruction* LChunkBuilder::DoStoreContextSlot(HStoreContextSlot* instr) {
1703 LOperand* context = UseTempRegister(instr->context());
1704 LOperand* value;
1705 if (instr->NeedsWriteBarrier()) {
1706 value = UseTempRegister(instr->value());
1707 } else {
1708 value = UseRegister(instr->value());
1709 }
1710 return new LStoreContextSlot(context, value);
1826 } 1711 }
1827 1712
1828 1713
1829 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 1714 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1830 return DefineAsRegister( 1715 return DefineAsRegister(
1831 new LLoadNamedField(UseRegisterAtStart(instr->object()))); 1716 new LLoadNamedField(UseRegisterAtStart(instr->object())));
1832 } 1717 }
1833 1718
1834 1719
1835 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { 1720 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
1836 LOperand* object = UseFixed(instr->object(), r0); 1721 LOperand* object = UseFixed(instr->object(), r0);
1837 LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), r0); 1722 LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), r0);
1838 return MarkAsCall(result, instr); 1723 return MarkAsCall(result, instr);
1839 } 1724 }
1840 1725
1841 1726
1842 LInstruction* LChunkBuilder::DoLoadFunctionPrototype( 1727 LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
1843 HLoadFunctionPrototype* instr) { 1728 HLoadFunctionPrototype* instr) {
1844 return AssignEnvironment(DefineAsRegister( 1729 return AssignEnvironment(DefineAsRegister(
1845 new LLoadFunctionPrototype(UseRegister(instr->function())))); 1730 new LLoadFunctionPrototype(UseRegister(instr->function()))));
1846 } 1731 }
1847 1732
1848 1733
1849 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { 1734 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
1850 LOperand* input = UseRegisterAtStart(instr->value()); 1735 LOperand* input = UseRegisterAtStart(instr->value());
1851 return DefineSameAsFirst(new LLoadElements(input)); 1736 return DefineAsRegister(new LLoadElements(input));
1737 }
1738
1739
1740 LInstruction* LChunkBuilder::DoLoadPixelArrayExternalPointer(
1741 HLoadPixelArrayExternalPointer* instr) {
1742 LOperand* input = UseRegisterAtStart(instr->value());
1743 return DefineAsRegister(new LLoadPixelArrayExternalPointer(input));
1852 } 1744 }
1853 1745
1854 1746
1855 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( 1747 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1856 HLoadKeyedFastElement* instr) { 1748 HLoadKeyedFastElement* instr) {
1857 Representation r = instr->representation(); 1749 ASSERT(instr->representation().IsTagged());
1750 ASSERT(instr->key()->representation().IsInteger32());
1858 LOperand* obj = UseRegisterAtStart(instr->object()); 1751 LOperand* obj = UseRegisterAtStart(instr->object());
1859 ASSERT(instr->key()->representation().IsInteger32());
1860 LOperand* key = UseRegisterAtStart(instr->key()); 1752 LOperand* key = UseRegisterAtStart(instr->key());
1861 LOperand* load_result = NULL; 1753 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1862 // Double needs an extra temp, because the result is converted from heap 1754 return AssignEnvironment(DefineSameAsFirst(result));
1863 // number to a double register.
1864 if (r.IsDouble()) load_result = TempRegister();
1865 LInstruction* result = new LLoadKeyedFastElement(obj,
1866 key,
1867 load_result);
1868 if (r.IsDouble()) {
1869 result = DefineAsRegister(result);
1870 } else {
1871 result = DefineSameAsFirst(result);
1872 }
1873 return AssignEnvironment(result);
1874 } 1755 }
1875 1756
1876 1757
1758 LInstruction* LChunkBuilder::DoLoadPixelArrayElement(
1759 HLoadPixelArrayElement* instr) {
1760 ASSERT(instr->representation().IsInteger32());
1761 ASSERT(instr->key()->representation().IsInteger32());
1762 LOperand* external_pointer =
1763 UseRegisterAtStart(instr->external_pointer());
1764 LOperand* key = UseRegisterAtStart(instr->key());
1765 LLoadPixelArrayElement* result =
1766 new LLoadPixelArrayElement(external_pointer, key);
1767 return DefineAsRegister(result);
1768 }
1769
1770
1877 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1771 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1878 LOperand* object = UseFixed(instr->object(), r1); 1772 LOperand* object = UseFixed(instr->object(), r1);
1879 LOperand* key = UseFixed(instr->key(), r0); 1773 LOperand* key = UseFixed(instr->key(), r0);
1880 1774
1881 LInstruction* result = 1775 LInstruction* result =
1882 DefineFixed(new LLoadKeyedGeneric(object, key), r0); 1776 DefineFixed(new LLoadKeyedGeneric(object, key), r0);
1883 return MarkAsCall(result, instr); 1777 return MarkAsCall(result, instr);
1884 } 1778 }
1885 1779
1886 1780
(...skipping 23 matching lines...) Expand all
1910 1804
1911 ASSERT(instr->object()->representation().IsTagged()); 1805 ASSERT(instr->object()->representation().IsTagged());
1912 ASSERT(instr->key()->representation().IsTagged()); 1806 ASSERT(instr->key()->representation().IsTagged());
1913 ASSERT(instr->value()->representation().IsTagged()); 1807 ASSERT(instr->value()->representation().IsTagged());
1914 1808
1915 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr); 1809 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr);
1916 } 1810 }
1917 1811
1918 1812
1919 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { 1813 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
1920 bool needs_write_barrier = !instr->value()->type().IsSmi(); 1814 bool needs_write_barrier = instr->NeedsWriteBarrier();
1921 1815
1922 LOperand* obj = needs_write_barrier 1816 LOperand* obj = needs_write_barrier
1923 ? UseTempRegister(instr->object()) 1817 ? UseTempRegister(instr->object())
1924 : UseRegisterAtStart(instr->object()); 1818 : UseRegisterAtStart(instr->object());
1925 1819
1926 LOperand* val = needs_write_barrier 1820 LOperand* val = needs_write_barrier
1927 ? UseTempRegister(instr->value()) 1821 ? UseTempRegister(instr->value())
1928 : UseRegister(instr->value()); 1822 : UseRegister(instr->value());
1929 1823
1930 // We only need a scratch register if we have a write barrier or we 1824 return new LStoreNamedField(obj, val);
1931 // have a store into the properties array (not in-object-property).
1932 LOperand* temp = (!instr->is_in_object() || needs_write_barrier)
1933 ? TempRegister() : NULL;
1934
1935 return new LStoreNamedField(obj,
1936 instr->name(),
1937 val,
1938 instr->is_in_object(),
1939 instr->offset(),
1940 temp,
1941 needs_write_barrier,
1942 instr->transition());
1943 } 1825 }
1944 1826
1945 1827
1946 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 1828 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
1947 LOperand* obj = UseFixed(instr->object(), r1); 1829 LOperand* obj = UseFixed(instr->object(), r1);
1948 LOperand* val = UseFixed(instr->value(), r0); 1830 LOperand* val = UseFixed(instr->value(), r0);
1949 1831
1950 LInstruction* result = new LStoreNamedGeneric(obj, instr->name(), val); 1832 LInstruction* result = new LStoreNamedGeneric(obj, val);
1951 return MarkAsCall(result, instr); 1833 return MarkAsCall(result, instr);
1952 } 1834 }
1953 1835
1954 1836
1837 LInstruction* LChunkBuilder::DoStringCharCodeAt(HStringCharCodeAt* instr) {
1838 LOperand* string = UseRegister(instr->string());
1839 LOperand* index = UseRegisterOrConstant(instr->index());
1840 LStringCharCodeAt* result = new LStringCharCodeAt(string, index);
1841 return AssignEnvironment(AssignPointerMap(DefineAsRegister(result)));
1842 }
1843
1844
1845 LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
1846 LOperand* string = UseRegisterAtStart(instr->value());
1847 return DefineAsRegister(new LStringLength(string));
1848 }
1849
1850
1955 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { 1851 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
1956 return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr); 1852 return MarkAsCall(DefineFixed(new LArrayLiteral, r0), instr);
1957 } 1853 }
1958 1854
1959 1855
1960 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { 1856 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
1961 return MarkAsCall(DefineFixed(new LObjectLiteral, r0), instr); 1857 return MarkAsCall(DefineFixed(new LObjectLiteral, r0), instr);
1962 } 1858 }
1963 1859
1964 1860
1965 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { 1861 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
1966 return MarkAsCall(DefineFixed(new LRegExpLiteral, r0), instr); 1862 return MarkAsCall(DefineFixed(new LRegExpLiteral, r0), instr);
1967 } 1863 }
1968 1864
1969 1865
1970 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { 1866 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
1971 return MarkAsCall(DefineFixed(new LFunctionLiteral, r0), instr); 1867 return MarkAsCall(DefineFixed(new LFunctionLiteral, r0), instr);
1972 } 1868 }
1973 1869
1974 1870
1975 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { 1871 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
1976 LInstruction* result = new LDeleteProperty(Use(instr->object()), 1872 LOperand* object = UseFixed(instr->object(), r0);
1977 UseOrConstant(instr->key())); 1873 LOperand* key = UseFixed(instr->key(), r1);
1874 LDeleteProperty* result = new LDeleteProperty(object, key);
1978 return MarkAsCall(DefineFixed(result, r0), instr); 1875 return MarkAsCall(DefineFixed(result, r0), instr);
1979 } 1876 }
1980 1877
1981 1878
1982 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { 1879 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
1983 allocator_->MarkAsOsrEntry(); 1880 allocator_->MarkAsOsrEntry();
1984 current_block_->last_environment()->set_ast_id(instr->ast_id()); 1881 current_block_->last_environment()->set_ast_id(instr->ast_id());
1985 return AssignEnvironment(new LOsrEntry); 1882 return AssignEnvironment(new LOsrEntry);
1986 } 1883 }
1987 1884
(...skipping 19 matching lines...) Expand all
2007 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { 1904 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2008 // There are no real uses of the arguments object (we bail out in all other 1905 // There are no real uses of the arguments object (we bail out in all other
2009 // cases). 1906 // cases).
2010 return NULL; 1907 return NULL;
2011 } 1908 }
2012 1909
2013 1910
2014 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 1911 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2015 LOperand* arguments = UseRegister(instr->arguments()); 1912 LOperand* arguments = UseRegister(instr->arguments());
2016 LOperand* length = UseTempRegister(instr->length()); 1913 LOperand* length = UseTempRegister(instr->length());
2017 LOperand* index = Use(instr->index()); 1914 LOperand* index = UseRegister(instr->index());
2018 LInstruction* result = new LAccessArgumentsAt(arguments, length, index); 1915 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index);
2019 return DefineAsRegister(AssignEnvironment(result)); 1916 return AssignEnvironment(DefineAsRegister(result));
2020 } 1917 }
2021 1918
2022 1919
2023 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 1920 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2024 LInstruction* result = new LTypeof(Use(instr->value())); 1921 LTypeof* result = new LTypeof(UseFixed(instr->value(), r0));
2025 return MarkAsCall(DefineFixed(result, r0), instr); 1922 return MarkAsCall(DefineFixed(result, r0), instr);
2026 } 1923 }
2027 1924
2028 1925
2029 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 1926 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
2030 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); 1927 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
2031 } 1928 }
2032 1929
1930
1931 LInstruction* LChunkBuilder::DoIsConstructCall(HIsConstructCall* instr) {
1932 return DefineAsRegister(new LIsConstructCall());
1933 }
1934
1935
2033 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 1936 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2034 HEnvironment* env = current_block_->last_environment(); 1937 HEnvironment* env = current_block_->last_environment();
2035 ASSERT(env != NULL); 1938 ASSERT(env != NULL);
2036 1939
2037 env->set_ast_id(instr->ast_id()); 1940 env->set_ast_id(instr->ast_id());
2038 1941
2039 env->Drop(instr->pop_count()); 1942 env->Drop(instr->pop_count());
2040 for (int i = 0; i < instr->values()->length(); ++i) { 1943 for (int i = 0; i < instr->values()->length(); ++i) {
2041 HValue* value = instr->values()->at(i); 1944 HValue* value = instr->values()->at(i);
2042 if (instr->HasAssignedIndexAt(i)) { 1945 if (instr->HasAssignedIndexAt(i)) {
2043 env->Bind(instr->GetAssignedIndexAt(i), value); 1946 env->Bind(instr->GetAssignedIndexAt(i), value);
2044 } else { 1947 } else {
2045 env->Push(value); 1948 env->Push(value);
2046 } 1949 }
2047 } 1950 }
2048 1951
2049 ASSERT(env->length() == instr->environment_length()); 1952 ASSERT(env->length() == instr->environment_length());
2050 1953
2051 // If there is an instruction pending deoptimization environment create a 1954 // If there is an instruction pending deoptimization environment create a
2052 // lazy bailout instruction to capture the environment. 1955 // lazy bailout instruction to capture the environment.
2053 if (pending_deoptimization_ast_id_ == instr->ast_id()) { 1956 if (pending_deoptimization_ast_id_ == instr->ast_id()) {
2054 LInstruction* result = new LLazyBailout; 1957 LInstruction* result = new LLazyBailout;
2055 result = AssignEnvironment(result); 1958 result = AssignEnvironment(result);
2056 instructions_pending_deoptimization_environment_-> 1959 instruction_pending_deoptimization_environment_->
2057 set_deoptimization_environment(result->environment()); 1960 set_deoptimization_environment(result->environment());
2058 ClearInstructionPendingDeoptimizationEnvironment(); 1961 ClearInstructionPendingDeoptimizationEnvironment();
2059 return result; 1962 return result;
2060 } 1963 }
2061 1964
2062 return NULL; 1965 return NULL;
2063 } 1966 }
2064 1967
2065 1968
2066 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) { 1969 LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
(...skipping 14 matching lines...) Expand all
2081 } 1984 }
2082 1985
2083 1986
2084 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 1987 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2085 HEnvironment* outer = current_block_->last_environment()->outer(); 1988 HEnvironment* outer = current_block_->last_environment()->outer();
2086 current_block_->UpdateEnvironment(outer); 1989 current_block_->UpdateEnvironment(outer);
2087 return NULL; 1990 return NULL;
2088 } 1991 }
2089 1992
2090 1993
2091 void LPointerMap::RecordPointer(LOperand* op) {
2092 // Do not record arguments as pointers.
2093 if (op->IsStackSlot() && op->index() < 0) return;
2094 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
2095 pointer_operands_.Add(op);
2096 }
2097
2098
2099 void LPointerMap::PrintTo(StringStream* stream) const {
2100 stream->Add("{");
2101 for (int i = 0; i < pointer_operands_.length(); ++i) {
2102 if (i != 0) stream->Add(";");
2103 pointer_operands_[i]->PrintTo(stream);
2104 }
2105 stream->Add("} @%d", position());
2106 }
2107
2108 } } // namespace v8::internal 1994 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698