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

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

Issue 1295823003: VM: Cache instructions entry point in RawFunction/RawCode. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « runtime/vm/raw_object.h ('k') | runtime/vm/stub_code_arm64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/cpu.h" 10 #include "vm/cpu.h"
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 __ EnterStubFrame(); 304 __ EnterStubFrame();
305 // Setup space on stack for return value and preserve arguments descriptor. 305 // Setup space on stack for return value and preserve arguments descriptor.
306 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 306 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
307 __ PushList((1 << R0) | (1 << R4)); 307 __ PushList((1 << R0) | (1 << R4));
308 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0); 308 __ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
309 // Get Code object result and restore arguments descriptor array. 309 // Get Code object result and restore arguments descriptor array.
310 __ PopList((1 << R0) | (1 << R4)); 310 __ PopList((1 << R0) | (1 << R4));
311 // Remove the stub frame. 311 // Remove the stub frame.
312 __ LeaveStubFrame(); 312 __ LeaveStubFrame();
313 // Jump to the dart function. 313 // Jump to the dart function.
314 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); 314 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset()));
315 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag);
316 __ bx(R0); 315 __ bx(R0);
317 } 316 }
318 317
319 318
320 // Called from a static call only when an invalid code has been entered 319 // Called from a static call only when an invalid code has been entered
321 // (invalid because its function was optimized or deoptimized). 320 // (invalid because its function was optimized or deoptimized).
322 // R4: arguments descriptor array. 321 // R4: arguments descriptor array.
323 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) { 322 void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
324 // Create a stub frame as we are pushing some objects on the stack before 323 // Create a stub frame as we are pushing some objects on the stack before
325 // calling into the runtime. 324 // calling into the runtime.
326 __ EnterStubFrame(); 325 __ EnterStubFrame();
327 // Setup space on stack for return value and preserve arguments descriptor. 326 // Setup space on stack for return value and preserve arguments descriptor.
328 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 327 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
329 __ PushList((1 << R0) | (1 << R4)); 328 __ PushList((1 << R0) | (1 << R4));
330 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0); 329 __ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
331 // Get Code object result and restore arguments descriptor array. 330 // Get Code object result and restore arguments descriptor array.
332 __ PopList((1 << R0) | (1 << R4)); 331 __ PopList((1 << R0) | (1 << R4));
333 // Remove the stub frame. 332 // Remove the stub frame.
334 __ LeaveStubFrame(); 333 __ LeaveStubFrame();
335 // Jump to the dart function. 334 // Jump to the dart function.
336 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); 335 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset()));
337 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag);
338 __ bx(R0); 336 __ bx(R0);
339 } 337 }
340 338
341 339
342 // Called from object allocate instruction when the allocation stub has been 340 // Called from object allocate instruction when the allocation stub has been
343 // disabled. 341 // disabled.
344 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) { 342 void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) {
345 __ EnterStubFrame(); 343 __ EnterStubFrame();
346 // Setup space on stack for return value. 344 // Setup space on stack for return value.
347 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 345 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
348 __ Push(R0); 346 __ Push(R0);
349 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0); 347 __ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
350 // Get Code object result. 348 // Get Code object result.
351 __ Pop(R0); 349 __ Pop(R0);
352 // Remove the stub frame. 350 // Remove the stub frame.
353 __ LeaveStubFrame(); 351 __ LeaveStubFrame();
354 // Jump to the dart function. 352 // Jump to the dart function.
355 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); 353 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset()));
356 __ AddImmediate(R0, R0, Instructions::HeaderSize() - kHeapObjectTag);
357 __ bx(R0); 354 __ bx(R0);
358 } 355 }
359 356
360 357
361 // Input parameters: 358 // Input parameters:
362 // R2: smi-tagged argument count, may be zero. 359 // R2: smi-tagged argument count, may be zero.
363 // FP[kParamEndSlotFromFp + 1]: last argument. 360 // FP[kParamEndSlotFromFp + 1]: last argument.
364 static void PushArgumentsArray(Assembler* assembler) { 361 static void PushArgumentsArray(Assembler* assembler) {
365 // Allocate array to store arguments of caller. 362 // Allocate array to store arguments of caller.
366 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null())); 363 __ LoadImmediate(R1, reinterpret_cast<intptr_t>(Object::null()));
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 575
579 __ LeaveStubFrame(); 576 __ LeaveStubFrame();
580 577
581 if (!FLAG_lazy_dispatchers) { 578 if (!FLAG_lazy_dispatchers) {
582 Label call_target_function; 579 Label call_target_function;
583 GenerateDispatcherCode(assembler, &call_target_function); 580 GenerateDispatcherCode(assembler, &call_target_function);
584 __ Bind(&call_target_function); 581 __ Bind(&call_target_function);
585 } 582 }
586 583
587 // Tail-call to target function. 584 // Tail-call to target function.
588 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); 585 __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
589 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
590 __ bx(R2); 586 __ bx(R2);
591 } 587 }
592 588
593 589
594 // Called for inline allocation of arrays. 590 // Called for inline allocation of arrays.
595 // Input parameters: 591 // Input parameters:
596 // LR: return address. 592 // LR: return address.
597 // R1: array element type (either NULL or an instantiated type). 593 // R1: array element type (either NULL or an instantiated type).
598 // R2: array length as Smi (must be preserved). 594 // R2: array length as Smi (must be preserved).
599 // The newly allocated object is returned in R0. 595 // The newly allocated object is returned in R0.
(...skipping 863 matching lines...) Expand 10 before | Expand all | Expand 10 after
1463 __ Comment("Update caller's counter"); 1459 __ Comment("Update caller's counter");
1464 __ LoadFromOffset(kWord, R1, R6, count_offset); 1460 __ LoadFromOffset(kWord, R1, R6, count_offset);
1465 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1461 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1466 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow. 1462 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow.
1467 __ StoreIntoSmiField(Address(R6, count_offset), R1); 1463 __ StoreIntoSmiField(Address(R6, count_offset), R1);
1468 } 1464 }
1469 1465
1470 __ Comment("Call target"); 1466 __ Comment("Call target");
1471 __ Bind(&call_target_function); 1467 __ Bind(&call_target_function);
1472 // R0: target function. 1468 // R0: target function.
1473 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); 1469 __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
1474 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1475 if (range_collection_mode == kCollectRanges) { 1470 if (range_collection_mode == kCollectRanges) {
1476 __ ldr(R1, Address(SP, 0 * kWordSize)); 1471 __ ldr(R1, Address(SP, 0 * kWordSize));
1477 if (num_args == 2) { 1472 if (num_args == 2) {
1478 __ ldr(R3, Address(SP, 1 * kWordSize)); 1473 __ ldr(R3, Address(SP, 1 * kWordSize));
1479 } 1474 }
1480 __ EnterStubFrame(); 1475 __ EnterStubFrame();
1481 if (num_args == 2) { 1476 if (num_args == 2) {
1482 __ PushList((1 << R1) | (1 << R3) | (1 << R5)); 1477 __ PushList((1 << R1) | (1 << R3) | (1 << R5));
1483 } else { 1478 } else {
1484 __ PushList((1 << R1) | (1 << R5)); 1479 __ PushList((1 << R1) | (1 << R5));
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1644 __ adds(R1, R1, Operand(Smi::RawValue(1))); 1639 __ adds(R1, R1, Operand(Smi::RawValue(1)));
1645 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow. 1640 __ LoadImmediate(R1, Smi::RawValue(Smi::kMaxValue), VS); // Overflow.
1646 __ StoreIntoSmiField(Address(R6, count_offset), R1); 1641 __ StoreIntoSmiField(Address(R6, count_offset), R1);
1647 } 1642 }
1648 1643
1649 // Load arguments descriptor into R4. 1644 // Load arguments descriptor into R4.
1650 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset())); 1645 __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
1651 1646
1652 // Get function and call it, if possible. 1647 // Get function and call it, if possible.
1653 __ LoadFromOffset(kWord, R0, R6, target_offset); 1648 __ LoadFromOffset(kWord, R0, R6, target_offset);
1654 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); 1649 __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
1655
1656 // R0: function.
1657 // R2: target instructions.
1658 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1659 __ bx(R2); 1650 __ bx(R2);
1660 1651
1661 if (FLAG_support_debugger) { 1652 if (FLAG_support_debugger) {
1662 __ Bind(&stepping); 1653 __ Bind(&stepping);
1663 __ EnterStubFrame(); 1654 __ EnterStubFrame();
1664 __ Push(R5); // Preserve IC data. 1655 __ Push(R5); // Preserve IC data.
1665 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0); 1656 __ CallRuntime(kSingleStepHandlerRuntimeEntry, 0);
1666 __ Pop(R5); 1657 __ Pop(R5);
1667 __ LeaveStubFrame(); 1658 __ LeaveStubFrame();
1668 __ b(&done_stepping); 1659 __ b(&done_stepping);
(...skipping 24 matching lines...) Expand all
1693 void StubCode::GenerateLazyCompileStub(Assembler* assembler) { 1684 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
1694 // Preserve arg desc. and IC data object. 1685 // Preserve arg desc. and IC data object.
1695 __ EnterStubFrame(); 1686 __ EnterStubFrame();
1696 __ PushList((1 << R4) | (1 << R5)); 1687 __ PushList((1 << R4) | (1 << R5));
1697 __ Push(R0); // Pass function. 1688 __ Push(R0); // Pass function.
1698 __ CallRuntime(kCompileFunctionRuntimeEntry, 1); 1689 __ CallRuntime(kCompileFunctionRuntimeEntry, 1);
1699 __ Pop(R0); // Restore argument. 1690 __ Pop(R0); // Restore argument.
1700 __ PopList((1 << R4) | (1 << R5)); // Restore arg desc. and IC data. 1691 __ PopList((1 << R4) | (1 << R5)); // Restore arg desc. and IC data.
1701 __ LeaveStubFrame(); 1692 __ LeaveStubFrame();
1702 1693
1703 __ ldr(R2, FieldAddress(R0, Function::instructions_offset())); 1694 __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
1704 __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
1705 __ bx(R2); 1695 __ bx(R2);
1706 } 1696 }
1707 1697
1708 1698
1709 // R5: Contains an ICData. 1699 // R5: Contains an ICData.
1710 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) { 1700 void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
1711 __ EnterStubFrame(); 1701 __ EnterStubFrame();
1712 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null())); 1702 __ LoadImmediate(R0, reinterpret_cast<intptr_t>(Object::null()));
1713 // Preserve arguments descriptor and make room for result. 1703 // Preserve arguments descriptor and make room for result.
1714 __ PushList((1 << R0) | (1 << R5)); 1704 __ PushList((1 << R0) | (1 << R5));
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) { 1889 void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
1900 __ EnterStubFrame(); 1890 __ EnterStubFrame();
1901 __ Push(R4); 1891 __ Push(R4);
1902 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null())); 1892 __ LoadImmediate(IP, reinterpret_cast<intptr_t>(Object::null()));
1903 __ Push(IP); // Setup space on stack for return value. 1893 __ Push(IP); // Setup space on stack for return value.
1904 __ Push(R6); 1894 __ Push(R6);
1905 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1); 1895 __ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
1906 __ Pop(R0); // Discard argument. 1896 __ Pop(R0); // Discard argument.
1907 __ Pop(R0); // Get Code object 1897 __ Pop(R0); // Get Code object
1908 __ Pop(R4); // Restore argument descriptor. 1898 __ Pop(R4); // Restore argument descriptor.
1909 __ ldr(R0, FieldAddress(R0, Code::instructions_offset())); 1899 __ ldr(R0, FieldAddress(R0, Code::entry_point_offset()));
1910 __ AddImmediate(R0, Instructions::HeaderSize() - kHeapObjectTag);
1911 __ LeaveStubFrame(); 1900 __ LeaveStubFrame();
1912 __ bx(R0); 1901 __ bx(R0);
1913 __ bkpt(0); 1902 __ bkpt(0);
1914 } 1903 }
1915 1904
1916 1905
1917 // Does identical check (object references are equal or not equal) with special 1906 // Does identical check (object references are equal or not equal) with special
1918 // checks for boxed numbers. 1907 // checks for boxed numbers.
1919 // LR: return address. 1908 // LR: return address.
1920 // Return Zero condition flag set if equal. 1909 // Return Zero condition flag set if equal.
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2062 __ cmp(R4, Operand(R0)); 2051 __ cmp(R4, Operand(R0));
2063 __ b(&update, NE); 2052 __ b(&update, NE);
2064 2053
2065 __ Bind(&call_target_function); 2054 __ Bind(&call_target_function);
2066 // Call the target found in the cache. For a class id match, this is a 2055 // Call the target found in the cache. For a class id match, this is a
2067 // proper target for the given name and arguments descriptor. If the 2056 // proper target for the given name and arguments descriptor. If the
2068 // illegal class id was found, the target is a cache miss handler that can 2057 // illegal class id was found, the target is a cache miss handler that can
2069 // be invoked as a normal Dart function. 2058 // be invoked as a normal Dart function.
2070 __ add(IP, R2, Operand(R3, LSL, 2)); 2059 __ add(IP, R2, Operand(R3, LSL, 2));
2071 __ ldr(R0, FieldAddress(IP, base + kWordSize)); 2060 __ ldr(R0, FieldAddress(IP, base + kWordSize));
2072 __ ldr(target, FieldAddress(R0, Function::instructions_offset())); 2061 __ ldr(target, FieldAddress(R0, Function::entry_point_offset()));
2073 // TODO(srdjan): Evaluate performance impact of moving the instruction below
2074 // to the call site, instead of having it here.
2075 __ AddImmediate(target, Instructions::HeaderSize() - kHeapObjectTag);
2076 } 2062 }
2077 2063
2078 2064
2079 // Called from megamorphic calls. 2065 // Called from megamorphic calls.
2080 // R0: receiver. 2066 // R0: receiver.
2081 // R1: lookup cache. 2067 // R1: lookup cache.
2082 // Result: 2068 // Result:
2083 // R1: entry point. 2069 // R1: entry point.
2084 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) { 2070 void StubCode::GenerateMegamorphicLookupStub(Assembler* assembler) {
2085 EmitMegamorphicLookup(assembler, R0, R1, R1); 2071 EmitMegamorphicLookup(assembler, R0, R1, R1);
2086 __ Ret(); 2072 __ Ret();
2087 } 2073 }
2088 2074
2089 } // namespace dart 2075 } // namespace dart
2090 2076
2091 #endif // defined TARGET_ARCH_ARM 2077 #endif // defined TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « runtime/vm/raw_object.h ('k') | runtime/vm/stub_code_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698