JavascriptFunctionA.S 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. .intel_syntax noprefix
  6. #include "unixasmmacros.inc"
  7. .global C_FUNC(_ZN2Js18JavascriptFunction20DeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz)
  8. .global C_FUNC(_ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz)
  9. #ifndef __APPLE__
  10. .extern _ZN2Js18JavascriptFunction13DeferredParseEPPNS_14ScriptFunctionE
  11. .extern _ZN2Js18JavascriptFunction19DeferredDeserializeEPNS_14ScriptFunctionE
  12. .type _ZN2Js18JavascriptFunction20DeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz, @function
  13. .type _ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz, @function
  14. #endif
  15. //------------------------------------------------------------------------------
  16. // Invoke
  17. //
  18. // JavascriptMethod(RecyclableObject* function, CallInfo callInfo, ...)
  19. //
  20. // with a custom calling convention in order to support JavascriptStackWalker
  21. // and RUNTIME_ARGUMENTS. JavascriptMethod entry stack layout:
  22. //
  23. // [Return Address]
  24. // [function] == RDI
  25. // [callInfo] == RSI
  26. // [arg0]
  27. // [arg1]
  28. // ...
  29. //------------------------------------------------------------------------------
  30. NESTED_ENTRY amd64_CallFunction, _TEXT, NoHandler
  31. // Var amd64_CallFunction(
  32. // RecyclableObject *function, (rdi)
  33. // JavascriptMethod entryPoint, (rsi)
  34. // CallInfo callInfo, (rdx)
  35. // uint argc, (rcx)
  36. // Var *argv); (r8)
  37. // push rbp and adjust CFA offset
  38. // CFA refers to Canonical Frame Address.
  39. // See section 6.4 of DWARF spec (http://dwarfstd.org/doc/DWARF4.pdf)
  40. push_nonvol_reg rbp
  41. mov rbp, rsp
  42. // Set to compute CFA as: rbp + 16
  43. // (16 == sizeof: [rbp] [ReturnAddress])
  44. // Since rbp remains unchanged, we don't need to adjust CFA offset
  45. // in this function.
  46. set_cfa_register rbp, (2*8)
  47. // Not using other callee-save registers: rbx/r12-r15.
  48. //
  49. // The stack is now 16 byte aligned. It was 8-byte aligned when we
  50. // came into the function, and since then we pushed 8 bytes onto
  51. // the stack.
  52. // We need to call the target function with the following:
  53. // rdi = function
  54. // rsi = CallInfo
  55. // function, callInfo, and all args on stack
  56. //
  57. // Lets store the entry point in r11 and set up its first two arguments.
  58. // Note that since rdi is already set up, it doesn't need to change.
  59. mov r11, rsi // Store entry point in r11
  60. mov rsi, rdx // Store CallInfo in rsi
  61. mov r10, rcx // Store argc in r10
  62. add r10, 3 // function, callInfo, ..., + 1 for alignment
  63. and r10, -2 // Mask off the lower bit to 16 byte align the stack
  64. shl r10, 3 // Calculate space for remaining args (* sizeof(Var*))
  65. cmp r10, 0x1000 // If the space is large, make sure the stack is committed
  66. jl LOCAL_LABEL(allocate_stack)
  67. // xplat-todo: Figure out if we need to implement __chkstk
  68. // call __chkstk
  69. LOCAL_LABEL(allocate_stack):
  70. sub rsp, r10 // Allocate the stack space
  71. mov qword ptr [rsp], rdi // function
  72. mov qword ptr [rsp + 0x8], rsi // callInfo
  73. cmp rcx, 0
  74. je LOCAL_LABEL(args_setup_done)
  75. // Copy all args (r8) to rsp[2]. rcx has argc.
  76. LOCAL_LABEL(copy_args_to_stack):
  77. lea rdi, [rsp + 0x10] // &rsp[2]
  78. mov rsi, r8 // argv
  79. rep movsq
  80. mov rdi, qword ptr [rsp] // restore rdi
  81. mov rsi, qword ptr [rsp + 0x8] // restore rsi
  82. LOCAL_LABEL(args_setup_done):
  83. xor rax, rax // Zero out rax in case r11 expects varags
  84. call r11
  85. LOCAL_LABEL(function_done):
  86. lea rsp, [rbp]
  87. pop_nonvol_reg rbp
  88. ret
  89. NESTED_END amd64_CallFunction, _TEXT
  90. //------------------------------------------------------------------------------
  91. #ifdef _ENABLE_DYNAMIC_THUNKS
  92. //extrn ?GetStackSizeForAsmJsUnboxing@Js@@YAHPEAVScriptFunction@1@@Z: PROC
  93. //extrn ?GetArgsSizesArray@Js@@YAPEAIPEAVScriptFunction@1@@Z : PROC
  94. // int CallAsmJsFunction<int>(RecyclableObject *function, JavascriptMethod entryPoint, uint argc, Var *argv);
  95. .balign 16
  96. NESTED_ENTRY _ZN2Js18JavascriptFunction17CallAsmJsFunctionIiEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh, _TEXT, NoHandler
  97. push_nonvol_reg rbp
  98. mov rbp, rsp
  99. // Set to compute CFA as: rbp + 2 words (RA, rbp)
  100. set_cfa_register rbp, (2*8)
  101. // rdi: function, rsi: entryPoint, rdx: argv, rcx: argSizes, r8: reg
  102. and rsp, -16 // Make sure the stack is 16 bytes aligned
  103. // add 16 bytes to argsSize to account for ScriptFunction and stay 16 bytes aligned
  104. add rcx, 16
  105. // Stack allocation
  106. sub rsp, rcx
  107. // Set entrypoint to r11
  108. mov r11, rsi
  109. // Make sure ScriptFunction* is first argument
  110. mov qword ptr [rdx], rdi
  111. shr rcx, 3 // rcx = rcx / 8 for qword size mov
  112. mov rsi, rdx // rsi = argv
  113. mov rdi, rsp // rdi = arguments destination
  114. rep movsq
  115. mov rdi, qword ptr [rsp]
  116. xor rax, rax // Zero out rax in case r11 expects varags
  117. call r11
  118. // done:
  119. // restore stack
  120. mov rsp, rbp
  121. pop_nonvol_reg rbp
  122. ret
  123. NESTED_END _ZN2Js18JavascriptFunction17CallAsmJsFunctionIiEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh, _TEXT
  124. // int64 CallAsmJsFunction<int64>(RecyclableObject *function, JavascriptMethod entryPoint, uint argc, Var *argv);
  125. .balign 16
  126. LEAF_ENTRY _ZN2Js18JavascriptFunction17CallAsmJsFunctionIlEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh, _TEXT
  127. jmp C_FUNC(_ZN2Js18JavascriptFunction17CallAsmJsFunctionIiEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh)
  128. LEAF_END _ZN2Js18JavascriptFunction17CallAsmJsFunctionIlEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh, _TEXT
  129. // float CallAsmJsFunction<float>(RecyclableObject *function, JavascriptMethod entryPoint, uint argc, Var *argv);
  130. .balign 16
  131. LEAF_ENTRY _ZN2Js18JavascriptFunction17CallAsmJsFunctionIfEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh, _TEXT
  132. jmp C_FUNC(_ZN2Js18JavascriptFunction17CallAsmJsFunctionIiEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh)
  133. LEAF_END _ZN2Js18JavascriptFunction17CallAsmJsFunctionIfEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh, _TEXT
  134. // double CallAsmJsFunction<double>(RecyclableObject *function, JavascriptMethod entryPoint, uint argc, Var *argv);
  135. .balign 16
  136. LEAF_ENTRY _ZN2Js18JavascriptFunction17CallAsmJsFunctionIdEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh, _TEXT
  137. jmp C_FUNC(_ZN2Js18JavascriptFunction17CallAsmJsFunctionIiEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh)
  138. LEAF_END _ZN2Js18JavascriptFunction17CallAsmJsFunctionIdEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh, _TEXT
  139. // AsmJsSIMDValue CallAsmJsFunction<AsmJsSIMDValue>(RecyclableObject *function, JavascriptMethod entryPoint, uint argc, Var *argv);
  140. .balign 16
  141. LEAF_ENTRY _ZN2Js18JavascriptFunction17CallAsmJsFunctionIDv4_fEET_PNS_16RecyclableObjectEPFPvS5_NS_8CallInfoEzEjPS6_, _TEXT
  142. int 3 //TODO: Verify this code path when enabling WASM.SIMD for xplat
  143. jmp C_FUNC(_ZN2Js18JavascriptFunction17CallAsmJsFunctionIiEET_PNS_16RecyclableObjectEPFPvS4_NS_8CallInfoEzEPS5_jPh)
  144. LEAF_END _ZN2Js18JavascriptFunction17CallAsmJsFunctionIDv4_fEET_PNS_16RecyclableObjectEPFPvS5_NS_8CallInfoEzEjPS6_, _TEXT
  145. #endif // _ENABLE_DYNAMIC_THUNKS
  146. //------------------------------------------------------------------------------
  147. .balign 16
  148. NESTED_ENTRY _ZN2Js18JavascriptFunction20DeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT, NoHandler
  149. push_nonvol_reg rbp
  150. lea rbp, [rsp]
  151. // save argument registers used by custom calling convention
  152. push_register rdi
  153. push_register rsi
  154. // Call
  155. // JavascriptMethod JavascriptFunction::DeferredParse(ScriptFunction**)
  156. //
  157. lea rdi, [rbp + 0x10] // &function, setup by custom calling convention
  158. call C_FUNC(_ZN2Js18JavascriptFunction13DeferredParseEPPNS_14ScriptFunctionE)
  159. pop_register rsi
  160. pop_register rdi
  161. mov rdi, qword ptr [rbp + 0x10] // re-load function, might have been changed by DeferredParse.
  162. // e.g. StackScriptFunction is Boxed
  163. // previous push/pop rdi is for stack alignment
  164. pop_nonvol_reg rbp
  165. jmp rax
  166. NESTED_END _ZN2Js18JavascriptFunction20DeferredParsingThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT
  167. //------------------------------------------------------------------------------
  168. // Var JavascriptFunction::DeferredDeserializeThunk(
  169. // RecyclableObject* function, CallInfo callInfo, ...)
  170. .balign 16
  171. NESTED_ENTRY _ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT, NoHandler
  172. push_nonvol_reg rbp
  173. lea rbp, [rsp]
  174. // save argument registers used by custom calling convention
  175. push_register rdi
  176. push_register rsi
  177. // Call
  178. // Js::JavascriptMethod JavascriptFunction::DeferredDeserialize(
  179. // ScriptFunction* function)
  180. //
  181. // RDI == function, setup by custom calling convention
  182. call C_FUNC(_ZN2Js18JavascriptFunction19DeferredDeserializeEPNS_14ScriptFunctionE)
  183. pop_register rsi
  184. pop_register rdi
  185. pop_nonvol_reg rbp
  186. jmp rax
  187. NESTED_END _ZN2Js18JavascriptFunction24DeferredDeserializeThunkEPNS_16RecyclableObjectENS_8CallInfoEz, _TEXT
  188. .balign 16
  189. NESTED_ENTRY BreakSpeculation, _TEXT, NoHandler
  190. cmp rdi, rdi
  191. cmove rax, rdi
  192. ret
  193. NESTED_END BreakSpeculation, _TEXT