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

Side by Side Diff: runtime/vm/stub_code_x64.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_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 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 __ pushq(RBX); 1241 __ pushq(RBX);
1242 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1242 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1243 __ popq(RBX); 1243 __ popq(RBX);
1244 __ LeaveStubFrame(); 1244 __ LeaveStubFrame();
1245 __ Bind(&not_stepping); 1245 __ Bind(&not_stepping);
1246 } 1246 }
1247 1247
1248 // Load arguments descriptor into R10. 1248 // Load arguments descriptor into R10.
1249 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset())); 1249 __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
1250 // Loop that checks if there is an IC data match. 1250 // Loop that checks if there is an IC data match.
1251 Label loop, update, test, found, get_class_id_as_smi; 1251 Label loop, update, test, found;
1252 // RBX: IC data object (preserved). 1252 // RBX: IC data object (preserved).
1253 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset())); 1253 __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
1254 // R12: ic_data_array with check entries: classes and target functions. 1254 // R12: ic_data_array with check entries: classes and target functions.
1255 __ leaq(R12, FieldAddress(R12, Array::data_offset())); 1255 __ leaq(R12, FieldAddress(R12, Array::data_offset()));
1256 // R12: points directly to the first ic data array element. 1256 // R12: points directly to the first ic data array element.
1257 1257
1258 // Get the receiver's class ID (first read number of arguments from 1258 // Get the receiver's class ID (first read number of arguments from
1259 // arguments descriptor array and then access the receiver from the stack). 1259 // arguments descriptor array and then access the receiver from the stack).
1260 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1260 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1261 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX (argument count) is Smi. 1261 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); // RAX (argument count) is Smi.
1262 __ call(&get_class_id_as_smi); 1262 __ LoadTaggedClassIdMayBeSmi(RAX, RAX);
1263 // RAX: receiver's class ID as smi. 1263 // RAX: receiver's class ID as smi.
1264 __ movq(R13, Address(R12, 0)); // First class ID (Smi) to check. 1264 __ movq(R13, Address(R12, 0)); // First class ID (Smi) to check.
1265 __ jmp(&test); 1265 __ jmp(&test);
1266 1266
1267 __ Bind(&loop); 1267 __ Bind(&loop);
1268 for (int i = 0; i < num_args; i++) { 1268 for (int i = 0; i < num_args; i++) {
1269 if (i > 0) { 1269 if (i > 0) {
1270 // If not the first, load the next argument's class ID. 1270 // If not the first, load the next argument's class ID.
1271 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1271 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1272 __ movq(RAX, Address(RSP, RAX, TIMES_4, - i * kWordSize)); 1272 __ movq(RAX, Address(RSP, RAX, TIMES_4, - i * kWordSize));
1273 __ call(&get_class_id_as_smi); 1273 __ LoadTaggedClassIdMayBeSmi(RAX, RAX);
1274 // RAX: next argument class ID (smi). 1274 // RAX: next argument class ID (smi).
1275 __ movq(R13, Address(R12, i * kWordSize)); 1275 __ movq(R13, Address(R12, i * kWordSize));
1276 // R13: next class ID to check (smi). 1276 // R13: next class ID to check (smi).
1277 } 1277 }
1278 __ cmpq(RAX, R13); // Class id match? 1278 __ cmpq(RAX, R13); // Class id match?
1279 if (i < (num_args - 1)) { 1279 if (i < (num_args - 1)) {
1280 __ j(NOT_EQUAL, &update); // Continue. 1280 __ j(NOT_EQUAL, &update); // Continue.
1281 } else { 1281 } else {
1282 // Last check, all checks before matched. 1282 // Last check, all checks before matched.
1283 __ j(EQUAL, &found); // Break. 1283 __ j(EQUAL, &found); // Break.
1284 } 1284 }
1285 } 1285 }
1286 __ Bind(&update); 1286 __ Bind(&update);
1287 // Reload receiver class ID. It has not been destroyed when num_args == 1. 1287 // Reload receiver class ID. It has not been destroyed when num_args == 1.
1288 if (num_args > 1) { 1288 if (num_args > 1) {
1289 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset())); 1289 __ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
1290 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0)); 1290 __ movq(RAX, Address(RSP, RAX, TIMES_4, 0));
1291 __ call(&get_class_id_as_smi); 1291 __ LoadTaggedClassIdMayBeSmi(RAX, RAX);
1292 } 1292 }
1293 1293
1294 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; 1294 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize;
1295 __ addq(R12, Immediate(entry_size)); // Next entry. 1295 __ addq(R12, Immediate(entry_size)); // Next entry.
1296 __ movq(R13, Address(R12, 0)); // Next class ID. 1296 __ movq(R13, Address(R12, 0)); // Next class ID.
1297 1297
1298 __ Bind(&test); 1298 __ Bind(&test);
1299 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done? 1299 __ cmpq(R13, Immediate(Smi::RawValue(kIllegalCid))); // Done?
1300 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); 1300 __ j(NOT_EQUAL, &loop, Assembler::kNearJump);
1301 1301
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump); 1336 __ j(NO_OVERFLOW, &call_target_function, Assembler::kNearJump);
1337 __ movq(Address(R12, count_offset), 1337 __ movq(Address(R12, count_offset),
1338 Immediate(Smi::RawValue(Smi::kMaxValue))); 1338 Immediate(Smi::RawValue(Smi::kMaxValue)));
1339 1339
1340 __ Bind(&call_target_function); 1340 __ Bind(&call_target_function);
1341 // RAX: Target function. 1341 // RAX: Target function.
1342 Label is_compiled; 1342 Label is_compiled;
1343 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset())); 1343 __ movq(RCX, FieldAddress(RAX, Function::instructions_offset()));
1344 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); 1344 __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
1345 __ jmp(RCX); 1345 __ jmp(RCX);
1346
1347 __ Bind(&get_class_id_as_smi);
1348 Label not_smi;
1349 // Test if Smi -> load Smi class for comparison.
1350 __ testq(RAX, Immediate(kSmiTagMask));
1351 __ j(NOT_ZERO, &not_smi, Assembler::kNearJump);
1352 __ movq(RAX, Immediate(Smi::RawValue(kSmiCid)));
1353 __ ret();
1354
1355 __ Bind(&not_smi);
1356 __ LoadClassId(RAX, RAX);
1357 __ SmiTag(RAX);
1358 __ ret();
1359 } 1346 }
1360 1347
1361 1348
1362 // Use inline cache data array to invoke the target or continue in inline 1349 // Use inline cache data array to invoke the target or continue in inline
1363 // cache miss handler. Stub for 1-argument check (receiver class). 1350 // cache miss handler. Stub for 1-argument check (receiver class).
1364 // RBX: Inline cache data object. 1351 // RBX: Inline cache data object.
1365 // TOS(0): Return address. 1352 // TOS(0): Return address.
1366 // Inline cache data object structure: 1353 // Inline cache data object structure:
1367 // 0: function-name 1354 // 0: function-name
1368 // 1: N, number of arguments checked. 1355 // 1: N, number of arguments checked.
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 1812
1826 __ movq(left, Address(RSP, 2 * kWordSize)); 1813 __ movq(left, Address(RSP, 2 * kWordSize));
1827 __ movq(right, Address(RSP, 1 * kWordSize)); 1814 __ movq(right, Address(RSP, 1 * kWordSize));
1828 GenerateIdenticalWithNumberCheckStub(assembler, left, right); 1815 GenerateIdenticalWithNumberCheckStub(assembler, left, right);
1829 __ ret(); 1816 __ ret();
1830 } 1817 }
1831 1818
1832 } // namespace dart 1819 } // namespace dart
1833 1820
1834 #endif // defined TARGET_ARCH_X64 1821 #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