JITTimeWorkItem.cpp 5.8 KB

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