BackendApi.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  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. #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. #define ProfileDeferredParsingThunk Js::ScriptContext::ProfileModeDeferredParsingThunk
  19. #define DefaultDeferredDeserializeThunk Js::JavascriptFunction::DeferredDeserializeThunk
  20. #define ProfileDeferredDeserializeThunk Js::ScriptContext::ProfileModeDeferredDeserializeThunk
  21. #if ENABLE_NATIVE_CODEGEN
  22. class NativeCodeGenerator;
  23. class ThreadContext;
  24. struct CodeGenWorkItem;
  25. class NativeCodeData;
  26. class StackSym;
  27. class Func;
  28. struct InlinedFrameLayout;
  29. typedef intptr_t IntConstType;
  30. typedef uintptr_t UIntConstType;
  31. typedef IntMath<intptr_t>::Type IntConstMath;
  32. typedef double FloatConstType;
  33. #include "EmitBuffer.h"
  34. #include "InterpreterThunkEmitter.h"
  35. #include "BackendOpCodeAttr.h"
  36. #include "BackendOpCodeAttrAsmJs.h"
  37. #include "CodeGenNumberAllocator.h"
  38. #include "NativeCodeData.h"
  39. #include "JnHelperMethod.h"
  40. #include "IRType.h"
  41. #include "InlineeFrameInfo.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, void* address);
  52. CodeGenAllocators* 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. BOOL IsIntermediateCodeGenThunk(Js::JavascriptMethod codeAddress);
  62. BOOL IsAsmJsCodeGenThunk(Js::JavascriptMethod codeAddress);
  63. typedef Js::JavascriptMethod (*CheckCodeGenFunction)(Js::ScriptFunction * function);
  64. CheckCodeGenFunction GetCheckCodeGenFunction(Js::JavascriptMethod codeAddress);
  65. uint GetBailOutRegisterSaveSlotCount();
  66. uint GetBailOutReserveSlotCount();
  67. #if DBG
  68. void CheckIsExecutable(Js::RecyclableObject * function, Js::JavascriptMethod entryPoint);
  69. #endif
  70. #ifdef PROFILE_EXEC
  71. namespace Js
  72. {
  73. class ScriptContextProfiler;
  74. };
  75. void CreateProfilerNativeCodeGen(NativeCodeGenerator * nativeCodeGen, Js::ScriptContextProfiler * profiler);
  76. void ProfilePrintNativeCodeGen(NativeCodeGenerator * nativeCodeGen);
  77. void SetProfilerFromNativeCodeGen(NativeCodeGenerator * toNativeCodeGen, NativeCodeGenerator * fromNativeCodeGen);
  78. #endif
  79. void DeleteNativeCodeData(NativeCodeData * data);
  80. #else
  81. inline BOOL IsIntermediateCodeGenThunk(Js::JavascriptMethod codeAddress) { return false; }
  82. inline BOOL IsAsmJsCodeGenThunk(Js::JavascriptMethod codeAddress) { return false; }
  83. #endif
  84. #if _M_X64
  85. extern "C" void * amd64_ReturnFromCallWithFakeFrame();
  86. #endif
  87. struct InlinedFrameLayout
  88. {
  89. Js::InlineeCallInfo callInfo;
  90. Js::JavascriptFunction *function;
  91. Js::Var arguments; // The arguments object.
  92. //Js::Var argv[0]; // Here it would be embedded arguments array (callInfo.count elements)
  93. // but can't have 0-size arr in base class, so we define it in derived class.
  94. Js::Var* GetArguments()
  95. {
  96. return (Js::Var*)(this + 1);
  97. }
  98. template<class Fn>
  99. void MapArgs(Fn callback)
  100. {
  101. Js::Var* arguments = this->GetArguments();
  102. for (uint i = 0; i < callInfo.Count; i++)
  103. {
  104. callback(i, (Js::Var*)((uintptr_t*)arguments + i));
  105. }
  106. }
  107. InlinedFrameLayout* Next()
  108. {
  109. InlinedFrameLayout *next = (InlinedFrameLayout *)(this->GetArguments() + this->callInfo.Count);
  110. return next;
  111. }
  112. };
  113. class BailOutRecord;
  114. struct LazyBailOutRecord
  115. {
  116. uint32 offset;
  117. BYTE* instructionPointer; // Instruction pointer of the bailout code
  118. BailOutRecord* bailoutRecord;
  119. LazyBailOutRecord() : offset(0), instructionPointer(nullptr), bailoutRecord(nullptr) {}
  120. LazyBailOutRecord(uint32 offset, BYTE* address, BailOutRecord* record) :
  121. offset(offset), instructionPointer(address),
  122. bailoutRecord(record)
  123. {}
  124. void SetBailOutKind();
  125. #if DBG
  126. void Dump(Js::FunctionBody* functionBody);
  127. #endif
  128. };
  129. struct StackFrameConstants
  130. {
  131. #if defined(_M_IX86)
  132. static const size_t StackCheckCodeHeightThreadBound = 35;
  133. static const size_t StackCheckCodeHeightNotThreadBound = 47;
  134. static const size_t StackCheckCodeHeightWithInterruptProbe = 53;
  135. #elif defined(_M_X64)
  136. static const size_t StackCheckCodeHeightThreadBound = 57;
  137. static const size_t StackCheckCodeHeightNotThreadBound = 62;
  138. static const size_t StackCheckCodeHeightWithInterruptProbe = 68;
  139. #elif defined(_M_ARM)
  140. static const size_t StackCheckCodeHeight = 64;
  141. static const size_t StackCheckCodeHeightThreadBound = StackFrameConstants::StackCheckCodeHeight;
  142. static const size_t StackCheckCodeHeightNotThreadBound = StackFrameConstants::StackCheckCodeHeight;
  143. static const size_t StackCheckCodeHeightWithInterruptProbe = StackFrameConstants::StackCheckCodeHeight;
  144. #elif defined(_M_ARM64)
  145. static const size_t StackCheckCodeHeight = 58*2;
  146. static const size_t StackCheckCodeHeightThreadBound = StackFrameConstants::StackCheckCodeHeight;
  147. static const size_t StackCheckCodeHeightNotThreadBound = StackFrameConstants::StackCheckCodeHeight;
  148. static const size_t StackCheckCodeHeightWithInterruptProbe = StackFrameConstants::StackCheckCodeHeight;
  149. #endif
  150. };
  151. struct NativeResourceIds
  152. {
  153. static const short SourceCodeResourceNameId = 0x64;
  154. static const short ByteCodeResourceNameId = 0x65;
  155. static const short NativeMapResourceNameId = 0x66;
  156. static const short NativeThrowMapResourceNameId = 0x67;
  157. };
  158. #if defined(_M_IX86)
  159. struct ThunkConstants
  160. {
  161. static const size_t ThunkInstructionSize = 2;
  162. static const size_t ThunkSize = 6;
  163. };
  164. #endif
  165. enum LibraryValue {
  166. ValueInvalid,
  167. ValueUndeclBlockVar,
  168. ValueEmptyString,
  169. ValueUndefined,
  170. ValueNull,
  171. ValueTrue,
  172. ValueFalse,
  173. ValueNegativeZero,
  174. ValueNumberTypeStatic,
  175. ValueStringTypeStatic,
  176. ValueObjectType,
  177. ValueObjectHeaderInlinedType,
  178. ValueRegexType,
  179. ValueArrayConstructor,
  180. ValuePositiveInfinity,
  181. ValueNaN,
  182. ValueJavascriptArrayType,
  183. ValueNativeIntArrayType,
  184. ValueNativeFloatArrayType,
  185. ValueConstructorCacheDefaultInstance,
  186. ValueAbsDoubleCst,
  187. ValueUintConvertConst,
  188. ValueBuiltinFunctions,
  189. ValueJnHelperMethods,
  190. ValueCharStringCache
  191. };
  192. enum VTableValue {
  193. #if !_M_X64
  194. VtableJavascriptNumber,
  195. #endif
  196. VtableDynamicObject,
  197. VtableInvalid,
  198. VtablePropertyString,
  199. VtableJavascriptBoolean,
  200. VtableSmallDynamicObjectSnapshotEnumeratorWPCache,
  201. VtableJavascriptArray,
  202. VtableInt8Array,
  203. VtableUint8Array,
  204. VtableUint8ClampedArray,
  205. VtableInt16Array,
  206. VtableUint16Array,
  207. VtableInt32Array,
  208. VtableUint32Array,
  209. VtableFloat32Array,
  210. VtableFloat64Array,
  211. VtableJavascriptPixelArray,
  212. VtableInt64Array,
  213. VtableUint64Array,
  214. VtableBoolArray,
  215. VtableCharArray,
  216. VtableInt8VirtualArray,
  217. VtableUint8VirtualArray,
  218. VtableUint8ClampedVirtualArray,
  219. VtableInt16VirtualArray,
  220. VtableUint16VirtualArray,
  221. VtableInt32VirtualArray,
  222. VtableUint32VirtualArray,
  223. VtableFloat32VirtualArray,
  224. VtableFloat64VirtualArray,
  225. VtableNativeIntArray,
  226. #if ENABLE_COPYONACCESS_ARRAY
  227. VtableCopyOnAccessNativeIntArray,
  228. #endif
  229. VtableNativeFloatArray,
  230. VtableJavascriptNativeIntArray,
  231. VtableJavascriptRegExp,
  232. VtableStackScriptFunction,
  233. VtableConcatStringMulti,
  234. VtableCompoundString,
  235. // SIMD_JS
  236. VtableSimd128F4,
  237. VtableSimd128I4,
  238. Count
  239. };
  240. #if DBG_DUMP || defined(ENABLE_IR_VIEWER)
  241. const wchar_t *GetVtableName(VTableValue value);
  242. #endif
  243. enum AuxArrayValue {
  244. AuxPropertyIdArray,
  245. AuxIntArray,
  246. AuxFloatArray,
  247. AuxVarsArray,
  248. AuxVarArrayVarCount,
  249. AuxFuncInfoArray
  250. };
  251. enum OptimizationOverridesValue {
  252. OptimizationOverridesArraySetElementFastPathVtable,
  253. OptimizationOverridesIntArraySetElementFastPathVtable,
  254. OptimizationOverridesFloatArraySetElementFastPathVtable,
  255. OptimizationOverridesSideEffects
  256. };
  257. enum FunctionBodyValue {
  258. FunctionBodyConstantVar,
  259. FunctionBodyNestedFuncReference,
  260. FunctionBodyReferencedPropertyId,
  261. FunctionBodyPropertyIdFromCacheId,
  262. FunctionBodyLiteralRegex,
  263. FunctionBodyStringTemplateCallsiteRef
  264. };
  265. enum ScriptContextValue {
  266. ScriptContextNumberAllocator,
  267. ScriptContextCharStringCache,
  268. ScriptContextRecycler,
  269. ScriptContextOptimizationOverrides
  270. };
  271. enum NumberAllocatorValue {
  272. NumberAllocatorEndAddress,
  273. NumberAllocatorFreeObjectList
  274. };