RCTProfileTrampoline-i386.S 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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(__i386__)
  10. .globl SYMBOL_NAME(RCTProfileTrampoline)
  11. SYMBOL_NAME(RCTProfileTrampoline):
  12. /**
  13. * The x86 version is much simpler, since all the arguments are passed in the
  14. * stack, so we just have to preserve the stack pointer (%esp) and the callee
  15. * saved register used to keep the memory allocated
  16. *
  17. * The explanation here is also shorter, refer to the x86_64 implementation to
  18. * a richer explanation
  19. */
  20. /**
  21. * Allocate memory to save the caller of RCTProfileTrampoline (used afterwards
  22. * to return at the end of the function) and the initial value for the callee
  23. * saved register (%edi) that will be used to point to the memory allocated.
  24. */
  25. subl $0x8, %esp // stack padding (16-byte alignment for function calls)
  26. pushl $0xc // allocate 12-bytes
  27. calll SYMBOL_NAME(RCTProfileMalloc)
  28. addl $0xc, %esp // restore stack (8-byte padding + 4-byte argument)
  29. /**
  30. * actually store the values in the memory allocated
  31. */
  32. movl %edi, 0x0(%eax) // previous value of edi
  33. popl 0x4(%eax) // caller of RCTProfileTrampoline
  34. // save the pointer to the allocated memory in %edi
  35. movl %eax, %edi
  36. /**
  37. * void RCTProfileGetImplementation(id object, SEL selector) in RCTProfile.m
  38. *
  39. * Get the address of the actual C function we have to profile
  40. */
  41. calll SYMBOL_NAME(RCTProfileGetImplementation)
  42. movl %eax, 0x8(%edi) // Save it in the allocated memory
  43. /**
  44. * void RCTProfileTrampolineStart(id, SEL) in RCTProfile.m
  45. *
  46. * start profile - the arguments are already in the right position in the
  47. * stack since it takes the same first 2 arguments as the any ObjC function -
  48. * "self" and "_cmd"
  49. */
  50. calll SYMBOL_NAME(RCTProfileTrampolineStart)
  51. /**
  52. * Call the actual function and save it's return value, since it should be the
  53. * return value of RCTProfileTrampoline
  54. */
  55. calll *0x8(%edi)
  56. pushl %eax
  57. // Align stack and end profile
  58. subl $0xc, %esp
  59. calll SYMBOL_NAME(RCTProfileTrampolineEnd)
  60. addl $0xc, %esp // restore the stack
  61. /**
  62. * Move the values from the allocated memory to the stack, restore the
  63. * value of %edi, and prepare to free the allocated memory.
  64. */
  65. pushl 0x4(%edi) // caller of RCTProfileTrampoline
  66. subl $0x4, %esp // Stack padding
  67. pushl %edi // push the memory address
  68. movl 0x0(%edi), %edi // restore the value of %edi
  69. /**
  70. * Actually free the memory used to store the values across function calls,
  71. * the stack has already been padded and the first and only argument, the
  72. * memory address, is already in the bottom of the stack.
  73. */
  74. calll SYMBOL_NAME(RCTProfileFree)
  75. addl $0x8, %esp
  76. /**
  77. * pop the caller address to %ecx and the actual function return value to
  78. * %eax, so it's the return value of RCTProfileTrampoline
  79. */
  80. popl %ecx
  81. popl %eax
  82. jmpl *%ecx
  83. #endif