Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/libgc
diff options
context:
space:
mode:
authorZoltan Varga <vargaz@gmail.com>2013-05-25 01:41:39 +0400
committerZoltan Varga <vargaz@gmail.com>2013-05-25 01:41:50 +0400
commitbab31bcb5831e5d8480e1f84d389402e5bd6c6ac (patch)
tree5a554b9730a923aec417c9a96bbefea0f4594016 /libgc
parenta6d12819a7223aa352a7ec63afb84865bc09d48a (diff)
Merge some Nacl/ARM changes from https://github.com/igotti-google/mono/commit/65d8d68e8c81cf6adb1076de7a9425c84cab86a3.
Diffstat (limited to 'libgc')
-rw-r--r--libgc/include/private/gc_locks.h27
-rw-r--r--libgc/include/private/gcconfig.h2
-rw-r--r--libgc/include/private/pthread_stop_world.h5
-rw-r--r--libgc/pthread_stop_world.c19
4 files changed, 34 insertions, 19 deletions
diff --git a/libgc/include/private/gc_locks.h b/libgc/include/private/gc_locks.h
index 80712fcdf3f..e95cec0b4c1 100644
--- a/libgc/include/private/gc_locks.h
+++ b/libgc/include/private/gc_locks.h
@@ -223,22 +223,22 @@
# define GC_CLEAR_DEFINED
# endif /* ALPHA */
# ifdef ARM32
-#ifdef __native_client__
-#define NACL_ALIGN() ".align 4\n"
-#define MASK_REGISTER(reg) "bic " reg ", " reg ", #0xc0000000\n"
-#else
-#define NACL_ALIGN()
-#define MASK_REGISTER(reg)
-#endif
+# ifdef __native_client__
+# define MASK_REGISTER(reg, cond) "bic" cond " " reg ", " reg ", #0xc0000000\n"
+# define NACL_ALIGN() ".align 4\n"
+# else
+# define MASK_REGISTER(reg, cond)
+# define NACL_ALIGN()
+# endif
inline static int GC_test_and_set(volatile unsigned int *addr) {
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7__)
int ret, tmp;
__asm__ __volatile__ (
"1:\n"
NACL_ALIGN()
- MASK_REGISTER("%3")
+ MASK_REGISTER("%3", "al")
"ldrex %0, [%3]\n"
- MASK_REGISTER("%3")
+ MASK_REGISTER("%3", "al")
"strex %1, %2, [%3]\n"
"teq %1, #0\n"
"bne 1b\n"
@@ -252,7 +252,7 @@
* bus because there are no SMP ARM machines. If/when there are,
* this code will likely need to be updated. */
/* See linuxthreads/sysdeps/arm/pt-machine.h in glibc-2.1 */
- __asm__ __volatile__(MASK_REGISTER("%2")
+ __asm__ __volatile__(MASK_REGISTER("%2", "al")
"swp %0, %1, [%2]"
: "=&r"(oldval)
: "r"(1), "r"(addr)
@@ -264,11 +264,18 @@
inline static void GC_clear(volatile unsigned int *addr) {
#ifdef HAVE_ARMV6
/* Memory barrier */
+#ifdef __native_client__
+ /* NaCl requires ARMv7 CPUs. */
+ __asm__ __volatile__("dsb" : : : "memory");
+#else
__asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory");
#endif
+#endif
*(addr) = 0;
}
# define GC_CLEAR_DEFINED
+# undef NACL_ALIGN
+# undef MASK_REGISTER
# endif /* ARM32 */
# ifdef CRIS
inline static int GC_test_and_set(volatile unsigned int *addr) {
diff --git a/libgc/include/private/gcconfig.h b/libgc/include/private/gcconfig.h
index c264b164a41..418e046ae12 100644
--- a/libgc/include/private/gcconfig.h
+++ b/libgc/include/private/gcconfig.h
@@ -67,7 +67,7 @@
/* Determine the machine type: */
# if defined(__native_client__)
# define NACL
-# if !defined(__portable_native_client__)
+# if !defined(__portable_native_client__) && !defined(__arm__)
# define I386
# define mach_type_known
# else
diff --git a/libgc/include/private/pthread_stop_world.h b/libgc/include/private/pthread_stop_world.h
index bd72739f580..e285a9a24ba 100644
--- a/libgc/include/private/pthread_stop_world.h
+++ b/libgc/include/private/pthread_stop_world.h
@@ -13,7 +13,12 @@ struct thread_stop_info {
/* the instrumented function uses any callee saved registers, they may */
/* be pushed to the stack much earlier. Also, on amd64 'push' puts 8 */
/* bytes on the stack even though our pointers are 4 bytes. */
+#ifdef __arm__
+/* For ARM we save r4-r8, r10-r12, r14 */
+#define NACL_GC_REG_STORAGE_SIZE 9
+#else
#define NACL_GC_REG_STORAGE_SIZE 20
+#endif
ptr_t reg_storage[NACL_GC_REG_STORAGE_SIZE];
#endif
};
diff --git a/libgc/pthread_stop_world.c b/libgc/pthread_stop_world.c
index fe2ba1a3810..334ff1de219 100644
--- a/libgc/pthread_stop_world.c
+++ b/libgc/pthread_stop_world.c
@@ -540,14 +540,17 @@ static void pthread_stop_world()
#elif __arm__
#define NACL_STORE_REGS() \
- do { \
- __asm__ __volatile__ ("push {r4-r12,lr}");\
- __asm__ __volatile__ ("mov r0, %0" : : "r" (&nacl_gc_thread_self->stop_info.stack_ptr)); \
- __asm__ __volatile__ ("bic r0, r0, #0xc0000000");\
- __asm__ __volatile__ ("str sp, [r0]");\
- memcpy(nacl_gc_thread_self->stop_info.reg_storage, nacl_gc_thread_self->stop_info.stack_ptr, NACL_GC_REG_STORAGE_SIZE * sizeof(ptr_t));\
- __asm__ __volatile__ ("add sp, sp, #40");\
- __asm__ __volatile__ ("bic sp, sp, #0xc0000000");\
+ do { \
+ __asm__ __volatile__ ( \
+ ".align 4\n\t" \
+ "bic %0, %0, #0xc0000000\n\t" \
+ "str sp, [%0]\n\t" \
+ "bic %1, %1, #0xc0000000\n\t" \
+ "stm %1, {r4-r8,r10-r12,lr}\n\t" \
+ : \
+ : "r" (&nacl_gc_thread_self->stop_info.stack_ptr), \
+ "r"(nacl_gc_thread_self->stop_info.reg_storage) \
+ : "memory"); \
} while (0)
#else