BackendApi.h 10 KB

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