EmitBuffer.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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, 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, __out_bcount(bytes) 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. //Ends here
  45. bool IsInHeap(void* address);
  46. #if DBG_DUMP
  47. void DumpAndResetStats(char16 const * source);
  48. #endif
  49. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  50. void CheckBufferPermissions(TEmitBufferAllocation *allocation);
  51. #endif
  52. #if DBG
  53. bool IsBufferExecuteReadOnly(TEmitBufferAllocation * allocation);
  54. #endif
  55. TEmitBufferAllocation * allocations;
  56. private:
  57. void FreeAllocations(bool release);
  58. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  59. bool CheckCommitFaultInjection();
  60. int commitCount;
  61. #endif
  62. ArenaAllocator * allocator;
  63. Js::ScriptContext * scriptContext;
  64. TEmitBufferAllocation * NewAllocation(DECLSPEC_GUARD_OVERFLOW size_t bytes, ushort pdataCount, ushort xdataSize, bool canAllocInPreReservedHeapPageSegment, bool isAnyJittedCode);
  65. TEmitBufferAllocation* GetBuffer(TEmitBufferAllocation *allocation, DECLSPEC_GUARD_OVERFLOW __in size_t bytes, __deref_bcount(bytes) BYTE** ppBuffer);
  66. bool FinalizeAllocation(TEmitBufferAllocation *allocation, BYTE* dstBuffer);
  67. CustomHeap::Heap<TAlloc, TPreReservedAlloc> allocationHeap;
  68. SyncObject criticalSection;
  69. HANDLE processHandle;
  70. #if DBG_DUMP
  71. public:
  72. LPCWSTR name;
  73. size_t totalBytesCode;
  74. size_t totalBytesLoopBody;
  75. size_t totalBytesAlignment;
  76. size_t totalBytesCommitted;
  77. size_t totalBytesReserved;
  78. #endif
  79. };
  80. typedef EmitBufferManager<VirtualAllocWrapper, PreReservedVirtualAllocWrapper, CriticalSection> InProcEmitBufferManagerWithlock;
  81. typedef EmitBufferManager<VirtualAllocWrapper, PreReservedVirtualAllocWrapper, FakeCriticalSection> InProcEmitBufferManager;
  82. #if ENABLE_OOP_NATIVE_CODEGEN
  83. typedef EmitBufferManager<SectionAllocWrapper, PreReservedSectionAllocWrapper, CriticalSection> OOPEmitBufferManagerWithLock;
  84. typedef EmitBufferManager<SectionAllocWrapper, PreReservedSectionAllocWrapper, FakeCriticalSection> OOPEmitBufferManager;
  85. #endif