fix reserve ocaml block pointer arithmetic
Summary:
hackc crashed for www/flib/autoload/autoload_map.php, which contains a very large string(~400M).
The root cause is Rust treats pointer as usize, but the pointer arithmetic logic in reserve_block assumes pointer as isize.
Detail,
A ocaml mem chunk is represented by three pointers,
- ocamlpool_bound
- ocamlpool_limit
- ocamlpool_cursor
ocamlpool_bound is the base pointer address of a chunk whereas ocamlpool_limit is the top of a chunk, ocamlpool_cursor points to first free address within the chunk. The allocation grows from higher address number to lower address number. For example,
- ocamlpool_bound == 0x10
- ocamlpool_limit == 0x02
- ocamlpool_cursor == 0x08
`reserve_block(size)` requests `size` number of words, it calculates the new block pointer, `ocamlpool_cursor - size`, then checks whether it is greater than `ocamlpool_limit`, if true, then just return the pointer, if false, it needs to reserve another chunk.
In `ocamlpool_cursor - size`, if `size > ocamlpool_curosr` the result is negative value, *however*, pointer comparison in Rust is treated as comparison of two `usize` numbers, a negative value is always greater than `ocamlpool_limit`. A check with `ocamlpool_bound` is added to avoid segmentation fault.
Reviewed By: dabek
Differential Revision:
D18830168
fbshipit-source-id:
e9d466649b2fd2effb7eba0dd0817ced89f724d7