Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions extension/apple/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ oncall("executorch")

non_fbcode_target(_kind = fb_apple_library,
name = "ExecuTorch",
# The ETDump extension subclasses ExecuTorchEventTracer, which needs the C++
# tracer seam this header declares, so export it beyond the target.
autoglob_additional_exported_headers = [
"ExecuTorch/Internal/ExecuTorchEventTracer+Internal.h",
],
autoglob_mode = "EXPORT_UNLESS_INTERNAL",
extension_api_only = True,
frameworks = [
Expand Down
18 changes: 18 additions & 0 deletions extension/apple/ExecuTorch/Exported/ExecuTorchEventTracer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,24 @@ NS_SWIFT_NAME(EventTracer)
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;

/**
* Initializes a tracer with a native std::unique_ptr<EventTracer> instance.
*
* @param nativeInstance A pointer to a native std::unique_ptr<EventTracer>
* instance.
* @return An initialized ExecuTorchEventTracer instance.
*/
- (instancetype)initWithNativeInstance:(void *)nativeInstance
NS_DESIGNATED_INITIALIZER NS_SWIFT_UNAVAILABLE("");

/**
* Pointer to the underlying native std::unique_ptr<EventTracer> instance.
*
* @return A raw pointer to the native std::unique_ptr<EventTracer> held by this
* class.
*/
@property(nonatomic, readonly) void *nativeInstance NS_SWIFT_UNAVAILABLE("");

@end

NS_ASSUME_NONNULL_END
16 changes: 9 additions & 7 deletions extension/apple/ExecuTorch/Exported/ExecuTorchEventTracer.mm
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,26 @@

#import "ExecuTorchEventTracer.h"

#import "ExecuTorchEventTracer+Internal.h"
#import <executorch/runtime/core/event_tracer.h>

Comment on lines 9 to 12

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does compile in a clean build: the apple (*) / build and build-frameworks-ios CI jobs (OSS CMake framework build) all pass on this branch, and I also compiled the pattern locally under Xcode 26. event_tracer.h transitively provides both: its evalue.h/result.h/array_ref.h includes pull platform/assert.h (ET_CHECK), and <memory> is present in its preprocessed output. The sibling ExecuTorchTensor.mm relies on the same transitive availability (no explicit <memory> there), so this follows the module convention.

using executorch::runtime::EventTracer;

@implementation ExecuTorchEventTracer {
std::unique_ptr<EventTracer> _tracer;
}

- (instancetype)initWithCppTracer:(std::unique_ptr<EventTracer>)tracer {
self = [super init];
if (self) {
_tracer = std::move(tracer);
- (instancetype)initWithNativeInstance:(void *)nativeInstance {
ET_CHECK(nativeInstance);
if (self = [super init]) {
_tracer = std::move(
*reinterpret_cast<std::unique_ptr<EventTracer> *>(nativeInstance));
ET_CHECK(_tracer);
}
Comment thread
Copilot marked this conversation as resolved.
return self;
}

- (std::unique_ptr<EventTracer>)takeCppTracer {
return std::move(_tracer);
- (void *)nativeInstance {
return &_tracer;
}

@end
6 changes: 4 additions & 2 deletions extension/apple/ExecuTorch/Exported/ExecuTorchModule.mm
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#import "ExecuTorchBackendOptionsMap+Internal.h"
#import "ExecuTorchBackendOptionsMap.h"
#import "ExecuTorchError.h"
#import "ExecuTorchEventTracer+Internal.h"
#import "ExecuTorchUtils.h"

#import <executorch/extension/module/module.h>
Expand Down Expand Up @@ -330,7 +329,10 @@ - (instancetype)initWithFilePath:(NSString *)filePath
// Taking it empties the handle, so a tracer handed to a second module would
// yield nothing and that module would run and record silently into nowhere.
// Catch it here rather than letting it surface as an empty profile.
auto cppTracer = [eventTracer takeCppTracer];
auto *cppTracerPtr = reinterpret_cast<std::unique_ptr<EventTracer> *>(
eventTracer.nativeInstance);
ET_CHECK(cppTracerPtr);
auto cppTracer = std::move(*cppTracerPtr);
NSAssert(cppTracer != nullptr,
@"This event tracer was already given to another module. Create one "
@"tracer per module.");
Expand Down

This file was deleted.

10 changes: 4 additions & 6 deletions extension/apple/dump/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ target_sources(extension_etdump_apple PRIVATE ${OBJC_SOURCES})
# The public header exposes ExecuTorchModule and so imports it as
# <ExecuTorch/ExecuTorchModule.h>, the path a consumer of the assembled
# framework uses. That layout does not exist during this build, so stage the
# core Exported and Internal headers under one ExecuTorch directory and put it
# on the include path, mirroring what the framework packaging produces. Staging
# them together in one directory is what lets the Internal header's own quoted
# import of "ExecuTorchModule.h" find its sibling, and keeps the module header
# reachable by a single path so it is not seen as two conflicting definitions.
# core Exported headers under one ExecuTorch directory and put it on the include
# path, mirroring what the framework packaging produces. Staging them together
# in one directory keeps the module header reachable by a single path so it is
# not seen as two conflicting definitions.
set(_etdump_core_headers_dir ${CMAKE_CURRENT_BINARY_DIR}/include)
file(GLOB _etdump_core_headers
${EXECUTORCH_ROOT}/extension/apple/ExecuTorch/Exported/*.h
${EXECUTORCH_ROOT}/extension/apple/ExecuTorch/Internal/*.h
)
# configure_file(... COPYONLY) rather than file(COPY): it registers each source
# header as a reconfigure dependency, so editing a core header re-stages it. A
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#import "ExecuTorchDumpError.h"
#import "ExecuTorchDumpTracer+Internal.h"

#import <ExecuTorch/ExecuTorchEventTracer+Internal.h>

#import <flatcc/flatcc_builder.h>

Comment on lines 11 to 15

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This compiles today (all six apple (*) / build jobs plus build-frameworks-ios pass on this branch) because <memory> is pulled transitively. This matches the established convention in this module: the sibling ExecuTorchTensor.mm uses std::make_unique/shared_ptr in four places and includes no <memory> either. Keeping includes minimal (no redundant transitively-provided headers) is the deliberate house style here, so I'm matching it rather than diverging for this one file.

using namespace executorch::etdump;
Expand All @@ -39,25 +37,21 @@ @implementation ExecuTorchDumpTracer {
NSLock *_lock;
}

// init chains to the base class's real designated initializer, initWithCppTracer:,
// which takes a C++ type and so lives in an Objective-C++ category rather than the
// public interface. Clang cannot see a category initializer as designated, so it
// wrongly flags this chain; the pattern is deliberate and correct.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-designated-initializers"

- (instancetype)init {
auto generator = std::make_unique<ETDumpGen>();
_generator = generator.get();
self = [super initWithCppTracer:std::move(generator)];
// The base moves out of the pointee as a std::unique_ptr<EventTracer>, so the
// local must be that type, not unique_ptr<ETDumpGen>. _generator keeps the
// concrete pointer for readback.
Comment on lines 41 to +45

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ivar-before-super ordering is pre-existing and unchanged by this PR (_generator = generator.get() before [super init...] is identical on main). It is also safe on every path: the local unique_ptr owns the ETDumpGen, so if super returns nil it is freed at scope exit (no leak), and _generator on an abandoned instance is never read because self is nil. Reworking it would expand this PR beyond the seam change for no behavioral gain, so I'm leaving the established shape.

std::unique_ptr<executorch::runtime::EventTracer> tracer =
std::move(generator);
self = [super initWithNativeInstance:&tracer];
if (self) {
_lock = [NSLock new];
}
return self;
}

#pragma clang diagnostic pop

- (ETDumpGen *)generator {
return _generator;
}
Expand Down
Loading