| 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 |