+/* highest_bit assumes that alloc_type is 32 bits. */
+extern char check_alloc_type_size[(sizeof (alloc_type) == 4) ? 1 : -1];
+
+/* Find the highest set bit in VALUE. Returns the bit number of that
+ bit, using the same values as ffs. */
+static inline alloc_type
+highest_bit (alloc_type value)
+{
+ /* This also assumes that alloc_type is unsigned. */
+ value |= value >> 1;
+ value |= value >> 2;
+ value |= value >> 4;
+ value |= value >> 8;
+ value |= value >> 16;
+ value = value ^ (value >> 1);
+ return alloc_ffs (value);
+}
+
+/* Find the offset from the start of an object to P, which may point
+ into the interior of the object. */
+
+static unsigned long
+zone_find_object_offset (alloc_type *alloc_bits, size_t start_word,
+ size_t start_bit)
+{
+ unsigned int offset_in_bits;
+ alloc_type alloc_word = alloc_bits[start_word];
+
+ /* Mask off any bits after the initial bit, but make sure to include
+ the initial bit in the result. Note that START_BIT is
+ 0-based. */
+ if (start_bit < 8 * sizeof (alloc_type) - 1)
+ alloc_word &= (1 << (start_bit + 1)) - 1;
+ offset_in_bits = start_bit;
+
+ /* Search for the start of the object. */
+ while (alloc_word == 0 && start_word > 0)
+ {
+ alloc_word = alloc_bits[--start_word];
+ offset_in_bits += 8 * sizeof (alloc_type);
+ }
+ /* We must always find a set bit. */
+ gcc_assert (alloc_word != 0);
+ /* Note that the result of highest_bit is 1-based. */
+ offset_in_bits -= highest_bit (alloc_word) - 1;
+
+ return BYTES_PER_ALLOC_BIT * offset_in_bits;
+}
+