Initial support of Xbox One (DURANGO) target
authorJonathan Chambers <joncham@gmail.com>
Tue, 30 Jan 2018 07:32:38 +0000 (10:32 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 30 Jan 2018 07:32:38 +0000 (10:32 +0300)
(part of commit 9379c66 from Unity-Technologies/bdwgc)

Issue #173 (bdwgc).

* include/private/gc_priv.h [THREADS && MSWIN_XBOX1] (GC_write_cs):
Declare.
* include/private/gcconfig.h [(_MSC_VER && _M_IX86 >= 300 || _WIN32)
&& _XBOX_ONE] (MSWIN_XBOX1): Define (instead of MSWIN32).
* include/private/gcconfig.h [X86_64 && MSWIN_XBOX1] (NO_GETENV,
DATASTART, DATAEND, STACKBOTTOM, GETPAGESIZE, USE_MMAP, PROT_NONE,
PROT_READ, PROT_WRITE, PROT_EXEC, MAP_PRIVATE, MAP_FIXED, MAP_FAILED):
Define.
* include/private/gcconfig.h [X86_64 && MSWIN_XBOX1]
(durango_get_stack_bottom): Declare external function.
* include/private/gcconfig.h [USE_MUNMAP && !MUNMAP_THRESHOLD
&& MSWIN_XBOX1] (MUNMAP_THRESHOLD): Define to 2; update comment.
* include/private/gcconfig.h [GC_WIN32_THREADS && !CYGWIN32
&& !MSWIN32 && !MSWINCE]: Do not issue #error if MSWIN_XBOX1.
* include/private/gcconfig.h [MSWIN_XBOX1] (durango_get_mem): Declare
function.
* include/private/gcconfig.h [MSWIN_XBOX1] (GET_MEM): Define.
* mark_rts.c [DYNAMIC_LOADING] (GC_cond_register_dynamic_libraries):
Do not call GC_remove_tmp_roots and GC_register_dynamic_libraries
if MSWIN_XBOX1 (set GC_no_dls to true instead).
* misc.c [MSWIN_XBOX1 && THREADS] (GC_write_cs): Define variable.
* misc.c [!MSWIN32 && !MSWINCE && !OS2 && !MACOS && !GC_ANDROID_LOG
&& !NN_PLATFORM_CTR && !NINTENDO_SWITCH && !AMIGA && !SN_TARGET_ORBIS
&& !__CC_ARM]: Do not include unistd.h if MSWIN_XBOX1.
* os_dep.c [!OS2 && !PCR && !AMIGA && !MACOS && !MSWINCE
&& !SN_TARGET_ORBIS && !__CC_ARM && !MSWIN32]: Likewise.
* os_dep.c [MMAP_SUPPORTED && MSWIN_XBOX1] (durango_get_mem): Define
new internal function.
* os_dep.c [!MSWINCE && USE_WINALLOC] (GLOBAL_ALLOC_TEST,
GC_mem_top_down, GC_win32_get_mem, GC_win32_free_heap): Do not define
if MSWIN_XBOX1.
* win32_threads.c [!CYGWIN32 && !MSWINCE] (GC_beginthreadex): Likewise.
* os_dep.c [USE_MUNMAP && !NN_PLATFORM_CTR && !MSWIN32 && !MSWINCE]:
Do not include unistd.h, sys/mman.h, sys/stat.h, sys/types.h if
MSWIN_XBOX1.
* win32_threads.c [GC_ASSERTIONS] (GC_write_disabled): Define only if
MSWIN32 or MSWINCE.
* win32_threads.c [GC_ASSERTIONS] (GC_stop_world): Do not use
GC_write_disabled if MSWIN_XBOX1.
* win32_threads.c [PARALLEL_MARK && !GC_PTHREADS_PARAMARK
&& MSWIN_XBOX1] (GC_start_mark_threads_inner): Use CreateThread()
instead of _beginthreadex().

include/private/gc_priv.h
include/private/gcconfig.h
mark_rts.c
misc.c
os_dep.c
win32_threads.c

index fae2888..14a4926 100644 (file)
@@ -2293,14 +2293,14 @@ GC_EXTERN signed_word GC_bytes_found;
 #endif
 
 #ifdef THREADS
-# if defined(MSWIN32) || defined(MSWINCE)
+# if defined(MSWIN32) || defined(MSWINCE) || defined(MSWIN_XBOX1)
     GC_EXTERN CRITICAL_SECTION GC_write_cs; /* defined in misc.c */
-#   ifdef GC_ASSERTIONS
-      GC_EXTERN GC_bool GC_write_disabled;
+# endif
+# if defined(GC_ASSERTIONS) && (defined(MSWIN32) || defined(MSWINCE))
+    GC_EXTERN GC_bool GC_write_disabled;
                                 /* defined in win32_threads.c;  */
                                 /* protected by GC_write_cs.    */
 
-#   endif
 # endif
 # ifdef MPROTECT_VDB
     GC_EXTERN volatile AO_TS_t GC_fault_handler_lock;
index 6ddc98e..aae4d74 100644 (file)
 #     else
 #       define I386
 #     endif
-#     define MSWIN32    /* or Win64 */
+#     ifdef _XBOX_ONE
+#       define MSWIN_XBOX1
+#     else
+#       define MSWIN32  /* or Win64 */
+#     endif
 #     define mach_type_known
 #   endif
 #   if defined(_MSC_VER) && defined(_M_IA64)
 #         define HEAP_START DATAEND
 #       endif
 #   endif
+#   ifdef MSWIN_XBOX1
+#     define NO_GETENV
+#     define DATASTART (ptr_t)ALIGNMENT
+#     define DATAEND (ptr_t)ALIGNMENT
+      LONG64 durango_get_stack_bottom(void);
+#     define STACKBOTTOM ((ptr_t)durango_get_stack_bottom())
+#     define GETPAGESIZE() 4096
+#     ifndef USE_MMAP
+#       define USE_MMAP
+#     endif
+      /* The following is from sys/mman.h:  */
+#     define PROT_NONE  0
+#     define PROT_READ  1
+#     define PROT_WRITE 2
+#     define PROT_EXEC  4
+#     define MAP_PRIVATE 2
+#     define MAP_FIXED  0x10
+#     define MAP_FAILED ((void *)-1)
+#   endif
 #   ifdef MSWIN32
 #       define OS_TYPE "MSWIN32"
                 /* STACKBOTTOM and DATASTART are handled specially in   */
 # define MMAP_SUPPORTED
 #endif
 
-/* Sony PS/3 may not need to be this aggressive, but the default is     */
-/* likely too lax under heavy allocation pressure.  The platform does   */
-/* not have a virtual paging system, so it does not have a large        */
-/* virtual address space that a standard x64 platform has.              */
+/* Xbox One (DURANGO) may not need to be this aggressive, but the       */
+/* default is likely too lax under heavy allocation pressure.           */
+/* The platform does not have a virtual paging system, so it does not   */
+/* have a large virtual address space that a standard x64 platform has. */
 #if defined(USE_MUNMAP) && !defined(MUNMAP_THRESHOLD) \
-    && (defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3))
+    && (defined(SN_TARGET_ORBIS) || defined(SN_TARGET_PS3) \
+        || defined(MSWIN_XBOX1))
 # define MUNMAP_THRESHOLD 2
 #endif
 
 #if defined(GC_AIX_THREADS) && !defined(_AIX)
 # error --> inconsistent configuration
 #endif
-#if defined(GC_WIN32_THREADS) && !defined(MSWIN32) && !defined(CYGWIN32) \
-    && !defined(MSWINCE)
+#if defined(GC_WIN32_THREADS) && !defined(CYGWIN32) && !defined(MSWIN32) \
+    && !defined(MSWINCE) && !defined(MSWIN_XBOX1)
 # error --> inconsistent configuration
 #endif
 # if defined(GC_WIN32_PTHREADS) && defined(CYGWIN32)
                                             SIZET_SAT_ADD(bytes, \
                                                           GC_page_size)) \
                                   + GC_page_size - 1)
+# elif defined(MSWIN_XBOX1)
+    void *durango_get_mem(size_t bytes, size_t page_size);
+#   define GET_MEM(bytes) (struct hblk *)durango_get_mem(bytes, 0)
 # elif defined(MSWIN32) || defined(CYGWIN32)
     ptr_t GC_win32_get_mem(size_t bytes);
 #   define GET_MEM(bytes) (struct hblk *)GC_win32_get_mem(bytes)
index 00d5450..5aca8be 100644 (file)
@@ -758,8 +758,9 @@ STATIC void GC_push_gc_structures(void)
 
 GC_INNER void GC_cond_register_dynamic_libraries(void)
 {
-# if defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE) \
-     || defined(CYGWIN32) || defined(PCR)
+# if (defined(DYNAMIC_LOADING) && !defined(MSWIN_XBOX1)) \
+     || defined(CYGWIN32) || defined(MSWIN32) || defined(MSWINCE) \
+     || defined(PCR)
     GC_remove_tmp_roots();
     if (!GC_no_dls) GC_register_dynamic_libraries();
 # else
diff --git a/misc.c b/misc.c
index 73d24d2..02dde3e 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -712,8 +712,9 @@ GC_API int GC_CALL GC_is_init_called(void)
   return GC_is_initialized;
 }
 
-#if (defined(MSWIN32) || defined(MSWINCE)) && defined(THREADS)
-    GC_INNER CRITICAL_SECTION GC_write_cs;
+#if (defined(MSWIN32) || defined(MSWINCE) || defined(MSWIN_XBOX1)) \
+    && defined(THREADS)
+  GC_INNER CRITICAL_SECTION GC_write_cs;
 #endif
 
 #ifndef DONT_USE_ATEXIT
@@ -1549,7 +1550,8 @@ GC_API void GC_CALL GC_enable_incremental(void)
 #   define WRITE(level, buf, len) switch_log_write(buf, len)
 
 #else
-# if !defined(AMIGA) && !defined(SN_TARGET_ORBIS) && !defined(__CC_ARM)
+# if !defined(AMIGA) && !defined(MSWIN_XBOX1) && !defined(SN_TARGET_ORBIS) \
+     && !defined(__CC_ARM)
 #   include <unistd.h>
 # endif
 
index a4f4a92..dda1abe 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -19,7 +19,7 @@
 #if !defined(OS2) && !defined(PCR) && !defined(AMIGA) && !defined(MACOS) \
     && !defined(MSWINCE) && !defined(SN_TARGET_ORBIS) && !defined(__CC_ARM)
 # include <sys/types.h>
-# if !defined(MSWIN32)
+# if !defined(MSWIN32) && !defined(MSWIN_XBOX1)
 #   include <unistd.h>
 # endif
 #endif
@@ -2114,8 +2114,17 @@ void GC_register_data_segments(void)
   extern char* GC_get_private_path_and_zero_file(void);
 #endif
 
-STATIC ptr_t GC_unix_mmap_get_mem(size_t bytes)
-{
+# ifdef MSWIN_XBOX1
+    void *durango_get_mem(size_t bytes, size_t page_size)
+    {
+      if (0 == bytes) return NULL;
+      return VirtualAlloc(NULL, bytes, MEM_COMMIT | MEM_TOP_DOWN,
+                          PAGE_READWRITE);
+    }
+
+# else
+  STATIC ptr_t GC_unix_mmap_get_mem(size_t bytes)
+  {
     void *result;
     static ptr_t last_addr = HEAP_START;
 
@@ -2164,9 +2173,10 @@ STATIC ptr_t GC_unix_mmap_get_mem(size_t bytes)
       ABORT(
        "GC_unix_get_mem: Memory returned by mmap is not aligned to HBLKSIZE.");
     return((ptr_t)result);
-}
+  }
+# endif  /* !MSWIN_XBOX1 */
 
-# endif  /* MMAP_SUPPORTED */
+#endif  /* MMAP_SUPPORTED */
 
 #if defined(USE_MMAP)
   ptr_t GC_unix_get_mem(size_t bytes)
@@ -2316,7 +2326,7 @@ void * os2_alloc(size_t bytes)
     return(result);
   }
 
-#elif defined(USE_WINALLOC) || defined(CYGWIN32)
+#elif (defined(USE_WINALLOC) && !defined(MSWIN_XBOX1)) || defined(CYGWIN32)
 
 # ifdef USE_GLOBAL_ALLOC
 #   define GLOBAL_ALLOC_TEST 1
@@ -2448,7 +2458,8 @@ void * os2_alloc(size_t bytes)
 /* systems.  If you have something else, don't define           */
 /* USE_MUNMAP.                                                  */
 
-#if !defined(NN_PLATFORM_CTR) && !defined(MSWIN32) && !defined(MSWINCE)
+#if !defined(NN_PLATFORM_CTR) && !defined(MSWIN32) && !defined(MSWINCE) \
+    && !defined(MSWIN_XBOX1)
 # include <unistd.h>
 # ifdef SN_TARGET_PS3
 #   include <sys/memory.h>
index bc8abdf..c0b99e9 100644 (file)
@@ -1204,7 +1204,7 @@ STATIC void GC_suspend(GC_thread t)
     GC_on_thread_event(GC_EVENT_THREAD_SUSPENDED, THREAD_HANDLE(t));
 }
 
-#if defined(GC_ASSERTIONS) && !defined(CYGWIN32)
+#if defined(GC_ASSERTIONS) && (defined(MSWIN32) || defined(MSWINCE))
   GC_INNER GC_bool GC_write_disabled = FALSE;
                 /* TRUE only if GC_stop_world() acquired GC_write_cs.   */
 #endif
@@ -1230,15 +1230,17 @@ GC_INNER void GC_stop_world(void)
     GC_please_stop = TRUE;
 # endif
 # ifndef CYGWIN32
-    GC_ASSERT(!GC_write_disabled);
+#   ifndef MSWIN_XBOX1
+      GC_ASSERT(!GC_write_disabled);
+#   endif
     EnterCriticalSection(&GC_write_cs);
+# endif
+# if defined(GC_ASSERTIONS) && (defined(MSWIN32) || defined(MSWINCE))
     /* It's not allowed to call GC_printf() (and friends) here down to  */
     /* LeaveCriticalSection (same applies recursively to GC_suspend,    */
     /* GC_delete_gc_thread_no_free, GC_get_max_thread_index, GC_size    */
     /* and GC_remove_protection).                                       */
-#   ifdef GC_ASSERTIONS
-      GC_write_disabled = TRUE;
-#   endif
+    GC_write_disabled = TRUE;
 # endif
 # ifndef GC_NO_THREADS_DISCOVERY
     if (GC_win32_dll_threads) {
@@ -1271,10 +1273,10 @@ GC_INNER void GC_stop_world(void)
       }
     }
   }
+# if defined(GC_ASSERTIONS) && (defined(MSWIN32) || defined(MSWINCE))
+    GC_write_disabled = FALSE;
+# endif
 # ifndef CYGWIN32
-#   ifdef GC_ASSERTIONS
-      GC_write_disabled = FALSE;
-#   endif
     LeaveCriticalSection(&GC_write_cs);
 # endif
 # ifdef PARALLEL_MARK
@@ -1991,7 +1993,7 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
       }
 
       for (i = 0; i < GC_markers_m1; ++i) {
-#       ifdef MSWINCE
+#       if defined(MSWINCE) || defined(MSWIN_XBOX1)
           HANDLE handle;
           DWORD thread_id;
 
@@ -2271,8 +2273,7 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
     ExitThread(dwExitCode);
   }
 
-# if !defined(MSWINCE) && !defined(CYGWIN32)
-
+# if !defined(CYGWIN32) && !defined(MSWINCE) && !defined(MSWIN_XBOX1)
     GC_API GC_uintptr_t GC_CALL GC_beginthreadex(
                                   void *security, unsigned stack_size,
                                   unsigned (__stdcall *start_address)(void *),
@@ -2323,8 +2324,7 @@ GC_INNER void GC_get_next_stack(char *start, char *limit,
       GC_unregister_my_thread();
       _endthreadex(retval);
     }
-
-# endif /* !MSWINCE && !CYGWIN32 */
+# endif /* !CYGWIN32 && !MSWINCE && !MSWIN_XBOX1 */
 
 #ifdef GC_WINMAIN_REDIRECT
   /* This might be useful on WinCE.  Shouldn't be used with GC_DLL.     */