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

Side by Side Diff: vm/intrinsifier_ia32.cc

Issue 11745022: - Make Boolean 'true' and 'false' singleton VM isolate objects. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: Created 7 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 | « vm/intermediate_language_x64.cc ('k') | vm/intrinsifier_x64.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 (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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « vm/intermediate_language_x64.cc ('k') | vm/intrinsifier_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698