Add support for MSVC

Tested with MSVC 8 32 and 64 bits.
This commit is contained in:
Mike Hommey 2012-04-30 12:38:31 +02:00 committed by Jason Evans
parent b45c57ecaf
commit fd97b1dfc7
11 changed files with 177 additions and 15 deletions

View File

@ -26,9 +26,11 @@ abs_objroot := @abs_objroot@
CPPFLAGS := @CPPFLAGS@ -I$(srcroot)include -I$(objroot)include CPPFLAGS := @CPPFLAGS@ -I$(srcroot)include -I$(objroot)include
CFLAGS := @CFLAGS@ CFLAGS := @CFLAGS@
LDFLAGS := @LDFLAGS@ LDFLAGS := @LDFLAGS@
EXTRA_LDFLAGS := @EXTRA_LDFLAGS@
LIBS := @LIBS@ LIBS := @LIBS@
RPATH_EXTRA := @RPATH_EXTRA@ RPATH_EXTRA := @RPATH_EXTRA@
SO := @so@ SO := @so@
IMPORTLIB := @importlib@
O := @o@ O := @o@
A := @a@ A := @a@
EXE := @exe@ EXE := @exe@
@ -49,6 +51,9 @@ enable_experimental := @enable_experimental@
DSO_LDFLAGS = @DSO_LDFLAGS@ DSO_LDFLAGS = @DSO_LDFLAGS@
SOREV = @SOREV@ SOREV = @SOREV@
PIC_CFLAGS = @PIC_CFLAGS@ PIC_CFLAGS = @PIC_CFLAGS@
CTARGET = @CTARGET@
LDTARGET = @LDTARGET@
MKLIB = @MKLIB@
ifeq (macho, $(ABI)) ifeq (macho, $(ABI))
TEST_LIBRARY_PATH := DYLD_FALLBACK_LIBRARY_PATH="$(objroot)lib" TEST_LIBRARY_PATH := DYLD_FALLBACK_LIBRARY_PATH="$(objroot)lib"
@ -77,9 +82,13 @@ CSRCS := $(srcroot)src/jemalloc.c $(srcroot)src/arena.c $(srcroot)src/atomic.c \
ifeq (macho, $(ABI)) ifeq (macho, $(ABI))
CSRCS += $(srcroot)src/zone.c CSRCS += $(srcroot)src/zone.c
endif endif
ifeq ($(IMPORTLIB),$(SO))
STATIC_LIBS := $(objroot)lib/$(LIBJEMALLOC).$(A) STATIC_LIBS := $(objroot)lib/$(LIBJEMALLOC).$(A)
endif
ifdef PIC_CFLAGS ifdef PIC_CFLAGS
STATIC_LIBS += $(objroot)lib/$(LIBJEMALLOC)_pic.$(A) STATIC_LIBS += $(objroot)lib/$(LIBJEMALLOC)_pic.$(A)
else
STATIC_LIBS += $(objroot)lib/$(LIBJEMALLOC)_s.$(A)
endif endif
DSOS := $(objroot)lib/$(LIBJEMALLOC).$(SOREV) DSOS := $(objroot)lib/$(LIBJEMALLOC).$(SOREV)
ifneq ($(SOREV),$(SO)) ifneq ($(SOREV),$(SO))
@ -136,10 +145,13 @@ $(CPICOBJS): $(objroot)src/%.pic.$(O): $(srcroot)src/%.c
$(CPICOBJS): CFLAGS += $(PIC_CFLAGS) $(CPICOBJS): CFLAGS += $(PIC_CFLAGS)
$(CTESTOBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c $(CTESTOBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c
$(CTESTOBJS): CPPFLAGS += -I$(objroot)test $(CTESTOBJS): CPPFLAGS += -I$(objroot)test
ifneq ($(IMPORTLIB),$(SO))
$(COBJS): CPPFLAGS += -DDLLEXPORT
endif
$(COBJS) $(CPICOBJS) $(CTESTOBJS): %.$(O): $(COBJS) $(CPICOBJS) $(CTESTOBJS): %.$(O):
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) $(CFLAGS) -c $(CPPFLAGS) -o $@ $< $(CC) $(CFLAGS) -c $(CPPFLAGS) $(CTARGET) $<
@$(CC) -MM $(CPPFLAGS) -MT $@ -o $(@:%.$(O)=%.d) $< @$(CC) -MM $(CPPFLAGS) -MT $@ -o $(@:%.$(O)=%.d) $<
ifneq ($(SOREV),$(SO)) ifneq ($(SOREV),$(SO))
@ -150,20 +162,21 @@ endif
$(objroot)lib/$(LIBJEMALLOC).$(SOREV) : $(if $(PIC_CFLAGS),$(CPICOBJS),$(COBJS)) $(objroot)lib/$(LIBJEMALLOC).$(SOREV) : $(if $(PIC_CFLAGS),$(CPICOBJS),$(COBJS))
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) $(DSO_LDFLAGS) $(call RPATH,$(RPATH_EXTRA)) -o $@ $+ $(LDFLAGS) $(LIBS) $(CC) $(DSO_LDFLAGS) $(call RPATH,$(RPATH_EXTRA)) $(LDTARGET) $+ $(LDFLAGS) $(LIBS) $(EXTRA_LDFLAGS)
$(objroot)lib/$(LIBJEMALLOC)_pic.$(A) : $(CPICOBJS) $(objroot)lib/$(LIBJEMALLOC)_pic.$(A) : $(CPICOBJS)
$(objroot)lib/$(LIBJEMALLOC).$(A) : $(COBJS) $(objroot)lib/$(LIBJEMALLOC).$(A) : $(COBJS)
$(objroot)lib/$(LIBJEMALLOC)_s.$(A) : $(COBJS)
$(STATIC_LIBS): $(STATIC_LIBS):
@mkdir -p $(@D) @mkdir -p $(@D)
ar crus $@ $+ $(MKLIB) $+
$(objroot)test/bitmap$(EXE): $(objroot)src/bitmap.$(O) $(objroot)test/bitmap$(EXE): $(objroot)src/bitmap.$(O)
$(objroot)test/%$(EXE): $(objroot)test/%.$(O) $(objroot)src/util.$(O) $(DSOS) $(objroot)test/%$(EXE): $(objroot)test/%.$(O) $(objroot)src/util.$(O) $(DSOS)
@mkdir -p $(@D) @mkdir -p $(@D)
$(CC) -o $@ $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) -L$(objroot)lib -ljemalloc$(install_suffix) $(filter -lpthread,$(LIBS)) $(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(filter -lpthread,$(LIBS)) $(EXTRA_LDFLAGS)
build_lib_shared: $(DSOS) build_lib_shared: $(DSOS)
build_lib_static: $(STATIC_LIBS) build_lib_static: $(STATIC_LIBS)

View File

@ -111,6 +111,19 @@ dnl If CFLAGS isn't defined, set CFLAGS to something reasonable. Otherwise,
dnl just prevent autoconf from molesting CFLAGS. dnl just prevent autoconf from molesting CFLAGS.
CFLAGS=$CFLAGS CFLAGS=$CFLAGS
AC_PROG_CC AC_PROG_CC
if test "x$GCC" != "xyes" ; then
AC_CACHE_CHECK([whether compiler is MSVC],
[je_cv_msvc],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],
[
#ifndef _MSC_VER
int fail[-1];
#endif
])],
[je_cv_msvc=yes],
[je_cv_msvc=no])])
fi
if test "x$CFLAGS" = "x" ; then if test "x$CFLAGS" = "x" ; then
no_CFLAGS="yes" no_CFLAGS="yes"
if test "x$GCC" = "xyes" ; then if test "x$GCC" = "xyes" ; then
@ -118,6 +131,12 @@ if test "x$CFLAGS" = "x" ; then
JE_CFLAGS_APPEND([-Wall]) JE_CFLAGS_APPEND([-Wall])
JE_CFLAGS_APPEND([-pipe]) JE_CFLAGS_APPEND([-pipe])
JE_CFLAGS_APPEND([-g3]) JE_CFLAGS_APPEND([-g3])
elif test "x$je_cv_msvc" = "xyes" ; then
CC="$CC -nologo"
JE_CFLAGS_APPEND([-Zi])
JE_CFLAGS_APPEND([-MT])
JE_CFLAGS_APPEND([-W3])
CPPFLAGS="$CPPFLAGS -I${srcroot}/include/msvc_compat"
fi fi
fi fi
dnl Append EXTRA_CFLAGS to CFLAGS, if defined. dnl Append EXTRA_CFLAGS to CFLAGS, if defined.
@ -195,6 +214,7 @@ AC_DEFINE_UNQUOTED([CPU_SPINWAIT], [$CPU_SPINWAIT])
LD_PRELOAD_VAR="LD_PRELOAD" LD_PRELOAD_VAR="LD_PRELOAD"
so="so" so="so"
importlib="${so}"
o="$ac_objext" o="$ac_objext"
a="a" a="a"
exe="$ac_exeext" exe="$ac_exeext"
@ -203,9 +223,10 @@ DSO_LDFLAGS='-shared -Wl,-soname,$(@F)'
RPATH='-Wl,-rpath,$(1)' RPATH='-Wl,-rpath,$(1)'
SOREV="${so}.${rev}" SOREV="${so}.${rev}"
PIC_CFLAGS='-fPIC -DPIC' PIC_CFLAGS='-fPIC -DPIC'
CTARGET='-o $@'
dnl Heap profiling uses the log(3) function. LDTARGET='-o $@'
LIBS="$LIBS -lm" EXTRA_LDFLAGS=
MKLIB='ar crus $@'
dnl Platform-specific settings. abi and RPATH can probably be determined dnl Platform-specific settings. abi and RPATH can probably be determined
dnl programmatically, but doing so is error-prone, which makes it generally dnl programmatically, but doing so is error-prone, which makes it generally
@ -223,6 +244,7 @@ case "${host}" in
RPATH="" RPATH=""
LD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES" LD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
so="dylib" so="dylib"
importlib="${so}"
force_tls="0" force_tls="0"
DSO_LDFLAGS='-shared -Wl,-dylib_install_name,$(@F)' DSO_LDFLAGS='-shared -Wl,-dylib_install_name,$(@F)'
SOREV="${rev}.${so}" SOREV="${rev}.${so}"
@ -278,7 +300,17 @@ case "${host}" in
force_tls="0" force_tls="0"
RPATH="" RPATH=""
so="dll" so="dll"
DSO_LDFLAGS="-shared" if test "x$je_cv_msvc" = "xyes" ; then
importlib="lib"
DSO_LDFLAGS="-LD"
EXTRA_LDFLAGS="-link -DEBUG"
CTARGET='-Fo$@'
LDTARGET='-Fe$@'
MKLIB='lib -nologo -out:$@'
else
importlib="${so}"
DSO_LDFLAGS="-shared"
fi
a="lib" a="lib"
libprefix="" libprefix=""
SOREV="${so}" SOREV="${so}"
@ -293,13 +325,23 @@ AC_SUBST([abi])
AC_SUBST([RPATH]) AC_SUBST([RPATH])
AC_SUBST([LD_PRELOAD_VAR]) AC_SUBST([LD_PRELOAD_VAR])
AC_SUBST([so]) AC_SUBST([so])
AC_SUBST([importlib])
AC_SUBST([o]) AC_SUBST([o])
AC_SUBST([a]) AC_SUBST([a])
AC_SUBST([exe]) AC_SUBST([exe])
AC_SUBST([libprefix]) AC_SUBST([libprefix])
AC_SUBST([DSO_LDFLAGS]) AC_SUBST([DSO_LDFLAGS])
AC_SUBST([EXTRA_LDFLAGS])
AC_SUBST([SOREV]) AC_SUBST([SOREV])
AC_SUBST([PIC_CFLAGS]) AC_SUBST([PIC_CFLAGS])
AC_SUBST([CTARGET])
AC_SUBST([LDTARGET])
AC_SUBST([MKLIB])
if test "x$abi" != "xpecoff"; then
dnl Heap profiling uses the log(3) function.
LIBS="$LIBS -lm"
fi
JE_COMPILABLE([__attribute__ syntax], JE_COMPILABLE([__attribute__ syntax],
[static __attribute__((unused)) void foo(void){}], [static __attribute__((unused)) void foo(void){}],
@ -530,6 +572,8 @@ if test "x$enable_debug" = "x0" -a "x$no_CFLAGS" = "xyes" ; then
if test "x$GCC" = "xyes" ; then if test "x$GCC" = "xyes" ; then
JE_CFLAGS_APPEND([-O3]) JE_CFLAGS_APPEND([-O3])
JE_CFLAGS_APPEND([-funroll-loops]) JE_CFLAGS_APPEND([-funroll-loops])
elif test "x$je_cv_msvc" = "xyes" ; then
JE_CFLAGS_APPEND([-O2])
else else
JE_CFLAGS_APPEND([-O]) JE_CFLAGS_APPEND([-O])
fi fi
@ -833,11 +877,11 @@ AC_CACHE_CHECK([STATIC_PAGE_SHIFT],
[je_cv_static_page_shift], [je_cv_static_page_shift],
AC_RUN_IFELSE([AC_LANG_PROGRAM( AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[ [[
#include <strings.h>
#ifdef _WIN32 #ifdef _WIN32
#include <windows.h> #include <windows.h>
#else #else
#include <unistd.h> #include <unistd.h>
#include <strings.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
]], ]],

View File

@ -47,6 +47,20 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
return (__sync_sub_and_fetch(p, x)); return (__sync_sub_and_fetch(p, x));
} }
#elif (defined(_MSC_VER))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
return (InterlockedExchangeAdd64(p, x));
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
return (InterlockedExchangeAdd64(p, -((int64_t)x)));
}
#elif (defined(JEMALLOC_OSATOMIC)) #elif (defined(JEMALLOC_OSATOMIC))
JEMALLOC_INLINE uint64_t JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x) atomic_add_uint64(uint64_t *p, uint64_t x)
@ -145,6 +159,20 @@ atomic_sub_uint32(uint32_t *p, uint32_t x)
return (__sync_sub_and_fetch(p, x)); return (__sync_sub_and_fetch(p, x));
} }
#elif (defined(_MSC_VER))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
return (InterlockedExchangeAdd(p, x));
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
return (InterlockedExchangeAdd(p, -((int32_t)x)));
}
#elif (defined(JEMALLOC_OSATOMIC)) #elif (defined(JEMALLOC_OSATOMIC))
JEMALLOC_INLINE uint32_t JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x) atomic_add_uint32(uint32_t *p, uint32_t x)

View File

@ -1,6 +1,5 @@
#ifndef JEMALLOC_INTERNAL_H #ifndef JEMALLOC_INTERNAL_H
#define JEMALLOC_INTERNAL_H #define JEMALLOC_INTERNAL_H
#include <sys/param.h>
#include <math.h> #include <math.h>
#ifdef _WIN32 #ifdef _WIN32
# include <windows.h> # include <windows.h>
@ -13,6 +12,7 @@
# undef ERANGE # undef ERANGE
# define ERANGE ERROR_INVALID_DATA # define ERANGE ERROR_INVALID_DATA
#else #else
# include <sys/param.h>
# include <sys/mman.h> # include <sys/mman.h>
# include <sys/syscall.h> # include <sys/syscall.h>
# if !defined(SYS_write) && defined(__NR_write) # if !defined(SYS_write) && defined(__NR_write)
@ -41,7 +41,17 @@
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #ifdef _MSC_VER
# include <io.h>
typedef intptr_t ssize_t;
# define PATH_MAX 1024
# define STDERR_FILENO 2
# define __func__ __FUNCTION__
/* Disable warnings about deprecated system functions */
# pragma warning(disable: 4996)
#else
# include <unistd.h>
#endif
#include <fcntl.h> #include <fcntl.h>
#define JEMALLOC_NO_DEMANGLE #define JEMALLOC_NO_DEMANGLE
@ -221,6 +231,9 @@ static const bool config_ivsalloc =
#else #else
# define JEMALLOC_ENABLE_INLINE # define JEMALLOC_ENABLE_INLINE
# define JEMALLOC_INLINE static inline # define JEMALLOC_INLINE static inline
# ifdef _MSC_VER
# define inline _inline
# endif
#endif #endif
/* Smallest size class to support. */ /* Smallest size class to support. */
@ -232,7 +245,7 @@ static const bool config_ivsalloc =
* classes). * classes).
*/ */
#ifndef LG_QUANTUM #ifndef LG_QUANTUM
# ifdef __i386__ # if (defined(__i386__) || defined(_M_IX86))
# define LG_QUANTUM 4 # define LG_QUANTUM 4
# endif # endif
# ifdef __ia64__ # ifdef __ia64__
@ -244,7 +257,7 @@ static const bool config_ivsalloc =
# ifdef __sparc64__ # ifdef __sparc64__
# define LG_QUANTUM 4 # define LG_QUANTUM 4
# endif # endif
# if (defined(__amd64__) || defined(__x86_64__)) # if (defined(__amd64__) || defined(__x86_64__) || defined(_M_X64))
# define LG_QUANTUM 4 # define LG_QUANTUM 4
# endif # endif
# ifdef __arm__ # ifdef __arm__

View File

@ -109,6 +109,16 @@
# define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s)) # define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s))
# define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s)) # define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s))
# define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline) # define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline)
#elif _MSC_VER
# define JEMALLOC_ATTR(s)
#ifdef DLLEXPORT
# define EXPORT __declspec(dllexport)
#else
# define EXPORT __declspec(dllimport)
#endif
# define JEMALLOC_ALIGNED(s) __declspec(align(s))
# define JEMALLOC_SECTION(s) __declspec(allocate(s))
# define JEMALLOC_NOINLINE __declspec(noinline)
#else #else
# define JEMALLOC_ATTR(s) # define JEMALLOC_ATTR(s)
# define JEMALLOC_EXPORT # define JEMALLOC_EXPORT

View File

@ -0,0 +1,16 @@
#ifndef stdbool_h
#define stdbool_h
#include <wtypes.h>
/* MSVC doesn't define _Bool or bool in C, but does have BOOL */
/* Note this doesn't pass autoconf's test because (bool) 0.5 != true */
typedef BOOL _Bool;
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif /* stdbool_h */

View File

@ -0,0 +1,23 @@
#ifndef strings_h
#define strings_h
/* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided
* for both */
#include <intrin.h>
#pragma intrinsic(_BitScanForward)
static __forceinline int ffsl(long x)
{
unsigned long i;
if (_BitScanForward(&i, x))
return (i + 1);
return (0);
}
static __forceinline int ffs(int x)
{
return (ffsl(x));
}
#endif

View File

@ -56,12 +56,19 @@ static bool malloc_initializer = NO_INITIALIZER;
static malloc_mutex_t init_lock; static malloc_mutex_t init_lock;
JEMALLOC_ATTR(constructor) JEMALLOC_ATTR(constructor)
static void static void WINAPI
init_init_lock() _init_init_lock(void)
{ {
malloc_mutex_init(&init_lock); malloc_mutex_init(&init_lock);
} }
#ifdef _MSC_VER
# pragma section(".CRT$XCU", read)
JEMALLOC_SECTION(".CRT$XCU") JEMALLOC_ATTR(used)
static const void (WINAPI *init_init_lock)(void) = _init_init_lock;
#endif
#else #else
static malloc_mutex_t init_lock = MALLOC_MUTEX_INITIALIZER; static malloc_mutex_t init_lock = MALLOC_MUTEX_INITIALIZER;
#endif #endif

View File

@ -93,6 +93,14 @@ _tls_callback(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
return (true); return (true);
} }
#ifdef _MSC_VER
# ifdef _M_IX86
# pragma comment(linker, "/INCLUDE:__tls_used")
# else
# pragma comment(linker, "/INCLUDE:_tls_used")
# endif
# pragma section(".CRT$XLY",long,read)
#endif
JEMALLOC_SECTION(".CRT$XLY") JEMALLOC_ATTR(used) JEMALLOC_SECTION(".CRT$XLY") JEMALLOC_ATTR(used)
static const BOOL (WINAPI *tls_callback)(HINSTANCE hinstDLL, static const BOOL (WINAPI *tls_callback)(HINSTANCE hinstDLL,
DWORD fdwReason, LPVOID lpvReserved) = _tls_callback; DWORD fdwReason, LPVOID lpvReserved) = _tls_callback;