Tcl Source Code

Check-in [af06c0fbf8]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:clarify the resume sequence in TEBCresume; make checkInterp a local variable, remove it from the saved struct
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: af06c0fbf8f83c0c49c65ef6a681bfa596ebec5c
User & Date: mig 2013-12-31 12:14:50
References
2014-09-26
16:19 New ticket [82521bfb67] Segfault from commit af06c0fbf8 onwards. artifact: 01f7bd1b90 user: anonymous
Context
2013-12-31
16:26
more peephole optimizations in TEBC, and better instruction execution traces check-in: c5d6c15df9 user: dkf tags: trunk
12:38
merge trunk; segfault in assemble-30.4, to be investigated check-in: 6896877443 user: mig tags: mig-optimize
12:14
clarify the resume sequence in TEBCresume; make checkInterp a local variable, remove it from the sav... check-in: af06c0fbf8 user: mig tags: trunk
10:47
remove ill-advised change to assembler

What made sense for the compiler does not for the assemble... check-in: eabc1b8699 user: dkf tags: trunk

Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tclExecute.c.

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
typedef struct TEBCdata {
    ByteCode *codePtr;		/* Constant until the BC returns */
				/* -----------------------------------------*/
    const unsigned char *pc;	/* These fields are used on return TO this */
    ptrdiff_t *catchTop;	/* this level: they record the state when a */
    int cleanup;		/* new codePtr was received for NR */
    Tcl_Obj *auxObjList;	/* execution. */
    int checkInterp;
    CmdFrame cmdFrame;
    void *stack[1];		/* Start of the actual combined catch and obj
				 * stacks; the struct will be expanded as
				 * necessary */
} TEBCdata;

#define TEBC_YIELD() \







<







174
175
176
177
178
179
180

181
182
183
184
185
186
187
typedef struct TEBCdata {
    ByteCode *codePtr;		/* Constant until the BC returns */
				/* -----------------------------------------*/
    const unsigned char *pc;	/* These fields are used on return TO this */
    ptrdiff_t *catchTop;	/* this level: they record the state when a */
    int cleanup;		/* new codePtr was received for NR */
    Tcl_Obj *auxObjList;	/* execution. */

    CmdFrame cmdFrame;
    void *stack[1];		/* Start of the actual combined catch and obj
				 * stacks; the struct will be expanded as
				 * necessary */
} TEBCdata;

#define TEBC_YIELD() \
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
    esPtr->tosPtr = initTosPtr;

    TD->codePtr     = codePtr;
    TD->pc	    = codePtr->codeStart;
    TD->catchTop    = initCatchTop;
    TD->cleanup     = 0;
    TD->auxObjList  = NULL;
    TD->checkInterp = 0;

    /*
     * TIP #280: Initialize the frame. Do not push it yet: it will be pushed
     * every time that we call out from this TD, popped when we return to it.
     */

    bcFramePtr->type = ((codePtr->flags & TCL_BYTECODE_PRECOMPILED)







<







1987
1988
1989
1990
1991
1992
1993

1994
1995
1996
1997
1998
1999
2000
    esPtr->tosPtr = initTosPtr;

    TD->codePtr     = codePtr;
    TD->pc	    = codePtr->codeStart;
    TD->catchTop    = initCatchTop;
    TD->cleanup     = 0;
    TD->auxObjList  = NULL;


    /*
     * TIP #280: Initialize the frame. Do not push it yet: it will be pushed
     * every time that we call out from this TD, popped when we return to it.
     */

    bcFramePtr->type = ((codePtr->flags & TCL_BYTECODE_PRECOMPILED)
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100


2101
2102
2103
2104
2105
2106
2107
     * used too frequently
     */

    TEBCdata *TD = data[0];
#define auxObjList	(TD->auxObjList)
#define catchTop	(TD->catchTop)
#define codePtr		(TD->codePtr)
#define checkInterp	(TD->checkInterp)
			/* Indicates when a check of interp readyness is
			 * necessary. Set by CACHE_STACK_INFO() */

    /*
     * Globals: variables that store state, must remain valid at all times.
     */

    Tcl_Obj **tosPtr;		/* Cached pointer to top of evaluation
				 * stack. */
    const unsigned char *pc;	/* The current program counter. */
    unsigned char inst;         /* The currently running instruction */
    
    /*
     * Transfer variables - needed only between opcodes, but not while
     * executing an instruction.
     */

    int cleanup = 0;
    Tcl_Obj *objResultPtr;



    /*
     * Locals - variables that are used within opcodes or bounded sections of
     * the file (jumps between opcodes within a family).
     * NOTE: These are now mostly defined locally where needed.
     */








<
<
<

















>
>







2072
2073
2074
2075
2076
2077
2078



2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
     * used too frequently
     */

    TEBCdata *TD = data[0];
#define auxObjList	(TD->auxObjList)
#define catchTop	(TD->catchTop)
#define codePtr		(TD->codePtr)




    /*
     * Globals: variables that store state, must remain valid at all times.
     */

    Tcl_Obj **tosPtr;		/* Cached pointer to top of evaluation
				 * stack. */
    const unsigned char *pc;	/* The current program counter. */
    unsigned char inst;         /* The currently running instruction */
    
    /*
     * Transfer variables - needed only between opcodes, but not while
     * executing an instruction.
     */

    int cleanup = 0;
    Tcl_Obj *objResultPtr;
    int checkInterp;            /* Indicates when a check of interp readyness
				 * is necessary. Set by CACHE_STACK_INFO() */

    /*
     * Locals - variables that are used within opcodes or bounded sections of
     * the file (jumps between opcodes within a family).
     * NOTE: These are now mostly defined locally where needed.
     */

2125
2126
2127
2128
2129
2130
2131





2132

2133
2134

2135

2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
    if (!data[1] && (tclTraceExec >= 2)) {
	PrintByteCodeInfo(codePtr);
	fprintf(stdout, "  Starting stack top=%d\n", (int) CURR_DEPTH);
	fflush(stdout);
    }
#endif






    if (data[1] /* resume from invocation */) {

	if (iPtr->execEnvPtr->rewind) {
	    result = TCL_ERROR;

	}

	NRE_ASSERT(iPtr->cmdFramePtr == bcFramePtr);
	if (bcFramePtr->cmdObj) {
	    Tcl_DecrRefCount(bcFramePtr->cmdObj);
	    bcFramePtr->cmdObj = NULL;
	    bcFramePtr->cmd = NULL;
	}
	iPtr->cmdFramePtr = bcFramePtr->nextPtr;
	if (iPtr->flags & INTERP_DEBUG_FRAME) {
	    TclArgumentBCRelease((Tcl_Interp *) iPtr, bcFramePtr);
	}
	if (codePtr->flags & TCL_BYTECODE_RECOMPILE) {
	    iPtr->flags |= ERR_ALREADY_LOGGED;
	    codePtr->flags &= ~TCL_BYTECODE_RECOMPILE;
	}

	CACHE_STACK_INFO();
	if (result == TCL_OK) {
	    /*
	     * Push the call's object result and continue execution with the
	     * next instruction.
	     */

	    TRACE_WITH_OBJ(("%u => ... after \"%.20s\": TCL_OK, result=",







>
>
>
>
>
|
>


>

>















<







2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155

2156
2157
2158
2159
2160
2161
2162
    if (!data[1] && (tclTraceExec >= 2)) {
	PrintByteCodeInfo(codePtr);
	fprintf(stdout, "  Starting stack top=%d\n", (int) CURR_DEPTH);
	fflush(stdout);
    }
#endif

    if (!data[1]) {
	/* bytecode is starting from scratch */
	checkInterp = 0;
	goto cleanup0;
    } else {
        /* resume from invocation */
	CACHE_STACK_INFO();
	if (iPtr->execEnvPtr->rewind) {
	    result = TCL_ERROR;
	    goto abnormalReturn;
	}

	NRE_ASSERT(iPtr->cmdFramePtr == bcFramePtr);
	if (bcFramePtr->cmdObj) {
	    Tcl_DecrRefCount(bcFramePtr->cmdObj);
	    bcFramePtr->cmdObj = NULL;
	    bcFramePtr->cmd = NULL;
	}
	iPtr->cmdFramePtr = bcFramePtr->nextPtr;
	if (iPtr->flags & INTERP_DEBUG_FRAME) {
	    TclArgumentBCRelease((Tcl_Interp *) iPtr, bcFramePtr);
	}
	if (codePtr->flags & TCL_BYTECODE_RECOMPILE) {
	    iPtr->flags |= ERR_ALREADY_LOGGED;
	    codePtr->flags &= ~TCL_BYTECODE_RECOMPILE;
	}


	if (result == TCL_OK) {
	    /*
	     * Push the call's object result and continue execution with the
	     * next instruction.
	     */

	    TRACE_WITH_OBJ(("%u => ... after \"%.20s\": TCL_OK, result=",
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
#ifndef TCL_COMPILE_DEBUG
	    if (*pc == INST_POP) {
		TclDecrRefCount(objResultPtr);
		NEXT_INST_V(1, cleanup, 0);
	    }
#endif
	    NEXT_INST_V(0, cleanup, -1);
	}

	/*
	 * Result not TCL_OK: fall through
	 */
    }

    if (iPtr->execEnvPtr->rewind) {
	result = TCL_ERROR;
	goto abnormalReturn;
    }

    if (result != TCL_OK) {
	pc--;
	goto processExceptionReturn;
    }

    /*
     * Loop executing instructions until a "done" instruction, a TCL_RETURN,
     * or some error.
     */

    goto cleanup0;

    /*
     * Targets for standard instruction endings; unrolled for speed in the
     * most frequent cases (instructions that consume up to two stack
     * elements).
     *
     * This used to be a "for(;;)" loop, with each instruction doing its own







<
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
<
<
<
<
<
<







2180
2181
2182
2183
2184
2185
2186

2187











2188
2189
2190
2191






2192
2193
2194
2195
2196
2197
2198
#ifndef TCL_COMPILE_DEBUG
	    if (*pc == INST_POP) {
		TclDecrRefCount(objResultPtr);
		NEXT_INST_V(1, cleanup, 0);
	    }
#endif
	    NEXT_INST_V(0, cleanup, -1);

	} else {











	    pc--;
	    goto processExceptionReturn;
	}
    }







    /*
     * Targets for standard instruction endings; unrolled for speed in the
     * most frequent cases (instructions that consume up to two stack
     * elements).
     *
     * This used to be a "for(;;)" loop, with each instruction doing its own