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_ARM) | 6 #if defined(TARGET_ARCH_ARM) |
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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 __ Bind(&loop); | 430 __ Bind(&loop); |
431 __ subs(R2, R2, ShifterOperand(Smi::RawValue(1))); // R2 is Smi. | 431 __ subs(R2, R2, ShifterOperand(Smi::RawValue(1))); // R2 is Smi. |
432 __ ldr(IP, Address(R1, 0), PL); | 432 __ ldr(IP, Address(R1, 0), PL); |
433 __ str(IP, Address(R3, 0), PL); | 433 __ str(IP, Address(R3, 0), PL); |
434 __ AddImmediate(R1, -kWordSize, PL); | 434 __ AddImmediate(R1, -kWordSize, PL); |
435 __ AddImmediate(R3, kWordSize, PL); | 435 __ AddImmediate(R3, kWordSize, PL); |
436 __ b(&loop, PL); | 436 __ b(&loop, PL); |
437 } | 437 } |
438 | 438 |
439 | 439 |
440 // Input parameters: | |
441 // R5: ic-data. | |
442 // R4: arguments descriptor array. | |
443 // Note: The receiver object is the first argument to the function being | |
444 // called, the stub accesses the receiver from this location directly | |
445 // when trying to resolve the call. | |
446 void StubCode::GenerateInstanceFunctionLookupStub(Assembler* assembler) { | |
447 __ EnterStubFrame(); | |
448 | |
449 // Load the receiver. | |
450 __ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset())); | |
451 __ add(IP, FP, ShifterOperand(R2, LSL, 1)); // R2 is Smi. | |
452 __ ldr(R6, Address(IP, kParamEndSlotFromFp * kWordSize)); | |
453 | |
454 // Push space for the return value. | |
455 // Push the receiver. | |
456 // Push IC data object. | |
457 // Push arguments descriptor array. | |
458 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | |
459 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); | |
460 | |
461 // R2: Smi-tagged arguments array length. | |
462 PushArgumentsArray(assembler); | |
463 | |
464 __ CallRuntime(kInstanceFunctionLookupRuntimeEntry, 4); | |
465 | |
466 // Remove arguments. | |
467 __ Drop(4); | |
468 __ Pop(R0); // Get result into R0. | |
469 __ LeaveStubFrame(); | |
470 __ Ret(); | |
471 } | |
472 | |
473 | |
474 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, | 440 DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptimizeCopyFrame, |
475 intptr_t deopt_reason, | 441 intptr_t deopt_reason, |
476 uword saved_registers_address); | 442 uword saved_registers_address); |
477 | 443 |
478 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); | 444 DECLARE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, uword last_fp); |
479 | 445 |
480 | 446 |
481 // Used by eager and lazy deoptimization. Preserve result in R0 if necessary. | 447 // Used by eager and lazy deoptimization. Preserve result in R0 if necessary. |
482 // This stub translates optimized frame into unoptimized frame. The optimized | 448 // This stub translates optimized frame into unoptimized frame. The optimized |
483 // frame can contain values in registers and on stack, the unoptimized | 449 // frame can contain values in registers and on stack, the unoptimized |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 | 574 |
609 // Push space for the return value. | 575 // Push space for the return value. |
610 // Push the receiver. | 576 // Push the receiver. |
611 // Push IC data object. | 577 // Push IC data object. |
612 // Push arguments descriptor array. | 578 // Push arguments descriptor array. |
613 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); | 579 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); |
614 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); | 580 __ PushList((1 << R4) | (1 << R5) | (1 << R6) | (1 << IP)); |
615 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); | 581 __ CallRuntime(kMegamorphicCacheMissHandlerRuntimeEntry, 3); |
616 // Remove arguments. | 582 // Remove arguments. |
617 __ Drop(3); | 583 __ Drop(3); |
618 __ Pop(R0); // Get result into R0. | 584 __ Pop(R0); // Get result into R0 (target function). |
619 | 585 |
620 // Restore IC data and arguments descriptor. | 586 // Restore IC data and arguments descriptor. |
621 __ PopList((1 << R4) | (1 << R5)); | 587 __ PopList((1 << R4) | (1 << R5)); |
622 | 588 |
623 __ LeaveStubFrame(); | 589 __ LeaveStubFrame(); |
624 | 590 |
625 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 591 // Tail-call to target function. |
626 __ Branch(&StubCode::InstanceFunctionLookupLabel(), EQ); | 592 __ ldr(R2, FieldAddress(R0, Function::code_offset())); |
627 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag); | 593 __ ldr(R2, FieldAddress(R2, Code::instructions_offset())); |
628 __ bx(R0); | 594 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag); |
| 595 __ bx(R2); |
629 } | 596 } |
630 | 597 |
631 | 598 |
632 // Called for inline allocation of arrays. | 599 // Called for inline allocation of arrays. |
633 // Input parameters: | 600 // Input parameters: |
634 // LR: return address. | 601 // LR: return address. |
635 // R2: array length as Smi. | 602 // R2: array length as Smi. |
636 // R1: array element type (either NULL or an instantiated type). | 603 // R1: array element type (either NULL or an instantiated type). |
637 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. | 604 // NOTE: R2 cannot be clobbered here as the caller relies on it being saved. |
638 // The newly allocated object is returned in R0. | 605 // The newly allocated object is returned in R0. |
(...skipping 819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1458 // Push call arguments. | 1425 // Push call arguments. |
1459 for (intptr_t i = 0; i < num_args; i++) { | 1426 for (intptr_t i = 0; i < num_args; i++) { |
1460 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); | 1427 __ LoadFromOffset(kWord, IP, R7, -i * kWordSize); |
1461 __ Push(IP); | 1428 __ Push(IP); |
1462 } | 1429 } |
1463 // Pass IC data object. | 1430 // Pass IC data object. |
1464 __ Push(R5); | 1431 __ Push(R5); |
1465 __ CallRuntime(handle_ic_miss, num_args + 1); | 1432 __ CallRuntime(handle_ic_miss, num_args + 1); |
1466 // Remove the call arguments pushed earlier, including the IC data object. | 1433 // Remove the call arguments pushed earlier, including the IC data object. |
1467 __ Drop(num_args + 1); | 1434 __ Drop(num_args + 1); |
1468 // Pop returned code object into R0 (null if not found). | 1435 // Pop returned function object into R0. |
1469 // Restore arguments descriptor array and IC data array. | 1436 // Restore arguments descriptor array and IC data array. |
1470 __ PopList((1 << R0) | (1 << R4) | (1 << R5)); | 1437 __ PopList((1 << R0) | (1 << R4) | (1 << R5)); |
1471 __ LeaveStubFrame(); | 1438 __ LeaveStubFrame(); |
1472 Label call_target_function; | 1439 Label call_target_function; |
1473 __ CompareImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); | 1440 __ b(&call_target_function); |
1474 __ b(&call_target_function, NE); | |
1475 // NoSuchMethod or closure. | |
1476 // Mark IC call that it may be a closure call that does not collect | |
1477 // type feedback. | |
1478 __ mov(IP, ShifterOperand(1)); | |
1479 __ strb(IP, FieldAddress(R5, ICData::is_closure_call_offset())); | |
1480 __ Branch(&StubCode::InstanceFunctionLookupLabel()); | |
1481 | 1441 |
1482 __ Bind(&found); | 1442 __ Bind(&found); |
1483 // R6: pointer to an IC data check group. | 1443 // R6: pointer to an IC data check group. |
1484 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; | 1444 const intptr_t target_offset = ICData::TargetIndexFor(num_args) * kWordSize; |
1485 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; | 1445 const intptr_t count_offset = ICData::CountIndexFor(num_args) * kWordSize; |
1486 __ LoadFromOffset(kWord, R0, R6, target_offset); | 1446 __ LoadFromOffset(kWord, R0, R6, target_offset); |
1487 __ LoadFromOffset(kWord, R1, R6, count_offset); | 1447 __ LoadFromOffset(kWord, R1, R6, count_offset); |
1488 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1))); | 1448 __ adds(R1, R1, ShifterOperand(Smi::RawValue(1))); |
1489 __ StoreToOffset(kWord, R1, R6, count_offset); | 1449 __ StoreToOffset(kWord, R1, R6, count_offset); |
1490 __ b(&call_target_function, VC); // No overflow. | 1450 __ b(&call_target_function, VC); // No overflow. |
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1967 const Register right = R0; | 1927 const Register right = R0; |
1968 __ ldr(left, Address(SP, 1 * kWordSize)); | 1928 __ ldr(left, Address(SP, 1 * kWordSize)); |
1969 __ ldr(right, Address(SP, 0 * kWordSize)); | 1929 __ ldr(right, Address(SP, 0 * kWordSize)); |
1970 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 1930 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
1971 __ Ret(); | 1931 __ Ret(); |
1972 } | 1932 } |
1973 | 1933 |
1974 } // namespace dart | 1934 } // namespace dart |
1975 | 1935 |
1976 #endif // defined TARGET_ARCH_ARM | 1936 #endif // defined TARGET_ARCH_ARM |
OLD | NEW |