Skip to content

Commit bf9fc46

Browse files
AustinWiseMichalStrehovskyAaronRobinsonMSFT
authored
[NativeAOT] Objective-C Marshal: object tracker support (#78280)
* NativeAOT Objective-C Marshal: object tracker support * Remove support for registering multiple begin/end callbacks, since the API was not designed with multiple managed worlds in mind. * Use more asserts where it should not be possible for there to be no callback. * Add missing GC-trigger disable when calling managed callouts. * Simplify initialization logic * Add comments to CoreCLR and NativeAOT about constants that should have the same size. * Remove superfluous use of C++ templates. * Use the C# unmanaged function pointer types in more places, improving type safety * Add SuppressGCTransition and fix compile error by adding cast Co-authored-by: Michal Strehovský <[email protected]> Co-authored-by: Aaron Robinson <[email protected]>
1 parent 0e60130 commit bf9fc46

File tree

19 files changed

+439
-4
lines changed

19 files changed

+439
-4
lines changed

src/coreclr/nativeaot/Bootstrap/main.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ extern "C" void OnFirstChanceException();
112112
extern "C" void OnUnhandledException();
113113
extern "C" void IDynamicCastableIsInterfaceImplemented();
114114
extern "C" void IDynamicCastableGetInterfaceImplementation();
115+
#ifdef FEATURE_OBJCMARSHAL
116+
extern "C" void ObjectiveCMarshalTryGetTaggedMemory();
117+
extern "C" void ObjectiveCMarshalGetIsTrackedReferenceCallback();
118+
extern "C" void ObjectiveCMarshalGetOnEnteredFinalizerQueueCallback();
119+
#endif
115120

116121
typedef void(*pfn)();
117122

@@ -126,6 +131,15 @@ static const pfn c_classlibFunctions[] = {
126131
&OnUnhandledException,
127132
&IDynamicCastableIsInterfaceImplemented,
128133
&IDynamicCastableGetInterfaceImplementation,
134+
#ifdef FEATURE_OBJCMARSHAL
135+
&ObjectiveCMarshalTryGetTaggedMemory,
136+
&ObjectiveCMarshalGetIsTrackedReferenceCallback,
137+
&ObjectiveCMarshalGetOnEnteredFinalizerQueueCallback,
138+
#else
139+
nullptr,
140+
nullptr,
141+
nullptr,
142+
#endif
129143
};
130144

131145
#ifndef _countof

src/coreclr/nativeaot/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ if(CLR_CMAKE_HOST_UNIX)
3434

3535
if(CLR_CMAKE_TARGET_OSX)
3636
add_definitions(-D_XOPEN_SOURCE)
37+
add_definitions(-DFEATURE_OBJCMARSHAL)
3738
endif(CLR_CMAKE_TARGET_OSX)
3839

3940
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)

src/coreclr/nativeaot/Common/src/Internal/Runtime/MethodTable.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,14 @@ internal bool IsHFA
791791
}
792792
}
793793

794+
internal bool IsTrackedReferenceWithFinalizer
795+
{
796+
get
797+
{
798+
return (ExtendedFlags & (ushort)EETypeFlagsEx.IsTrackedReferenceWithFinalizerFlag) != 0;
799+
}
800+
}
801+
794802
internal uint ValueTypeFieldPadding
795803
{
796804
get

src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/InternalCalls.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ internal enum ClassLibFunctionId
4444
OnUnhandledException = 7,
4545
IDynamicCastableIsInterfaceImplemented = 8,
4646
IDynamicCastableGetInterfaceImplementation = 9,
47+
ObjectiveCMarshalTryGetTaggedMemory = 10,
48+
ObjectiveCMarshalGetIsTrackedReferenceCallback = 11,
49+
ObjectiveCMarshalGetOnEnteredFinalizerQueueCallback = 12,
4750
}
4851

4952
internal static class InternalCalls

src/coreclr/nativeaot/Runtime/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,12 @@ else()
170170
set(ASM_SUFFIX S)
171171
endif()
172172

173+
if (CLR_CMAKE_TARGET_OSX)
174+
list(APPEND COMMON_RUNTIME_SOURCES
175+
interoplibinterface_objc.cpp
176+
)
177+
endif (CLR_CMAKE_TARGET_OSX)
178+
173179
if (CLR_CMAKE_TARGET_ARCH_AMD64 AND CLR_CMAKE_TARGET_WIN32)
174180
list(APPEND COMMON_RUNTIME_SOURCES
175181
${GC_DIR}/vxsort/isa_detection.cpp

src/coreclr/nativeaot/Runtime/Crst.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ enum CrstType
1818
CrstInterfaceDispatchGlobalLists,
1919
CrstStressLog,
2020
CrstRestrictedCallouts,
21+
CrstObjectiveCMarshalCallouts,
2122
CrstGcStressControl,
2223
CrstSuspendEE,
2324
CrstCastCache,

src/coreclr/nativeaot/Runtime/GCHelpers.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "varint.h"
1919
#include "regdisplay.h"
2020
#include "StackFrameIterator.h"
21+
#include "interoplibinterface.h"
2122

2223
#include "thread.h"
2324
#include "RWLock.h"
@@ -132,6 +133,13 @@ COOP_PINVOKE_HELPER(void, RhUnregisterGcCallout, (GcRestrictedCalloutKind eKind,
132133
RestrictedCallouts::UnregisterGcCallout(eKind, pCallout);
133134
}
134135

136+
#ifdef FEATURE_OBJCMARSHAL
137+
COOP_PINVOKE_HELPER(FC_BOOL_RET, RhRegisterObjectiveCMarshalBeginEndCallback, (void * pCallback))
138+
{
139+
FC_RETURN_BOOL(ObjCMarshalNative::RegisterBeginEndCallback(pCallback));
140+
}
141+
#endif
142+
135143
COOP_PINVOKE_HELPER(int32_t, RhGetLohCompactionMode, ())
136144
{
137145
return GCHeapUtilities::GetGCHeap()->GetLOHCompactionMode();

src/coreclr/nativeaot/Runtime/ICodeManager.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ enum class ClasslibFunctionId
154154
OnUnhandledException = 7,
155155
IDynamicCastableIsInterfaceImplemented = 8,
156156
IDynamicCastableGetInterfaceImplementation = 9,
157+
ObjectiveCMarshalTryGetTaggedMemory = 10,
158+
ObjectiveCMarshalGetIsTrackedReferenceCallback = 11,
159+
ObjectiveCMarshalGetOnEnteredFinalizerQueueCallback = 12,
157160
};
158161

159162
enum class AssociatedDataFlags : unsigned char

src/coreclr/nativeaot/Runtime/gcrhenv.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "daccess.h"
4646

4747
#include "GCMemoryHelpers.h"
48+
#include "interoplibinterface.h"
4849

4950
#include "holder.h"
5051
#include "volatile.h"
@@ -682,13 +683,25 @@ void GCToEEInterface::GcStartWork(int condemned, int /*max_gen*/)
682683

683684
void GCToEEInterface::BeforeGcScanRoots(int condemned, bool is_bgc, bool is_concurrent)
684685
{
686+
#ifdef FEATURE_OBJCMARSHAL
687+
if (!is_concurrent)
688+
{
689+
ObjCMarshalNative::BeforeRefCountedHandleCallbacks();
690+
}
691+
#endif
685692
}
686693

687694
// EE can perform post stack scanning action, while the user threads are still suspended
688-
void GCToEEInterface::AfterGcScanRoots(int condemned, int /*max_gen*/, ScanContext* /*sc*/)
695+
void GCToEEInterface::AfterGcScanRoots(int condemned, int /*max_gen*/, ScanContext* sc)
689696
{
690697
// Invoke any registered callouts for the end of the mark phase.
691698
RestrictedCallouts::InvokeGcCallouts(GCRC_AfterMarkPhase, condemned);
699+
#ifdef FEATURE_OBJCMARSHAL
700+
if (!sc->concurrent)
701+
{
702+
ObjCMarshalNative::AfterRefCountedHandleCallbacks();
703+
}
704+
#endif
692705
}
693706

694707
void GCToEEInterface::GcDone(int condemned)
@@ -699,6 +712,11 @@ void GCToEEInterface::GcDone(int condemned)
699712

700713
bool GCToEEInterface::RefCountedHandleCallbacks(Object * pObject)
701714
{
715+
#ifdef FEATURE_OBJCMARSHAL
716+
bool isReferenced = false;
717+
if (ObjCMarshalNative::IsTrackedReference(pObject, &isReferenced))
718+
return isReferenced;
719+
#endif // FEATURE_OBJCMARSHAL
702720
return RestrictedCallouts::InvokeRefCountedHandleCallbacks(pObject);
703721
}
704722

@@ -1153,6 +1171,14 @@ void GCToEEInterface::HandleFatalError(unsigned int exitCode)
11531171

11541172
bool GCToEEInterface::EagerFinalized(Object* obj)
11551173
{
1174+
#ifdef FEATURE_OBJCMARSHAL
1175+
if (obj->GetGCSafeMethodTable()->IsTrackedReferenceWithFinalizer())
1176+
{
1177+
ObjCMarshalNative::OnEnteredFinalizerQueue(obj);
1178+
return false;
1179+
}
1180+
#endif
1181+
11561182
if (!obj->GetGCSafeMethodTable()->HasEagerFinalizer())
11571183
return false;
11581184

src/coreclr/nativeaot/Runtime/inc/MethodTable.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ class MethodTable
194194
{
195195
HasEagerFinalizerFlag = 0x0001,
196196
HasCriticalFinalizerFlag = 0x0002,
197+
IsTrackedReferenceWithFinalizerFlag = 0x0004,
197198
};
198199

199200
public:
@@ -269,6 +270,11 @@ class MethodTable
269270
return (m_uFlags & HasCriticalFinalizerFlag) && !HasComponentSize();
270271
}
271272

273+
bool IsTrackedReferenceWithFinalizer()
274+
{
275+
return (m_uFlags & IsTrackedReferenceWithFinalizerFlag) && !HasComponentSize();
276+
}
277+
272278
bool HasComponentSize()
273279
{
274280
static_assert(HasComponentSizeFlag == (MethodTable::Flags)(1 << 31), "we assume that HasComponentSizeFlag matches the sign bit");

0 commit comments

Comments
 (0)