mirror of
https://github.com/status-im/react-native.git
synced 2025-01-10 09:35:48 +00:00
0f92639a96
Summary: public I was using `dlsym` as a more elegant way of checking if the function was defined to prevent crashes if running on an unsupported architecture, but Xcode might strip the symbol, even with `.no_dead_strip`, if there's no references to the compilation unit at all. Replace it with an ugly `#if` that checks if it's any of the supported targets and extern the function prototype. Reviewed By: jspahrsummers Differential Revision: D2581143 fb-gh-sync-id: b004ed351de97f96c04b4a6c914ce55cfcbbbcbb
91 lines
2.8 KiB
ArmAsm
91 lines
2.8 KiB
ArmAsm
#include "RCTDefines.h"
|
|
#include "RCTMacros.h"
|
|
|
|
#if RCT_DEV && 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(malloc)
|
|
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(free)
|
|
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
|