MemoryMappedFile.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "il2cpp-config.h"
  2. #if !RUNTIME_TINY
  3. #include "MemoryMappedFile.h"
  4. #include "Baselib.h"
  5. #include "Cpp/ReentrantLock.h"
  6. #if ENABLE_HMI_MODE && IL2CPP_TARGET_ANDROID
  7. #include "os/Posix/FileHandle.h"
  8. #include "os/Android/GenericMemoryMappedFile.h"
  9. #include "os/Debug.h"
  10. #endif
  11. namespace il2cpp
  12. {
  13. namespace utils
  14. {
  15. static baselib::ReentrantLock s_Mutex;
  16. static std::map<void*, os::FileHandle*> s_MappedAddressToMappedFileObject;
  17. static std::map<void*, int64_t> s_MappedAddressToMappedLength;
  18. // These are 2 fallback functions, used when we can't memory map files inside Apk
  19. #if ENABLE_HMI_MODE && IL2CPP_TARGET_ANDROID
  20. void* MapGeneric(os::FileHandle* file, int64_t length, int64_t offset, int32_t access)
  21. {
  22. os::FastAutoLock lock(&s_Mutex);
  23. int64_t unused = 0;
  24. os::MemoryMappedFileError error = os::NO_MEMORY_MAPPED_FILE_ERROR;
  25. os::FileHandle* mappedFileHandle = os::GenericMemoryMappedFile::Create(file, NULL, 0, &unused, (os::MemoryMappedFileAccess)access, 0, &error);
  26. if (error != 0)
  27. return NULL;
  28. int64_t actualOffset = offset;
  29. void* address = os::GenericMemoryMappedFile::View(mappedFileHandle, &length, offset, (os::MemoryMappedFileAccess)access, &actualOffset, &error);
  30. if (address != NULL)
  31. {
  32. address = (uint8_t*)address + (offset - actualOffset);
  33. if (os::GenericMemoryMappedFile::OwnsDuplicatedFileHandle(mappedFileHandle))
  34. s_MappedAddressToMappedFileObject[address] = mappedFileHandle;
  35. s_MappedAddressToMappedLength[address] = length;
  36. }
  37. if (address != NULL)
  38. {
  39. utils::Logging::Write("[ERROR] Compressed file in Apk can't be memory-mapped! Setup noCompress in aaptOptions for less memory usage!");
  40. }
  41. return address;
  42. }
  43. bool UnmapGeneric(void* address, int64_t length)
  44. {
  45. os::FastAutoLock lock(&s_Mutex);
  46. if (length == 0)
  47. {
  48. std::map<void*, int64_t>::iterator entry = s_MappedAddressToMappedLength.find(address);
  49. if (entry != s_MappedAddressToMappedLength.end())
  50. {
  51. length = entry->second;
  52. s_MappedAddressToMappedLength.erase(entry);
  53. }
  54. }
  55. bool success = os::GenericMemoryMappedFile::UnmapView(address, length);
  56. if (!success)
  57. return false;
  58. std::map<void*, os::FileHandle*>::iterator entry = s_MappedAddressToMappedFileObject.find(address);
  59. if (entry != s_MappedAddressToMappedFileObject.end())
  60. {
  61. bool result = os::GenericMemoryMappedFile::Close(entry->second);
  62. s_MappedAddressToMappedFileObject.erase(entry);
  63. return result;
  64. }
  65. return true;
  66. }
  67. #endif
  68. void* MemoryMappedFile::Map(os::FileHandle* file)
  69. {
  70. return Map(file, 0, 0);
  71. }
  72. bool MemoryMappedFile::Unmap(void* address)
  73. {
  74. return Unmap(address, 0);
  75. }
  76. void* MemoryMappedFile::Map(os::FileHandle* file, int64_t length, int64_t offset)
  77. {
  78. return Map(file, length, offset, os::MMAP_FILE_ACCESS_READ);
  79. }
  80. void* MemoryMappedFile::Map(os::FileHandle* file, int64_t length, int64_t offset, int32_t access)
  81. {
  82. os::FastAutoLock lock(&s_Mutex);
  83. int64_t unused = 0;
  84. os::MemoryMappedFileError error = os::NO_MEMORY_MAPPED_FILE_ERROR;
  85. os::FileHandle* mappedFileHandle = os::MemoryMappedFile::Create(file, NULL, 0, &unused, (os::MemoryMappedFileAccess)access, 0, &error);
  86. if (error != 0)
  87. #if ENABLE_HMI_MODE && IL2CPP_TARGET_ANDROID
  88. return MapGeneric(file, length, offset, access);
  89. #else
  90. return NULL;
  91. #endif
  92. int64_t actualOffset = offset;
  93. void* address = os::MemoryMappedFile::View(mappedFileHandle, &length, offset, (os::MemoryMappedFileAccess)access, &actualOffset, &error);
  94. if (address != NULL)
  95. {
  96. address = (uint8_t*)address + (offset - actualOffset);
  97. #if ENABLE_HMI_MODE && IL2CPP_TARGET_ANDROID
  98. address = (uint8_t*)address + file->fdOffset;
  99. length -= file->fdOffset;
  100. #endif
  101. if (os::MemoryMappedFile::OwnsDuplicatedFileHandle(mappedFileHandle))
  102. s_MappedAddressToMappedFileObject[address] = mappedFileHandle;
  103. s_MappedAddressToMappedLength[address] = length;
  104. }
  105. return address;
  106. }
  107. bool MemoryMappedFile::Unmap(void* address, int64_t length)
  108. {
  109. os::FastAutoLock lock(&s_Mutex);
  110. if (length == 0)
  111. {
  112. std::map<void*, int64_t>::iterator entry = s_MappedAddressToMappedLength.find(address);
  113. if (entry != s_MappedAddressToMappedLength.end())
  114. {
  115. length = entry->second;
  116. s_MappedAddressToMappedLength.erase(entry);
  117. }
  118. }
  119. bool success = os::MemoryMappedFile::UnmapView(address, length);
  120. if (!success)
  121. #if ENABLE_HMI_MODE && IL2CPP_TARGET_ANDROID
  122. return UnmapGeneric(address, length);
  123. #else
  124. return false;
  125. #endif
  126. std::map<void*, os::FileHandle*>::iterator entry = s_MappedAddressToMappedFileObject.find(address);
  127. if (entry != s_MappedAddressToMappedFileObject.end())
  128. {
  129. bool result = os::MemoryMappedFile::Close(entry->second);
  130. s_MappedAddressToMappedFileObject.erase(entry);
  131. return result;
  132. }
  133. return true;
  134. }
  135. int64_t MemoryMappedFile::MapSize(void* address) {
  136. os::FastAutoLock lock(&s_Mutex);
  137. std::map<void*, int64_t>::iterator entry = s_MappedAddressToMappedLength.find(address);
  138. if (entry != s_MappedAddressToMappedLength.end())
  139. {
  140. return entry->second;
  141. }
  142. return 0;
  143. }
  144. }
  145. }
  146. #endif