Comments 3
В последнем примере. Не знаю, как в Java, но в C# помогает унести редко используемую часть метода в отдельный метод. Тогда checkexpression устроится, а хелпер, бросающий exception, нет (что нам и нужно). Это более менее стандартный паттерн, хорошо виден по стектрейсам стандартных библиотек.
JIT заменит холодную часть метода на uncommon trap. В случае, если мы таки попали в редкую часть метода — управление свалится в интерпретатор, а в бэкграунде запиститься замещающая компиляция. Для хотспота я бы не стал разбивать код на хелпер методы, чтобы "помочь JITу".
Смотря для чего "помогает". Вынесение редких кусков кода в отдельный метод — это и в джаве стандартный прием. Он помогает и с логической точки зрения — основная задача отделена от вспомогательных, и часто помогает JIT-у, потому что часто выполняющийся метод становится короче, и с большей вероятностью вклеивается. Но не в этом случае
Тогда checkexpression устроится, а хелпер, бросающий exception, нет (что нам и нужно).
Нет, это не то, что нам нужно, ровно наоборот: с точки зрения escape-анализа если ссылка уходит в невклеенный метод — это значит, что она "убегает" за границы анализа, т.е. доступна неопределенному кругу лиц. И значит никакой скаляризации, точка.
… Кроме случая, когда холодная ветка кода прямо совсем уж холодная — вообще ни разу не вызывалась за время сбора профиля. Тогда JIT может спекулятивно предположить, что этот кусок никогда и не будет вызываться, и скомпилировать метод вообще без этого куска, вставив охранную проверку, uncommon trap, со ссылкой на полную версию метода в интерпретируемом режиме, и рекомпиляцию. Именно это здесь и происходит, когда вероятность попадания на исключение пренебрежимо мала.
Если же вероятность попадания в редкую ветку все-таки не нулевая — то выносить ее в отдельный метод с точки зрения скаляризации как раз-таки хуже, потому что редкий метод скорее всего не будет вклеен. Здесь я разбирал такое на примере HashMap
Escape analysis и скаляризация: Пусть GC отдохнет