Skip to content

Commit a92e146

Browse files
committed
stdlib/msvc: Runtime with MSVC library
This patch is for libswiftCore.lib, linking with the library set of Visual Studio 2015. Clang with the option -fms-extension is used to build.
1 parent cbd6573 commit a92e146

19 files changed

+382
-54
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 {};

include/swift/Runtime/Mutex.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
#if (defined(__APPLE__) || defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__))
2424
#include "swift/Runtime/MutexPThread.h"
25+
#elif defined(_MSC_VER)
26+
#include "swift/Runtime/MutexWin32.h"
2527
#else
2628
#error "Implement equivalent of MutexPThread.h/cpp for your platform."
2729
#endif

include/swift/Runtime/MutexWin32.h

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//===--- MutexWin32.h - ---------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
14+
// using Windows Slim Reader/Writer Locks and Conditional Variables.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_RUNTIME_MUTEX_WIN32_H
19+
#define SWIFT_RUNTIME_MUTEX_WIN32_H
20+
21+
#include <windows.h>
22+
23+
namespace swift {
24+
25+
typedef CONDITION_VARIABLE ConditionHandle;
26+
typedef SRWLOCK MutexHandle;
27+
typedef SRWLOCK ReadWriteLockHandle;
28+
29+
#define CONDITION_SUPPORTS_CONSTEXPR 1
30+
#define MUTEX_SUPPORTS_CONSTEXPR 1
31+
#define READWRITELOCK_SUPPORTS_CONSTEXPR 1
32+
33+
struct ConditionPlatformHelper {
34+
static constexpr ConditionHandle staticInit() {
35+
return CONDITION_VARIABLE_INIT;
36+
};
37+
static void init(ConditionHandle &condition) {
38+
InitializeConditionVariable(&condition);
39+
}
40+
static void destroy(ConditionHandle &condition) {}
41+
static void notifyOne(ConditionHandle &condition) {
42+
WakeConditionVariable(&condition);
43+
}
44+
static void notifyAll(ConditionHandle &condition) {
45+
WakeAllConditionVariable(&condition);
46+
}
47+
static void wait(ConditionHandle &condition, MutexHandle &mutex);
48+
};
49+
50+
struct MutexPlatformHelper {
51+
static constexpr MutexHandle staticInit() { return SRWLOCK_INIT; }
52+
static void init(MutexHandle &mutex, bool checked = false) {
53+
InitializeSRWLock(&mutex);
54+
}
55+
static void destroy(MutexHandle &mutex) {}
56+
static void lock(MutexHandle &mutex) { AcquireSRWLockExclusive(&mutex); }
57+
static void unlock(MutexHandle &mutex) { ReleaseSRWLockExclusive(&mutex); }
58+
static bool try_lock(MutexHandle &mutex) {
59+
return TryAcquireSRWLockExclusive(&mutex) != 0;
60+
}
61+
// The unsafe versions don't do error checking.
62+
static void unsafeLock(MutexHandle &mutex) {
63+
AcquireSRWLockExclusive(&mutex);
64+
}
65+
static void unsafeUnlock(MutexHandle &mutex) {
66+
ReleaseSRWLockExclusive(&mutex);
67+
}
68+
};
69+
70+
struct ReadWriteLockPlatformHelper {
71+
static constexpr ReadWriteLockHandle staticInit() { return SRWLOCK_INIT; }
72+
static void init(ReadWriteLockHandle &rwlock) { InitializeSRWLock(&rwlock); }
73+
static void destroy(ReadWriteLockHandle &rwlock) {}
74+
static void readLock(ReadWriteLockHandle &rwlock) {
75+
AcquireSRWLockShared(&rwlock);
76+
}
77+
static bool try_readLock(ReadWriteLockHandle &rwlock) {
78+
return TryAcquireSRWLockShared(&rwlock) != 0;
79+
}
80+
static void readUnlock(ReadWriteLockHandle &rwlock) {
81+
ReleaseSRWLockShared(&rwlock);
82+
}
83+
static void writeLock(ReadWriteLockHandle &rwlock) {
84+
AcquireSRWLockExclusive(&rwlock);
85+
}
86+
static bool try_writeLock(ReadWriteLockHandle &rwlock) {
87+
return TryAcquireSRWLockExclusive(&rwlock) != 0;
88+
}
89+
static void writeUnlock(ReadWriteLockHandle &rwlock) {
90+
ReleaseSRWLockExclusive(&rwlock);
91+
}
92+
};
93+
}
94+
95+
#endif

stdlib/public/SwiftShims/LibcShims.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ namespace swift { extern "C" {
3131
// the current platform in the runtime code.
3232
#if defined(__linux__) && defined (__arm__) && !defined(__android__)
3333
typedef int __swift_ssize_t;
34+
#elif defined(_MSC_VER)
35+
typedef long long __swift_ssize_t;
3436
#else
3537
typedef long int __swift_ssize_t;
3638
#endif

stdlib/public/runtime/CMakeLists.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,17 @@ if(SWIFT_RUNTIME_ENABLE_LEAK_CHECKER)
1818
endif()
1919

2020
set(swift_runtime_port_sources)
21-
if("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
21+
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
2222
set(swift_runtime_port_sources
23+
MutexWin32.cpp
2324
CygwinPort.cpp)
25+
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "CYGWIN")
26+
set(swift_runtime_port_sources
27+
MutexPThread.cpp
28+
CygwinPort.cpp)
29+
else()
30+
set(swift_runtime_port_sources
31+
MutexPThread.cpp)
2432
endif()
2533

2634
list(APPEND swift_runtime_compile_flags
@@ -48,7 +56,6 @@ set(swift_runtime_sources
4856
KnownMetadata.cpp
4957
Metadata.cpp
5058
MetadataLookup.cpp
51-
MutexPThread.cpp
5259
Once.cpp
5360
Portability.cpp
5461
ProtocolConformance.cpp
@@ -60,6 +67,8 @@ set(swift_runtime_sources
6067
set(LLVM_OPTIONAL_SOURCES
6168
Remangle.cpp
6269
swift_sections.S
70+
MutexPThread.cpp
71+
MutexWin32.cpp
6372
CygwinPort.cpp
6473
${swift_runtime_sources}
6574
${swift_runtime_objc_sources}

stdlib/public/runtime/CygwinPort.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ uint8_t *swift::_swift_getSectionDataPE(void *handle, const char *sectionName,
133133

134134
return nullptr;
135135
}
136-
136+
#if !defined(_MSC_VER)
137137
void swift::_swift_once_f(uintptr_t *predicate, void *context,
138138
void (*function)(void *)) {
139139
// FIXME: This implementation does a global lock, which is much worse than
@@ -148,3 +148,4 @@ void swift::_swift_once_f(uintptr_t *predicate, void *context,
148148
} else
149149
swiftOnceMutex.unlock();
150150
}
151+
#endif

stdlib/public/runtime/Errors.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,24 @@
1818
#include <stdlib.h>
1919
#include <string.h>
2020
#include <stdint.h>
21+
#if defined(_MSC_VER)
22+
#include <io.h>
23+
#else
2124
#include <unistd.h>
25+
#endif
26+
#if !defined(_MSC_VER)
2227
#include <pthread.h>
28+
#endif
2329
#include <stdarg.h>
2430
#include "swift/Runtime/Debug.h"
2531
#include "swift/Runtime/Mutex.h"
2632
#include "swift/Basic/Demangle.h"
2733
#include "swift/Basic/LLVM.h"
2834
#include "llvm/ADT/StringRef.h"
29-
35+
#if !defined(_MSC_VER)
3036
#include <cxxabi.h>
31-
32-
#if !defined(__CYGWIN__) && !defined(__ANDROID__)
37+
#endif
38+
#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(_MSC_VER)
3339

3440
// execinfo.h is not available on Android. Checks in this file ensure that
3541
// fatalError behaves as expected, but without stack traces.
@@ -51,7 +57,7 @@ enum: uint32_t {
5157

5258
using namespace swift;
5359

54-
#if !defined(__CYGWIN__) && !defined(__ANDROID__)
60+
#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(_MSC_VER)
5561

5662
static bool getSymbolNameAddr(llvm::StringRef libraryName, Dl_info dlinfo,
5763
std::string &symbolName, uintptr_t &addrOut) {
@@ -188,11 +194,16 @@ reportOnCrash(uint32_t flags, const char *message)
188194
static void
189195
reportNow(uint32_t flags, const char *message)
190196
{
197+
#if defined(_MSC_VER)
198+
#define STDERR_FILENO 2
199+
_write(STDERR_FILENO, message, strlen(message));
200+
#else
191201
write(STDERR_FILENO, message, strlen(message));
202+
#endif
192203
#ifdef __APPLE__
193204
asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s", message);
194205
#endif
195-
#if !defined(__CYGWIN__) && !defined(__ANDROID__)
206+
#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(_MSC_VER)
196207
if (flags & FatalErrorFlags::ReportBacktrace) {
197208
fputs("Current stack trace:\n", stderr);
198209
constexpr unsigned maxSupportedStackDepth = 128;
@@ -223,7 +234,13 @@ swift::fatalError(uint32_t flags, const char *format, ...)
223234
va_start(args, format);
224235

225236
char *log;
237+
#if defined(_MSC_VER)
238+
int len = _vscprintf(format, args) + 1;
239+
log = reinterpret_cast<char *>(malloc(len));
240+
vsprintf(log, format, args);
241+
#else
226242
vasprintf(&log, format, args);
243+
#endif
227244

228245
swift_reportError(flags, log);
229246
abort();

stdlib/public/runtime/HeapObject.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@
2828
#include <cstring>
2929
#include <cstdio>
3030
#include <cstdlib>
31+
#if !defined(_MSC_VER)
3132
#include <unistd.h>
33+
#endif
3234
#include "../SwiftShims/RuntimeShims.h"
3335
#if SWIFT_OBJC_INTEROP
3436
# include <objc/NSObject.h>

stdlib/public/runtime/Metadata.cpp

Lines changed: 39 additions & 11 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,45 @@
5662
using namespace swift;
5763
using namespace metadataimpl;
5864

65+
// allocate memory up to a nearby page boundary
66+
static void *swift_allocPage(size_t size) {
67+
#if defined(_MSC_VER)
68+
auto mem = VirtualAlloc(
69+
nullptr, size, MEM_TOP_DOWN | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
70+
#else
71+
auto mem = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
72+
VM_TAG_FOR_SWIFT_METADATA, 0);
73+
if (mem == MAP_FAILED)
74+
mem = nullptr;
75+
#endif
76+
return mem;
77+
}
78+
79+
// free memory allocated by swift_allocPage()
80+
// On success, swift_freePage() returns 0, on failure -1
81+
static int swift_freePage(void *addr, size_t size) {
82+
#if defined(_MSC_VER)
83+
return VirtualFree(addr, 0, MEM_RELEASE) == 0 ? -1 : 0;
84+
#else
85+
return munmap(addr, size);
86+
#endif
87+
}
88+
5989
void *MetadataAllocator::alloc(size_t size) {
6090
#if defined(__APPLE__)
6191
const uintptr_t PageSizeMask = vm_page_mask;
92+
#elif defined(_MSC_VER)
93+
SYSTEM_INFO SystemInfo;
94+
GetSystemInfo(&SystemInfo);
95+
const uintptr_t PageSizeMask = SystemInfo.dwPageSize - 1;
6296
#else
6397
static const uintptr_t PageSizeMask = sysconf(_SC_PAGESIZE) - 1;
6498
#endif
6599
// If the requested size is a page or larger, map page(s) for it
66100
// specifically.
67101
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)
102+
void *mem = swift_allocPage((size + PageSizeMask) & ~PageSizeMask);
103+
if (!mem)
72104
crash("unable to allocate memory for metadata cache");
73105
return mem;
74106
}
@@ -83,13 +115,9 @@ void *MetadataAllocator::alloc(size_t size) {
83115
if (LLVM_UNLIKELY(((uintptr_t)next & ~PageSizeMask)
84116
!= (((uintptr_t)end & ~PageSizeMask)))) {
85117
// 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);
118+
allocation = swift_allocPage(PageSizeMask + 1);
91119

92-
if (allocation == MAP_FAILED)
120+
if (!allocation)
93121
crash("unable to allocate memory for metadata cache");
94122

95123
next = (char*) allocation;
@@ -107,7 +135,7 @@ void *MetadataAllocator::alloc(size_t size) {
107135
// This potentially causes us to perform multiple mmaps under contention,
108136
// but it keeps the fast path pristine.
109137
if (allocation) {
110-
munmap(allocation, PageSizeMask + 1);
138+
swift_freePage(allocation, PageSizeMask + 1);
111139
}
112140
}
113141
}

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@
3434
#include <link.h>
3535
#endif
3636

37+
#if defined(_MSC_VER)
38+
#include <windows.h>
39+
#else
3740
#include <dlfcn.h>
41+
#endif
3842

3943
using namespace swift;
4044
using namespace Demangle;
@@ -49,7 +53,7 @@ using namespace Demangle;
4953
#define SWIFT_TYPE_METADATA_SECTION "__swift2_types"
5054
#elif defined(__ELF__)
5155
#define SWIFT_TYPE_METADATA_SECTION ".swift2_type_metadata_start"
52-
#elif defined(__CYGWIN__)
56+
#elif defined(__CYGWIN__) || defined(_MSC_VER)
5357
#define SWIFT_TYPE_METADATA_SECTION ".sw2tymd"
5458
#endif
5559

stdlib/public/runtime/MutexWin32.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//===--- MutexWin32.cpp - -------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See http://swift.org/LICENSE.txt for license information
9+
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
14+
// using Windows Slim Reader/Writer Locks and Conditional Variables.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#include "swift/Runtime/Mutex.h"
19+
#include "swift/Runtime/Debug.h"
20+
21+
using namespace swift;
22+
23+
void ConditionPlatformHelper::wait(CONDITION_VARIABLE &condition,
24+
SRWLOCK &mutex) {
25+
BOOL result = SleepConditionVariableSRW(&condition, &mutex, INFINITE, 0);
26+
if (result == FALSE) {
27+
DWORD errorcode = GetLastError();
28+
fatalError(/* flags = */ 0,
29+
"'SleepConditionVariableSRW()' failed with error code %d\n",
30+
errorcode);
31+
}
32+
}

0 commit comments

Comments
 (0)