Coverage checking of the test suite showed that objc_disposeClassPair
wasn't tested at all, which then led to discovering that it didn't
unregister the class.
This cleans up handling of objects that are not reference counted and
makes their interactions with ARC more consistent. We should probably
generalise this somewhat - it currently special cases NSConstantString
and NSGlobalBlock, but it would be nice to have an API for constant
objects.
This test was accidentally passing sometimes, with the isa pointer being
set using some bit of memory in inter-object padding. This breaks
horribly with an allocator that packs objects densely.
Fix type of `__cxa_allocate_exception` with recent libsupc++.
Recent versions of GNU libsupc++ provide a definition of `__cxa_allocate_exception` that has a `noexcept` qualifier. This is sensible (if allocating an exception throws an exception, then something is badly wrong) but it not what the ABI spec says. We provide our own definition of this, which must match another if provided.
This wouldn't normally be a problem, but recent libstdc++ headers appear to leak libsupc++ headers into the namespace, so we're seeing these definitions even without explicitly including any C++ ABI-related headers.
Without this fix, we would lose associated objects silently after adding
the 11th. We would also allocate full pages for each object after the
11th because we couldn't find empty slots.
* use fiber local storage if NO_PTHREADS is defined
* use critical sections instead of mutexes
Contributing-author: Ben Viglietta <benvi@microsoft.com>
It looks like this was the initial intent of 4ea82e1, but as implemented
it would still only scan the unresolved class list once. Since
unresolved_class_list represents the head and classes are pushed onto
the head, any classes added to the resolution list after resolution
started would be skipped.
This commit fixes a data loss bug in our hopscotch table implementation.
Removing values from the table can result in other values becoming
disconnected and lost.
Let A, B, and C be values that all hash to cell 0.
Assume the hopscotch distance factor H = 2.
0 1 2
+-----+-----+-----+
| | | |
+-----+-----+-----+
After adding A
0 1 2
+-----+-----+-----+
| A | | |
+-----+-----+-----+
|
+-Neighbors =
After adding B
0 1 2
+-----+-----+-----+
| A | B | |
+-----+-----+-----+
|
+-Neighbors = 1
After adding C
0 1 2
+-----+-----+-----+
| A | B | C |
+-----+-----+-----+
|
+-Neighbors = 1, 2
If we then remove B,
0 1 2
+-----+-----+-----+
| A | [X] | C |
+-----+-----+-----+
|
+-Neighbors = 1, 2
* It is replaced with a placeholder [X].
* A's neighbor table is not updated to reflect the loss.
If we then remove A,
0 1 2
+-----+-----+-----+
| [X] | [X] | [C] |
+-----+-----+-----+
|
+-Neighbors = 2
* The table is rebalanced to promote A's lowest neighbor to the primary
cell position.
* C from cell 2 remains cell 0's neighbor.
The bug manifests if [X] the placeholder value passes the null check set
out in MAP_TABLE_VALUE_NULL; that is, the placeholder is "effectively
null".
Looking up the key that matches C will first evaluate its base cell, the
one that collided with the key in the first place. Since that is
placeholder [X], and [X] is "effectively null", the lookup stops.
C is never retrieved from the hash table.
---
The expedient solution to this bug is to update cell 0's neighbors when
B is first removed, effectively skipping the hole:
If we remove B as above,
0 1 2
+-----+-----+-----+
| A | [X] | C |
+-----+-----+-----+
|
+-Neighbors = 2 <<< HERE
but clear the neighbor bit for cell 1, the promotion that happens when A
is later removed places C in cell 0.
0 1 2
+-----+-----+-----+
| C | [X] | [X] |
+-----+-----+-----+
|
+-Neighbors =
macOS ships with libc++abi, which doesn't provide the hooks required
for interop, so this was causing all of the tests to fail to link in
the Travis macOS test. We're now correctly detecting that it won't
work on macOS and disabling those tests.