Skip to content

Commit 54ed815

Browse files
committed
Bake following variable links into most TEBC LVT accesses; only the link formation opcodes don't do it that way
1 parent 6accfb8 commit 54ed815

File tree

1 file changed

+42
-109
lines changed

1 file changed

+42
-109
lines changed

generic/tclExecute.c

Lines changed: 42 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,16 @@ TclNRExecuteByteCode(
21022102
return TCL_OK;
21032103
}
21042104

2105+
static inline Var *
2106+
FollowLinks(
2107+
Var *varPtr)
2108+
{
2109+
while (TclIsVarLink(varPtr)) {
2110+
varPtr = varPtr->value.linkPtr;
2111+
}
2112+
return varPtr;
2113+
}
2114+
21052115
static int
21062116
TEBCresume(
21072117
void *data[],
@@ -2150,6 +2160,7 @@ TEBCresume(
21502160

21512161
#define LOCAL(i) (&compiledLocals[(i)])
21522162
#define TCONST(i) (constants[(i)])
2163+
#define LOCALVAR(i) FollowLinks(LOCAL(i))
21532164

21542165
/*
21552166
* These macros are just meant to save some global variables that are not
@@ -3160,10 +3171,7 @@ TEBCresume(
31603171
case INST_LOAD_SCALAR1:
31613172
DEPRECATED_OPCODE_MARK(INST_LOAD_SCALAR1);
31623173
varIdx = TclGetUInt1AtPtr(pc + 1);
3163-
varPtr = LOCAL(varIdx);
3164-
while (TclIsVarLink(varPtr)) {
3165-
varPtr = varPtr->value.linkPtr;
3166-
}
3174+
varPtr = LOCALVAR(varIdx);
31673175
TRACE(("%u => ", (unsigned) varIdx));
31683176
if (TclIsVarDirectReadable(varPtr)) {
31693177
/*
@@ -3184,10 +3192,7 @@ TEBCresume(
31843192
case INST_LOAD_SCALAR:
31853193
instLoadScalar:
31863194
varIdx = TclGetUInt4AtPtr(pc + 1);
3187-
varPtr = LOCAL(varIdx);
3188-
while (TclIsVarLink(varPtr)) {
3189-
varPtr = varPtr->value.linkPtr;
3190-
}
3195+
varPtr = LOCALVAR(varIdx);
31913196
TRACE(("%u => ", (unsigned) varIdx));
31923197
if (TclIsVarDirectReadable(varPtr)) {
31933198
/*
@@ -3219,10 +3224,7 @@ TEBCresume(
32193224
#endif
32203225
part1Ptr = NULL;
32213226
part2Ptr = OBJ_AT_TOS;
3222-
arrayPtr = LOCAL(varIdx);
3223-
while (TclIsVarLink(arrayPtr)) {
3224-
arrayPtr = arrayPtr->value.linkPtr;
3225-
}
3227+
arrayPtr = LOCALVAR(varIdx);
32263228
TRACE(("%u \"%.30s\" => ", (unsigned) varIdx, O2S(part2Ptr)));
32273229
if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr)) {
32283230
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
@@ -3332,12 +3334,9 @@ TEBCresume(
33323334
#endif
33333335
valuePtr = OBJ_AT_TOS;
33343336
part2Ptr = OBJ_UNDER_TOS;
3335-
arrayPtr = LOCAL(varIdx);
3337+
arrayPtr = LOCALVAR(varIdx);
33363338
TRACE(("%u \"%.30s\" <- \"%.30s\" => ", (unsigned) varIdx, O2S(part2Ptr),
33373339
O2S(valuePtr)));
3338-
while (TclIsVarLink(arrayPtr)) {
3339-
arrayPtr = arrayPtr->value.linkPtr;
3340-
}
33413340
if (TclIsVarArray(arrayPtr) && !WriteTraced(arrayPtr)) {
33423341
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
33433342
if (varPtr && TclIsVarDirectWritable(varPtr)) {
@@ -3368,11 +3367,8 @@ TEBCresume(
33683367
doStoreScalarDirect:
33693368
#endif
33703369
valuePtr = OBJ_AT_TOS;
3371-
varPtr = LOCAL(varIdx);
3370+
varPtr = LOCALVAR(varIdx);
33723371
TRACE(("%u <- \"%.30s\" => ", (unsigned) varIdx, O2S(valuePtr)));
3373-
while (TclIsVarLink(varPtr)) {
3374-
varPtr = varPtr->value.linkPtr;
3375-
}
33763372
if (!TclIsVarDirectWritable(varPtr)) {
33773373
storeFlags = TCL_LEAVE_ERR_MSG;
33783374
part1Ptr = NULL;
@@ -3501,12 +3497,9 @@ TEBCresume(
35013497
doStoreArray:
35023498
valuePtr = OBJ_AT_TOS;
35033499
part2Ptr = OBJ_UNDER_TOS;
3504-
arrayPtr = LOCAL(varIdx);
3500+
arrayPtr = LOCALVAR(varIdx);
35053501
TRACE(("%u \"%.30s\" <- \"%.30s\" => ", (unsigned) varIdx, O2S(part2Ptr),
35063502
O2S(valuePtr)));
3507-
while (TclIsVarLink(arrayPtr)) {
3508-
arrayPtr = arrayPtr->value.linkPtr;
3509-
}
35103503
cleanup = 2;
35113504
part1Ptr = NULL;
35123505

@@ -3553,11 +3546,8 @@ TEBCresume(
35533546

35543547
doStoreScalar:
35553548
valuePtr = OBJ_AT_TOS;
3556-
varPtr = LOCAL(varIdx);
3549+
varPtr = LOCALVAR(varIdx);
35573550
TRACE(("%u <- \"%.30s\" => ", (unsigned) varIdx, O2S(valuePtr)));
3558-
while (TclIsVarLink(varPtr)) {
3559-
varPtr = varPtr->value.linkPtr;
3560-
}
35613551
cleanup = 1;
35623552
arrayPtr = NULL;
35633553
part1Ptr = part2Ptr = NULL;
@@ -3582,12 +3572,9 @@ TEBCresume(
35823572
case INST_LAPPEND_LIST:
35833573
varIdx = TclGetUInt4AtPtr(pc + 1);
35843574
valuePtr = OBJ_AT_TOS;
3585-
varPtr = LOCAL(varIdx);
3575+
varPtr = LOCALVAR(varIdx);
35863576
cleanup = 1;
35873577
pcAdjustment = 5;
3588-
while (TclIsVarLink(varPtr)) {
3589-
varPtr = varPtr->value.linkPtr;
3590-
}
35913578
TRACE(("%u <- \"%.30s\" => ", (unsigned) varIdx, O2S(valuePtr)));
35923579
if (TclListObjGetElements(interp, valuePtr, &objc, &objv)
35933580
!= TCL_OK) {
@@ -3607,12 +3594,9 @@ TEBCresume(
36073594
valuePtr = OBJ_AT_TOS;
36083595
part1Ptr = NULL;
36093596
part2Ptr = OBJ_UNDER_TOS;
3610-
arrayPtr = LOCAL(varIdx);
3597+
arrayPtr = LOCALVAR(varIdx);
36113598
cleanup = 2;
36123599
pcAdjustment = 5;
3613-
while (TclIsVarLink(arrayPtr)) {
3614-
arrayPtr = arrayPtr->value.linkPtr;
3615-
}
36163600
TRACE(("%u \"%.30s\" \"%.30s\" => ",
36173601
(unsigned) varIdx, O2S(part2Ptr), O2S(valuePtr)));
36183602
if (TclListObjGetElements(interp, valuePtr, &objc, &objv)
@@ -3868,11 +3852,8 @@ TEBCresume(
38683852
doIncrArray:
38693853
part1Ptr = NULL;
38703854
part2Ptr = OBJ_AT_TOS;
3871-
arrayPtr = LOCAL(varIdx);
3855+
arrayPtr = LOCALVAR(varIdx);
38723856
cleanup = 1;
3873-
while (TclIsVarLink(arrayPtr)) {
3874-
arrayPtr = arrayPtr->value.linkPtr;
3875-
}
38763857
TRACE(("%u \"%.30s\" (by %ld) => ", (unsigned) varIdx, O2S(part2Ptr),
38773858
increment));
38783859
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
@@ -3900,10 +3881,7 @@ TEBCresume(
39003881
doIncrScalarImm:
39013882
#endif
39023883
cleanup = 0;
3903-
varPtr = LOCAL(varIdx);
3904-
while (TclIsVarLink(varPtr)) {
3905-
varPtr = varPtr->value.linkPtr;
3906-
}
3884+
varPtr = LOCALVAR(varIdx);
39073885

39083886
if (TclIsVarDirectModifyable(varPtr)) {
39093887
void *ptr;
@@ -3981,10 +3959,7 @@ TEBCresume(
39813959
Tcl_IncrRefCount(incrPtr);
39823960

39833961
doIncrScalar:
3984-
varPtr = LOCAL(varIdx);
3985-
while (TclIsVarLink(varPtr)) {
3986-
varPtr = varPtr->value.linkPtr;
3987-
}
3962+
varPtr = LOCALVAR(varIdx);
39883963
arrayPtr = NULL;
39893964
part1Ptr = part2Ptr = NULL;
39903965
cleanup = 0;
@@ -4038,10 +4013,7 @@ TEBCresume(
40384013
cleanup = 0;
40394014
pcAdjustment = 5;
40404015
varIdx = TclGetUInt4AtPtr(pc + 1);
4041-
varPtr = LOCAL(varIdx);
4042-
while (TclIsVarLink(varPtr)) {
4043-
varPtr = varPtr->value.linkPtr;
4044-
}
4016+
varPtr = LOCALVAR(varIdx);
40454017
TRACE(("%u => ", (unsigned) varIdx));
40464018
if (ReadTraced(varPtr)) {
40474019
DECACHE_STACK_INFO();
@@ -4060,10 +4032,7 @@ TEBCresume(
40604032
pcAdjustment = 5;
40614033
varIdx = TclGetUInt4AtPtr(pc + 1);
40624034
part2Ptr = OBJ_AT_TOS;
4063-
arrayPtr = LOCAL(varIdx);
4064-
while (TclIsVarLink(arrayPtr)) {
4065-
arrayPtr = arrayPtr->value.linkPtr;
4066-
}
4035+
arrayPtr = LOCALVAR(varIdx);
40674036
TRACE(("%u \"%.30s\" => ", (unsigned)varIdx, O2S(part2Ptr)));
40684037
if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr)) {
40694038
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
@@ -4141,10 +4110,7 @@ TEBCresume(
41414110
case INST_UNSET_SCALAR:
41424111
flags = TclGetUInt1AtPtr(pc + 1) ? TCL_LEAVE_ERR_MSG : 0;
41434112
varIdx = TclGetUInt4AtPtr(pc + 2);
4144-
varPtr = LOCAL(varIdx);
4145-
while (TclIsVarLink(varPtr)) {
4146-
varPtr = varPtr->value.linkPtr;
4147-
}
4113+
varPtr = LOCALVAR(varIdx);
41484114
TRACE(("%s %u => ", (flags ? "normal" : "noerr"), (unsigned)varIdx));
41494115
if (TclIsVarDirectUnsettable(varPtr) && !TclIsVarInHash(varPtr)) {
41504116
/*
@@ -4175,10 +4141,7 @@ TEBCresume(
41754141
flags = TclGetUInt1AtPtr(pc + 1) ? TCL_LEAVE_ERR_MSG : 0;
41764142
varIdx = TclGetUInt4AtPtr(pc + 2);
41774143
part2Ptr = OBJ_AT_TOS;
4178-
arrayPtr = LOCAL(varIdx);
4179-
while (TclIsVarLink(arrayPtr)) {
4180-
arrayPtr = arrayPtr->value.linkPtr;
4181-
}
4144+
arrayPtr = LOCALVAR(varIdx);
41824145
TRACE(("%s %u \"%.30s\" => ",
41834146
(flags ? "normal" : "noerr"), (unsigned)varIdx, O2S(part2Ptr)));
41844147
if (TclIsVarArray(arrayPtr) && !UnsetTraced(arrayPtr)
@@ -4272,11 +4235,8 @@ TEBCresume(
42724235
part1Ptr = NULL;
42734236
objPtr = OBJ_AT_TOS;
42744237
TRACE(("%u \"%.30s\" => \n", (unsigned) varIdx, O2S(objPtr)));
4275-
varPtr = LOCAL(varIdx);
4238+
varPtr = LOCALVAR(varIdx);
42764239
arrayPtr = NULL;
4277-
while (TclIsVarLink(varPtr)) {
4278-
varPtr = varPtr->value.linkPtr;
4279-
}
42804240
goto doConst;
42814241
case INST_CONST_STK:
42824242
varIdx = -1;
@@ -4341,10 +4301,7 @@ TEBCresume(
43414301
part1Ptr = NULL;
43424302
arrayPtr = NULL;
43434303
TRACE(("%u => ", (unsigned)varIdx));
4344-
varPtr = LOCAL(varIdx);
4345-
while (TclIsVarLink(varPtr)) {
4346-
varPtr = varPtr->value.linkPtr;
4347-
}
4304+
varPtr = LOCALVAR(varIdx);
43484305
goto doArrayExists;
43494306
case INST_ARRAY_EXISTS_STK:
43504307
varIdx = -1;
@@ -4377,10 +4334,7 @@ TEBCresume(
43774334
part1Ptr = NULL;
43784335
arrayPtr = NULL;
43794336
TRACE(("%u => ", (unsigned)varIdx));
4380-
varPtr = LOCAL(varIdx);
4381-
while (TclIsVarLink(varPtr)) {
4382-
varPtr = varPtr->value.linkPtr;
4383-
}
4337+
varPtr = LOCALVAR(varIdx);
43844338
goto doArrayMake;
43854339
case INST_ARRAY_MAKE_STK:
43864340
varIdx = -1;
@@ -6967,10 +6921,7 @@ TEBCresume(
69676921
}
69686922

69696923
varIndex = varListPtr->varIndexes[j];
6970-
varPtr = LOCAL(varIndex);
6971-
while (TclIsVarLink(varPtr)) {
6972-
varPtr = varPtr->value.linkPtr;
6973-
}
6924+
varPtr = LOCALVAR(varIndex);
69746925
if (TclIsVarDirectWritable(varPtr)) {
69756926
value2Ptr = varPtr->value.objPtr;
69766927
if (valuePtr != value2Ptr) {
@@ -7312,10 +7263,7 @@ TEBCresume(
73127263
numArgs = TclGetUInt4AtPtr(pc + 1);
73137264
varIdx = TclGetUInt4AtPtr(pc + 5);
73147265

7315-
varPtr = LOCAL(varIdx);
7316-
while (TclIsVarLink(varPtr)) {
7317-
varPtr = varPtr->value.linkPtr;
7318-
}
7266+
varPtr = LOCALVAR(varIdx);
73197267
TRACE(("%u %u => ", (unsigned)numArgs, (unsigned)varIdx));
73207268
if (TclIsVarDirectReadable(varPtr)) {
73217269
dictPtr = varPtr->value.objPtr;
@@ -7415,10 +7363,7 @@ TEBCresume(
74157363
case INST_DICT_APPEND:
74167364
case INST_DICT_LAPPEND:
74177365
varIdx = TclGetUInt4AtPtr(pc + 1);
7418-
varPtr = LOCAL(varIdx);
7419-
while (TclIsVarLink(varPtr)) {
7420-
varPtr = varPtr->value.linkPtr;
7421-
}
7366+
varPtr = LOCALVAR(varIdx);
74227367
TRACE(("%u => ", (unsigned)varIdx));
74237368
if (TclIsVarDirectReadable(varPtr)) {
74247369
dictPtr = varPtr->value.objPtr;
@@ -7569,6 +7514,7 @@ TEBCresume(
75697514
ir.twoPtrValue.ptr2 = dictPtr;
75707515
Tcl_StoreInternalRep(statePtr, &dictIteratorType, &ir);
75717516
}
7517+
// Special var; never linked
75727518
varPtr = LOCAL(varIdx);
75737519
if (varPtr->value.objPtr) {
75747520
if (TclHasInternalRep(varPtr->value.objPtr, &dictIteratorType)) {
@@ -7584,6 +7530,7 @@ TEBCresume(
75847530
case INST_DICT_NEXT:
75857531
varIdx = TclGetUInt4AtPtr(pc + 1);
75867532
TRACE(("%u => ", (unsigned)varIdx));
7533+
// Special var; never linked
75877534
statePtr = (*LOCAL(varIdx)).value.objPtr;
75887535
{
75897536
const Tcl_ObjInternalRep *irPtr;
@@ -7622,11 +7569,8 @@ TEBCresume(
76227569
varIdx = TclGetUInt4AtPtr(pc + 1);
76237570
tblIdx = TclGetUInt4AtPtr(pc + 5);
76247571
TRACE(("%u %u => ", (unsigned)varIdx, tblIdx));
7625-
varPtr = LOCAL(varIdx);
7572+
varPtr = LOCALVAR(varIdx);
76267573
duiPtr = (DictUpdateInfo *)codePtr->auxDataArrayPtr[tblIdx].clientData;
7627-
while (TclIsVarLink(varPtr)) {
7628-
varPtr = varPtr->value.linkPtr;
7629-
}
76307574
if (TclIsVarDirectReadable(varPtr)) {
76317575
dictPtr = varPtr->value.objPtr;
76327576
} else {
@@ -7656,10 +7600,7 @@ TEBCresume(
76567600
Tcl_DecrRefCount(dictPtr);
76577601
goto gotError;
76587602
}
7659-
varPtr = LOCAL(duiPtr->varIndices[i]);
7660-
while (TclIsVarLink(varPtr)) {
7661-
varPtr = varPtr->value.linkPtr;
7662-
}
7603+
varPtr = LOCALVAR(duiPtr->varIndices[i]);
76637604
DECACHE_STACK_INFO();
76647605
if (valuePtr == NULL) {
76657606
TclObjUnsetVar2(interp,
@@ -7683,11 +7624,8 @@ TEBCresume(
76837624
varIdx = TclGetUInt4AtPtr(pc + 1);
76847625
tblIdx = TclGetUInt4AtPtr(pc + 5);
76857626
TRACE(("%u %u => ", (unsigned)varIdx, tblIdx));
7686-
varPtr = LOCAL(varIdx);
7627+
varPtr = LOCALVAR(varIdx);
76877628
duiPtr = (DictUpdateInfo *)codePtr->auxDataArrayPtr[tblIdx].clientData;
7688-
while (TclIsVarLink(varPtr)) {
7689-
varPtr = varPtr->value.linkPtr;
7690-
}
76917629
if (TclIsVarDirectReadable(varPtr)) {
76927630
dictPtr = varPtr->value.objPtr;
76937631
} else {
@@ -7714,11 +7652,9 @@ TEBCresume(
77147652
TclInvalidateStringRep(dictPtr);
77157653
}
77167654
for (i=0 ; i<length ; i++) {
7717-
Var *var2Ptr = LOCAL(duiPtr->varIndices[i]);
7718-
7719-
while (TclIsVarLink(var2Ptr)) {
7720-
var2Ptr = var2Ptr->value.linkPtr;
7721-
}
7655+
Var *var2Ptr;
7656+
7657+
var2Ptr = LOCALVAR(duiPtr->varIndices[i]);
77227658
if (TclIsVarDirectReadable(var2Ptr)) {
77237659
valuePtr = var2Ptr->value.objPtr;
77247660
} else {
@@ -7806,16 +7742,13 @@ TEBCresume(
78067742
varIdx = TclGetUInt4AtPtr(pc + 1);
78077743
listPtr = OBJ_UNDER_TOS;
78087744
keysPtr = OBJ_AT_TOS;
7809-
varPtr = LOCAL(varIdx);
7745+
varPtr = LOCALVAR(varIdx);
78107746
TRACE(("%u <- \"%.30s\" \"%.30s\" => ", (unsigned)varIdx, O2S(valuePtr),
78117747
O2S(keysPtr)));
78127748
if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
78137749
TRACE_ERROR(interp);
78147750
goto gotError;
78157751
}
7816-
while (TclIsVarLink(varPtr)) {
7817-
varPtr = varPtr->value.linkPtr;
7818-
}
78197752
DECACHE_STACK_INFO();
78207753
result = TclDictWithFinish(interp, varPtr, NULL, NULL, NULL, varIdx,
78217754
objc, objv, keysPtr);

0 commit comments

Comments
 (0)