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

Side by Side Diff: vm/intrinsifier_x64.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/intrinsifier_ia32.cc ('k') | vm/object.h » ('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 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64.
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 969 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 __ Bind(&overflow); 980 __ Bind(&overflow);
981 // Mint is rarely used on x64 (only for integers requiring 64 bit instead of 981 // Mint is rarely used on x64 (only for integers requiring 64 bit instead of
982 // 63 bits as represented by Smi). 982 // 63 bits as represented by Smi).
983 __ Bind(&fall_through); 983 __ Bind(&fall_through);
984 return false; 984 return false;
985 } 985 }
986 986
987 987
988 static bool CompareIntegers(Assembler* assembler, Condition true_condition) { 988 static bool CompareIntegers(Assembler* assembler, Condition true_condition) {
989 Label fall_through, true_label; 989 Label fall_through, true_label;
990 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
991 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
992 TestBothArgumentsSmis(assembler, &fall_through); 990 TestBothArgumentsSmis(assembler, &fall_through);
993 // RAX contains the right argument. 991 // RAX contains the right argument.
994 __ cmpq(Address(RSP, + 2 * kWordSize), RAX); 992 __ cmpq(Address(RSP, + 2 * kWordSize), RAX);
995 __ j(true_condition, &true_label, Assembler::kNearJump); 993 __ j(true_condition, &true_label, Assembler::kNearJump);
996 __ LoadObject(RAX, bool_false); 994 __ LoadObject(RAX, Bool::False());
997 __ ret(); 995 __ ret();
998 __ Bind(&true_label); 996 __ Bind(&true_label);
999 __ LoadObject(RAX, bool_true); 997 __ LoadObject(RAX, Bool::True());
1000 __ ret(); 998 __ ret();
1001 __ Bind(&fall_through); 999 __ Bind(&fall_through);
1002 return false; 1000 return false;
1003 } 1001 }
1004 1002
1005 1003
1006 1004
1007 bool Intrinsifier::Integer_lessThan(Assembler* assembler) { 1005 bool Intrinsifier::Integer_lessThan(Assembler* assembler) {
1008 return CompareIntegers(assembler, LESS); 1006 return CompareIntegers(assembler, LESS);
1009 } 1007 }
(...skipping 16 matching lines...) Expand all
1026 1024
1027 bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) { 1025 bool Intrinsifier::Integer_greaterEqualThan(Assembler* assembler) {
1028 return CompareIntegers(assembler, GREATER_EQUAL); 1026 return CompareIntegers(assembler, GREATER_EQUAL);
1029 } 1027 }
1030 1028
1031 1029
1032 // This is called for Smi, Mint and Bigint receivers. The right argument 1030 // This is called for Smi, Mint and Bigint receivers. The right argument
1033 // can be Smi, Mint, Bigint or double. 1031 // can be Smi, Mint, Bigint or double.
1034 bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) { 1032 bool Intrinsifier::Integer_equalToInteger(Assembler* assembler) {
1035 Label fall_through, true_label, check_for_mint; 1033 Label fall_through, true_label, check_for_mint;
1036 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1037 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1038 // For integer receiver '===' check first. 1034 // For integer receiver '===' check first.
1039 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 1035 __ movq(RAX, Address(RSP, + 1 * kWordSize));
1040 __ movq(RCX, Address(RSP, + 2 * kWordSize)); 1036 __ movq(RCX, Address(RSP, + 2 * kWordSize));
1041 __ cmpq(RAX, RCX); 1037 __ cmpq(RAX, RCX);
1042 __ j(EQUAL, &true_label, Assembler::kNearJump); 1038 __ j(EQUAL, &true_label, Assembler::kNearJump);
1043 __ orq(RAX, RCX); 1039 __ orq(RAX, RCX);
1044 __ testq(RAX, Immediate(kSmiTagMask)); 1040 __ testq(RAX, Immediate(kSmiTagMask));
1045 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump); 1041 __ j(NOT_ZERO, &check_for_mint, Assembler::kNearJump);
1046 // Both arguments are smi, '===' is good enough. 1042 // Both arguments are smi, '===' is good enough.
1047 __ LoadObject(RAX, bool_false); 1043 __ LoadObject(RAX, Bool::False());
1048 __ ret(); 1044 __ ret();
1049 __ Bind(&true_label); 1045 __ Bind(&true_label);
1050 __ LoadObject(RAX, bool_true); 1046 __ LoadObject(RAX, Bool::True());
1051 __ ret(); 1047 __ ret();
1052 1048
1053 // At least one of the arguments was not Smi. 1049 // At least one of the arguments was not Smi.
1054 Label receiver_not_smi; 1050 Label receiver_not_smi;
1055 __ Bind(&check_for_mint); 1051 __ Bind(&check_for_mint);
1056 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Receiver. 1052 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Receiver.
1057 __ testq(RAX, Immediate(kSmiTagMask)); 1053 __ testq(RAX, Immediate(kSmiTagMask));
1058 __ j(NOT_ZERO, &receiver_not_smi); 1054 __ j(NOT_ZERO, &receiver_not_smi);
1059 1055
1060 // Left (receiver) is Smi, return false if right is not Double. 1056 // Left (receiver) is Smi, return false if right is not Double.
1061 // Note that an instance of Mint or Bigint never contains a value that can be 1057 // Note that an instance of Mint or Bigint never contains a value that can be
1062 // represented by Smi. 1058 // represented by Smi.
1063 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 1059 __ movq(RAX, Address(RSP, + 1 * kWordSize));
1064 __ CompareClassId(RAX, kDoubleCid); 1060 __ CompareClassId(RAX, kDoubleCid);
1065 __ j(EQUAL, &fall_through); 1061 __ j(EQUAL, &fall_through);
1066 __ LoadObject(RAX, bool_false); 1062 __ LoadObject(RAX, Bool::False());
1067 __ ret(); 1063 __ ret();
1068 1064
1069 __ Bind(&receiver_not_smi); 1065 __ Bind(&receiver_not_smi);
1070 // RAX:: receiver. 1066 // RAX:: receiver.
1071 __ CompareClassId(RAX, kMintCid); 1067 __ CompareClassId(RAX, kMintCid);
1072 __ j(NOT_EQUAL, &fall_through); 1068 __ j(NOT_EQUAL, &fall_through);
1073 // Receiver is Mint, return false if right is Smi. 1069 // Receiver is Mint, return false if right is Smi.
1074 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Right argument. 1070 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Right argument.
1075 __ testq(RAX, Immediate(kSmiTagMask)); 1071 __ testq(RAX, Immediate(kSmiTagMask));
1076 __ j(NOT_ZERO, &fall_through); 1072 __ j(NOT_ZERO, &fall_through);
1077 __ LoadObject(RAX, bool_false); // Smi == Mint -> false. 1073 __ LoadObject(RAX, Bool::False()); // Smi == Mint -> false.
1078 __ ret(); 1074 __ ret();
1079 // TODO(srdjan): Implement Mint == Mint comparison. 1075 // TODO(srdjan): Implement Mint == Mint comparison.
1080 1076
1081 __ Bind(&fall_through); 1077 __ Bind(&fall_through);
1082 return false; 1078 return false;
1083 } 1079 }
1084 1080
1085 1081
1086 bool Intrinsifier::Integer_equal(Assembler* assembler) { 1082 bool Intrinsifier::Integer_equal(Assembler* assembler) {
1087 return Integer_equalToInteger(assembler); 1083 return Integer_equalToInteger(assembler);
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1137 __ j(NOT_EQUAL, not_double_smi, Assembler::kNearJump); 1133 __ j(NOT_EQUAL, not_double_smi, Assembler::kNearJump);
1138 // Fall through if double. 1134 // Fall through if double.
1139 } 1135 }
1140 1136
1141 1137
1142 // Both arguments on stack, left argument is a double, right argument is of 1138 // Both arguments on stack, left argument is a double, right argument is of
1143 // unknown type. Return true or false object in RAX. Any NaN argument 1139 // unknown type. Return true or false object in RAX. Any NaN argument
1144 // returns false. Any non-double argument causes control flow to fall through 1140 // returns false. Any non-double argument causes control flow to fall through
1145 // to the slow case (compiled method body). 1141 // to the slow case (compiled method body).
1146 static bool CompareDoubles(Assembler* assembler, Condition true_condition) { 1142 static bool CompareDoubles(Assembler* assembler, Condition true_condition) {
1147 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1148 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1149 Label fall_through, is_false, is_true, is_smi, double_op; 1143 Label fall_through, is_false, is_true, is_smi, double_op;
1150 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); 1144 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
1151 // Both arguments are double, right operand is in RAX. 1145 // Both arguments are double, right operand is in RAX.
1152 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset())); 1146 __ movsd(XMM1, FieldAddress(RAX, Double::value_offset()));
1153 __ Bind(&double_op); 1147 __ Bind(&double_op);
1154 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left argument. 1148 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left argument.
1155 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); 1149 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
1156 __ comisd(XMM0, XMM1); 1150 __ comisd(XMM0, XMM1);
1157 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false; 1151 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false;
1158 __ j(true_condition, &is_true, Assembler::kNearJump); 1152 __ j(true_condition, &is_true, Assembler::kNearJump);
1159 // Fall through false. 1153 // Fall through false.
1160 __ Bind(&is_false); 1154 __ Bind(&is_false);
1161 __ LoadObject(RAX, bool_false); 1155 __ LoadObject(RAX, Bool::False());
1162 __ ret(); 1156 __ ret();
1163 __ Bind(&is_true); 1157 __ Bind(&is_true);
1164 __ LoadObject(RAX, bool_true); 1158 __ LoadObject(RAX, Bool::True());
1165 __ ret(); 1159 __ ret();
1166 __ Bind(&is_smi); 1160 __ Bind(&is_smi);
1167 __ SmiUntag(RAX); 1161 __ SmiUntag(RAX);
1168 __ cvtsi2sd(XMM1, RAX); 1162 __ cvtsi2sd(XMM1, RAX);
1169 __ jmp(&double_op); 1163 __ jmp(&double_op);
1170 __ Bind(&fall_through); 1164 __ Bind(&fall_through);
1171 return false; 1165 return false;
1172 } 1166 }
1173 1167
1174 1168
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1290 Assembler::kNearJump, 1284 Assembler::kNearJump,
1291 RAX); // Result register. 1285 RAX); // Result register.
1292 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0); 1286 __ movsd(FieldAddress(RAX, Double::value_offset()), XMM0);
1293 __ ret(); 1287 __ ret();
1294 __ Bind(&fall_through); 1288 __ Bind(&fall_through);
1295 return false; 1289 return false;
1296 } 1290 }
1297 1291
1298 1292
1299 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) { 1293 bool Intrinsifier::Double_getIsNaN(Assembler* assembler) {
1300 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1301 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1302 Label is_true; 1294 Label is_true;
1303 __ movq(RAX, Address(RSP, +1 * kWordSize)); 1295 __ movq(RAX, Address(RSP, +1 * kWordSize));
1304 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); 1296 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
1305 __ comisd(XMM0, XMM0); 1297 __ comisd(XMM0, XMM0);
1306 __ j(PARITY_EVEN, &is_true, Assembler::kNearJump); // NaN -> true; 1298 __ j(PARITY_EVEN, &is_true, Assembler::kNearJump); // NaN -> true;
1307 __ LoadObject(RAX, bool_false); 1299 __ LoadObject(RAX, Bool::False());
1308 __ ret(); 1300 __ ret();
1309 __ Bind(&is_true); 1301 __ Bind(&is_true);
1310 __ LoadObject(RAX, bool_true); 1302 __ LoadObject(RAX, Bool::True());
1311 __ ret(); 1303 __ ret();
1312 return true; // Method is complete, no slow case. 1304 return true; // Method is complete, no slow case.
1313 } 1305 }
1314 1306
1315 1307
1316 bool Intrinsifier::Double_getIsNegative(Assembler* assembler) { 1308 bool Intrinsifier::Double_getIsNegative(Assembler* assembler) {
1317 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1318 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1319 Label is_false, is_true, is_zero; 1309 Label is_false, is_true, is_zero;
1320 __ movq(RAX, Address(RSP, +1 * kWordSize)); 1310 __ movq(RAX, Address(RSP, +1 * kWordSize));
1321 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset())); 1311 __ movsd(XMM0, FieldAddress(RAX, Double::value_offset()));
1322 __ xorpd(XMM1, XMM1); // 0.0 -> XMM1. 1312 __ xorpd(XMM1, XMM1); // 0.0 -> XMM1.
1323 __ comisd(XMM0, XMM1); 1313 __ comisd(XMM0, XMM1);
1324 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false. 1314 __ j(PARITY_EVEN, &is_false, Assembler::kNearJump); // NaN -> false.
1325 __ j(EQUAL, &is_zero, Assembler::kNearJump); // Check for negative zero. 1315 __ j(EQUAL, &is_zero, Assembler::kNearJump); // Check for negative zero.
1326 __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump); // >= 0 -> false. 1316 __ j(ABOVE_EQUAL, &is_false, Assembler::kNearJump); // >= 0 -> false.
1327 __ Bind(&is_true); 1317 __ Bind(&is_true);
1328 __ LoadObject(RAX, bool_true); 1318 __ LoadObject(RAX, Bool::True());
1329 __ ret(); 1319 __ ret();
1330 __ Bind(&is_false); 1320 __ Bind(&is_false);
1331 __ LoadObject(RAX, bool_false); 1321 __ LoadObject(RAX, Bool::False());
1332 __ ret(); 1322 __ ret();
1333 __ Bind(&is_zero); 1323 __ Bind(&is_zero);
1334 // Check for negative zero (get the sign bit). 1324 // Check for negative zero (get the sign bit).
1335 __ movmskpd(RAX, XMM0); 1325 __ movmskpd(RAX, XMM0);
1336 __ testq(RAX, Immediate(1)); 1326 __ testq(RAX, Immediate(1));
1337 __ j(NOT_ZERO, &is_true, Assembler::kNearJump); 1327 __ j(NOT_ZERO, &is_true, Assembler::kNearJump);
1338 __ jmp(&is_false, Assembler::kNearJump); 1328 __ jmp(&is_false, Assembler::kNearJump);
1339 return true; // Method is complete, no slow case. 1329 return true; // Method is complete, no slow case.
1340 } 1330 }
1341 1331
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 1425
1436 bool Intrinsifier::Math_cos(Assembler* assembler) { 1426 bool Intrinsifier::Math_cos(Assembler* assembler) {
1437 EmitTrigonometric(assembler, kCosine); 1427 EmitTrigonometric(assembler, kCosine);
1438 return false; // Compile method for slow case. 1428 return false; // Compile method for slow case.
1439 } 1429 }
1440 1430
1441 1431
1442 // Identity comparison. 1432 // Identity comparison.
1443 bool Intrinsifier::Object_equal(Assembler* assembler) { 1433 bool Intrinsifier::Object_equal(Assembler* assembler) {
1444 Label is_true; 1434 Label is_true;
1445 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1446 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1447 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 1435 __ movq(RAX, Address(RSP, + 1 * kWordSize));
1448 __ cmpq(RAX, Address(RSP, + 2 * kWordSize)); 1436 __ cmpq(RAX, Address(RSP, + 2 * kWordSize));
1449 __ j(EQUAL, &is_true, Assembler::kNearJump); 1437 __ j(EQUAL, &is_true, Assembler::kNearJump);
1450 __ LoadObject(RAX, bool_false); 1438 __ LoadObject(RAX, Bool::False());
1451 __ ret(); 1439 __ ret();
1452 __ Bind(&is_true); 1440 __ Bind(&is_true);
1453 __ LoadObject(RAX, bool_true); 1441 __ LoadObject(RAX, Bool::True());
1454 __ ret(); 1442 __ ret();
1455 return true; 1443 return true;
1456 } 1444 }
1457 1445
1458 1446
1459 static intptr_t GetOffsetForField(const char* class_name_p, 1447 static intptr_t GetOffsetForField(const char* class_name_p,
1460 const char* field_name_p) { 1448 const char* field_name_p) {
1461 const String& class_name = String::Handle(Symbols::New(class_name_p)); 1449 const String& class_name = String::Handle(Symbols::New(class_name_p));
1462 const String& field_name = String::Handle(Symbols::New(field_name_p)); 1450 const String& field_name = String::Handle(Symbols::New(field_name_p));
1463 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 1451 const Library& core_lib = Library::Handle(Library::CoreLibrary());
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1518 return false; 1506 return false;
1519 } 1507 }
1520 1508
1521 1509
1522 // Class 'FixedSizeArrayIterator': 1510 // Class 'FixedSizeArrayIterator':
1523 // bool get hasNext { 1511 // bool get hasNext {
1524 // return _length > _pos; 1512 // return _length > _pos;
1525 // } 1513 // }
1526 bool Intrinsifier::FixedSizeArrayIterator_getHasNext(Assembler* assembler) { 1514 bool Intrinsifier::FixedSizeArrayIterator_getHasNext(Assembler* assembler) {
1527 Label fall_through, is_true; 1515 Label fall_through, is_true;
1528 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1529 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1530 const intptr_t length_offset = 1516 const intptr_t length_offset =
1531 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_length"); 1517 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_length");
1532 const intptr_t pos_offset = 1518 const intptr_t pos_offset =
1533 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_pos"); 1519 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_pos");
1534 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Receiver. 1520 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // Receiver.
1535 __ movq(RCX, FieldAddress(RAX, length_offset)); // Field _length. 1521 __ movq(RCX, FieldAddress(RAX, length_offset)); // Field _length.
1536 __ movq(RAX, FieldAddress(RAX, pos_offset)); // Field _pos. 1522 __ movq(RAX, FieldAddress(RAX, pos_offset)); // Field _pos.
1537 __ movq(RDI, RAX); 1523 __ movq(RDI, RAX);
1538 __ orq(RDI, RCX); 1524 __ orq(RDI, RCX);
1539 __ testq(RDI, Immediate(kSmiTagMask)); 1525 __ testq(RDI, Immediate(kSmiTagMask));
1540 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi _length/_pos. 1526 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi _length/_pos.
1541 __ cmpq(RCX, RAX); // _length > _pos. 1527 __ cmpq(RCX, RAX); // _length > _pos.
1542 __ j(GREATER, &is_true, Assembler::kNearJump); 1528 __ j(GREATER, &is_true, Assembler::kNearJump);
1543 __ LoadObject(RAX, bool_false); 1529 __ LoadObject(RAX, Bool::False());
1544 __ ret(); 1530 __ ret();
1545 __ Bind(&is_true); 1531 __ Bind(&is_true);
1546 __ LoadObject(RAX, bool_true); 1532 __ LoadObject(RAX, Bool::True());
1547 __ ret(); 1533 __ ret();
1548 __ Bind(&fall_through); 1534 __ Bind(&fall_through);
1549 return false; 1535 return false;
1550 } 1536 }
1551 1537
1552 1538
1553 bool Intrinsifier::String_getHashCode(Assembler* assembler) { 1539 bool Intrinsifier::String_getHashCode(Assembler* assembler) {
1554 Label fall_through; 1540 Label fall_through;
1555 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. 1541 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object.
1556 __ movq(RAX, FieldAddress(RAX, String::hash_offset())); 1542 __ movq(RAX, FieldAddress(RAX, String::hash_offset()));
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 __ movzxb(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset())); 1574 __ movzxb(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
1589 __ SmiTag(RAX); 1575 __ SmiTag(RAX);
1590 __ ret(); 1576 __ ret();
1591 __ Bind(&fall_through); 1577 __ Bind(&fall_through);
1592 return false; 1578 return false;
1593 } 1579 }
1594 1580
1595 1581
1596 bool Intrinsifier::String_getIsEmpty(Assembler* assembler) { 1582 bool Intrinsifier::String_getIsEmpty(Assembler* assembler) {
1597 Label is_true; 1583 Label is_true;
1598 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1599 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1600 // Get length. 1584 // Get length.
1601 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object. 1585 __ movq(RAX, Address(RSP, + 1 * kWordSize)); // String object.
1602 __ movq(RAX, FieldAddress(RAX, String::length_offset())); 1586 __ movq(RAX, FieldAddress(RAX, String::length_offset()));
1603 __ cmpq(RAX, Immediate(Smi::RawValue(0))); 1587 __ cmpq(RAX, Immediate(Smi::RawValue(0)));
1604 __ j(EQUAL, &is_true, Assembler::kNearJump); 1588 __ j(EQUAL, &is_true, Assembler::kNearJump);
1605 __ LoadObject(RAX, bool_false); 1589 __ LoadObject(RAX, Bool::False());
1606 __ ret(); 1590 __ ret();
1607 __ Bind(&is_true); 1591 __ Bind(&is_true);
1608 __ LoadObject(RAX, bool_true); 1592 __ LoadObject(RAX, Bool::True());
1609 __ ret(); 1593 __ ret();
1610 return true; 1594 return true;
1611 } 1595 }
1612 1596
1613 #undef __ 1597 #undef __
1614 1598
1615 } // namespace dart 1599 } // namespace dart
1616 1600
1617 #endif // defined TARGET_ARCH_X64 1601 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « vm/intrinsifier_ia32.cc ('k') | vm/object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698