And it cannot call back into JavaScript. Because that could obviously also trigger garbage collection. Because you don't know what your JavaScript functions do. And so, the idea is, you write two implementations of a C++ function. One that is slow and one that is fast. And the fast calls are only being used after V8 detects that your code has run a lot. And so, it needs to optimize it. It wants to optimize it. And it recompiles your JavaScript function that was called a lot to be able to make use of the fast API. And one particular thing that's worth calling out about this is that V8, again, is a very smart piece of software. It may do this asynchronously.
So, like, it may take your JavaScript code, notice it has been called a lot, notice that it should be optimized, but then do that optimization on another thread in your application. So, like, it doesn't stop your code from running. It just, like, says, hey, this function needs to be optimized, recompile it, hands it off to another thread. And once it's done, it starts using that new implementation of your function. Super smart, really, if you think about it. And so, we go back to the example from earlier, and we look at this, and it kind of all comes together, right?
So, like, the reason why this happens after a flaky number of iterations and only after a bunch of them is that this function, this buffer.from in this case, needs to be called a lot in order to make the engine realize, hey, it's worth spending time to optimize this. It's worth spending energy on. Because it happens in a separate thread, it only happens after an unknown, but undeterministic number of iterations. So, that is definitely where this bug comes from. And so, I told you there's, like, two of these string representations that are worth paying special attention to, right? And so, one of them, one byte string, that's V8's name for ISA88591, and two byte string, that's V8's name for UTF-16. And those are just, like, the, so, six stands for sequential. So, those are the sequential representations where a string is really just, like, one sequence of bytes in memory without any special substring or slice or, you know, concatenation or anything like that.
So, if we look again at this slide from earlier, where we looked at the implementation of the fast write string method, we can see, okay, so, this fast write string method has the prerequisite, the second argument it gets, is a one byte string. And if you remember the previous slide, that means it's an ISA88591 string. And so, it copies this into the destination from the source, from this ISA88591 string, and this method doesn't do any other checking. So, if you remember, we were using this implementation for UTF-8 as well. And so, that's not what it should be doing. It just literally copies byte sequences from something that is one thing into something that's supposed to be something else. That's also why this bug, for example, didn't reproduce with all the characters.
Comments