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

Side by Side Diff: runtime/vm/stub_code_arm.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 | « no previous file | runtime/vm/stub_code_arm64.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) 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_ARM) 6 #if defined(TARGET_ARCH_ARM)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/code_generator.h" 9 #include "vm/code_generator.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 1242
1243 1243
1244 // Note: R5 must be preserved. 1244 // Note: R5 must be preserved.
1245 // Attempt a quick Smi operation for known operations ('kind'). The ICData 1245 // Attempt a quick Smi operation for known operations ('kind'). The ICData
1246 // must have been primed with a Smi/Smi check that will be used for counting 1246 // must have been primed with a Smi/Smi check that will be used for counting
1247 // the invocations. 1247 // the invocations.
1248 static void EmitFastSmiOp(Assembler* assembler, 1248 static void EmitFastSmiOp(Assembler* assembler,
1249 Token::Kind kind, 1249 Token::Kind kind,
1250 intptr_t num_args, 1250 intptr_t num_args,
1251 Label* not_smi_or_overflow) { 1251 Label* not_smi_or_overflow) {
1252 __ Comment("Fast Smi op");
1252 __ ldr(R0, Address(SP, 0 * kWordSize)); 1253 __ ldr(R0, Address(SP, 0 * kWordSize));
1253 __ ldr(R1, Address(SP, 1 * kWordSize)); 1254 __ ldr(R1, Address(SP, 1 * kWordSize));
1254 __ orr(TMP, R0, Operand(R1)); 1255 __ orr(TMP, R0, Operand(R1));
1255 __ tst(TMP, Operand(kSmiTagMask)); 1256 __ tst(TMP, Operand(kSmiTagMask));
1256 __ b(not_smi_or_overflow, NE); 1257 __ b(not_smi_or_overflow, NE);
1257 switch (kind) { 1258 switch (kind) {
1258 case Token::kADD: { 1259 case Token::kADD: {
1259 __ adds(R0, R1, Operand(R0)); // Adds. 1260 __ adds(R0, R1, Operand(R0)); // Adds.
1260 __ b(not_smi_or_overflow, VS); // Branch if overflow. 1261 __ b(not_smi_or_overflow, VS); // Branch if overflow.
1261 break; 1262 break;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1327 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1328 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1328 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask())); 1329 __ and_(R6, R6, Operand(ICData::NumArgsTestedMask()));
1329 __ CompareImmediate(R6, num_args); 1330 __ CompareImmediate(R6, num_args);
1330 __ b(&ok, EQ); 1331 __ b(&ok, EQ);
1331 __ Stop("Incorrect stub for IC data"); 1332 __ Stop("Incorrect stub for IC data");
1332 __ Bind(&ok); 1333 __ Bind(&ok);
1333 } 1334 }
1334 #endif // DEBUG 1335 #endif // DEBUG
1335 1336
1336 1337
1337 // Check single stepping. 1338 __ Comment("Check single stepping");
1338 Label stepping, done_stepping; 1339 Label stepping, done_stepping;
1339 __ LoadIsolate(R6); 1340 __ LoadIsolate(R6);
1340 __ ldrb(R6, Address(R6, Isolate::single_step_offset())); 1341 __ ldrb(R6, Address(R6, Isolate::single_step_offset()));
1341 __ CompareImmediate(R6, 0); 1342 __ CompareImmediate(R6, 0);
1342 __ b(&stepping, NE); 1343 __ b(&stepping, NE);
1343 __ Bind(&done_stepping); 1344 __ Bind(&done_stepping);
1344 1345
1346 __ Comment("Range feedback collection");
1345 Label not_smi_or_overflow; 1347 Label not_smi_or_overflow;
1346 if (range_collection_mode == kCollectRanges) { 1348 if (range_collection_mode == kCollectRanges) {
1347 ASSERT((num_args == 1) || (num_args == 2)); 1349 ASSERT((num_args == 1) || (num_args == 2));
1348 if (num_args == 2) { 1350 if (num_args == 2) {
1349 __ ldr(R0, Address(SP, 1 * kWordSize)); 1351 __ ldr(R0, Address(SP, 1 * kWordSize));
1350 __ UpdateRangeFeedback(R0, 0, R5, R1, R4, &not_smi_or_overflow); 1352 __ UpdateRangeFeedback(R0, 0, R5, R1, R4, &not_smi_or_overflow);
1351 } 1353 }
1352 1354
1353 __ ldr(R0, Address(SP, 0 * kWordSize)); 1355 __ ldr(R0, Address(SP, 0 * kWordSize));
1354 __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, &not_smi_or_overflow); 1356 __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, &not_smi_or_overflow);
1355 } 1357 }
1356 if (kind != Token::kILLEGAL) { 1358 if (kind != Token::kILLEGAL) {
1357 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow); 1359 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
1358 } 1360 }
1359 __ Bind(&not_smi_or_overflow); 1361 __ Bind(&not_smi_or_overflow);
1360 1362
1363 __ Comment("Extract ICData initial values and receiver cid");
1361 // Load arguments descriptor into R4. 1364 // Load arguments descriptor into R4.
1362 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 1365 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
1363 // Loop that checks if there is an IC data match. 1366 // Loop that checks if there is an IC data match.
1364 Label loop, update, test, found; 1367 Label loop, update, test, found;
1365 // R5: IC data object (preserved). 1368 // R5: IC data object (preserved).
1366 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset())); 1369 __ ldr(R6, FieldAddress(R5, ICData::ic_data_offset()));
1367 // R6: ic_data_array with check entries: classes and target functions. 1370 // R6: ic_data_array with check entries: classes and target functions.
1368 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag); 1371 __ AddImmediate(R6, R6, Array::data_offset() - kHeapObjectTag);
1369 // R6: points directly to the first ic data array element. 1372 // R6: points directly to the first ic data array element.
1370 1373
1371 // Get the receiver's class ID (first read number of arguments from 1374 // Get the receiver's class ID (first read number of arguments from
1372 // arguments descriptor array and then access the receiver from the stack). 1375 // arguments descriptor array and then access the receiver from the stack).
1373 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset())); 1376 __ ldr(R7, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
1374 __ sub(R7, R7, Operand(Smi::RawValue(1))); 1377 __ sub(R7, R7, Operand(Smi::RawValue(1)));
1375 __ ldr(R0, Address(SP, R7, LSL, 1)); // R7 (argument_count - 1) is smi. 1378 __ ldr(R0, Address(SP, R7, LSL, 1)); // R7 (argument_count - 1) is smi.
1376 __ LoadTaggedClassIdMayBeSmi(R0, R0); 1379 __ LoadTaggedClassIdMayBeSmi(R0, R0);
1377 // R7: argument_count - 1 (smi). 1380 // R7: argument_count - 1 (smi).
1378 // R0: receiver's class ID (smi). 1381 // R0: receiver's class ID (smi).
1379 __ ldr(R1, Address(R6, 0)); // First class id (smi) to check. 1382 __ ldr(R1, Address(R6, 0)); // First class id (smi) to check.
1380 __ b(&test); 1383 __ b(&test);
1381 1384
1385 __ Comment("ICData loop");
1382 __ Bind(&loop); 1386 __ Bind(&loop);
1383 for (int i = 0; i < num_args; i++) { 1387 for (int i = 0; i < num_args; i++) {
1384 if (i > 0) { 1388 if (i > 0) {
1385 // If not the first, load the next argument's class ID. 1389 // If not the first, load the next argument's class ID.
1386 __ AddImmediate(R0, R7, Smi::RawValue(-i)); 1390 __ AddImmediate(R0, R7, Smi::RawValue(-i));
1387 __ ldr(R0, Address(SP, R0, LSL, 1)); 1391 __ ldr(R0, Address(SP, R0, LSL, 1));
1388 __ LoadTaggedClassIdMayBeSmi(R0, R0); 1392 __ LoadTaggedClassIdMayBeSmi(R0, R0);
1389 // R0: next argument class ID (smi). 1393 // R0: next argument class ID (smi).
1390 __ LoadFromOffset(kWord, R1, R6, i * kWordSize); 1394 __ LoadFromOffset(kWord, R1, R6, i * kWordSize);
1391 // R1: next class ID to check (smi). 1395 // R1: next class ID to check (smi).
(...skipping 14 matching lines...) Expand all
1406 } 1410 }
1407 1411
1408 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1412 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1409 __ AddImmediate(R6, entry_size); // Next entry. 1413 __ AddImmediate(R6, entry_size); // Next entry.
1410 __ ldr(R1, Address(R6, 0)); // Next class ID. 1414 __ ldr(R1, Address(R6, 0)); // Next class ID.
1411 1415
1412 __ Bind(&test); 1416 __ Bind(&test);
1413 __ CompareImmediate(R1, Smi::RawValue(kIllegalCid)); // Done? 1417 __ CompareImmediate(R1, Smi::RawValue(kIllegalCid)); // Done?
1414 __ b(&loop, NE); 1418 __ b(&loop, NE);
1415 1419
1416 // IC miss. 1420 __ Comment("IC miss");
1417 // Compute address of arguments. 1421 // Compute address of arguments.
1418 // R7: argument_count - 1 (smi). 1422 // R7: argument_count - 1 (smi).
1419 __ add(R7, SP, Operand(R7, LSL, 1)); // R7 is Smi. 1423 __ add(R7, SP, Operand(R7, LSL, 1)); // R7 is Smi.
1420 // R7: address of receiver. 1424 // R7: address of receiver.
1421 // Create a stub frame as we are pushing some objects on the stack before 1425 // Create a stub frame as we are pushing some objects on the stack before
1422 // calling into the runtime. 1426 // calling into the runtime.
1423 __ EnterStubFrame(); 1427 __ EnterStubFrame();
1424 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1428 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1425 // Preserve IC data object and arguments descriptor array and 1429 // Preserve IC data object and arguments descriptor array and
1426 // setup space on stack for result (target code object). 1430 // setup space on stack for result (target code object).
(...skipping 14 matching lines...) Expand all
1441 __ LeaveStubFrame(); 1445 __ LeaveStubFrame();
1442 Label call_target_function; 1446 Label call_target_function;
1443 __ b(&call_target_function); 1447 __ b(&call_target_function);
1444 1448
1445 __ Bind(&found); 1449 __ Bind(&found);
1446 // R6: pointer to an IC data check group. 1450 // R6: pointer to an IC data check group.
1447 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1451 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1448 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1452 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1449 __ LoadFromOffset(kWord, R0, R6, target_offset); 1453 __ LoadFromOffset(kWord, R0, R6, target_offset);
1450 1454
1451 // Update counter. 1455 __ Comment("Update caller's counter");
1452 __ LoadFromOffset(kWord, R1, R6, count_offset); 1456 __ LoadFromOffset(kWord, R1, R6, count_offset);
1453 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1457 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1454 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow. 1458 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow.
1455 __ StoreIntoSmiField(Address(R6, count_offset), R1); 1459 __ StoreIntoSmiField(Address(R6, count_offset), R1);
1456 1460
1461 __ Comment("Call target");
1457 __ Bind(&call_target_function); 1462 __ Bind(&call_target_function);
1458 // R0: target function. 1463 // R0: target function.
1459 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); 1464 __ ldr(R2, FieldAddress(R0, Function::instructions_offset()));
1460 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); 1465 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1461 if (range_collection_mode == kCollectRanges) { 1466 if (range_collection_mode == kCollectRanges) {
1462 __ ldr(R1, Address(SP, 0 * kWordSize)); 1467 __ ldr(R1, Address(SP, 0 * kWordSize));
1463 if (num_args == 2) { 1468 if (num_args == 2) {
1464 __ ldr(R3, Address(SP, 1 * kWordSize)); 1469 __ ldr(R3, Address(SP, 1 * kWordSize));
1465 } 1470 }
1466 __ EnterStubFrame(); 1471 __ EnterStubFrame();
(...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after
2042 const Register right = R0; 2047 const Register right = R0;
2043 __ ldr(left, Address(SP, 1 * kWordSize)); 2048 __ ldr(left, Address(SP, 1 * kWordSize));
2044 __ ldr(right, Address(SP, 0 * kWordSize)); 2049 __ ldr(right, Address(SP, 0 * kWordSize));
2045 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2050 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2046 __ Ret(); 2051 __ Ret();
2047 } 2052 }
2048 2053
2049 } // namespace dart 2054 } // namespace dart
2050 2055
2051 #endif // defined TARGET_ARCH_ARM 2056 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/stub_code_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698