RCTProfileTrampoline-arm64.S 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. */
  7. #include "RCTDefines.h"
  8. #include "RCTMacros.h"
  9. #if RCT_PROFILE && defined(__arm64__)
  10. .align 5
  11. .globl SYMBOL_NAME(RCTProfileTrampoline)
  12. SYMBOL_NAME(RCTProfileTrampoline):
  13. /**
  14. * The explanation here is shorter, refer to the x86_64 implementation to a
  15. * richer explanation
  16. */
  17. // Basic prolog: save the frame pointer and the link register (caller address)
  18. stp fp, lr, [sp, #-16]!
  19. mov fp, sp
  20. /**
  21. * Store the value of all the parameter registers (x0-x8, q0-q7) so we can
  22. * restore everything to the initial state at the time of the actual function
  23. * call
  24. */
  25. sub sp, sp, #(10*8 + 8*16)
  26. stp q0, q1, [sp, #(0*16)]
  27. stp q2, q3, [sp, #(2*16)]
  28. stp q4, q5, [sp, #(4*16)]
  29. stp q6, q7, [sp, #(6*16)]
  30. stp x0, x1, [sp, #(8*16+0*8)]
  31. stp x2, x3, [sp, #(8*16+2*8)]
  32. stp x4, x5, [sp, #(8*16+4*8)]
  33. stp x6, x7, [sp, #(8*16+6*8)]
  34. str x8, [sp, #(8*16+8*8)]
  35. /**
  36. * Allocate 16-bytes for the values that have to be preserved across the call
  37. * to the actual function, since the stack has to be in the exact initial
  38. * state. During its lifetimewe use it to store the initial value of the
  39. * callee saved registers we use to point the memory, the actual address of
  40. * the implementation and the caller address.
  41. */
  42. mov x0, #0x10
  43. bl SYMBOL_NAME(RCTProfileMalloc)
  44. // store the initial value of r19, the callee saved register we'll use
  45. str x19, [x0]
  46. mov x19, x0
  47. /**
  48. * void RCTProfileGetImplementation(id object, SEL selector)
  49. *
  50. * Load the 2 first arguments from the stack, they are the same used to call
  51. * this function
  52. */
  53. ldp x0, x1, [sp, #(8*16+0*8)]
  54. bl SYMBOL_NAME(RCTProfileGetImplementation)
  55. str x0, [x19, #0x8] // store the actual function address
  56. /**
  57. * void RCTProfileTrampolineStart(id, SEL) in RCTProfile.m
  58. *
  59. * start the profile, it takes the same first 2 arguments as above.
  60. */
  61. ldp x0, x1, [sp, #(8*16+0*8)]
  62. bl SYMBOL_NAME(RCTProfileTrampolineStart)
  63. // Restore all the parameter registers to the initial state.
  64. ldp q0, q1, [sp, #(0*16)]
  65. ldp q2, q3, [sp, #(2*16)]
  66. ldp q4, q5, [sp, #(4*16)]
  67. ldp q6, q7, [sp, #(6*16)]
  68. ldp x0, x1, [sp, #(8*16+0*8)]
  69. ldp x2, x3, [sp, #(8*16+2*8)]
  70. ldp x4, x5, [sp, #(8*16+4*8)]
  71. ldp x6, x7, [sp, #(8*16+6*8)]
  72. ldr x8, [sp, #(8*16+8*8)]
  73. // Restore the stack pointer, frame pointer and link register
  74. mov sp, fp
  75. ldp fp, lr, [sp], #16
  76. ldr x9, [x19, #0x8] // Load the function
  77. str lr, [x19, #0x8] // store the address of the caller
  78. blr x9 // call the actual function
  79. /**
  80. * allocate 32-bytes on the stack, for the 2 return values + the caller
  81. * address that has to preserved across the call to `free`
  82. */
  83. sub sp, sp, #0x20
  84. str q0, [sp, #0x0] // 16-byte return value
  85. str x0, [sp, #0x10] // 8-byte return value
  86. // void RCTProfileTrampolineEnd(void) in RCTProfile.m - just ends this profile
  87. bl SYMBOL_NAME(RCTProfileTrampolineEnd)
  88. /**
  89. * restore the callee saved registers, move the values we still need to the
  90. * stack and free the allocated memory
  91. */
  92. mov x0, x19 // move the address of the memory to x0, first argument
  93. ldr x10, [x19, #0x8] // load the caller address
  94. ldr x19, [x19] // restore x19
  95. str x10, [sp, #0x18] // store x10 on the stack space allocated above
  96. bl SYMBOL_NAME(RCTProfileFree)
  97. // Load both return values and link register from the stack
  98. ldr q0, [sp, #0x0]
  99. ldr x0, [sp, #0x10]
  100. ldr lr, [sp, #0x18]
  101. // restore the stack pointer
  102. add sp, sp, #0x20
  103. // jump to the calleer, without a link
  104. br lr
  105. #endif