JITTimeWorkItem.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. #include "Backend.h"
  6. JITTimeWorkItem::JITTimeWorkItem(CodeGenWorkItemIDL * workItemData) :
  7. m_workItemData(workItemData),
  8. m_jitBody(workItemData->jitData->bodyData),
  9. m_fullStatementList(nullptr)
  10. {
  11. }
  12. CodeGenWorkItemType
  13. JITTimeWorkItem::Type() const
  14. {
  15. return static_cast<CodeGenWorkItemType>(m_workItemData->type);
  16. }
  17. ExecutionMode
  18. JITTimeWorkItem::GetJitMode() const
  19. {
  20. return static_cast<ExecutionMode>(m_workItemData->jitMode);
  21. }
  22. // loop number if IsLoopBody, otherwise Js::LoopHeader::NoLoop
  23. uint
  24. JITTimeWorkItem::GetLoopNumber() const
  25. {
  26. Assert(IsLoopBody() || m_workItemData->loopNumber == Js::LoopHeader::NoLoop);
  27. return m_workItemData->loopNumber;
  28. }
  29. bool
  30. JITTimeWorkItem::IsLoopBody() const
  31. {
  32. return Type() == JsLoopBodyWorkItemType;
  33. }
  34. bool
  35. JITTimeWorkItem::IsJitInDebugMode() const
  36. {
  37. return m_workItemData->isJitInDebugMode;
  38. }
  39. intptr_t
  40. JITTimeWorkItem::GetCallsCountAddress() const
  41. {
  42. Assert(Type() == JsFunctionType);
  43. return m_workItemData->jitData->callsCountAddress;
  44. }
  45. intptr_t
  46. JITTimeWorkItem::GetJittedLoopIterationsSinceLastBailoutAddr() const
  47. {
  48. Assert(IsLoopBody());
  49. Assert(m_workItemData->jittedLoopIterationsSinceLastBailoutAddr != 0);
  50. return m_workItemData->jittedLoopIterationsSinceLastBailoutAddr;
  51. }
  52. const JITLoopHeaderIDL *
  53. JITTimeWorkItem::GetLoopHeader() const
  54. {
  55. return m_jitBody.GetLoopHeaderData(GetLoopNumber());
  56. }
  57. intptr_t
  58. JITTimeWorkItem::GetLoopHeaderAddr() const
  59. {
  60. return m_jitBody.GetLoopHeaderAddr(GetLoopNumber());
  61. }
  62. void
  63. JITTimeWorkItem::InitializeReader(
  64. Js::ByteCodeReader * reader,
  65. Js::StatementReader<Js::FunctionBody::ArenaStatementMapList> * statementReader, ArenaAllocator* alloc)
  66. {
  67. uint startOffset = IsLoopBody() ? GetLoopHeader()->startOffset : 0;
  68. if (IsJitInDebugMode())
  69. {
  70. // TODO: OOP JIT, directly use the array rather than making a list
  71. m_fullStatementList = Js::FunctionBody::ArenaStatementMapList::New(alloc);
  72. CompileAssert(sizeof(StatementMapIDL) == sizeof(Js::FunctionBody::StatementMap));
  73. StatementMapIDL * fullArr = m_jitBody.GetFullStatementMap();
  74. for (uint i = 0; i < m_jitBody.GetFullStatementMapCount(); ++i)
  75. {
  76. m_fullStatementList->Add((Js::FunctionBody::StatementMap*)&fullArr[i]);
  77. }
  78. }
  79. #if DBG
  80. reader->Create(m_jitBody.GetByteCodeBuffer(), startOffset, m_jitBody.GetByteCodeLength());
  81. if (!JITManager::GetJITManager()->IsOOPJITEnabled())
  82. {
  83. Js::FunctionBody::StatementMapList * runtimeMap = ((Js::FunctionBody*)m_jitBody.GetAddr())->GetStatementMaps();
  84. Assert(!m_fullStatementList || ((int)m_jitBody.GetFullStatementMapCount() == runtimeMap->Count() && runtimeMap->Count() >= 0));
  85. for (uint i = 0; i < m_jitBody.GetFullStatementMapCount(); ++i)
  86. {
  87. Assert(runtimeMap->Item(i)->byteCodeSpan.begin == m_fullStatementList->Item(i)->byteCodeSpan.begin);
  88. Assert(runtimeMap->Item(i)->byteCodeSpan.end == m_fullStatementList->Item(i)->byteCodeSpan.end);
  89. Assert(runtimeMap->Item(i)->sourceSpan.begin == m_fullStatementList->Item(i)->sourceSpan.begin);
  90. Assert(runtimeMap->Item(i)->sourceSpan.end == m_fullStatementList->Item(i)->sourceSpan.end);
  91. Assert(runtimeMap->Item(i)->isSubexpression == m_fullStatementList->Item(i)->isSubexpression);
  92. }
  93. }
  94. #else
  95. reader->Create(m_jitBody.GetByteCodeBuffer(), startOffset);
  96. #endif
  97. bool hasSpanSequenceMap = m_jitBody.InitializeStatementMap(&m_statementMap, alloc);
  98. Js::SmallSpanSequence * spanSeq = hasSpanSequenceMap ? &m_statementMap : nullptr;
  99. if (statementReader)
  100. {
  101. statementReader->Create(m_jitBody.GetByteCodeBuffer(), startOffset, spanSeq, m_fullStatementList);
  102. }
  103. }
  104. JITTimeFunctionBody *
  105. JITTimeWorkItem::GetJITFunctionBody()
  106. {
  107. return &m_jitBody;
  108. }
  109. uint16
  110. JITTimeWorkItem::GetProfiledIterations() const
  111. {
  112. return m_workItemData->profiledIterations;
  113. }
  114. CodeGenWorkItemIDL *
  115. JITTimeWorkItem::GetWorkItemData()
  116. {
  117. return m_workItemData;
  118. }
  119. JITTimePolymorphicInlineCacheInfo *
  120. JITTimeWorkItem::GetPolymorphicInlineCacheInfo()
  121. {
  122. return (JITTimePolymorphicInlineCacheInfo *)m_workItemData->selfInfo;
  123. }
  124. JITTimePolymorphicInlineCacheInfo *
  125. JITTimeWorkItem::GetInlineePolymorphicInlineCacheInfo(intptr_t funcBodyAddr)
  126. {
  127. for (uint i = 0; i < m_workItemData->inlineeInfoCount; ++i)
  128. {
  129. if (m_workItemData->inlineeInfo[i].functionBodyAddr == (void*)funcBodyAddr)
  130. {
  131. return (JITTimePolymorphicInlineCacheInfo *)&m_workItemData->inlineeInfo[i];
  132. }
  133. }
  134. return nullptr;
  135. }
  136. void
  137. JITTimeWorkItem::SetJITTimeData(FunctionJITTimeDataIDL * jitData)
  138. {
  139. m_workItemData->jitData = jitData;
  140. }
  141. FunctionJITTimeInfo *
  142. JITTimeWorkItem::GetJITTimeInfo() const
  143. {
  144. return reinterpret_cast<FunctionJITTimeInfo *>(m_workItemData->jitData);
  145. }
  146. bool
  147. JITTimeWorkItem::HasSymIdToValueTypeMap() const
  148. {
  149. return m_workItemData->symIdToValueTypeMap != nullptr;
  150. }
  151. bool
  152. JITTimeWorkItem::TryGetValueType(uint symId, ValueType * valueType) const
  153. {
  154. Assert(IsLoopBody());
  155. uint index = symId - m_jitBody.GetConstCount();
  156. if (symId >= m_jitBody.GetConstCount() && index < m_workItemData->symIdToValueTypeMapCount)
  157. {
  158. ValueType type = ((ValueType*)m_workItemData->symIdToValueTypeMap)[index];
  159. if (type.GetRawData() != 0)
  160. {
  161. *valueType = type;
  162. return true;
  163. }
  164. }
  165. return false;
  166. }