EmitBuffer.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. //---------------------------------------------------------------------------------
  7. // One allocation chunk from CustomHeap + PData if needed, tracked as a linked list
  8. //---------------------------------------------------------------------------------
  9. template <typename TAlloc, typename TPreReservedAlloc>
  10. struct EmitBufferAllocation
  11. {
  12. CustomHeap::Allocation * allocation;
  13. size_t bytesUsed;
  14. size_t bytesCommitted;
  15. bool inPrereservedRegion;
  16. bool recorded;
  17. EmitBufferAllocation<TAlloc, TPreReservedAlloc> * nextAllocation;
  18. BYTE * GetUnused() const { return (BYTE*) allocation->address + bytesUsed; }
  19. BYTE * GetUncommitted() const { return (BYTE*) allocation->address + bytesCommitted; }
  20. size_t GetBytesUsed() const { return bytesUsed; }
  21. // Truncation to DWORD okay here
  22. DWORD BytesFree() const { return static_cast<DWORD>(this->bytesCommitted - this->bytesUsed); }
  23. };
  24. typedef void* NativeMethod;
  25. //----------------------------------------------------------------------------
  26. // Emit buffer manager - manages allocation chunks from VirtualAlloc
  27. //----------------------------------------------------------------------------
  28. template <typename TAlloc, typename TPreReservedAlloc, class SyncObject = FakeCriticalSection>
  29. class EmitBufferManager
  30. {
  31. typedef EmitBufferAllocation<TAlloc, TPreReservedAlloc> TEmitBufferAllocation;
  32. public:
  33. EmitBufferManager(ArenaAllocator * allocator, CustomHeap::CodePageAllocators<TAlloc, TPreReservedAlloc> * codePageAllocators, Js::ScriptContext * scriptContext, ThreadContextInfo * threadContext, LPCWSTR name, HANDLE processHandle);
  34. ~EmitBufferManager();
  35. // All the following methods are guarded with the SyncObject
  36. void Decommit();
  37. void Clear();
  38. TEmitBufferAllocation* AllocateBuffer(DECLSPEC_GUARD_OVERFLOW __in size_t bytes, __deref_bcount(bytes) BYTE** ppBuffer, ushort pdataCount = 0, ushort xdataSize = 0, bool canAllocInPreReservedHeapPageSegment = false, bool isAnyJittedCode = false);
  39. bool CommitBuffer(TEmitBufferAllocation* allocation, __in const size_t destBufferBytes, __out_bcount(destBufferBytes) BYTE* destBuffer, __in size_t bytes, __in_bcount(bytes) const BYTE* sourceBuffer, __in DWORD alignPad = 0);
  40. bool ProtectBufferWithExecuteReadWriteForInterpreter(TEmitBufferAllocation* allocation);
  41. bool CommitBufferForInterpreter(TEmitBufferAllocation* allocation, _In_reads_bytes_(bufferSize) BYTE* pBuffer, _In_ size_t bufferSize);
  42. void CompletePreviousAllocation(TEmitBufferAllocation* allocation);
  43. bool FreeAllocation(void* address);
  44. void SetValidCallTarget(TEmitBufferAllocation* allocation, void* callTarget, bool isValid);
  45. //Ends here
  46. bool IsInHeap(void* address);
  47. #if DBG_DUMP
  48. void DumpAndResetStats(char16 const * source);
  49. #endif
  50. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  51. void CheckBufferPermissions(TEmitBufferAllocation *allocation);
  52. #endif
  53. #if DBG
  54. bool IsBufferExecuteReadOnly(TEmitBufferAllocation * allocation);
  55. #endif
  56. TEmitBufferAllocation * allocations;
  57. private:
  58. void FreeAllocations(bool release);
  59. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  60. bool CheckCommitFaultInjection();
  61. int commitCount;
  62. #endif
  63. ArenaAllocator * allocator;
  64. Js::ScriptContext * scriptContext;
  65. ThreadContextInfo * threadContext;
  66. TEmitBufferAllocation * NewAllocation(DECLSPEC_GUARD_OVERFLOW size_t bytes, ushort pdataCount, ushort xdataSize, bool canAllocInPreReservedHeapPageSegment, bool isAnyJittedCode);
  67. TEmitBufferAllocation* GetBuffer(TEmitBufferAllocation *allocation, DECLSPEC_GUARD_OVERFLOW __in size_t bytes, __deref_bcount(bytes) BYTE** ppBuffer);
  68. bool FinalizeAllocation(TEmitBufferAllocation *allocation, BYTE* dstBuffer);
  69. CustomHeap::Heap<TAlloc, TPreReservedAlloc> allocationHeap;
  70. SyncObject criticalSection;
  71. HANDLE processHandle;
  72. #if DBG_DUMP
  73. public:
  74. LPCWSTR name;
  75. size_t totalBytesCode;
  76. size_t totalBytesLoopBody;
  77. size_t totalBytesAlignment;
  78. size_t totalBytesCommitted;
  79. size_t totalBytesReserved;
  80. #endif
  81. };
  82. typedef EmitBufferManager<VirtualAllocWrapper, PreReservedVirtualAllocWrapper, CriticalSection> InProcEmitBufferManagerWithlock;
  83. typedef EmitBufferManager<VirtualAllocWrapper, PreReservedVirtualAllocWrapper, FakeCriticalSection> InProcEmitBufferManager;
  84. #if ENABLE_OOP_NATIVE_CODEGEN
  85. typedef EmitBufferManager<SectionAllocWrapper, PreReservedSectionAllocWrapper, CriticalSection> OOPEmitBufferManagerWithLock;
  86. typedef EmitBufferManager<SectionAllocWrapper, PreReservedSectionAllocWrapper, FakeCriticalSection> OOPEmitBufferManager;
  87. #endif