You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#definePTFROMTYPE(z,t) {I pt=CTTZ(t); pt-=(LASTNOUNX+1); pt|=REPSGN(pt); z=ptcol[pt+1];} // here when we know it's CAVN (not assignment)
146
146
#definePTFROMTYPEASGN(z,t) {I pt=CTTZ(t); pt-=(LASTNOUNX+1); pt|=REPSGN(pt)|((t>>(CONWX-2))&(CONWX-(LASTNOUNX+1))); z=ptcol[pt+1];} // clear flag bit if ASGN to name, by fetching from unused CONW hole, which is 4 above ASGN
147
+
// CONWX-2 moves CONW to its position in the table, which is at CONWX-(LASTNOUNX+1)
147
148
148
149
staticPSTK*jtpfork(Jjt,PSTK*stack){
149
150
Ay=folk(stack[1].a,stack[2].a,stack[3].a); // create the fork
@@ -512,7 +513,9 @@ A jtparsea(J jt, A *queue, I nwds){F1PREFIP;PSTK * RESTRICT stack;A z,*v;
512
513
// Move in the new word and check its type. If it is a name that is not being assigned, resolve its
513
514
// value. m has the index of the word we just moved
514
515
// obsolete I at=AT(y = queue[mes>>2]); // fetch the next word from queue; pop the queue; extract the type, save as at
515
-
Iat=AT(nexty); y=nexty; // loop was unrolled once. We can't keep nexty and nextat in regs so we just unroll one
516
+
Iat=AT(nexty); // loop was unrolled once. We can't keep nexty and nextat in regs so we just unroll one
517
+
L*sympv=JT(jt,sympv); // symbol root can change during parse, but not during stacking of a single execution. This is a quiet time to load. Loading outside the loop causes a spill.
518
+
y=nexty;
516
519
nexty=queue[(US)mes-1]; // fetch the next word from queue; pop the queue; extract the type, save as at.
517
520
// The last fetch of nexty fetches from queue[-1]. This will not segfault, and we never come back to fetch from inside that bogus block.
518
521
stack[0].t= (US)(mes+1); // install the original token number for the word
@@ -526,12 +529,11 @@ A jtparsea(J jt, A *queue, I nwds){F1PREFIP;PSTK * RESTRICT stack;A z,*v;
526
529
// The important performance case is local names with bucket info. Pull that out & do it without the call overhead
527
530
// This code is copied from s.c, except for the symx: since that occurs only in explicit definitions we can get to it only through here
528
531
// obsolete I locstflags=AR(UNLXAV0(locbuckets)); // flags from local symbol table
529
-
L*sympv=JT(jt,sympv); // symbol root can change during parse, but not during stacking of a single execution
530
-
if(likely((SGNIF(locbuckets,ARLCLONEDX)|(NAV(y)->symx-1))>=0)){ // if we are using primary table and there is a symbol stored there...
532
+
if((SGNIF(locbuckets,ARLCLONEDX)|(NAV(y)->symx-1))>=0){ // if we are using primary table and there is a symbol stored there...
531
533
s=sympv+(I)NAV(y)->symx; // get address of symbol in primary table
532
534
if(unlikely((sv=s->val)==0))goto rdglob; // if value has not been assigned, ignore it
533
535
}elseif(likely(NAV(y)->bucket!=0)){Ibx;
534
-
if(likely(0 <= (bx= ~NAV(y)->bucketx))){ // negative bucketx (now positive); skip that many items, and then you're at the right place. This is the path for almost all local symbols
536
+
if(0 <= (bx= ~NAV(y)->bucketx)){ // negative bucketx (now positive); skip that many items, and then you're at the right place. This is the path for almost all local symbols
535
537
s= ((LX*)((I)locbuckets&-8))[NAV(y)->bucket]+sympv; // fetch hashchain headptr, point to L for first symbol
536
538
if(unlikely(bx>0)){NOUNROLLdo{s=s->next+sympv;}while(--bx);} // skip the prescribed number, which is usually 1
537
539
if(unlikely((sv=s->val)==0))goto rdglob; // if value has not been assigned, ignore it
@@ -551,12 +553,12 @@ A jtparsea(J jt, A *queue, I nwds){F1PREFIP;PSTK * RESTRICT stack;A z,*v;
551
553
IFCMPNAME(NAV(s->name),nm,m,hsh,{if(unlikely((sv=s->val)==0))goto rdglob; break;}) // if match, we're done looking; could be not found, if no value
552
554
lx=s->next;
553
555
}
554
-
// Here there was a value in the local symbol table
556
+
// Here there was a value in the local symbol table. Skip to use it
555
557
}
556
558
}else{
557
559
// No bucket info. Usually this is a locative/global, but it could be an explicit modifier, console level, or ".
558
560
// If the name has a cached reference, use it
559
-
if(likely(NAV(y)->cachedref!=0)){ // if the user doesn't care enough to turn on caching, performance must not be that important
561
+
if(NAV(y)->cachedref!=0){ // if the user doesn't care enough to turn on caching, performance must not be that important
560
562
// Note: this cannot be a NAMEABANDON, because such a name is never stacked where it can have the cachedref filled in
561
563
Acachead=NAV(y)->cachedref; // use the cached address
562
564
if(unlikely(NAV(y)->flag&NMCACHEDSYM)){cachead=(A)((sympv[(I)cachead]).val); if(unlikely(!cachead)){jsignal(EVVALUE);FP}} // if it's a symbol index, fetch that. value error only if cached symbol deleted
0 commit comments