Skip to content

Address post-commit review comments on PR #11910 #12605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 25, 2017
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
22 changes: 11 additions & 11 deletions stdlib/public/core/RuntimeFunctionCounters.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ struct _RuntimeFunctionCounters {

/// Get the names of all runtime functions whose calls are being
/// tracked.
@_silgen_name("getRuntimeFunctionNames")
@_silgen_name("_swift_getRuntimeFunctionNames")
static public func _getRuntimeFunctionNames() ->
UnsafePointer<UnsafePointer<CChar>>

Expand All @@ -129,21 +129,21 @@ struct _RuntimeFunctionCounters {

/// Get the offsets of the collected runtime function counters inside
/// the state.
@_silgen_name("getRuntimeFunctionCountersOffsets")
@_silgen_name("_swift_getRuntimeFunctionCountersOffsets")
static public func getRuntimeFunctionCountersOffsets() ->
UnsafePointer<UInt16>

/// Get the number of different runtime functions whose calls are being
/// tracked.
@_silgen_name("getNumRuntimeFunctionCounters")
@_silgen_name("_swift_getNumRuntimeFunctionCounters")
static public func getNumRuntimeFunctionCounters() -> Int

/// Dump all per-object runtime function counters.
@_silgen_name("dumpObjectsRuntimeFunctionPointers")
@_silgen_name("_swift_dumpObjectsRuntimeFunctionPointers")
static public func dumpObjectsRuntimeFunctionPointers()

@discardableResult
@_silgen_name("setGlobalRuntimeFunctionCountersUpdateHandler")
@_silgen_name("_swift_setGlobalRuntimeFunctionCountersUpdateHandler")
static public func setGlobalRuntimeFunctionCountersUpdateHandler(
handler: RuntimeFunctionCountersUpdateHandler?
) -> RuntimeFunctionCountersUpdateHandler?
Expand Down Expand Up @@ -312,31 +312,31 @@ internal struct _RuntimeFunctionCountersState: _RuntimeFunctionCountersStats {
}

extension _RuntimeFunctionCounters {
@_silgen_name("getObjectRuntimeFunctionCounters")
@_silgen_name("_swift_getObjectRuntimeFunctionCounters")
static internal func getObjectRuntimeFunctionCounters(
_ object: UnsafeRawPointer, _ result: inout _RuntimeFunctionCountersState)

@_silgen_name("getGlobalRuntimeFunctionCounters")
@_silgen_name("_swift_getGlobalRuntimeFunctionCounters")
static internal func getGlobalRuntimeFunctionCounters(
_ result: inout _RuntimeFunctionCountersState)

@_silgen_name("setGlobalRuntimeFunctionCounters")
@_silgen_name("_swift_setGlobalRuntimeFunctionCounters")
static internal func setGlobalRuntimeFunctionCounters(
_ state: inout _RuntimeFunctionCountersState)

@_silgen_name("setObjectRuntimeFunctionCounters")
@_silgen_name("_swift_setObjectRuntimeFunctionCounters")
static internal func setObjectRuntimeFunctionCounters(
_ object: UnsafeRawPointer,
_ state: inout _RuntimeFunctionCountersState)

@discardableResult
@_silgen_name("setGlobalRuntimeFunctionCountersMode")
@_silgen_name("_swift_setGlobalRuntimeFunctionCountersMode")
static
public // @testable
func setGlobalRuntimeFunctionCountersMode(enable: Bool) -> Bool

@discardableResult
@_silgen_name("setPerObjectRuntimeFunctionCountersMode")
@_silgen_name("_swift_setPerObjectRuntimeFunctionCountersMode")
static
public // @testable
func setPerObjectRuntimeFunctionCountersMode(enable: Bool) -> Bool
Expand Down
98 changes: 55 additions & 43 deletions stdlib/public/runtime/RuntimeInvocationsTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

#include "llvm/ADT/DenseMap.h"
#include "RuntimeInvocationsTracking.h"
#include "swift/Basic/Lazy.h"
#include "swift/Runtime/HeapObject.h"
#include "swift/Runtime/Mutex.h"

// This file is compiled always, even if assertions are disabled and no runtime
// functions are being tracked. This is done to avoid recompiling Swift clients
Expand Down Expand Up @@ -48,12 +50,19 @@ static bool UpdateGlobalRuntimeFunctionCounters = false;
/// TODO: Add support for enabling/disabling counters on a per object basis?

/// Global set of counters tracking the total number of runtime invocations.
static RuntimeFunctionCountersState RuntimeGlobalFunctionCountersState;
struct RuntimeFunctionCountersStateSentinel {
RuntimeFunctionCountersState State;
StaticReadWriteLock Lock;
};
static RuntimeFunctionCountersStateSentinel RuntimeGlobalFunctionCountersState;

/// The object state cache mapping objects to the collected state associated with
/// them.
/// TODO: Do we need to make it thread-safe?
static llvm::DenseMap<HeapObject *, RuntimeFunctionCountersState> RuntimeObjectStateCache;
struct RuntimeObjectCacheSentinel {
llvm::DenseMap<HeapObject *, RuntimeFunctionCountersState> Cache;
StaticReadWriteLock Lock;
};
static Lazy<RuntimeObjectCacheSentinel> RuntimeObjectStateCache;

static const char *RuntimeFunctionNames[] {
/// Define names of runtime functions.
Expand Down Expand Up @@ -95,79 +104,84 @@ static uint16_t RuntimeFunctionCountersOffsets[] = {
void SWIFT_RT_TRACK_INVOCATION_NAME(RT_FUNCTION)(HeapObject * object) { \
/* Update global counters. */ \
if (UpdateGlobalRuntimeFunctionCounters) { \
RuntimeGlobalFunctionCountersState \
StaticScopedWriteLock lock(RuntimeGlobalFunctionCountersState.Lock); \
RuntimeGlobalFunctionCountersState.State \
.SWIFT_RT_FUNCTION_INVOCATION_COUNTER_NAME(RT_FUNCTION)++; \
if (GlobalRuntimeFunctionCountersUpdateHandler) { \
auto oldGlobalMode = setGlobalRuntimeFunctionCountersMode(0); \
auto oldPerObjectMode = setPerObjectRuntimeFunctionCountersMode(0); \
auto oldGlobalMode = _swift_setGlobalRuntimeFunctionCountersMode(0); \
auto oldPerObjectMode = \
_swift_setPerObjectRuntimeFunctionCountersMode(0); \
GlobalRuntimeFunctionCountersUpdateHandler( \
object, RT_FUNCTION_ID(RT_FUNCTION)); \
setGlobalRuntimeFunctionCountersMode(oldGlobalMode); \
setPerObjectRuntimeFunctionCountersMode(oldPerObjectMode); \
_swift_setGlobalRuntimeFunctionCountersMode(oldGlobalMode); \
_swift_setPerObjectRuntimeFunctionCountersMode(oldPerObjectMode); \
} \
} \
/* Update per object counters. */ \
if (UpdatePerObjectRuntimeFunctionCounters && object) { \
RuntimeObjectStateCache[object] \
.SWIFT_RT_FUNCTION_INVOCATION_COUNTER_NAME(RT_FUNCTION)++; \
/* TODO: Remember the order/history of operations? */ \
auto &theSentinel = RuntimeObjectStateCache.get(); \
StaticScopedWriteLock lock(theSentinel.Lock); \
theSentinel.Cache[object].SWIFT_RT_FUNCTION_INVOCATION_COUNTER_NAME( \
RT_FUNCTION)++; \
/* TODO: Remember the order/history of operations? */ \
} \
}
#include "RuntimeInvocationsTracking.def"

/// Public APIs

/// Get the runtime object state associated with an object.
SWIFT_RT_ENTRY_VISIBILITY
void getObjectRuntimeFunctionCounters(HeapObject *object,
RuntimeFunctionCountersState *result) {
*result = RuntimeObjectStateCache[object];
void _swift_getObjectRuntimeFunctionCounters(
HeapObject *object, RuntimeFunctionCountersState *result) {
auto &theSentinel = RuntimeObjectStateCache.get();
StaticScopedReadLock lock(theSentinel.Lock);
*result = theSentinel.Cache[object];
}

/// Set the runtime object state associated with an object from a provided
/// state.
SWIFT_RT_ENTRY_VISIBILITY
void setObjectRuntimeFunctionCounters(HeapObject *object,
RuntimeFunctionCountersState *state) {
RuntimeObjectStateCache[object] = *state;
void _swift_setObjectRuntimeFunctionCounters(
HeapObject *object, RuntimeFunctionCountersState *state) {
auto &theSentinel = RuntimeObjectStateCache.get();
StaticScopedWriteLock lock(theSentinel.Lock);
theSentinel.Cache[object] = *state;
}

/// Get the global runtime state containing the total numbers of invocations for
/// each runtime function of interest.
SWIFT_RT_ENTRY_VISIBILITY
void getGlobalRuntimeFunctionCounters(RuntimeFunctionCountersState *result) {
*result = RuntimeGlobalFunctionCountersState;
void _swift_getGlobalRuntimeFunctionCounters(
RuntimeFunctionCountersState *result) {
StaticScopedReadLock lock(RuntimeGlobalFunctionCountersState.Lock);
*result = RuntimeGlobalFunctionCountersState.State;
}

/// Set the global runtime state of function pointers from a provided state.
SWIFT_RT_ENTRY_VISIBILITY
void setGlobalRuntimeFunctionCounters(RuntimeFunctionCountersState *state) {
RuntimeGlobalFunctionCountersState = *state;
void _swift_setGlobalRuntimeFunctionCounters(
RuntimeFunctionCountersState *state) {
StaticScopedWriteLock lock(RuntimeGlobalFunctionCountersState.Lock);
RuntimeGlobalFunctionCountersState.State = *state;
}

/// Return the names of the runtime functions being tracked.
/// Their order is the same as the order of the counters in the
/// RuntimeObjectState structure. All these strings are null terminated.
SWIFT_RT_ENTRY_VISIBILITY
const char **getRuntimeFunctionNames() {
const char **_swift_getRuntimeFunctionNames() {
return RuntimeFunctionNames;
}

/// Return the offsets of the runtime function counters being tracked.
/// Their order is the same as the order of the counters in the
/// RuntimeObjectState structure.
SWIFT_RT_ENTRY_VISIBILITY
const uint16_t *getRuntimeFunctionCountersOffsets() {
const uint16_t *_swift_getRuntimeFunctionCountersOffsets() {
return RuntimeFunctionCountersOffsets;
}

/// Return the number of runtime functions being tracked.
SWIFT_RT_ENTRY_VISIBILITY
uint64_t getNumRuntimeFunctionCounters() {
uint64_t _swift_getNumRuntimeFunctionCounters() {
return ID_LastRuntimeFunctionName;
}

static void dumpRuntimeCounters(RuntimeFunctionCountersState *State) {
static void _swift_dumpRuntimeCounters(RuntimeFunctionCountersState *State) {
uint32_t tmp;
/// Define how to dump the counter for a given runtime function.
#define FUNCTION_TO_TRACK(RT_FUNCTION) \
Expand All @@ -179,28 +193,27 @@ static void dumpRuntimeCounters(RuntimeFunctionCountersState *State) {
}

/// Dump all per-object runtime function pointers.
SWIFT_RT_ENTRY_VISIBILITY
void dumpObjectsRuntimeFunctionPointers() {
for (auto &Pair : RuntimeObjectStateCache) {
void _swift_dumpObjectsRuntimeFunctionPointers() {
auto &theSentinel = RuntimeObjectStateCache.get();
StaticScopedReadLock lock(theSentinel.Lock);
for (auto &Pair : theSentinel.Cache) {
printf("\n\nRuntime counters for object at address %p:\n", Pair.getFirst());
dumpRuntimeCounters(&Pair.getSecond());
_swift_dumpRuntimeCounters(&Pair.getSecond());
printf("\n");
}
}

/// Set mode for global runtime function counters.
/// Return the old value of this flag.
SWIFT_RT_ENTRY_VISIBILITY
int setGlobalRuntimeFunctionCountersMode(int mode) {
int _swift_setGlobalRuntimeFunctionCountersMode(int mode) {
int oldMode = UpdateGlobalRuntimeFunctionCounters;
UpdateGlobalRuntimeFunctionCounters = mode ? 1 : 0;
return oldMode;
}

/// Set mode for per object runtime function counters.
/// Return the old value of this flag.
SWIFT_RT_ENTRY_VISIBILITY
int setPerObjectRuntimeFunctionCountersMode(int mode) {
int _swift_setPerObjectRuntimeFunctionCountersMode(int mode) {
int oldMode = UpdatePerObjectRuntimeFunctionCounters;
UpdatePerObjectRuntimeFunctionCounters = mode ? 1 : 0;
return oldMode;
Expand All @@ -210,13 +223,12 @@ int setPerObjectRuntimeFunctionCountersMode(int mode) {
/// is being updated. The handler should take the object and may be
/// the name of the runtime function as parameters. And this handler
/// could e.g. check some conditions and stop the program under
/// a debuggger if a certain condition is met, like a refcount has
/// a debugger if a certain condition is met, like a refcount has
/// reached a certain value.
/// We could allow for setting global handlers or even per-object
/// handlers.
SWIFT_RT_ENTRY_VISIBILITY
RuntimeFunctionCountersUpdateHandler
setGlobalRuntimeFunctionCountersUpdateHandler(
_swift_setGlobalRuntimeFunctionCountersUpdateHandler(
RuntimeFunctionCountersUpdateHandler handler) {
auto oldHandler = GlobalRuntimeFunctionCountersUpdateHandler;
GlobalRuntimeFunctionCountersUpdateHandler = handler;
Expand Down
37 changes: 19 additions & 18 deletions stdlib/public/runtime/RuntimeInvocationsTracking.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,52 +69,53 @@ using RuntimeFunctionCountersUpdateHandler =

/// Get the runtime object state associated with an object and store it
/// into the result.
SWIFT_RT_ENTRY_VISIBILITY void
getObjectRuntimeFunctionCounters(HeapObject *object,
RuntimeFunctionCountersState *result);
SWIFT_RUNTIME_EXPORT void
_swift_getObjectRuntimeFunctionCounters(HeapObject *object,
RuntimeFunctionCountersState *result);

/// Get the global runtime state containing the total numbers of invocations for
/// each runtime function of interest and store it into the result.
SWIFT_RT_ENTRY_VISIBILITY void
getGlobalRuntimeFunctionCounters(swift::RuntimeFunctionCountersState *result);
SWIFT_RUNTIME_EXPORT void _swift_getGlobalRuntimeFunctionCounters(
swift::RuntimeFunctionCountersState *result);

/// Return the names of the runtime functions being tracked.
/// Their order is the same as the order of the counters in the
/// RuntimeObjectState structure.
SWIFT_RT_ENTRY_VISIBILITY const char **getRuntimeFunctionNames();
SWIFT_RUNTIME_EXPORT const char **_swift_getRuntimeFunctionNames();

/// Return the offsets of the runtime function counters being tracked.
/// Their order is the same as the order of the counters in the
/// RuntimeFunctionCountersState structure.
SWIFT_RT_ENTRY_VISIBILITY const uint16_t *getRuntimeFunctionCountersOffsets();
SWIFT_RUNTIME_EXPORT const uint16_t *_swift_getRuntimeFunctionCountersOffsets();

/// Return the number of runtime functions being tracked.
SWIFT_RT_ENTRY_VISIBILITY uint64_t getNumRuntimeFunctionCounters();
SWIFT_RUNTIME_EXPORT uint64_t _swift_getNumRuntimeFunctionCounters();

/// Dump all per-object runtime function pointers.
SWIFT_RT_ENTRY_VISIBILITY void dumpObjectsRuntimeFunctionPointers();
SWIFT_RUNTIME_EXPORT void _swift_dumpObjectsRuntimeFunctionPointers();

/// Set mode for global runtime function counters.
/// Return the old value of this flag.
SWIFT_RT_ENTRY_VISIBILITY int setPerObjectRuntimeFunctionCountersMode(int mode);
SWIFT_RUNTIME_EXPORT int
_swift_setPerObjectRuntimeFunctionCountersMode(int mode);

/// Set mode for per object runtime function counters.
/// Return the old value of this flag.
SWIFT_RT_ENTRY_VISIBILITY int setGlobalRuntimeFunctionCountersMode(int mode);
SWIFT_RUNTIME_EXPORT int _swift_setGlobalRuntimeFunctionCountersMode(int mode);

/// Set the global runtime state of function pointers from a provided state.
SWIFT_RT_ENTRY_VISIBILITY void
setGlobalRuntimeFunctionCounters(swift::RuntimeFunctionCountersState *state);
SWIFT_RUNTIME_EXPORT void _swift_setGlobalRuntimeFunctionCounters(
swift::RuntimeFunctionCountersState *state);

/// Set the runtime object state associated with an object from a provided
/// state.
SWIFT_RT_ENTRY_VISIBILITY void
setObjectRuntimeFunctionCounters(HeapObject *object,
RuntimeFunctionCountersState *state);
SWIFT_RUNTIME_EXPORT void
_swift_setObjectRuntimeFunctionCounters(HeapObject *object,
RuntimeFunctionCountersState *state);

/// Set the global runtime function counters update handler.
SWIFT_RT_ENTRY_VISIBILITY RuntimeFunctionCountersUpdateHandler
setGlobalRuntimeFunctionCountersUpdateHandler(
SWIFT_RUNTIME_EXPORT RuntimeFunctionCountersUpdateHandler
_swift_setGlobalRuntimeFunctionCountersUpdateHandler(
RuntimeFunctionCountersUpdateHandler handler);

#endif