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

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

Issue 51653006: Track live instance and allocation counts for classes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month 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 // 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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray))); 122 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray)));
123 Label done; 123 Label done;
124 Label init_loop; 124 Label init_loop;
125 __ Bind(&init_loop); 125 __ Bind(&init_loop);
126 __ cmpl(EDI, EBX); 126 __ cmpl(EDI, EBX);
127 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); 127 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump);
128 __ movl(Address(EDI, 0), raw_null); 128 __ movl(Address(EDI, 0), raw_null);
129 __ addl(EDI, Immediate(kWordSize)); 129 __ addl(EDI, Immediate(kWordSize));
130 __ jmp(&init_loop, Assembler::kNearJump); 130 __ jmp(&init_loop, Assembler::kNearJump);
131 __ Bind(&done); 131 __ Bind(&done);
132 __ BumpAllocationCount(kArrayCid, EBX);
132 __ ret(); // returns the newly allocated object in EAX. 133 __ ret(); // returns the newly allocated object in EAX.
133 134
134 __ Bind(&fall_through); 135 __ Bind(&fall_through);
135 } 136 }
136 137
137 138
138 void Intrinsifier::Array_getLength(Assembler* assembler) { 139 void Intrinsifier::Array_getLength(Assembler* assembler) {
139 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 140 __ movl(EAX, Address(ESP, + 1 * kWordSize));
140 __ movl(EAX, FieldAddress(EAX, Array::length_offset())); 141 __ movl(EAX, FieldAddress(EAX, Array::length_offset()));
141 __ ret(); 142 __ ret();
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 // Store the type argument field in the growable array object. 297 // Store the type argument field in the growable array object.
297 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. 298 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument.
298 __ StoreIntoObjectNoBarrier( 299 __ StoreIntoObjectNoBarrier(
299 EAX, 300 EAX,
300 FieldAddress(EAX, GrowableObjectArray::type_arguments_offset()), 301 FieldAddress(EAX, GrowableObjectArray::type_arguments_offset()),
301 EBX); 302 EBX);
302 303
303 // Set the length field in the growable array object to 0. 304 // Set the length field in the growable array object to 0.
304 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), 305 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()),
305 Immediate(0)); 306 Immediate(0));
307 __ BumpAllocationCount(kGrowableObjectArrayCid, EBX);
306 __ ret(); // returns the newly allocated object in EAX. 308 __ ret(); // returns the newly allocated object in EAX.
307 309
308 __ Bind(&fall_through); 310 __ Bind(&fall_through);
309 } 311 }
310 312
311 313
312 // Get length of growable object array. 314 // Get length of growable object array.
313 // On stack: growable array (+1), return-address (+0). 315 // On stack: growable array (+1), return-address (+0).
314 void Intrinsifier::GrowableList_getLength(Assembler* assembler) { 316 void Intrinsifier::GrowableList_getLength(Assembler* assembler) {
315 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 317 __ movl(EAX, Address(ESP, + 1 * kWordSize));
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 __ xorl(ECX, ECX); /* Zero. */ \ 530 __ xorl(ECX, ECX); /* Zero. */ \
529 __ leal(EDI, FieldAddress(EAX, sizeof(Raw##type_name))); \ 531 __ leal(EDI, FieldAddress(EAX, sizeof(Raw##type_name))); \
530 Label done, init_loop; \ 532 Label done, init_loop; \
531 __ Bind(&init_loop); \ 533 __ Bind(&init_loop); \
532 __ cmpl(EDI, EBX); \ 534 __ cmpl(EDI, EBX); \
533 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \ 535 __ j(ABOVE_EQUAL, &done, Assembler::kNearJump); \
534 __ movl(Address(EDI, 0), ECX); \ 536 __ movl(Address(EDI, 0), ECX); \
535 __ addl(EDI, Immediate(kWordSize)); \ 537 __ addl(EDI, Immediate(kWordSize)); \
536 __ jmp(&init_loop, Assembler::kNearJump); \ 538 __ jmp(&init_loop, Assembler::kNearJump); \
537 __ Bind(&done); \ 539 __ Bind(&done); \
538 \ 540 __ BumpAllocationCount(cid, EBX); \
539 __ ret(); \ 541 __ ret(); \
540 __ Bind(&fall_through); \ 542 __ Bind(&fall_through); \
541 543
542 544
543 545
544 // Gets the length of a TypedData. 546 // Gets the length of a TypedData.
545 void Intrinsifier::TypedData_getLength(Assembler* assembler) { 547 void Intrinsifier::TypedData_getLength(Assembler* assembler) {
546 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 548 __ movl(EAX, Address(ESP, + 1 * kWordSize));
547 __ movl(EAX, FieldAddress(EAX, TypedData::length_offset())); 549 __ movl(EAX, FieldAddress(EAX, TypedData::length_offset()));
548 __ ret(); 550 __ ret();
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 // Arguments are Smi but the shift produced an overflow to Mint. 867 // Arguments are Smi but the shift produced an overflow to Mint.
866 __ cmpl(EBX, Immediate(0)); 868 __ cmpl(EBX, Immediate(0));
867 // TODO(srdjan): Implement negative values, for now fall through. 869 // TODO(srdjan): Implement negative values, for now fall through.
868 __ j(LESS, &fall_through, Assembler::kNearJump); 870 __ j(LESS, &fall_through, Assembler::kNearJump);
869 __ SmiUntag(EBX); 871 __ SmiUntag(EBX);
870 __ movl(EAX, EBX); 872 __ movl(EAX, EBX);
871 __ shll(EBX, ECX); 873 __ shll(EBX, ECX);
872 __ xorl(EDI, EDI); 874 __ xorl(EDI, EDI);
873 __ shld(EDI, EAX); 875 __ shld(EDI, EAX);
874 // Result in EDI (high) and EBX (low). 876 // Result in EDI (high) and EBX (low).
877 __ pushl(EBX);
875 const Class& mint_class = Class::Handle( 878 const Class& mint_class = Class::Handle(
876 Isolate::Current()->object_store()->mint_class()); 879 Isolate::Current()->object_store()->mint_class());
877 __ TryAllocate(mint_class, 880 __ TryAllocate(mint_class,
878 &fall_through, 881 &fall_through,
879 Assembler::kNearJump, 882 Assembler::kNearJump,
880 EAX); // Result register. 883 EAX,
884 EBX); // Result register.
885 __ popl(EBX);
881 // EBX and EDI are not objects but integer values. 886 // EBX and EDI are not objects but integer values.
882 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); 887 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX);
883 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI); 888 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI);
884 __ ret(); 889 __ ret();
885 __ Bind(&fall_through); 890 __ Bind(&fall_through);
886 } 891 }
887 892
888 893
889 static void Push64SmiOrMint(Assembler* assembler, 894 static void Push64SmiOrMint(Assembler* assembler,
890 Register reg, 895 Register reg,
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 case Token::kSUB: __ subsd(XMM0, XMM1); break; 1196 case Token::kSUB: __ subsd(XMM0, XMM1); break;
1192 case Token::kMUL: __ mulsd(XMM0, XMM1); break; 1197 case Token::kMUL: __ mulsd(XMM0, XMM1); break;
1193 case Token::kDIV: __ divsd(XMM0, XMM1); break; 1198 case Token::kDIV: __ divsd(XMM0, XMM1); break;
1194 default: UNREACHABLE(); 1199 default: UNREACHABLE();
1195 } 1200 }
1196 const Class& double_class = Class::Handle( 1201 const Class& double_class = Class::Handle(
1197 Isolate::Current()->object_store()->double_class()); 1202 Isolate::Current()->object_store()->double_class());
1198 __ TryAllocate(double_class, 1203 __ TryAllocate(double_class,
1199 &fall_through, 1204 &fall_through,
1200 Assembler::kNearJump, 1205 Assembler::kNearJump,
1201 EAX); // Result register. 1206 EAX, // Result register.
1207 EBX);
1202 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); 1208 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
1203 __ ret(); 1209 __ ret();
1204 __ Bind(&fall_through); 1210 __ Bind(&fall_through);
1205 } 1211 }
1206 1212
1207 1213
1208 void Intrinsifier::Double_add(Assembler* assembler) { 1214 void Intrinsifier::Double_add(Assembler* assembler) {
1209 return DoubleArithmeticOperations(assembler, Token::kADD); 1215 return DoubleArithmeticOperations(assembler, Token::kADD);
1210 } 1216 }
1211 1217
(...skipping 24 matching lines...) Expand all
1236 __ SmiUntag(EAX); 1242 __ SmiUntag(EAX);
1237 __ cvtsi2sd(XMM1, EAX); 1243 __ cvtsi2sd(XMM1, EAX);
1238 __ movl(EAX, Address(ESP, + 2 * kWordSize)); 1244 __ movl(EAX, Address(ESP, + 2 * kWordSize));
1239 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); 1245 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
1240 __ mulsd(XMM0, XMM1); 1246 __ mulsd(XMM0, XMM1);
1241 const Class& double_class = Class::Handle( 1247 const Class& double_class = Class::Handle(
1242 Isolate::Current()->object_store()->double_class()); 1248 Isolate::Current()->object_store()->double_class());
1243 __ TryAllocate(double_class, 1249 __ TryAllocate(double_class,
1244 &fall_through, 1250 &fall_through,
1245 Assembler::kNearJump, 1251 Assembler::kNearJump,
1246 EAX); // Result register. 1252 EAX, // Result register.
1253 EBX);
1247 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); 1254 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
1248 __ ret(); 1255 __ ret();
1249 __ Bind(&fall_through); 1256 __ Bind(&fall_through);
1250 } 1257 }
1251 1258
1252 1259
1253 void Intrinsifier::Double_fromInteger(Assembler* assembler) { 1260 void Intrinsifier::Double_fromInteger(Assembler* assembler) {
1254 Label fall_through; 1261 Label fall_through;
1255 __ movl(EAX, Address(ESP, +1 * kWordSize)); 1262 __ movl(EAX, Address(ESP, +1 * kWordSize));
1256 __ testl(EAX, Immediate(kSmiTagMask)); 1263 __ testl(EAX, Immediate(kSmiTagMask));
1257 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); 1264 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);
1258 // Is Smi. 1265 // Is Smi.
1259 __ SmiUntag(EAX); 1266 __ SmiUntag(EAX);
1260 __ cvtsi2sd(XMM0, EAX); 1267 __ cvtsi2sd(XMM0, EAX);
1261 const Class& double_class = Class::Handle( 1268 const Class& double_class = Class::Handle(
1262 Isolate::Current()->object_store()->double_class()); 1269 Isolate::Current()->object_store()->double_class());
1263 __ TryAllocate(double_class, 1270 __ TryAllocate(double_class,
1264 &fall_through, 1271 &fall_through,
1265 Assembler::kNearJump, 1272 Assembler::kNearJump,
1266 EAX); // Result register. 1273 EAX, // Result register.
1274 EBX);
1267 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); 1275 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
1268 __ ret(); 1276 __ ret();
1269 __ Bind(&fall_through); 1277 __ Bind(&fall_through);
1270 } 1278 }
1271 1279
1272 1280
1273 void Intrinsifier::Double_getIsNaN(Assembler* assembler) { 1281 void Intrinsifier::Double_getIsNaN(Assembler* assembler) {
1274 Label is_true; 1282 Label is_true;
1275 __ movl(EAX, Address(ESP, +1 * kWordSize)); 1283 __ movl(EAX, Address(ESP, +1 * kWordSize));
1276 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset())); 1284 __ movsd(XMM0, FieldAddress(EAX, Double::value_offset()));
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through); 1337 TestLastArgumentIsDouble(assembler, &is_smi, &fall_through);
1330 // Argument is double and is in EAX. 1338 // Argument is double and is in EAX.
1331 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset())); 1339 __ movsd(XMM1, FieldAddress(EAX, Double::value_offset()));
1332 __ Bind(&double_op); 1340 __ Bind(&double_op);
1333 __ sqrtsd(XMM0, XMM1); 1341 __ sqrtsd(XMM0, XMM1);
1334 const Class& double_class = Class::Handle( 1342 const Class& double_class = Class::Handle(
1335 Isolate::Current()->object_store()->double_class()); 1343 Isolate::Current()->object_store()->double_class());
1336 __ TryAllocate(double_class, 1344 __ TryAllocate(double_class,
1337 &fall_through, 1345 &fall_through,
1338 Assembler::kNearJump, 1346 Assembler::kNearJump,
1339 EAX); // Result register. 1347 EAX, // Result register.
1348 EBX);
1340 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0); 1349 __ movsd(FieldAddress(EAX, Double::value_offset()), XMM0);
1341 __ ret(); 1350 __ ret();
1342 __ Bind(&is_smi); 1351 __ Bind(&is_smi);
1343 __ SmiUntag(EAX); 1352 __ SmiUntag(EAX);
1344 __ cvtsi2sd(XMM1, EAX); 1353 __ cvtsi2sd(XMM1, EAX);
1345 __ jmp(&double_op); 1354 __ jmp(&double_op);
1346 __ Bind(&fall_through); 1355 __ Bind(&fall_through);
1347 } 1356 }
1348 1357
1349 1358
(...skipping 15 matching lines...) Expand all
1365 case kCosine: __ fcos(); break; 1374 case kCosine: __ fcos(); break;
1366 default: 1375 default:
1367 UNREACHABLE(); 1376 UNREACHABLE();
1368 } 1377 }
1369 const Class& double_class = Class::Handle( 1378 const Class& double_class = Class::Handle(
1370 Isolate::Current()->object_store()->double_class()); 1379 Isolate::Current()->object_store()->double_class());
1371 Label alloc_failed; 1380 Label alloc_failed;
1372 __ TryAllocate(double_class, 1381 __ TryAllocate(double_class,
1373 &alloc_failed, 1382 &alloc_failed,
1374 Assembler::kNearJump, 1383 Assembler::kNearJump,
1375 EAX); // Result register. 1384 EAX, // Result register.
1385 EBX);
1376 __ fstpl(FieldAddress(EAX, Double::value_offset())); 1386 __ fstpl(FieldAddress(EAX, Double::value_offset()));
1377 __ ret(); 1387 __ ret();
1378 1388
1379 __ Bind(&is_smi); // smi -> double. 1389 __ Bind(&is_smi); // smi -> double.
1380 __ SmiUntag(EAX); 1390 __ SmiUntag(EAX);
1381 __ pushl(EAX); 1391 __ pushl(EAX);
1382 __ filds(Address(ESP, 0)); 1392 __ filds(Address(ESP, 0));
1383 __ popl(EAX); 1393 __ popl(EAX);
1384 __ jmp(&double_op); 1394 __ jmp(&double_op);
1385 1395
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
1653 __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags. 1663 __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags.
1654 } 1664 }
1655 1665
1656 // Set the length field. 1666 // Set the length field.
1657 __ popl(EDI); 1667 __ popl(EDI);
1658 __ StoreIntoObjectNoBarrier(EAX, 1668 __ StoreIntoObjectNoBarrier(EAX,
1659 FieldAddress(EAX, String::length_offset()), 1669 FieldAddress(EAX, String::length_offset()),
1660 EDI); 1670 EDI);
1661 // Clear hash. 1671 // Clear hash.
1662 __ movl(FieldAddress(EAX, String::hash_offset()), Immediate(0)); 1672 __ movl(FieldAddress(EAX, String::hash_offset()), Immediate(0));
1673 __ BumpAllocationCount(kOneByteStringCid, EBX);
1663 __ jmp(ok, Assembler::kNearJump); 1674 __ jmp(ok, Assembler::kNearJump);
1664 1675
1665 __ Bind(&pop_and_fail); 1676 __ Bind(&pop_and_fail);
1666 __ popl(EDI); 1677 __ popl(EDI);
1667 __ jmp(failure); 1678 __ jmp(failure);
1668 } 1679 }
1669 1680
1670 1681
1671 // Arg0: Onebyte String 1682 // Arg0: Onebyte String
1672 // Arg1: Start index as Smi. 1683 // Arg1: Start index as Smi.
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 1810
1800 1811
1801 void Intrinsifier::TwoByteString_equality(Assembler* assembler) { 1812 void Intrinsifier::TwoByteString_equality(Assembler* assembler) {
1802 StringEquality(assembler, kTwoByteStringCid); 1813 StringEquality(assembler, kTwoByteStringCid);
1803 } 1814 }
1804 1815
1805 #undef __ 1816 #undef __
1806 } // namespace dart 1817 } // namespace dart
1807 1818
1808 #endif // defined TARGET_ARCH_IA32 1819 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698