Index: TODO =================================================================== diff -u -rbb0d12c63024e25ca81a370eb934dbbe2b7a10fd -r7f1ad54528440269c6a26b63c1cb0f0d35001e9c --- TODO (.../TODO) (revision bb0d12c63024e25ca81a370eb934dbbe2b7a10fd) +++ TODO (.../TODO) (revision 7f1ad54528440269c6a26b63c1cb0f0d35001e9c) @@ -2331,8 +2331,24 @@ - updated documentation - reanimated NSF_PROFILE (when activated, needs more stack and slows execution slightly down) +- fixed a problem with object-level alias +- nsf.c: provide low-level commands for managing profile data +- nsfStack.c: provide hook to obtain callers information in profiling code + +- nx.tcl: provide caching for computed values of object slots to make + method objectparameter nearly twice as fast; direct changes on slots + require a reconfigure call. +- nsf.c: removed SUBST from shadow commands (does not appear to be + necessary any more) +- nsf.c: fixing a memory leak (some substituted values were not freed correctly) +- nsf.c: fix potential crash for epoched cmds +- some minor updates for profiling support + TODO: +- serializer: check, why catch is needed for object-level alias + (search for ns_cache_flush) + - NSF_PROFILE * provide an interface to clear and to output PROFILE data. * output should provide a cutoff value. Index: generic/nsf.c =================================================================== diff -u -r257ab674b56a5d699871bbe89157049bdf67127e -r7f1ad54528440269c6a26b63c1cb0f0d35001e9c --- generic/nsf.c (.../nsf.c) (revision 257ab674b56a5d699871bbe89157049bdf67127e) +++ generic/nsf.c (.../nsf.c) (revision 7f1ad54528440269c6a26b63c1cb0f0d35001e9c) @@ -60,13 +60,9 @@ #ifdef USE_TCL_STUBS # define Nsf_ExprObjCmd(clientData, interp, objc, objv) \ NsfCallCommand(interp, NSF_EXPR, objc, objv) -# define Nsf_SubstObjCmd(clientData, interp, objc, objv) \ - NsfCallCommand(interp, NSF_SUBST, objc, objv) #else # define Nsf_ExprObjCmd(clientData, interp, objc, objv) \ Tcl_ExprObjCmd(clientData, interp, objc, objv) -# define Nsf_SubstObjCmd(clientData, interp, objc, objv) \ - Tcl_SubstObjCmd(clientData, interp, objc, objv) #endif /* @@ -530,7 +526,7 @@ if (status) { if (status & NSF_PC_STATUS_MUST_DECR) { int i; - for (i = 0; i < pcPtr->lastobjc; i++) { + for (i = 0; i < pcPtr->objc-1; i++) { if (pcPtr->flags[i] & NSF_PC_MUST_DECR) { DECR_REF_COUNT(pcPtr->objv[i]); } @@ -539,10 +535,14 @@ /* objv can be separately extended */ if (status & NSF_PC_STATUS_FREE_OBJV) { - /*fprintf(stderr, "ParseContextRelease %p free %p %p\n", pcPtr, pcPtr->full_objv, pcPtr->clientData);*/ + /*fprintf(stderr, "ParseContextRelease %p free %p %p\n", + pcPtr, pcPtr->full_objv, pcPtr->clientData);*/ ckfree((char *)pcPtr->full_objv); } - /* if the parameter definition was extended, both clientData and flags are extended */ + /* + * If the parameter definition was extended, both clientData and flags are + * extended. + */ if (status & NSF_PC_STATUS_FREE_CD) { /*fprintf(stderr, "free clientdata and flags\n");*/ ckfree((char *)pcPtr->clientData); @@ -1094,6 +1094,7 @@ if (cmd) { cls = NsfGetClassFromCmdPtr(cmd); +#if 1 if (cls == NULL) { /* * We have a cmd, but no class; namesspace-imported classes are @@ -1114,6 +1115,9 @@ result = Tcl_GetAliasObj(interp, objName, &alias_interp, &alias_cmd_name, &alias_oc, &alias_ov); + Tcl_ResetResult(interp); + //fprintf(stderr, "alias retuns oc %s\n", alias_oc); + /* we only want aliases with 0 args */ if (result == TCL_OK && alias_oc == 0) { cmd = NSFindCommand(interp, alias_cmd_name); @@ -1122,11 +1126,13 @@ cls = NsfGetClassFromCmdPtr(cmd); } } + /*fprintf(stderr, "..... final cmd %p, cls %p\n", cmd , cls);*/ if (nameObj != objPtr) { DECR_REF_COUNT(nameObj); } } +#endif if (cls) { if (cl) *cl = cls; return TCL_OK; @@ -6844,36 +6850,6 @@ return result; } -/* - *---------------------------------------------------------------------- - * SubstValue -- - * - * Perform subst on the provided value (Tcl_Obj) - * - * Results: - * Tcl result code. - * - * Side effects: - * Setting result of interp. - * - *---------------------------------------------------------------------- - */ -static int -SubstValue(Tcl_Interp *interp, Tcl_Obj **value) { - Tcl_Obj *ov[2]; - int result; - - ov[1] = *value; - Tcl_ResetResult(interp); - - result = Nsf_SubstObjCmd(NULL, interp, 2, ov); - - if (result == TCL_OK) { - *value = Tcl_GetObjResult(interp); - } - return result; -} - #if defined(WITH_TCL_COMPILE) # include #endif @@ -8014,7 +7990,7 @@ /* * Check the return value if wanted */ - if (result == TCL_OK && cscPtr->cmdPtr) { + if (result == TCL_OK && cscPtr->cmdPtr && Tcl_Command_cmdEpoch(cscPtr->cmdPtr) == 0) { NsfParamDefs *paramDefs = ParamDefsGet(cscPtr->cmdPtr); if (paramDefs && paramDefs->returns) { @@ -12364,7 +12340,7 @@ if (Tcl_Command_cmdEpoch(tcd->aliasedCmd)) { NsfObject *defObject = tcd->class ? &(tcd->class->object) : tcd->object; Tcl_Obj **listElements, *entryObj, *targetObj; - int result, nrElements, withPer_object; + int nrElements, withPer_object; Tcl_Command cmd; //int withFrame; @@ -12393,7 +12369,7 @@ */ cmd = Tcl_GetCommandFromObj(interp, targetObj); if (cmd == NULL) { - result = NsfPrintError(interp, "target \"%s\" of alias %s apparently disappeared", + int result = NsfPrintError(interp, "target \"%s\" of alias %s apparently disappeared", ObjStr(targetObj), methodName); DECR_REF_COUNT(entryObj); return result; @@ -12830,10 +12806,14 @@ /* we have a default, do we have to subst it? */ if (pPtr->flags & NSF_ARG_SUBST_DEFAULT) { - int result = SubstValue(interp, &newValue); - if (result != TCL_OK) { - return result; - } + Tcl_Obj *obj = Tcl_SubstObj(interp, newValue, TCL_SUBST_ALL); + + if (obj) { + newValue = obj; + } else { + return TCL_ERROR; + } + /*fprintf(stderr, "attribute %s default %p %s => %p '%s'\n", pPtr->name, pPtr->defaultValue, ObjStr(pPtr->defaultValue), newValue, ObjStr(newValue));*/ @@ -14399,7 +14379,9 @@ */ static int NsfProfileClearDataStub(Tcl_Interp *interp) { +#if defined(NSF_PROFILE) NsfProfileClearData(interp); +#endif return TCL_OK; } @@ -14408,7 +14390,9 @@ */ static int NsfProfilePrintDataStub(Tcl_Interp *interp) { +#if defined(NSF_PROFILE) NsfProfilePrintData(interp); +#endif return TCL_OK; } @@ -14417,7 +14401,9 @@ */ static int NsfProfileGetDataStub(Tcl_Interp *interp) { +#if defined(NSF_PROFILE) NsfProfileGetData(interp); +#endif return TCL_OK; } @@ -14557,7 +14543,6 @@ } #if defined(WITH_IMPORT_REFS) - // TODO remove 1 in expr when decided xxxx if (newObjProc) { /* * Define the reference chain like for 'namespace import' to @@ -16784,7 +16769,7 @@ } else /* must be NSF_ARG_FORWARD */ { Tcl_Obj *forwardSpec = paramPtr->converterArg ? paramPtr->converterArg : NULL; /* different default? */ Tcl_Obj **nobjv, *ov[3]; - int nobjc, oc=1; + int nobjc; /* * The current implementation performs for every object @@ -16809,6 +16794,7 @@ } else { Tcl_Obj *methodObj = paramPtr->nameObj; ForwardCmdClientData *tcd = NULL; + int oc = 1; result = ForwardProcessOptions(interp, methodObj, NULL /*withDefault*/, 0 /*withEarlybinding*/, Index: generic/nsf.h =================================================================== diff -u -rbb0d12c63024e25ca81a370eb934dbbe2b7a10fd -r7f1ad54528440269c6a26b63c1cb0f0d35001e9c --- generic/nsf.h (.../nsf.h) (revision bb0d12c63024e25ca81a370eb934dbbe2b7a10fd) +++ generic/nsf.h (.../nsf.h) (revision 7f1ad54528440269c6a26b63c1cb0f0d35001e9c) @@ -73,6 +73,7 @@ of running the program #define NSF_PROFILE 1 */ +//#define NSF_PROFILE 1 /* are we developing? #define NSF_DEVELOPMENT 1 @@ -111,7 +112,6 @@ #define NRE_CALLBACK_TRACE 1 */ - /* * Sanity checks and dependencies for optional compile flags */ Index: generic/nsfInt.h =================================================================== diff -u -rbb0d12c63024e25ca81a370eb934dbbe2b7a10fd -r7f1ad54528440269c6a26b63c1cb0f0d35001e9c --- generic/nsfInt.h (.../nsfInt.h) (revision bb0d12c63024e25ca81a370eb934dbbe2b7a10fd) +++ generic/nsfInt.h (.../nsfInt.h) (revision 7f1ad54528440269c6a26b63c1cb0f0d35001e9c) @@ -600,7 +600,7 @@ NSF_GUARD_OPTION, NSF___UNKNOWN__, /* Partly redefined Tcl commands; leave them together at the end */ NSF_EXPR, NSF_FORMAT, NSF_INFO_BODY, NSF_INFO_FRAME, NSF_INTERP, NSF_IS, - NSF_RENAME, NSF_SUBST + NSF_RENAME } NsfGlobalNames; #if !defined(NSF_C) extern char *NsfGlobalStrings[]; @@ -620,7 +620,7 @@ "-guard", "__unknown__", /* tcl commands */ "expr", "format", "::tcl::info::body", "::tcl::info::frame", "interp", "::tcl::string::is", - "rename", "subst" + "rename" }; #endif @@ -704,6 +704,8 @@ #if defined(NSF_PROFILE) typedef struct NsfProfile { long int overallTime; + long int startSec; + long int startUSec; Tcl_HashTable objectData; Tcl_HashTable methodData; } NsfProfile; @@ -778,20 +780,12 @@ */ #if defined(NSF_PROFILE) -extern void -NsfProfileFillTable(Tcl_HashTable *table, Tcl_DString *key, - double totalMicroSec); -extern void -NsfProfileEvaluateData(Tcl_Interp* interp, NsfCallStackContent *cscPtr); - -extern void -NsfProfilePrintTable(Tcl_HashTable *table); - -extern void -NsfProfilePrintData(Tcl_Interp *interp); - -extern void -NsfProfileInit(Tcl_Interp *interp); +extern void NsfProfileEvaluateData(Tcl_Interp* interp, NsfCallStackContent *cscPtr); +extern void NsfProfilePrintData(Tcl_Interp *interp); +extern void NsfProfileInit(Tcl_Interp *interp); +extern void NsfProfileClearData(Tcl_Interp *interp); +extern void NsfProfileGetData(Tcl_Interp *interp); +extern NsfCallStackContent *NsfCallStackGetTopFrame(Tcl_Interp *interp, Tcl_CallFrame **framePtrPtr); #endif /* Index: generic/nsfProfile.c =================================================================== diff -u -r257ab674b56a5d699871bbe89157049bdf67127e -r7f1ad54528440269c6a26b63c1cb0f0d35001e9c --- generic/nsfProfile.c (.../nsfProfile.c) (revision 257ab674b56a5d699871bbe89157049bdf67127e) +++ generic/nsfProfile.c (.../nsfProfile.c) (revision 7f1ad54528440269c6a26b63c1cb0f0d35001e9c) @@ -15,12 +15,13 @@ #include "nsfInt.h" +#if defined(NSF_PROFILE) + typedef struct NsfProfileData { long microSec; long count; } NsfProfileData; -#if defined(NSF_PROFILE) static void NsfProfileFillTable(Tcl_HashTable *table, char *keyStr, double totalMicroSec) { NsfProfileData *value; Index: generic/nsfShadow.c =================================================================== diff -u -reea1c3907d9df65b1e1f80a0d19df35a5dc33d50 -r7f1ad54528440269c6a26b63c1cb0f0d35001e9c --- generic/nsfShadow.c (.../nsfShadow.c) (revision eea1c3907d9df65b1e1f80a0d19df35a5dc33d50) +++ generic/nsfShadow.c (.../nsfShadow.c) (revision 7f1ad54528440269c6a26b63c1cb0f0d35001e9c) @@ -352,7 +352,7 @@ int initialized = (RUNTIME_STATE(interp)->tclCommands != NULL); assert(initialized == 0); RUNTIME_STATE(interp)->tclCommands = - NEW_ARRAY(NsfShadowTclCommandInfo, NSF_SUBST - NSF_EXPR + 1); + NEW_ARRAY(NsfShadowTclCommandInfo, NSF_RENAME - NSF_EXPR + 1); /*fprintf(stderr, "+++ load tcl commands %d %d\n", load, initialized);*/ @@ -361,7 +361,6 @@ e.g. Tcl_ExprObjCmd(), Tcl_IncrObjCmd() and Tcl_SubstObjCmd(), which are not available in though the stub table */ rc |= NsfReplaceCommand(interp, NSF_EXPR, NULL, initialized); - rc |= NsfReplaceCommand(interp, NSF_SUBST, NULL, initialized); #endif rc |= NsfReplaceCommand(interp, NSF_FORMAT, NULL, initialized); rc |= NsfReplaceCommand(interp, NSF_INTERP, NULL, initialized); Index: generic/nsfStack.c =================================================================== diff -u -r257ab674b56a5d699871bbe89157049bdf67127e -r7f1ad54528440269c6a26b63c1cb0f0d35001e9c --- generic/nsfStack.c (.../nsfStack.c) (revision 257ab674b56a5d699871bbe89157049bdf67127e) +++ generic/nsfStack.c (.../nsfStack.c) (revision 7f1ad54528440269c6a26b63c1cb0f0d35001e9c) @@ -887,7 +887,6 @@ int allowDestroy = RUNTIME_STATE(interp)->exitHandlerDestroyRound != NSF_EXITHANDLER_ON_SOFT_DESTROY; NsfObject *object; - int flags; assert(cscPtr); assert(cscPtr->self); @@ -897,7 +896,6 @@ #endif object = cscPtr->self; - flags = cscPtr->flags; /*fprintf(stderr, "CscFinish %p object %p %s flags %.6x cmdPtr %p\n",cscPtr, object, ObjectName(object), flags, cscPtr->cmdPtr); */ Index: generic/tclAPI.h =================================================================== diff -u -r28fd214e129bc6c2384a2ef587a2be8b480c7248 -r7f1ad54528440269c6a26b63c1cb0f0d35001e9c --- generic/tclAPI.h (.../tclAPI.h) (revision 28fd214e129bc6c2384a2ef587a2be8b480c7248) +++ generic/tclAPI.h (.../tclAPI.h) (revision 7f1ad54528440269c6a26b63c1cb0f0d35001e9c) @@ -241,6 +241,9 @@ static int NsfNSCopyVarsCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfNextCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfProcCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int NsfProfileClearDataStubStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int NsfProfileGetDataStubStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); +static int NsfProfilePrintDataStubStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfQualifyObjCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfRelationCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); static int NsfSelfCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv []); @@ -324,6 +327,9 @@ static int NsfNSCopyVarsCmd(Tcl_Interp *interp, Tcl_Obj *fromNs, Tcl_Obj *toNs); static int NsfNextCmd(Tcl_Interp *interp, Tcl_Obj *arguments); static int NsfProcCmd(Tcl_Interp *interp, int withAd, Tcl_Obj *procName, Tcl_Obj *arguments, Tcl_Obj *body); +static int NsfProfileClearDataStub(Tcl_Interp *interp); +static int NsfProfileGetDataStub(Tcl_Interp *interp); +static int NsfProfilePrintDataStub(Tcl_Interp *interp); static int NsfQualifyObjCmd(Tcl_Interp *interp, Tcl_Obj *objectName); static int NsfRelationCmd(Tcl_Interp *interp, NsfObject *object, int relationtype, Tcl_Obj *value); static int NsfSelfCmd(Tcl_Interp *interp); @@ -408,6 +414,9 @@ NsfNSCopyVarsCmdIdx, NsfNextCmdIdx, NsfProcCmdIdx, + NsfProfileClearDataStubIdx, + NsfProfileGetDataStubIdx, + NsfProfilePrintDataStubIdx, NsfQualifyObjCmdIdx, NsfRelationCmdIdx, NsfSelfCmdIdx, @@ -1336,6 +1345,54 @@ } static int +NsfProfileClearDataStubStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + (void)clientData; + + + + if (objc != 1) { + return ArgumentError(interp, "too many arguments:", + method_definitions[NsfProfileClearDataStubIdx].paramDefs, + NULL, objv[0]); + } + + return NsfProfileClearDataStub(interp); + +} + +static int +NsfProfileGetDataStubStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + (void)clientData; + + + + if (objc != 1) { + return ArgumentError(interp, "too many arguments:", + method_definitions[NsfProfileGetDataStubIdx].paramDefs, + NULL, objv[0]); + } + + return NsfProfileGetDataStub(interp); + +} + +static int +NsfProfilePrintDataStubStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { + (void)clientData; + + + + if (objc != 1) { + return ArgumentError(interp, "too many arguments:", + method_definitions[NsfProfilePrintDataStubIdx].paramDefs, + NULL, objv[0]); + } + + return NsfProfilePrintDataStub(interp); + +} + +static int NsfQualifyObjCmdStub(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { (void)clientData; @@ -2249,6 +2306,15 @@ {"arguments", NSF_ARG_REQUIRED, 0, ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}, {"body", NSF_ARG_REQUIRED, 0, ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, +{"::nsf::__profile_clear", NsfProfileClearDataStubStub, 0, { + {NULL, 0, 0, NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} +}, +{"::nsf::__profile_get", NsfProfileGetDataStubStub, 0, { + {NULL, 0, 0, NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} +}, +{"::nsf::__profile_print", NsfProfilePrintDataStubStub, 0, { + {NULL, 0, 0, NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} +}, {"::nsf::qualify", NsfQualifyObjCmdStub, 1, { {"objectName", NSF_ARG_REQUIRED, 0, ConvertToTclobj, NULL,NULL,NULL,NULL,NULL,NULL,NULL}} }, Index: library/nx/nx.tcl =================================================================== diff -u -r1da9ce4144ca62bd435da5c165fc40983611ecc4 -r7f1ad54528440269c6a26b63c1cb0f0d35001e9c --- library/nx/nx.tcl (.../nx.tcl) (revision 1da9ce4144ca62bd435da5c165fc40983611ecc4) +++ library/nx/nx.tcl (.../nx.tcl) (revision 7f1ad54528440269c6a26b63c1cb0f0d35001e9c) @@ -1030,11 +1030,12 @@ ::nsf::forward ${os}::Object class ::nsf::relation %self class # all other relation cmds are defined as slots + ::nx::RelationSlot create ${os}::Class::slot::superclass \ -default ${os}::Object ::nx::RelationSlot create ${os}::Object::slot::mixin \ - -forwardername object-mixin + -forwardername object-mixin ::nx::RelationSlot create ${os}::Object::slot::filter -elementtype "" \ -forwardername object-filter