From: Jonathan Chambers Date: Tue, 6 Feb 2018 08:59:25 +0000 (+0300) Subject: Initial support of WinRT X-Git-Tag: v8.0.0~372 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=548435c68d0a69b72b08e7eb3b8df9d21b9e2fd4;p=platform%2Fupstream%2Flibgc.git Initial support of WinRT (part of commit 9379c66 from Unity-Technologies/bdwgc) Issue #173 (bdwgc). * include/private/gc_priv.h [MSWIN32] (GET_TIME): Use GetTickCount64 if MSWINRT_FLAVOR (instead of GetTickCount). * include/private/gcconfig.h [_MSC_VER && _M_IX86>=300 || _WIN32 && !__CYGWIN__ && !SYMBIAN && _M_ARM] (ARM32): Define macro. * include/private/gcconfig.h [(_MSC_VER && _M_IX86>=300 || _WIN32 && !__CYGWIN__ && !SYMBIAN) && !_XBOX_ONE && WINAPI_FAMILY==WINAPI_FAMILY_APP] (MSWINRT_FLAVOR): Likewise. * include/private/gcconfig.h [MSWINRT_FLAVOR] (NO_GETENV): Likewise. * include/private/gcconfig.h [X86_64 && MSWIN32] (DATAEND): Do not define if already defined. * misc.c [MSWIN32] (GC_win32_MessageBoxA): Do not define if MSWINRT_FLAVOR. * misc.c [MSWIN32] (GC_init): Call InitializeCriticalSectionAndSpinCount() directly if MSWINRT_FLAVOR (instead of using GetProcAddress). * misc.c [MSWIN32 && MSWINRT_FLAVOR]: Include windows.storage.h. * misc.c [MSWIN32 && MSWINRT_FLAVOR] (RoGetActivationFactory): Declare. * misc.c [MSWIN32 && MSWINRT_FLAVOR] (getWinRTLogPath): New static function. * misc.c [MSWIN32 && MSWINRT_FLAVOR] (GC_CreateLogFile): Use getWinRTLogPath(). * os_dep.c [GWW_VDB && MSWINRT_FLAVOR] (detect_GetWriteWatch): Use memInfo.AllocationBase to get hK32. * os_dep.c [USE_WINALLOC && !MSWIN_XBOX1] (GC_win32_get_mem, GC_win32_free_heap): Do not use GlobalAlloc and GlobalFree if MSWINRT_FLAVOR. --- diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 00bd3ea..1892d68 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -432,7 +432,11 @@ typedef char * ptr_t; /* A generic pointer to which we can add */ # include # include # define CLOCK_TYPE DWORD -# define GET_TIME(x) (void)(x = GetTickCount()) +# ifdef MSWINRT_FLAVOR +# define GET_TIME(x) (void)(x = (DWORD)GetTickCount64()) +# else +# define GET_TIME(x) (void)(x = GetTickCount()) +# endif # define MS_TIME_DIFF(a,b) ((long)((a)-(b))) #elif defined(NN_PLATFORM_CTR) # define CLOCK_TYPE long long diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h index a1933ba..c4c69a3 100644 --- a/include/private/gcconfig.h +++ b/include/private/gcconfig.h @@ -521,13 +521,18 @@ && !defined(SYMBIAN)) # if defined(__LP64__) || defined(_WIN64) # define X86_64 -# else +# elif defined(_M_ARM) +# define ARM32 +# else /* _M_IX86 */ # define I386 # endif # ifdef _XBOX_ONE # define MSWIN_XBOX1 # else # define MSWIN32 /* or Win64 */ +# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +# define MSWINRT_FLAVOR +# endif # endif # define mach_type_known # endif @@ -2670,7 +2675,9 @@ # define MPROTECT_VDB # endif # define GWW_VDB -# define DATAEND /* not needed */ +# ifndef DATAEND +# define DATAEND /* not needed */ +# endif # endif # endif /* X86_64 */ @@ -3219,7 +3226,8 @@ # define USE_MARK_BYTES #endif -#if defined(MSWINCE) && !defined(__CEGCC__) && !defined(NO_GETENV) +#if (defined(MSWINCE) && !defined(__CEGCC__) || defined(MSWINRT_FLAVOR)) \ + && !defined(NO_GETENV) # define NO_GETENV #endif diff --git a/misc.c b/misc.c index 2af1f37..6e38c0c 100644 --- a/misc.c +++ b/misc.c @@ -795,7 +795,7 @@ GC_API int GC_CALL GC_is_init_called(void) } #endif -#if defined(MSWIN32) && (!defined(SMALL_CONFIG) \ +#if defined(MSWIN32) && !defined(MSWINRT_FLAVOR) && (!defined(SMALL_CONFIG) \ || (!defined(_WIN64) && defined(GC_WIN32_THREADS) \ && defined(CHECK_NOT_WOW64))) STATIC void GC_win32_MessageBoxA(const char *msg, const char *caption, @@ -927,20 +927,27 @@ GC_API void GC_CALL GC_init(void) # endif # endif /* THREADS */ # if defined(GC_WIN32_THREADS) && !defined(GC_PTHREADS) - { -# ifndef MSWINCE - BOOL (WINAPI *pfn) (LPCRITICAL_SECTION, DWORD) = NULL; - HMODULE hK32 = GetModuleHandle(TEXT("kernel32.dll")); - if (hK32) - pfn = (BOOL (WINAPI *) (LPCRITICAL_SECTION, DWORD)) - GetProcAddress (hK32, - "InitializeCriticalSectionAndSpinCount"); - if (pfn) - pfn(&GC_allocate_ml, 4000); - else -# endif /* !MSWINCE */ - /* else */ InitializeCriticalSection (&GC_allocate_ml); - } +# ifndef SPIN_COUNT +# define SPIN_COUNT 4000 +# endif +# ifdef MSWINRT_FLAVOR + InitializeCriticalSectionAndSpinCount(&GC_allocate_ml, SPIN_COUNT); +# else + { +# ifndef MSWINCE + BOOL (WINAPI *pfn)(LPCRITICAL_SECTION, DWORD) = 0; + HMODULE hK32 = GetModuleHandle(TEXT("kernel32.dll")); + if (hK32) + pfn = (BOOL (WINAPI *)(LPCRITICAL_SECTION, DWORD)) + GetProcAddress(hK32, + "InitializeCriticalSectionAndSpinCount"); + if (pfn) { + pfn(&GC_allocate_ml, SPIN_COUNT); + } else +# endif /* !MSWINCE */ + /* else */ InitializeCriticalSection(&GC_allocate_ml); + } +# endif # endif /* GC_WIN32_THREADS */ # if (defined(MSWIN32) || defined(MSWINCE)) && defined(THREADS) InitializeCriticalSection(&GC_write_cs); @@ -1410,9 +1417,97 @@ GC_API void GC_CALL GC_enable_incremental(void) # define IF_NEED_TO_LOCK(x) # endif /* !THREADS */ +# ifdef MSWINRT_FLAVOR +# include + + /* This API is defined in roapi.h, but we cannot include it here */ + /* since it does not compile in C. */ + DECLSPEC_IMPORT HRESULT WINAPI RoGetActivationFactory( + HSTRING activatableClassId, + REFIID iid, void** factory); + + static GC_bool getWinRTLogPath(wchar_t* buf, size_t bufLen) + { + static const GUID kIID_IApplicationDataStatics = { + 0x5612147B, 0xE843, 0x45E3, + 0x94, 0xD8, 0x06, 0x16, 0x9E, 0x3C, 0x8E, 0x17 + }; + static const GUID kIID_IStorageItem = { + 0x4207A996, 0xCA2F, 0x42F7, + 0xBD, 0xE8, 0x8B, 0x10, 0x45, 0x7A, 0x7F, 0x30 + }; + GC_bool result = FALSE; + HSTRING_HEADER appDataClassNameHeader; + HSTRING appDataClassName; + __x_ABI_CWindows_CStorage_CIApplicationDataStatics* appDataStatics = 0; + + GC_ASSERT(bufLen > 0); + if (SUCCEEDED(WindowsCreateStringReference( + RuntimeClass_Windows_Storage_ApplicationData, + (sizeof(RuntimeClass_Windows_Storage_ApplicationData)-1) + / sizeof(wchar_t), + &appDataClassNameHeader, &appDataClassName)) + && SUCCEEDED(RoGetActivationFactory(appDataClassName, + &kIID_IApplicationDataStatics, + &appDataStatics))) { + __x_ABI_CWindows_CStorage_CIApplicationData* appData = NULL; + __x_ABI_CWindows_CStorage_CIStorageFolder* tempFolder = NULL; + __x_ABI_CWindows_CStorage_CIStorageItem* tempFolderItem = NULL; + HSTRING tempPath = NULL; + + if (SUCCEEDED(appDataStatics->lpVtbl->get_Current(appDataStatics, + &appData)) + && SUCCEEDED(appData->lpVtbl->get_TemporaryFolder(appData, + &tempFolder)) + && SUCCEEDED(tempFolder->lpVtbl->QueryInterface(tempFolder, + &kIID_IStorageItem, + &tempFolderItem)) + && SUCCEEDED(tempFolderItem->lpVtbl->get_Path(tempFolderItem, + &tempPath))) { + UINT32 tempPathLen; + const wchar_t* tempPathBuf = + WindowsGetStringRawBuffer(tempPath, &tempPathLen); + + buf[0] = '\0'; + if (wcsncat_s(buf, bufLen, tempPathBuf, tempPathLen) == 0 + && wcscat_s(buf, bufLen, L"\\") == 0 + && wcscat_s(buf, bufLen, TEXT(GC_LOG_STD_NAME)) == 0) + result = TRUE; + WindowsDeleteString(tempPath); + } + + if (tempFolderItem != NULL) + tempFolderItem->lpVtbl->Release(tempFolderItem); + if (tempFolder != NULL) + tempFolder->lpVtbl->Release(tempFolder); + if (appData != NULL) + appData->lpVtbl->Release(appData); + appDataStatics->lpVtbl->Release(appDataStatics); + } + return result; + } +# endif /* MSWINRT_FLAVOR */ + STATIC HANDLE GC_CreateLogFile(void) { HANDLE hFile; +# ifdef MSWINRT_FLAVOR + TCHAR pathBuf[_MAX_PATH + 0x10]; /* buffer for path + ext */ + + hFile = INVALID_HANDLE_VALUE; + if (getWinRTLogPath(pathBuf, _MAX_PATH + 1)) { + CREATEFILE2_EXTENDED_PARAMETERS extParams; + + BZERO(&extParams, sizeof(extParams)); + extParams.dwSize = sizeof(extParams); + extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; + extParams.dwFileFlags = GC_print_stats == VERBOSE ? 0 + : FILE_FLAG_WRITE_THROUGH; + hFile = CreateFile2(pathBuf, GENERIC_WRITE, FILE_SHARE_READ, + CREATE_ALWAYS, &extParams); + } + +# else TCHAR *logPath; BOOL appendToFile = FALSE; # if !defined(NO_GETENV_WIN32) || !defined(OLD_WIN32_LOG_FILE) @@ -1451,6 +1546,7 @@ GC_API void GC_CALL GC_enable_incremental(void) /* immediately flush writes unless very verbose */ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL /* hTemplateFile */); + # ifndef NO_GETENV_WIN32 if (appendToFile && hFile != INVALID_HANDLE_VALUE) { LONG posHigh = 0; @@ -1458,6 +1554,7 @@ GC_API void GC_CALL GC_enable_incremental(void) /* Seek to file end (ignoring any error) */ } # endif +# endif return hFile; } diff --git a/os_dep.c b/os_dep.c index cd089c7..0155c20 100644 --- a/os_dep.c +++ b/os_dep.c @@ -1644,7 +1644,18 @@ void GC_register_data_segments(void) } # endif - hK32 = GetModuleHandle(TEXT("kernel32.dll")); +# ifdef MSWINRT_FLAVOR + { + MEMORY_BASIC_INFORMATION memInfo; + SIZE_T result = VirtualQuery(GetProcAddress, + &memInfo, sizeof(memInfo)); + if (result != sizeof(memInfo)) + ABORT("Weird VirtualQuery result"); + hK32 = (HMODULE)memInfo.AllocationBase; + } +# else + hK32 = GetModuleHandle(TEXT("kernel32.dll")); +# endif if (hK32 != (HMODULE)0 && (GetWriteWatch_func = (GetWriteWatch_type)GetProcAddress(hK32, "GetWriteWatch")) != NULL) { @@ -2352,7 +2363,7 @@ void * os2_alloc(size_t bytes) # ifndef USE_WINALLOC result = GC_unix_get_mem(bytes); # else -# ifdef MSWIN32 +# if defined(MSWIN32) && !defined(MSWINRT_FLAVOR) if (GLOBAL_ALLOC_TEST) { /* VirtualAlloc doesn't like PAGE_EXECUTE_READWRITE. */ /* There are also unconfirmed rumors of other */ @@ -2409,26 +2420,27 @@ void * os2_alloc(size_t bytes) GC_API void GC_CALL GC_win32_free_heap(void) { -# ifndef CYGWIN32 - if (GLOBAL_ALLOC_TEST) -# endif - { - while (GC_n_heap_bases-- > 0) { -# ifdef CYGWIN32 - /* FIXME: Is it OK to use non-GC free() here? */ -# else - GlobalFree(GC_heap_bases[GC_n_heap_bases]); -# endif - GC_heap_bases[GC_n_heap_bases] = 0; - } - } /* else */ -# ifndef CYGWIN32 - else { - /* Avoiding VirtualAlloc leak. */ - while (GC_n_heap_bases > 0) { - VirtualFree(GC_heap_bases[--GC_n_heap_bases], 0, MEM_RELEASE); +# ifndef MSWINRT_FLAVOR +# ifndef CYGWIN32 + if (GLOBAL_ALLOC_TEST) +# endif + { + while (GC_n_heap_bases-- > 0) { +# ifdef CYGWIN32 + /* FIXME: Is it OK to use non-GC free() here? */ +# else + GlobalFree(GC_heap_bases[GC_n_heap_bases]); +# endif GC_heap_bases[GC_n_heap_bases] = 0; } + return; + } +# endif +# ifndef CYGWIN32 + /* Avoiding VirtualAlloc leak. */ + while (GC_n_heap_bases > 0) { + VirtualFree(GC_heap_bases[--GC_n_heap_bases], 0, MEM_RELEASE); + GC_heap_bases[GC_n_heap_bases] = 0; } # endif }