InlineeFrameInfo.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  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. struct BailoutConstantValue {
  7. public:
  8. void InitIntConstValue(int32 value) { this->type = TyInt32; this->u.intConst.value = (IntConstType)value; };
  9. void InitIntConstValue(IntConstType value, IRType type) {
  10. Assert(IRType_IsSignedInt(type));
  11. this->type = type; this->u.intConst.value = value;
  12. };
  13. void InitVarConstValue(Js::Var value);
  14. void InitFloatConstValue(FloatConstType value) { this->type = TyFloat64; this->u.floatConst.value = value; }
  15. bool IsEqual(const BailoutConstantValue & bailoutConstValue);
  16. public:
  17. IRType type;
  18. union
  19. {
  20. struct sIntConst
  21. {
  22. IntConstType value;
  23. } intConst;
  24. struct sVarConst
  25. {
  26. Js::Var value;
  27. } varConst;
  28. struct sFloatConst
  29. {
  30. FloatConstType value;
  31. } floatConst;
  32. } u;
  33. Js::Var ToVar(Func* func) const;
  34. };
  35. enum InlineeFrameInfoValueType
  36. {
  37. InlineeFrameInfoValueType_None,
  38. InlineeFrameInfoValueType_Sym,
  39. InlineeFrameInfoValueType_Const
  40. };
  41. struct InlineFrameInfoValue
  42. {
  43. InlineeFrameInfoValueType type;
  44. union
  45. {
  46. StackSym* sym;
  47. BailoutConstantValue constValue;
  48. };
  49. bool IsConst() { return this->type == InlineeFrameInfoValueType_Const; }
  50. InlineFrameInfoValue() : type(InlineeFrameInfoValueType_None), sym(nullptr) {}
  51. InlineFrameInfoValue(StackSym* sym) : type(InlineeFrameInfoValueType_Sym), sym(sym) {}
  52. InlineFrameInfoValue(BailoutConstantValue value) : type(InlineeFrameInfoValueType_Const), constValue(value) {}
  53. };
  54. struct InlineeFrameInfo;
  55. struct InlineeFrameRecord
  56. {
  57. int functionOffset;
  58. int inlineDepth;
  59. uint inlineeStartOffset;
  60. int* argOffsets;
  61. Js::Var * constants;
  62. InlineeFrameRecord* parent;
  63. uint argCount;
  64. BVUnit floatArgs;
  65. BVUnit losslessInt32Args;
  66. template<class Fnc>
  67. void MapOffsets(Fnc callback)
  68. {
  69. callback(functionOffset);
  70. for (uint i = 0; i < argCount; i++)
  71. {
  72. callback(argOffsets[i]);
  73. }
  74. }
  75. #if DBG_DUMP
  76. uint constantCount;
  77. Js::FunctionBody* functionBody;
  78. InlineeFrameInfo* frameInfo;
  79. #endif
  80. // Fields are zero initialized any way
  81. InlineeFrameRecord(uint argCount, Js::FunctionBody* functionBody, InlineeFrameInfo* frameInfo) : argCount(argCount)
  82. #if DBG_DUMP
  83. , functionBody(functionBody)
  84. , frameInfo(frameInfo)
  85. #endif
  86. {}
  87. static InlineeFrameRecord* New(NativeCodeData::Allocator* alloc, uint argCount, uint constantCount, intptr_t functionBodyAddr, InlineeFrameInfo* frameInfo)
  88. {
  89. InlineeFrameRecord* record = NativeCodeDataNewZ(alloc, InlineeFrameRecord, argCount, (Js::FunctionBody*)functionBodyAddr, frameInfo);
  90. record->argOffsets = (int*)NativeCodeDataNewArrayNoFixup(alloc, IntType<DataDesc_InlineeFrameRecord_ArgOffsets>, argCount);
  91. record->constants = (Js::Var*)NativeCodeDataNewArrayNoFixup(alloc, VarType<DataDesc_InlineeFrameRecord_Constants>, constantCount);
  92. DebugOnly(record->constantCount = constantCount);
  93. return record;
  94. }
  95. void PopulateParent(Func* func);
  96. void RestoreFrames(Js::FunctionBody* functionBody, InlinedFrameLayout* outerMostInlinee, Js::JavascriptCallStackLayout* callstack);
  97. void Finalize(Func* inlinee, uint currentOffset);
  98. #if DBG_DUMP
  99. void Dump() const;
  100. void DumpOffset(int offset) const;
  101. #endif
  102. void Fixup(NativeCodeData::DataChunk* chunkList)
  103. {
  104. FixupNativeDataPointer(argOffsets, chunkList);
  105. FixupNativeDataPointer(constants, chunkList);
  106. FixupNativeDataPointer(parent, chunkList);
  107. }
  108. private:
  109. void Restore(Js::FunctionBody* functionBody, InlinedFrameLayout *outerMostFrame, Js::JavascriptCallStackLayout * layout) const;
  110. Js::Var Restore(int offset, bool isFloat64, bool isInt32, Js::JavascriptCallStackLayout * layout, Js::FunctionBody* functionBody) const;
  111. InlineeFrameRecord* Reverse();
  112. };
  113. struct NativeOffsetInlineeFramePair
  114. {
  115. uint32 offset;
  116. InlineeFrameRecord* record;
  117. };
  118. struct NativeOffsetInlineeFrameRecordOffset
  119. {
  120. uint32 offset;
  121. uint32 recordOffset;
  122. static uint32 InvalidRecordOffset;
  123. };
  124. struct InlineeFrameInfo
  125. {
  126. typedef JsUtil::List<InlineFrameInfoValue, JitArenaAllocator, /*isLeaf*/ false> ArgList;
  127. InlineFrameInfoValue function;
  128. ArgList* arguments;
  129. InlineeFrameRecord* record;
  130. BVSparse<JitArenaAllocator>* floatSyms;
  131. BVSparse<JitArenaAllocator>* intSyms;
  132. #ifdef ENABLE_SIMDJS
  133. BVSparse<JitArenaAllocator>* simd128F4Syms;
  134. BVSparse<JitArenaAllocator>* simd128I4Syms;
  135. BVSparse<JitArenaAllocator>* simd128I8Syms;
  136. BVSparse<JitArenaAllocator>* simd128I16Syms;
  137. BVSparse<JitArenaAllocator>* simd128U4Syms;
  138. BVSparse<JitArenaAllocator>* simd128U8Syms;
  139. BVSparse<JitArenaAllocator>* simd128U16Syms;
  140. #endif
  141. bool isRecorded;
  142. static InlineeFrameInfo* New(JitArenaAllocator* alloc)
  143. {
  144. InlineeFrameInfo* frameInfo = JitAnewStructZ(alloc, InlineeFrameInfo);
  145. frameInfo->arguments = JitAnew(alloc, ArgList, alloc);
  146. return frameInfo;
  147. }
  148. template<class Fn>
  149. void IterateSyms(Fn callback, bool inReverse = false)
  150. {
  151. auto iterator = [=](uint index, InlineFrameInfoValue& value)
  152. {
  153. if (value.type == InlineeFrameInfoValueType_Sym)
  154. {
  155. callback(value.sym);
  156. }
  157. Assert(value.type != InlineeFrameInfoValueType_None);
  158. };
  159. if (inReverse && function.type == InlineeFrameInfoValueType_Sym)
  160. {
  161. callback(function.sym);
  162. }
  163. if (inReverse)
  164. {
  165. arguments->ReverseMap(iterator);
  166. }
  167. else
  168. {
  169. arguments->Map(iterator);
  170. }
  171. Assert(function.type != InlineeFrameInfoValueType_None);
  172. if (!inReverse && function.type == InlineeFrameInfoValueType_Sym)
  173. {
  174. callback(function.sym);
  175. }
  176. }
  177. void AllocateRecord(Func* func, intptr_t functionBodyAddr);
  178. #if DBG_DUMP
  179. void Dump() const;
  180. #endif
  181. };