The instance size was being reported incorrectly which meant that
associated objects looked for a reference list slightly after the end of
the object.
Fixes#228
CI was failing because a number of our host platforms were no longer
supported. This commit:
- Moves to the latest FreeBSD 12, 13, and 14 branch releases.
- Moves to modern Ubuntu.
- Replaces Windows 2016 with 2022
- Moves from Azure Pipelines to GitHub for the non-FreeBSD tests.
- Fixes some tests that are not reliable in some contexts.
Reorders how locking is handled in `objc_send_initialize()` to prevent a deadlock.
Previously, contention on the low level spinlocks could cause a very intermittent deadlock:
- Thread A : `objc_send_initialize()` holds the runtime lock, then tries to acquire the object lock on the metaclass, which needs to initialize the mutex for the new metaclass inside `referenceListForObject()`, so it tries to lock the `lock_for_pointer()` / `lock_spinlock()`
- Thread B : `referenceListForObject()` holds a spinlock for an unrelated object while running `initHiddenClassForObject()` -> `allocateHiddenClass()`, which tries to acquire the runtime lock
If the metaclass object pointer in Thread A hashes to the same spinlock as the object in thread B, the runtime lock ends up deadlocked forever.
This test used to fail on Windows, because Clang's codegen and transformation haven't been in-line with the requirements of the WinEH backend in LLVM. The following changes implement the missing pieces and let the test to pass in both debug and release mode:
https://reviews.llvm.org/D128190 [WinEH] Apply funclet operand bundles to nounwind intrinsics that lower to function calls in the course of IR transforms
https://reviews.llvm.org/D134441 [ObjC][ARC] Fix target register for call expanded from CALL_RVMARKER on Windows
https://reviews.llvm.org/D137939 [CGObjC] Open cleanup scope before SaveAndRestore CurrentFuncletPad and push CatchRetScope early
https://reviews.llvm.org/D137944 [ObjC][ARC] Teach the OptimizeSequences step of ObjCARCOpts about WinEH funclet tokens
Fixes building for Android arm64-v8a with NDK r25, which no longer supports this flag. Since we were passing this unconditionally we were previously inadvertently disabling NEON support if the flag wasn't set.
This originally came up as an issue with libc++abi support (#152), but is not specific to that ABI.
* Use the C++ runtime to check for uncaught C++ exceptions.
As discussed in #152, use the function defined in the Itanium C++ ABI to
check whether the thrown exception is the current caught C++ exception
and needs rethrowing via `__cxa_rethrow()`.
Co-authored-by: Niels Grewe <grewe@ocean-insights.com>
Co-authored-by: David Chisnall <gnustep@theravensnest.org>
* Add test for emptying autorelease pool
* Fix arc autorelease pool emptying when adding further references
When releasing a reference in the arc autorelease pool, it is
possible and anticipated that new references may added to the pool.
This fix addresses an edge case where releasing a reference in the
same pool page as the stop position can add more references which
cause the insertion of a new page and emptyPool() returns early
after emptying the new page.
This fixes a regression in 73132a6 (#200) where nil was returned
from a retain call after the object begins deallocating. Normal
retains of a deallocating object are still expected to return an
instance pointer inside its dealloc method and code compiled with ARC
will generate calls to objc_storeStrong() when a block captures the
self pointer inside the dealloc method.
The previous checks for a deallocating object with negative reference count did not work because:
1. the sign bit has to be recreated as was happening in objc_delete_weak_refs()
2. there was no distinction between a saturated count and a negative reference count
refcount_max now indicates when the refcount has saturated and should no longer be mutated.
An underflow to -1 still maps to refcount_mask, allowing us to detect when an object is supposed to be deallocated.
Neither objc_release_fast_no_destroy_np() nor objc_retain_fast_np() mutate the refcount when it is one of those values, so the comment in objc_delete_weak_refs() was adjusted.
Add 32-bit x86-Linux builds.
Add building with the nightly LLVM releases. There are some regressions
since LLVM 8 that would have been caught by this that we can hopefully
fix in time for the LLVM 12 release.
When we stopped using CXXFLAGS in eh_personality.s generation, we lost
the ability to propagate -m32 or -target through, so cross-compile
didn't work. These flags are now passed through correctly, so (so
'-pipe -O2' will appear as two arguments, rather than being combined as
a single value that then causes clang to abort with an unknown argument
error, which was the original motivation for this change).
This is the correct fix for #177
The way that we were doing this didn't handle multiple flags and we
actually don't want the user to override these flags because that file
needs to be compiled in a very specific way.
Fixes#177
Several of the hooks were being generated with common linkage in hooks.c
and as normal initialised symbols in sendmsg2.c. Recent clang defaults
to -fno-common, which causes the common linkage versions to become
strong symbols and then causes a linkage failure from duplicate
definitions: one zero initialised, one initialised with a real value.
This removes copy in hooks.c, retaining only the initialised version.
Fixes#171
- Don't try to detect libc++abi. It doesn't actually work, so don't
try it.
- Correctly try to link the standard library.
This should fix the build on GNU/Linux systems with libc++abi.so
installed (including our Ubuntu CI!).
libsupc++ is more aggressive about internal consistency checks than
libcxxrt, so we need to be more careful in the interop. The tests from
PR #138 now pass for me on Debian with libsupc++.
* Make sure the unwind state is synchronised between the Objective-C
and C++ exception objects.
* Reintroduce the is-pointer callback so that `__cxa_begin_catch`
adjusts the pointer correctly. Objective-C++ code uses
`__cxa_begin_catch` without the `objc_begin_catch` wrapper and the
runtime does not call the `__do_catch` method on the type info if the
type info is an exact match, so the caught object ended up being a
pointer to the object. This also meant that we needed to remove the
double dereference in the `__do_catch` methods.
* Introduce a subclass of `std::type_info` for all Objective-C types
and move the `virtual` functions there. This should simplify
supporting libc++abi.
We now, the first time we encounter a foreign exception, throw a C++
exception through a frame that has a custom personality function and
probe the layout of the __cxa_exception structure.
We then use the offsets learned from this along with the public ABI
functions for allocating the structure.
At the same time, add a test that we are correctly setting the count of
uncaught exceptions.
Fixes#146