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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 | 223 |
224 // Remove the stub frame as we are about to jump to the dart function. | 224 // Remove the stub frame as we are about to jump to the dart function. |
225 __ LeaveStubFrame(); | 225 __ LeaveStubFrame(); |
226 | 226 |
227 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); | 227 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); |
228 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); | 228 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); |
229 __ jr(T0); | 229 __ jr(T0); |
230 } | 230 } |
231 | 231 |
232 | 232 |
| 233 // Called from a static call only when an invalid code has been entered |
| 234 // (invalid because its function was optimized or deoptimized). |
| 235 // S4: arguments descriptor array. |
233 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { | 236 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { |
234 __ Unimplemented("FixCallersTarget stub"); | 237 // Create a stub frame as we are pushing some objects on the stack before |
| 238 // calling into the runtime. |
| 239 __ EnterStubFrame(); |
| 240 // Setup space on stack for return value and preserve arguments descriptor. |
| 241 __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null())); |
| 242 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 243 __ sw(S4, Address(SP, 1 * kWordSize)); |
| 244 __ sw(T0, Address(SP, 0 * kWordSize)); |
| 245 __ CallRuntime(kFixCallersTargetRuntimeEntry); |
| 246 // Get Code object result and restore arguments descriptor array. |
| 247 __ lw(T0, Address(SP, 0 * kWordSize)); |
| 248 __ lw(S4, Address(SP, 1 * kWordSize)); |
| 249 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 250 // Remove the stub frame. |
| 251 __ LeaveStubFrame(); |
| 252 // Jump to the dart function. |
| 253 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); |
| 254 __ AddImmediate(T0, T0, Instructions::HeaderSize() - kHeapObjectTag); |
| 255 __ jr(T0); |
235 } | 256 } |
236 | 257 |
237 | 258 |
238 // Input parameters: | 259 // Input parameters: |
239 // A1: Smi-tagged argument count, may be zero. | 260 // A1: Smi-tagged argument count, may be zero. |
240 // FP[kLastParamSlotIndex]: Last argument. | 261 // FP[kLastParamSlotIndex]: Last argument. |
241 static void PushArgumentsArray(Assembler* assembler) { | 262 static void PushArgumentsArray(Assembler* assembler) { |
242 __ TraceSimMsg("PushArgumentsArray"); | 263 __ TraceSimMsg("PushArgumentsArray"); |
243 // Allocate array to store arguments of caller. | 264 // Allocate array to store arguments of caller. |
244 __ LoadImmediate(A0, reinterpret_cast<intptr_t>(Object::null())); | 265 __ LoadImmediate(A0, reinterpret_cast<intptr_t>(Object::null())); |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 | 592 |
572 // Load smi-tagged arguments array length, including the non-closure. | 593 // Load smi-tagged arguments array length, including the non-closure. |
573 __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); | 594 __ lw(A1, FieldAddress(S4, ArgumentsDescriptor::count_offset())); |
574 PushArgumentsArray(assembler); | 595 PushArgumentsArray(assembler); |
575 | 596 |
576 // Stack: | 597 // Stack: |
577 // TOS + 0: Argument array. | 598 // TOS + 0: Argument array. |
578 // TOS + 1: Arguments descriptor array. | 599 // TOS + 1: Arguments descriptor array. |
579 // TOS + 2: Place for result from the call. | 600 // TOS + 2: Place for result from the call. |
580 // TOS + 3: Saved FP of previous frame. | 601 // TOS + 3: Saved FP of previous frame. |
581 // TOS + 4: Dart code return address | 602 // TOS + 4: Dart code return address. |
582 // TOS + 5: PC marker (0 for stub). | 603 // TOS + 5: PC marker (0 for stub). |
583 // TOS + 6: Last argument of caller. | 604 // TOS + 6: Last argument of caller. |
584 // .... | 605 // .... |
585 __ CallRuntime(kInvokeNonClosureRuntimeEntry); | 606 __ CallRuntime(kInvokeNonClosureRuntimeEntry); |
586 __ lw(V0, Address(SP, 2 * kWordSize)); // Get result into V0. | 607 __ lw(V0, Address(SP, 2 * kWordSize)); // Get result into V0. |
587 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Remove arguments. | 608 __ addiu(SP, SP, Immediate(3 * kWordSize)); // Remove arguments. |
588 | 609 |
589 // Remove the stub frame as we are about to return. | 610 // Remove the stub frame as we are about to return. |
590 __ LeaveStubFrame(); | 611 __ LeaveStubFrame(); |
591 __ Ret(); | 612 __ Ret(); |
(...skipping 918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1510 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { | 1531 void StubCode::GenerateClosureCallInlineCacheStub(Assembler* assembler) { |
1511 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1532 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
1512 } | 1533 } |
1513 | 1534 |
1514 | 1535 |
1515 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { | 1536 void StubCode::GenerateMegamorphicCallStub(Assembler* assembler) { |
1516 GenerateNArgsCheckInlineCacheStub(assembler, 1); | 1537 GenerateNArgsCheckInlineCacheStub(assembler, 1); |
1517 } | 1538 } |
1518 | 1539 |
1519 | 1540 |
| 1541 // RA: return address (Dart code). |
| 1542 // S4: Arguments descriptor array. |
1520 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { | 1543 void StubCode::GenerateBreakpointStaticStub(Assembler* assembler) { |
1521 __ Unimplemented("BreakpointStatic stub"); | 1544 __ TraceSimMsg("BreakpointStaticStub"); |
| 1545 // Create a stub frame as we are pushing some objects on the stack before |
| 1546 // calling into the runtime. |
| 1547 __ EnterStubFrame(); |
| 1548 __ LoadImmediate(T0, reinterpret_cast<intptr_t>(Object::null())); |
| 1549 // Preserve arguments descriptor and make room for result. |
| 1550 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 1551 __ sw(S4, Address(SP, 1 * kWordSize)); |
| 1552 __ sw(T0, Address(SP, 0 * kWordSize)); |
| 1553 __ CallRuntime(kBreakpointStaticHandlerRuntimeEntry); |
| 1554 // Pop code object result and restore arguments descriptor. |
| 1555 __ lw(T0, Address(SP, 0 * kWordSize)); |
| 1556 __ lw(S4, Address(SP, 1 * kWordSize)); |
| 1557 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 1558 __ LeaveStubFrame(); |
| 1559 |
| 1560 // Now call the static function. The breakpoint handler function |
| 1561 // ensures that the call target is compiled. |
| 1562 __ lw(T0, FieldAddress(T0, Code::instructions_offset())); |
| 1563 __ AddImmediate(T0, Instructions::HeaderSize() - kHeapObjectTag); |
| 1564 __ jr(T0); |
1522 } | 1565 } |
1523 | 1566 |
1524 | 1567 |
| 1568 // V0: return value. |
1525 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { | 1569 void StubCode::GenerateBreakpointReturnStub(Assembler* assembler) { |
1526 __ Unimplemented("BreakpointReturn stub"); | 1570 __ TraceSimMsg("BreakpoingReturnStub"); |
| 1571 // Create a stub frame as we are pushing some objects on the stack before |
| 1572 // calling into the runtime. |
| 1573 __ EnterStubFrame(); |
| 1574 __ Push(V0); |
| 1575 __ CallRuntime(kBreakpointReturnHandlerRuntimeEntry); |
| 1576 __ Pop(V0); |
| 1577 __ LeaveStubFrame(); |
| 1578 |
| 1579 // Instead of returning to the patched Dart function, emulate the |
| 1580 // smashed return code pattern and return to the function's caller. |
| 1581 __ LeaveDartFrame(); |
| 1582 __ Ret(); |
1527 } | 1583 } |
1528 | 1584 |
1529 | 1585 |
| 1586 // RA: return address (Dart code). |
| 1587 // S5: Inline cache data array. |
| 1588 // S4: Arguments descriptor array. |
1530 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { | 1589 void StubCode::GenerateBreakpointDynamicStub(Assembler* assembler) { |
1531 __ Unimplemented("BreakpointDynamic stub"); | 1590 // Create a stub frame as we are pushing some objects on the stack before |
| 1591 // calling into the runtime. |
| 1592 __ EnterStubFrame(); |
| 1593 __ addiu(SP, SP, Immediate(-2 * kWordSize)); |
| 1594 __ sw(S5, Address(SP, 1 * kWordSize)); |
| 1595 __ sw(S4, Address(SP, 0 * kWordSize)); |
| 1596 __ CallRuntime(kBreakpointDynamicHandlerRuntimeEntry); |
| 1597 __ lw(S4, Address(SP, 0 * kWordSize)); |
| 1598 __ lw(S5, Address(SP, 1 * kWordSize)); |
| 1599 __ addiu(SP, SP, Immediate(2 * kWordSize)); |
| 1600 __ LeaveStubFrame(); |
| 1601 |
| 1602 // Find out which dispatch stub to call. |
| 1603 __ lw(TMP1, FieldAddress(S5, ICData::num_args_tested_offset())); |
| 1604 |
| 1605 Label one_arg, two_args, three_args; |
| 1606 __ BranchEqual(TMP1, 1, &one_arg); |
| 1607 __ BranchEqual(TMP1, 2, &two_args); |
| 1608 __ BranchEqual(TMP1, 3, &three_args); |
| 1609 __ Stop("Unsupported number of arguments tested."); |
| 1610 |
| 1611 __ Bind(&one_arg); |
| 1612 __ Branch(&StubCode::OneArgCheckInlineCacheLabel()); |
| 1613 __ Bind(&two_args); |
| 1614 __ Branch(&StubCode::TwoArgsCheckInlineCacheLabel()); |
| 1615 __ Bind(&three_args); |
| 1616 __ Branch(&StubCode::ThreeArgsCheckInlineCacheLabel()); |
| 1617 __ break_(0); |
1532 } | 1618 } |
1533 | 1619 |
1534 | 1620 |
1535 // Used to check class and type arguments. Arguments passed in registers: | 1621 // Used to check class and type arguments. Arguments passed in registers: |
1536 // RA: return address. | 1622 // RA: return address. |
1537 // A0: instance (must be preserved). | 1623 // A0: instance (must be preserved). |
1538 // A1: instantiator type arguments or NULL. | 1624 // A1: instantiator type arguments or NULL. |
1539 // A2: cache array. | 1625 // A2: cache array. |
1540 // Result in V0: null -> not found, otherwise result (true or false). | 1626 // Result in V0: null -> not found, otherwise result (true or false). |
1541 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { | 1627 static void GenerateSubtypeNTestCacheStub(Assembler* assembler, int n) { |
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1881 __ Bind(&done); | 1967 __ Bind(&done); |
1882 __ lw(T0, Address(SP, 0 * kWordSize)); | 1968 __ lw(T0, Address(SP, 0 * kWordSize)); |
1883 __ lw(T1, Address(SP, 1 * kWordSize)); | 1969 __ lw(T1, Address(SP, 1 * kWordSize)); |
1884 __ Ret(); | 1970 __ Ret(); |
1885 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); | 1971 __ delay_slot()->addiu(SP, SP, Immediate(2 * kWordSize)); |
1886 } | 1972 } |
1887 | 1973 |
1888 } // namespace dart | 1974 } // namespace dart |
1889 | 1975 |
1890 #endif // defined TARGET_ARCH_MIPS | 1976 #endif // defined TARGET_ARCH_MIPS |
OLD | NEW |