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 1255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1266 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); | 1266 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); |
1267 } | 1267 } |
1268 | 1268 |
1269 | 1269 |
1270 // Loads function into 'temp_reg'. | 1270 // Loads function into 'temp_reg'. |
1271 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, | 1271 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, |
1272 Register temp_reg) { | 1272 Register temp_reg) { |
1273 Register ic_reg = ECX; | 1273 Register ic_reg = ECX; |
1274 Register func_reg = temp_reg; | 1274 Register func_reg = temp_reg; |
1275 ASSERT(ic_reg != func_reg); | 1275 ASSERT(ic_reg != func_reg); |
1276 __ movl(func_reg, FieldAddress(ic_reg, ICData::function_offset())); | 1276 __ movl(func_reg, FieldAddress(ic_reg, ICData::owner_offset())); |
1277 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); | 1277 __ incl(FieldAddress(func_reg, Function::usage_counter_offset())); |
1278 } | 1278 } |
1279 | 1279 |
1280 | 1280 |
1281 // Generate inline cache check for 'num_args'. | 1281 // Generate inline cache check for 'num_args'. |
1282 // ECX: Inline cache data object. | 1282 // ECX: Inline cache data object. |
1283 // TOS(0): return address | 1283 // TOS(0): return address |
1284 // Control flow: | 1284 // Control flow: |
1285 // - If receiver is null -> jump to IC miss. | 1285 // - If receiver is null -> jump to IC miss. |
1286 // - If receiver is Smi -> load Smi class. | 1286 // - If receiver is Smi -> load Smi class. |
1287 // - If receiver is not-Smi -> load receiver's class. | 1287 // - If receiver is not-Smi -> load receiver's class. |
1288 // - Check if 'num_args' (including receiver) match any IC data group. | 1288 // - Check if 'num_args' (including receiver) match any IC data group. |
1289 // - Match found -> jump to target. | 1289 // - Match found -> jump to target. |
1290 // - Match not found -> jump to IC miss. | 1290 // - Match not found -> jump to IC miss. |
1291 void StubCode::GenerateNArgsCheckInlineCacheStub( | 1291 void StubCode::GenerateNArgsCheckInlineCacheStub( |
1292 Assembler* assembler, | 1292 Assembler* assembler, |
1293 intptr_t num_args, | 1293 intptr_t num_args, |
1294 const RuntimeEntry& handle_ic_miss) { | 1294 const RuntimeEntry& handle_ic_miss) { |
1295 ASSERT(num_args > 0); | 1295 ASSERT(num_args > 0); |
1296 #if defined(DEBUG) | 1296 #if defined(DEBUG) |
1297 { Label ok; | 1297 { Label ok; |
1298 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. | 1298 // Check that the IC data array has NumArgsTested() == num_args. |
1299 // 'num_args_tested' is stored as an untagged int. | 1299 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
1300 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); | 1300 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset())); |
| 1301 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1302 __ andl(EBX, Immediate(ICData::NumArgsTestedMask())); |
1301 __ cmpl(EBX, Immediate(num_args)); | 1303 __ cmpl(EBX, Immediate(num_args)); |
1302 __ j(EQUAL, &ok, Assembler::kNearJump); | 1304 __ j(EQUAL, &ok, Assembler::kNearJump); |
1303 __ Stop("Incorrect stub for IC data"); | 1305 __ Stop("Incorrect stub for IC data"); |
1304 __ Bind(&ok); | 1306 __ Bind(&ok); |
1305 } | 1307 } |
1306 #endif // DEBUG | 1308 #endif // DEBUG |
1307 | 1309 |
1308 // Check single stepping. | 1310 // Check single stepping. |
1309 Label not_stepping; | 1311 Label not_stepping; |
1310 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1312 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1519 } | 1521 } |
1520 | 1522 |
1521 // Intermediary stub between a static call and its target. ICData contains | 1523 // Intermediary stub between a static call and its target. ICData contains |
1522 // the target function and the call count. | 1524 // the target function and the call count. |
1523 // ECX: ICData | 1525 // ECX: ICData |
1524 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1526 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
1525 GenerateUsageCounterIncrement(assembler, EBX); | 1527 GenerateUsageCounterIncrement(assembler, EBX); |
1526 | 1528 |
1527 #if defined(DEBUG) | 1529 #if defined(DEBUG) |
1528 { Label ok; | 1530 { Label ok; |
1529 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. | 1531 // Check that the IC data array has NumArgsTested() == num_args. |
1530 // 'num_args_tested' is stored as an untagged int. | 1532 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
1531 __ movl(EBX, FieldAddress(ECX, ICData::num_args_tested_offset())); | 1533 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset())); |
| 1534 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1535 __ andl(EBX, Immediate(ICData::NumArgsTestedMask())); |
1532 __ cmpl(EBX, Immediate(0)); | 1536 __ cmpl(EBX, Immediate(0)); |
1533 __ j(EQUAL, &ok, Assembler::kNearJump); | 1537 __ j(EQUAL, &ok, Assembler::kNearJump); |
1534 __ Stop("Incorrect IC data for unoptimized static call"); | 1538 __ Stop("Incorrect IC data for unoptimized static call"); |
1535 __ Bind(&ok); | 1539 __ Bind(&ok); |
1536 } | 1540 } |
1537 #endif // DEBUG | 1541 #endif // DEBUG |
1538 // Check single stepping. | 1542 // Check single stepping. |
1539 Label not_stepping; | 1543 Label not_stepping; |
1540 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); | 1544 __ movl(EAX, FieldAddress(CTX, Context::isolate_offset())); |
1541 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); | 1545 __ movzxb(EAX, Address(EAX, Isolate::single_step_offset())); |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1916 const Register temp = ECX; | 1920 const Register temp = ECX; |
1917 __ movl(left, Address(ESP, 2 * kWordSize)); | 1921 __ movl(left, Address(ESP, 2 * kWordSize)); |
1918 __ movl(right, Address(ESP, 1 * kWordSize)); | 1922 __ movl(right, Address(ESP, 1 * kWordSize)); |
1919 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1923 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1920 __ ret(); | 1924 __ ret(); |
1921 } | 1925 } |
1922 | 1926 |
1923 } // namespace dart | 1927 } // namespace dart |
1924 | 1928 |
1925 #endif // defined TARGET_ARCH_IA32 | 1929 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |