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

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

Issue 815173002: Add code comments to inline cache stubs. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years 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 | « runtime/vm/stub_code_mips.cc ('k') | no next file » | 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) 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/globals.h" 5 #include "vm/globals.h"
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1199 1199
1200 // Note: RBX must be preserved. 1200 // Note: RBX must be preserved.
1201 // Attempt a quick Smi operation for known operations ('kind'). The ICData 1201 // Attempt a quick Smi operation for known operations ('kind'). The ICData
1202 // must have been primed with a Smi/Smi check that will be used for counting 1202 // must have been primed with a Smi/Smi check that will be used for counting
1203 // the invocations. 1203 // the invocations.
1204 static void EmitFastSmiOp(Assembler* assembler, 1204 static void EmitFastSmiOp(Assembler* assembler,
1205 Token::Kind kind, 1205 Token::Kind kind,
1206 intptr_t num_args, 1206 intptr_t num_args,
1207 Label* not_smi_or_overflow, 1207 Label* not_smi_or_overflow,
1208 bool should_update_result_range) { 1208 bool should_update_result_range) {
1209 __ Comment("Fast Smi op");
1209 if (FLAG_throw_on_javascript_int_overflow) { 1210 if (FLAG_throw_on_javascript_int_overflow) {
1210 // The overflow check is more complex than implemented below. 1211 // The overflow check is more complex than implemented below.
1211 return; 1212 return;
1212 } 1213 }
1213 ASSERT(num_args == 2); 1214 ASSERT(num_args == 2);
1214 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Right 1215 __ movq(RCX, Address(RSP, + 1 * kWordSize)); // Right
1215 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left. 1216 __ movq(RAX, Address(RSP, + 2 * kWordSize)); // Left.
1216 __ movq(R12, RCX); 1217 __ movq(R12, RCX);
1217 __ orq(R12, RAX); 1218 __ orq(R12, RAX);
1218 __ testq(R12, Immediate(kSmiTagMask)); 1219 __ testq(R12, Immediate(kSmiTagMask));
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset())); 1306 __ movl(RCX, FieldAddress(RBX, ICData::state_bits_offset()));
1306 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1307 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1307 __ andq(RCX, Immediate(ICData::NumArgsTestedMask())); 1308 __ andq(RCX, Immediate(ICData::NumArgsTestedMask()));
1308 __ cmpq(RCX, Immediate(num_args)); 1309 __ cmpq(RCX, Immediate(num_args));
1309 __ j(EQUAL, &ok, Assembler::kNearJump); 1310 __ j(EQUAL, &ok, Assembler::kNearJump);
1310 __ Stop("Incorrect stub for IC data"); 1311 __ Stop("Incorrect stub for IC data");
1311 __ Bind(&ok); 1312 __ Bind(&ok);
1312 } 1313 }
1313 #endif // DEBUG 1314 #endif // DEBUG
1314 1315
1315 // Check single stepping. 1316 __ Comment("Check single stepping");
1316 Label stepping, done_stepping; 1317 Label stepping, done_stepping;
1317 __ LoadIsolate(RAX); 1318 __ LoadIsolate(RAX);
1318 __ cmpb(Address(RAX, Isolate::single_step_offset()), Immediate(0)); 1319 __ cmpb(Address(RAX, Isolate::single_step_offset()), Immediate(0));
1319 __ j(NOT_EQUAL, &stepping); 1320 __ j(NOT_EQUAL, &stepping);
1320 __ Bind(&done_stepping); 1321 __ Bind(&done_stepping);
1321 1322
1323 __ Comment("Range feedback collection");
1322 Label not_smi_or_overflow; 1324 Label not_smi_or_overflow;
1323 if (range_collection_mode == kCollectRanges) { 1325 if (range_collection_mode == kCollectRanges) {
1324 ASSERT((num_args == 1) || (num_args == 2)); 1326 ASSERT((num_args == 1) || (num_args == 2));
1325 if (num_args == 2) { 1327 if (num_args == 2) {
1326 __ movq(RAX, Address(RSP, + 2 * kWordSize)); 1328 __ movq(RAX, Address(RSP, + 2 * kWordSize));
1327 __ UpdateRangeFeedback(RAX, 0, RBX, RCX, &not_smi_or_overflow); 1329 __ UpdateRangeFeedback(RAX, 0, RBX, RCX, &not_smi_or_overflow);
1328 } 1330 }
1329 1331
1330 __ movq(RAX, Address(RSP, + 1 * kWordSize)); 1332 __ movq(RAX, Address(RSP, + 1 * kWordSize));
1331 __ UpdateRangeFeedback(RAX, (num_args - 1), RBX, RCX, &not_smi_or_overflow); 1333 __ UpdateRangeFeedback(RAX, (num_args - 1), RBX, RCX, &not_smi_or_overflow);
1332 } 1334 }
1333 if (kind != Token::kILLEGAL) { 1335 if (kind != Token::kILLEGAL) {
1334 EmitFastSmiOp( 1336 EmitFastSmiOp(
1335 assembler, 1337 assembler,
1336 kind, 1338 kind,
1337 num_args, 1339 num_args,
1338 &not_smi_or_overflow, 1340 &not_smi_or_overflow,
1339 range_collection_mode == kCollectRanges); 1341 range_collection_mode == kCollectRanges);
1340 } 1342 }
1341 __ Bind(&not_smi_or_overflow); 1343 __ Bind(&not_smi_or_overflow);
1342 1344
1345 __ Comment("Extract ICData initial values and receiver cid");
1343 // Load arguments descriptor into R10. 1346 // Load arguments descriptor into R10.
1344 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1347 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1345 // Loop that checks if there is an IC data match. 1348 // Loop that checks if there is an IC data match.
1346 Label loop, update, test, found; 1349 Label loop, update, test, found;
1347 // RBX: IC data object (preserved). 1350 // RBX: IC data object (preserved).
1348 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); 1351 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1349 // R12: ic_data_array with check entries: classes and target functions. 1352 // R12: ic_data_array with check entries: classes and target functions.
1350 __ leaq(R12, FieldAddress(R12, Array::data_offset())); 1353 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
1351 // R12: points directly to the first ic data array element. 1354 // R12: points directly to the first ic data array element.
1352 1355
1353 // Get the receiver's class ID (first read number of arguments from 1356 // Get the receiver's class ID (first read number of arguments from
1354 // arguments descriptor array and then access the receiver from the stack). 1357 // arguments descriptor array and then access the receiver from the stack).
1355 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1358 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1356 __ movq(R13, Address(RSP, RAX, TIMES_4, 0)); // RAX (argument count) is Smi. 1359 __ movq(R13, Address(RSP, RAX, TIMES_4, 0)); // RAX (argument count) is Smi.
1357 __ LoadTaggedClassIdMayBeSmi(RAX, R13); 1360 __ LoadTaggedClassIdMayBeSmi(RAX, R13);
1358 // RAX: receiver's class ID as smi. 1361 // RAX: receiver's class ID as smi.
1359 __ movq(R13, Address(R12, 0)); // First class ID (Smi) to check. 1362 __ movq(R13, Address(R12, 0)); // First class ID (Smi) to check.
1360 __ jmp(&test); 1363 __ jmp(&test);
1361 1364
1365 __ Comment("ICData loop");
1362 __ Bind(&loop); 1366 __ Bind(&loop);
1363 for (int i = 0; i < num_args; i++) { 1367 for (int i = 0; i < num_args; i++) {
1364 if (i > 0) { 1368 if (i > 0) {
1365 // If not the first, load the next argument's class ID. 1369 // If not the first, load the next argument's class ID.
1366 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1370 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1367 __ movq(R13, Address(RSP, RAX, TIMES_4, - i * kWordSize)); 1371 __ movq(R13, Address(RSP, RAX, TIMES_4, - i * kWordSize));
1368 __ LoadTaggedClassIdMayBeSmi(RAX, R13); 1372 __ LoadTaggedClassIdMayBeSmi(RAX, R13);
1369 // RAX: next argument class ID (smi). 1373 // RAX: next argument class ID (smi).
1370 __ movq(R13, Address(R12, i * kWordSize)); 1374 __ movq(R13, Address(R12, i * kWordSize));
1371 // R13: next class ID to check (smi). 1375 // R13: next class ID to check (smi).
(...skipping 15 matching lines...) Expand all
1387 } 1391 }
1388 1392
1389 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1393 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1390 __ addq(R12, Immediate(entry_size)); // Next entry. 1394 __ addq(R12, Immediate(entry_size)); // Next entry.
1391 __ movq(R13, Address(R12, 0)); // Next class ID. 1395 __ movq(R13, Address(R12, 0)); // Next class ID.
1392 1396
1393 __ Bind(&test); 1397 __ Bind(&test);
1394 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done? 1398 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done?
1395 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1399 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1396 1400
1397 // IC miss. 1401 __ Comment("IC miss");
1398 __ LoadObject(R12, Object::null_object(), PP); 1402 __ LoadObject(R12, Object::null_object(), PP);
1399 // Compute address of arguments (first read number of arguments from 1403 // Compute address of arguments (first read number of arguments from
1400 // arguments descriptor array and then compute address on the stack). 1404 // arguments descriptor array and then compute address on the stack).
1401 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1405 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1402 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi. 1406 __ leaq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX is Smi.
1403 __ EnterStubFrame(); 1407 __ EnterStubFrame();
1404 __ pushq(R10); // Preserve arguments descriptor array. 1408 __ pushq(R10); // Preserve arguments descriptor array.
1405 __ pushq(RBX); // Preserve IC data object. 1409 __ pushq(RBX); // Preserve IC data object.
1406 __ pushq(R12); // Setup space on stack for result (target code object). 1410 __ pushq(R12); // Setup space on stack for result (target code object).
1407 // Push call arguments. 1411 // Push call arguments.
1408 for (intptr_t i = 0; i < num_args; i++) { 1412 for (intptr_t i = 0; i < num_args; i++) {
1409 __ movq(RCX, Address(RAX, -kWordSize * i)); 1413 __ movq(RCX, Address(RAX, -kWordSize * i));
1410 __ pushq(RCX); 1414 __ pushq(RCX);
1411 } 1415 }
1412 __ pushq(RBX); // Pass IC data object. 1416 __ pushq(RBX); // Pass IC data object.
1413 __ CallRuntime(handle_ic_miss, num_args + 1); 1417 __ CallRuntime(handle_ic_miss, num_args + 1);
1414 // Remove the call arguments pushed earlier, including the IC data object. 1418 // Remove the call arguments pushed earlier, including the IC data object.
1415 for (intptr_t i = 0; i < num_args + 1; i++) { 1419 for (intptr_t i = 0; i < num_args + 1; i++) {
1416 __ popq(RAX); 1420 __ popq(RAX);
1417 } 1421 }
1418 __ popq(RAX); // Pop returned function object into RAX. 1422 __ popq(RAX); // Pop returned function object into RAX.
1419 __ popq(RBX); // Restore IC data array. 1423 __ popq(RBX); // Restore IC data array.
1420 __ popq(R10); // Restore arguments descriptor array. 1424 __ popq(R10); // Restore arguments descriptor array.
1421 __ LeaveStubFrame(); 1425 __ LeaveStubFrame();
1422 Label call_target_function; 1426 Label call_target_function;
1423 __ jmp(&call_target_function); 1427 __ jmp(&call_target_function);
1424 1428
1425 __ Bind(&found); 1429 __ Bind(&found);
1430 __ Comment("Update caller's counter");
1426 // R12: Pointer to an IC data check group. 1431 // R12: Pointer to an IC data check group.
1427 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1432 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1428 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1433 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1429 __ movq(RAX, Address(R12, target_offset)); 1434 __ movq(RAX, Address(R12, target_offset));
1430 1435
1431 // Update counter. 1436 // Update counter.
1432 __ movq(R8, Address(R12, count_offset)); 1437 __ movq(R8, Address(R12, count_offset));
1433 __ addq(R8, Immediate(Smi::RawValue(1))); 1438 __ addq(R8, Immediate(Smi::RawValue(1)));
1434 __ movq(R9, Immediate(Smi::RawValue(Smi::kMaxValue))); 1439 __ movq(R9, Immediate(Smi::RawValue(Smi::kMaxValue)));
1435 __ cmovnoq(R9, R8); 1440 __ cmovnoq(R9, R8);
1436 __ StoreIntoSmiField(Address(R12, count_offset), R9); 1441 __ StoreIntoSmiField(Address(R12, count_offset), R9);
1437 1442
1443 __ Comment("Call target");
1438 __ Bind(&call_target_function); 1444 __ Bind(&call_target_function);
1439 // RAX: Target function. 1445 // RAX: Target function.
1440 Label is_compiled; 1446 Label is_compiled;
1441 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset())); 1447 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset()));
1442 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1448 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1443 if (range_collection_mode == kCollectRanges) { 1449 if (range_collection_mode == kCollectRanges) {
1444 __ movq(R8, Address(RSP, + 1 * kWordSize)); 1450 __ movq(R8, Address(RSP, + 1 * kWordSize));
1445 if (num_args == 2) { 1451 if (num_args == 2) {
1446 __ movq(R9, Address(RSP, + 2 * kWordSize)); 1452 __ movq(R9, Address(RSP, + 2 * kWordSize));
1447 } 1453 }
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
2062 2068
2063 __ movq(left, Address(RSP, 2 * kWordSize)); 2069 __ movq(left, Address(RSP, 2 * kWordSize));
2064 __ movq(right, Address(RSP, 1 * kWordSize)); 2070 __ movq(right, Address(RSP, 1 * kWordSize));
2065 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 2071 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
2066 __ ret(); 2072 __ ret();
2067 } 2073 }
2068 2074
2069 } // namespace dart 2075 } // namespace dart
2070 2076
2071 #endif // defined TARGET_ARCH_X64 2077 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698