InlineeFrameInfo.h 6.1 KB

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