summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2015-10-27 22:09:57 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2015-10-27 22:09:57 (GMT)
commit21d397d48716466a3fbefaf0bacd0bef7ead69ea (patch)
tree3860a0154a59cc684e5b6de6178c023e1fb775e9 /generic
parenta94ede13beafd4d4c3ab5e4013882e35f9d03ad8 (diff)
downloadtcl-21d397d48716466a3fbefaf0bacd0bef7ead69ea.zip
tcl-21d397d48716466a3fbefaf0bacd0bef7ead69ea.tar.gz
tcl-21d397d48716466a3fbefaf0bacd0bef7ead69ea.tar.bz2
Chisel 1% from the TclOO object creation μbenchmark.
Diffstat (limited to 'generic')
-rw-r--r--generic/tcl.h3
-rw-r--r--generic/tclOOCall.c43
2 files changed, 40 insertions, 6 deletions
diff --git a/generic/tcl.h b/generic/tcl.h
index a08edde..d778e19 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -144,6 +144,7 @@ extern "C" {
#if defined(__GNUC__) && (__GNUC__ > 2)
# define TCL_FORMAT_PRINTF(a,b) __attribute__ ((__format__ (__printf__, a, b)))
# define TCL_NORETURN __attribute__ ((noreturn))
+# define TCL_NOINLINE __attribute__ ((noinline))
# if defined(BUILD_tcl) || defined(BUILD_tk)
# define TCL_NORETURN1 __attribute__ ((noreturn))
# else
@@ -153,8 +154,10 @@ extern "C" {
# define TCL_FORMAT_PRINTF(a,b)
# if defined(_MSC_VER) && (_MSC_VER >= 1310)
# define TCL_NORETURN _declspec(noreturn)
+# define TCL_NOINLINE __declspec(noinline)
# else
# define TCL_NORETURN /* nothing */
+# define TCL_NOINLINE /* nothing */
# endif
# define TCL_NORETURN1 /* nothing */
#endif
diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c
index facf90d..fa16a6e 100644
--- a/generic/tclOOCall.c
+++ b/generic/tclOOCall.c
@@ -726,6 +726,14 @@ AddSimpleChainToCallContext(
* ----------------------------------------------------------------------
*/
+static TCL_NOINLINE void
+AddMethodToCallChainCore(
+ Method *const mPtr,
+ struct ChainBuilder *const cbPtr,
+ Tcl_HashTable *const doneFilters,
+ Class *const filterDecl,
+ int flags);
+
static inline void
AddMethodToCallChain(
Method *const mPtr, /* Actual method implementation to add to call
@@ -748,20 +756,43 @@ AddMethodToCallChain(
* looking to add things from a mixin and have
* not passed a mixin. */
{
- register CallChain *callPtr = cbPtr->callChainPtr;
- int i;
-
/*
- * Return if this is just an entry used to record whether this is a public
+ * Check if this is just an entry used to record whether this is a public
* method. If so, there's nothing real to call and so nothing to add to
* the call chain.
*
* This is also where we enforce mixin-consistency.
*/
- if (mPtr == NULL || mPtr->typePtr == NULL || !MIXIN_CONSISTENT(flags)) {
- return;
+ if (mPtr && mPtr->typePtr && MIXIN_CONSISTENT(flags)) {
+ AddMethodToCallChainCore(mPtr, cbPtr, doneFilters, filterDecl, flags);
}
+}
+
+static TCL_NOINLINE void
+AddMethodToCallChainCore(
+ Method *const mPtr, /* Actual method implementation to add to call
+ * chain (or NULL, a no-op). */
+ struct ChainBuilder *const cbPtr,
+ /* The call chain to add the method
+ * implementation to. */
+ Tcl_HashTable *const doneFilters,
+ /* Where to record what filters have been
+ * processed. If NULL, not processing filters.
+ * Note that this function does not update
+ * this hashtable. */
+ Class *const filterDecl, /* The class that declared the filter. If
+ * NULL, either the filter was declared by the
+ * object or this isn't a filter. */
+ int flags) /* Used to check if we're mixin-consistent
+ * only. Mixin-consistent means that either
+ * we're looking to add things from a mixin
+ * and we have passed a mixin, or we're not
+ * looking to add things from a mixin and have
+ * not passed a mixin. */
+{
+ register CallChain *callPtr = cbPtr->callChainPtr;
+ int i;
/*
* Enforce real private method handling here. We will skip adding this