Calling [[GetOwnProperty]] on the GSP ends us in . In step 3, we call the "named property visibility algorithm"  with object /object/ (==window). In step 7 there, we call [[HasProperty]] on window.__proto__ == Window.prototype. This walks the prototype chain  and ends up calling [[GetOwnProperty]] on the GSP again.
Note that we only need to pass in the Window because we need to know stuff about its interface. We could pass the interface to the named property visibility algorithm and then pass in the gsp or its proto...
That said, I'm also not sure what step 4 of this algorithm means. Does it not involve calling [[GetOwnProperty]] on the object? Should it talk about calling the default [[GetOwnProperty]] or something?
If fact, it looks like steps 4-8 are just "return !O.[[HasProperty]](P)".
I fixed it by manually traversing up the prototype chain and skipping the named properties object.