Rework charRange() to avoid full string scans

charRange() was originally written before we explicitly tracked the
character length of strings. This left a few oppertunities to avoid full
string scans of Unicode strings:

- If the range extends past the end of the string fail the range
  immediately

- Instead of special casing end == -1 also recognize end == charLength()
  and immediately generate a pointer to the end of the string

- If start == end == charLength() immediately generate a zero length
  range at the end of the string
Add alloc::FreezeGc

This freezes the garbage collector with the specified number of conses
pre-allocated. This is intended to be used when building complex
structures incrementally where a GC pass might erroneously free the
partial structure before it can be returned and become reachable.

Due to lack of a GC implementation this is currently a stub.