| 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 ASSERT(ICData::kNumArgsTestedBits == 0); // No shift needed. |
| 1301 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset())); |
| 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 ASSERT(ICData::kNumArgsTestedBits == 0); // No shift needed. |
| 1534 __ movl(EBX, FieldAddress(ECX, ICData::state_bits_offset())); |
| 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 |