Skip to content

Commit

Permalink
[vm] Fix running under WSL 1
Browse files Browse the repository at this point in the history
On WSL 1 trying to allocate memory close to the binary
by supplying a hint fails with ENOMEM for unclear reason.
Some reports suggest that this might be related to the
alignment of the hint but aligning it by 64Kb does not
make the issue go away in our experiments. Instead
just retry without any hint.

Fixes #54587

TEST=manually under WSL 1

Change-Id: I0adf997fbf76e470a57da00f5ce7a26bb50706f7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/345802
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
  • Loading branch information
mraleph authored and Commit Queue committed Jan 11, 2024
1 parent b990bd2 commit aaca6ce
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 0 deletions.
12 changes: 12 additions & 0 deletions runtime/bin/file_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,21 @@ MappedMemory* File::Map(MapType type,
flags |= MAP_FIXED;
}
void* addr = mmap(hint, length, prot, flags, handle_->fd(), position);

// On WSL 1 trying to allocate memory close to the binary by supplying a hint
// fails with ENOMEM for unclear reason. Some reports suggest that this might
// be related to the alignment of the hint but aligning it by 64Kb does not
// make the issue go away in our experiments. Instead just retry without any
// hint.
if (addr == MAP_FAILED && hint != nullptr && start == nullptr &&
Utils::IsWindowsSubsystemForLinux()) {
addr = mmap(nullptr, length, prot, flags, handle_->fd(), position);
}

if (addr == MAP_FAILED) {
return nullptr;
}

return new MappedMemory(addr, length, /*should_unmap=*/start == nullptr);
}

Expand Down
11 changes: 11 additions & 0 deletions runtime/bin/virtual_memory_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ VirtualMemory* VirtualMemory::Allocate(intptr_t size,
// generated code near the VM binary to avoid this.
void* hint = is_executable ? reinterpret_cast<void*>(&Allocate) : nullptr;
void* address = mmap(hint, size, prot, map_flags, -1, 0);
#if defined(DART_HOST_OS_LINUX)
// On WSL 1 trying to allocate memory close to the binary by supplying a hint
// fails with ENOMEM for unclear reason. Some reports suggest that this might
// be related to the alignment of the hint but aligning it by 64Kb does not
// make the issue go away in our experiments. Instead just retry without any
// hint.
if (address == MAP_FAILED && hint != nullptr &&
Utils::IsWindowsSubsystemForLinux()) {
address = mmap(nullptr, size, prot, map_flags, -1, 0);
}
#endif
if (address == MAP_FAILED) {
return nullptr;
}
Expand Down
4 changes: 4 additions & 0 deletions runtime/platform/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,10 @@ class Utils {
// when it is no longer needed).
static void UnloadDynamicLibrary(void* library_handle,
char** error = nullptr);

#if defined(DART_HOST_OS_LINUX)
static bool IsWindowsSubsystemForLinux();
#endif
};

} // namespace dart
Expand Down
15 changes: 15 additions & 0 deletions runtime/platform/utils_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "platform/globals.h"
#if defined(DART_HOST_OS_LINUX)

#include <sys/utsname.h>

#include "platform/utils.h"
#include "platform/utils_linux.h"

Expand Down Expand Up @@ -42,13 +44,26 @@ int Utils::VSNPrint(char* str, size_t size, const char* format, va_list args) {
int Utils::Close(int fildes) {
return close(fildes);
}

size_t Utils::Read(int filedes, void* buf, size_t nbyte) {
return read(filedes, buf, nbyte);
}

int Utils::Unlink(const char* path) {
return unlink(path);
}

bool Utils::IsWindowsSubsystemForLinux() {
struct utsname info;
if (uname(&info) != 0) {
return false; // Not sure.
}

// If info.release contains either Microsoft or microsoft then we are
// most likely running under WSL.
return strstr(info.release, "icrosoft") != nullptr;
}

} // namespace dart

#endif // defined(DART_HOST_OS_LINUX)
12 changes: 12 additions & 0 deletions runtime/vm/virtual_memory_posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,18 @@ VirtualMemory* VirtualMemory::AllocateAligned(intptr_t size,
}
void* address =
GenericMapAligned(hint, prot, size, alignment, allocated_size, map_flags);
#if defined(DART_HOST_OS_LINUX)
// On WSL 1 trying to allocate memory close to the binary by supplying a hint
// fails with ENOMEM for unclear reason. Some reports suggest that this might
// be related to the alignment of the hint but aligning it by 64Kb does not
// make the issue go away in our experiments. Instead just retry without any
// hint.
if (address == nullptr && hint != nullptr &&
Utils::IsWindowsSubsystemForLinux()) {
address = GenericMapAligned(nullptr, prot, size, alignment, allocated_size,
map_flags);
}
#endif
if (address == nullptr) {
return nullptr;
}
Expand Down

0 comments on commit aaca6ce

Please sign in to comment.