InlineeFrameInfo.h 5.5 KB

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