Ruby 2.6.0 ships with a JIT (just in time compiler) that utilizes GCC (or any other `cc` such as clang) at runtime. This version of Ruby will be released on December 25th, 2018 and Heroku needs to provide support for this feature out of the box.
## Background
The design alternatives can be found in this document
https://docs.google.com/document/d/1q5yEpRddUU2JPynESmffI_BpLDW4XaBgO7iyJE-mwio/edit?usp=sharing
## This PR
This PR adds the `gcc` package to Heroku-16 and Heroku-18 runtime images.
## Size cost
Adding the `gcc` package increases the runtime stack image by about 84mb:
Before adding `gcc`
```
-----> Size breakdown...
# ...
ubuntu:18.04 85.8MB
heroku/heroku:18 428MB
heroku/heroku:18-build 805MB
```
After adding `gcc`
```
-----> Size breakdown...
# ...
ubuntu:18.04 85.8MB
heroku/heroku:18 512MB
heroku/heroku:18-build 805MB
```
It looks like this works with only `gcc`, however if we end up needing `build-essential` then the cost would increase by 64MB to 576MB.
## Testing JIT on the stack images testing
On a currently running Heroku-18 dyno with Ruby 2.6:
```
$ hs run bash -a infinite-everglades-58502
~ $ ruby -v
ruby 2.6.0preview3 (2018-11-06 trunk 65578) [x86_64-linux]
~ $ ruby -e "def a; end; def b; end; a; a; a; a; a; a; a; puts 'done'" --jit --jit-verbose=1
MJIT: Error in execv: /usr/bin/gcc
MJIT warning: Making precompiled header failed on compilation. Stopping MJIT worker...
done
```
> Note: The warnings in the output indicate gcc could not be found
On a local docker image with `gcc` available:
```
$ bin/build.sh heroku-18 heroku/heroku:18 heroku/heroku:18-build
# ...
$ docker run -i -t heroku/heroku:18 /bin/bash
root@4437f834d502:/# mkdir -p vendor/ruby-2.6.0
root@4437f834d502:/# cd vendor/ruby-2.6.0
root@4437f834d502:/vendor/ruby-2.6.0# curl https://heroku-buildpack-ruby.s3.amazonaws.com/heroku-18/ruby-2.6.0.tgz -s -o - | tar zxf -
root@4437f834d502:/vendor/ruby-2.6.0# bin/ruby -e "def a; end; def b; end; a; a; a; a; a; a; a; puts 'done'" --jit --jit-verbose=1
done
Successful MJIT finish
```
> Note: The output indicates that MJIT was successful
For more output you can also apply `--jit-wait` which will force mjit to run synchronously (instead of in a background thread).
cc/ @hone @hunterloftis