12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- /**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
- #include "RCTDefines.h"
- #include "RCTMacros.h"
- #if RCT_PROFILE && defined(__i386__)
- .globl SYMBOL_NAME(RCTProfileTrampoline)
- SYMBOL_NAME(RCTProfileTrampoline):
- /**
- * The x86 version is much simpler, since all the arguments are passed in the
- * stack, so we just have to preserve the stack pointer (%esp) and the callee
- * saved register used to keep the memory allocated
- *
- * The explanation here is also shorter, refer to the x86_64 implementation to
- * a richer explanation
- */
- /**
- * Allocate memory to save the caller of RCTProfileTrampoline (used afterwards
- * to return at the end of the function) and the initial value for the callee
- * saved register (%edi) that will be used to point to the memory allocated.
- */
- subl $0x8, %esp // stack padding (16-byte alignment for function calls)
- pushl $0xc // allocate 12-bytes
- calll SYMBOL_NAME(RCTProfileMalloc)
- addl $0xc, %esp // restore stack (8-byte padding + 4-byte argument)
- /**
- * actually store the values in the memory allocated
- */
- movl %edi, 0x0(%eax) // previous value of edi
- popl 0x4(%eax) // caller of RCTProfileTrampoline
- // save the pointer to the allocated memory in %edi
- movl %eax, %edi
- /**
- * void RCTProfileGetImplementation(id object, SEL selector) in RCTProfile.m
- *
- * Get the address of the actual C function we have to profile
- */
- calll SYMBOL_NAME(RCTProfileGetImplementation)
- movl %eax, 0x8(%edi) // Save it in the allocated memory
- /**
- * void RCTProfileTrampolineStart(id, SEL) in RCTProfile.m
- *
- * start profile - the arguments are already in the right position in the
- * stack since it takes the same first 2 arguments as the any ObjC function -
- * "self" and "_cmd"
- */
- calll SYMBOL_NAME(RCTProfileTrampolineStart)
- /**
- * Call the actual function and save it's return value, since it should be the
- * return value of RCTProfileTrampoline
- */
- calll *0x8(%edi)
- pushl %eax
- // Align stack and end profile
- subl $0xc, %esp
- calll SYMBOL_NAME(RCTProfileTrampolineEnd)
- addl $0xc, %esp // restore the stack
- /**
- * Move the values from the allocated memory to the stack, restore the
- * value of %edi, and prepare to free the allocated memory.
- */
- pushl 0x4(%edi) // caller of RCTProfileTrampoline
- subl $0x4, %esp // Stack padding
- pushl %edi // push the memory address
- movl 0x0(%edi), %edi // restore the value of %edi
- /**
- * Actually free the memory used to store the values across function calls,
- * the stack has already been padded and the first and only argument, the
- * memory address, is already in the bottom of the stack.
- */
- calll SYMBOL_NAME(RCTProfileFree)
- addl $0x8, %esp
- /**
- * pop the caller address to %ecx and the actual function return value to
- * %eax, so it's the return value of RCTProfileTrampoline
- */
- popl %ecx
- popl %eax
- jmpl *%ecx
- #endif
|