Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: runtime/vm/stub_code_arm.cc

Issue 221173011: Simplify handling of IC and megamorphic cache misses. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698