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