InterLisp (and a number of other things coming out of Xerox PARC in the early eighties) had the same feature. You saved the running state of your system to file, you invoked the function (sysout). To restore the running state of your system from a file, you invoked (sysin filename). Essentially this was a memory dump of the heap, but it had the special property that the 'spaghetti stack' - the branching stack structure through which InterLisp managed multitasking - was implemented in the heap rather than as a separate structure, so loading in the heap also loaded in the stack, for all threads.
Obviously, in InterLisp as in Smalltalk, everything in memory was inspectable and editable, and when you edited a function that didn't mean editing and reloading a file, the source code was an in-memory structure. It wasn't entirely without problems - there were small semantic differences between interpreted code and compiled code (if I remember correctly interpreted code implemented shallow binding while compiled code implemented deep binding), so that when you compiled your code its behaviour could change. Also it was possible, if you added a comment in the wrong place, that it could change the semantics of a function. For example if you added a comment as the last form in a function body, that function would always return nil. Nevertheless in terms of programmer productivity these environments were streets ahead of anything that's commercially available now; and although I love LightTable and hope that it is the shape of things to come, even LightTable isn't a patch on InterLisp's DEdit.