Skip to content

Commit 7f80f0e

Browse files
authored
Merge pull request #11682 from alies-dev/disable-jit-by-default
Disable JIT by default, make it opt-in via --force-jit
2 parents 551172c + 82367f5 commit 7f80f0e

3 files changed

Lines changed: 38 additions & 22 deletions

File tree

docs/running_psalm/configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ When `true`, Psalm will attempt to find all unused code (including unused variab
265265
forceJit="[bool]"
266266
>
267267
```
268-
When `true`, Psalm will exit immediately if JIT acceleration (up to +20% performance) cannot be enabled, the equivalent of running with `--force-jit`. Defaults to `false`.
268+
When `true`, Psalm will enable JIT acceleration and exit immediately if it cannot be enabled, the equivalent of running with `--force-jit`. When `false` (default), Psalm runs without JIT.
269269

270270
#### noCache
271271
```xml

src/Psalm/Internal/Cli/Psalm.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,7 @@ private static function restart(
953953
Progress $progress,
954954
): void {
955955
$ini_handler = new PsalmRestarter('PSALM');
956+
$ini_handler->enableJit = $force_jit;
956957

957958
if (isset($options['disable-extension'])) {
958959
if (is_array($options['disable-extension'])) {
@@ -1001,20 +1002,20 @@ private static function restart(
10011002
$progress->write(PHP_EOL
10021003
. 'JIT acceleration: ON'
10031004
. PHP_EOL . PHP_EOL);
1004-
} else {
1005+
} elseif ($force_jit) {
10051006
$progress->write(PHP_EOL
10061007
. 'JIT acceleration: OFF (an error occurred while enabling JIT)' . PHP_EOL
10071008
. 'Please report this to https://github.com/vimeo/psalm with your OS and PHP configuration!'
10081009
. PHP_EOL . PHP_EOL);
10091010
}
1010-
} else {
1011+
} elseif ($force_jit) {
10111012
$progress->write(PHP_EOL
10121013
. 'JIT acceleration: OFF (opcache not installed or not enabled)' . PHP_EOL
1013-
. 'Install and enable the opcache extension to make use of JIT for a 20%+ performance boost!'
1014+
. 'Install and enable the opcache extension to use JIT with --force-jit.'
10141015
. PHP_EOL . PHP_EOL);
10151016
}
10161017
if ($force_jit && !$hasJit) {
1017-
$progress->write('Exiting because JIT was requested but is not available.' . PHP_EOL . PHP_EOL);
1018+
$progress->write('Exiting because --force-jit was set but JIT is not available.' . PHP_EOL . PHP_EOL);
10181019
exit(1);
10191020
}
10201021

@@ -1393,7 +1394,7 @@ private static function getHelpText(): string
13931394
Used to disable certain extensions while Psalm is running.
13941395
13951396
--force-jit
1396-
If set, requires JIT acceleration to be available in order to run Psalm, exiting immediately if it cannot be enabled.
1397+
Enable JIT acceleration. Exits immediately if JIT cannot be enabled.
13971398
13981399
--threads=INT
13991400
If greater than one, Psalm will run the scan and analysis on multiple threads, speeding things up.

src/Psalm/Internal/Fork/PsalmRestarter.php

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,20 @@ final class PsalmRestarter extends XdebugHandler
3030
private const REQUIRED_OPCACHE_SETTINGS = [
3131
'enable' => 1,
3232
'enable_cli' => 1,
33-
'jit' => 1205,
3433
'validate_timestamps' => 0,
3534
'file_update_protection' => 0,
36-
'jit_buffer_size' => 128 * 1024 * 1024,
3735
'max_accelerated_files' => 1_000_000,
3836
'interned_strings_buffer' => 64,
37+
'optimization_level' => '0x7FFEBFFF',
38+
'preload' => '',
39+
'log_verbosity_level' => 0,
40+
'save_comments' => 1,
41+
'restrict_api' => '',
42+
];
43+
44+
private const JIT_OPCACHE_SETTINGS = [
45+
'jit' => 1205,
46+
'jit_buffer_size' => 128 * 1024 * 1024,
3947
'jit_max_root_traces' => 100_000,
4048
'jit_max_side_traces' => 100_000,
4149
'jit_max_exit_counters' => 100_000,
@@ -45,13 +53,10 @@ final class PsalmRestarter extends XdebugHandler
4553
'jit_hot_side_exit' => 1,
4654
'jit_blacklist_root_trace' => 255,
4755
'jit_blacklist_side_trace' => 255,
48-
'optimization_level' => '0x7FFEBFFF',
49-
'preload' => '',
50-
'log_verbosity_level' => 0,
51-
'save_comments' => 1,
52-
'restrict_api' => '',
5356
];
5457

58+
public bool $enableJit = false;
59+
5560
private bool $required = false;
5661

5762
/**
@@ -90,8 +95,7 @@ protected function requiresRestart($default): bool
9095
return true;
9196
}
9297

93-
// restart to enable JIT if it's not configured in the optimal way
94-
foreach (self::REQUIRED_OPCACHE_SETTINGS as $ini_name => $required_value) {
98+
foreach ($this->getEffectiveOpcacheSettings() as $ini_name => $required_value) {
9599
$value = (string) ini_get("opcache.$ini_name");
96100
if ($ini_name === 'jit_buffer_size') {
97101
$value = self::toBytes($value);
@@ -105,7 +109,7 @@ protected function requiresRestart($default): bool
105109
}
106110
}
107111

108-
$requiredMemoryConsumption = self::getRequiredMemoryConsumption();
112+
$requiredMemoryConsumption = $this->getRequiredMemoryConsumption();
109113

110114
if ((int)ini_get('opcache.memory_consumption') < $requiredMemoryConsumption) {
111115
return true;
@@ -169,17 +173,16 @@ protected function restart($command): void
169173
// if it wasn't loaded then we apparently don't have opcache installed and there's no point trying
170174
// to tweak it
171175
$additional_options = $opcache_loaded ? [] : ['-dzend_extension=opcache'];
172-
foreach (self::REQUIRED_OPCACHE_SETTINGS as $key => $value) {
176+
foreach ($this->getEffectiveOpcacheSettings() as $key => $value) {
173177
$additional_options []= "-dopcache.{$key}={$value}";
174178
}
175179

176-
$requiredMemoryConsumption = self::getRequiredMemoryConsumption();
180+
$requiredMemoryConsumption = $this->getRequiredMemoryConsumption();
177181

178182
if ((int)ini_get('opcache.memory_consumption') < $requiredMemoryConsumption) {
179183
$additional_options []= "-dopcache.memory_consumption={$requiredMemoryConsumption}";
180184
}
181185

182-
183186
array_splice(
184187
$command,
185188
1,
@@ -191,16 +194,28 @@ protected function restart($command): void
191194
parent::restart($command);
192195
}
193196

197+
/**
198+
* @return array<string, int|string>
199+
*/
200+
private function getEffectiveOpcacheSettings(): array
201+
{
202+
if ($this->enableJit) {
203+
return self::REQUIRED_OPCACHE_SETTINGS + self::JIT_OPCACHE_SETTINGS;
204+
}
205+
206+
return self::REQUIRED_OPCACHE_SETTINGS;
207+
}
208+
194209
/**
195210
* @return positive-int
196211
*/
197-
private static function getRequiredMemoryConsumption(): int
212+
private function getRequiredMemoryConsumption(): int
198213
{
199214
// Reserve for byte-codes
200215
$result = 256;
201216

202-
if (isset(self::REQUIRED_OPCACHE_SETTINGS['jit_buffer_size'])) {
203-
$result += self::REQUIRED_OPCACHE_SETTINGS['jit_buffer_size'] / 1024 / 1024;
217+
if ($this->enableJit) {
218+
$result += self::JIT_OPCACHE_SETTINGS['jit_buffer_size'] / 1024 / 1024;
204219
}
205220

206221
if (isset(self::REQUIRED_OPCACHE_SETTINGS['interned_strings_buffer'])) {

0 commit comments

Comments
 (0)