Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 540 static bool HasOnlyTwoSmis(const ICData& ic_data) { | 540 static bool HasOnlyTwoSmis(const ICData& ic_data) { |
| 541 return (ic_data.NumberOfChecks() == 1) && | 541 return (ic_data.NumberOfChecks() == 1) && |
| 542 ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid); | 542 ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid); |
| 543 } | 543 } |
| 544 | 544 |
| 545 static bool HasOnlyTwoFloat32x4s(const ICData& ic_data) { | 545 static bool HasOnlyTwoFloat32x4s(const ICData& ic_data) { |
| 546 return (ic_data.NumberOfChecks() == 1) && | 546 return (ic_data.NumberOfChecks() == 1) && |
| 547 ICDataHasReceiverArgumentClassIds(ic_data, kFloat32x4Cid, kFloat32x4Cid); | 547 ICDataHasReceiverArgumentClassIds(ic_data, kFloat32x4Cid, kFloat32x4Cid); |
| 548 } | 548 } |
| 549 | 549 |
| 550 static bool HasOnlyTwoUint32x4s(const ICData& ic_data) { | |
| 551 return (ic_data.NumberOfChecks() == 1) && | |
| 552 ICDataHasReceiverArgumentClassIds(ic_data, kUint32x4Cid, kUint32x4Cid); | |
| 553 } | |
| 550 | 554 |
| 551 // Returns false if the ICData contains anything other than the 4 combinations | 555 // Returns false if the ICData contains anything other than the 4 combinations |
| 552 // of Mint and Smi for the receiver and argument classes. | 556 // of Mint and Smi for the receiver and argument classes. |
| 553 static bool HasTwoMintOrSmi(const ICData& ic_data) { | 557 static bool HasTwoMintOrSmi(const ICData& ic_data) { |
| 554 GrowableArray<intptr_t> class_ids(2); | 558 GrowableArray<intptr_t> class_ids(2); |
| 555 class_ids.Add(kSmiCid); | 559 class_ids.Add(kSmiCid); |
| 556 class_ids.Add(kMintCid); | 560 class_ids.Add(kMintCid); |
| 557 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids); | 561 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids); |
| 558 } | 562 } |
| 559 | 563 |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1018 return false; | 1022 return false; |
| 1019 } | 1023 } |
| 1020 break; | 1024 break; |
| 1021 case Token::kBIT_AND: | 1025 case Token::kBIT_AND: |
| 1022 case Token::kBIT_OR: | 1026 case Token::kBIT_OR: |
| 1023 case Token::kBIT_XOR: | 1027 case Token::kBIT_XOR: |
| 1024 if (HasOnlyTwoSmis(ic_data)) { | 1028 if (HasOnlyTwoSmis(ic_data)) { |
| 1025 operands_type = kSmiCid; | 1029 operands_type = kSmiCid; |
| 1026 } else if (HasTwoMintOrSmi(ic_data)) { | 1030 } else if (HasTwoMintOrSmi(ic_data)) { |
| 1027 operands_type = kMintCid; | 1031 operands_type = kMintCid; |
| 1032 } else if (HasOnlyTwoUint32x4s(ic_data)) { | |
| 1033 operands_type = kUint32x4Cid; | |
| 1028 } else { | 1034 } else { |
| 1029 return false; | 1035 return false; |
| 1030 } | 1036 } |
| 1031 break; | 1037 break; |
| 1032 case Token::kSHR: | 1038 case Token::kSHR: |
| 1033 case Token::kSHL: | 1039 case Token::kSHL: |
| 1034 if (HasOnlyTwoSmis(ic_data)) { | 1040 if (HasOnlyTwoSmis(ic_data)) { |
| 1035 // Left shift may overflow from smi into mint or big ints. | 1041 // Left shift may overflow from smi into mint or big ints. |
| 1036 // Don't generate smi code if the IC data is marked because | 1042 // Don't generate smi code if the IC data is marked because |
| 1037 // of an overflow. | 1043 // of an overflow. |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1106 ICData::ZoneHandle( | 1112 ICData::ZoneHandle( |
| 1107 call->ic_data()->AsUnaryClassChecksForArgNr(1)), | 1113 call->ic_data()->AsUnaryClassChecksForArgNr(1)), |
| 1108 call->deopt_id(), | 1114 call->deopt_id(), |
| 1109 call->env(), | 1115 call->env(), |
| 1110 call); | 1116 call); |
| 1111 // Replace call. | 1117 // Replace call. |
| 1112 BinaryFloat32x4OpInstr* float32x4_bin_op = | 1118 BinaryFloat32x4OpInstr* float32x4_bin_op = |
| 1113 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right), | 1119 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right), |
| 1114 call); | 1120 call); |
| 1115 ReplaceCall(call, float32x4_bin_op); | 1121 ReplaceCall(call, float32x4_bin_op); |
| 1122 } else if (operands_type == kUint32x4Cid) { | |
| 1123 // Type check left. | |
| 1124 AddCheckClass(left, | |
| 1125 ICData::ZoneHandle( | |
| 1126 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1127 call->deopt_id(), | |
| 1128 call->env(), | |
| 1129 call); | |
| 1130 // Type check right. | |
| 1131 AddCheckClass(right, | |
| 1132 ICData::ZoneHandle( | |
| 1133 call->ic_data()->AsUnaryClassChecksForArgNr(1)), | |
| 1134 call->deopt_id(), | |
| 1135 call->env(), | |
| 1136 call); | |
| 1137 // Replace call. | |
| 1138 BinaryUint32x4OpInstr* uint32x4_bin_op = | |
| 1139 new BinaryUint32x4OpInstr(op_kind, new Value(left), new Value(right), | |
| 1140 call); | |
| 1141 ReplaceCall(call, uint32x4_bin_op); | |
| 1116 } else if (op_kind == Token::kMOD) { | 1142 } else if (op_kind == Token::kMOD) { |
| 1117 // TODO(vegorov): implement fast path code for modulo. | 1143 // TODO(vegorov): implement fast path code for modulo. |
| 1118 ASSERT(operands_type == kSmiCid); | 1144 ASSERT(operands_type == kSmiCid); |
| 1119 if (!right->IsConstant()) return false; | 1145 if (!right->IsConstant()) return false; |
| 1120 const Object& obj = right->AsConstant()->value(); | 1146 const Object& obj = right->AsConstant()->value(); |
| 1121 if (!obj.IsSmi()) return false; | 1147 if (!obj.IsSmi()) return false; |
| 1122 const intptr_t value = Smi::Cast(obj).Value(); | 1148 const intptr_t value = Smi::Cast(obj).Value(); |
| 1123 if ((value <= 0) || !Utils::IsPowerOfTwo(value)) return false; | 1149 if ((value <= 0) || !Utils::IsPowerOfTwo(value)) return false; |
| 1124 | 1150 |
| 1125 // Insert smi check and attach a copy of the original environment | 1151 // Insert smi check and attach a copy of the original environment |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1480 case MethodRecognizer::kFloat32x4ShuffleWWWW: | 1506 case MethodRecognizer::kFloat32x4ShuffleWWWW: |
| 1481 case MethodRecognizer::kFloat32x4ShuffleX: | 1507 case MethodRecognizer::kFloat32x4ShuffleX: |
| 1482 case MethodRecognizer::kFloat32x4ShuffleY: | 1508 case MethodRecognizer::kFloat32x4ShuffleY: |
| 1483 case MethodRecognizer::kFloat32x4ShuffleZ: | 1509 case MethodRecognizer::kFloat32x4ShuffleZ: |
| 1484 case MethodRecognizer::kFloat32x4ShuffleW: | 1510 case MethodRecognizer::kFloat32x4ShuffleW: |
| 1485 if (!ic_data.HasReceiverClassId(kFloat32x4Cid) || | 1511 if (!ic_data.HasReceiverClassId(kFloat32x4Cid) || |
| 1486 !ic_data.HasOneTarget()) { | 1512 !ic_data.HasOneTarget()) { |
| 1487 return false; | 1513 return false; |
| 1488 } | 1514 } |
| 1489 return InlineFloat32x4Getter(call, recognized_kind); | 1515 return InlineFloat32x4Getter(call, recognized_kind); |
| 1516 case MethodRecognizer::kUint32x4GetFlagX: | |
| 1517 case MethodRecognizer::kUint32x4GetFlagY: | |
| 1518 case MethodRecognizer::kUint32x4GetFlagZ: | |
| 1519 case MethodRecognizer::kUint32x4GetFlagW: { | |
| 1520 if (!ic_data.HasReceiverClassId(kUint32x4Cid) || | |
|
srdjan
2013/05/10 18:36:58
Bad indent (3 instead of 2)
Cutch
2013/05/13 19:40:24
Done.
| |
| 1521 !ic_data.HasOneTarget()) { | |
| 1522 return false; | |
| 1523 } | |
| 1524 return false; | |
|
Florian Schneider
2013/05/13 08:46:20
dbc: Shouldn't this return a Uint32x4GetFlagInstr
Cutch
2013/05/13 19:40:24
Done.
| |
| 1525 } | |
| 1490 default: | 1526 default: |
| 1491 ASSERT(recognized_kind == MethodRecognizer::kUnknown); | 1527 ASSERT(recognized_kind == MethodRecognizer::kUnknown); |
| 1492 } | 1528 } |
| 1493 return false; | 1529 return false; |
| 1494 } | 1530 } |
| 1495 | 1531 |
| 1496 | 1532 |
| 1497 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt( | 1533 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt( |
| 1498 InstanceCallInstr* call, | 1534 InstanceCallInstr* call, |
| 1499 intptr_t cid) { | 1535 intptr_t cid) { |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1747 call, class_ids[0], kTypedDataFloat32x4ArrayCid); | 1783 call, class_ids[0], kTypedDataFloat32x4ArrayCid); |
| 1748 default: | 1784 default: |
| 1749 // Unsupported method. | 1785 // Unsupported method. |
| 1750 return false; | 1786 return false; |
| 1751 } | 1787 } |
| 1752 } | 1788 } |
| 1753 | 1789 |
| 1754 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 1790 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { |
| 1755 return TryInlineFloat32x4Method(call, recognized_kind); | 1791 return TryInlineFloat32x4Method(call, recognized_kind); |
| 1756 } | 1792 } |
| 1793 | |
| 1794 if ((class_ids[0] == kUint32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | |
| 1795 return TryInlineUint32x4Method(call, recognized_kind); | |
| 1796 } | |
| 1757 return false; | 1797 return false; |
| 1758 } | 1798 } |
| 1759 | 1799 |
| 1760 | 1800 |
| 1761 bool FlowGraphOptimizer::TryInlineFloat32x4Method( | 1801 bool FlowGraphOptimizer::TryInlineFloat32x4Method( |
| 1762 InstanceCallInstr* call, | 1802 InstanceCallInstr* call, |
| 1763 MethodRecognizer::Kind recognized_kind) { | 1803 MethodRecognizer::Kind recognized_kind) { |
| 1764 ASSERT(call->HasICData()); | 1804 ASSERT(call->HasICData()); |
| 1765 switch (recognized_kind) { | 1805 switch (recognized_kind) { |
| 1766 case MethodRecognizer::kFloat32x4Equal: | 1806 case MethodRecognizer::kFloat32x4Equal: |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1902 new Float32x4ToUint32x4Instr(new Value(left), call); | 1942 new Float32x4ToUint32x4Instr(new Value(left), call); |
| 1903 ReplaceCall(call, cast); | 1943 ReplaceCall(call, cast); |
| 1904 return true; | 1944 return true; |
| 1905 } | 1945 } |
| 1906 default: | 1946 default: |
| 1907 return false; | 1947 return false; |
| 1908 } | 1948 } |
| 1909 } | 1949 } |
| 1910 | 1950 |
| 1911 | 1951 |
| 1952 bool FlowGraphOptimizer::TryInlineUint32x4Method( | |
| 1953 InstanceCallInstr* call, | |
| 1954 MethodRecognizer::Kind recognized_kind) { | |
| 1955 ASSERT(call->HasICData()); | |
| 1956 switch (recognized_kind) { | |
| 1957 case MethodRecognizer::kUint32x4Select: { | |
| 1958 Definition* mask = call->ArgumentAt(0); | |
| 1959 Definition* trueValue = call->ArgumentAt(1); | |
| 1960 Definition* falseValue = call->ArgumentAt(2); | |
| 1961 // Type check left. | |
| 1962 AddCheckClass(mask, | |
| 1963 ICData::ZoneHandle( | |
| 1964 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1965 call->deopt_id(), | |
| 1966 call->env(), | |
| 1967 call); | |
| 1968 Uint32x4SelectInstr* select = new Uint32x4SelectInstr( | |
| 1969 new Value(mask), | |
| 1970 new Value(trueValue), | |
| 1971 new Value(falseValue), | |
| 1972 call); | |
| 1973 ReplaceCall(call, select); | |
| 1974 return true; | |
| 1975 } | |
| 1976 case MethodRecognizer::kUint32x4ToUint32x4: { | |
| 1977 Definition* left = call->ArgumentAt(0); | |
| 1978 // Type check left. | |
| 1979 AddCheckClass(left, | |
| 1980 ICData::ZoneHandle( | |
| 1981 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 1982 call->deopt_id(), | |
| 1983 call->env(), | |
| 1984 call); | |
| 1985 Uint32x4ToFloat32x4Instr* cast = | |
| 1986 new Uint32x4ToFloat32x4Instr(new Value(left), call); | |
| 1987 ReplaceCall(call, cast); | |
| 1988 return true; | |
| 1989 } | |
| 1990 case MethodRecognizer::kUint32x4WithFlagX: | |
| 1991 case MethodRecognizer::kUint32x4WithFlagY: | |
| 1992 case MethodRecognizer::kUint32x4WithFlagZ: | |
| 1993 case MethodRecognizer::kUint32x4WithFlagW: { | |
| 1994 Definition* left = call->ArgumentAt(0); | |
| 1995 Definition* flag = call->ArgumentAt(1); | |
| 1996 // Type check left. | |
| 1997 AddCheckClass(left, | |
| 1998 ICData::ZoneHandle( | |
| 1999 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
| 2000 call->deopt_id(), | |
| 2001 call->env(), | |
| 2002 call); | |
| 2003 Uint32x4SetFlagInstr* setFlag = new Uint32x4SetFlagInstr(recognized_kind, | |
| 2004 new Value(left), | |
| 2005 new Value(flag), | |
| 2006 call); | |
| 2007 ReplaceCall(call, setFlag); | |
| 2008 return true; | |
| 2009 } | |
| 2010 default: | |
| 2011 return false; | |
| 2012 } | |
| 2013 } | |
| 2014 | |
| 2015 | |
| 1912 bool FlowGraphOptimizer::BuildByteArrayViewLoad( | 2016 bool FlowGraphOptimizer::BuildByteArrayViewLoad( |
| 1913 InstanceCallInstr* call, | 2017 InstanceCallInstr* call, |
| 1914 intptr_t receiver_cid, | 2018 intptr_t receiver_cid, |
| 1915 intptr_t view_cid) { | 2019 intptr_t view_cid) { |
| 1916 Definition* array = call->ArgumentAt(0); | 2020 Definition* array = call->ArgumentAt(0); |
| 1917 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); | 2021 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); |
| 1918 | 2022 |
| 1919 // Optimistically build a smi-checked load for Int32 and Uint32 | 2023 // Optimistically build a smi-checked load for Int32 and Uint32 |
| 1920 // loads on ia32 like we do for normal array loads, and only revert to | 2024 // loads on ia32 like we do for normal array loads, and only revert to |
| 1921 // mint case after deoptimizing here. | 2025 // mint case after deoptimizing here. |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2295 new Float32x4SplatInstr(new Value(call->ArgumentAt(1)), call); | 2399 new Float32x4SplatInstr(new Value(call->ArgumentAt(1)), call); |
| 2296 ReplaceCall(call, splat); | 2400 ReplaceCall(call, splat); |
| 2297 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) { | 2401 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) { |
| 2298 Float32x4ConstructorInstr* con = | 2402 Float32x4ConstructorInstr* con = |
| 2299 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)), | 2403 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)), |
| 2300 new Value(call->ArgumentAt(2)), | 2404 new Value(call->ArgumentAt(2)), |
| 2301 new Value(call->ArgumentAt(3)), | 2405 new Value(call->ArgumentAt(3)), |
| 2302 new Value(call->ArgumentAt(4)), | 2406 new Value(call->ArgumentAt(4)), |
| 2303 call); | 2407 call); |
| 2304 ReplaceCall(call, con); | 2408 ReplaceCall(call, con); |
| 2409 } else if (recognized_kind == MethodRecognizer::kUint32x4BoolConstructor) { | |
| 2410 Uint32x4BoolConstructorInstr* con = new Uint32x4BoolConstructorInstr( | |
| 2411 new Value(call->ArgumentAt(1)), | |
| 2412 new Value(call->ArgumentAt(2)), | |
| 2413 new Value(call->ArgumentAt(3)), | |
| 2414 new Value(call->ArgumentAt(4)), | |
| 2415 call); | |
|
srdjan
2013/05/10 18:36:58
Indent 4 spaces
| |
| 2416 ReplaceCall(call, con); | |
| 2305 } | 2417 } |
| 2306 } | 2418 } |
| 2307 | 2419 |
| 2308 | 2420 |
| 2309 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, | 2421 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, |
| 2310 const ICData& unary_ic_data) { | 2422 const ICData& unary_ic_data) { |
| 2311 ASSERT((unary_ic_data.NumberOfChecks() > 0) && | 2423 ASSERT((unary_ic_data.NumberOfChecks() > 0) && |
| 2312 (unary_ic_data.num_args_tested() == 1)); | 2424 (unary_ic_data.num_args_tested() == 1)); |
| 2313 if (FLAG_enable_type_checks) { | 2425 if (FLAG_enable_type_checks) { |
| 2314 // TODO(srdjan): Add assignable check node if --enable_type_checks. | 2426 // TODO(srdjan): Add assignable check node if --enable_type_checks. |
| (...skipping 2937 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5252 SetValue(instr, non_constant_); | 5364 SetValue(instr, non_constant_); |
| 5253 } | 5365 } |
| 5254 | 5366 |
| 5255 | 5367 |
| 5256 void ConstantPropagator::VisitFloat32x4ToUint32x4( | 5368 void ConstantPropagator::VisitFloat32x4ToUint32x4( |
| 5257 Float32x4ToUint32x4Instr* instr) { | 5369 Float32x4ToUint32x4Instr* instr) { |
| 5258 SetValue(instr, non_constant_); | 5370 SetValue(instr, non_constant_); |
| 5259 } | 5371 } |
| 5260 | 5372 |
| 5261 | 5373 |
| 5374 void ConstantPropagator::VisitUint32x4BoolConstructor( | |
| 5375 Uint32x4BoolConstructorInstr* instr) { | |
| 5376 SetValue(instr, non_constant_); | |
| 5377 } | |
| 5378 | |
| 5379 | |
| 5380 void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) { | |
| 5381 SetValue(instr, non_constant_); | |
| 5382 } | |
| 5383 | |
| 5384 | |
| 5385 void ConstantPropagator::VisitUint32x4SetFlag(Uint32x4SetFlagInstr* instr) { | |
| 5386 SetValue(instr, non_constant_); | |
| 5387 } | |
| 5388 | |
| 5389 | |
| 5390 void ConstantPropagator::VisitUint32x4Select(Uint32x4SelectInstr* instr) { | |
| 5391 SetValue(instr, non_constant_); | |
| 5392 } | |
| 5393 | |
| 5394 | |
| 5395 void ConstantPropagator::VisitUint32x4ToFloat32x4( | |
| 5396 Uint32x4ToFloat32x4Instr* instr) { | |
| 5397 SetValue(instr, non_constant_); | |
| 5398 } | |
| 5399 | |
| 5400 | |
| 5401 void ConstantPropagator::VisitBinaryUint32x4Op(BinaryUint32x4OpInstr* instr) { | |
| 5402 SetValue(instr, non_constant_); | |
| 5403 } | |
| 5404 | |
| 5405 | |
| 5262 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) { | 5406 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) { |
| 5263 const Object& value = instr->value()->definition()->constant_value(); | 5407 const Object& value = instr->value()->definition()->constant_value(); |
| 5264 if (IsNonConstant(value)) { | 5408 if (IsNonConstant(value)) { |
| 5265 SetValue(instr, non_constant_); | 5409 SetValue(instr, non_constant_); |
| 5266 } else if (IsConstant(value)) { | 5410 } else if (IsConstant(value)) { |
| 5267 // TODO(kmillikin): Handle sqrt. | 5411 // TODO(kmillikin): Handle sqrt. |
| 5268 SetValue(instr, non_constant_); | 5412 SetValue(instr, non_constant_); |
| 5269 } | 5413 } |
| 5270 } | 5414 } |
| 5271 | 5415 |
| (...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6145 | 6289 |
| 6146 // Insert materializations at environment uses. | 6290 // Insert materializations at environment uses. |
| 6147 const Class& cls = Class::Handle(alloc->constructor().Owner()); | 6291 const Class& cls = Class::Handle(alloc->constructor().Owner()); |
| 6148 for (intptr_t i = 0; i < exits.length(); i++) { | 6292 for (intptr_t i = 0; i < exits.length(); i++) { |
| 6149 CreateMaterializationAt(exits[i], alloc, cls, *fields); | 6293 CreateMaterializationAt(exits[i], alloc, cls, *fields); |
| 6150 } | 6294 } |
| 6151 } | 6295 } |
| 6152 | 6296 |
| 6153 | 6297 |
| 6154 } // namespace dart | 6298 } // namespace dart |
| OLD | NEW |