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

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 552303005: Fix StoreIndexedInstr input representation requirements for Int32/Uint32 arrays. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 3 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cpu.h" 8 #include "vm/cpu.h"
9 #include "vm/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_allocator.h" 10 #include "vm/flow_graph_allocator.h"
(...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 } 1161 }
1162 1162
1163 1163
1164 void Instruction::Goto(JoinEntryInstr* entry) { 1164 void Instruction::Goto(JoinEntryInstr* entry) {
1165 LinkTo(new GotoInstr(entry)); 1165 LinkTo(new GotoInstr(entry));
1166 } 1166 }
1167 1167
1168 1168
1169 bool UnboxedIntConverterInstr::CanDeoptimize() const { 1169 bool UnboxedIntConverterInstr::CanDeoptimize() const {
1170 return (to() == kUnboxedInt32) && 1170 return (to() == kUnboxedInt32) &&
1171 !is_truncating() &&
1171 !RangeUtils::Fits(value()->definition()->range(), 1172 !RangeUtils::Fits(value()->definition()->range(),
1172 RangeBoundary::kRangeBoundaryInt32); 1173 RangeBoundary::kRangeBoundaryInt32);
1173 } 1174 }
1174 1175
1175 1176
1176 bool UnboxInt32Instr::CanDeoptimize() const { 1177 bool UnboxInt32Instr::CanDeoptimize() const {
1177 const intptr_t value_cid = value()->Type()->ToCid(); 1178 const intptr_t value_cid = value()->Type()->ToCid();
1178 if (value_cid == kSmiCid) { 1179 if (value_cid == kSmiCid) {
1179 return false; 1180 return (kSmiBits > 32) &&
1181 !is_truncating() &&
1182 !RangeUtils::Fits(value()->definition()->range(),
1183 RangeBoundary::kRangeBoundaryInt32);
1180 } else if (value_cid == kMintCid) { 1184 } else if (value_cid == kMintCid) {
1181 return !RangeUtils::Fits(value()->definition()->range(), 1185 return !is_truncating() &&
1182 RangeBoundary::kRangeBoundaryInt32); 1186 !RangeUtils::Fits(value()->definition()->range(),
1187 RangeBoundary::kRangeBoundaryInt32);
1183 } else { 1188 } else {
1184 return true; 1189 return true;
1185 } 1190 }
1186 } 1191 }
1187 1192
1188 1193
1189 bool BinaryInt32OpInstr::CanDeoptimize() const { 1194 bool BinaryInt32OpInstr::CanDeoptimize() const {
1190 switch (op_kind()) { 1195 switch (op_kind()) {
1191 case Token::kBIT_AND: 1196 case Token::kBIT_AND:
1192 case Token::kBIT_OR: 1197 case Token::kBIT_OR:
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 BoxIntNInstr* box_defn = value()->definition()->AsBoxIntN(); 1741 BoxIntNInstr* box_defn = value()->definition()->AsBoxIntN();
1737 if (box_defn != NULL) { 1742 if (box_defn != NULL) {
1738 if (box_defn->value()->definition()->representation() == representation()) { 1743 if (box_defn->value()->definition()->representation() == representation()) {
1739 return box_defn->value()->definition(); 1744 return box_defn->value()->definition();
1740 } else { 1745 } else {
1741 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( 1746 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr(
1742 box_defn->value()->definition()->representation(), 1747 box_defn->value()->definition()->representation(),
1743 representation(), 1748 representation(),
1744 box_defn->value()->CopyWithType(), 1749 box_defn->value()->CopyWithType(),
1745 representation() == kUnboxedInt32 ? deopt_id_ : Isolate::kNoDeoptId); 1750 representation() == kUnboxedInt32 ? deopt_id_ : Isolate::kNoDeoptId);
1751 if ((representation() == kUnboxedInt32) && is_truncating()) {
1752 converter->mark_truncating();
1753 }
1746 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); 1754 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
1747 return converter; 1755 return converter;
1748 } 1756 }
1749 } 1757 }
1750 1758
1751 return this; 1759 return this;
1752 } 1760 }
1753 1761
1754 1762
1755 Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) { 1763 Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) {
1756 if (!HasUses()) return NULL; 1764 if (!HasUses()) return NULL;
1757 1765
1758 UnboxedIntConverterInstr* box_defn = 1766 UnboxedIntConverterInstr* box_defn =
1759 value()->definition()->AsUnboxedIntConverter(); 1767 value()->definition()->AsUnboxedIntConverter();
1760 if ((box_defn != NULL) && (box_defn->representation() == from())) { 1768 if ((box_defn != NULL) && (box_defn->representation() == from())) {
1761 if (box_defn->from() == to()) { 1769 if (box_defn->from() == to()) {
1762 return box_defn->value()->definition(); 1770 return box_defn->value()->definition();
1763 } 1771 }
1764 1772
1765 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr( 1773 UnboxedIntConverterInstr* converter = new UnboxedIntConverterInstr(
1766 box_defn->from(), 1774 box_defn->from(),
1767 representation(), 1775 representation(),
1768 box_defn->value()->CopyWithType(), 1776 box_defn->value()->CopyWithType(),
1769 to() == kUnboxedInt32 ? deopt_id_ : NULL); 1777 to() == kUnboxedInt32 ? deopt_id_ : NULL);
1778 if ((representation() == kUnboxedInt32) && is_truncating()) {
1779 converter->mark_truncating();
1780 }
1770 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); 1781 flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
1771 return converter; 1782 return converter;
1772 } 1783 }
1773 1784
1774 UnboxIntegerInstr* unbox_defn = value()->definition()->AsUnboxInteger(); 1785 UnboxIntegerInstr* unbox_defn = value()->definition()->AsUnboxInteger();
1775 if (unbox_defn != NULL && 1786 if (unbox_defn != NULL &&
1776 (from() == kUnboxedMint) && 1787 (from() == kUnboxedMint) &&
1777 (to() == kUnboxedInt32) && 1788 (to() == kUnboxedInt32) &&
1778 unbox_defn->HasOnlyInputUse(value())) { 1789 unbox_defn->HasOnlyInputUse(value())) {
1779 // TODO(vegorov): there is a duplication of code between UnboxedIntCoverter 1790 // TODO(vegorov): there is a duplication of code between UnboxedIntCoverter
1780 // and code path that unboxes Mint into Int32. We should just schedule 1791 // and code path that unboxes Mint into Int32. We should just schedule
1781 // these instructions close to each other instead of fusing them. 1792 // these instructions close to each other instead of fusing them.
1782 Definition* replacement = 1793 Definition* replacement =
1783 new UnboxInt32Instr(unbox_defn->value()->CopyWithType(), deopt_id_); 1794 new UnboxInt32Instr(unbox_defn->value()->CopyWithType(), deopt_id_);
1795 if (is_truncating()) {
1796 replacement->AsUnboxInt32()->mark_truncating();
1797 }
1784 flow_graph->InsertBefore(this, 1798 flow_graph->InsertBefore(this,
1785 replacement, 1799 replacement,
1786 env(), 1800 env(),
1787 FlowGraph::kValue); 1801 FlowGraph::kValue);
1788 return replacement; 1802 return replacement;
1789 } 1803 }
1790 1804
1791 return this; 1805 return this;
1792 } 1806 }
1793 1807
1794 1808
1795 Definition* UnboxInt32Instr::Canonicalize(FlowGraph* flow_graph) { 1809 Definition* UnboxInt32Instr::Canonicalize(FlowGraph* flow_graph) {
1796 Definition* replacement = UnboxIntNInstr::Canonicalize(flow_graph); 1810 Definition* replacement = UnboxIntNInstr::Canonicalize(flow_graph);
1797 if (replacement != this) { 1811 if (replacement != this) {
1798 return replacement; 1812 return replacement;
1799 } 1813 }
1800 1814
1801 ConstantInstr* c = value()->definition()->AsConstant(); 1815 ConstantInstr* c = value()->definition()->AsConstant();
1802 if ((c != NULL) && c->value().IsSmi()) { 1816 if ((c != NULL) && c->value().IsSmi()) {
1817 if (!is_truncating() && (kSmiBits > 32)) {
1818 // Check that constant fits into 32-bit integer.
1819 const int64_t value =
1820 static_cast<int64_t>(Smi::Cast(c->value()).Value());
1821 if (!Utils::IsInt(32, value)) {
1822 return this;
1823 }
1824 }
1825
1803 UnboxedConstantInstr* uc = 1826 UnboxedConstantInstr* uc =
1804 new UnboxedConstantInstr(c->value(), kUnboxedInt32); 1827 new UnboxedConstantInstr(c->value(), kUnboxedInt32);
1805 flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue); 1828 flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue);
1806 return uc; 1829 return uc;
1807 } 1830 }
1808 1831
1809 return this; 1832 return this;
1810 } 1833 }
1811 1834
1812 1835
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after
3092 case Token::kTRUNCDIV: return 0; 3115 case Token::kTRUNCDIV: return 0;
3093 case Token::kMOD: return 1; 3116 case Token::kMOD: return 1;
3094 default: UNIMPLEMENTED(); return -1; 3117 default: UNIMPLEMENTED(); return -1;
3095 } 3118 }
3096 } 3119 }
3097 3120
3098 3121
3099 #undef __ 3122 #undef __
3100 3123
3101 } // namespace dart 3124 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698