BackendApi.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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 IntMath<IntConstType>::Type IntConstMath;
  35. typedef double FloatConstType;
  36. #include "EmitBuffer.h"
  37. #include "InterpreterThunkEmitter.h"
  38. #include "JITThunkEmitter.h"
  39. #include "BackendOpCodeAttr.h"
  40. #include "BackendOpCodeAttrAsmJs.h"
  41. #include "CodeGenNumberAllocator.h"
  42. #include "NativeCodeData.h"
  43. #include "JnHelperMethod.h"
  44. #include "IRType.h"
  45. #include "InlineeFrameInfo.h"
  46. #include "CodeGenAllocators.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. BOOL IsIntermediateCodeGenThunk(Js::JavascriptMethod codeAddress);
  67. BOOL IsAsmJsCodeGenThunk(Js::JavascriptMethod codeAddress);
  68. typedef Js::JavascriptMethod (*CheckCodeGenFunction)(Js::ScriptFunction * function);
  69. CheckCodeGenFunction GetCheckCodeGenFunction(Js::JavascriptMethod codeAddress);
  70. Js::JavascriptMethod GetCheckCodeGenThunk();
  71. #ifdef ASMJS_PLAT
  72. Js::JavascriptMethod GetCheckAsmJsCodeGenThunk();
  73. #endif
  74. uint GetBailOutRegisterSaveSlotCount();
  75. uint GetBailOutReserveSlotCount();
  76. #if DBG
  77. void CheckIsExecutable(Js::RecyclableObject * function, Js::JavascriptMethod entryPoint);
  78. #endif
  79. #ifdef PROFILE_EXEC
  80. namespace Js
  81. {
  82. class ScriptContextProfiler;
  83. };
  84. void CreateProfilerNativeCodeGen(NativeCodeGenerator * nativeCodeGen, Js::ScriptContextProfiler * profiler);
  85. void ProfilePrintNativeCodeGen(NativeCodeGenerator * nativeCodeGen);
  86. void SetProfilerFromNativeCodeGen(NativeCodeGenerator * toNativeCodeGen, NativeCodeGenerator * fromNativeCodeGen);
  87. #endif
  88. void DeleteNativeCodeData(NativeCodeData * data);
  89. #else
  90. inline BOOL IsIntermediateCodeGenThunk(Js::JavascriptMethod codeAddress) { return false; }
  91. inline BOOL IsAsmJsCodeGenThunk(Js::JavascriptMethod codeAddress) { return false; }
  92. #endif
  93. #if _M_X64
  94. extern "C" void * amd64_ReturnFromCallWithFakeFrame();
  95. #endif
  96. struct InlinedFrameLayout
  97. {
  98. Js::InlineeCallInfo callInfo;
  99. Js::JavascriptFunction *function;
  100. Js::Var arguments; // The arguments object.
  101. //Js::Var argv[0]; // Here it would be embedded arguments array (callInfo.count elements)
  102. // but can't have 0-size arr in base class, so we define it in derived class.
  103. Js::Var* GetArguments()
  104. {
  105. return (Js::Var*)(this + 1);
  106. }
  107. template<class Fn>
  108. void MapArgs(Fn callback)
  109. {
  110. Js::Var* arguments = this->GetArguments();
  111. for (uint i = 0; i < callInfo.Count; i++)
  112. {
  113. callback(i, (Js::Var*)((uintptr_t*)arguments + i));
  114. }
  115. }
  116. InlinedFrameLayout* Next()
  117. {
  118. InlinedFrameLayout *next = (InlinedFrameLayout *)(this->GetArguments() + this->callInfo.Count);
  119. return next;
  120. }
  121. };
  122. class BailOutRecord;
  123. struct LazyBailOutRecord
  124. {
  125. uint32 offset;
  126. BYTE* instructionPointer; // Instruction pointer of the bailout code
  127. BailOutRecord* bailoutRecord;
  128. LazyBailOutRecord() : offset(0), instructionPointer(nullptr), bailoutRecord(nullptr) {}
  129. LazyBailOutRecord(uint32 offset, BYTE* address, BailOutRecord* record) :
  130. offset(offset), instructionPointer(address),
  131. bailoutRecord(record)
  132. {}
  133. void SetBailOutKind();
  134. #if DBG
  135. void Dump(Js::FunctionBody* functionBody);
  136. #endif
  137. };
  138. struct StackFrameConstants
  139. {
  140. #if defined(_M_IX86)
  141. static const size_t StackCheckCodeHeightThreadBound = 35;
  142. static const size_t StackCheckCodeHeightNotThreadBound = 47;
  143. static const size_t StackCheckCodeHeightWithInterruptProbe = 53;
  144. #elif defined(_M_X64)
  145. static const size_t StackCheckCodeHeightThreadBound = 57;
  146. static const size_t StackCheckCodeHeightNotThreadBound = 62;
  147. static const size_t StackCheckCodeHeightWithInterruptProbe = 68;
  148. #elif defined(_M_ARM)
  149. static const size_t StackCheckCodeHeight = 64;
  150. static const size_t StackCheckCodeHeightThreadBound = StackFrameConstants::StackCheckCodeHeight;
  151. static const size_t StackCheckCodeHeightNotThreadBound = StackFrameConstants::StackCheckCodeHeight;
  152. static const size_t StackCheckCodeHeightWithInterruptProbe = StackFrameConstants::StackCheckCodeHeight;
  153. #elif defined(_M_ARM64)
  154. static const size_t StackCheckCodeHeight = 58*2;
  155. static const size_t StackCheckCodeHeightThreadBound = StackFrameConstants::StackCheckCodeHeight;
  156. static const size_t StackCheckCodeHeightNotThreadBound = StackFrameConstants::StackCheckCodeHeight;
  157. static const size_t StackCheckCodeHeightWithInterruptProbe = StackFrameConstants::StackCheckCodeHeight;
  158. #endif
  159. };
  160. struct NativeResourceIds
  161. {
  162. static const short SourceCodeResourceNameId = 0x64;
  163. static const short ByteCodeResourceNameId = 0x65;
  164. static const short NativeMapResourceNameId = 0x66;
  165. static const short NativeThrowMapResourceNameId = 0x67;
  166. };
  167. #if defined(_M_IX86)
  168. struct ThunkConstants
  169. {
  170. static const size_t ThunkInstructionSize = 2;
  171. static const size_t ThunkSize = 6;
  172. };
  173. #endif
  174. enum LibraryValue {
  175. ValueInvalid,
  176. ValueUndeclBlockVar,
  177. ValueEmptyString,
  178. ValueUndefined,
  179. ValueNull,
  180. ValueTrue,
  181. ValueFalse,
  182. ValueNegativeZero,
  183. ValueNumberTypeStatic,
  184. ValueStringTypeStatic,
  185. ValueObjectType,
  186. ValueObjectHeaderInlinedType,
  187. ValueRegexType,
  188. ValueArrayConstructor,
  189. ValuePositiveInfinity,
  190. ValueNaN,
  191. ValueJavascriptArrayType,
  192. ValueNativeIntArrayType,
  193. ValueNativeFloatArrayType,
  194. ValueConstructorCacheDefaultInstance,
  195. ValueAbsDoubleCst,
  196. ValueUintConvertConst,
  197. ValueBuiltinFunctions,
  198. ValueJnHelperMethods,
  199. ValueCharStringCache
  200. };
  201. enum VTableValue {
  202. //#if !_M_X64 TODO: OOP JIT, can we make this arch specific again?
  203. VtableJavascriptNumber,
  204. //#endif
  205. VtableDynamicObject,
  206. VtableInvalid,
  207. VtablePropertyString,
  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. VtableConcatStringMulti,
  246. VtableCompoundString,
  247. // SIMD_JS
  248. VtableSimd128F4,
  249. VtableSimd128I4,
  250. VtableSimd128I8,
  251. VtableSimd128I16,
  252. VtableSimd128U4,
  253. VtableSimd128U8,
  254. VtableSimd128U16,
  255. Count
  256. };
  257. #if DBG_DUMP || defined(ENABLE_IR_VIEWER)
  258. const char16 *GetVtableName(VTableValue value);
  259. #endif
  260. enum AuxArrayValue {
  261. AuxPropertyIdArray,
  262. AuxIntArray,
  263. AuxFloatArray,
  264. AuxVarsArray,
  265. AuxVarArrayVarCount,
  266. AuxFuncInfoArray
  267. };
  268. enum OptimizationOverridesValue {
  269. OptimizationOverridesArraySetElementFastPathVtable,
  270. OptimizationOverridesIntArraySetElementFastPathVtable,
  271. OptimizationOverridesFloatArraySetElementFastPathVtable,
  272. OptimizationOverridesSideEffects
  273. };
  274. enum FunctionBodyValue {
  275. FunctionBodyConstantVar,
  276. FunctionBodyNestedFuncReference,
  277. FunctionBodyReferencedPropertyId,
  278. FunctionBodyPropertyIdFromCacheId,
  279. FunctionBodyLiteralRegex,
  280. FunctionBodyStringTemplateCallsiteRef
  281. };
  282. enum ScriptContextValue {
  283. ScriptContextNumberAllocator,
  284. ScriptContextCharStringCache,
  285. ScriptContextRecycler,
  286. ScriptContextOptimizationOverrides
  287. };
  288. enum NumberAllocatorValue {
  289. NumberAllocatorEndAddress,
  290. NumberAllocatorFreeObjectList
  291. };