summaryrefslogtreecommitdiff
path: root/src/alloc.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2012-03-01 18:29:30 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2012-03-01 18:29:30 -0800
commit9d6b4d53469a9ffd67bd770fabc6fe254e35c21d (patch)
treede238c6f707915be9ed1f10235589b4e975a08fb /src/alloc.c
parenta89654f8f34114db543cb91363e8fded6d73e986 (diff)
parenteec1549a6b89359b6d970f14dead275e59b7bc6f (diff)
downloademacs-9d6b4d53469a9ffd67bd770fabc6fe254e35c21d.tar.gz
Merge from trunk.
Diffstat (limited to 'src/alloc.c')
-rw-r--r--src/alloc.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/alloc.c b/src/alloc.c
index c4db234aba5..6e4cfa07fa0 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -1582,6 +1582,21 @@ make_number (EMACS_INT n)
}
#endif
+/* Convert the pointer-sized word P to EMACS_INT while preserving its
+ type and ptr fields. */
+static Lisp_Object
+widen_to_Lisp_Object (void *p)
+{
+ intptr_t i = (intptr_t) p;
+#ifdef USE_LISP_UNION_TYPE
+ Lisp_Object obj;
+ obj.i = i;
+ return obj;
+#else
+ return i;
+#endif
+}
+
/***********************************************************************
String Allocation
***********************************************************************/
@@ -4294,7 +4309,19 @@ mark_memory (void *start, void *end)
for (pp = start; (void *) pp < end; pp++)
for (i = 0; i < sizeof *pp; i += GC_POINTER_ALIGNMENT)
- mark_maybe_pointer (*(void **) ((char *) pp + i));
+ {
+ void *w = *(void **) ((char *) pp + i);
+ mark_maybe_pointer (w);
+
+#ifdef USE_LSB_TAG
+ /* A host where a Lisp_Object is wider than a pointer might
+ allocate a Lisp_Object in non-adjacent halves. If
+ USE_LSB_TAG, the bottom half is not a valid pointer, so
+ widen it to to a Lisp_Object and check it that way. */
+ if (sizeof w < sizeof (Lisp_Object))
+ mark_maybe_object (widen_to_Lisp_Object (w));
+#endif
+ }
}
/* setjmp will work with GCC unless NON_SAVING_SETJMP is defined in