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_MIPS) | 6 #if defined(TARGET_ARCH_MIPS) |
7 | 7 |
8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
9 #include "vm/code_generator.h" | 9 #include "vm/code_generator.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 1373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1384 } | 1384 } |
1385 | 1385 |
1386 | 1386 |
1387 // Loads function into 'temp_reg'. | 1387 // Loads function into 'temp_reg'. |
1388 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, | 1388 void StubCode::GenerateUsageCounterIncrement(Assembler* assembler, |
1389 Register temp_reg) { | 1389 Register temp_reg) { |
1390 __ TraceSimMsg("UsageCounterIncrement"); | 1390 __ TraceSimMsg("UsageCounterIncrement"); |
1391 Register ic_reg = S5; | 1391 Register ic_reg = S5; |
1392 Register func_reg = temp_reg; | 1392 Register func_reg = temp_reg; |
1393 ASSERT(temp_reg == T0); | 1393 ASSERT(temp_reg == T0); |
1394 __ lw(func_reg, FieldAddress(ic_reg, ICData::function_offset())); | 1394 __ lw(func_reg, FieldAddress(ic_reg, ICData::owner_offset())); |
1395 __ lw(T1, FieldAddress(func_reg, Function::usage_counter_offset())); | 1395 __ lw(T1, FieldAddress(func_reg, Function::usage_counter_offset())); |
1396 __ addiu(T1, T1, Immediate(1)); | 1396 __ addiu(T1, T1, Immediate(1)); |
1397 __ sw(T1, FieldAddress(func_reg, Function::usage_counter_offset())); | 1397 __ sw(T1, FieldAddress(func_reg, Function::usage_counter_offset())); |
1398 } | 1398 } |
1399 | 1399 |
1400 | 1400 |
1401 // Generate inline cache check for 'num_args'. | 1401 // Generate inline cache check for 'num_args'. |
1402 // RA: return address | 1402 // RA: return address |
1403 // S5: Inline cache data object. | 1403 // S5: Inline cache data object. |
1404 // Control flow: | 1404 // Control flow: |
1405 // - If receiver is null -> jump to IC miss. | 1405 // - If receiver is null -> jump to IC miss. |
1406 // - If receiver is Smi -> load Smi class. | 1406 // - If receiver is Smi -> load Smi class. |
1407 // - If receiver is not-Smi -> load receiver's class. | 1407 // - If receiver is not-Smi -> load receiver's class. |
1408 // - Check if 'num_args' (including receiver) match any IC data group. | 1408 // - Check if 'num_args' (including receiver) match any IC data group. |
1409 // - Match found -> jump to target. | 1409 // - Match found -> jump to target. |
1410 // - Match not found -> jump to IC miss. | 1410 // - Match not found -> jump to IC miss. |
1411 void StubCode::GenerateNArgsCheckInlineCacheStub( | 1411 void StubCode::GenerateNArgsCheckInlineCacheStub( |
1412 Assembler* assembler, | 1412 Assembler* assembler, |
1413 intptr_t num_args, | 1413 intptr_t num_args, |
1414 const RuntimeEntry& handle_ic_miss) { | 1414 const RuntimeEntry& handle_ic_miss) { |
1415 __ TraceSimMsg("NArgsCheckInlineCacheStub"); | 1415 __ TraceSimMsg("NArgsCheckInlineCacheStub"); |
1416 ASSERT(num_args > 0); | 1416 ASSERT(num_args > 0); |
1417 #if defined(DEBUG) | 1417 #if defined(DEBUG) |
1418 { Label ok; | 1418 { Label ok; |
1419 // Check that the IC data array has NumberOfArgumentsChecked() == num_args. | 1419 // Check that the IC data array has NumArgsTested() == num_args. |
1420 // 'num_args_tested' is stored as an untagged int. | 1420 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
1421 __ lw(T0, FieldAddress(S5, ICData::num_args_tested_offset())); | 1421 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset())); |
| 1422 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1423 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); |
1422 __ BranchEqual(T0, num_args, &ok); | 1424 __ BranchEqual(T0, num_args, &ok); |
1423 __ Stop("Incorrect stub for IC data"); | 1425 __ Stop("Incorrect stub for IC data"); |
1424 __ Bind(&ok); | 1426 __ Bind(&ok); |
1425 } | 1427 } |
1426 #endif // DEBUG | 1428 #endif // DEBUG |
1427 | 1429 |
1428 | 1430 |
1429 // Check single stepping. | 1431 // Check single stepping. |
1430 Label not_stepping; | 1432 Label not_stepping; |
1431 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 1433 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1661 | 1663 |
1662 | 1664 |
1663 // Intermediary stub between a static call and its target. ICData contains | 1665 // Intermediary stub between a static call and its target. ICData contains |
1664 // the target function and the call count. | 1666 // the target function and the call count. |
1665 // S5: ICData | 1667 // S5: ICData |
1666 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { | 1668 void StubCode::GenerateZeroArgsUnoptimizedStaticCallStub(Assembler* assembler) { |
1667 GenerateUsageCounterIncrement(assembler, T0); | 1669 GenerateUsageCounterIncrement(assembler, T0); |
1668 __ TraceSimMsg("UnoptimizedStaticCallStub"); | 1670 __ TraceSimMsg("UnoptimizedStaticCallStub"); |
1669 #if defined(DEBUG) | 1671 #if defined(DEBUG) |
1670 { Label ok; | 1672 { Label ok; |
1671 // Check that the IC data array has NumberOfArgumentsChecked() == 0. | 1673 // Check that the IC data array has NumArgsTested() == 0. |
1672 // 'num_args_tested' is stored as an untagged int. | 1674 // 'NumArgsTested' is stored in the least significant bits of 'state_bits'. |
1673 __ lw(T0, FieldAddress(S5, ICData::num_args_tested_offset())); | 1675 __ lw(T0, FieldAddress(S5, ICData::state_bits_offset())); |
| 1676 ASSERT(ICData::NumArgsTestedShift() == 0); // No shift needed. |
| 1677 __ andi(T0, T0, Immediate(ICData::NumArgsTestedMask())); |
1674 __ beq(T0, ZR, &ok); | 1678 __ beq(T0, ZR, &ok); |
1675 __ Stop("Incorrect IC data for unoptimized static call"); | 1679 __ Stop("Incorrect IC data for unoptimized static call"); |
1676 __ Bind(&ok); | 1680 __ Bind(&ok); |
1677 } | 1681 } |
1678 #endif // DEBUG | 1682 #endif // DEBUG |
1679 | 1683 |
1680 // Check single stepping. | 1684 // Check single stepping. |
1681 Label not_stepping; | 1685 Label not_stepping; |
1682 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); | 1686 __ lw(T0, FieldAddress(CTX, Context::isolate_offset())); |
1683 __ lbu(T0, Address(T0, Isolate::single_step_offset())); | 1687 __ lbu(T0, Address(T0, Isolate::single_step_offset())); |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2097 const Register right = T0; | 2101 const Register right = T0; |
2098 __ lw(left, Address(SP, 1 * kWordSize)); | 2102 __ lw(left, Address(SP, 1 * kWordSize)); |
2099 __ lw(right, Address(SP, 0 * kWordSize)); | 2103 __ lw(right, Address(SP, 0 * kWordSize)); |
2100 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); | 2104 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp1, temp2); |
2101 __ Ret(); | 2105 __ Ret(); |
2102 } | 2106 } |
2103 | 2107 |
2104 } // namespace dart | 2108 } // namespace dart |
2105 | 2109 |
2106 #endif // defined TARGET_ARCH_MIPS | 2110 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |