2
0

ServerScriptContext.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  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. #include "Backend.h"
  6. #if ENABLE_OOP_NATIVE_CODEGEN
  7. #include "JITServer/JITServer.h"
  8. ServerScriptContext::ThreadContextHolder::ThreadContextHolder(ServerThreadContext* threadContextInfo) : threadContextInfo(threadContextInfo)
  9. {
  10. threadContextInfo->AddRef();
  11. }
  12. ServerScriptContext::ThreadContextHolder::~ThreadContextHolder()
  13. {
  14. threadContextInfo->Release();
  15. }
  16. ServerScriptContext::ServerScriptContext(ScriptContextDataIDL * contextData, ServerThreadContext* threadContextInfo) :
  17. m_contextData(*contextData),
  18. threadContextHolder(threadContextInfo),
  19. m_isPRNGSeeded(false),
  20. m_sourceCodeArena(_u("JITSourceCodeArena"), threadContextInfo->GetForegroundPageAllocator(), Js::Throw::OutOfMemory, nullptr),
  21. m_interpreterThunkBufferManager(&m_sourceCodeArena, threadContextInfo->GetThunkPageAllocators(), nullptr, threadContextInfo, _u("Interpreter thunk buffer"), GetThreadContext()->GetProcessHandle()),
  22. m_asmJsInterpreterThunkBufferManager(&m_sourceCodeArena, threadContextInfo->GetThunkPageAllocators(), nullptr, threadContextInfo, _u("Asm.js interpreter thunk buffer"), GetThreadContext()->GetProcessHandle()),
  23. m_moduleRecords(&HeapAllocator::Instance),
  24. m_codeGenAlloc(nullptr, nullptr, threadContextInfo, threadContextInfo->GetCodePageAllocators(), threadContextInfo->GetProcessHandle()),
  25. m_globalThisAddr(0),
  26. #ifdef PROFILE_EXEC
  27. codeGenProfiler(nullptr),
  28. #endif
  29. m_refCount(0),
  30. m_isClosed(false)
  31. {
  32. #if !TARGET_64 && _CONTROL_FLOW_GUARD
  33. m_codeGenAlloc.canCreatePreReservedSegment = threadContextInfo->CanCreatePreReservedSegment();
  34. #endif
  35. }
  36. ServerScriptContext::~ServerScriptContext()
  37. {
  38. m_moduleRecords.Map([](uint, Js::ServerSourceTextModuleRecord* record)
  39. {
  40. HeapDelete(record);
  41. });
  42. #ifdef PROFILE_EXEC
  43. while (this->codeGenProfiler)
  44. {
  45. Js::ScriptContextProfiler* profiler = this->codeGenProfiler;
  46. this->codeGenProfiler = this->codeGenProfiler->next;
  47. HeapDelete(profiler);
  48. }
  49. #endif
  50. }
  51. intptr_t
  52. ServerScriptContext::GetNullAddr() const
  53. {
  54. return m_contextData.nullAddr;
  55. }
  56. intptr_t
  57. ServerScriptContext::GetUndefinedAddr() const
  58. {
  59. return m_contextData.undefinedAddr;
  60. }
  61. intptr_t
  62. ServerScriptContext::GetTrueAddr() const
  63. {
  64. return m_contextData.trueAddr;
  65. }
  66. intptr_t
  67. ServerScriptContext::GetFalseAddr() const
  68. {
  69. return m_contextData.falseAddr;
  70. }
  71. intptr_t
  72. ServerScriptContext::GetUndeclBlockVarAddr() const
  73. {
  74. return m_contextData.undeclBlockVarAddr;
  75. }
  76. intptr_t
  77. ServerScriptContext::GetEmptyStringAddr() const
  78. {
  79. return m_contextData.emptyStringAddr;
  80. }
  81. intptr_t
  82. ServerScriptContext::GetNegativeZeroAddr() const
  83. {
  84. return m_contextData.negativeZeroAddr;
  85. }
  86. intptr_t
  87. ServerScriptContext::GetNumberTypeStaticAddr() const
  88. {
  89. return m_contextData.numberTypeStaticAddr;
  90. }
  91. intptr_t
  92. ServerScriptContext::GetStringTypeStaticAddr() const
  93. {
  94. return m_contextData.stringTypeStaticAddr;
  95. }
  96. intptr_t
  97. ServerScriptContext::GetSymbolTypeStaticAddr() const
  98. {
  99. return m_contextData.symbolTypeStaticAddr;
  100. }
  101. intptr_t
  102. ServerScriptContext::GetObjectTypeAddr() const
  103. {
  104. return m_contextData.objectTypeAddr;
  105. }
  106. intptr_t
  107. ServerScriptContext::GetObjectHeaderInlinedTypeAddr() const
  108. {
  109. return m_contextData.objectHeaderInlinedTypeAddr;
  110. }
  111. intptr_t
  112. ServerScriptContext::GetRegexTypeAddr() const
  113. {
  114. return m_contextData.regexTypeAddr;
  115. }
  116. intptr_t
  117. ServerScriptContext::GetArrayTypeAddr() const
  118. {
  119. return m_contextData.arrayTypeAddr;
  120. }
  121. intptr_t
  122. ServerScriptContext::GetNativeIntArrayTypeAddr() const
  123. {
  124. return m_contextData.nativeIntArrayTypeAddr;
  125. }
  126. intptr_t
  127. ServerScriptContext::GetNativeFloatArrayTypeAddr() const
  128. {
  129. return m_contextData.nativeFloatArrayTypeAddr;
  130. }
  131. intptr_t
  132. ServerScriptContext::GetArrayConstructorAddr() const
  133. {
  134. return m_contextData.arrayConstructorAddr;
  135. }
  136. intptr_t
  137. ServerScriptContext::GetCharStringCacheAddr() const
  138. {
  139. return m_contextData.charStringCacheAddr;
  140. }
  141. intptr_t
  142. ServerScriptContext::GetSideEffectsAddr() const
  143. {
  144. return m_contextData.sideEffectsAddr;
  145. }
  146. intptr_t
  147. ServerScriptContext::GetArraySetElementFastPathVtableAddr() const
  148. {
  149. return m_contextData.arraySetElementFastPathVtableAddr;
  150. }
  151. intptr_t
  152. ServerScriptContext::GetIntArraySetElementFastPathVtableAddr() const
  153. {
  154. return m_contextData.intArraySetElementFastPathVtableAddr;
  155. }
  156. intptr_t
  157. ServerScriptContext::GetFloatArraySetElementFastPathVtableAddr() const
  158. {
  159. return m_contextData.floatArraySetElementFastPathVtableAddr;
  160. }
  161. intptr_t
  162. ServerScriptContext::GetLibraryAddr() const
  163. {
  164. return m_contextData.libraryAddr;
  165. }
  166. intptr_t
  167. ServerScriptContext::GetGlobalObjectAddr() const
  168. {
  169. return m_contextData.globalObjectAddr;
  170. }
  171. intptr_t
  172. ServerScriptContext::GetGlobalObjectThisAddr() const
  173. {
  174. return m_globalThisAddr;
  175. }
  176. void
  177. ServerScriptContext::UpdateGlobalObjectThisAddr(intptr_t globalThis)
  178. {
  179. m_globalThisAddr = globalThis;
  180. }
  181. intptr_t
  182. ServerScriptContext::GetObjectPrototypeAddr() const
  183. {
  184. return m_contextData.objectPrototypeAddr;
  185. }
  186. intptr_t
  187. ServerScriptContext::GetFunctionPrototypeAddr() const
  188. {
  189. return m_contextData.functionPrototypeAddr;
  190. }
  191. intptr_t
  192. ServerScriptContext::GetNumberAllocatorAddr() const
  193. {
  194. return m_contextData.numberAllocatorAddr;
  195. }
  196. intptr_t
  197. ServerScriptContext::GetRecyclerAddr() const
  198. {
  199. return m_contextData.recyclerAddr;
  200. }
  201. bool
  202. ServerScriptContext::GetRecyclerAllowNativeCodeBumpAllocation() const
  203. {
  204. return m_contextData.recyclerAllowNativeCodeBumpAllocation != 0;
  205. }
  206. intptr_t
  207. ServerScriptContext::GetBuiltinFunctionsBaseAddr() const
  208. {
  209. return m_contextData.builtinFunctionsBaseAddr;
  210. }
  211. intptr_t
  212. ServerScriptContext::GetAddr() const
  213. {
  214. return m_contextData.scriptContextAddr;
  215. }
  216. intptr_t
  217. ServerScriptContext::GetVTableAddress(VTableValue vtableType) const
  218. {
  219. Assert(vtableType < VTableValue::Count);
  220. return m_contextData.vtableAddresses[vtableType];
  221. }
  222. bool
  223. ServerScriptContext::IsRecyclerVerifyEnabled() const
  224. {
  225. return m_contextData.isRecyclerVerifyEnabled != FALSE;
  226. }
  227. uint
  228. ServerScriptContext::GetRecyclerVerifyPad() const
  229. {
  230. return m_contextData.recyclerVerifyPad;
  231. }
  232. bool
  233. ServerScriptContext::IsPRNGSeeded() const
  234. {
  235. return m_isPRNGSeeded;
  236. }
  237. #ifdef ENABLE_SCRIPT_DEBUGGING
  238. intptr_t
  239. ServerScriptContext::GetDebuggingFlagsAddr() const
  240. {
  241. return static_cast<intptr_t>(m_contextData.debuggingFlagsAddr);
  242. }
  243. intptr_t
  244. ServerScriptContext::GetDebugStepTypeAddr() const
  245. {
  246. return static_cast<intptr_t>(m_contextData.debugStepTypeAddr);
  247. }
  248. intptr_t
  249. ServerScriptContext::GetDebugFrameAddressAddr() const
  250. {
  251. return static_cast<intptr_t>(m_contextData.debugFrameAddressAddr);
  252. }
  253. intptr_t
  254. ServerScriptContext::GetDebugScriptIdWhenSetAddr() const
  255. {
  256. return static_cast<intptr_t>(m_contextData.debugScriptIdWhenSetAddr);
  257. }
  258. #endif
  259. intptr_t
  260. ServerScriptContext::GetChakraLibAddr() const
  261. {
  262. return m_contextData.chakraLibAddr;
  263. }
  264. bool
  265. ServerScriptContext::IsClosed() const
  266. {
  267. return m_isClosed;
  268. }
  269. ArenaAllocator *
  270. ServerScriptContext::GetSourceCodeArena()
  271. {
  272. return &m_sourceCodeArena;
  273. }
  274. void
  275. ServerScriptContext::DecommitEmitBufferManager(bool asmJsManager)
  276. {
  277. GetEmitBufferManager(asmJsManager)->Decommit();
  278. }
  279. OOPEmitBufferManagerWithLock *
  280. ServerScriptContext::GetEmitBufferManager(bool asmJsManager)
  281. {
  282. if (asmJsManager)
  283. {
  284. return &m_asmJsInterpreterThunkBufferManager;
  285. }
  286. else
  287. {
  288. return &m_interpreterThunkBufferManager;
  289. }
  290. }
  291. void
  292. ServerScriptContext::Close()
  293. {
  294. Assert(!IsClosed());
  295. m_isClosed = true;
  296. m_codeGenAlloc.emitBufferManager.Decommit();
  297. #ifdef STACK_BACK_TRACE
  298. ServerContextManager::RecordCloseContext(this);
  299. #endif
  300. }
  301. void
  302. ServerScriptContext::AddRef()
  303. {
  304. InterlockedExchangeAdd(&m_refCount, 1u);
  305. }
  306. void
  307. ServerScriptContext::Release()
  308. {
  309. InterlockedExchangeSubtract(&m_refCount, 1u);
  310. if (m_isClosed && m_refCount == 0)
  311. {
  312. // Not freeing here, we'll expect explicit ServerCleanupScriptContext() call to do the free
  313. // otherwise after free, the CodeGen call can still get same scriptContext if there's another
  314. // ServerInitializeScriptContext call
  315. }
  316. }
  317. OOPCodeGenAllocators *
  318. ServerScriptContext::GetCodeGenAllocators()
  319. {
  320. return &m_codeGenAlloc;
  321. }
  322. Field(Js::Var)*
  323. ServerScriptContext::GetModuleExportSlotArrayAddress(uint moduleIndex, uint slotIndex)
  324. {
  325. AutoCriticalSection cs(&m_cs);
  326. AssertOrFailFast(m_moduleRecords.ContainsKey(moduleIndex));
  327. auto record = m_moduleRecords.Item(moduleIndex);
  328. return record->localExportSlotsAddr;
  329. }
  330. void
  331. ServerScriptContext::SetIsPRNGSeeded(bool value)
  332. {
  333. m_isPRNGSeeded = value;
  334. }
  335. void
  336. ServerScriptContext::AddModuleRecordInfo(unsigned int moduleId, __int64 localExportSlotsAddr)
  337. {
  338. AutoCriticalSection cs(&m_cs);
  339. Js::ServerSourceTextModuleRecord* record = HeapNewStructZ(Js::ServerSourceTextModuleRecord);
  340. record->moduleId = moduleId;
  341. record->localExportSlotsAddr = (Field(Js::Var)*)localExportSlotsAddr;
  342. m_moduleRecords.Add(moduleId, record);
  343. }
  344. #ifdef PROFILE_EXEC
  345. Js::ScriptContextProfiler*
  346. ServerScriptContext::GetCodeGenProfiler(_In_ PageAllocator* pageAllocator)
  347. {
  348. if (Js::Configuration::Global.flags.IsEnabled(Js::ProfileFlag))
  349. {
  350. AutoCriticalSection cs(&this->profilerCS);
  351. Js::ScriptContextProfiler* profiler = this->codeGenProfiler;
  352. while (profiler)
  353. {
  354. if (profiler->pageAllocator == pageAllocator)
  355. {
  356. if (!profiler->IsInitialized())
  357. {
  358. profiler->Initialize(pageAllocator, nullptr);
  359. }
  360. return profiler;
  361. }
  362. profiler = profiler->next;
  363. }
  364. // If we didn't find a profiler, allocate a new one
  365. profiler = HeapNew(Js::ScriptContextProfiler);
  366. profiler->Initialize(pageAllocator, nullptr);
  367. profiler->next = this->codeGenProfiler;
  368. this->codeGenProfiler = profiler;
  369. return profiler;
  370. }
  371. return nullptr;
  372. }
  373. Js::ScriptContextProfiler*
  374. ServerScriptContext::GetFirstCodeGenProfiler() const
  375. {
  376. return this->codeGenProfiler;
  377. }
  378. #endif // PROFILE_EXEC
  379. #endif // ENABLE_OOP_NATIVE_CODEGEN