Engine.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #include "Engine.h"
  2. #include "codegen/il2cpp-codegen.h"
  3. #include "Interpreter.h"
  4. #include "MemoryUtil.h"
  5. #include "../metadata/InterpreterImage.h"
  6. #include "../metadata/MetadataModule.h"
  7. namespace hybridclr
  8. {
  9. namespace interpreter
  10. {
  11. #if HYBRIDCLR_ENABLE_STRACKTRACE
  12. #define PUSH_STACK_FRAME(method, rawIp) do { \
  13. Il2CppStackFrameInfo stackFrameInfo = { method, rawIp }; \
  14. il2cpp::vm::StackTrace::PushFrame(stackFrameInfo); \
  15. } while(0)
  16. #define POP_STACK_FRAME() do { il2cpp::vm::StackTrace::PopFrame(); } while(0)
  17. #else
  18. #define PUSH_STACK_FRAME(method, rawIp)
  19. #define POP_STACK_FRAME()
  20. #endif
  21. InterpFrame* InterpFrameGroup::EnterFrameFromInterpreter(const MethodInfo* method, StackObject* argBase)
  22. {
  23. #if HYBRIDCLR_ENABLE_PROFILER
  24. il2cpp_codegen_profiler_method_enter(method);
  25. #endif
  26. const InterpMethodInfo* imi = (const InterpMethodInfo*)method->interpData;
  27. int32_t oldStackTop = _machineState.GetStackTop();
  28. StackObject* stackBasePtr = _machineState.AllocStackSlot(imi->maxStackSize - imi->argStackObjectSize);
  29. InterpFrame* newFrame = _machineState.PushFrame();
  30. *newFrame = { method, argBase, oldStackTop, nullptr, nullptr, nullptr, 0, 0, _machineState.GetLocalPoolBottomIdx() };
  31. PUSH_STACK_FRAME(method, (uintptr_t)newFrame);
  32. return newFrame;
  33. }
  34. InterpFrame* InterpFrameGroup::EnterFrameFromNative(const MethodInfo* method, StackObject* argBase)
  35. {
  36. #if HYBRIDCLR_ENABLE_PROFILER
  37. il2cpp_codegen_profiler_method_enter(method);
  38. #endif
  39. const InterpMethodInfo* imi = (const InterpMethodInfo*)method->interpData;
  40. int32_t oldStackTop = _machineState.GetStackTop();
  41. StackObject* stackBasePtr = _machineState.AllocStackSlot(imi->maxStackSize);
  42. InterpFrame* newFrame = _machineState.PushFrame();
  43. *newFrame = { method, stackBasePtr, oldStackTop, nullptr, nullptr, nullptr, 0, 0, _machineState.GetLocalPoolBottomIdx() };
  44. // if not prepare arg stack. copy from args
  45. if (imi->args)
  46. {
  47. IL2CPP_ASSERT(imi->argCount == metadata::GetActualArgumentNum(method));
  48. CopyStackObject(stackBasePtr, argBase, imi->argStackObjectSize);
  49. }
  50. PUSH_STACK_FRAME(method, (uintptr_t)newFrame);
  51. return newFrame;
  52. }
  53. InterpFrame* InterpFrameGroup::LeaveFrame()
  54. {
  55. IL2CPP_ASSERT(_machineState.GetFrameTopIdx() > _frameBaseIdx);
  56. POP_STACK_FRAME();
  57. InterpFrame* frame = _machineState.GetTopFrame();
  58. #if HYBRIDCLR_ENABLE_PROFILER
  59. il2cpp_codegen_profiler_method_exit(frame->method);
  60. #endif
  61. if (frame->exFlowBase)
  62. {
  63. _machineState.SetExceptionFlowTop(frame->exFlowBase);
  64. }
  65. _machineState.PopFrame();
  66. _machineState.SetStackTop(frame->oldStackTop);
  67. _machineState.SetLocalPoolBottomIdx(frame->oldLocalPoolBottomIdx);
  68. return _machineState.GetFrameTopIdx() > _frameBaseIdx ? _machineState.GetTopFrame() : nullptr;
  69. }
  70. static bool FrameNeedsSkipped(const Il2CppStackFrameInfo& frame)
  71. {
  72. const MethodInfo* method = frame.method;
  73. const Il2CppClass* klass = method->klass;
  74. return (strcmp(klass->namespaze, "System.Diagnostics") == 0 &&
  75. (strcmp(klass->name, "StackFrame") == 0 || strcmp(klass->name, "StackTrace") == 0))
  76. || (strcmp(klass->namespaze, "UnityEngine") == 0
  77. && (strcmp(klass->name, "StackTraceUtility") == 0
  78. || strcmp(klass->name, "Debug") == 0
  79. || strcmp(klass->name, "Logger") == 0
  80. || strcmp(klass->name, "DebugLogHandler") == 0));
  81. }
  82. static void SetupStackFrameInfo(const InterpFrame* frame, Il2CppStackFrameInfo& stackFrame)
  83. {
  84. const MethodInfo* method = frame->method;
  85. const InterpMethodInfo* imi = (const InterpMethodInfo*)method->interpData;
  86. const byte* actualIp = (const byte*)frame->ip;
  87. stackFrame.method = method;
  88. stackFrame.raw_ip = (uintptr_t)frame;
  89. if (!hybridclr::metadata::IsInterpreterMethod(method))
  90. {
  91. return;
  92. }
  93. hybridclr::metadata::InterpreterImage* interpImage = hybridclr::metadata::MetadataModule::GetImage(method);
  94. if (!interpImage)
  95. {
  96. return;
  97. }
  98. hybridclr::metadata::PDBImage* pdbImage = interpImage->GetPDBImage();
  99. if (!pdbImage)
  100. {
  101. return;
  102. }
  103. pdbImage->SetupStackFrameInfo(method, actualIp, stackFrame);
  104. }
  105. void MachineState::CollectFrames(il2cpp::vm::StackFrames* stackFrames)
  106. {
  107. if (_frameTopIdx <= 0)
  108. {
  109. return;
  110. }
  111. size_t insertIndex = 0;
  112. for (; insertIndex < stackFrames->size(); insertIndex++)
  113. {
  114. if (FrameNeedsSkipped((*stackFrames)[insertIndex]))
  115. {
  116. break;
  117. }
  118. }
  119. stackFrames->insert(stackFrames->begin() + insertIndex, _frameTopIdx, Il2CppStackFrameInfo());
  120. for (int32_t i = 0; i < _frameTopIdx; i++)
  121. {
  122. SetupStackFrameInfo(_frameBase + i, (*stackFrames)[insertIndex + i]);
  123. }
  124. }
  125. void MachineState::SetupFramesDebugInfo(il2cpp::vm::StackFrames* stackFrames)
  126. {
  127. for (Il2CppStackFrameInfo& frame : *stackFrames)
  128. {
  129. if (frame.method && hybridclr::metadata::IsInterpreterImplement(frame.method))
  130. {
  131. hybridclr::metadata::InterpreterImage* interpImage = hybridclr::metadata::MetadataModule::GetImage(frame.method);
  132. if (interpImage)
  133. {
  134. hybridclr::metadata::PDBImage* pdbImage = interpImage->GetPDBImage();
  135. if (pdbImage)
  136. {
  137. pdbImage->SetupStackFrameInfo(frame.method, (const byte*)(((InterpFrame*)frame.raw_ip)->ip), frame);
  138. }
  139. }
  140. }
  141. }
  142. }
  143. }
  144. }