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

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

Issue 6577036: [Isolates] Merge from bleeding_edge to isolates, revisions 6100-6300. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
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/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.cc » ('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 "v8.h"
29
30 #if defined(V8_TARGET_ARCH_IA32)
31
28 #include "ia32/lithium-ia32.h" 32 #include "ia32/lithium-ia32.h"
29 #include "ia32/lithium-codegen-ia32.h" 33 #include "ia32/lithium-codegen-ia32.h"
30 34
31 namespace v8 { 35 namespace v8 {
32 namespace internal { 36 namespace internal {
33 37
34 #define DEFINE_COMPILE(type) \ 38 #define DEFINE_COMPILE(type) \
35 void L##type::CompileToNative(LCodeGen* generator) { \ 39 void L##type::CompileToNative(LCodeGen* generator) { \
36 generator->Do##type(this); \ 40 generator->Do##type(this); \
37 } 41 }
(...skipping 19 matching lines...) Expand all
57 61
58 62
59 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index, 63 void LOsrEntry::MarkSpilledDoubleRegister(int allocation_index,
60 LOperand* spill_operand) { 64 LOperand* spill_operand) {
61 ASSERT(spill_operand->IsDoubleStackSlot()); 65 ASSERT(spill_operand->IsDoubleStackSlot());
62 ASSERT(double_register_spills_[allocation_index] == NULL); 66 ASSERT(double_register_spills_[allocation_index] == NULL);
63 double_register_spills_[allocation_index] = spill_operand; 67 double_register_spills_[allocation_index] = spill_operand;
64 } 68 }
65 69
66 70
67 void LInstruction::PrintTo(StringStream* stream) const { 71 void LInstruction::PrintTo(StringStream* stream) {
68 stream->Add("%s ", this->Mnemonic()); 72 stream->Add("%s ", this->Mnemonic());
69 if (HasResult()) { 73 if (HasResult()) {
70 result()->PrintTo(stream); 74 PrintOutputOperandTo(stream);
71 stream->Add(" ");
72 } 75 }
76
73 PrintDataTo(stream); 77 PrintDataTo(stream);
74 78
75 if (HasEnvironment()) { 79 if (HasEnvironment()) {
76 stream->Add(" "); 80 stream->Add(" ");
77 environment()->PrintTo(stream); 81 environment()->PrintTo(stream);
78 } 82 }
79 83
80 if (HasPointerMap()) { 84 if (HasPointerMap()) {
81 stream->Add(" "); 85 stream->Add(" ");
82 pointer_map()->PrintTo(stream); 86 pointer_map()->PrintTo(stream);
83 } 87 }
84 } 88 }
85 89
86 90
87 void LLabel::PrintDataTo(StringStream* stream) const { 91 template<int R, int I, int T>
92 void LTemplateInstruction<R, I, T>::PrintDataTo(StringStream* stream) {
93 for (int i = 0; i < I; i++) {
94 stream->Add(i == 0 ? "= " : " ");
95 inputs_.at(i)->PrintTo(stream);
96 }
97 }
98
99
100 template<int R, int I, int T>
101 void LTemplateInstruction<R, I, T>::PrintOutputOperandTo(StringStream* stream) {
102 if (this->HasResult()) {
103 this->result()->PrintTo(stream);
104 stream->Add(" ");
105 }
106 }
107
108
109 void LLabel::PrintDataTo(StringStream* stream) {
88 LGap::PrintDataTo(stream); 110 LGap::PrintDataTo(stream);
89 LLabel* rep = replacement(); 111 LLabel* rep = replacement();
90 if (rep != NULL) { 112 if (rep != NULL) {
91 stream->Add(" Dead block replaced with B%d", rep->block_id()); 113 stream->Add(" Dead block replaced with B%d", rep->block_id());
92 } 114 }
93 } 115 }
94 116
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 117
122 bool LGap::IsRedundant() const { 118 bool LGap::IsRedundant() const {
123 for (int i = 0; i < 4; i++) { 119 for (int i = 0; i < 4; i++) {
124 if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) { 120 if (parallel_moves_[i] != NULL && !parallel_moves_[i]->IsRedundant()) {
125 return false; 121 return false;
126 } 122 }
127 } 123 }
128 124
129 return true; 125 return true;
130 } 126 }
131 127
132 128
133 void LGap::PrintDataTo(StringStream* stream) const { 129 void LGap::PrintDataTo(StringStream* stream) {
134 for (int i = 0; i < 4; i++) { 130 for (int i = 0; i < 4; i++) {
135 stream->Add("("); 131 stream->Add("(");
136 if (parallel_moves_[i] != NULL) { 132 if (parallel_moves_[i] != NULL) {
137 parallel_moves_[i]->PrintDataTo(stream); 133 parallel_moves_[i]->PrintDataTo(stream);
138 } 134 }
139 stream->Add(") "); 135 stream->Add(") ");
140 } 136 }
141 } 137 }
142 138
143 139
(...skipping 18 matching lines...) Expand all
162 case Token::MUL: return "mul-t"; 158 case Token::MUL: return "mul-t";
163 case Token::MOD: return "mod-t"; 159 case Token::MOD: return "mod-t";
164 case Token::DIV: return "div-t"; 160 case Token::DIV: return "div-t";
165 default: 161 default:
166 UNREACHABLE(); 162 UNREACHABLE();
167 return NULL; 163 return NULL;
168 } 164 }
169 } 165 }
170 166
171 167
172 168 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()); 169 stream->Add("B%d", block_id());
183 } 170 }
184 171
185 172
186 void LBranch::PrintDataTo(StringStream* stream) const { 173 void LBranch::PrintDataTo(StringStream* stream) {
187 stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); 174 stream->Add("B%d | B%d on ", true_block_id(), false_block_id());
188 input()->PrintTo(stream); 175 input()->PrintTo(stream);
189 } 176 }
190 177
191 178
192 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) const { 179 void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
193 stream->Add("if "); 180 stream->Add("if ");
194 left()->PrintTo(stream); 181 left()->PrintTo(stream);
195 stream->Add(" %s ", Token::String(op())); 182 stream->Add(" %s ", Token::String(op()));
196 right()->PrintTo(stream); 183 right()->PrintTo(stream);
197 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); 184 stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
198 } 185 }
199 186
200 187
201 void LIsNullAndBranch::PrintDataTo(StringStream* stream) const { 188 void LIsNullAndBranch::PrintDataTo(StringStream* stream) {
202 stream->Add("if "); 189 stream->Add("if ");
203 input()->PrintTo(stream); 190 input()->PrintTo(stream);
204 stream->Add(is_strict() ? " === null" : " == null"); 191 stream->Add(is_strict() ? " === null" : " == null");
205 stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); 192 stream->Add(" then B%d else B%d", true_block_id(), false_block_id());
206 } 193 }
207 194
208 195
209 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) const { 196 void LIsObjectAndBranch::PrintDataTo(StringStream* stream) {
210 stream->Add("if is_object("); 197 stream->Add("if is_object(");
211 input()->PrintTo(stream); 198 input()->PrintTo(stream);
212 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 199 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
213 } 200 }
214 201
215 202
216 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) const { 203 void LIsSmiAndBranch::PrintDataTo(StringStream* stream) {
217 stream->Add("if is_smi("); 204 stream->Add("if is_smi(");
218 input()->PrintTo(stream); 205 input()->PrintTo(stream);
219 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 206 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
220 } 207 }
221 208
222 209
223 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) const { 210 void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) {
224 stream->Add("if has_instance_type("); 211 stream->Add("if has_instance_type(");
225 input()->PrintTo(stream); 212 input()->PrintTo(stream);
226 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());
227 } 214 }
228 215
229 216
230 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) const { 217 void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) {
231 stream->Add("if has_cached_array_index("); 218 stream->Add("if has_cached_array_index(");
232 input()->PrintTo(stream); 219 input()->PrintTo(stream);
233 stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); 220 stream->Add(") then B%d else B%d", true_block_id(), false_block_id());
234 } 221 }
235 222
236 223
237 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) const { 224 void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) {
238 stream->Add("if class_of_test("); 225 stream->Add("if class_of_test(");
239 input()->PrintTo(stream); 226 input()->PrintTo(stream);
240 stream->Add(", \"%o\") then B%d else B%d", 227 stream->Add(", \"%o\") then B%d else B%d",
241 *hydrogen()->class_name(), 228 *hydrogen()->class_name(),
242 true_block_id(), 229 true_block_id(),
243 false_block_id()); 230 false_block_id());
244 } 231 }
245 232
246 233
247 void LTypeofIs::PrintDataTo(StringStream* stream) const { 234 void LTypeofIs::PrintDataTo(StringStream* stream) {
248 input()->PrintTo(stream); 235 input()->PrintTo(stream);
249 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); 236 stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString());
250 } 237 }
251 238
252 239
253 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) const { 240 void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) {
254 stream->Add("if typeof "); 241 stream->Add("if typeof ");
255 input()->PrintTo(stream); 242 input()->PrintTo(stream);
256 stream->Add(" == \"%s\" then B%d else B%d", 243 stream->Add(" == \"%s\" then B%d else B%d",
257 *hydrogen()->type_literal()->ToCString(), 244 *hydrogen()->type_literal()->ToCString(),
258 true_block_id(), false_block_id()); 245 true_block_id(), false_block_id());
259 } 246 }
260 247
261 248
262 void LCallConstantFunction::PrintDataTo(StringStream* stream) const { 249 void LCallConstantFunction::PrintDataTo(StringStream* stream) {
263 stream->Add("#%d / ", arity()); 250 stream->Add("#%d / ", arity());
264 } 251 }
265 252
266 253
267 void LUnaryMathOperation::PrintDataTo(StringStream* stream) const { 254 void LUnaryMathOperation::PrintDataTo(StringStream* stream) {
268 stream->Add("/%s ", hydrogen()->OpName()); 255 stream->Add("/%s ", hydrogen()->OpName());
269 input()->PrintTo(stream); 256 input()->PrintTo(stream);
270 } 257 }
271 258
272 259
273 void LCallKeyed::PrintDataTo(StringStream* stream) const { 260 void LCallKeyed::PrintDataTo(StringStream* stream) {
274 stream->Add("[ecx] #%d / ", arity()); 261 stream->Add("[ecx] #%d / ", arity());
275 } 262 }
276 263
277 264
278 void LCallNamed::PrintDataTo(StringStream* stream) const { 265 void LCallNamed::PrintDataTo(StringStream* stream) {
279 SmartPointer<char> name_string = name()->ToCString(); 266 SmartPointer<char> name_string = name()->ToCString();
280 stream->Add("%s #%d / ", *name_string, arity()); 267 stream->Add("%s #%d / ", *name_string, arity());
281 } 268 }
282 269
283 270
284 void LCallGlobal::PrintDataTo(StringStream* stream) const { 271 void LCallGlobal::PrintDataTo(StringStream* stream) {
285 SmartPointer<char> name_string = name()->ToCString(); 272 SmartPointer<char> name_string = name()->ToCString();
286 stream->Add("%s #%d / ", *name_string, arity()); 273 stream->Add("%s #%d / ", *name_string, arity());
287 } 274 }
288 275
289 276
290 void LCallKnownGlobal::PrintDataTo(StringStream* stream) const { 277 void LCallKnownGlobal::PrintDataTo(StringStream* stream) {
291 stream->Add("#%d / ", arity()); 278 stream->Add("#%d / ", arity());
292 } 279 }
293 280
294 281
295 void LCallNew::PrintDataTo(StringStream* stream) const { 282 void LCallNew::PrintDataTo(StringStream* stream) {
296 LUnaryOperation::PrintDataTo(stream); 283 stream->Add("= ");
284 input()->PrintTo(stream);
297 stream->Add(" #%d / ", arity()); 285 stream->Add(" #%d / ", arity());
298 } 286 }
299 287
300 288
301 void LClassOfTest::PrintDataTo(StringStream* stream) const { 289 void LClassOfTest::PrintDataTo(StringStream* stream) {
302 stream->Add("= class_of_test("); 290 stream->Add("= class_of_test(");
303 input()->PrintTo(stream); 291 input()->PrintTo(stream);
304 stream->Add(", \"%o\")", *hydrogen()->class_name()); 292 stream->Add(", \"%o\")", *hydrogen()->class_name());
305 } 293 }
306 294
307 295
308 void LUnaryOperation::PrintDataTo(StringStream* stream) const { 296 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); 297 arguments()->PrintTo(stream);
316 298
317 stream->Add(" length "); 299 stream->Add(" length ");
318 length()->PrintTo(stream); 300 length()->PrintTo(stream);
319 301
320 stream->Add(" index "); 302 stream->Add(" index ");
321 index()->PrintTo(stream); 303 index()->PrintTo(stream);
322 } 304 }
323 305
324 306
325 LChunk::LChunk(HGraph* graph)
326 : spill_slot_count_(0),
327 graph_(graph),
328 instructions_(32),
329 pointer_maps_(8),
330 inlined_closures_(1) {
331 }
332
333
334 void LChunk::Verify() const {
335 // TODO(twuerthinger): Implement verification for chunk.
336 }
337
338
339 int LChunk::GetNextSpillIndex(bool is_double) { 307 int LChunk::GetNextSpillIndex(bool is_double) {
340 // Skip a slot if for a double-width slot. 308 // Skip a slot if for a double-width slot.
341 if (is_double) spill_slot_count_++; 309 if (is_double) spill_slot_count_++;
342 return spill_slot_count_++; 310 return spill_slot_count_++;
343 } 311 }
344 312
345 313
346 LOperand* LChunk::GetNextSpillSlot(bool is_double) { 314 LOperand* LChunk::GetNextSpillSlot(bool is_double) {
347 int index = GetNextSpillIndex(is_double); 315 int index = GetNextSpillIndex(is_double);
348 if (is_double) { 316 if (is_double) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 351
384 if (can_eliminate) { 352 if (can_eliminate) {
385 label->set_replacement(GetLabel(goto_instr->block_id())); 353 label->set_replacement(GetLabel(goto_instr->block_id()));
386 } 354 }
387 } 355 }
388 } 356 }
389 } 357 }
390 } 358 }
391 359
392 360
393 void LStoreNamed::PrintDataTo(StringStream* stream) const { 361 void LStoreNamed::PrintDataTo(StringStream* stream) {
394 object()->PrintTo(stream); 362 object()->PrintTo(stream);
395 stream->Add("."); 363 stream->Add(".");
396 stream->Add(*String::cast(*name())->ToCString()); 364 stream->Add(*String::cast(*name())->ToCString());
397 stream->Add(" <- "); 365 stream->Add(" <- ");
398 value()->PrintTo(stream); 366 value()->PrintTo(stream);
399 } 367 }
400 368
401 369
402 void LStoreKeyed::PrintDataTo(StringStream* stream) const { 370 void LStoreKeyed::PrintDataTo(StringStream* stream) {
403 object()->PrintTo(stream); 371 object()->PrintTo(stream);
404 stream->Add("["); 372 stream->Add("[");
405 key()->PrintTo(stream); 373 key()->PrintTo(stream);
406 stream->Add("] <- "); 374 stream->Add("] <- ");
407 value()->PrintTo(stream); 375 value()->PrintTo(stream);
408 } 376 }
409 377
410 378
411 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) { 379 int LChunk::AddInstruction(LInstruction* instr, HBasicBlock* block) {
412 LGap* gap = new LGap(block); 380 LGap* gap = new LGap(block);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 while (!IsGapAt(index)) index--; 433 while (!IsGapAt(index)) index--;
466 return index; 434 return index;
467 } 435 }
468 436
469 437
470 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) { 438 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
471 GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to); 439 GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to);
472 } 440 }
473 441
474 442
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 { 443 Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
621 return HConstant::cast(graph_->LookupValue(operand->index()))->handle(); 444 return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
622 } 445 }
623 446
624 447
625 Representation LChunk::LookupLiteralRepresentation( 448 Representation LChunk::LookupLiteralRepresentation(
626 LConstantOperand* operand) const { 449 LConstantOperand* operand) const {
627 return graph_->LookupValue(operand->index())->representation(); 450 return graph_->LookupValue(operand->index())->representation();
628 } 451 }
629 452
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) { 568 LOperand* LChunkBuilder::Use(HValue* value, LUnallocated* operand) {
746 if (value->EmitAtUses()) { 569 if (value->EmitAtUses()) {
747 HInstruction* instr = HInstruction::cast(value); 570 HInstruction* instr = HInstruction::cast(value);
748 VisitInstruction(instr); 571 VisitInstruction(instr);
749 } 572 }
750 allocator_->RecordUse(value, operand); 573 allocator_->RecordUse(value, operand);
751 return operand; 574 return operand;
752 } 575 }
753 576
754 577
755 LInstruction* LChunkBuilder::Define(LInstruction* instr) { 578 template<int I, int T>
579 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr,
580 LUnallocated* result) {
581 allocator_->RecordDefinition(current_instruction_, result);
582 instr->set_result(result);
583 return instr;
584 }
585
586
587 template<int I, int T>
588 LInstruction* LChunkBuilder::Define(LTemplateInstruction<1, I, T>* instr) {
756 return Define(instr, new LUnallocated(LUnallocated::NONE)); 589 return Define(instr, new LUnallocated(LUnallocated::NONE));
757 } 590 }
758 591
759 592
760 LInstruction* LChunkBuilder::DefineAsRegister(LInstruction* instr) { 593 template<int I, int T>
594 LInstruction* LChunkBuilder::DefineAsRegister(
595 LTemplateInstruction<1, I, T>* instr) {
761 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); 596 return Define(instr, new LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
762 } 597 }
763 598
764 599
765 LInstruction* LChunkBuilder::DefineAsSpilled(LInstruction* instr, int index) { 600 template<int I, int T>
601 LInstruction* LChunkBuilder::DefineAsSpilled(
602 LTemplateInstruction<1, I, T>* instr,
603 int index) {
766 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index)); 604 return Define(instr, new LUnallocated(LUnallocated::FIXED_SLOT, index));
767 } 605 }
768 606
769 607
770 LInstruction* LChunkBuilder::DefineSameAsAny(LInstruction* instr) { 608 template<int I, int T>
771 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_ANY_INPUT)); 609 LInstruction* LChunkBuilder::DefineSameAsFirst(
772 } 610 LTemplateInstruction<1, I, T>* instr) {
773
774
775 LInstruction* LChunkBuilder::DefineSameAsFirst(LInstruction* instr) {
776 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT)); 611 return Define(instr, new LUnallocated(LUnallocated::SAME_AS_FIRST_INPUT));
777 } 612 }
778 613
779 614
780 LInstruction* LChunkBuilder::DefineFixed(LInstruction* instr, Register reg) { 615 template<int I, int T>
616 LInstruction* LChunkBuilder::DefineFixed(LTemplateInstruction<1, I, T>* instr,
617 Register reg) {
781 return Define(instr, ToUnallocated(reg)); 618 return Define(instr, ToUnallocated(reg));
782 } 619 }
783 620
784 621
785 LInstruction* LChunkBuilder::DefineFixedDouble(LInstruction* instr, 622 template<int I, int T>
786 XMMRegister reg) { 623 LInstruction* LChunkBuilder::DefineFixedDouble(
624 LTemplateInstruction<1, I, T>* instr,
625 XMMRegister reg) {
787 return Define(instr, ToUnallocated(reg)); 626 return Define(instr, ToUnallocated(reg));
788 } 627 }
789 628
790 629
791 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { 630 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
792 HEnvironment* hydrogen_env = current_block_->last_environment(); 631 HEnvironment* hydrogen_env = current_block_->last_environment();
793 instr->set_environment(CreateEnvironment(hydrogen_env)); 632 instr->set_environment(CreateEnvironment(hydrogen_env));
794 return instr; 633 return instr;
795 } 634 }
796 635
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
831 bool needs_environment = 670 bool needs_environment =
832 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); 671 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects();
833 if (needs_environment && !instr->HasEnvironment()) { 672 if (needs_environment && !instr->HasEnvironment()) {
834 instr = AssignEnvironment(instr); 673 instr = AssignEnvironment(instr);
835 } 674 }
836 675
837 return instr; 676 return instr;
838 } 677 }
839 678
840 679
680 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
681 allocator_->MarkAsSaveDoubles();
682 return instr;
683 }
684
685
841 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { 686 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
842 ASSERT(!instr->HasPointerMap()); 687 ASSERT(!instr->HasPointerMap());
843 instr->set_pointer_map(new LPointerMap(position_)); 688 instr->set_pointer_map(new LPointerMap(position_));
844 return instr; 689 return instr;
845 } 690 }
846 691
847 692
848 LInstruction* LChunkBuilder::Define(LInstruction* instr, LUnallocated* result) {
849 allocator_->RecordDefinition(current_instruction_, result);
850 instr->set_result(result);
851 return instr;
852 }
853
854
855 LOperand* LChunkBuilder::Temp() {
856 LUnallocated* operand = new LUnallocated(LUnallocated::NONE);
857 allocator_->RecordTemporary(operand);
858 return operand;
859 }
860
861
862 LUnallocated* LChunkBuilder::TempRegister() { 693 LUnallocated* LChunkBuilder::TempRegister() {
863 LUnallocated* operand = new LUnallocated(LUnallocated::MUST_HAVE_REGISTER); 694 LUnallocated* operand = new LUnallocated(LUnallocated::MUST_HAVE_REGISTER);
864 allocator_->RecordTemporary(operand); 695 allocator_->RecordTemporary(operand);
865 return operand; 696 return operand;
866 } 697 }
867 698
868 699
869 LOperand* LChunkBuilder::FixedTemp(Register reg) { 700 LOperand* LChunkBuilder::FixedTemp(Register reg) {
870 LUnallocated* operand = ToUnallocated(reg); 701 LUnallocated* operand = ToUnallocated(reg);
871 allocator_->RecordTemporary(operand); 702 allocator_->RecordTemporary(operand);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 bool can_truncate = true; 758 bool can_truncate = true;
928 for (int i = 0; i < instr->uses()->length(); i++) { 759 for (int i = 0; i < instr->uses()->length(); i++) {
929 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) { 760 if (!instr->uses()->at(i)->CheckFlag(HValue::kTruncatingToInt32)) {
930 can_truncate = false; 761 can_truncate = false;
931 break; 762 break;
932 } 763 }
933 } 764 }
934 can_deopt = !can_truncate; 765 can_deopt = !can_truncate;
935 } 766 }
936 767
937 LInstruction* result = 768 LShiftI* result = new LShiftI(op, left, right, can_deopt);
938 DefineSameAsFirst(new LShiftI(op, left, right, can_deopt)); 769 return can_deopt
939 if (can_deopt) AssignEnvironment(result); 770 ? AssignEnvironment(DefineSameAsFirst(result))
940 return result; 771 : DefineSameAsFirst(result);
941 } 772 }
942 773
943 774
944 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op, 775 LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
945 HArithmeticBinaryOperation* instr) { 776 HArithmeticBinaryOperation* instr) {
946 ASSERT(instr->representation().IsDouble()); 777 ASSERT(instr->representation().IsDouble());
947 ASSERT(instr->left()->representation().IsDouble()); 778 ASSERT(instr->left()->representation().IsDouble());
948 ASSERT(instr->right()->representation().IsDouble()); 779 ASSERT(instr->right()->representation().IsDouble());
949 LOperand* left = UseRegisterAtStart(instr->left()); 780 LOperand* left = UseRegisterAtStart(instr->left());
950 LOperand* right = UseRegisterAtStart(instr->right()); 781 LOperand* right = UseRegisterAtStart(instr->right());
951 LArithmeticD* result = new LArithmeticD(op, left, right); 782 LArithmeticD* result = new LArithmeticD(op, left, right);
952 return DefineSameAsFirst(result); 783 return DefineSameAsFirst(result);
953 } 784 }
954 785
955 786
956 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op, 787 LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
957 HArithmeticBinaryOperation* instr) { 788 HArithmeticBinaryOperation* instr) {
958 ASSERT(op == Token::ADD || 789 ASSERT(op == Token::ADD ||
959 op == Token::DIV || 790 op == Token::DIV ||
960 op == Token::MOD || 791 op == Token::MOD ||
961 op == Token::MUL || 792 op == Token::MUL ||
962 op == Token::SUB); 793 op == Token::SUB);
963 HValue* left = instr->left(); 794 HValue* left = instr->left();
964 HValue* right = instr->right(); 795 HValue* right = instr->right();
965 ASSERT(left->representation().IsTagged()); 796 ASSERT(left->representation().IsTagged());
966 ASSERT(right->representation().IsTagged()); 797 ASSERT(right->representation().IsTagged());
967 LOperand* left_operand = UseFixed(left, edx); 798 LOperand* left_operand = UseFixed(left, edx);
968 LOperand* right_operand = UseFixed(right, eax); 799 LOperand* right_operand = UseFixed(right, eax);
969 LInstruction* result = new LArithmeticT(op, left_operand, right_operand); 800 LArithmeticT* result = new LArithmeticT(op, left_operand, right_operand);
970 return MarkAsCall(DefineFixed(result, eax), instr); 801 return MarkAsCall(DefineFixed(result, eax), instr);
971 } 802 }
972 803
973 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) { 804 void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
974 ASSERT(is_building()); 805 ASSERT(is_building());
975 current_block_ = block; 806 current_block_ = block;
976 next_block_ = next_block; 807 next_block_ = next_block;
977 if (block->IsStartBlock()) { 808 if (block->IsStartBlock()) {
978 block->UpdateEnvironment(graph_->start_environment()); 809 block->UpdateEnvironment(graph_->start_environment());
979 argument_count_ = 0; 810 argument_count_ = 0;
(...skipping 29 matching lines...) Expand all
1009 last_environment->SetValueAt(block->deleted_phis()->at(i), 840 last_environment->SetValueAt(block->deleted_phis()->at(i),
1010 graph_->GetConstantUndefined()); 841 graph_->GetConstantUndefined());
1011 } 842 }
1012 block->UpdateEnvironment(last_environment); 843 block->UpdateEnvironment(last_environment);
1013 // Pick up the outgoing argument count of one of the predecessors. 844 // Pick up the outgoing argument count of one of the predecessors.
1014 argument_count_ = pred->argument_count(); 845 argument_count_ = pred->argument_count();
1015 } 846 }
1016 HInstruction* current = block->first(); 847 HInstruction* current = block->first();
1017 int start = chunk_->instructions()->length(); 848 int start = chunk_->instructions()->length();
1018 while (current != NULL && !is_aborted()) { 849 while (current != NULL && !is_aborted()) {
1019 if (FLAG_trace_environment) {
1020 PrintF("Process instruction %d\n", current->id());
1021 }
1022 // Code for constants in registers is generated lazily. 850 // Code for constants in registers is generated lazily.
1023 if (!current->EmitAtUses()) { 851 if (!current->EmitAtUses()) {
1024 VisitInstruction(current); 852 VisitInstruction(current);
1025 } 853 }
1026 current = current->next(); 854 current = current->next();
1027 } 855 }
1028 int end = chunk_->instructions()->length() - 1; 856 int end = chunk_->instructions()->length() - 1;
1029 if (end >= start) { 857 if (end >= start) {
1030 block->set_first_instruction_index(start); 858 block->set_first_instruction_index(start);
1031 block->set_last_instruction_index(end); 859 block->set_last_instruction_index(end);
(...skipping 27 matching lines...) Expand all
1059 int index = chunk_->AddInstruction(instr, current_block_); 887 int index = chunk_->AddInstruction(instr, current_block_);
1060 allocator_->SummarizeInstruction(index); 888 allocator_->SummarizeInstruction(index);
1061 } else { 889 } else {
1062 // This instruction should be omitted. 890 // This instruction should be omitted.
1063 allocator_->OmitInstruction(); 891 allocator_->OmitInstruction();
1064 } 892 }
1065 current_instruction_ = old_current; 893 current_instruction_ = old_current;
1066 } 894 }
1067 895
1068 896
1069 void LEnvironment::WriteTranslation(LCodeGen* cgen,
1070 Translation* translation) const {
1071 if (this == NULL) return;
1072
1073 // The translation includes one command per value in the environment.
1074 int translation_size = values()->length();
1075 // The output frame height does not include the parameters.
1076 int height = translation_size - parameter_count();
1077
1078 outer()->WriteTranslation(cgen, translation);
1079 int closure_id = cgen->DefineDeoptimizationLiteral(closure());
1080 translation->BeginFrame(ast_id(), closure_id, height);
1081 for (int i = 0; i < translation_size; ++i) {
1082 LOperand* value = values()->at(i);
1083 // spilled_registers_ and spilled_double_registers_ are either
1084 // both NULL or both set.
1085 if (spilled_registers_ != NULL && value != NULL) {
1086 if (value->IsRegister() &&
1087 spilled_registers_[value->index()] != NULL) {
1088 translation->MarkDuplicate();
1089 cgen->AddToTranslation(translation,
1090 spilled_registers_[value->index()],
1091 HasTaggedValueAt(i));
1092 } else if (value->IsDoubleRegister() &&
1093 spilled_double_registers_[value->index()] != NULL) {
1094 translation->MarkDuplicate();
1095 cgen->AddToTranslation(translation,
1096 spilled_double_registers_[value->index()],
1097 false);
1098 }
1099 }
1100
1101 cgen->AddToTranslation(translation, value, HasTaggedValueAt(i));
1102 }
1103 }
1104
1105
1106 void LEnvironment::PrintTo(StringStream* stream) const {
1107 stream->Add("[id=%d|", ast_id());
1108 stream->Add("[parameters=%d|", parameter_count());
1109 stream->Add("[arguments_stack_height=%d|", arguments_stack_height());
1110 for (int i = 0; i < values_.length(); ++i) {
1111 if (i != 0) stream->Add(";");
1112 if (values_[i] == NULL) {
1113 stream->Add("[hole]");
1114 } else {
1115 values_[i]->PrintTo(stream);
1116 }
1117 }
1118 stream->Add("]");
1119 }
1120
1121
1122 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) { 897 LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
1123 if (hydrogen_env == NULL) return NULL; 898 if (hydrogen_env == NULL) return NULL;
1124 899
1125 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer()); 900 LEnvironment* outer = CreateEnvironment(hydrogen_env->outer());
1126 int ast_id = hydrogen_env->ast_id(); 901 int ast_id = hydrogen_env->ast_id();
1127 ASSERT(ast_id != AstNode::kNoNumber); 902 ASSERT(ast_id != AstNode::kNoNumber);
1128 int value_count = hydrogen_env->values()->length(); 903 int value_count = hydrogen_env->length();
1129 LEnvironment* result = new LEnvironment(hydrogen_env->closure(), 904 LEnvironment* result = new LEnvironment(hydrogen_env->closure(),
1130 ast_id, 905 ast_id,
1131 hydrogen_env->parameter_count(), 906 hydrogen_env->parameter_count(),
1132 argument_count_, 907 argument_count_,
1133 value_count, 908 value_count,
1134 outer); 909 outer);
1135 int argument_index = 0; 910 int argument_index = 0;
1136 for (int i = 0; i < value_count; ++i) { 911 for (int i = 0; i < value_count; ++i) {
1137 HValue* value = hydrogen_env->values()->at(i); 912 HValue* value = hydrogen_env->values()->at(i);
1138 LOperand* op = NULL; 913 LOperand* op = NULL;
1139 if (value->IsArgumentsObject()) { 914 if (value->IsArgumentsObject()) {
1140 op = NULL; 915 op = NULL;
1141 } else if (value->IsPushArgument()) { 916 } else if (value->IsPushArgument()) {
1142 op = new LArgument(argument_index++); 917 op = new LArgument(argument_index++);
1143 } else { 918 } else {
1144 op = UseOrConstant(value); 919 op = UseOrConstant(value);
1145 if (op->IsUnallocated()) { 920 if (op->IsUnallocated()) {
1146 LUnallocated* unalloc = LUnallocated::cast(op); 921 LUnallocated* unalloc = LUnallocated::cast(op);
1147 unalloc->set_policy(LUnallocated::ANY); 922 unalloc->set_policy(LUnallocated::ANY);
1148 } 923 }
1149 } 924 }
1150 result->AddValue(op, value->representation()); 925 result->AddValue(op, value->representation());
1151 } 926 }
1152 927
1153 return result; 928 return result;
1154 } 929 }
1155 930
1156 931
1157 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { 932 LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
1158 LInstruction* result = new LGoto(instr->FirstSuccessor()->block_id(), 933 LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(),
1159 instr->include_stack_check()); 934 instr->include_stack_check());
1160 if (instr->include_stack_check()) result = AssignPointerMap(result); 935 return (instr->include_stack_check())
1161 return result; 936 ? AssignPointerMap(result)
937 : result;
1162 } 938 }
1163 939
1164 940
1165 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { 941 LInstruction* LChunkBuilder::DoBranch(HBranch* instr) {
1166 HValue* v = instr->value(); 942 HValue* v = instr->value();
1167 HBasicBlock* first = instr->FirstSuccessor(); 943 HBasicBlock* first = instr->FirstSuccessor();
1168 HBasicBlock* second = instr->SecondSuccessor(); 944 HBasicBlock* second = instr->SecondSuccessor();
1169 ASSERT(first != NULL && second != NULL); 945 ASSERT(first != NULL && second != NULL);
1170 int first_id = first->block_id(); 946 int first_id = first->block_id();
1171 int second_id = second->block_id(); 947 int second_id = second->block_id();
1172 948
1173 if (v->EmitAtUses()) { 949 if (v->EmitAtUses()) {
1174 if (v->IsClassOfTest()) { 950 if (v->IsClassOfTest()) {
1175 HClassOfTest* compare = HClassOfTest::cast(v); 951 HClassOfTest* compare = HClassOfTest::cast(v);
1176 ASSERT(compare->value()->representation().IsTagged()); 952 ASSERT(compare->value()->representation().IsTagged());
1177 953
1178 return new LClassOfTestAndBranch(UseTempRegister(compare->value()), 954 return new LClassOfTestAndBranch(UseTempRegister(compare->value()),
1179 TempRegister(), 955 TempRegister(),
1180 TempRegister(), 956 TempRegister(),
1181 first_id, 957 first_id,
1182 second_id); 958 second_id);
1183 } else if (v->IsCompare()) { 959 } else if (v->IsCompare()) {
1184 HCompare* compare = HCompare::cast(v); 960 HCompare* compare = HCompare::cast(v);
1185 Token::Value op = compare->token(); 961 Token::Value op = compare->token();
1186 HValue* left = compare->left(); 962 HValue* left = compare->left();
1187 HValue* right = compare->right(); 963 HValue* right = compare->right();
1188 if (left->representation().IsInteger32()) { 964 Representation r = compare->GetInputRepresentation();
965 if (r.IsInteger32()) {
966 ASSERT(left->representation().IsInteger32());
1189 ASSERT(right->representation().IsInteger32()); 967 ASSERT(right->representation().IsInteger32());
1190 return new LCmpIDAndBranch(op, 968
1191 UseRegisterAtStart(left), 969 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1192 UseOrConstantAtStart(right), 970 UseOrConstantAtStart(right),
1193 first_id, 971 first_id,
1194 second_id, 972 second_id);
1195 false); 973 } else if (r.IsDouble()) {
1196 } else if (left->representation().IsDouble()) { 974 ASSERT(left->representation().IsDouble());
1197 ASSERT(right->representation().IsDouble()); 975 ASSERT(right->representation().IsDouble());
1198 return new LCmpIDAndBranch(op, 976
1199 UseRegisterAtStart(left), 977 return new LCmpIDAndBranch(UseRegisterAtStart(left),
1200 UseRegisterAtStart(right), 978 UseRegisterAtStart(right),
1201 first_id, 979 first_id,
1202 second_id, 980 second_id);
1203 true);
1204 } else { 981 } else {
1205 ASSERT(left->representation().IsTagged()); 982 ASSERT(left->representation().IsTagged());
1206 ASSERT(right->representation().IsTagged()); 983 ASSERT(right->representation().IsTagged());
1207 bool reversed = op == Token::GT || op == Token::LTE; 984 bool reversed = op == Token::GT || op == Token::LTE;
1208 LOperand* left_operand = UseFixed(left, reversed ? eax : edx); 985 LOperand* left_operand = UseFixed(left, reversed ? eax : edx);
1209 LOperand* right_operand = UseFixed(right, reversed ? edx : eax); 986 LOperand* right_operand = UseFixed(right, reversed ? edx : eax);
1210 LInstruction* result = new LCmpTAndBranch(left_operand, 987 LCmpTAndBranch* result = new LCmpTAndBranch(left_operand,
1211 right_operand, 988 right_operand,
1212 first_id, 989 first_id,
1213 second_id); 990 second_id);
1214 return MarkAsCall(result, instr); 991 return MarkAsCall(result, instr);
1215 } 992 }
1216 } else if (v->IsIsSmi()) { 993 } else if (v->IsIsSmi()) {
1217 HIsSmi* compare = HIsSmi::cast(v); 994 HIsSmi* compare = HIsSmi::cast(v);
1218 ASSERT(compare->value()->representation().IsTagged()); 995 ASSERT(compare->value()->representation().IsTagged());
1219 996
1220 return new LIsSmiAndBranch(Use(compare->value()), 997 return new LIsSmiAndBranch(Use(compare->value()),
1221 first_id, 998 first_id,
1222 second_id); 999 second_id);
1223 } else if (v->IsHasInstanceType()) { 1000 } else if (v->IsHasInstanceType()) {
(...skipping 10 matching lines...) Expand all
1234 1011
1235 return new LHasCachedArrayIndexAndBranch( 1012 return new LHasCachedArrayIndexAndBranch(
1236 UseRegisterAtStart(compare->value()), first_id, second_id); 1013 UseRegisterAtStart(compare->value()), first_id, second_id);
1237 } else if (v->IsIsNull()) { 1014 } else if (v->IsIsNull()) {
1238 HIsNull* compare = HIsNull::cast(v); 1015 HIsNull* compare = HIsNull::cast(v);
1239 ASSERT(compare->value()->representation().IsTagged()); 1016 ASSERT(compare->value()->representation().IsTagged());
1240 1017
1241 // We only need a temp register for non-strict compare. 1018 // We only need a temp register for non-strict compare.
1242 LOperand* temp = compare->is_strict() ? NULL : TempRegister(); 1019 LOperand* temp = compare->is_strict() ? NULL : TempRegister();
1243 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), 1020 return new LIsNullAndBranch(UseRegisterAtStart(compare->value()),
1244 compare->is_strict(),
1245 temp, 1021 temp,
1246 first_id, 1022 first_id,
1247 second_id); 1023 second_id);
1248 } else if (v->IsIsObject()) { 1024 } else if (v->IsIsObject()) {
1249 HIsObject* compare = HIsObject::cast(v); 1025 HIsObject* compare = HIsObject::cast(v);
1250 ASSERT(compare->value()->representation().IsTagged()); 1026 ASSERT(compare->value()->representation().IsTagged());
1251 1027
1252 LOperand* temp1 = TempRegister(); 1028 LOperand* temp1 = TempRegister();
1253 LOperand* temp2 = TempRegister(); 1029 LOperand* temp2 = TempRegister();
1254 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), 1030 return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()),
1255 temp1, 1031 temp1,
1256 temp2, 1032 temp2,
1257 first_id, 1033 first_id,
1258 second_id); 1034 second_id);
1259 } else if (v->IsCompareJSObjectEq()) { 1035 } else if (v->IsCompareJSObjectEq()) {
1260 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); 1036 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1261 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), 1037 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1262 UseRegisterAtStart(compare->right()), 1038 UseRegisterAtStart(compare->right()),
1263 first_id, 1039 first_id,
1264 second_id); 1040 second_id);
1265 } else if (v->IsInstanceOf()) { 1041 } else if (v->IsInstanceOf()) {
1266 HInstanceOf* instance_of = HInstanceOf::cast(v); 1042 HInstanceOf* instance_of = HInstanceOf::cast(v);
1267 LInstruction* result = 1043 LInstanceOfAndBranch* result =
1268 new LInstanceOfAndBranch(UseFixed(instance_of->left(), eax), 1044 new LInstanceOfAndBranch(
1269 UseFixed(instance_of->right(), edx), 1045 UseFixed(instance_of->left(), InstanceofStub::left()),
1270 first_id, 1046 UseFixed(instance_of->right(), InstanceofStub::right()),
1271 second_id); 1047 first_id,
1048 second_id);
1272 return MarkAsCall(result, instr); 1049 return MarkAsCall(result, instr);
1273 } else if (v->IsTypeofIs()) { 1050 } else if (v->IsTypeofIs()) {
1274 HTypeofIs* typeof_is = HTypeofIs::cast(v); 1051 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1275 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), 1052 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()),
1276 first_id, 1053 first_id,
1277 second_id); 1054 second_id);
1278 } else { 1055 } else {
1279 if (v->IsConstant()) { 1056 if (v->IsConstant()) {
1280 if (HConstant::cast(v)->handle()->IsTrue()) { 1057 if (HConstant::cast(v)->handle()->IsTrue()) {
1281 return new LGoto(first_id); 1058 return new LGoto(first_id);
1282 } else if (HConstant::cast(v)->handle()->IsFalse()) { 1059 } else if (HConstant::cast(v)->handle()->IsFalse()) {
1283 return new LGoto(second_id); 1060 return new LGoto(second_id);
1284 } 1061 }
1285 } 1062 }
1286 Abort("Undefined compare before branch"); 1063 Abort("Undefined compare before branch");
1287 return NULL; 1064 return NULL;
1288 } 1065 }
1289 } 1066 }
1290 return new LBranch(UseRegisterAtStart(v), first_id, second_id); 1067 return new LBranch(UseRegisterAtStart(v), first_id, second_id);
1291 } 1068 }
1292 1069
1293 1070
1294 LInstruction* LChunkBuilder::DoCompareMapAndBranch( 1071 LInstruction* LChunkBuilder::DoCompareMapAndBranch(
1295 HCompareMapAndBranch* instr) { 1072 HCompareMapAndBranch* instr) {
1296 ASSERT(instr->value()->representation().IsTagged()); 1073 ASSERT(instr->value()->representation().IsTagged());
1297 LOperand* value = UseRegisterAtStart(instr->value()); 1074 LOperand* value = UseRegisterAtStart(instr->value());
1298 HBasicBlock* first = instr->FirstSuccessor(); 1075 return new LCmpMapAndBranch(value);
1299 HBasicBlock* second = instr->SecondSuccessor();
1300 return new LCmpMapAndBranch(value,
1301 instr->map(),
1302 first->block_id(),
1303 second->block_id());
1304 } 1076 }
1305 1077
1306 1078
1307 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { 1079 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
1308 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); 1080 return DefineAsRegister(new LArgumentsLength(Use(length->value())));
1309 } 1081 }
1310 1082
1311 1083
1312 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { 1084 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
1313 return DefineAsRegister(new LArgumentsElements); 1085 return DefineAsRegister(new LArgumentsElements);
1314 } 1086 }
1315 1087
1316 1088
1317 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { 1089 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1318 LInstruction* result = 1090 LInstanceOf* result =
1319 new LInstanceOf(UseFixed(instr->left(), eax), 1091 new LInstanceOf(UseFixed(instr->left(), InstanceofStub::left()),
1320 UseFixed(instr->right(), edx)); 1092 UseFixed(instr->right(), InstanceofStub::right()));
1321 return MarkAsCall(DefineFixed(result, eax), instr); 1093 return MarkAsCall(DefineFixed(result, eax), instr);
1322 } 1094 }
1323 1095
1324 1096
1097 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1098 HInstanceOfKnownGlobal* instr) {
1099 LInstanceOfKnownGlobal* result =
1100 new LInstanceOfKnownGlobal(
1101 UseFixed(instr->value(), InstanceofStub::left()),
1102 FixedTemp(edi));
1103 MarkAsSaveDoubles(result);
1104 return AssignEnvironment(AssignPointerMap(DefineFixed(result, eax)));
1105 }
1106
1107
1325 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1108 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1326 LOperand* function = UseFixed(instr->function(), edi); 1109 LOperand* function = UseFixed(instr->function(), edi);
1327 LOperand* receiver = UseFixed(instr->receiver(), eax); 1110 LOperand* receiver = UseFixed(instr->receiver(), eax);
1328 LOperand* length = UseRegisterAtStart(instr->length()); 1111 LOperand* length = UseRegisterAtStart(instr->length());
1329 LOperand* elements = UseRegisterAtStart(instr->elements()); 1112 LOperand* elements = UseRegisterAtStart(instr->elements());
1330 LInstruction* result = new LApplyArguments(function, 1113 LApplyArguments* result = new LApplyArguments(function,
1331 receiver, 1114 receiver,
1332 length, 1115 length,
1333 elements); 1116 elements);
1334 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); 1117 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
1335 } 1118 }
1336 1119
1337 1120
1338 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) { 1121 LInstruction* LChunkBuilder::DoPushArgument(HPushArgument* instr) {
1339 ++argument_count_; 1122 ++argument_count_;
1340 LOperand* argument = UseOrConstant(instr->argument()); 1123 LOperand* argument = UseOrConstant(instr->argument());
1341 return new LPushArgument(argument); 1124 return new LPushArgument(argument);
1342 } 1125 }
1343 1126
(...skipping 12 matching lines...) Expand all
1356 HCallConstantFunction* instr) { 1139 HCallConstantFunction* instr) {
1357 argument_count_ -= instr->argument_count(); 1140 argument_count_ -= instr->argument_count();
1358 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr); 1141 return MarkAsCall(DefineFixed(new LCallConstantFunction, eax), instr);
1359 } 1142 }
1360 1143
1361 1144
1362 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { 1145 LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
1363 BuiltinFunctionId op = instr->op(); 1146 BuiltinFunctionId op = instr->op();
1364 if (op == kMathLog || op == kMathSin || op == kMathCos) { 1147 if (op == kMathLog || op == kMathSin || op == kMathCos) {
1365 LOperand* input = UseFixedDouble(instr->value(), xmm1); 1148 LOperand* input = UseFixedDouble(instr->value(), xmm1);
1366 LInstruction* result = new LUnaryMathOperation(input); 1149 LUnaryMathOperation* result = new LUnaryMathOperation(input);
1367 return MarkAsCall(DefineFixedDouble(result, xmm1), instr); 1150 return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
1368 } else { 1151 } else {
1369 LOperand* input = UseRegisterAtStart(instr->value()); 1152 LOperand* input = UseRegisterAtStart(instr->value());
1370 LInstruction* result = new LUnaryMathOperation(input); 1153 LUnaryMathOperation* result = new LUnaryMathOperation(input);
1371 switch (op) { 1154 switch (op) {
1372 case kMathAbs: 1155 case kMathAbs:
1373 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1156 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1374 case kMathFloor: 1157 case kMathFloor:
1375 return AssignEnvironment(DefineAsRegister(result)); 1158 return AssignEnvironment(DefineAsRegister(result));
1376 case kMathRound: 1159 case kMathRound:
1377 return AssignEnvironment(DefineAsRegister(result)); 1160 return AssignEnvironment(DefineAsRegister(result));
1378 case kMathSqrt: 1161 case kMathSqrt:
1379 return DefineSameAsFirst(result); 1162 return DefineSameAsFirst(result);
1380 case kMathPowHalf: 1163 case kMathPowHalf:
(...skipping 28 matching lines...) Expand all
1409 1192
1410 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) { 1193 LInstruction* LChunkBuilder::DoCallKnownGlobal(HCallKnownGlobal* instr) {
1411 argument_count_ -= instr->argument_count(); 1194 argument_count_ -= instr->argument_count();
1412 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr); 1195 return MarkAsCall(DefineFixed(new LCallKnownGlobal, eax), instr);
1413 } 1196 }
1414 1197
1415 1198
1416 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { 1199 LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) {
1417 LOperand* constructor = UseFixed(instr->constructor(), edi); 1200 LOperand* constructor = UseFixed(instr->constructor(), edi);
1418 argument_count_ -= instr->argument_count(); 1201 argument_count_ -= instr->argument_count();
1419 LInstruction* result = new LCallNew(constructor); 1202 LCallNew* result = new LCallNew(constructor);
1420 return MarkAsCall(DefineFixed(result, eax), instr); 1203 return MarkAsCall(DefineFixed(result, eax), instr);
1421 } 1204 }
1422 1205
1423 1206
1424 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) { 1207 LInstruction* LChunkBuilder::DoCallFunction(HCallFunction* instr) {
1425 argument_count_ -= instr->argument_count(); 1208 argument_count_ -= instr->argument_count();
1426 return MarkAsCall(DefineFixed(new LCallFunction, eax), instr); 1209 return MarkAsCall(DefineFixed(new LCallFunction, eax), instr);
1427 } 1210 }
1428 1211
1429 1212
(...skipping 19 matching lines...) Expand all
1449 1232
1450 1233
1451 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) { 1234 LInstruction* LChunkBuilder::DoBitAnd(HBitAnd* instr) {
1452 return DoBit(Token::BIT_AND, instr); 1235 return DoBit(Token::BIT_AND, instr);
1453 } 1236 }
1454 1237
1455 1238
1456 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) { 1239 LInstruction* LChunkBuilder::DoBitNot(HBitNot* instr) {
1457 ASSERT(instr->value()->representation().IsInteger32()); 1240 ASSERT(instr->value()->representation().IsInteger32());
1458 ASSERT(instr->representation().IsInteger32()); 1241 ASSERT(instr->representation().IsInteger32());
1459 return DefineSameAsFirst(new LBitNotI(UseRegisterAtStart(instr->value()))); 1242 LOperand* input = UseRegisterAtStart(instr->value());
1243 LBitNotI* result = new LBitNotI(input);
1244 return DefineSameAsFirst(result);
1460 } 1245 }
1461 1246
1462 1247
1463 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) { 1248 LInstruction* LChunkBuilder::DoBitOr(HBitOr* instr) {
1464 return DoBit(Token::BIT_OR, instr); 1249 return DoBit(Token::BIT_OR, instr);
1465 } 1250 }
1466 1251
1467 1252
1468 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) { 1253 LInstruction* LChunkBuilder::DoBitXor(HBitXor* instr) {
1469 return DoBit(Token::BIT_XOR, instr); 1254 return DoBit(Token::BIT_XOR, instr);
(...skipping 19 matching lines...) Expand all
1489 1274
1490 LInstruction* LChunkBuilder::DoMod(HMod* instr) { 1275 LInstruction* LChunkBuilder::DoMod(HMod* instr) {
1491 if (instr->representation().IsInteger32()) { 1276 if (instr->representation().IsInteger32()) {
1492 ASSERT(instr->left()->representation().IsInteger32()); 1277 ASSERT(instr->left()->representation().IsInteger32());
1493 ASSERT(instr->right()->representation().IsInteger32()); 1278 ASSERT(instr->right()->representation().IsInteger32());
1494 // The temporary operand is necessary to ensure that right is not allocated 1279 // The temporary operand is necessary to ensure that right is not allocated
1495 // into edx. 1280 // into edx.
1496 FixedTemp(edx); 1281 FixedTemp(edx);
1497 LOperand* value = UseFixed(instr->left(), eax); 1282 LOperand* value = UseFixed(instr->left(), eax);
1498 LOperand* divisor = UseRegister(instr->right()); 1283 LOperand* divisor = UseRegister(instr->right());
1499 LInstruction* result = DefineFixed(new LModI(value, divisor), edx); 1284 LModI* mod = new LModI(value, divisor);
1500 if (instr->CheckFlag(HValue::kBailoutOnMinusZero) || 1285 LInstruction* result = DefineFixed(mod, edx);
1501 instr->CheckFlag(HValue::kCanBeDivByZero)) { 1286 return (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
1502 result = AssignEnvironment(result); 1287 instr->CheckFlag(HValue::kCanBeDivByZero))
1503 } 1288 ? AssignEnvironment(result)
1504 return result; 1289 : result;
1505 } else if (instr->representation().IsTagged()) { 1290 } else if (instr->representation().IsTagged()) {
1506 return DoArithmeticT(Token::MOD, instr); 1291 return DoArithmeticT(Token::MOD, instr);
1507 } else { 1292 } else {
1508 ASSERT(instr->representation().IsDouble()); 1293 ASSERT(instr->representation().IsDouble());
1509 // We call a C function for double modulo. It can't trigger a GC. 1294 // We call a C function for double modulo. It can't trigger a GC.
1510 // We need to use fixed result register for the call. 1295 // We need to use fixed result register for the call.
1511 // TODO(fschneider): Allow any register as input registers. 1296 // TODO(fschneider): Allow any register as input registers.
1512 LOperand* left = UseFixedDouble(instr->left(), xmm1); 1297 LOperand* left = UseFixedDouble(instr->left(), xmm1);
1513 LOperand* right = UseFixedDouble(instr->right(), xmm2); 1298 LOperand* right = UseFixedDouble(instr->right(), xmm2);
1514 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right); 1299 LArithmeticD* result = new LArithmeticD(Token::MOD, left, right);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1591 UseFixedDouble(instr->right(), xmm2) : 1376 UseFixedDouble(instr->right(), xmm2) :
1592 UseFixed(instr->right(), eax); 1377 UseFixed(instr->right(), eax);
1593 LPower* result = new LPower(left, right); 1378 LPower* result = new LPower(left, right);
1594 return MarkAsCall(DefineFixedDouble(result, xmm3), instr, 1379 return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
1595 CAN_DEOPTIMIZE_EAGERLY); 1380 CAN_DEOPTIMIZE_EAGERLY);
1596 } 1381 }
1597 1382
1598 1383
1599 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) { 1384 LInstruction* LChunkBuilder::DoCompare(HCompare* instr) {
1600 Token::Value op = instr->token(); 1385 Token::Value op = instr->token();
1601 if (instr->left()->representation().IsInteger32()) { 1386 Representation r = instr->GetInputRepresentation();
1387 if (r.IsInteger32()) {
1388 ASSERT(instr->left()->representation().IsInteger32());
1602 ASSERT(instr->right()->representation().IsInteger32()); 1389 ASSERT(instr->right()->representation().IsInteger32());
1603 LOperand* left = UseRegisterAtStart(instr->left()); 1390 LOperand* left = UseRegisterAtStart(instr->left());
1604 LOperand* right = UseOrConstantAtStart(instr->right()); 1391 LOperand* right = UseOrConstantAtStart(instr->right());
1605 return DefineAsRegister(new LCmpID(op, left, right, false)); 1392 return DefineAsRegister(new LCmpID(left, right));
1606 } else if (instr->left()->representation().IsDouble()) { 1393 } else if (r.IsDouble()) {
1394 ASSERT(instr->left()->representation().IsDouble());
1607 ASSERT(instr->right()->representation().IsDouble()); 1395 ASSERT(instr->right()->representation().IsDouble());
1608 LOperand* left = UseRegisterAtStart(instr->left()); 1396 LOperand* left = UseRegisterAtStart(instr->left());
1609 LOperand* right = UseRegisterAtStart(instr->right()); 1397 LOperand* right = UseRegisterAtStart(instr->right());
1610 return DefineAsRegister(new LCmpID(op, left, right, true)); 1398 return DefineAsRegister(new LCmpID(left, right));
1611 } else { 1399 } else {
1400 ASSERT(instr->left()->representation().IsTagged());
1401 ASSERT(instr->right()->representation().IsTagged());
1612 bool reversed = (op == Token::GT || op == Token::LTE); 1402 bool reversed = (op == Token::GT || op == Token::LTE);
1613 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx); 1403 LOperand* left = UseFixed(instr->left(), reversed ? eax : edx);
1614 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax); 1404 LOperand* right = UseFixed(instr->right(), reversed ? edx : eax);
1615 LInstruction* result = new LCmpT(left, right); 1405 LCmpT* result = new LCmpT(left, right);
1616 return MarkAsCall(DefineFixed(result, eax), instr); 1406 return MarkAsCall(DefineFixed(result, eax), instr);
1617 } 1407 }
1618 } 1408 }
1619 1409
1620 1410
1621 LInstruction* LChunkBuilder::DoCompareJSObjectEq( 1411 LInstruction* LChunkBuilder::DoCompareJSObjectEq(
1622 HCompareJSObjectEq* instr) { 1412 HCompareJSObjectEq* instr) {
1623 LOperand* left = UseRegisterAtStart(instr->left()); 1413 LOperand* left = UseRegisterAtStart(instr->left());
1624 LOperand* right = UseRegisterAtStart(instr->right()); 1414 LOperand* right = UseRegisterAtStart(instr->right());
1625 LInstruction* result = new LCmpJSObjectEq(left, right); 1415 LCmpJSObjectEq* result = new LCmpJSObjectEq(left, right);
1626 return DefineAsRegister(result); 1416 return DefineAsRegister(result);
1627 } 1417 }
1628 1418
1629 1419
1630 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) { 1420 LInstruction* LChunkBuilder::DoIsNull(HIsNull* instr) {
1631 ASSERT(instr->value()->representation().IsTagged()); 1421 ASSERT(instr->value()->representation().IsTagged());
1632 LOperand* value = UseRegisterAtStart(instr->value()); 1422 LOperand* value = UseRegisterAtStart(instr->value());
1633 1423
1634 return DefineAsRegister(new LIsNull(value, 1424 return DefineAsRegister(new LIsNull(value));
1635 instr->is_strict()));
1636 } 1425 }
1637 1426
1638 1427
1639 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { 1428 LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) {
1640 ASSERT(instr->value()->representation().IsTagged()); 1429 ASSERT(instr->value()->representation().IsTagged());
1641 LOperand* value = UseRegister(instr->value()); 1430 LOperand* value = UseRegister(instr->value());
1642 1431
1643 return DefineAsRegister(new LIsObject(value, TempRegister())); 1432 return DefineAsRegister(new LIsObject(value, TempRegister()));
1644 } 1433 }
1645 1434
(...skipping 24 matching lines...) Expand all
1670 1459
1671 1460
1672 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) { 1461 LInstruction* LChunkBuilder::DoClassOfTest(HClassOfTest* instr) {
1673 ASSERT(instr->value()->representation().IsTagged()); 1462 ASSERT(instr->value()->representation().IsTagged());
1674 LOperand* value = UseTempRegister(instr->value()); 1463 LOperand* value = UseTempRegister(instr->value());
1675 1464
1676 return DefineSameAsFirst(new LClassOfTest(value, TempRegister())); 1465 return DefineSameAsFirst(new LClassOfTest(value, TempRegister()));
1677 } 1466 }
1678 1467
1679 1468
1680 LInstruction* LChunkBuilder::DoArrayLength(HArrayLength* instr) { 1469 LInstruction* LChunkBuilder::DoJSArrayLength(HJSArrayLength* instr) {
1681 LOperand* array = NULL; 1470 LOperand* array = UseRegisterAtStart(instr->value());
1682 LOperand* temporary = NULL; 1471 return DefineAsRegister(new LJSArrayLength(array));
1472 }
1683 1473
1684 if (instr->value()->IsLoadElements()) {
1685 array = UseRegisterAtStart(instr->value());
1686 } else {
1687 array = UseRegister(instr->value());
1688 temporary = TempRegister();
1689 }
1690 1474
1691 LInstruction* result = new LArrayLength(array, temporary); 1475 LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
1692 return AssignEnvironment(DefineAsRegister(result)); 1476 LOperand* array = UseRegisterAtStart(instr->value());
1477 return DefineAsRegister(new LFixedArrayLength(array));
1693 } 1478 }
1694 1479
1695 1480
1696 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1481 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1697 LOperand* object = UseRegister(instr->value()); 1482 LOperand* object = UseRegister(instr->value());
1698 LInstruction* result = new LValueOf(object, TempRegister()); 1483 LValueOf* result = new LValueOf(object, TempRegister());
1699 return AssignEnvironment(DefineSameAsFirst(result)); 1484 return AssignEnvironment(DefineSameAsFirst(result));
1700 } 1485 }
1701 1486
1702 1487
1703 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1488 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1704 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1489 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1705 Use(instr->length()))); 1490 Use(instr->length())));
1706 } 1491 }
1707 1492
1708 1493
1709 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1494 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1710 LOperand* value = UseFixed(instr->value(), eax); 1495 LOperand* value = UseFixed(instr->value(), eax);
1711 return MarkAsCall(new LThrow(value), instr); 1496 return MarkAsCall(new LThrow(value), instr);
1712 } 1497 }
1713 1498
1714 1499
1715 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1500 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
1716 Representation from = instr->from(); 1501 Representation from = instr->from();
1717 Representation to = instr->to(); 1502 Representation to = instr->to();
1718 if (from.IsTagged()) { 1503 if (from.IsTagged()) {
1719 if (to.IsDouble()) { 1504 if (to.IsDouble()) {
1720 LOperand* value = UseRegister(instr->value()); 1505 LOperand* value = UseRegister(instr->value());
1721 LInstruction* res = new LNumberUntagD(value); 1506 LNumberUntagD* res = new LNumberUntagD(value);
1722 return AssignEnvironment(DefineAsRegister(res)); 1507 return AssignEnvironment(DefineAsRegister(res));
1723 } else { 1508 } else {
1724 ASSERT(to.IsInteger32()); 1509 ASSERT(to.IsInteger32());
1725 LOperand* value = UseRegister(instr->value()); 1510 LOperand* value = UseRegister(instr->value());
1726 bool needs_check = !instr->value()->type().IsSmi(); 1511 bool needs_check = !instr->value()->type().IsSmi();
1727 if (needs_check) { 1512 if (needs_check) {
1728 CpuFeatures* cpu_features = Isolate::Current()->cpu_features(); 1513 CpuFeatures* cpu_features = Isolate::Current()->cpu_features();
1729 LOperand* xmm_temp = 1514 LOperand* xmm_temp =
1730 (instr->CanTruncateToInt32() && !cpu_features->IsSupported(SSE3)) 1515 (instr->CanTruncateToInt32() && !cpu_features->IsSupported(SSE3))
1731 ? NULL 1516 ? NULL
1732 : FixedTemp(xmm1); 1517 : FixedTemp(xmm1);
1733 LInstruction* res = new LTaggedToI(value, xmm_temp); 1518 LTaggedToI* res = new LTaggedToI(value, xmm_temp);
1734 return AssignEnvironment(DefineSameAsFirst(res)); 1519 return AssignEnvironment(DefineSameAsFirst(res));
1735 } else { 1520 } else {
1736 return DefineSameAsFirst(new LSmiUntag(value, needs_check)); 1521 return DefineSameAsFirst(new LSmiUntag(value, needs_check));
1737 } 1522 }
1738 } 1523 }
1739 } else if (from.IsDouble()) { 1524 } else if (from.IsDouble()) {
1740 if (to.IsTagged()) { 1525 if (to.IsTagged()) {
1741 LOperand* value = UseRegister(instr->value()); 1526 LOperand* value = UseRegister(instr->value());
1742 LOperand* temp = TempRegister(); 1527 LOperand* temp = TempRegister();
1743 1528
1744 // Make sure that temp and result_temp are different registers. 1529 // Make sure that temp and result_temp are different registers.
1745 LUnallocated* result_temp = TempRegister(); 1530 LUnallocated* result_temp = TempRegister();
1746 LInstruction* result = new LNumberTagD(value, temp); 1531 LNumberTagD* result = new LNumberTagD(value, temp);
1747 return AssignPointerMap(Define(result, result_temp)); 1532 return AssignPointerMap(Define(result, result_temp));
1748 } else { 1533 } else {
1749 ASSERT(to.IsInteger32()); 1534 ASSERT(to.IsInteger32());
1750 LOperand* value = UseRegister(instr->value()); 1535 bool needs_temp = instr->CanTruncateToInt32() &&
1751 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value))); 1536 !Isolate::Current()->cpu_features()->IsSupported(SSE3);
1537 LOperand* value = needs_temp ?
1538 UseTempRegister(instr->value()) : UseRegister(instr->value());
1539 LOperand* temp = needs_temp ? TempRegister() : NULL;
1540 return AssignEnvironment(DefineAsRegister(new LDoubleToI(value, temp)));
1752 } 1541 }
1753 } else if (from.IsInteger32()) { 1542 } else if (from.IsInteger32()) {
1754 if (to.IsTagged()) { 1543 if (to.IsTagged()) {
1755 HValue* val = instr->value(); 1544 HValue* val = instr->value();
1756 LOperand* value = UseRegister(val); 1545 LOperand* value = UseRegister(val);
1757 if (val->HasRange() && val->range()->IsInSmiRange()) { 1546 if (val->HasRange() && val->range()->IsInSmiRange()) {
1758 return DefineSameAsFirst(new LSmiTag(value)); 1547 return DefineSameAsFirst(new LSmiTag(value));
1759 } else { 1548 } else {
1760 LInstruction* result = new LNumberTagI(value); 1549 LNumberTagI* result = new LNumberTagI(value);
1761 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result))); 1550 return AssignEnvironment(AssignPointerMap(DefineSameAsFirst(result)));
1762 } 1551 }
1763 } else { 1552 } else {
1764 ASSERT(to.IsDouble()); 1553 ASSERT(to.IsDouble());
1765 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value()))); 1554 return DefineAsRegister(new LInteger32ToDouble(Use(instr->value())));
1766 } 1555 }
1767 } 1556 }
1768 UNREACHABLE(); 1557 UNREACHABLE();
1769 return NULL; 1558 return NULL;
1770 } 1559 }
1771 1560
1772 1561
1773 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { 1562 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
1774 LOperand* value = UseRegisterAtStart(instr->value()); 1563 LOperand* value = UseRegisterAtStart(instr->value());
1775 return AssignEnvironment(new LCheckSmi(value, zero)); 1564 return AssignEnvironment(new LCheckSmi(value, zero));
1776 } 1565 }
1777 1566
1778 1567
1779 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { 1568 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1780 LOperand* value = UseRegisterAtStart(instr->value()); 1569 LOperand* value = UseRegisterAtStart(instr->value());
1781 LOperand* temp = TempRegister(); 1570 LOperand* temp = TempRegister();
1782 LInstruction* result = new LCheckInstanceType(value, temp); 1571 LCheckInstanceType* result = new LCheckInstanceType(value, temp);
1783 return AssignEnvironment(result); 1572 return AssignEnvironment(result);
1784 } 1573 }
1785 1574
1786 1575
1787 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { 1576 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) {
1788 LOperand* temp = TempRegister(); 1577 LOperand* temp = TempRegister();
1789 LInstruction* result = 1578 LCheckPrototypeMaps* result = new LCheckPrototypeMaps(temp);
1790 new LCheckPrototypeMaps(temp,
1791 instr->holder(),
1792 instr->receiver_map());
1793 return AssignEnvironment(result); 1579 return AssignEnvironment(result);
1794 } 1580 }
1795 1581
1796 1582
1797 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { 1583 LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) {
1798 LOperand* value = UseRegisterAtStart(instr->value()); 1584 LOperand* value = UseRegisterAtStart(instr->value());
1799 return AssignEnvironment(new LCheckSmi(value, not_zero)); 1585 return AssignEnvironment(new LCheckSmi(value, not_zero));
1800 } 1586 }
1801 1587
1802 1588
1803 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) { 1589 LInstruction* LChunkBuilder::DoCheckFunction(HCheckFunction* instr) {
1804 LOperand* value = UseRegisterAtStart(instr->value()); 1590 LOperand* value = UseRegisterAtStart(instr->value());
1805 return AssignEnvironment(new LCheckFunction(value)); 1591 return AssignEnvironment(new LCheckFunction(value));
1806 } 1592 }
1807 1593
1808 1594
1809 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) { 1595 LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
1810 LOperand* value = UseRegisterAtStart(instr->value()); 1596 LOperand* value = UseRegisterAtStart(instr->value());
1811 LInstruction* result = new LCheckMap(value); 1597 LCheckMap* result = new LCheckMap(value);
1812 return AssignEnvironment(result); 1598 return AssignEnvironment(result);
1813 } 1599 }
1814 1600
1815 1601
1816 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 1602 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
1817 return new LReturn(UseFixed(instr->value(), eax)); 1603 return new LReturn(UseFixed(instr->value(), eax));
1818 } 1604 }
1819 1605
1820 1606
1821 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 1607 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
1822 Representation r = instr->representation(); 1608 Representation r = instr->representation();
1823 if (r.IsInteger32()) { 1609 if (r.IsInteger32()) {
1824 int32_t value = instr->Integer32Value(); 1610 int32_t value = instr->Integer32Value();
1825 return DefineAsRegister(new LConstantI(value)); 1611 return DefineAsRegister(new LConstantI(value));
1826 } else if (r.IsDouble()) { 1612 } else if (r.IsDouble()) {
1827 double value = instr->DoubleValue(); 1613 double value = instr->DoubleValue();
1828 return DefineAsRegister(new LConstantD(value)); 1614 return DefineAsRegister(new LConstantD(value));
1829 } else if (r.IsTagged()) { 1615 } else if (r.IsTagged()) {
1830 return DefineAsRegister(new LConstantT(instr->handle())); 1616 return DefineAsRegister(new LConstantT(instr->handle()));
1831 } else { 1617 } else {
1832 Abort("unsupported constant of type double"); 1618 Abort("unsupported constant of type double");
1833 return NULL; 1619 return NULL;
1834 } 1620 }
1835 } 1621 }
1836 1622
1837 1623
1838 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) { 1624 LInstruction* LChunkBuilder::DoLoadGlobal(HLoadGlobal* instr) {
1839 LInstruction* result = new LLoadGlobal; 1625 LLoadGlobal* result = new LLoadGlobal;
1840 return instr->check_hole_value() 1626 return instr->check_hole_value()
1841 ? AssignEnvironment(DefineAsRegister(result)) 1627 ? AssignEnvironment(DefineAsRegister(result))
1842 : DefineAsRegister(result); 1628 : DefineAsRegister(result);
1843 } 1629 }
1844 1630
1845 1631
1846 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) { 1632 LInstruction* LChunkBuilder::DoStoreGlobal(HStoreGlobal* instr) {
1847 return new LStoreGlobal(UseRegisterAtStart(instr->value())); 1633 return new LStoreGlobal(UseRegisterAtStart(instr->value()));
1848 } 1634 }
1849 1635
1850 1636
1851 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) { 1637 LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
1852 return DefineAsRegister( 1638 ASSERT(instr->representation().IsTagged());
1853 new LLoadNamedField(UseRegisterAtStart(instr->object()))); 1639 LOperand* obj = UseRegisterAtStart(instr->object());
1640 return DefineAsRegister(new LLoadNamedField(obj));
1854 } 1641 }
1855 1642
1856 1643
1857 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { 1644 LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
1858 LOperand* object = UseFixed(instr->object(), eax); 1645 LOperand* object = UseFixed(instr->object(), eax);
1859 LInstruction* result = DefineFixed(new LLoadNamedGeneric(object), eax); 1646 LLoadNamedGeneric* result = new LLoadNamedGeneric(object);
1860 return MarkAsCall(result, instr); 1647 return MarkAsCall(DefineFixed(result, eax), instr);
1648 }
1649
1650
1651 LInstruction* LChunkBuilder::DoLoadFunctionPrototype(
1652 HLoadFunctionPrototype* instr) {
1653 return AssignEnvironment(DefineAsRegister(
1654 new LLoadFunctionPrototype(UseRegister(instr->function()),
1655 TempRegister())));
1861 } 1656 }
1862 1657
1863 1658
1864 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) { 1659 LInstruction* LChunkBuilder::DoLoadElements(HLoadElements* instr) {
1865 LOperand* input = UseRegisterAtStart(instr->value()); 1660 LOperand* input = UseRegisterAtStart(instr->value());
1866 return DefineSameAsFirst(new LLoadElements(input)); 1661 return DefineSameAsFirst(new LLoadElements(input));
1867 } 1662 }
1868 1663
1869 1664
1870 LInstruction* LChunkBuilder::DoLoadKeyedFastElement( 1665 LInstruction* LChunkBuilder::DoLoadKeyedFastElement(
1871 HLoadKeyedFastElement* instr) { 1666 HLoadKeyedFastElement* instr) {
1872 Representation r = instr->representation(); 1667 ASSERT(instr->representation().IsTagged());
1668 ASSERT(instr->key()->representation().IsInteger32());
1873 LOperand* obj = UseRegisterAtStart(instr->object()); 1669 LOperand* obj = UseRegisterAtStart(instr->object());
1874 ASSERT(instr->key()->representation().IsInteger32());
1875 LOperand* key = UseRegisterAtStart(instr->key()); 1670 LOperand* key = UseRegisterAtStart(instr->key());
1876 LOperand* load_result = NULL; 1671 LLoadKeyedFastElement* result = new LLoadKeyedFastElement(obj, key);
1877 // Double needs an extra temp, because the result is converted from heap 1672 return AssignEnvironment(DefineSameAsFirst(result));
1878 // number to a double register.
1879 if (r.IsDouble()) load_result = TempRegister();
1880 LInstruction* result = new LLoadKeyedFastElement(obj,
1881 key,
1882 load_result);
1883 if (r.IsDouble()) {
1884 result = DefineAsRegister(result);
1885 } else {
1886 result = DefineSameAsFirst(result);
1887 }
1888 return AssignEnvironment(result);
1889 } 1673 }
1890 1674
1891 1675
1892 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { 1676 LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
1893 LOperand* object = UseFixed(instr->object(), edx); 1677 LOperand* object = UseFixed(instr->object(), edx);
1894 LOperand* key = UseFixed(instr->key(), eax); 1678 LOperand* key = UseFixed(instr->key(), eax);
1895 1679
1896 LInstruction* result = 1680 LLoadKeyedGeneric* result = new LLoadKeyedGeneric(object, key);
1897 DefineFixed(new LLoadKeyedGeneric(object, key), eax); 1681 return MarkAsCall(DefineFixed(result, eax), instr);
1898 return MarkAsCall(result, instr);
1899 } 1682 }
1900 1683
1901 1684
1902 LInstruction* LChunkBuilder::DoStoreKeyedFastElement( 1685 LInstruction* LChunkBuilder::DoStoreKeyedFastElement(
1903 HStoreKeyedFastElement* instr) { 1686 HStoreKeyedFastElement* instr) {
1904 bool needs_write_barrier = instr->NeedsWriteBarrier(); 1687 bool needs_write_barrier = instr->NeedsWriteBarrier();
1905 ASSERT(instr->value()->representation().IsTagged()); 1688 ASSERT(instr->value()->representation().IsTagged());
1906 ASSERT(instr->object()->representation().IsTagged()); 1689 ASSERT(instr->object()->representation().IsTagged());
1907 ASSERT(instr->key()->representation().IsInteger32()); 1690 ASSERT(instr->key()->representation().IsInteger32());
1908 1691
(...skipping 16 matching lines...) Expand all
1925 1708
1926 ASSERT(instr->object()->representation().IsTagged()); 1709 ASSERT(instr->object()->representation().IsTagged());
1927 ASSERT(instr->key()->representation().IsTagged()); 1710 ASSERT(instr->key()->representation().IsTagged());
1928 ASSERT(instr->value()->representation().IsTagged()); 1711 ASSERT(instr->value()->representation().IsTagged());
1929 1712
1930 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr); 1713 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr);
1931 } 1714 }
1932 1715
1933 1716
1934 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { 1717 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
1935 bool needs_write_barrier = !instr->value()->type().IsSmi(); 1718 bool needs_write_barrier = instr->NeedsWriteBarrier();
1936 1719
1937 LOperand* obj = needs_write_barrier 1720 LOperand* obj = needs_write_barrier
1938 ? UseTempRegister(instr->object()) 1721 ? UseTempRegister(instr->object())
1939 : UseRegisterAtStart(instr->object()); 1722 : UseRegisterAtStart(instr->object());
1940 1723
1941 LOperand* val = needs_write_barrier 1724 LOperand* val = needs_write_barrier
1942 ? UseTempRegister(instr->value()) 1725 ? UseTempRegister(instr->value())
1943 : UseRegister(instr->value()); 1726 : UseRegister(instr->value());
1944 1727
1945 // We only need a scratch register if we have a write barrier or we 1728 // We only need a scratch register if we have a write barrier or we
1946 // have a store into the properties array (not in-object-property). 1729 // have a store into the properties array (not in-object-property).
1947 LOperand* temp = (!instr->is_in_object() || needs_write_barrier) 1730 LOperand* temp = (!instr->is_in_object() || needs_write_barrier)
1948 ? TempRegister() : NULL; 1731 ? TempRegister() : NULL;
1949 1732
1950 return new LStoreNamedField(obj, 1733 return new LStoreNamedField(obj, val, temp);
1951 instr->name(),
1952 val,
1953 instr->is_in_object(),
1954 instr->offset(),
1955 temp,
1956 needs_write_barrier,
1957 instr->transition());
1958 } 1734 }
1959 1735
1960 1736
1961 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 1737 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
1962 LOperand* obj = UseFixed(instr->object(), edx); 1738 LOperand* obj = UseFixed(instr->object(), edx);
1963 LOperand* val = UseFixed(instr->value(), eax); 1739 LOperand* val = UseFixed(instr->value(), eax);
1964 1740
1965 LInstruction* result = new LStoreNamedGeneric(obj, instr->name(), val); 1741 LStoreNamedGeneric* result = new LStoreNamedGeneric(obj, val);
1966 return MarkAsCall(result, instr); 1742 return MarkAsCall(result, instr);
1967 } 1743 }
1968 1744
1969 1745
1970 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) { 1746 LInstruction* LChunkBuilder::DoArrayLiteral(HArrayLiteral* instr) {
1971 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr); 1747 return MarkAsCall(DefineFixed(new LArrayLiteral, eax), instr);
1972 } 1748 }
1973 1749
1974 1750
1975 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) { 1751 LInstruction* LChunkBuilder::DoObjectLiteral(HObjectLiteral* instr) {
1976 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr); 1752 return MarkAsCall(DefineFixed(new LObjectLiteral, eax), instr);
1977 } 1753 }
1978 1754
1979 1755
1980 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) { 1756 LInstruction* LChunkBuilder::DoRegExpLiteral(HRegExpLiteral* instr) {
1981 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr); 1757 return MarkAsCall(DefineFixed(new LRegExpLiteral, eax), instr);
1982 } 1758 }
1983 1759
1984 1760
1985 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) { 1761 LInstruction* LChunkBuilder::DoFunctionLiteral(HFunctionLiteral* instr) {
1986 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr); 1762 return MarkAsCall(DefineFixed(new LFunctionLiteral, eax), instr);
1987 } 1763 }
1988 1764
1989 1765
1990 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) { 1766 LInstruction* LChunkBuilder::DoDeleteProperty(HDeleteProperty* instr) {
1991 LInstruction* result = new LDeleteProperty(Use(instr->object()), 1767 LDeleteProperty* result = new LDeleteProperty(Use(instr->object()),
1992 UseOrConstant(instr->key())); 1768 UseOrConstant(instr->key()));
1993 return MarkAsCall(DefineFixed(result, eax), instr); 1769 return MarkAsCall(DefineFixed(result, eax), instr);
1994 } 1770 }
1995 1771
1996 1772
1997 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) { 1773 LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
1998 allocator_->MarkAsOsrEntry(); 1774 allocator_->MarkAsOsrEntry();
1999 current_block_->last_environment()->set_ast_id(instr->ast_id()); 1775 current_block_->last_environment()->set_ast_id(instr->ast_id());
2000 return AssignEnvironment(new LOsrEntry); 1776 return AssignEnvironment(new LOsrEntry);
2001 } 1777 }
2002 1778
(...skipping 20 matching lines...) Expand all
2023 // There are no real uses of the arguments object (we bail out in all other 1799 // There are no real uses of the arguments object (we bail out in all other
2024 // cases). 1800 // cases).
2025 return NULL; 1801 return NULL;
2026 } 1802 }
2027 1803
2028 1804
2029 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 1805 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2030 LOperand* arguments = UseRegister(instr->arguments()); 1806 LOperand* arguments = UseRegister(instr->arguments());
2031 LOperand* length = UseTempRegister(instr->length()); 1807 LOperand* length = UseTempRegister(instr->length());
2032 LOperand* index = Use(instr->index()); 1808 LOperand* index = Use(instr->index());
2033 LInstruction* result = new LAccessArgumentsAt(arguments, length, index); 1809 LAccessArgumentsAt* result = new LAccessArgumentsAt(arguments, length, index);
2034 return DefineAsRegister(AssignEnvironment(result)); 1810 return AssignEnvironment(DefineAsRegister(result));
2035 } 1811 }
2036 1812
2037 1813
2038 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 1814 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2039 LInstruction* result = new LTypeof(Use(instr->value())); 1815 LTypeof* result = new LTypeof(UseAtStart(instr->value()));
2040 return MarkAsCall(DefineFixed(result, eax), instr); 1816 return MarkAsCall(DefineFixed(result, eax), instr);
2041 } 1817 }
2042 1818
2043 1819
2044 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 1820 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
2045 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); 1821 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
2046 } 1822 }
2047 1823
2048 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 1824 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2049 HEnvironment* env = current_block_->last_environment(); 1825 HEnvironment* env = current_block_->last_environment();
2050 ASSERT(env != NULL); 1826 ASSERT(env != NULL);
2051 1827
2052 env->set_ast_id(instr->ast_id()); 1828 env->set_ast_id(instr->ast_id());
2053 1829
2054 env->Drop(instr->pop_count()); 1830 env->Drop(instr->pop_count());
2055 for (int i = 0; i < instr->values()->length(); ++i) { 1831 for (int i = 0; i < instr->values()->length(); ++i) {
2056 HValue* value = instr->values()->at(i); 1832 HValue* value = instr->values()->at(i);
2057 if (instr->HasAssignedIndexAt(i)) { 1833 if (instr->HasAssignedIndexAt(i)) {
2058 env->Bind(instr->GetAssignedIndexAt(i), value); 1834 env->Bind(instr->GetAssignedIndexAt(i), value);
2059 } else { 1835 } else {
2060 env->Push(value); 1836 env->Push(value);
2061 } 1837 }
2062 } 1838 }
2063 1839 ASSERT(env->length() == instr->environment_length());
2064 if (FLAG_trace_environment) {
2065 PrintF("Reconstructed environment ast_id=%d, instr_id=%d\n",
2066 instr->ast_id(),
2067 instr->id());
2068 env->PrintToStd();
2069 }
2070 ASSERT(env->values()->length() == instr->environment_height());
2071 1840
2072 // If there is an instruction pending deoptimization environment create a 1841 // If there is an instruction pending deoptimization environment create a
2073 // lazy bailout instruction to capture the environment. 1842 // lazy bailout instruction to capture the environment.
2074 if (pending_deoptimization_ast_id_ == instr->ast_id()) { 1843 if (pending_deoptimization_ast_id_ == instr->ast_id()) {
2075 LInstruction* result = new LLazyBailout; 1844 LLazyBailout* lazy_bailout = new LLazyBailout;
2076 result = AssignEnvironment(result); 1845 LInstruction* result = AssignEnvironment(lazy_bailout);
2077 instructions_pending_deoptimization_environment_-> 1846 instructions_pending_deoptimization_environment_->
2078 set_deoptimization_environment(result->environment()); 1847 set_deoptimization_environment(result->environment());
2079 ClearInstructionPendingDeoptimizationEnvironment(); 1848 ClearInstructionPendingDeoptimizationEnvironment();
2080 return result; 1849 return result;
2081 } 1850 }
2082 1851
2083 return NULL; 1852 return NULL;
2084 } 1853 }
2085 1854
2086 1855
(...skipping 15 matching lines...) Expand all
2102 } 1871 }
2103 1872
2104 1873
2105 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) { 1874 LInstruction* LChunkBuilder::DoLeaveInlined(HLeaveInlined* instr) {
2106 HEnvironment* outer = current_block_->last_environment()->outer(); 1875 HEnvironment* outer = current_block_->last_environment()->outer();
2107 current_block_->UpdateEnvironment(outer); 1876 current_block_->UpdateEnvironment(outer);
2108 return NULL; 1877 return NULL;
2109 } 1878 }
2110 1879
2111 1880
2112 void LPointerMap::RecordPointer(LOperand* op) { 1881 } } // namespace v8::internal
2113 // Do not record arguments as pointers.
2114 if (op->IsStackSlot() && op->index() < 0) return;
2115 ASSERT(!op->IsDoubleRegister() && !op->IsDoubleStackSlot());
2116 pointer_operands_.Add(op);
2117 }
2118 1882
2119 1883 #endif // V8_TARGET_ARCH_IA32
2120 void LPointerMap::PrintTo(StringStream* stream) const {
2121 stream->Add("{");
2122 for (int i = 0; i < pointer_operands_.length(); ++i) {
2123 if (i != 0) stream->Add(";");
2124 pointer_operands_[i]->PrintTo(stream);
2125 }
2126 stream->Add("} @%d", position());
2127 }
2128
2129 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698