Add String#delete cases for benchmarks

Also move down empty check since otherwise the JIT specializes for empty
strings causing a massive skew in the performance of the other versions.
In real situations it is very unlikely that the JIT heats up for a
String#delete! with empty strings, so this gives a better real world
picture.
Also track call count increases due to looping

This allows for starting with the right number of hits when compiling a
method. Consider the follow sample code:

def foo
  i = 0
  bar(i)
  while i < 1000000
    quz(i)
  end
end

In this case the method foo heats up because of the loop it executes.
But when we JIT foo, we didn't inline the call to bar() since that was
called only once while it throught foo was called 1000000 times.

By tracking this count for loops separate, we can substract it from the
call count to initialize the hits counter for the toplevel method with
the right value. In that case it would be 1 as well as the count for
bar() and it would inline bar() properly.

This was extracted from example from how String#delete! behaves. This
uses a similar mechanism with a loop.
Small optimizations for String#delete! Ruby code

This prevents some array allocations for i, j = 0, 1 initialization
style and uses the bytearray direct access when possible.
Create special version for klass() attribute writer

These are only used for exceptional cases where the klass is different
due to inheritence setup. The common case is that they are the same, so
it helps to check before writing and checking the write barrier.
Mark String::allocate as safe primitive

This is safe since String::allocate can't raise a C++ exception, so we
don't need that for the primitive. Also marks Object#infect as a safe
primitive.
Use direct ByteArray allocator

We use inside other .allocate methods and this also prevents from
triggering the .new compiler transform that would inject serial checks
here that always fail.

Benchmark for duplicating strings with String.new:

Before:
=== bin/rbx ===
  create new strings  6153055.0 (±1.5%) i/s -   30878770 in   5.019694s

After:
=== bin/rbx ===
  create new strings  6902461.7 (±3.0%) i/s -   34552320 in   5.011257s
Remove unneccessary zeroing calls

ByteArray::create already zeroes the entire ByteArray so no need to
additionally set a byte here.
Better version of pushing system objects

We can use the memory address here from the roots to directly load these
objects, since they are also setup as roots. This turns this into a
direct load instead of having to go through a helper method call.
Remove invalid comment in String