| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 // The intrinsic code below is executed before a method has built its frame. | 5 // The intrinsic code below is executed before a method has built its frame. |
| 6 // The return address is on the stack and the arguments below it. | 6 // The return address is on the stack and the arguments below it. |
| 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. | 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. |
| 8 // Each intrinsification method returns true if the corresponding | 8 // Each intrinsification method returns true if the corresponding |
| 9 // Dart method was intrinsified. | 9 // Dart method was intrinsified. |
| 10 | 10 |
| (...skipping 1057 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1068 __ j(NOT_EQUAL, not_smi_or_mint); | 1068 __ j(NOT_EQUAL, not_smi_or_mint); |
| 1069 // Mint. | 1069 // Mint. |
| 1070 __ pushl(FieldAddress(reg, Mint::value_offset() + kWordSize)); | 1070 __ pushl(FieldAddress(reg, Mint::value_offset() + kWordSize)); |
| 1071 __ pushl(FieldAddress(reg, Mint::value_offset())); | 1071 __ pushl(FieldAddress(reg, Mint::value_offset())); |
| 1072 __ Bind(&done); | 1072 __ Bind(&done); |
| 1073 } | 1073 } |
| 1074 | 1074 |
| 1075 | 1075 |
| 1076 static bool CompareIntegers(Assembler* assembler, Condition true_condition) { | 1076 static bool CompareIntegers(Assembler* assembler, Condition true_condition) { |
| 1077 Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through; | 1077 Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through; |
| 1078 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 1079 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 1080 TestBothArgumentsSmis(assembler, &try_mint_smi); | 1078 TestBothArgumentsSmis(assembler, &try_mint_smi); |
| 1081 // EAX contains the right argument. | 1079 // EAX contains the right argument. |
| 1082 __ cmpl(Address(ESP, + 2 * kWordSize), EAX); | 1080 __ cmpl(Address(ESP, + 2 * kWordSize), EAX); |
| 1083 __ j(true_condition, &is_true, Assembler::kNearJump); | 1081 __ j(true_condition, &is_true, Assembler::kNearJump); |
| 1084 __ Bind(&is_false); | 1082 __ Bind(&is_false); |
| 1085 __ LoadObject(EAX, bool_false); | 1083 __ LoadObject(EAX, Bool::False()); |
| 1086 __ ret(); | 1084 __ ret(); |
| 1087 __ Bind(&is_true); | 1085 __ Bind(&is_true); |
| 1088 __ LoadObject(EAX, bool_true); | 1086 __ LoadObject(EAX, Bool::True()); |
| 1089 __ ret(); | 1087 __ ret(); |
| 1090 | 1088 |
| 1091 // 64-bit comparison | 1089 // 64-bit comparison |
| 1092 Condition hi_true_cond, hi_false_cond, lo_false_cond; | 1090 Condition hi_true_cond, hi_false_cond, lo_false_cond; |
| 1093 switch (true_condition) { | 1091 switch (true_condition) { |
| 1094 case LESS: | 1092 case LESS: |
| 1095 case LESS_EQUAL: | 1093 case LESS_EQUAL: |
| 1096 hi_true_cond = LESS; | 1094 hi_true_cond = LESS; |
| 1097 hi_false_cond = GREATER; | 1095 hi_false_cond = GREATER; |
| 1098 lo_false_cond = (true_condition == LESS) ? ABOVE_EQUAL : ABOVE; | 1096 lo_false_cond = (true_condition == LESS) ? ABOVE_EQUAL : ABOVE; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1158 | 1156 |
| 1159 bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) { | 1157 bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) { |
| 1160 return CompareIntegers(assembler, GREATER_EQUAL); | 1158 return CompareIntegers(assembler, GREATER_EQUAL); |
| 1161 } | 1159 } |
| 1162 | 1160 |
| 1163 | 1161 |
| 1164 // This is called for Smi, Mint and Bigint receivers. The right argument | 1162 // This is called for Smi, Mint and Bigint receivers. The right argument |
| 1165 // can be Smi, Mint, Bigint or double. | 1163 // can be Smi, Mint, Bigint or double. |
| 1166 bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) { | 1164 bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) { |
| 1167 Label fall_through, true_label, check_for_mint; | 1165 Label fall_through, true_label, check_for_mint; |
| 1168 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 1169 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 1170 // For integer receiver '===' check first. | 1166 // For integer receiver '===' check first. |
| 1171 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 1167 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 1172 __ cmpl(EAX, Address(ESP, + 2 * kWordSize)); | 1168 __ cmpl(EAX, Address(ESP, + 2 * kWordSize)); |
| 1173 __ j(EQUAL, &true_label, Assembler::kNearJump); | 1169 __ j(EQUAL, &true_label, Assembler::kNearJump); |
| 1174 __ movl(EBX, Address(ESP, + 2 * kWordSize)); | 1170 __ movl(EBX, Address(ESP, + 2 * kWordSize)); |
| 1175 __ orl(EAX, EBX); | 1171 __ orl(EAX, EBX); |
| 1176 __ testl(EAX, Immediate(kSmiTagMask)); | 1172 __ testl(EAX, Immediate(kSmiTagMask)); |
| 1177 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump); | 1173 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump); |
| 1178 // Both arguments are smi, '===' is good enough. | 1174 // Both arguments are smi, '===' is good enough. |
| 1179 __ LoadObject(EAX, bool_false); | 1175 __ LoadObject(EAX, Bool::False()); |
| 1180 __ ret(); | 1176 __ ret(); |
| 1181 __ Bind(&true_label); | 1177 __ Bind(&true_label); |
| 1182 __ LoadObject(EAX, bool_true); | 1178 __ LoadObject(EAX, Bool::True()); |
| 1183 __ ret(); | 1179 __ ret(); |
| 1184 | 1180 |
| 1185 // At least one of the arguments was not Smi. | 1181 // At least one of the arguments was not Smi. |
| 1186 Label receiver_not_smi; | 1182 Label receiver_not_smi; |
| 1187 __ Bind(&check_for_mint); | 1183 __ Bind(&check_for_mint); |
| 1188 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Receiver. | 1184 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Receiver. |
| 1189 __ testl(EAX, Immediate(kSmiTagMask)); | 1185 __ testl(EAX, Immediate(kSmiTagMask)); |
| 1190 __ j(NOT_ZERO, &receiver_not_smi); | 1186 __ j(NOT_ZERO, &receiver_not_smi); |
| 1191 | 1187 |
| 1192 // Left (receiver) is Smi, return false if right is not Double. | 1188 // Left (receiver) is Smi, return false if right is not Double. |
| 1193 // Note that an instance of Mint or Bigint never contains a value that can be | 1189 // Note that an instance of Mint or Bigint never contains a value that can be |
| 1194 // represented by Smi. | 1190 // represented by Smi. |
| 1195 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument. | 1191 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument. |
| 1196 __ CompareClassId(EAX, kDoubleCid, EDI); | 1192 __ CompareClassId(EAX, kDoubleCid, EDI); |
| 1197 __ j(EQUAL, &fall_through); | 1193 __ j(EQUAL, &fall_through); |
| 1198 __ LoadObject(EAX, bool_false); // Smi == Mint -> false. | 1194 __ LoadObject(EAX, Bool::False()); // Smi == Mint -> false. |
| 1199 __ ret(); | 1195 __ ret(); |
| 1200 | 1196 |
| 1201 __ Bind(&receiver_not_smi); | 1197 __ Bind(&receiver_not_smi); |
| 1202 // EAX:: receiver. | 1198 // EAX:: receiver. |
| 1203 __ CompareClassId(EAX, kMintCid, EDI); | 1199 __ CompareClassId(EAX, kMintCid, EDI); |
| 1204 __ j(NOT_EQUAL, &fall_through); | 1200 __ j(NOT_EQUAL, &fall_through); |
| 1205 // Receiver is Mint, return false if right is Smi. | 1201 // Receiver is Mint, return false if right is Smi. |
| 1206 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument. | 1202 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Right argument. |
| 1207 __ testl(EAX, Immediate(kSmiTagMask)); | 1203 __ testl(EAX, Immediate(kSmiTagMask)); |
| 1208 __ j(NOT_ZERO, &fall_through); | 1204 __ j(NOT_ZERO, &fall_through); |
| 1209 __ LoadObject(EAX, bool_false); | 1205 __ LoadObject(EAX, Bool::False()); |
| 1210 __ ret(); | 1206 __ ret(); |
| 1211 // TODO(srdjan): Implement Mint == Mint comparison. | 1207 // TODO(srdjan): Implement Mint == Mint comparison. |
| 1212 | 1208 |
| 1213 __ Bind(&fall_through); | 1209 __ Bind(&fall_through); |
| 1214 return false; | 1210 return false; |
| 1215 } | 1211 } |
| 1216 | 1212 |
| 1217 | 1213 |
| 1218 bool Intrinsifier::Integer_equal(Assembler* assembler) { | 1214 bool Intrinsifier::Integer_equal(Assembler* assembler) { |
| 1219 return Integer_equalToInteger(assembler); | 1215 return Integer_equalToInteger(assembler); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1270 __ j(NOT_EQUAL, not_double_smi, Assembler::kNearJump); | 1266 __ j(NOT_EQUAL, not_double_smi, Assembler::kNearJump); |
| 1271 // Fall through if double. | 1267 // Fall through if double. |
| 1272 } | 1268 } |
| 1273 | 1269 |
| 1274 | 1270 |
| 1275 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown | 1271 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown |
| 1276 // type. Return true or false object in the register EAX. Any NaN argument | 1272 // type. Return true or false object in the register EAX. Any NaN argument |
| 1277 // returns false. Any non-double arg1 causes control flow to fall through to the | 1273 // returns false. Any non-double arg1 causes control flow to fall through to the |
| 1278 // slow case (compiled method body). | 1274 // slow case (compiled method body). |
| 1279 static bool CompareDoubles(Assembler* assembler, Condition true_condition) { | 1275 static bool CompareDoubles(Assembler* assembler, Condition true_condition) { |
| 1280 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 1281 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 1282 Label fall_through, is_false, is_true, is_smi, double_op; | 1276 Label fall_through, is_false, is_true, is_smi, double_op; |
| 1283 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); | 1277 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); |
| 1284 // Both arguments are double, right operand is in EAX. | 1278 // Both arguments are double, right operand is in EAX. |
| 1285 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); | 1279 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); |
| 1286 __ Bind(&double_op); | 1280 __ Bind(&double_op); |
| 1287 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument. | 1281 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left argument. |
| 1288 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); | 1282 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); |
| 1289 __ comisd(XMM0, XMM1); | 1283 __ comisd(XMM0, XMM1); |
| 1290 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false; | 1284 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false; |
| 1291 __ j(true_condition, &is_true, Assembler::kNearJump); | 1285 __ j(true_condition, &is_true, Assembler::kNearJump); |
| 1292 // Fall through false. | 1286 // Fall through false. |
| 1293 __ Bind(&is_false); | 1287 __ Bind(&is_false); |
| 1294 __ LoadObject(EAX, bool_false); | 1288 __ LoadObject(EAX, Bool::False()); |
| 1295 __ ret(); | 1289 __ ret(); |
| 1296 __ Bind(&is_true); | 1290 __ Bind(&is_true); |
| 1297 __ LoadObject(EAX, bool_true); | 1291 __ LoadObject(EAX, Bool::True()); |
| 1298 __ ret(); | 1292 __ ret(); |
| 1299 __ Bind(&is_smi); | 1293 __ Bind(&is_smi); |
| 1300 __ SmiUntag(EAX); | 1294 __ SmiUntag(EAX); |
| 1301 __ cvtsi2sd(XMM1, EAX); | 1295 __ cvtsi2sd(XMM1, EAX); |
| 1302 __ jmp(&double_op); | 1296 __ jmp(&double_op); |
| 1303 __ Bind(&fall_through); | 1297 __ Bind(&fall_through); |
| 1304 return false; | 1298 return false; |
| 1305 } | 1299 } |
| 1306 | 1300 |
| 1307 | 1301 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1428 Assembler::kNearJump, | 1422 Assembler::kNearJump, |
| 1429 EAX); // Result register. | 1423 EAX); // Result register. |
| 1430 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); | 1424 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); |
| 1431 __ ret(); | 1425 __ ret(); |
| 1432 __ Bind(&fall_through); | 1426 __ Bind(&fall_through); |
| 1433 return false; | 1427 return false; |
| 1434 } | 1428 } |
| 1435 | 1429 |
| 1436 | 1430 |
| 1437 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) { | 1431 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) { |
| 1438 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 1439 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 1440 Label is_true; | 1432 Label is_true; |
| 1441 __ movl(EAX, Address(ESP, +1 * kWordSize)); | 1433 __ movl(EAX, Address(ESP, +1 * kWordSize)); |
| 1442 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); | 1434 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); |
| 1443 __ comisd(XMM0, XMM0); | 1435 __ comisd(XMM0, XMM0); |
| 1444 __ j(PARITY_EVEN, &is_true, Assembler::kNearJump); // NaN -> true; | 1436 __ j(PARITY_EVEN, &is_true, Assembler::kNearJump); // NaN -> true; |
| 1445 __ LoadObject(EAX, bool_false); | 1437 __ LoadObject(EAX, Bool::False()); |
| 1446 __ ret(); | 1438 __ ret(); |
| 1447 __ Bind(&is_true); | 1439 __ Bind(&is_true); |
| 1448 __ LoadObject(EAX, bool_true); | 1440 __ LoadObject(EAX, Bool::True()); |
| 1449 __ ret(); | 1441 __ ret(); |
| 1450 return true; // Method is complete, no slow case. | 1442 return true; // Method is complete, no slow case. |
| 1451 } | 1443 } |
| 1452 | 1444 |
| 1453 | 1445 |
| 1454 bool Intrinsifier::Double_getIsNegative(Assembler* assembler) { | 1446 bool Intrinsifier::Double_getIsNegative(Assembler* assembler) { |
| 1455 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 1456 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 1457 Label is_false, is_true, is_zero; | 1447 Label is_false, is_true, is_zero; |
| 1458 __ movl(EAX, Address(ESP, +1 * kWordSize)); | 1448 __ movl(EAX, Address(ESP, +1 * kWordSize)); |
| 1459 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); | 1449 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); |
| 1460 __ xorpd(XMM1, XMM1); // 0.0 -> XMM1. | 1450 __ xorpd(XMM1, XMM1); // 0.0 -> XMM1. |
| 1461 __ comisd(XMM0, XMM1); | 1451 __ comisd(XMM0, XMM1); |
| 1462 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false. | 1452 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false. |
| 1463 __ j(EQUAL, &is_zero, Assembler::kNearJump); // Check for negative zero. | 1453 __ j(EQUAL, &is_zero, Assembler::kNearJump); // Check for negative zero. |
| 1464 __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump); // >= 0 -> false. | 1454 __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump); // >= 0 -> false. |
| 1465 __ Bind(&is_true); | 1455 __ Bind(&is_true); |
| 1466 __ LoadObject(EAX, bool_true); | 1456 __ LoadObject(EAX, Bool::True()); |
| 1467 __ ret(); | 1457 __ ret(); |
| 1468 __ Bind(&is_false); | 1458 __ Bind(&is_false); |
| 1469 __ LoadObject(EAX, bool_false); | 1459 __ LoadObject(EAX, Bool::False()); |
| 1470 __ ret(); | 1460 __ ret(); |
| 1471 __ Bind(&is_zero); | 1461 __ Bind(&is_zero); |
| 1472 // Check for negative zero (get the sign bit). | 1462 // Check for negative zero (get the sign bit). |
| 1473 __ movmskpd(EAX, XMM0); | 1463 __ movmskpd(EAX, XMM0); |
| 1474 __ testl(EAX, Immediate(1)); | 1464 __ testl(EAX, Immediate(1)); |
| 1475 __ j(NOT_ZERO, &is_true, Assembler::kNearJump); | 1465 __ j(NOT_ZERO, &is_true, Assembler::kNearJump); |
| 1476 __ jmp(&is_false, Assembler::kNearJump); | 1466 __ jmp(&is_false, Assembler::kNearJump); |
| 1477 return true; // Method is complete, no slow case. | 1467 return true; // Method is complete, no slow case. |
| 1478 } | 1468 } |
| 1479 | 1469 |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1573 | 1563 |
| 1574 bool Intrinsifier::Math_cos(Assembler* assembler) { | 1564 bool Intrinsifier::Math_cos(Assembler* assembler) { |
| 1575 EmitTrigonometric(assembler, kCosine); | 1565 EmitTrigonometric(assembler, kCosine); |
| 1576 return false; // Compile method for slow case. | 1566 return false; // Compile method for slow case. |
| 1577 } | 1567 } |
| 1578 | 1568 |
| 1579 | 1569 |
| 1580 // Identity comparison. | 1570 // Identity comparison. |
| 1581 bool Intrinsifier::Object_equal(Assembler* assembler) { | 1571 bool Intrinsifier::Object_equal(Assembler* assembler) { |
| 1582 Label is_true; | 1572 Label is_true; |
| 1583 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 1584 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 1585 __ movl(EAX, Address(ESP, + 1 * kWordSize)); | 1573 __ movl(EAX, Address(ESP, + 1 * kWordSize)); |
| 1586 __ cmpl(EAX, Address(ESP, + 2 * kWordSize)); | 1574 __ cmpl(EAX, Address(ESP, + 2 * kWordSize)); |
| 1587 __ j(EQUAL, &is_true, Assembler::kNearJump); | 1575 __ j(EQUAL, &is_true, Assembler::kNearJump); |
| 1588 __ LoadObject(EAX, bool_false); | 1576 __ LoadObject(EAX, Bool::False()); |
| 1589 __ ret(); | 1577 __ ret(); |
| 1590 __ Bind(&is_true); | 1578 __ Bind(&is_true); |
| 1591 __ LoadObject(EAX, bool_true); | 1579 __ LoadObject(EAX, Bool::True()); |
| 1592 __ ret(); | 1580 __ ret(); |
| 1593 return true; | 1581 return true; |
| 1594 } | 1582 } |
| 1595 | 1583 |
| 1596 | 1584 |
| 1597 static const char* kFixedSizeArrayIteratorClassName = "_FixedSizeArrayIterator"; | 1585 static const char* kFixedSizeArrayIteratorClassName = "_FixedSizeArrayIterator"; |
| 1598 | 1586 |
| 1599 | 1587 |
| 1600 // Class 'FixedSizeArrayIterator': | 1588 // Class 'FixedSizeArrayIterator': |
| 1601 // T next() { | 1589 // T next() { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1643 return false; | 1631 return false; |
| 1644 } | 1632 } |
| 1645 | 1633 |
| 1646 | 1634 |
| 1647 // Class 'FixedSizeArrayIterator': | 1635 // Class 'FixedSizeArrayIterator': |
| 1648 // bool get hasNext { | 1636 // bool get hasNext { |
| 1649 // return _length > _pos; | 1637 // return _length > _pos; |
| 1650 // } | 1638 // } |
| 1651 bool Intrinsifier::FixedSizeArrayIterator_getHasNext(Assembler* assembler) { | 1639 bool Intrinsifier::FixedSizeArrayIterator_getHasNext(Assembler* assembler) { |
| 1652 Label fall_through, is_true; | 1640 Label fall_through, is_true; |
| 1653 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 1654 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 1655 intptr_t length_offset = | 1641 intptr_t length_offset = |
| 1656 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_length"); | 1642 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_length"); |
| 1657 intptr_t pos_offset = | 1643 intptr_t pos_offset = |
| 1658 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_pos"); | 1644 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_pos"); |
| 1659 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver. | 1645 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver. |
| 1660 __ movl(EBX, FieldAddress(EAX, length_offset)); // Field _length. | 1646 __ movl(EBX, FieldAddress(EAX, length_offset)); // Field _length. |
| 1661 __ movl(EAX, FieldAddress(EAX, pos_offset)); // Field _pos. | 1647 __ movl(EAX, FieldAddress(EAX, pos_offset)); // Field _pos. |
| 1662 __ movl(EDI, EAX); | 1648 __ movl(EDI, EAX); |
| 1663 __ orl(EDI, EBX); | 1649 __ orl(EDI, EBX); |
| 1664 __ testl(EDI, Immediate(kSmiTagMask)); | 1650 __ testl(EDI, Immediate(kSmiTagMask)); |
| 1665 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi _length. | 1651 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi _length. |
| 1666 __ cmpl(EBX, EAX); // _length > _pos. | 1652 __ cmpl(EBX, EAX); // _length > _pos. |
| 1667 __ j(GREATER, &is_true, Assembler::kNearJump); | 1653 __ j(GREATER, &is_true, Assembler::kNearJump); |
| 1668 __ LoadObject(EAX, bool_false); | 1654 __ LoadObject(EAX, Bool::False()); |
| 1669 __ ret(); | 1655 __ ret(); |
| 1670 __ Bind(&is_true); | 1656 __ Bind(&is_true); |
| 1671 __ LoadObject(EAX, bool_true); | 1657 __ LoadObject(EAX, Bool::True()); |
| 1672 __ ret(); | 1658 __ ret(); |
| 1673 __ Bind(&fall_through); | 1659 __ Bind(&fall_through); |
| 1674 return false; | 1660 return false; |
| 1675 } | 1661 } |
| 1676 | 1662 |
| 1677 | 1663 |
| 1678 bool Intrinsifier::String_getHashCode(Assembler* assembler) { | 1664 bool Intrinsifier::String_getHashCode(Assembler* assembler) { |
| 1679 Label fall_through; | 1665 Label fall_through; |
| 1680 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. | 1666 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. |
| 1681 __ movl(EAX, FieldAddress(EAX, String::hash_offset())); | 1667 __ movl(EAX, FieldAddress(EAX, String::hash_offset())); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1713 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset())); | 1699 __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset())); |
| 1714 __ SmiTag(EAX); | 1700 __ SmiTag(EAX); |
| 1715 __ ret(); | 1701 __ ret(); |
| 1716 __ Bind(&fall_through); | 1702 __ Bind(&fall_through); |
| 1717 return false; | 1703 return false; |
| 1718 } | 1704 } |
| 1719 | 1705 |
| 1720 | 1706 |
| 1721 bool Intrinsifier::String_getIsEmpty(Assembler* assembler) { | 1707 bool Intrinsifier::String_getIsEmpty(Assembler* assembler) { |
| 1722 Label is_true; | 1708 Label is_true; |
| 1723 const Bool& bool_true = Bool::ZoneHandle(Bool::True()); | |
| 1724 const Bool& bool_false = Bool::ZoneHandle(Bool::False()); | |
| 1725 // Get length. | 1709 // Get length. |
| 1726 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. | 1710 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. |
| 1727 __ movl(EAX, FieldAddress(EAX, String::length_offset())); | 1711 __ movl(EAX, FieldAddress(EAX, String::length_offset())); |
| 1728 __ cmpl(EAX, Immediate(Smi::RawValue(0))); | 1712 __ cmpl(EAX, Immediate(Smi::RawValue(0))); |
| 1729 __ j(EQUAL, &is_true, Assembler::kNearJump); | 1713 __ j(EQUAL, &is_true, Assembler::kNearJump); |
| 1730 __ LoadObject(EAX, bool_false); | 1714 __ LoadObject(EAX, Bool::False()); |
| 1731 __ ret(); | 1715 __ ret(); |
| 1732 __ Bind(&is_true); | 1716 __ Bind(&is_true); |
| 1733 __ LoadObject(EAX, bool_true); | 1717 __ LoadObject(EAX, Bool::True()); |
| 1734 __ ret(); | 1718 __ ret(); |
| 1735 return true; | 1719 return true; |
| 1736 } | 1720 } |
| 1737 | 1721 |
| 1738 #undef __ | 1722 #undef __ |
| 1739 } // namespace dart | 1723 } // namespace dart |
| 1740 | 1724 |
| 1741 #endif // defined TARGET_ARCH_IA32 | 1725 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |