slavapestov/factor — Issue #384: Bug with compiler optimizations?
Author: mrjbq7
Created: 2011-11-10 18:48:19+00:00
State: open

I'm trying to fix #381... but I get a weird behavior.

First, scaffold a `fasttables` vocabulary, starting with the `hashtables` implementation:

```
$ cd $FACTOR
$ mkdir work/fasttables
$ cp core/hashtables/hashtables.factor work/fasttables/fasttables.factor
```

Then, apply these diffs to add the "new key" logic:

```
> assocs math.private sequences sequences.private vectors
> hashtables.private ;
> IN: fasttables
---
> TUPLE: fasttable
---
> ! i = first-empty-or-found
> ! j = first-deleted
> : (new-key@) ( key array i j probe# -- array i j empty? )
> [ 2dup swap array-nth ] 2dip pick tombstone?
> [
> rot ((empty)) eq?
> [ drop [ drop ] 3dip t ]
> [ [ dupd or ] dip swap [ probe ] dip swap (new-key@) ]
> if
> ] [
> [ [ pick ] dip = ] 2dip rot
> [ drop [ drop ] 3dip f ]
> [ swap [ probe ] dip swap (new-key@) ]
---
> : new-key@ ( key hash -- array n empty? )
> array>> 2dup hash@ f 0 (new-key@)
> [ [ swap or ] [ drop ] if ] keep ; inline
---
> dup hash-stale? [
> drop ! grow-hash
---
> : ( n -- hash )
> fasttable new [ reset-hash ] keep ; inline
---
> M: fasttable at* ( key hash -- value ? )
---
> M: fasttable clear-assoc ( hash -- )
---
> M: fasttable delete-at ( key hash -- )
---
> M: fasttable assoc-size ( hash -- n )
---
> M: fasttable set-at ( value key hash -- )
---
> : associate ( value key -- hash )
> 2 [ set-at ] keep ;
---
> M: fasttable >alist
---
> M: fasttable clone
---
> M: fasttable equal?
> over fasttable? [ assoc= ] [ 2drop f ] if ;
---
< ! Default method
< M: assoc new-assoc drop ; inline
<
< M: f new-assoc drop ; inline
---
> M: fasttable new-assoc drop ; inline
---
> : >fasttable ( assoc -- fasttable )
> 0 assoc-clone-like ;
---
> M: fasttable assoc-like
> drop dup fasttable? [ >fasttable ] unless ; inline
---
> USE: words
>
> M\ fasttable at* { { fixnum object } { word object } } "specializer" set-word-prop
>
> M\ fasttable set-at { { object fixnum object } { object word object } } "specializer" set-word-prop
>
> USE: parser
>
> SYNTAX: F{ \ } [ >fasttable ] parse-literal ;
>
> INSTANCE: fasttable assoc
```

Try to run it from the listener (with compiler optimizations disabled):

```
IN: scratchpad USE: fasttables
IN: scratchpad F{ } clone
{ 4 2 5 4 1 6 0 0 9 5 4 9 7 9 3 7 8 2 8 9 0 8 3 0 }
[ even? [ dup pick set-at ] [ over delete-at ] if ] each-index
IN: scratchpad disable-optimizer
IN: scratchpad "fasttables" reload
IN: scratchpad 0 0 pick set-at
```
If you remove the "disable optimizer/reload" lines then it goes into an infinite loop.

I found this by adding a `B` breakpoint to `(new-key@)` and having it "work", removing it and having it infinite loop...