summaryrefslogtreecommitdiff
path: root/darwin_stop_world.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2015-02-28 23:01:14 +0300
committerIvan Maidanski <ivmai@mail.ru>2015-03-07 16:18:03 +0300
commitb51a05f39899bddbe97bb6a7ad86d15d6d0289d8 (patch)
treee2254b704cf093b993da5808ca0b630f02d64417 /darwin_stop_world.c
parent1741274f2a746d4ed9d3c2eb0463c7caefe7e3f9 (diff)
parent5e756d4d8df2949cb3b6e51532d3016cbb276fd7 (diff)
downloadbdwgc-b51a05f39899bddbe97bb6a7ad86d15d6d0289d8.tar.gz
Merge branch 'master' into ios-unified-ts-fix
Conflicts: include/private/gc_priv.h
Diffstat (limited to 'darwin_stop_world.c')
-rw-r--r--darwin_stop_world.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/darwin_stop_world.c b/darwin_stop_world.c
index 04e978e1..fc747f53 100644
--- a/darwin_stop_world.c
+++ b/darwin_stop_world.c
@@ -21,6 +21,10 @@
#if defined(GC_DARWIN_THREADS)
+#include <sys/sysctl.h>
+#include <mach/machine.h>
+#include <CoreFoundation/CoreFoundation.h>
+
/* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple
Page 49:
"The space beneath the stack pointer, where a new stack frame would normally
@@ -118,6 +122,10 @@ GC_API void GC_CALL GC_use_threads_discovery(void)
# endif
}
+#ifndef kCFCoreFoundationVersionNumber_iOS_8_0
+# define kCFCoreFoundationVersionNumber_iOS_8_0 1140.1
+#endif
+
/* Evaluates the stack range for a given thread. Returns the lower */
/* bound and sets *phi to the upper one. */
STATIC ptr_t GC_stack_range_for(ptr_t *phi, thread_act_t thread, GC_thread p,
@@ -142,13 +150,41 @@ STATIC ptr_t GC_stack_range_for(ptr_t *phi, thread_act_t thread, GC_thread p,
/* everywhere. Hence we use our own version. Alternatively, */
/* we could use THREAD_STATE_MAX (but seems to be not optimal). */
kern_return_t kern_result;
- mach_msg_type_number_t thread_state_count = GC_MACH_THREAD_STATE_COUNT;
GC_THREAD_STATE_T state;
- /* Get the thread state (registers, etc) */
- kern_result = thread_get_state(thread, GC_MACH_THREAD_STATE,
- (natural_t *)&state,
- &thread_state_count);
+# if defined(ARM32) && defined(ARM_THREAD_STATE32)
+ /* Use ARM_UNIFIED_THREAD_STATE on iOS8+ 32-bit targets and on */
+ /* 64-bit H/W (iOS7+ 32-bit mode). */
+ size_t size;
+ static cpu_type_t cputype = 0;
+
+ if (cputype == 0) {
+ sysctlbyname("hw.cputype", &cputype, &size, NULL, 0);
+ }
+ if (cputype == CPU_TYPE_ARM64
+ || kCFCoreFoundationVersionNumber
+ >= kCFCoreFoundationVersionNumber_iOS_8_0) {
+ arm_unified_thread_state_t unified_state;
+ mach_msg_type_number_t unified_thread_state_count
+ = ARM_UNIFIED_THREAD_STATE_COUNT;
+
+ kern_result = thread_get_state(thread, ARM_UNIFIED_THREAD_STATE,
+ (natural_t *)&unified_state,
+ &unified_thread_state_count);
+ if (unified_state.ash.flavor != ARM_THREAD_STATE32) {
+ ABORT("unified_state flavor should be ARM_THREAD_STATE32");
+ }
+ state = unified_state.ts_32;
+ } else
+# endif
+ /* else */ {
+ mach_msg_type_number_t thread_state_count = GC_MACH_THREAD_STATE_COUNT;
+
+ /* Get the thread state (registers, etc) */
+ kern_result = thread_get_state(thread, GC_MACH_THREAD_STATE,
+ (natural_t *)&state,
+ &thread_state_count);
+ }
# ifdef DEBUG_THREADS
GC_log_printf("thread_get_state returns value = %d\n", kern_result);
# endif