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

Side by Side Diff: src/arm/lithium-arm.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/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.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 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 while (!IsGapAt(index)) index--; 465 while (!IsGapAt(index)) index--;
466 return index; 466 return index;
467 } 467 }
468 468
469 469
470 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) { 470 void LChunk::AddGapMove(int index, LOperand* from, LOperand* to) {
471 GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to); 471 GetGapAt(index)->GetOrCreateParallelMove(LGap::START)->AddMove(from, to);
472 } 472 }
473 473
474 474
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 { 475 Handle<Object> LChunk::LookupLiteral(LConstantOperand* operand) const {
621 return HConstant::cast(graph_->LookupValue(operand->index()))->handle(); 476 return HConstant::cast(graph_->LookupValue(operand->index()))->handle();
622 } 477 }
623 478
624 479
625 Representation LChunk::LookupLiteralRepresentation( 480 Representation LChunk::LookupLiteralRepresentation(
626 LConstantOperand* operand) const { 481 LConstantOperand* operand) const {
627 return graph_->LookupValue(operand->index())->representation(); 482 return graph_->LookupValue(operand->index())->representation();
628 } 483 }
629 484
(...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after
1282 LInstruction* LChunkBuilder::DoCompareMapAndBranch( 1137 LInstruction* LChunkBuilder::DoCompareMapAndBranch(
1283 HCompareMapAndBranch* instr) { 1138 HCompareMapAndBranch* instr) {
1284 ASSERT(instr->value()->representation().IsTagged()); 1139 ASSERT(instr->value()->representation().IsTagged());
1285 LOperand* value = UseRegisterAtStart(instr->value()); 1140 LOperand* value = UseRegisterAtStart(instr->value());
1286 LOperand* temp = TempRegister(); 1141 LOperand* temp = TempRegister();
1287 return new LCmpMapAndBranch(value, temp); 1142 return new LCmpMapAndBranch(value, temp);
1288 } 1143 }
1289 1144
1290 1145
1291 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) { 1146 LInstruction* LChunkBuilder::DoArgumentsLength(HArgumentsLength* length) {
1292 return DefineAsRegister(new LArgumentsLength(Use(length->value()))); 1147 return DefineAsRegister(new LArgumentsLength(UseRegister(length->value())));
1293 } 1148 }
1294 1149
1295 1150
1296 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { 1151 LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) {
1297 return DefineAsRegister(new LArgumentsElements); 1152 return DefineAsRegister(new LArgumentsElements);
1298 } 1153 }
1299 1154
1300 1155
1301 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { 1156 LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) {
1302 LInstruction* result = 1157 LInstruction* result =
1303 new LInstanceOf(UseFixed(instr->left(), r0), 1158 new LInstanceOf(UseFixed(instr->left(), r0),
1304 UseFixed(instr->right(), r1)); 1159 UseFixed(instr->right(), r1));
1305 return MarkAsCall(DefineFixed(result, r0), instr); 1160 return MarkAsCall(DefineFixed(result, r0), instr);
1306 } 1161 }
1307 1162
1308 1163
1164 LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal(
1165 HInstanceOfKnownGlobal* instr) {
1166 LInstruction* result =
1167 new LInstanceOfKnownGlobal(UseFixed(instr->value(), r0));
1168 return MarkAsCall(DefineFixed(result, r0), instr);
1169 }
1170
1171
1309 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) { 1172 LInstruction* LChunkBuilder::DoApplyArguments(HApplyArguments* instr) {
1310 LOperand* function = UseFixed(instr->function(), r1); 1173 LOperand* function = UseFixed(instr->function(), r1);
1311 LOperand* receiver = UseFixed(instr->receiver(), r0); 1174 LOperand* receiver = UseFixed(instr->receiver(), r0);
1312 LOperand* length = UseRegisterAtStart(instr->length()); 1175 LOperand* length = UseRegisterAtStart(instr->length());
1313 LOperand* elements = UseRegisterAtStart(instr->elements()); 1176 LOperand* elements = UseRegisterAtStart(instr->elements());
1314 LInstruction* result = new LApplyArguments(function, 1177 LInstruction* result = new LApplyArguments(function,
1315 receiver, 1178 receiver,
1316 length, 1179 length,
1317 elements); 1180 elements);
1318 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY); 1181 return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 1530
1668 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) { 1531 LInstruction* LChunkBuilder::DoValueOf(HValueOf* instr) {
1669 LOperand* object = UseRegister(instr->value()); 1532 LOperand* object = UseRegister(instr->value());
1670 LInstruction* result = new LValueOf(object, TempRegister()); 1533 LInstruction* result = new LValueOf(object, TempRegister());
1671 return AssignEnvironment(DefineSameAsFirst(result)); 1534 return AssignEnvironment(DefineSameAsFirst(result));
1672 } 1535 }
1673 1536
1674 1537
1675 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { 1538 LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) {
1676 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()), 1539 return AssignEnvironment(new LBoundsCheck(UseRegisterAtStart(instr->index()),
1677 Use(instr->length()))); 1540 UseRegister(instr->length())));
1678 } 1541 }
1679 1542
1680 1543
1681 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) { 1544 LInstruction* LChunkBuilder::DoThrow(HThrow* instr) {
1682 LOperand* value = UseFixed(instr->value(), r0); 1545 LOperand* value = UseFixed(instr->value(), r0);
1683 return MarkAsCall(new LThrow(value), instr); 1546 return MarkAsCall(new LThrow(value), instr);
1684 } 1547 }
1685 1548
1686 1549
1687 LInstruction* LChunkBuilder::DoChange(HChange* instr) { 1550 LInstruction* LChunkBuilder::DoChange(HChange* instr) {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 1610
1748 1611
1749 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) { 1612 LInstruction* LChunkBuilder::DoCheckNonSmi(HCheckNonSmi* instr) {
1750 LOperand* value = UseRegisterAtStart(instr->value()); 1613 LOperand* value = UseRegisterAtStart(instr->value());
1751 return AssignEnvironment(new LCheckSmi(value, eq)); 1614 return AssignEnvironment(new LCheckSmi(value, eq));
1752 } 1615 }
1753 1616
1754 1617
1755 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { 1618 LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) {
1756 LOperand* value = UseRegisterAtStart(instr->value()); 1619 LOperand* value = UseRegisterAtStart(instr->value());
1757 LOperand* temp = TempRegister(); 1620 LInstruction* result = new LCheckInstanceType(value);
1758 LInstruction* result = new LCheckInstanceType(value, temp);
1759 return AssignEnvironment(result); 1621 return AssignEnvironment(result);
1760 } 1622 }
1761 1623
1762 1624
1763 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) { 1625 LInstruction* LChunkBuilder::DoCheckPrototypeMaps(HCheckPrototypeMaps* instr) {
1764 LOperand* temp1 = TempRegister(); 1626 LOperand* temp1 = TempRegister();
1765 LOperand* temp2 = TempRegister(); 1627 LOperand* temp2 = TempRegister();
1766 LInstruction* result = 1628 LInstruction* result =
1767 new LCheckPrototypeMaps(temp1, 1629 new LCheckPrototypeMaps(temp1,
1768 temp2, 1630 temp2,
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1910 1772
1911 ASSERT(instr->object()->representation().IsTagged()); 1773 ASSERT(instr->object()->representation().IsTagged());
1912 ASSERT(instr->key()->representation().IsTagged()); 1774 ASSERT(instr->key()->representation().IsTagged());
1913 ASSERT(instr->value()->representation().IsTagged()); 1775 ASSERT(instr->value()->representation().IsTagged());
1914 1776
1915 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr); 1777 return MarkAsCall(new LStoreKeyedGeneric(obj, key, val), instr);
1916 } 1778 }
1917 1779
1918 1780
1919 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { 1781 LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) {
1920 bool needs_write_barrier = !instr->value()->type().IsSmi(); 1782 bool needs_write_barrier = instr->NeedsWriteBarrier();
1921 1783
1922 LOperand* obj = needs_write_barrier 1784 LOperand* obj = needs_write_barrier
1923 ? UseTempRegister(instr->object()) 1785 ? UseTempRegister(instr->object())
1924 : UseRegisterAtStart(instr->object()); 1786 : UseRegisterAtStart(instr->object());
1925 1787
1926 LOperand* val = needs_write_barrier 1788 LOperand* val = needs_write_barrier
1927 ? UseTempRegister(instr->value()) 1789 ? UseTempRegister(instr->value())
1928 : UseRegister(instr->value()); 1790 : UseRegister(instr->value());
1929 1791
1930 // We only need a scratch register if we have a write barrier or we
1931 // have a store into the properties array (not in-object-property).
1932 LOperand* temp = (!instr->is_in_object() || needs_write_barrier)
1933 ? TempRegister() : NULL;
1934
1935 return new LStoreNamedField(obj, 1792 return new LStoreNamedField(obj,
1936 instr->name(), 1793 instr->name(),
1937 val, 1794 val,
1938 instr->is_in_object(), 1795 instr->is_in_object(),
1939 instr->offset(), 1796 instr->offset(),
1940 temp,
1941 needs_write_barrier, 1797 needs_write_barrier,
1942 instr->transition()); 1798 instr->transition());
1943 } 1799 }
1944 1800
1945 1801
1946 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) { 1802 LInstruction* LChunkBuilder::DoStoreNamedGeneric(HStoreNamedGeneric* instr) {
1947 LOperand* obj = UseFixed(instr->object(), r1); 1803 LOperand* obj = UseFixed(instr->object(), r1);
1948 LOperand* val = UseFixed(instr->value(), r0); 1804 LOperand* val = UseFixed(instr->value(), r0);
1949 1805
1950 LInstruction* result = new LStoreNamedGeneric(obj, instr->name(), val); 1806 LInstruction* result = new LStoreNamedGeneric(obj, instr->name(), val);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2007 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { 1863 LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) {
2008 // There are no real uses of the arguments object (we bail out in all other 1864 // There are no real uses of the arguments object (we bail out in all other
2009 // cases). 1865 // cases).
2010 return NULL; 1866 return NULL;
2011 } 1867 }
2012 1868
2013 1869
2014 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { 1870 LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
2015 LOperand* arguments = UseRegister(instr->arguments()); 1871 LOperand* arguments = UseRegister(instr->arguments());
2016 LOperand* length = UseTempRegister(instr->length()); 1872 LOperand* length = UseTempRegister(instr->length());
2017 LOperand* index = Use(instr->index()); 1873 LOperand* index = UseRegister(instr->index());
2018 LInstruction* result = new LAccessArgumentsAt(arguments, length, index); 1874 LInstruction* result = new LAccessArgumentsAt(arguments, length, index);
2019 return DefineAsRegister(AssignEnvironment(result)); 1875 return DefineAsRegister(AssignEnvironment(result));
2020 } 1876 }
2021 1877
2022 1878
2023 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { 1879 LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
2024 LInstruction* result = new LTypeof(Use(instr->value())); 1880 LInstruction* result = new LTypeof(UseRegisterAtStart(instr->value()));
2025 return MarkAsCall(DefineFixed(result, r0), instr); 1881 return MarkAsCall(DefineFixed(result, r0), instr);
2026 } 1882 }
2027 1883
2028 1884
2029 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { 1885 LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
2030 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value()))); 1886 return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
2031 } 1887 }
2032 1888
2033 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) { 1889 LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
2034 HEnvironment* env = current_block_->last_environment(); 1890 HEnvironment* env = current_block_->last_environment();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2099 void LPointerMap::PrintTo(StringStream* stream) const { 1955 void LPointerMap::PrintTo(StringStream* stream) const {
2100 stream->Add("{"); 1956 stream->Add("{");
2101 for (int i = 0; i < pointer_operands_.length(); ++i) { 1957 for (int i = 0; i < pointer_operands_.length(); ++i) {
2102 if (i != 0) stream->Add(";"); 1958 if (i != 0) stream->Add(";");
2103 pointer_operands_[i]->PrintTo(stream); 1959 pointer_operands_[i]->PrintTo(stream);
2104 } 1960 }
2105 stream->Add("} @%d", position()); 1961 stream->Add("} @%d", position());
2106 } 1962 }
2107 1963
2108 } } // namespace v8::internal 1964 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/arm/lithium-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698