Skip to content

Commit

Permalink
Runtime: Avoid instantiating call_once on Darwin by using cross-platf…
Browse files Browse the repository at this point in the history
…orm Lazy definitions.
  • Loading branch information
jckarter committed Nov 16, 2015
1 parent 6d064d1 commit dc26310
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 22 deletions.
22 changes: 12 additions & 10 deletions include/swift/Basic/Lazy.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,22 @@

namespace swift {

#ifdef __APPLE__
using OnceToken_t = dispatch_once_t;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
dispatch_once_f(&TOKEN, CONTEXT, FUNC)
#else
using OnceToken_t = std::once_flag;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
std::call_once(TOKEN, FUNC, CONTEXT)
#endif

/// A template for lazily-constructed, zero-initialized, leaked-on-exit
/// global objects.
template <class T> class Lazy {
typename std::aligned_storage<sizeof(T), alignof(T)>::type Value;

#ifdef __APPLE__
dispatch_once_t OnceToken;
#else
std::once_flag OnceToken;
#endif
OnceToken_t OnceToken;

public:
T &get();
Expand Down Expand Up @@ -59,11 +65,7 @@ template <typename T> inline T &Lazy<T>::get() {
static_assert(std::is_literal_type<Lazy<T>>::value,
"Lazy<T> must be a literal type");

#ifdef __APPLE__
dispatch_once_f(&OnceToken, this, lazyInitCallback);
#else
std::call_once(OnceToken, lazyInitCallback, this);
#endif
SWIFT_ONCE_F(OnceToken, lazyInitCallback, this);
return unsafeGetAlreadyInitialized();
}

Expand Down
24 changes: 12 additions & 12 deletions stdlib/public/runtime/Casting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2188,8 +2188,6 @@ const {
#define SWIFT_PROTOCOL_CONFORMANCES_SECTION ".swift2_protocol_conformances_start"
#endif

// FIXME: Implement this callback on non-apple platforms.

// std:once_flag token to install the dyld callback to enqueue images for
// protocol conformance lookup.
static std::once_flag InstallProtocolConformanceAddImageCallbackOnce;
Expand Down Expand Up @@ -2385,23 +2383,25 @@ static int _addImageProtocolConformances(struct dl_phdr_info *info,
#endif

static void installCallbacksToInspectDylib() {
// TODO: Generic types, subclasses, foreign classes
std::call_once(InstallProtocolConformanceAddImageCallbackOnce, [](){
#if defined(__APPLE__) && defined(__MACH__)
static OnceToken_t token;
auto callback = [](void*) {
#if defined(__APPLE__) && defined(__MACH__)
// Install our dyld callback if we haven't already.
// Dyld will invoke this on our behalf for all images that have already been
// loaded.
// Dyld will invoke this on our behalf for all images that have already
// been loaded.
_dyld_register_func_for_add_image(_addImageProtocolConformances);
#elif defined(__ELF__)
#elif defined(__ELF__)
// Search the loaded dls. Unlike the above, this only searches the already
// loaded ones.
// FIXME: Find a way to have this continue to happen after.
// rdar://problem/19045112
dl_iterate_phdr(_addImageProtocolConformances, nullptr);
#else
#error No known mechanism to inspect loaded dynamic libraries on this platform.
#endif
});
#else
# error No known mechanism to inspect dynamic libraries on this platform.
#endif
};

SWIFT_ONCE_F(token, callback, nullptr);
}

static size_t hashTypeProtocolPair(const void *type,
Expand Down

0 comments on commit dc26310

Please sign in to comment.