OLD | NEW |
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 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 __ j(EQUAL, &ok, Assembler::kNearJump); | 1290 __ j(EQUAL, &ok, Assembler::kNearJump); |
1291 __ Stop("Incorrect stub for IC data"); | 1291 __ Stop("Incorrect stub for IC data"); |
1292 __ Bind(&ok); | 1292 __ Bind(&ok); |
1293 } | 1293 } |
1294 #endif // DEBUG | 1294 #endif // DEBUG |
1295 | 1295 |
1296 Label stepping, done_stepping; | 1296 Label stepping, done_stepping; |
1297 if (FLAG_enable_debugger) { | 1297 if (FLAG_enable_debugger) { |
1298 // Check single stepping. | 1298 // Check single stepping. |
1299 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1299 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
1300 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 1300 __ cmpb(Address(EAX, Isolate::single_step_offset()), Immediate(0)); |
1301 __ cmpl(EAX, Immediate(0)); | |
1302 __ j(NOT_EQUAL, &stepping); | 1301 __ j(NOT_EQUAL, &stepping); |
1303 __ Bind(&done_stepping); | 1302 __ Bind(&done_stepping); |
1304 } | 1303 } |
1305 | 1304 |
1306 // ECX: IC data object (preserved). | 1305 // ECX: IC data object (preserved). |
1307 // Load arguments descriptor into EDX. | 1306 // Load arguments descriptor into EDX. |
1308 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); | 1307 __ movl(EDX, FieldAddress(ECX, ICData::arguments_descriptor_offset())); |
1309 // Loop that checks if there is an IC data match. | 1308 // Loop that checks if there is an IC data match. |
1310 Label loop, update, test, found; | 1309 Label loop, update, test, found; |
1311 // ECX: IC data object (preserved). | 1310 // ECX: IC data object (preserved). |
1312 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); | 1311 __ movl(EBX, FieldAddress(ECX, ICData::ic_data_offset())); |
1313 // EBX: ic_data_array with check entries: classes and target functions. | 1312 // EBX: ic_data_array with check entries: classes and target functions. |
1314 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); | 1313 __ leal(EBX, FieldAddress(EBX, Array::data_offset())); |
1315 // EBX: points directly to the first ic data array element. | 1314 // EBX: points directly to the first ic data array element. |
1316 | 1315 |
1317 // Get the receiver's class ID (first read number of arguments from | 1316 // Get the receiver's class ID (first read number of arguments from |
1318 // arguments descriptor array and then access the receiver from the stack). | 1317 // arguments descriptor array and then access the receiver from the stack). |
1319 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 1318 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
1320 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is smi. | 1319 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); // EAX (argument_count) is smi. |
1321 __ LoadTaggedClassIdMayBeSmi(EAX, EAX, EDI); | 1320 __ LoadTaggedClassIdMayBeSmi(EAX, EDI); |
1322 | 1321 |
1323 // EAX: receiver's class ID (smi). | 1322 // EAX: receiver's class ID (smi). |
1324 __ movl(EDI, Address(EBX, 0)); // First class id (smi) to check. | 1323 __ movl(EDI, Address(EBX, 0)); // First class id (smi) to check. |
1325 __ jmp(&test); | 1324 __ jmp(&test); |
1326 | 1325 |
1327 __ Bind(&loop); | 1326 __ Bind(&loop); |
1328 for (int i = 0; i < num_args; i++) { | 1327 for (int i = 0; i < num_args; i++) { |
1329 if (i > 0) { | 1328 if (i > 0) { |
1330 // If not the first, load the next argument's class ID. | 1329 // If not the first, load the next argument's class ID. |
1331 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 1330 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
1332 __ movl(EAX, Address(ESP, EAX, TIMES_2, - i * kWordSize)); | 1331 __ movl(EDI, Address(ESP, EAX, TIMES_2, - i * kWordSize)); |
1333 __ LoadTaggedClassIdMayBeSmi(EAX, EAX, EDI); | 1332 __ LoadTaggedClassIdMayBeSmi(EAX, EDI); |
1334 | 1333 |
1335 // EAX: next argument class ID (smi). | 1334 // EAX: next argument class ID (smi). |
1336 __ movl(EDI, Address(EBX, i * kWordSize)); | 1335 __ movl(EDI, Address(EBX, i * kWordSize)); |
1337 // EDI: next class ID to check (smi). | 1336 // EDI: next class ID to check (smi). |
1338 } | 1337 } |
1339 __ cmpl(EAX, EDI); // Class id match? | 1338 __ cmpl(EAX, EDI); // Class id match? |
1340 if (i < (num_args - 1)) { | 1339 if (i < (num_args - 1)) { |
1341 __ j(NOT_EQUAL, &update); // Continue. | 1340 __ j(NOT_EQUAL, &update); // Continue. |
1342 } else { | 1341 } else { |
1343 // Last check, all checks before matched. | 1342 // Last check, all checks before matched. |
1344 __ j(EQUAL, &found, Assembler::kNearJump); // Break. | 1343 __ j(EQUAL, &found, Assembler::kNearJump); // Break. |
1345 } | 1344 } |
1346 } | 1345 } |
1347 __ Bind(&update); | 1346 __ Bind(&update); |
1348 // Reload receiver class ID. It has not been destroyed when num_args == 1. | 1347 // Reload receiver class ID. It has not been destroyed when num_args == 1. |
1349 if (num_args > 1) { | 1348 if (num_args > 1) { |
1350 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); | 1349 __ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset())); |
1351 __ movl(EAX, Address(ESP, EAX, TIMES_2, 0)); | 1350 __ movl(EDI, Address(ESP, EAX, TIMES_2, 0)); |
1352 __ LoadTaggedClassIdMayBeSmi(EAX, EAX, EDI); | 1351 __ LoadTaggedClassIdMayBeSmi(EAX, EDI); |
1353 } | 1352 } |
1354 | 1353 |
1355 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; | 1354 const intptr_t entry_size = ICData::TestEntryLengthFor(num_args) * kWordSize; |
1356 __ addl(EBX, Immediate(entry_size)); // Next entry. | 1355 __ addl(EBX, Immediate(entry_size)); // Next entry. |
1357 __ movl(EDI, Address(EBX, 0)); // Next class ID. | 1356 __ movl(EDI, Address(EBX, 0)); // Next class ID. |
1358 | 1357 |
1359 __ Bind(&test); | 1358 __ Bind(&test); |
1360 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done? | 1359 __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid))); // Done? |
1361 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1360 __ j(NOT_EQUAL, &loop, Assembler::kNearJump); |
1362 | 1361 |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1941 const Register temp = ECX; | 1940 const Register temp = ECX; |
1942 __ movl(left, Address(ESP, 2 * kWordSize)); | 1941 __ movl(left, Address(ESP, 2 * kWordSize)); |
1943 __ movl(right, Address(ESP, 1 * kWordSize)); | 1942 __ movl(right, Address(ESP, 1 * kWordSize)); |
1944 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1943 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1945 __ ret(); | 1944 __ ret(); |
1946 } | 1945 } |
1947 | 1946 |
1948 } // namespace dart | 1947 } // namespace dart |
1949 | 1948 |
1950 #endif // defined TARGET_ARCH_IA32 | 1949 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |