BackendApi.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation and contributors. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. #if DYNAMIC_INTERPRETER_THUNK
  7. #define DefaultEntryThunk Js::InterpreterStackFrame::DelayDynamicInterpreterThunk
  8. #if _M_X64
  9. #define AsmJsDefaultEntryThunk Js::InterpreterStackFrame::AsmJsDelayDynamicInterpreterThunk
  10. #elif _M_IX86
  11. #define AsmJsDefaultEntryThunk Js::InterpreterStackFrame::DelayDynamicInterpreterThunk
  12. #endif
  13. #else
  14. #define DefaultEntryThunk Js::InterpreterStackFrame::InterpreterThunk
  15. #endif
  16. #define ProfileEntryThunk Js::ScriptContext::DebugProfileProbeThunk
  17. #define DefaultDeferredParsingThunk Js::JavascriptFunction::DeferredParsingThunk
  18. #if defined(ENABLE_SCRIPT_PROFILING) || defined(ENABLE_SCRIPT_DEBUGGING)
  19. #define ProfileDeferredParsingThunk Js::ScriptContext::ProfileModeDeferredParsingThunk
  20. #endif
  21. #define DefaultDeferredDeserializeThunk Js::JavascriptFunction::DeferredDeserializeThunk
  22. #define ProfileDeferredDeserializeThunk Js::ScriptContext::ProfileModeDeferredDeserializeThunk
  23. #if ENABLE_NATIVE_CODEGEN
  24. class NativeCodeGenerator;
  25. class ThreadContext;
  26. struct CodeGenWorkItem;
  27. class NativeCodeData;
  28. class ThreadContextInfo;
  29. class StackSym;
  30. class Func;
  31. struct InlinedFrameLayout;
  32. typedef intptr_t IntConstType;
  33. typedef uintptr_t UIntConstType;
  34. typedef double FloatConstType;
  35. #include "EmitBuffer.h"
  36. #include "InterpreterThunkEmitter.h"
  37. #include "JITThunkEmitter.h"
  38. #include "BackendOpCodeAttr.h"
  39. #include "BackendOpCodeAttrAsmJs.h"
  40. #include "CodeGenNumberAllocator.h"
  41. #include "NativeCodeData.h"
  42. #include "JnHelperMethod.h"
  43. #include "IRType.h"
  44. #include "InlineeFrameInfo.h"
  45. #include "CodeGenAllocators.h"
  46. #include "PropertyGuard.h"
  47. NativeCodeGenerator * NewNativeCodeGenerator(Js::ScriptContext * nativeCodeGen);
  48. void DeleteNativeCodeGenerator(NativeCodeGenerator * nativeCodeGen);
  49. void CloseNativeCodeGenerator(NativeCodeGenerator* nativeCodeGen);
  50. bool IsClosedNativeCodeGenerator(NativeCodeGenerator* nativeCodeGen);
  51. void SetProfileModeNativeCodeGen(NativeCodeGenerator *pNativeCodeGen, BOOL fSet);
  52. void UpdateNativeCodeGeneratorForDebugMode(NativeCodeGenerator* nativeCodeGen);
  53. CriticalSection *GetNativeCodeGenCriticalSection(NativeCodeGenerator *pNativeCodeGen);
  54. bool TryReleaseNonHiPriWorkItem(Js::ScriptContext* scriptContext, CodeGenWorkItem* workItem);
  55. void NativeCodeGenEnterScriptStart(NativeCodeGenerator * nativeCodeGen);
  56. void FreeNativeCodeGenAllocation(Js::ScriptContext* scriptContext, Js::JavascriptMethod codeAddress, Js::JavascriptMethod thunkAddress);
  57. InProcCodeGenAllocators* GetForegroundAllocator(NativeCodeGenerator * nativeCodeGen, PageAllocator* pageallocator);
  58. void GenerateFunction(NativeCodeGenerator * nativeCodeGen, Js::FunctionBody * functionBody, Js::ScriptFunction * function = NULL);
  59. void GenerateLoopBody(NativeCodeGenerator * nativeCodeGen, Js::FunctionBody * functionBody, Js::LoopHeader * loopHeader, Js::EntryPointInfo* entryPointInfo, uint localCount, Js::Var localSlots[]);
  60. #ifdef ENABLE_PREJIT
  61. void GenerateAllFunctions(NativeCodeGenerator * nativeCodeGen, Js::FunctionBody * fn);
  62. #endif
  63. #ifdef IR_VIEWER
  64. Js::Var RejitIRViewerFunction(NativeCodeGenerator *nativeCodeGen, Js::FunctionBody *fn, Js::ScriptContext *scriptContext);
  65. #endif
  66. #ifdef ALLOW_JIT_REPRO
  67. HRESULT JitFromEncodedWorkItem(NativeCodeGenerator *nativeCodeGen, _In_reads_(bufSize) const byte* buffer, _In_ uint bufferSize);
  68. #endif
  69. BOOL IsIntermediateCodeGenThunk(Js::JavascriptMethod codeAddress);
  70. BOOL IsAsmJsCodeGenThunk(Js::JavascriptMethod codeAddress);
  71. typedef Js::JavascriptMethod (*CheckCodeGenFunction)(Js::ScriptFunction * function);
  72. CheckCodeGenFunction GetCheckCodeGenFunction(Js::JavascriptMethod codeAddress);
  73. Js::JavascriptMethod GetCheckCodeGenThunk();
  74. #ifdef ASMJS_PLAT
  75. Js::JavascriptMethod GetCheckAsmJsCodeGenThunk();
  76. #endif
  77. uint GetBailOutRegisterSaveSlotCount();
  78. uint GetBailOutReserveSlotCount();
  79. #if DBG
  80. void CheckIsExecutable(Js::RecyclableObject * function, Js::JavascriptMethod entryPoint);
  81. #endif
  82. #ifdef PROFILE_EXEC
  83. namespace Js
  84. {
  85. class ScriptContextProfiler;
  86. };
  87. void CreateProfilerNativeCodeGen(NativeCodeGenerator * nativeCodeGen, Js::ScriptContextProfiler * profiler);
  88. void ProfilePrintNativeCodeGen(NativeCodeGenerator * nativeCodeGen);
  89. void SetProfilerFromNativeCodeGen(NativeCodeGenerator * toNativeCodeGen, NativeCodeGenerator * fromNativeCodeGen);
  90. #endif
  91. void DeleteNativeCodeData(NativeCodeData * data);
  92. #else
  93. inline BOOL IsIntermediateCodeGenThunk(Js::JavascriptMethod codeAddress) { return false; }
  94. inline BOOL IsAsmJsCodeGenThunk(Js::JavascriptMethod codeAddress) { return false; }
  95. #endif
  96. #if _M_X64
  97. extern "C" void * amd64_ReturnFromCallWithFakeFrame();
  98. #endif
  99. struct InlinedFrameLayout
  100. {
  101. Js::InlineeCallInfo callInfo;
  102. Js::JavascriptFunction *function;
  103. Js::Var arguments; // The arguments object.
  104. //Js::Var argv[0]; // Here it would be embedded arguments array (callInfo.count elements)
  105. // but can't have 0-size arr in base class, so we define it in derived class.
  106. Js::Var* GetArguments()
  107. {
  108. return (Js::Var*)(this + 1);
  109. }
  110. template<class Fn>
  111. void MapArgs(Fn callback)
  112. {
  113. Js::Var* arguments = this->GetArguments();
  114. for (uint i = 0; i < callInfo.Count; i++)
  115. {
  116. callback(i, (Js::Var*)((uintptr_t*)arguments + i));
  117. }
  118. }
  119. InlinedFrameLayout* Next()
  120. {
  121. InlinedFrameLayout *next = (InlinedFrameLayout *)(this->GetArguments() + this->callInfo.Count);
  122. return next;
  123. }
  124. };
  125. class BailOutRecord;
  126. struct LazyBailOutRecord
  127. {
  128. uint32 offset;
  129. BYTE* instructionPointer; // Instruction pointer of the bailout code
  130. BailOutRecord* bailoutRecord;
  131. LazyBailOutRecord() : offset(0), instructionPointer(nullptr), bailoutRecord(nullptr) {}
  132. LazyBailOutRecord(uint32 offset, BYTE* address, BailOutRecord* record) :
  133. offset(offset), instructionPointer(address),
  134. bailoutRecord(record)
  135. {}
  136. void SetBailOutKind();
  137. #if DBG
  138. void Dump(Js::FunctionBody* functionBody);
  139. #endif
  140. };
  141. struct StackFrameConstants
  142. {
  143. #if defined(_M_IX86)
  144. static const size_t StackCheckCodeHeightThreadBound = 35;
  145. static const size_t StackCheckCodeHeightNotThreadBound = 47;
  146. static const size_t StackCheckCodeHeightWithInterruptProbe = 53;
  147. #elif defined(_M_X64)
  148. static const size_t StackCheckCodeHeightThreadBound = 57;
  149. static const size_t StackCheckCodeHeightNotThreadBound = 62;
  150. static const size_t StackCheckCodeHeightWithInterruptProbe = 68;
  151. #elif defined(_M_ARM)
  152. static const size_t StackCheckCodeHeight = 64;
  153. static const size_t StackCheckCodeHeightThreadBound = StackFrameConstants::StackCheckCodeHeight;
  154. static const size_t StackCheckCodeHeightNotThreadBound = StackFrameConstants::StackCheckCodeHeight;
  155. static const size_t StackCheckCodeHeightWithInterruptProbe = StackFrameConstants::StackCheckCodeHeight;
  156. #elif defined(_M_ARM64)
  157. static const size_t StackCheckCodeHeight = 58*2;
  158. static const size_t StackCheckCodeHeightThreadBound = StackFrameConstants::StackCheckCodeHeight;
  159. static const size_t StackCheckCodeHeightNotThreadBound = StackFrameConstants::StackCheckCodeHeight;
  160. static const size_t StackCheckCodeHeightWithInterruptProbe = StackFrameConstants::StackCheckCodeHeight;
  161. #endif
  162. };
  163. struct NativeResourceIds
  164. {
  165. static const short SourceCodeResourceNameId = 0x64;
  166. static const short ByteCodeResourceNameId = 0x65;
  167. static const short NativeMapResourceNameId = 0x66;
  168. static const short NativeThrowMapResourceNameId = 0x67;
  169. };
  170. #if defined(_M_IX86)
  171. struct ThunkConstants
  172. {
  173. static const size_t ThunkInstructionSize = 2;
  174. static const size_t ThunkSize = 6;
  175. };
  176. #endif
  177. enum LibraryValue {
  178. ValueInvalid,
  179. ValueUndeclBlockVar,
  180. ValueEmptyString,
  181. ValueUndefined,
  182. ValueNull,
  183. ValueTrue,
  184. ValueFalse,
  185. ValueNegativeZero,
  186. ValueNumberTypeStatic,
  187. ValueStringTypeStatic,
  188. ValueObjectType,
  189. ValueObjectHeaderInlinedType,
  190. ValueRegexType,
  191. ValueArrayConstructor,
  192. ValuePositiveInfinity,
  193. ValueNaN,
  194. ValueJavascriptArrayType,
  195. ValueNativeIntArrayType,
  196. ValueNativeFloatArrayType,
  197. ValueConstructorCacheDefaultInstance,
  198. ValueAbsDoubleCst,
  199. ValueUintConvertConst,
  200. ValueBuiltinFunctions,
  201. ValueJnHelperMethods,
  202. ValueCharStringCache
  203. };
  204. enum VTableValue {
  205. //#if !_M_X64 TODO: OOP JIT, can we make this arch specific again?
  206. VtableJavascriptNumber,
  207. //#endif
  208. VtableDynamicObject,
  209. VtableInvalid,
  210. VtablePropertyString,
  211. VtableLazyJSONString,
  212. VtableLiteralStringWithPropertyStringPtr,
  213. VtableJavascriptBoolean,
  214. VtableJavascriptArray,
  215. VtableInt8Array,
  216. VtableUint8Array,
  217. VtableUint8ClampedArray,
  218. VtableInt16Array,
  219. VtableUint16Array,
  220. VtableInt32Array,
  221. VtableUint32Array,
  222. VtableFloat32Array,
  223. VtableFloat64Array,
  224. VtableJavascriptPixelArray,
  225. VtableInt64Array,
  226. VtableUint64Array,
  227. VtableBoolArray,
  228. VtableCharArray,
  229. VtableInt8VirtualArray,
  230. VtableUint8VirtualArray,
  231. VtableUint8ClampedVirtualArray,
  232. VtableInt16VirtualArray,
  233. VtableUint16VirtualArray,
  234. VtableInt32VirtualArray,
  235. VtableUint32VirtualArray,
  236. VtableFloat32VirtualArray,
  237. VtableFloat64VirtualArray,
  238. VtableNativeIntArray,
  239. #if ENABLE_COPYONACCESS_ARRAY
  240. VtableCopyOnAccessNativeIntArray,
  241. #endif
  242. VtableNativeFloatArray,
  243. VtableJavascriptNativeIntArray,
  244. VtableJavascriptRegExp,
  245. VtableScriptFunction,
  246. VtableJavascriptGeneratorFunction,
  247. VtableJavascriptAsyncFunction,
  248. VtableStackScriptFunction,
  249. VtableConcatStringMulti,
  250. VtableCompoundString,
  251. // SIMD_JS
  252. VtableSimd128F4,
  253. VtableSimd128I4,
  254. VtableSimd128I8,
  255. VtableSimd128I16,
  256. VtableSimd128U4,
  257. VtableSimd128U8,
  258. VtableSimd128U16,
  259. Count
  260. };
  261. #if DBG_DUMP || defined(ENABLE_IR_VIEWER)
  262. const char16 *GetVtableName(VTableValue value);
  263. #endif
  264. enum AuxArrayValue {
  265. AuxPropertyIdArray,
  266. AuxIntArray,
  267. AuxFloatArray,
  268. AuxVarsArray,
  269. AuxVarArrayVarCount,
  270. AuxFuncInfoArray
  271. };
  272. enum OptimizationOverridesValue {
  273. OptimizationOverridesArraySetElementFastPathVtable,
  274. OptimizationOverridesIntArraySetElementFastPathVtable,
  275. OptimizationOverridesFloatArraySetElementFastPathVtable,
  276. OptimizationOverridesSideEffects
  277. };
  278. enum FunctionBodyValue {
  279. FunctionBodyConstantVar,
  280. FunctionBodyNestedFuncReference,
  281. FunctionBodyReferencedPropertyId,
  282. FunctionBodyPropertyIdFromCacheId,
  283. FunctionBodyLiteralRegex,
  284. FunctionBodyStringTemplateCallsiteRef
  285. };
  286. enum ScriptContextValue {
  287. ScriptContextNumberAllocator,
  288. ScriptContextCharStringCache,
  289. ScriptContextRecycler,
  290. ScriptContextOptimizationOverrides
  291. };
  292. enum NumberAllocatorValue {
  293. NumberAllocatorEndAddress,
  294. NumberAllocatorFreeObjectList
  295. };