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

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

Issue 6113004: Version 3.0.7 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 years, 11 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.
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 arguments()->PrintTo(stream); 315 arguments()->PrintTo(stream);
316 316
317 stream->Add(" length "); 317 stream->Add(" length ");
318 length()->PrintTo(stream); 318 length()->PrintTo(stream);
319 319
320 stream->Add(" index "); 320 stream->Add(" index ");
321 index()->PrintTo(stream); 321 index()->PrintTo(stream);
322 } 322 }
323 323
324 324
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 { 325 void LChunk::Verify() const {
335 // TODO(twuerthinger): Implement verification for chunk. 326 // TODO(twuerthinger): Implement verification for chunk.
336 } 327 }
337 328
338 329
339 int LChunk::GetNextSpillIndex(bool is_double) { 330 int LChunk::GetNextSpillIndex(bool is_double) {
340 // Skip a slot if for a double-width slot. 331 // Skip a slot if for a double-width slot.
341 if (is_double) spill_slot_count_++; 332 if (is_double) spill_slot_count_++;
342 return spill_slot_count_++; 333 return spill_slot_count_++;
343 } 334 }
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 while (!IsGapAt(index)) index--; 456 while (!IsGapAt(index)) index--;
466 return index; 457 return index;
467 } 458 }
468 459
469 460
470 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) { 461 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
471 GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to); 462 GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to);
472 } 463 }
473 464
474 465
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 { 466 Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
621 return HConstant::cast(graph_->LookupValue(operand->index()))->handle(); 467 return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
622 } 468 }
623 469
624 470
625 Representation LChunk::LookupLiteralRepresentation( 471 Representation LChunk::LookupLiteralRepresentation(
626 LConstantOperand* operand) const { 472 LConstantOperand* operand) const {
627 return graph_->LookupValue(operand->index())->representation(); 473 return graph_->LookupValue(operand->index())->representation();
628 } 474 }
629 475
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
826 bool needs_environment = 672 bool needs_environment =
827 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects(); 673 (can_deoptimize == CAN_DEOPTIMIZE_EAGERLY) || !hinstr->HasSideEffects();
828 if (needs_environment && !instr->HasEnvironment()) { 674 if (needs_environment && !instr->HasEnvironment()) {
829 instr = AssignEnvironment(instr); 675 instr = AssignEnvironment(instr);
830 } 676 }
831 677
832 return instr; 678 return instr;
833 } 679 }
834 680
835 681
682 LInstruction* LChunkBuilder::MarkAsSaveDoubles(LInstruction* instr) {
683 allocator_->MarkAsSaveDoubles();
684 return instr;
685 }
686
687
836 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) { 688 LInstruction* LChunkBuilder::AssignPointerMap(LInstruction* instr) {
837 ASSERT(!instr->HasPointerMap()); 689 ASSERT(!instr->HasPointerMap());
838 instr->set_pointer_map(new LPointerMap(position_)); 690 instr->set_pointer_map(new LPointerMap(position_));
839 return instr; 691 return instr;
840 } 692 }
841 693
842 694
843 LInstruction* LChunkBuilder::Define(LInstruction* instr, LUnallocated* result) { 695 LInstruction* LChunkBuilder::Define(LInstruction* instr, LUnallocated* result) {
844 allocator_->RecordDefinition(current_instruction_, result); 696 allocator_->RecordDefinition(current_instruction_, result);
845 instr->set_result(result); 697 instr->set_result(result);
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 second_id); 1102 second_id);
1251 } else if (v->IsCompareJSObjectEq()) { 1103 } else if (v->IsCompareJSObjectEq()) {
1252 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); 1104 HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v);
1253 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), 1105 return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()),
1254 UseRegisterAtStart(compare->right()), 1106 UseRegisterAtStart(compare->right()),
1255 first_id, 1107 first_id,
1256 second_id); 1108 second_id);
1257 } else if (v->IsInstanceOf()) { 1109 } else if (v->IsInstanceOf()) {
1258 HInstanceOf* instance_of = HInstanceOf::cast(v); 1110 HInstanceOf* instance_of = HInstanceOf::cast(v);
1259 LInstruction* result = 1111 LInstruction* result =
1260 new LInstanceOfAndBranch(UseFixed(instance_of->left(), eax), 1112 new LInstanceOfAndBranch(
1261 UseFixed(instance_of->right(), edx), 1113 UseFixed(instance_of->left(), InstanceofStub::left()),
1262 first_id, 1114 UseFixed(instance_of->right(), InstanceofStub::right()),
1263 second_id); 1115 first_id,
1116 second_id);
1264 return MarkAsCall(result, instr); 1117 return MarkAsCall(result, instr);
1265 } else if (v->IsTypeofIs()) { 1118 } else if (v->IsTypeofIs()) {
1266 HTypeofIs* typeof_is = HTypeofIs::cast(v); 1119 HTypeofIs* typeof_is = HTypeofIs::cast(v);
1267 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), 1120 return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()),
1268 first_id, 1121 first_id,
1269 second_id); 1122 second_id);
1270 } else { 1123 } else {
1271 if (v->IsConstant()) { 1124 if (v->IsConstant()) {
1272 if (HConstant::cast(v)->handle()->IsTrue()) { 1125 if (HConstant::cast(v)->handle()->IsTrue()) {
1273 return new LGoto(first_id); 1126 return new LGoto(first_id);
1274 } else if (HConstant::cast(v)->handle()->IsFalse()) { 1127 } else if (HConstant::cast(v)->handle()->IsFalse()) {
1275 return new LGoto(second_id); 1128 return new LGoto(second_id);
1276 } 1129 }
1277 } 1130 }
1278 Abort("Undefined compare before branch"); 1131 Abort("Undefined compare before branch");
1279 return NULL; 1132 return NULL;
1280 } 1133 }
1281 } 1134 }
1282 return new LBranch(UseRegisterAtStart(v), first_id, second_id); 1135 return new LBranch(UseRegisterAtStart(v), first_id, second_id);
1283 } 1136 }
1284 1137
1285 1138
1286 LInstruction* LChunkBuilder::DoCompareMapAndBranch( 1139 LInstruction* LChunkBuilder::DoCompareMapAndBranch(
1287 HCompareMapAndBranch* instr) { 1140 HCompareMapAndBranch* instr) {
1288 ASSERT(instr->value()->representation().IsTagged()); 1141 ASSERT(instr->value()->representation().IsTagged());
1289 LOperand* value = UseRegisterAtStart(instr->value()); 1142 LOperand* value = UseRegisterAtStart(instr->value());
1290 HBasicBlock* first = instr->FirstSuccessor(); 1143 return new LCmpMapAndBranch(value);
1291 HBasicBlock* second = instr->SecondSuccessor();
1292 return new LCmpMapAndBranch(value,
1293 instr->map(),
1294 first->block_id(),
1295 second->block_id());
1296 } 1144 }
1297 1145
1298 1146
1299 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { 1147 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
1300 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); 1148 return DefineAsRegister(new LArgumentsLength(Use(length->value())));
1301 } 1149 }
1302 1150
1303 1151
1304 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { 1152 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
1305 return DefineAsRegister(new LArgumentsElements); 1153 return DefineAsRegister(new LArgumentsElements);
1306 } 1154 }
1307 1155
1308 1156
1309 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { 1157 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1310 LInstruction* result = 1158 LInstruction* result =
1311 new LInstanceOf(UseFixed(instr->left(), eax), 1159 new LInstanceOf(UseFixed(instr->left(), InstanceofStub::left()),
1312 UseFixed(instr->right(), edx)); 1160 UseFixed(instr->right(), InstanceofStub::right()));
1313 return MarkAsCall(DefineFixed(result, eax), instr); 1161 return MarkAsCall(DefineFixed(result, eax), instr);
1314 } 1162 }
1315 1163
1316 1164
1165 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1166 HInstanceOfKnownGlobal* instr) {
1167 LInstruction* result =
1168 new LInstanceOfKnownGlobal(
1169 UseFixed(instr->value(), InstanceofStub::left()),
1170 FixedTemp(edi));
1171 MarkAsSaveDoubles(result);
1172 return AssignEnvironment(AssignPointerMap(DefineFixed(result, eax)));
1173 }
1174
1175
1317 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1176 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1318 LOperand* function = UseFixed(instr->function(), edi); 1177 LOperand* function = UseFixed(instr->function(), edi);
1319 LOperand* receiver = UseFixed(instr->receiver(), eax); 1178 LOperand* receiver = UseFixed(instr->receiver(), eax);
1320 LOperand* length = UseRegisterAtStart(instr->length()); 1179 LOperand* length = UseRegisterAtStart(instr->length());
1321 LOperand* elements = UseRegisterAtStart(instr->elements()); 1180 LOperand* elements = UseRegisterAtStart(instr->elements());
1322 LInstruction* result = new LApplyArguments(function, 1181 LInstruction* result = new LApplyArguments(function,
1323 receiver, 1182 receiver,
1324 length, 1183 length,
1325 elements); 1184 elements);
1326 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY); 1185 return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after
2108 void LPointerMap::PrintTo(StringStream* stream) const { 1967 void LPointerMap::PrintTo(StringStream* stream) const {
2109 stream->Add("{"); 1968 stream->Add("{");
2110 for (int i = 0; i < pointer_operands_.length(); ++i) { 1969 for (int i = 0; i < pointer_operands_.length(); ++i) {
2111 if (i != 0) stream->Add(";"); 1970 if (i != 0) stream->Add(";");
2112 pointer_operands_[i]->PrintTo(stream); 1971 pointer_operands_[i]->PrintTo(stream);
2113 } 1972 }
2114 stream->Add("} @%d", position()); 1973 stream->Add("} @%d", position());
2115 } 1974 }
2116 1975
2117 } } // namespace v8::internal 1976 } } // 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