BackendApi.h 11 KB

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