EmitBuffer.h 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  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. struct EmitBufferAllocation
  10. {
  11. CustomHeap::Allocation* allocation;
  12. size_t bytesUsed;
  13. size_t bytesCommitted;
  14. bool recorded;
  15. EmitBufferAllocation * nextAllocation;
  16. BYTE * GetUnused() const { return (BYTE*) allocation->address + bytesUsed; }
  17. BYTE * GetUncommitted() const { return (BYTE*) allocation->address + bytesCommitted; }
  18. // Truncation to DWORD okay here
  19. DWORD BytesFree() const { return static_cast<DWORD>(this->bytesCommitted - this->bytesUsed); }
  20. };
  21. typedef void* NativeMethod;
  22. //----------------------------------------------------------------------------
  23. // Emit buffer manager - manages allocation chunks from VirtualAlloc
  24. //----------------------------------------------------------------------------
  25. template <class SyncObject = FakeCriticalSection>
  26. class EmitBufferManager
  27. {
  28. public:
  29. EmitBufferManager(ArenaAllocator * allocator, CustomHeap::CodePageAllocators * codePageAllocators, Js::ScriptContext * scriptContext, LPCWSTR name);
  30. ~EmitBufferManager();
  31. // All the following methods are guarded with the SyncObject
  32. void Decommit();
  33. void Clear();
  34. EmitBufferAllocation* AllocateBuffer(__in size_t bytes, __deref_bcount(bytes) BYTE** ppBuffer, ushort pdataCount = 0, ushort xdataSize = 0, bool canAllocInPreReservedHeapPageSegment = false, bool isAnyJittedCode = false);
  35. bool CommitBuffer(EmitBufferAllocation* allocation, __out_bcount(bytes) BYTE* destBuffer, __in size_t bytes, __in_bcount(bytes) const BYTE* sourceBuffer, __in DWORD alignPad = 0);
  36. bool ProtectBufferWithExecuteReadWriteForInterpreter(EmitBufferAllocation* allocation);
  37. bool CommitReadWriteBufferForInterpreter(EmitBufferAllocation* allocation, _In_reads_bytes_(bufferSize) BYTE* pBuffer, _In_ size_t bufferSize);
  38. void CompletePreviousAllocation(EmitBufferAllocation* allocation);
  39. bool FreeAllocation(void* address);
  40. //Ends here
  41. bool IsInHeap(void* address);
  42. #if DBG_DUMP
  43. void DumpAndResetStats(wchar_t const * source);
  44. #endif
  45. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  46. void CheckBufferPermissions(EmitBufferAllocation *allocation);
  47. #endif
  48. EmitBufferAllocation * allocations;
  49. private:
  50. void FreeAllocations(bool release);
  51. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  52. bool CheckCommitFaultInjection();
  53. int commitCount;
  54. #endif
  55. ArenaAllocator * allocator;
  56. Js::ScriptContext * scriptContext;
  57. EmitBufferAllocation * NewAllocation(size_t bytes, ushort pdataCount, ushort xdataSize, bool canAllocInPreReservedHeapPageSegment, bool isAnyJittedCode);
  58. EmitBufferAllocation* GetBuffer(EmitBufferAllocation *allocation, __in size_t bytes, __deref_bcount(bytes) BYTE** ppBuffer);
  59. bool FinalizeAllocation(EmitBufferAllocation *allocation);
  60. CustomHeap::Heap allocationHeap;
  61. SyncObject criticalSection;
  62. #if DBG_DUMP
  63. public:
  64. LPCWSTR name;
  65. size_t totalBytesCode;
  66. size_t totalBytesLoopBody;
  67. size_t totalBytesAlignment;
  68. size_t totalBytesCommitted;
  69. size_t totalBytesReserved;
  70. #endif
  71. };