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

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

Issue 313083008: Add LoadTaggedClassIdMayBeSmi to assembly and improve performance of inline cache stubs. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 6 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 | « 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 1303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1314 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1315 __ popl(ECX); 1315 __ popl(ECX);
1316 __ LeaveFrame(); 1316 __ LeaveFrame();
1317 __ Bind(&not_stepping); 1317 __ Bind(&not_stepping);
1318 } 1318 }
1319 1319
1320 // ECX: IC data object (preserved). 1320 // ECX: IC data object (preserved).
1321 // Load arguments descriptor into EDX. 1321 // Load arguments descriptor into EDX.
1322 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); 1322 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset()));
1323 // Loop that checks if there is an IC data match. 1323 // Loop that checks if there is an IC data match.
1324 Label loop, update, test, found, get_class_id_as_smi; 1324 Label loop, update, test, found;
1325 // ECX: IC data object (preserved). 1325 // ECX: IC data object (preserved).
1326 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); 1326 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset()));
1327 // EBX: ic_data_array with check entries: classes and target functions. 1327 // EBX: ic_data_array with check entries: classes and target functions.
1328 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); 1328 __ leal(EBX, FieldAddress(EBX, Array::data_offset()));
1329 // EBX: points directly to the first ic data array element. 1329 // EBX: points directly to the first ic data array element.
1330 1330
1331 // Get the receiver's class ID (first read number of arguments from 1331 // Get the receiver's class ID (first read number of arguments from
1332 // arguments descriptor array and then access the receiver from the stack). 1332 // arguments descriptor array and then access the receiver from the stack).
1333 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 1333 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
1334 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is smi. 1334 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is smi.
1335 __ call(&get_class_id_as_smi); 1335 __ LoadTaggedClassIdMayBeSmi(EAX, EAX);
1336
1336 // EAX: receiver's class ID (smi). 1337 // EAX: receiver's class ID (smi).
1337 __ movl(EDI, Address(EBX, 0)); // First class id (smi) to check. 1338 __ movl(EDI, Address(EBX, 0)); // First class id (smi) to check.
1338 __ jmp(&test); 1339 __ jmp(&test);
1339 1340
1340 __ Bind(&loop); 1341 __ Bind(&loop);
1341 for (int i = 0; i < num_args; i++) { 1342 for (int i = 0; i < num_args; i++) {
1342 if (i > 0) { 1343 if (i > 0) {
1343 // If not the first, load the next argument's class ID. 1344 // If not the first, load the next argument's class ID.
1344 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 1345 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
1345 __ movl(EAX, Address(ESP, EAX, TIMES_2, - i * kWordSize)); 1346 __ movl(EAX, Address(ESP, EAX, TIMES_2, - i * kWordSize));
1346 __ call(&get_class_id_as_smi); 1347 __ LoadTaggedClassIdMayBeSmi(EAX, EAX);
1348
1347 // EAX: next argument class ID (smi). 1349 // EAX: next argument class ID (smi).
1348 __ movl(EDI, Address(EBX, i * kWordSize)); 1350 __ movl(EDI, Address(EBX, i * kWordSize));
1349 // EDI: next class ID to check (smi). 1351 // EDI: next class ID to check (smi).
1350 } 1352 }
1351 __ cmpl(EAX, EDI); // Class id match? 1353 __ cmpl(EAX, EDI); // Class id match?
1352 if (i < (num_args - 1)) { 1354 if (i < (num_args - 1)) {
1353 __ j(NOT_EQUAL, &update); // Continue. 1355 __ j(NOT_EQUAL, &update); // Continue.
1354 } else { 1356 } else {
1355 // Last check, all checks before matched. 1357 // Last check, all checks before matched.
1356 __ j(EQUAL, &found, Assembler::kNearJump); // Break. 1358 __ j(EQUAL, &found, Assembler::kNearJump); // Break.
1357 } 1359 }
1358 } 1360 }
1359 __ Bind(&update); 1361 __ Bind(&update);
1360 // Reload receiver class ID. It has not been destroyed when num_args == 1. 1362 // Reload receiver class ID. It has not been destroyed when num_args == 1.
1361 if (num_args > 1) { 1363 if (num_args > 1) {
1362 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); 1364 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
1363 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); 1365 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0));
1364 __ call(&get_class_id_as_smi); 1366 __ LoadTaggedClassIdMayBeSmi(EAX, EAX);
1365 } 1367 }
1366 1368
1367 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1369 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1368 __ addl(EBX, Immediate(entry_size)); // Next entry. 1370 __ addl(EBX, Immediate(entry_size)); // Next entry.
1369 __ movl(EDI, Address(EBX, 0)); // Next class ID. 1371 __ movl(EDI, Address(EBX, 0)); // Next class ID.
1370 1372
1371 __ Bind(&test); 1373 __ Bind(&test);
1372 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done? 1374 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done?
1373 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1375 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1374 1376
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1))); 1413 __ addl(Address(EBX, count_offset), Immediate(Smi::RawValue(1)));
1412 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); 1414 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump);
1413 __ movl(Address(EBX, count_offset), 1415 __ movl(Address(EBX, count_offset),
1414 Immediate(Smi::RawValue(Smi::kMaxValue))); 1416 Immediate(Smi::RawValue(Smi::kMaxValue)));
1415 1417
1416 __ Bind(&call_target_function); 1418 __ Bind(&call_target_function);
1417 // EAX: Target function. 1419 // EAX: Target function.
1418 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset())); 1420 __ movl(EBX, FieldAddress(EAX, Function::instructions_offset()));
1419 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1421 __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1420 __ jmp(EBX); 1422 __ jmp(EBX);
1421 1423 __ int3();
1422 // Instance in EAX, return its class-id in EAX as Smi.
1423 __ Bind(&get_class_id_as_smi);
1424 Label not_smi;
1425 // Test if Smi -> load Smi class for comparison.
1426 __ testl(EAX, Immediate(kSmiTagMask));
1427 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
1428 __ movl(EAX, Immediate(Smi::RawValue(kSmiCid)));
1429 __ ret();
1430
1431 __ Bind(&not_smi);
1432 __ LoadClassId(EAX, EAX);
1433 __ SmiTag(EAX);
1434 __ ret();
1435 } 1424 }
1436 1425
1437 1426
1438 // Use inline cache data array to invoke the target or continue in inline 1427 // Use inline cache data array to invoke the target or continue in inline
1439 // cache miss handler. Stub for 1-argument check (receiver class). 1428 // cache miss handler. Stub for 1-argument check (receiver class).
1440 // ECX: Inline cache data object. 1429 // ECX: Inline cache data object.
1441 // TOS(0): Return address. 1430 // TOS(0): Return address.
1442 // Inline cache data object structure: 1431 // Inline cache data object structure:
1443 // 0: function-name 1432 // 0: function-name
1444 // 1: N, number of arguments checked. 1433 // 1: N, number of arguments checked.
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1912 const Register temp = ECX; 1901 const Register temp = ECX;
1913 __ movl(left, Address(ESP, 2 * kWordSize)); 1902 __ movl(left, Address(ESP, 2 * kWordSize));
1914 __ movl(right, Address(ESP, 1 * kWordSize)); 1903 __ movl(right, Address(ESP, 1 * kWordSize));
1915 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); 1904 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp);
1916 __ ret(); 1905 __ ret();
1917 } 1906 }
1918 1907
1919 } // namespace dart 1908 } // namespace dart
1920 1909
1921 #endif // defined TARGET_ARCH_IA32 1910 #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