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

Side by Side Diff: runtime/vm/stub_code_ia32.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_arm64.cc ('k') | runtime/vm/stub_code_mips.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_IA32) 6 #if defined(TARGET_ARCH_IA32)
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 1172 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 1183
1184 1184
1185 // Note: ECX must be preserved. 1185 // Note: ECX must be preserved.
1186 // Attempt a quick Smi operation for known operations ('kind'). The ICData 1186 // Attempt a quick Smi operation for known operations ('kind'). The ICData
1187 // must have been primed with a Smi/Smi check that will be used for counting 1187 // must have been primed with a Smi/Smi check that will be used for counting
1188 // the invocations. 1188 // the invocations.
1189 static void EmitFastSmiOp(Assembler* assembler, 1189 static void EmitFastSmiOp(Assembler* assembler,
1190 Token::Kind kind, 1190 Token::Kind kind,
1191 intptr_t num_args, 1191 intptr_t num_args,
1192 Label* not_smi_or_overflow) { 1192 Label* not_smi_or_overflow) {
1193 __ Comment("Fast Smi op");
1193 ASSERT(num_args == 2); 1194 ASSERT(num_args == 2);
1194 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Right 1195 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Right
1195 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left 1196 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Left
1196 __ movl(EBX, EDI); 1197 __ movl(EBX, EDI);
1197 __ orl(EBX, EAX); 1198 __ orl(EBX, EAX);
1198 __ testl(EBX, Immediate(kSmiTagMask)); 1199 __ testl(EBX, Immediate(kSmiTagMask));
1199 __ j(NOT_ZERO, not_smi_or_overflow, Assembler::kNearJump); 1200 __ j(NOT_ZERO, not_smi_or_overflow, Assembler::kNearJump);
1200 switch (kind) { 1201 switch (kind) {
1201 case Token::kADD: { 1202 case Token::kADD: {
1202 __ addl(EAX, EDI); 1203 __ addl(EAX, EDI);
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1281 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset())); 1282 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset()));
1282 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. 1283 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed.
1283 __ andl(EBX, Immediate(ICData::NumArgsTestedMask())); 1284 __ andl(EBX, Immediate(ICData::NumArgsTestedMask()));
1284 __ cmpl(EBX, Immediate(num_args)); 1285 __ cmpl(EBX, Immediate(num_args));
1285 __ j(EQUAL, &ok, Assembler::kNearJump); 1286 __ j(EQUAL, &ok, Assembler::kNearJump);
1286 __ Stop("Incorrect stub for IC data"); 1287 __ Stop("Incorrect stub for IC data");
1287 __ Bind(&ok); 1288 __ Bind(&ok);
1288 } 1289 }
1289 #endif // DEBUG 1290 #endif // DEBUG
1290 1291
1291 // Check single stepping. 1292 __ Comment("Check single stepping");
1292 Label stepping, done_stepping; 1293 Label stepping, done_stepping;
1293 uword single_step_address = reinterpret_cast<uword>(Isolate::Current()) + 1294 uword single_step_address = reinterpret_cast<uword>(Isolate::Current()) +
1294 Isolate::single_step_offset(); 1295 Isolate::single_step_offset();
1295 __ cmpb(Address::Absolute(single_step_address), Immediate(0)); 1296 __ cmpb(Address::Absolute(single_step_address), Immediate(0));
1296 __ j(NOT_EQUAL, &stepping); 1297 __ j(NOT_EQUAL, &stepping);
1297 __ Bind(&done_stepping); 1298 __ Bind(&done_stepping);
1298 1299
1300 __ Comment("Range feedback collection");
1299 Label not_smi_or_overflow; 1301 Label not_smi_or_overflow;
1300 if (range_collection_mode == kCollectRanges) { 1302 if (range_collection_mode == kCollectRanges) {
1301 ASSERT((num_args == 1) || (num_args == 2)); 1303 ASSERT((num_args == 1) || (num_args == 2));
1302 if (num_args == 2) { 1304 if (num_args == 2) {
1303 __ movl(EAX, Address(ESP, + 2 * kWordSize)); 1305 __ movl(EAX, Address(ESP, + 2 * kWordSize));
1304 __ UpdateRangeFeedback(EAX, 0, ECX, EBX, EDI, ESI, &not_smi_or_overflow); 1306 __ UpdateRangeFeedback(EAX, 0, ECX, EBX, EDI, ESI, &not_smi_or_overflow);
1305 } 1307 }
1306 1308
1307 __ movl(EAX, Address(ESP, + 1 * kWordSize)); 1309 __ movl(EAX, Address(ESP, + 1 * kWordSize));
1308 __ UpdateRangeFeedback(EAX, (num_args - 1), ECX, EBX, EDI, ESI, 1310 __ UpdateRangeFeedback(EAX, (num_args - 1), ECX, EBX, EDI, ESI,
1309 &not_smi_or_overflow); 1311 &not_smi_or_overflow);
1310 } 1312 }
1311 if (kind != Token::kILLEGAL) { 1313 if (kind != Token::kILLEGAL) {
1312 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow); 1314 EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
1313 } 1315 }
1314 __ Bind(&not_smi_or_overflow); 1316 __ Bind(&not_smi_or_overflow);
1315 1317
1318 __ Comment("Extract ICData initial values and receiver cid");
1316 // ECX: IC data object (preserved). 1319 // ECX: IC data object (preserved).
1317 // Load arguments descriptor into EDX. 1320 // Load arguments descriptor into EDX.
1318 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); 1321 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
1319 // Loop that checks if there is an IC data match. 1322 // Loop that checks if there is an IC data match.
1320 Label loop, update, test, found;
1321 // ECX: IC data object (preserved). 1323 // ECX: IC data object (preserved).
1322 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); 1324 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1323 // EBX: ic_data_array with check entries: classes and target functions. 1325 // EBX: ic_data_array with check entries: classes and target functions.
1324 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); 1326 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1325 // EBX: points directly to the first ic data array element. 1327 // EBX: points directly to the first ic data array element.
1326 1328
1327 // Get the receiver's class ID (first read number of arguments from 1329 // Get the receiver's class ID (first read number of arguments from
1328 // arguments descriptor array and then access the receiver from the stack). 1330 // arguments descriptor array and then access the receiver from the stack).
1329 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 1331 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
1330 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is smi. 1332 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is smi.
1331 __ LoadTaggedClassIdMayBeSmi(EAX, EDI); 1333 __ LoadTaggedClassIdMayBeSmi(EAX, EDI);
1332 1334
1333 // EAX: receiver's class ID (smi). 1335 // EAX: receiver's class ID (smi).
1334 __ movl(EDI, Address(EBX, 0)); // First class id (smi) to check. 1336 __ movl(EDI, Address(EBX, 0)); // First class id (smi) to check.
1337 Label loop, update, test, found;
1335 __ jmp(&test); 1338 __ jmp(&test);
1336 1339
1340 __ Comment("ICData loop");
1337 __ Bind(&loop); 1341 __ Bind(&loop);
1338 for (int i = 0; i < num_args; i++) { 1342 for (int i = 0; i < num_args; i++) {
1339 if (i > 0) { 1343 if (i > 0) {
1340 // If not the first, load the next argument's class ID. 1344 // If not the first, load the next argument's class ID.
1341 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 1345 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
1342 __ movl(EDI, Address(ESP, EAX, TIMES_2, - i * kWordSize)); 1346 __ movl(EDI, Address(ESP, EAX, TIMES_2, - i * kWordSize));
1343 __ LoadTaggedClassIdMayBeSmi(EAX, EDI); 1347 __ LoadTaggedClassIdMayBeSmi(EAX, EDI);
1344 1348
1345 // EAX: next argument class ID (smi). 1349 // EAX: next argument class ID (smi).
1346 __ movl(EDI, Address(EBX, i * kWordSize)); 1350 __ movl(EDI, Address(EBX, i * kWordSize));
(...skipping 16 matching lines...) Expand all
1363 } 1367 }
1364 1368
1365 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1369 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1366 __ addl(EBX, Immediate(entry_size)); // Next entry. 1370 __ addl(EBX, Immediate(entry_size)); // Next entry.
1367 __ movl(EDI, Address(EBX, 0)); // Next class ID. 1371 __ movl(EDI, Address(EBX, 0)); // Next class ID.
1368 1372
1369 __ Bind(&test); 1373 __ Bind(&test);
1370 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done? 1374 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done?
1371 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1375 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1372 1376
1373 // IC miss. 1377 __ Comment("IC miss");
1374 const Immediate& raw_null = 1378 const Immediate& raw_null =
1375 Immediate(reinterpret_cast<intptr_t>(Object::null())); 1379 Immediate(reinterpret_cast<intptr_t>(Object::null()));
1376 // Compute address of arguments (first read number of arguments from 1380 // Compute address of arguments (first read number of arguments from
1377 // arguments descriptor array and then compute address on the stack). 1381 // arguments descriptor array and then compute address on the stack).
1378 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 1382 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
1379 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi. 1383 __ leal(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX is Smi.
1380 // Create a stub frame as we are pushing some objects on the stack before 1384 // Create a stub frame as we are pushing some objects on the stack before
1381 // calling into the runtime. 1385 // calling into the runtime.
1382 __ EnterStubFrame(); 1386 __ EnterStubFrame();
1383 __ pushl(EDX); // Preserve arguments descriptor array. 1387 __ pushl(EDX); // Preserve arguments descriptor array.
(...skipping 11 matching lines...) Expand all
1395 __ popl(EAX); 1399 __ popl(EAX);
1396 } 1400 }
1397 __ popl(EAX); // Pop returned function object into EAX. 1401 __ popl(EAX); // Pop returned function object into EAX.
1398 __ popl(ECX); // Restore IC data array. 1402 __ popl(ECX); // Restore IC data array.
1399 __ popl(EDX); // Restore arguments descriptor array. 1403 __ popl(EDX); // Restore arguments descriptor array.
1400 __ LeaveFrame(); 1404 __ LeaveFrame();
1401 Label call_target_function; 1405 Label call_target_function;
1402 __ jmp(&call_target_function); 1406 __ jmp(&call_target_function);
1403 1407
1404 __ Bind(&found); 1408 __ Bind(&found);
1409
1405 // EBX: Pointer to an IC data check group. 1410 // EBX: Pointer to an IC data check group.
1406 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; 1411 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize;
1407 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; 1412 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize;
1408 1413
1409 // Update counter. 1414 __ Comment("Update caller's counter");
1410 __ movl(EAX, Address(EBX, count_offset)); 1415 __ movl(EAX, Address(EBX, count_offset));
1411 __ addl(EAX, Immediate(Smi::RawValue(1))); 1416 __ addl(EAX, Immediate(Smi::RawValue(1)));
1412 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue))); 1417 __ movl(EDI, Immediate(Smi::RawValue(Smi::kMaxValue)));
1413 __ cmovno(EDI, EAX); 1418 __ cmovno(EDI, EAX);
1414 __ StoreIntoSmiField(Address(EBX, count_offset), EDI); 1419 __ StoreIntoSmiField(Address(EBX, count_offset), EDI);
1415 1420
1416 __ movl(EAX, Address(EBX, target_offset)); 1421 __ movl(EAX, Address(EBX, target_offset));
1417 __ Bind(&call_target_function); 1422 __ Bind(&call_target_function);
1423 __ Comment("Call target");
1418 // EAX: Target function. 1424 // EAX: Target function.
1419 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); 1425 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset()));
1420 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1426 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1421 if (range_collection_mode == kCollectRanges) { 1427 if (range_collection_mode == kCollectRanges) {
1422 __ movl(EDI, Address(ESP, + 1 * kWordSize)); 1428 __ movl(EDI, Address(ESP, + 1 * kWordSize));
1423 if (num_args == 2) { 1429 if (num_args == 2) {
1424 __ movl(ESI, Address(ESP, + 2 * kWordSize)); 1430 __ movl(ESI, Address(ESP, + 2 * kWordSize));
1425 } 1431 }
1426 __ EnterStubFrame(); 1432 __ EnterStubFrame();
1427 __ pushl(ECX); 1433 __ pushl(ECX);
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 const Register temp = ECX; 2038 const Register temp = ECX;
2033 __ movl(left, Address(ESP, 2 * kWordSize)); 2039 __ movl(left, Address(ESP, 2 * kWordSize));
2034 __ movl(right, Address(ESP, 1 * kWordSize)); 2040 __ movl(right, Address(ESP, 1 * kWordSize));
2035 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 2041 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
2036 __ ret(); 2042 __ ret();
2037 } 2043 }
2038 2044
2039 } // namespace dart 2045 } // namespace dart
2040 2046
2041 #endif // defined TARGET_ARCH_IA32 2047 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/stub_code_arm64.cc ('k') | runtime/vm/stub_code_mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698