JITProxy.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. // Copyright (C) 2012 Sony Computer Entertainment Inc.
  2. // All Rights Reserved.
  3. #include "config.h"
  4. #if ENABLE(JIT) && ENABLE(DETACHED_JIT) && !BUILDING_DETACHED_JIT
  5. #include "JIT.h"
  6. #include "JSCBridge.h"
  7. #include "JSCBridgeToll.h"
  8. #include <wtf/OwnPtr.h>
  9. namespace JSC {
  10. void ctiPatchCallByReturnAddress(CodeBlock* codeBlock, ReturnAddressPtr returnAddress, MacroAssemblerCodePtr newCalleeFunction)
  11. {
  12. PROFILE_FUNCTION_CALL;
  13. JSCBridge * const bridge(JSCBridge::sharedInstance());
  14. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  15. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  16. payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
  17. payload->sendArgument(reinterpret_cast<uintptr_t>(newCalleeFunction.executableAddress()));
  18. bridge->requestCompilerTask(JSCBridge::e_ctiPatchCallReturnAddrCodePtr);
  19. }
  20. void ctiPatchCallByReturnAddress(CodeBlock* codeBlock, ReturnAddressPtr returnAddress, FunctionPtr newCalleeFunction)
  21. {
  22. PROFILE_FUNCTION_CALL;
  23. JSCBridge * const bridge(JSCBridge::sharedInstance());
  24. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  25. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  26. payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
  27. payload->sendArgument(reinterpret_cast<uintptr_t>(newCalleeFunction.executableAddress()));
  28. bridge->requestCompilerTask(JSCBridge::e_ctiPatchCallReturnAddrFunctionPtr);
  29. }
  30. JITCode JIT::compile(VM* vm, CodeBlock* codeBlock, JITCompilationEffort effort, CodePtr* functionEntryArityCheck)
  31. {
  32. PROFILE_FUNCTION_CALL;
  33. JSCBridge * const bridge(JSCBridge::sharedInstance());
  34. CodePtr * sharedFunctionArityCheck(functionEntryArityCheck ? sharedNew<CodePtr>(*functionEntryArityCheck) : NULL);
  35. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  36. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  37. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  38. payload->sendArgument(static_cast <uintptr_t>(effort));
  39. payload->sendArgument(reinterpret_cast<uintptr_t>(sharedFunctionArityCheck));
  40. OwnPtr<JSCBridgeToll> toll(adoptPtr(bridge->createToll(payload.get())));
  41. toll->prepare(vm);
  42. toll->prepare(codeBlock);
  43. JITCode * sharedCode(reinterpret_cast<JITCode *>(bridge->requestCompilerTask(JSCBridge::e_JIT_compile)));
  44. JITCode result(*sharedCode);
  45. sharedDelete<JITCode>(sharedCode);
  46. if (functionEntryArityCheck) {
  47. *functionEntryArityCheck = *sharedFunctionArityCheck;
  48. sharedDelete<CodePtr>(sharedFunctionArityCheck);
  49. }
  50. return result;
  51. }
  52. void JIT::compileClosureCall(VM* vm, CallLinkInfo* callLinkInfo, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, Structure* expectedStructure, ExecutableBase* expectedExecutable, MacroAssemblerCodePtr codePtr)
  53. {
  54. PROFILE_FUNCTION_CALL;
  55. JSCBridge * const bridge(JSCBridge::sharedInstance());
  56. MacroAssemblerCodePtr * const sharedCode(sharedNew<MacroAssemblerCodePtr>(codePtr));
  57. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  58. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  59. payload->sendArgument(reinterpret_cast<uintptr_t>(callLinkInfo));
  60. payload->sendArgument(reinterpret_cast<uintptr_t>(callerCodeBlock));
  61. payload->sendArgument(reinterpret_cast<uintptr_t>(calleeCodeBlock));
  62. payload->sendArgument(reinterpret_cast<uintptr_t>(expectedStructure));
  63. payload->sendArgument(reinterpret_cast<uintptr_t>(expectedExecutable));
  64. payload->sendArgument(reinterpret_cast<uintptr_t>(sharedCode));
  65. bridge->requestCompilerTask(JSCBridge::e_JIT_compileClosureCall);
  66. sharedDelete<MacroAssemblerCodePtr>(sharedCode);
  67. }
  68. JIT::CodeRef JIT::compileCTINativeCall(VM* vm, NativeFunction func)
  69. {
  70. if (!vm->canUseJIT()) {
  71. #if ENABLE(LLINT)
  72. return CodeRef::createLLIntCodeRef(llint_native_call_trampoline);
  73. #else
  74. return CodeRef();
  75. #endif
  76. }
  77. {
  78. PROFILE_FUNCTION_CALL;
  79. JSCBridge * const bridge(JSCBridge::sharedInstance());
  80. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  81. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  82. payload->sendArgument(reinterpret_cast<uintptr_t>(func));
  83. MacroAssemblerCodeRef * sharedCodeRef(reinterpret_cast<MacroAssemblerCodeRef *>(bridge->requestCompilerTask(JSCBridge::e_JIT_compileCTINativeCall)));
  84. MacroAssemblerCodeRef codeRef(*sharedCodeRef);
  85. sharedDelete<MacroAssemblerCodeRef>(sharedCodeRef);
  86. return codeRef;
  87. }
  88. }
  89. void JIT::compileGetByIdChain(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
  90. {
  91. PROFILE_FUNCTION_CALL;
  92. JSCBridge * const bridge(JSCBridge::sharedInstance());
  93. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  94. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  95. payload->sendArgument(reinterpret_cast<uintptr_t>(callFrame));
  96. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  97. payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
  98. payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
  99. payload->sendArgument(reinterpret_cast<uintptr_t>(chain));
  100. payload->sendArgument( static_cast<uintptr_t>(count));
  101. payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
  102. payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
  103. payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
  104. payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
  105. bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdChain);
  106. }
  107. void JIT::compileGetByIdChainList(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
  108. {
  109. PROFILE_FUNCTION_CALL;
  110. JSCBridge * const bridge(JSCBridge::sharedInstance());
  111. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  112. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  113. payload->sendArgument(reinterpret_cast<uintptr_t>(callFrame));
  114. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  115. payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
  116. payload->sendArgument(reinterpret_cast<uintptr_t>(prototypeStructureList));
  117. payload->sendArgument( static_cast<uintptr_t>(currentIndex));
  118. payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
  119. payload->sendArgument(reinterpret_cast<uintptr_t>(chain));
  120. payload->sendArgument( static_cast<uintptr_t>(count));
  121. payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
  122. payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
  123. payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
  124. bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdChainList);
  125. }
  126. void JIT::compileGetByIdProto(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset, ReturnAddressPtr returnAddress)
  127. {
  128. PROFILE_FUNCTION_CALL;
  129. JSCBridge * const bridge(JSCBridge::sharedInstance());
  130. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  131. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  132. payload->sendArgument(reinterpret_cast<uintptr_t>(callFrame));
  133. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  134. payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
  135. payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
  136. payload->sendArgument(reinterpret_cast<uintptr_t>(prototypeStructure));
  137. payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
  138. payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
  139. payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
  140. payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
  141. bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdProto);
  142. }
  143. void JIT::compileGetByIdProtoList(VM* vm, CallFrame* callFrame, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* prototypeStructureList, int currentIndex, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
  144. {
  145. PROFILE_FUNCTION_CALL;
  146. JSCBridge * const bridge(JSCBridge::sharedInstance());
  147. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  148. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  149. payload->sendArgument(reinterpret_cast<uintptr_t>(callFrame));
  150. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  151. payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
  152. payload->sendArgument(reinterpret_cast<uintptr_t>(prototypeStructureList));
  153. payload->sendArgument( static_cast<uintptr_t>(currentIndex));
  154. payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
  155. payload->sendArgument(reinterpret_cast<uintptr_t>(prototypeStructure));
  156. payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
  157. payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
  158. payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
  159. bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdProtoList);
  160. }
  161. void JIT::compileGetByIdSelfList(VM* vm, CodeBlock* codeBlock, StructureStubInfo* stubInfo, PolymorphicAccessStructureList* polymorphicStructures, int currentIndex, Structure* structure, const Identifier& ident, const PropertySlot& slot, PropertyOffset cachedOffset)
  162. {
  163. PROFILE_FUNCTION_CALL;
  164. JSCBridge * const bridge(JSCBridge::sharedInstance());
  165. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  166. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  167. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  168. payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
  169. payload->sendArgument(reinterpret_cast<uintptr_t>(polymorphicStructures));
  170. payload->sendArgument( static_cast<uintptr_t>(currentIndex));
  171. payload->sendArgument(reinterpret_cast<uintptr_t>(structure));
  172. payload->sendArgument(reinterpret_cast<uintptr_t>(&ident)); // ident is only used as a TrustedImmPtr so it's ok for it to be not shared allocated
  173. payload->sendPOD(&slot); // slot is a const so it's safe to assume slot will not be modifed so no need to expect a return value from the compiler
  174. payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
  175. bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByIdSelfList);
  176. }
  177. void JIT::compileGetByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
  178. {
  179. PROFILE_FUNCTION_CALL;
  180. JSCBridge * const bridge(JSCBridge::sharedInstance());
  181. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  182. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  183. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  184. payload->sendArgument(reinterpret_cast<uintptr_t>(byValInfo));
  185. payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
  186. payload->sendArgument( static_cast<uintptr_t>(arrayMode));
  187. bridge->requestCompilerTask(JSCBridge::e_JIT_compileGetByVal);
  188. }
  189. void JIT::compilePatchGetArrayLength(VM* vm, CodeBlock* codeBlock, ReturnAddressPtr returnAddress)
  190. {
  191. PROFILE_FUNCTION_CALL;
  192. JSCBridge * const bridge(JSCBridge::sharedInstance());
  193. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  194. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  195. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  196. payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
  197. bridge->requestCompilerTask(JSCBridge::e_JIT_compilePatchGetArrayLength);
  198. }
  199. void JIT::compilePutByIdTransition(VM* vm, CodeBlock* codeBlock, StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, PropertyOffset cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct)
  200. {
  201. PROFILE_FUNCTION_CALL;
  202. JSCBridge * const bridge(JSCBridge::sharedInstance());
  203. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  204. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  205. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  206. payload->sendArgument(reinterpret_cast<uintptr_t>(stubInfo));
  207. payload->sendArgument(reinterpret_cast<uintptr_t>(oldStructure));
  208. payload->sendArgument(reinterpret_cast<uintptr_t>(newStructure));
  209. payload->sendArgument( static_cast<uintptr_t>(cachedOffset));
  210. payload->sendArgument(reinterpret_cast<uintptr_t>(chain));
  211. payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
  212. payload->sendArgument( static_cast<uintptr_t>(direct));
  213. OwnPtr<JSCBridgeToll> toll(adoptPtr(bridge->createToll(payload.get())));
  214. toll->prepare(vm);
  215. toll->prepare(codeBlock);
  216. bridge->requestCompilerTask(JSCBridge::e_JIT_compilePutByIdTransition);
  217. }
  218. void JIT::compilePutByVal(VM* vm, CodeBlock* codeBlock, ByValInfo* byValInfo, ReturnAddressPtr returnAddress, JITArrayMode arrayMode)
  219. {
  220. PROFILE_FUNCTION_CALL;
  221. JSCBridge * const bridge(JSCBridge::sharedInstance());
  222. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  223. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  224. payload->sendArgument(reinterpret_cast<uintptr_t>(codeBlock));
  225. payload->sendArgument(reinterpret_cast<uintptr_t>(byValInfo));
  226. payload->sendArgument(reinterpret_cast<uintptr_t>(returnAddress.value()));
  227. payload->sendArgument( static_cast<uintptr_t>(arrayMode));
  228. bridge->requestCompilerTask(JSCBridge::e_JIT_compilePutByVal);
  229. }
  230. void JIT::linkFor(JSFunction* callee, CodeBlock* callerCodeBlock, CodeBlock* calleeCodeBlock, MacroAssemblerCodePtr code, CallLinkInfo* callLinkInfo, VM* vm, CodeSpecializationKind kind)
  231. {
  232. PROFILE_FUNCTION_CALL;
  233. JSCBridge * const bridge(JSCBridge::sharedInstance());
  234. MacroAssemblerCodePtr * const sharedCode(sharedNew<MacroAssemblerCodePtr>(code));
  235. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  236. payload->sendArgument(reinterpret_cast<uintptr_t>(callee));
  237. payload->sendArgument(reinterpret_cast<uintptr_t>(callerCodeBlock));
  238. payload->sendArgument(reinterpret_cast<uintptr_t>(calleeCodeBlock));
  239. payload->sendArgument(reinterpret_cast<uintptr_t>(sharedCode));
  240. payload->sendArgument(reinterpret_cast<uintptr_t>(callLinkInfo));
  241. payload->sendArgument(reinterpret_cast<uintptr_t>(vm));
  242. payload->sendArgument( static_cast<uintptr_t>(kind));
  243. bridge->requestCompilerTask(JSCBridge::e_JIT_linkFor);
  244. sharedDelete<MacroAssemblerCodePtr>(sharedCode);
  245. }
  246. void JIT::linkSlowCall(CodeBlock* callerCodeBlock, CallLinkInfo* callLinkInfo)
  247. {
  248. PROFILE_FUNCTION_CALL;
  249. JSCBridge * const bridge(JSCBridge::sharedInstance());
  250. OwnPtr<JSCBridge::Payload> payload(adoptPtr(bridge->createPayload()));
  251. payload->sendArgument(reinterpret_cast<uintptr_t>(callerCodeBlock));
  252. payload->sendArgument(reinterpret_cast<uintptr_t>(callLinkInfo));
  253. bridge->requestCompilerTask(JSCBridge::e_JIT_linkSlowCall);
  254. }
  255. } // namespace JSC
  256. #endif // #if ENABLE(JIT) && ENABLE(DETACHED_JIT) && !BUILDING_DETACHED_JIT