Skip to content

Commit 91ffcd7

Browse files
authored
Merge pull request #1918 from tinysun212/pr-stdlib-msvc-1
2 parents 593d850 + e6ecc9a commit 91ffcd7

File tree

10 files changed

+226
-36
lines changed

10 files changed

+226
-36
lines changed

include/swift/Runtime/HeapObject.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ struct TwoWordPair {
106106
// in registers, so cram the result into an unsigned long long.
107107
// Use an enum class with implicit conversions so we don't dirty C callers
108108
// too much.
109-
#if __arm__ || __i386__ || defined(__CYGWIN__)
110-
#if defined(__CYGWIN__)
109+
#if __arm__ || __i386__ || defined(__CYGWIN__) || defined(_MSC_VER)
110+
#if defined(__CYGWIN__) || defined(_MSC_VER)
111111
enum class Return : unsigned __int128 {};
112112
#else
113113
enum class Return : unsigned long long {};

stdlib/public/runtime/Errors.cpp

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,31 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17+
#if defined(__CYGWIN__) || defined(__ANDROID__) || defined(_MSC_VER)
18+
# define SWIFT_SUPPORTS_BACKTRACE_REPORTING 0
19+
#else
20+
# define SWIFT_SUPPORTS_BACKTRACE_REPORTING 1
21+
#endif
22+
1723
#include <stdio.h>
1824
#include <stdlib.h>
1925
#include <string.h>
2026
#include <stdint.h>
27+
#if defined(_MSC_VER)
28+
#include <io.h>
29+
#else
2130
#include <unistd.h>
31+
#endif
2232
#include <stdarg.h>
2333
#include "swift/Runtime/Debug.h"
2434
#include "swift/Runtime/Mutex.h"
2535
#include "swift/Basic/Demangle.h"
2636
#include "swift/Basic/LLVM.h"
2737
#include "llvm/ADT/StringRef.h"
28-
38+
#if !defined(_MSC_VER)
2939
#include <cxxabi.h>
30-
31-
#if !defined(__CYGWIN__) && !defined(__ANDROID__)
40+
#endif
41+
#if SWIFT_SUPPORTS_BACKTRACE_REPORTING
3242

3343
// execinfo.h is not available on Android. Checks in this file ensure that
3444
// fatalError behaves as expected, but without stack traces.
@@ -50,7 +60,7 @@ enum: uint32_t {
5060

5161
using namespace swift;
5262

53-
#if !defined(__CYGWIN__) && !defined(__ANDROID__)
63+
#if SWIFT_SUPPORTS_BACKTRACE_REPORTING
5464

5565
static bool getSymbolNameAddr(llvm::StringRef libraryName, Dl_info dlinfo,
5666
std::string &symbolName, uintptr_t &addrOut) {
@@ -187,11 +197,16 @@ reportOnCrash(uint32_t flags, const char *message)
187197
static void
188198
reportNow(uint32_t flags, const char *message)
189199
{
200+
#if defined(_MSC_VER)
201+
#define STDERR_FILENO 2
202+
_write(STDERR_FILENO, message, strlen(message));
203+
#else
190204
write(STDERR_FILENO, message, strlen(message));
205+
#endif
191206
#ifdef __APPLE__
192207
asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s", message);
193208
#endif
194-
#if !defined(__CYGWIN__) && !defined(__ANDROID__)
209+
#if SWIFT_SUPPORTS_BACKTRACE_REPORTING
195210
if (flags & FatalErrorFlags::ReportBacktrace) {
196211
fputs("Current stack trace:\n", stderr);
197212
constexpr unsigned maxSupportedStackDepth = 128;
@@ -213,6 +228,26 @@ void swift::swift_reportError(uint32_t flags,
213228
reportOnCrash(flags, message);
214229
}
215230

231+
static int swift_vasprintf(char **strp, const char *fmt, va_list ap) {
232+
#if defined(_MSC_VER)
233+
int len = _vscprintf(fmt, ap);
234+
if (len < 0)
235+
return -1;
236+
char *buffer = reinterpret_cast<char *>(malloc(len + 1));
237+
if (!buffer)
238+
return -1;
239+
int result = vsprintf(*strp, fmt, ap);
240+
if (result < 0) {
241+
free(buffer);
242+
return -1;
243+
}
244+
*strp = buffer;
245+
return result;
246+
#else
247+
return vasprintf(strp, fmt, ap);
248+
#endif
249+
}
250+
216251
// Report a fatal error to system console, stderr, and crash logs, then abort.
217252
LLVM_ATTRIBUTE_NORETURN
218253
void
@@ -222,7 +257,7 @@ swift::fatalError(uint32_t flags, const char *format, ...)
222257
va_start(args, format);
223258

224259
char *log;
225-
vasprintf(&log, format, args);
260+
swift_vasprintf(&log, format, args);
226261

227262
swift_reportError(flags, log);
228263
abort();

stdlib/public/runtime/Metadata.cpp

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,14 @@
2828
#include <condition_variable>
2929
#include <new>
3030
#include <cctype>
31+
#if defined(_MSC_VER)
32+
// Avoid defining macro max(), min() which conflict with std::max(), std::min()
33+
#define NOMINMAX
34+
#include <windows.h>
35+
#else
3136
#include <sys/mman.h>
3237
#include <unistd.h>
38+
#endif
3339
#include "llvm/ADT/DenseMap.h"
3440
#include "llvm/ADT/Hashing.h"
3541
#include "ErrorObject.h"
@@ -56,19 +62,56 @@
5662
using namespace swift;
5763
using namespace metadataimpl;
5864

59-
void *MetadataAllocator::alloc(size_t size) {
65+
static uintptr_t swift_pageSize() {
6066
#if defined(__APPLE__)
61-
const uintptr_t PageSizeMask = vm_page_mask;
67+
return vm_page_size;
68+
#elif defined(_MSC_VER)
69+
SYSTEM_INFO SystemInfo;
70+
GetSystemInfo(&SystemInfo);
71+
return SystemInfo.dwPageSize;
72+
#else
73+
return sysconf(_SC_PAGESIZE);
74+
#endif
75+
}
76+
77+
// allocate memory up to a nearby page boundary
78+
static void *swift_allocateMetadataRoundingToPage(size_t size) {
79+
const uintptr_t PageSizeMask = SWIFT_LAZY_CONSTANT(swift_pageSize()) - 1;
80+
size = (size + PageSizeMask) & ~PageSizeMask;
81+
#if defined(_MSC_VER)
82+
auto mem = VirtualAlloc(
83+
nullptr, size, MEM_TOP_DOWN | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
6284
#else
63-
static const uintptr_t PageSizeMask = sysconf(_SC_PAGESIZE) - 1;
85+
auto mem = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
86+
VM_TAG_FOR_SWIFT_METADATA, 0);
87+
if (mem == MAP_FAILED)
88+
mem = nullptr;
6489
#endif
90+
return mem;
91+
}
92+
93+
// free memory allocated by swift_allocateMetadataRoundingToPage()
94+
static void swift_freeMetadata(void *addr, size_t size) {
95+
#if defined(_MSC_VER)
96+
// On success, VirtualFree() returns nonzero, on failure 0
97+
int result = VirtualFree(addr, 0, MEM_RELEASE);
98+
if (result == 0)
99+
fatalError(/* flags = */ 0, "swift_freePage: VirtualFree() failed");
100+
#else
101+
// On success, munmap() returns 0, on failure -1
102+
int result = munmap(addr, size);
103+
if (result != 0)
104+
fatalError(/* flags = */ 0, "swift_freePage: munmap() failed");
105+
#endif
106+
}
107+
108+
void *MetadataAllocator::alloc(size_t size) {
109+
const uintptr_t PageSize = SWIFT_LAZY_CONSTANT(swift_pageSize());
65110
// If the requested size is a page or larger, map page(s) for it
66111
// specifically.
67-
if (LLVM_UNLIKELY(size > PageSizeMask)) {
68-
auto mem = mmap(nullptr, (size + PageSizeMask) & ~PageSizeMask,
69-
PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE,
70-
VM_TAG_FOR_SWIFT_METADATA, 0);
71-
if (mem == MAP_FAILED)
112+
if (LLVM_UNLIKELY(size >= PageSize)) {
113+
void *mem = swift_allocateMetadataRoundingToPage(size);
114+
if (!mem)
72115
crash("unable to allocate memory for metadata cache");
73116
return mem;
74117
}
@@ -80,16 +123,13 @@ void *MetadataAllocator::alloc(size_t size) {
80123

81124
// If we wrap over the end of the page, allocate a new page.
82125
void *allocation = nullptr;
126+
const uintptr_t PageSizeMask = PageSize - 1;
83127
if (LLVM_UNLIKELY(((uintptr_t)next & ~PageSizeMask)
84128
!= (((uintptr_t)end & ~PageSizeMask)))) {
85129
// Allocate a new page if we haven't already.
86-
allocation = mmap(nullptr, PageSizeMask + 1,
87-
PROT_READ|PROT_WRITE,
88-
MAP_ANON|MAP_PRIVATE,
89-
VM_TAG_FOR_SWIFT_METADATA,
90-
/*offset*/ 0);
130+
allocation = swift_allocateMetadataRoundingToPage(PageSize);
91131

92-
if (allocation == MAP_FAILED)
132+
if (!allocation)
93133
crash("unable to allocate memory for metadata cache");
94134

95135
next = (char*) allocation;
@@ -107,7 +147,7 @@ void *MetadataAllocator::alloc(size_t size) {
107147
// This potentially causes us to perform multiple mmaps under contention,
108148
// but it keeps the fast path pristine.
109149
if (allocation) {
110-
munmap(allocation, PageSizeMask + 1);
150+
swift_freeMetadata(allocation, PageSize);
111151
}
112152
}
113153
}

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ using namespace Demangle;
4747
#define SWIFT_TYPE_METADATA_SECTION "__swift2_types"
4848
#elif defined(__ELF__)
4949
#define SWIFT_TYPE_METADATA_SECTION ".swift2_type_metadata_start"
50-
#elif defined(__CYGWIN__)
50+
#elif defined(__CYGWIN__) || defined(_MSC_VER)
5151
#define SWIFT_TYPE_METADATA_SECTION ".sw2tymd"
5252
#endif
5353

stdlib/public/runtime/Once.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ void swift::swift_once(swift_once_t *predicate, void (*fn)(void *)) {
4949
// process (the token is a word that is atomically incremented from 0 to
5050
// 1 to 2 during initialization) to work. We should implement our own version
5151
// that we can rely on to continue to work that way.
52+
// The MSVC port also relies on this, because the std::call_once on MSVC
53+
// follows the compatible init process.
5254
// For more information, see rdar://problem/18499385
5355
std::call_once(*predicate, [fn]() { fn(nullptr); });
5456
#endif

stdlib/public/runtime/Private.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ namespace swift {
172172
dest = newValue;
173173
}
174174

175-
#if defined(__CYGWIN__)
175+
#if defined(__CYGWIN__) || defined(_MSC_VER)
176176
struct dl_phdr_info {
177177
void *dlpi_addr;
178178
const char *dlpi_name;
@@ -183,6 +183,8 @@ namespace swift {
183183
void *data);
184184
uint8_t *_swift_getSectionDataPE(void *handle, const char *sectionName,
185185
unsigned long *sectionSize);
186+
#endif
187+
#if defined(__CYGWIN__)
186188
void _swift_once_f(uintptr_t *predicate, void *context,
187189
void (*function)(void *));
188190
#endif

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@
2929
#include <link.h>
3030
#endif
3131

32+
#if defined(_MSC_VER)
33+
#include <windows.h>
34+
#else
3235
#include <dlfcn.h>
36+
#endif
3337

3438
using namespace swift;
3539

@@ -144,7 +148,7 @@ const {
144148
#define SWIFT_PROTOCOL_CONFORMANCES_SECTION "__swift2_proto"
145149
#elif defined(__ELF__)
146150
#define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".swift2_protocol_conformances_start"
147-
#elif defined(__CYGWIN__)
151+
#elif defined(__CYGWIN__) || defined(_MSC_VER)
148152
#define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".sw2prtc"
149153
#endif
150154

@@ -396,17 +400,25 @@ void swift::_swift_initializeCallbacksToInspectDylib(
396400
// rdar://problem/19045112
397401
dl_iterate_phdr(_addImageProtocolConformances, &inspectArgs);
398402
}
399-
#elif defined(__CYGWIN__)
403+
#elif defined(__CYGWIN__) || defined(_MSC_VER)
400404
static int _addImageProtocolConformances(struct dl_phdr_info *info,
401405
size_t size, void *data) {
402406
InspectArgs *inspectArgs = (InspectArgs *)data;
403407
// inspectArgs contains addImage*Block function and the section name
408+
#if defined(_MSC_VER)
409+
HMODULE handle;
404410

411+
if (!info->dlpi_name || info->dlpi_name[0] == '\0')
412+
handle = GetModuleHandle(nullptr);
413+
else
414+
handle = GetModuleHandle(info->dlpi_name);
415+
#else
405416
void *handle;
406-
if (!info->dlpi_name || info->dlpi_name[0] == '\0') {
417+
if (!info->dlpi_name || info->dlpi_name[0] == '\0')
407418
handle = dlopen(nullptr, RTLD_LAZY);
408-
} else
419+
else
409420
handle = dlopen(info->dlpi_name, RTLD_LAZY | RTLD_NOLOAD);
421+
#endif
410422

411423
unsigned long conformancesSize;
412424
const uint8_t *conformances =
@@ -416,7 +428,11 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info,
416428
if (conformances)
417429
inspectArgs->fnAddImageBlock(conformances, conformancesSize);
418430

431+
#if defined(_MSC_VER)
432+
FreeLibrary(handle);
433+
#else
419434
dlclose(handle);
435+
#endif
420436
return 0;
421437
}
422438

stdlib/public/runtime/SwiftObject.mm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
#include "../SwiftShims/RuntimeShims.h"
3535
#include "Private.h"
3636
#include "swift/Runtime/Debug.h"
37+
#if SWIFT_OBJC_INTEROP
3738
#include <dlfcn.h>
39+
#endif
3840
#include <stdio.h>
3941
#include <stdlib.h>
4042
#include <unordered_map>

stdlib/public/stubs/LibcShims.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@
1212

1313
#include <random>
1414
#include <type_traits>
15+
#if defined(_MSC_VER)
16+
#include <io.h>
17+
#else
1518
#include <unistd.h>
19+
#endif
1620
#include <stdlib.h>
1721
#include <stdio.h>
1822
#include <string.h>
1923
#include "../SwiftShims/LibcShims.h"
24+
#include "llvm/Support/DataTypes.h"
2025

2126
using namespace swift;
2227

@@ -28,7 +33,11 @@ void swift::_swift_stdlib_free(void *ptr) {
2833
}
2934

3035
int swift::_swift_stdlib_putchar_unlocked(int c) {
36+
#if defined(_MSC_VER)
37+
return _putc_nolock(c, stdout);
38+
#else
3139
return putchar_unlocked(c);
40+
#endif
3241
}
3342

3443
__swift_size_t swift::_swift_stdlib_fwrite_stdout(const void *ptr,
@@ -48,16 +57,28 @@ int swift::_swift_stdlib_memcmp(const void *s1, const void *s2,
4857

4958
__swift_ssize_t
5059
swift::_swift_stdlib_read(int fd, void *buf, __swift_size_t nbyte) {
60+
#if defined(_MSC_VER)
61+
return _read(fd, buf, nbyte);
62+
#else
5163
return read(fd, buf, nbyte);
64+
#endif
5265
}
5366

5467
__swift_ssize_t
5568
swift::_swift_stdlib_write(int fd, const void *buf, __swift_size_t nbyte) {
69+
#if defined(_MSC_VER)
70+
return _write(fd, buf, nbyte);
71+
#else
5672
return write(fd, buf, nbyte);
73+
#endif
5774
}
5875

5976
int swift::_swift_stdlib_close(int fd) {
77+
#if defined(_MSC_VER)
78+
return _close(fd);
79+
#else
6080
return close(fd);
81+
#endif
6182
}
6283

6384
#if defined(__APPLE__)
@@ -70,6 +91,11 @@ size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
7091
size_t swift::_swift_stdlib_malloc_size(const void *ptr) {
7192
return malloc_usable_size(const_cast<void *>(ptr));
7293
}
94+
#elif defined(_MSC_VER)
95+
#include <malloc.h>
96+
size_t _swift_stdlib_malloc_size(const void *ptr) {
97+
return _msize(const_cast<void *>(ptr));
98+
}
7399
#elif defined(__FreeBSD__)
74100
#include <malloc_np.h>
75101
size_t swift::_swift_stdlib_malloc_size(const void *ptr) {

0 commit comments

Comments
 (0)