There are four different ways that one might want to use string chars and two problems that can result when one does. ==== Problem #1: Forgetting to root the owning string for the full lifetime of the jschar* ownership. The analysis will not catch JSString *str; js::SomethingGCy(str->chars()) because there is no use of str itself after the GC. Beefing up the analysis here would be hard. Problem #2: Inline characters might move. Even if the above is fixed, once we store small strings in the nursery, the str->chars() will become invalid on a minor GC. ==== Usage #1: Looking at a single character. For example, checking if the first character of a string is a '/'. Currently we have to flatten and getChars so we have all the problems above. A new API that could avoid flattening would be nice here. Usage #2: Copying characters out of the string into a buffer. We currently have a couple of hard-to-use APIs that do this. Usage #3: Borrowing the jschar* to implement a full-string algorithm that needs the performance of raw pointer access. Usage #4: Stealing ownership of the string's characters. ==== #1 and #2 are clearly safe. We should add these APIs to JSString. #3 is the most likely to get wrong and currently the easiest to use. We should add an RAII AutoBorrowOwnedChars that forces rooting of the JSString and remove direct getChars access. This class can also solve problem #2 directly by copying short strings to the stack before giving out a jschar*. I don't think that #4 is ever done intentionally at the point.