/**** $SP,"<1>",BI=1$ Tasks have symbol tables. If symbol not found, parent task's table is searched. Adam task has system-wide symbols. SYMBOL LOOK-UP (Especially, used by JIT compiler and Loader) 1) Symbol text name is hashed -- Adding the ASCII values of all chars with shifts. 2) Hash body array is indexed. 3) Linked-lst is traversed until match of text and type-of-entry 4) If not found, next hash table is searched. Duplicate entries are allowed--they overshadow old entries. ADDRESS-TO-SYMBOL LOOK-UP (Slow because not important--could add tree) 1)PSect Cache is scanned. 2)"next_added,last_added" que links are traversed. This speeds look-up instead of scanning hash table because hash table is so sparce. See $LK,"PSectFind",A="MN:PSectFind"$(). ****/ asm { USE64 //************************************ SYS_HASH_STR:: // IN: RSI=Addr of string // OUT: RAX XOR RAX,RAX TEST RSI,RSI JZ @@15 PUSH RSI PUSH RBX XOR RBX,RBX JMP @@10 @@05: SHL1 RBX ADC RBX,RAX @@10: LODSB TEST AL,AL JNZ @@05 MOV RAX,RBX SHR RBX,16 ADC RAX,RBX POP RBX POP RSI @@15: RET //************************************ SYS_HASH_SINGLE_TABLE_FIND1:: // IN: RAX=HASHED_STRING // RSI=STR // RBX=TYPE MASK // RDI=TABLE // RCX=INSTANCE, NOT ZERO // OUT: RAX=ENTRY OR ZERO NOT FOUND // RDX=POINTER TO POINTER TO ENTRY // RCX IF NOT FOUND ENOUGH, DECREMENTED BY NUM MATCHES // ZERO FLAG SET NOT FOUND MOV RCX,1 SYS_HASH_SINGLE_TABLE_FIND:: TEST RCX,RCX JNZ @@05 XOR RAX,RAX RET @@05: AND RAX,U64 CHashTable.mask[RDI] MOV RDX,U64 CHashTable.body[RDI] LEA RDX,U64 [RDX+RAX*8] @@10: MOV RAX,U64 [RDX] TEST RAX,RAX JNZ @@15 RET @@15: TEST U32 CHash.type[RAX],EBX JZ @@30 PUSH RAX PUSH RDI PUSH RSI MOV RDI,U64 CHash.str[RAX] @@20: LODSB CMP U8 [RDI],AL JNE @@25 INC RDI TEST AL,AL JNZ @@20 POP RSI POP RDI POP RAX LOOP @@30 INC U32 CHash.use_cnt[RAX] TEST RAX,RAX RET @@25: POP RSI POP RDI POP RAX @@30: LEA RDX,U64 CHash.next[RAX] JMP @@10 //************************************ SYS_HASH_FIND1:: // IN: RSI=STR // RBX=TYPE MASK // RDI=TABLE // RCX=INSTANCE NUM // OUT: RAX=ENTRY OR ZERO NOT FOUND // ZERO FLAG SET NOT FOUND MOV RCX,1 SYS_HASH_FIND:: PUSH RDI CALL SYS_HASH_STR @@05: PUSH RAX CALL SYS_HASH_SINGLE_TABLE_FIND JNZ @@15 POP RAX @@10: MOV RDI,U64 CHashTable.next[RDI] TEST RDI,RDI JNZ @@05 POP RDI XOR RAX,RAX RET @@15: ADD RSP,8 POP RDI TEST RAX,RAX RET //************************************ SYS_HASH_BUCKET_FIND:: // IN: RSI=STR // RDI=TABLE // OUT: RAX=BUCKET PUSH RDX CALL SYS_HASH_STR AND RAX,U64 CHashTable.mask[RDI] MOV RDX,U64 CHashTable.body[RDI] LEA RAX,U64 [RDX+RAX*8] POP RDX RET _HASH_STR:: PUSH RBP MOV RBP,RSP PUSH RSI MOV RSI,U64 SF_ARG1[RBP] CALL SYS_HASH_STR POP RSI POP RBP RET1 8 _HASH_FIND:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RSI,U64 SF_ARG1[RBP] MOV RDI,U64 SF_ARG2[RBP] MOV RBX,U64 SF_ARG3[RBP] MOV RCX,U64 SF_ARG4[RBP] CALL SYS_HASH_FIND POP RDI POP RSI POP RBP RET1 32 _HASH_SINGLE_TABLE_FIND:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RSI,U64 SF_ARG1[RBP] MOV RDI,U64 SF_ARG2[RBP] MOV RBX,U64 SF_ARG3[RBP] MOV RCX,U64 SF_ARG4[RBP] CALL SYS_HASH_STR CALL SYS_HASH_SINGLE_TABLE_FIND POP RDI POP RSI POP RBP RET1 32 _HASH_BUCKET_FIND:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RSI,U64 SF_ARG1[RBP] MOV RDI,U64 SF_ARG2[RBP] CALL SYS_HASH_BUCKET_FIND POP RDI POP RSI POP RBP RET1 16 _HASH_ADD:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RCX,U64 SF_ARG1[RBP] MOV RSI,U64 CHash.str[RCX] MOV RDI,U64 SF_ARG2[RBP] CALL SYS_HASH_BUCKET_FIND MOV RCX,U64 SF_ARG1[RBP] PUSHFD CLI MOV RBX,U64 [RAX] MOV U64 CHash.next[RCX],RBX MOV U64 [RAX],RCX //QueIns RCX MOV RBX,U64 CHashTable.last_added[RDI] MOV U64 CHash.next_added[RCX],RDI MOV U64 CHash.last_added[RCX],RBX MOV U64 CHash.next_added[RBX],RCX MOV U64 CHashTable.last_added[RDI],RCX POPFD POP RDI POP RSI POP RBP RET1 16 _HASH_ADD_AFTER:: PUSH RBP MOV RBP,RSP PUSH RDI MOV RCX,U64 SF_ARG1[RBP] MOV RDI,U64 SF_ARG3[RBP] PUSHFD CLI MOV RAX,SF_ARG2[RBP] MOV RBX,U64 [RAX] MOV U64 CHash.next[RCX],RBX MOV U64 [RAX],RCX //QueIns RCX MOV RBX,U64 CHashTable.last_added[RDI] MOV U64 CHash.next_added[RCX],RDI MOV U64 CHash.last_added[RCX],RBX MOV U64 CHash.next_added[RBX],RCX MOV U64 CHashTable.last_added[RDI],RCX POPFD POP RDI POP RBP RET1 24 _HASH_REM_DEL:: PUSH RBP MOV RBP,RSP PUSH RSI PUSH RDI MOV RCX,U64 SF_ARG1[RBP] TEST RCX,RCX JZ @@10 MOV RSI,U64 CHash.str[RCX] XOR RBX,RBX MOV EBX,U32 CHash.type[RCX] AND EBX,~HTG_FLAGS_MASK&0xFFFFFFFF MOV RDI,U64 SF_ARG2[RBP] MOV RCX,U64 SF_ARG3[RBP] CALL SYS_HASH_STR PUSHFD CLI CALL SYS_HASH_SINGLE_TABLE_FIND JZ @@05 CMP RAX,U64 SF_ARG1[RBP] JNE @@05 MOV RBX,U64 CHash.next[RAX] MOV U64 [RDX],RBX //QueRem RAX MOV RBX,U64 CHash.next_added[RAX] MOV RDX,U64 CHash.last_added[RAX] MOV U64 CHash.next_added[RDX],RBX MOV U64 CHash.last_added[RBX],RDX POPFD PUSH_C_REGS PUSH RAX CALL &HashDel POP_C_REGS POP RDI POP RSI MOV RAX,1 POP RBP RET1 24 @@05: POPFD @@10: POP RDI POP RSI XOR RAX,RAX POP RBP RET1 24 } _extern _HASH_STR I64 HashStr(U8 *st); //Hash a string. _extern _HASH_FIND CHash * HashFind(U8 *needle_str,CHashTable *haystack_table,I64 mask,I64 instance=1);//Find string in hash table. _extern _HASH_SINGLE_TABLE_FIND CHash * HashSingleTableFind(U8 *needle_str,CHashTable *haystack_table,I64 mask,I64 instance=1);//Find string in single hash table. _extern _HASH_BUCKET_FIND CHash ** HashBucketFind(U8 *needle_str,CHashTable *haystack_table); //Find hash bucket. _extern _HASH_ADD U0 HashAdd(CHash *temph,CHashTable *table); //Add entry to hash table. _extern _HASH_REM_DEL Bool HashRemDel(CHash *temph,CHashTable *table,I64 instance=1);//Remove hash entry and del. Instance must match. Í  Cat8äCbsX DogtäDogÀ BirdD\`h€ô´\Ì(\,0@ô XHX` X`T` T`TH THXH lHl` ªxª\ ÀxÀ\ €H€` HHH` \H\` pHp` 4H4` xðx ðxð\ ð\\ \x $\$x 8\8x L\Lx `\`x \x 0\0x D\Dx \x x8 8ìÿÿÿ8 ìÿÿÿ8ìÿÿÿx ìÿÿÿxx H`H, H,4, 4,4` 4`H`hhHTXTüÿÿÿ8@d P\Ì\Ì4èTèdèdèdd�èpè`è\è\ô\ô¼ä<LLL(L(Œ(Œ(tT\ \ÐT4ì`Ð`TtŒ0Œ0H,H,HH<ä¼`ø`ø`ì`ìpì�ìdd`ì`ìTì