Adding JIT information (#75)
* http to https (#73) * Added better jit-flag output in directives * Added additional jit information * Added a highlight/graph of jit buffer usage * Added jit buffer values to the 'memory usage' info panel * Added jit 'highlight' option * Fixed #69 * Updated README
This commit is contained in:
parent
d660fbee43
commit
52d691a82b
8 changed files with 194 additions and 44 deletions
26
README.md
26
README.md
|
@ -13,13 +13,13 @@ There are two ways to getting started using this gui:
|
||||||
|
|
||||||
#### Copy/clone this repo
|
#### Copy/clone this repo
|
||||||
|
|
||||||
The easiest way to start using the opcache-gui is to clone this repo, or simply to copy/paste/download the `index.php` file, to a location which your web server can load. Then point your browser to that location, such as `https://www.example.com/opcache/index.php`.
|
The easiest way to start using the opcache-gui is to clone this repo, or simply copy/paste/download the `index.php` file to a location which your web server can load. Then point your browser to that location, such as `https://www.example.com/opcache/index.php`.
|
||||||
|
|
||||||
#### Install via composer
|
#### Install via composer
|
||||||
|
|
||||||
You can include the files with [Composer](https://getcomposer.org/) by running the command `composer require amnuts/opcache-gui`.
|
You can include the files with [Composer](https://getcomposer.org/) by running the command `composer require amnuts/opcache-gui`.
|
||||||
|
|
||||||
Once in your `vendor` directory, there are numerous ways in which you can use the interface. For example if you're using a framework such as Symfony or Laravel, you could load opcache-gui into a `Controller`. Your requirements of setting it up within your framework of choice will vary, so it's not really possible to detail how to do that within this readme... but I have faith in your ability to figure it out!
|
Once in your `vendor` directory, there are numerous ways in which you can use the interface. For example, if you're using a framework such as Symfony or Laravel, you could load opcache-gui into a `Controller`. Your requirements of setting it up within your framework of choice will vary, so it's not really possible to detail how to do that within this readme... but I have faith in your ability to figure it out!
|
||||||
|
|
||||||
The namespace used for the class is `Amnuts\Opcache`, so once the dependency is in your `autoload.php` you can use the `\Amnuts\Opcache\Service` class. For example, you could do something like:
|
The namespace used for the class is `Amnuts\Opcache`, so once the dependency is in your `autoload.php` you can use the `\Amnuts\Opcache\Service` class. For example, you could do something like:
|
||||||
|
|
||||||
|
@ -79,7 +79,8 @@ $options = [
|
||||||
'highlight' => [
|
'highlight' => [
|
||||||
'memory' => true, // show the memory chart/big number
|
'memory' => true, // show the memory chart/big number
|
||||||
'hits' => true, // show the hit rate chart/big number
|
'hits' => true, // show the hit rate chart/big number
|
||||||
'keys' => true // show the keys used chart/big number
|
'keys' => true, // show the keys used chart/big number
|
||||||
|
'jit' => true // show the jit buffer chart/big number
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
```
|
```
|
||||||
|
@ -116,9 +117,9 @@ The core PHP template used in the build process, and that acts to pass various b
|
||||||
|
|
||||||
### Overview
|
### Overview
|
||||||
|
|
||||||
The overview will show you all the core information. From here you'll be able to see what host and platform you're running on, what version of OPcache you're using, when it was last reset, the functions that are available, all the directives and all the statistics associated with the OPcache (number of hits, memory used, free and wasted memory, etc.)
|
The overview will show you all the core information. From here you'll be able to see what host and platform you're running on, what version of OPcache you're using, when it was last reset, the functions and directives available (with links to the php.net manual), and all the statistics associated with the OPcache (number of hits, memory used, free and wasted memory, and more).
|
||||||
|
|
||||||
![Screenshot of the Overview tab](http://amnuts.com/images/opcache/screenshot/overview-v3.0.0.png)
|
![Screenshot of the Overview tab](http://amnuts.com/images/opcache/screenshot/overview-v3.3.0.png)
|
||||||
|
|
||||||
### Cached files
|
### Cached files
|
||||||
|
|
||||||
|
@ -154,10 +155,23 @@ Resetting can be disabled with the use of the configuration options `allow_reset
|
||||||
|
|
||||||
The interface can poll every so often to get a fresh look at the opcache. You can change how often this happens with the configuration option `refresh_time`, which is in seconds.
|
The interface can poll every so often to get a fresh look at the opcache. You can change how often this happens with the configuration option `refresh_time`, which is in seconds.
|
||||||
|
|
||||||
When the real-time updates are active the interface will automatically update all the values as needed. Also, if you choose to invalidate any files or reset the cache it will do this without reloading the page, so the search term you've entered, or the page you've navigated to do not get reset. If the real-time update is not on then the page will reload on any invalidation usage.
|
When the real-time updates are active, the interface will automatically update all the values as needed.
|
||||||
|
|
||||||
|
Also, if you choose to invalidate any files or reset the cache it will do this without reloading the page, so the search term you've entered, or the page to which you've navigated do not get reset. If the real-time update is not on then the page will reload on any invalidation usage.
|
||||||
|
|
||||||
## Releases
|
## Releases
|
||||||
|
|
||||||
|
**Version 3.3.0**\
|
||||||
|
Mostly added JIT information for PHP 8:
|
||||||
|
* Added JIT buffer graph (optionally able to turn it off)
|
||||||
|
* Added JIT information to the memory usage panel
|
||||||
|
* Improved the JIT information shown in the directives
|
||||||
|
* Fixed a long outstanding interface bug that allowed you to see the 'invalidate all' link even if invalidation option was `false`
|
||||||
|
|
||||||
|
If you want to enable JIT you have to put in a value for the [opcache.jit_buffer_size](https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit-buffer-size) ini setting, else it's disabled by default.
|
||||||
|
|
||||||
|
If you're not using PHP 8, the interface will compensate and not show the additional JIT information.
|
||||||
|
|
||||||
**Version 3.2.1**\
|
**Version 3.2.1**\
|
||||||
Minor maintenance release to:
|
Minor maintenance release to:
|
||||||
* Put back "spaceship operator" so PHP8 doesn't give deprecation warnings (must have been accidentally removed in a previous commit)
|
* Put back "spaceship operator" so PHP8 doesn't give deprecation warnings (must have been accidentally removed in a previous commit)
|
||||||
|
|
|
@ -264,7 +264,8 @@ function OverviewCounts(props) {
|
||||||
const graphList = [
|
const graphList = [
|
||||||
{id: 'memoryUsageCanvas', title: 'memory', show: props.highlight.memory, value: props.overview.used_memory_percentage},
|
{id: 'memoryUsageCanvas', title: 'memory', show: props.highlight.memory, value: props.overview.used_memory_percentage},
|
||||||
{id: 'hitRateCanvas', title: 'hit rate', show: props.highlight.hits, value: props.overview.hit_rate_percentage},
|
{id: 'hitRateCanvas', title: 'hit rate', show: props.highlight.hits, value: props.overview.hit_rate_percentage},
|
||||||
{id: 'keyUsageCanvas', title: 'keys', show: props.highlight.keys, value: props.overview.used_key_percentage}
|
{id: 'keyUsageCanvas', title: 'keys', show: props.highlight.keys, value: props.overview.used_key_percentage},
|
||||||
|
{id: 'jitUsageCanvas', title: 'jit buffer', show: props.highlight.jit, value: props.overview.jit_buffer_used_percentage}
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -287,6 +288,9 @@ function OverviewCounts(props) {
|
||||||
wasted={props.overview.readable.wasted_memory}
|
wasted={props.overview.readable.wasted_memory}
|
||||||
preload={props.overview.readable.preload_memory || null}
|
preload={props.overview.readable.preload_memory || null}
|
||||||
wastedPercent={props.overview.wasted_percentage}
|
wastedPercent={props.overview.wasted_percentage}
|
||||||
|
jitBuffer={props.overview.readable.jit_buffer_size || null}
|
||||||
|
jitBufferFree={props.overview.readable.jit_buffer_free || null}
|
||||||
|
jitBufferFreePercentage={props.overview.jit_buffer_used_percentage || null}
|
||||||
/>
|
/>
|
||||||
<StatisticsPanel
|
<StatisticsPanel
|
||||||
num_cached_scripts={props.overview.readable.num_cached_scripts}
|
num_cached_scripts={props.overview.readable.num_cached_scripts}
|
||||||
|
@ -358,7 +362,7 @@ function Directives(props) {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<tr key={directive.k}>
|
<tr key={directive.k}>
|
||||||
<td title={'View ' + directive.k + ' manual entry'}><a href={'http://php.net/manual/en/opcache.configuration.php#ini.'
|
<td title={'View ' + directive.k + ' manual entry'}><a href={'https://php.net/manual/en/opcache.configuration.php#ini.'
|
||||||
+ (directive.k).replace(/_/g,'-')} target="_blank">{dShow}</a></td>
|
+ (directive.k).replace(/_/g,'-')} target="_blank">{dShow}</a></td>
|
||||||
<td>{vShow}</td>
|
<td>{vShow}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -380,7 +384,7 @@ function Functions(props) {
|
||||||
<thead><tr><th>Available functions</th></tr></thead>
|
<thead><tr><th>Available functions</th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{props.functions.map(f =>
|
{props.functions.map(f =>
|
||||||
<tr key={f}><td><a href={"http://php.net/"+f} title="View manual page" target="_blank">{f}</a></td></tr>
|
<tr key={f}><td><a href={"https://php.net/"+f} title="View manual page" target="_blank">{f}</a></td></tr>
|
||||||
)}
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -618,6 +622,8 @@ function MemoryUsagePanel(props) {
|
||||||
<p><b>free memory:</b> {props.free}</p>
|
<p><b>free memory:</b> {props.free}</p>
|
||||||
{ props.preload && <p><b>preload memory:</b> {props.preload}</p> }
|
{ props.preload && <p><b>preload memory:</b> {props.preload}</p> }
|
||||||
<p><b>wasted memory:</b> {props.wasted} ({props.wastedPercent}%)</p>
|
<p><b>wasted memory:</b> {props.wasted} ({props.wastedPercent}%)</p>
|
||||||
|
{ props.jitBuffer && <p><b>jit buffer:</b> {props.jitBuffer}</p> }
|
||||||
|
{ props.jitBufferFree && <p><b>jit buffer free:</b> {props.jitBufferFree} ({100 - props.jitBufferFreePercentage}%)</p> }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -754,7 +760,7 @@ class CachedFiles extends React.Component {
|
||||||
|
|
||||||
<h3>{allFilesTotal} files cached{showingTotal !== allFilesTotal && `, ${showingTotal} showing due to filter '${this.state.searchTerm}'`}</h3>
|
<h3>{allFilesTotal} files cached{showingTotal !== allFilesTotal && `, ${showingTotal} showing due to filter '${this.state.searchTerm}'`}</h3>
|
||||||
|
|
||||||
{ this.state.searchTerm && showingTotal !== allFilesTotal &&
|
{ this.props.allow.invalidate && this.state.searchTerm && showingTotal !== allFilesTotal &&
|
||||||
<p><a href={`?invalidate_searched=${encodeURIComponent(this.state.searchTerm)}`} onClick={this.handleInvalidate}>Invalidate all matching files</a></p>
|
<p><a href={`?invalidate_searched=${encodeURIComponent(this.state.searchTerm)}`} onClick={this.handleInvalidate}>Invalidate all matching files</a></p>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* OPcache GUI - build script
|
* OPcache GUI - build script
|
||||||
*
|
*
|
||||||
* @author Andrew Collington, andy@amnuts.com
|
* @author Andrew Collington, andy@amnuts.com
|
||||||
* @version 3.2.1
|
* @version 3.3.0
|
||||||
* @link https://github.com/amnuts/opcache-gui
|
* @link https://github.com/amnuts/opcache-gui
|
||||||
* @license MIT, http://acollington.mit-license.org/
|
* @license MIT, https://acollington.mit-license.org/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$parentPath = dirname(__DIR__);
|
$parentPath = dirname(__DIR__);
|
||||||
|
|
|
@ -8,9 +8,9 @@ namespace Amnuts\Opcache;
|
||||||
* A simple but effective single-file GUI for the OPcache PHP extension.
|
* A simple but effective single-file GUI for the OPcache PHP extension.
|
||||||
*
|
*
|
||||||
* @author Andrew Collington, andy@amnuts.com
|
* @author Andrew Collington, andy@amnuts.com
|
||||||
* @version 3.2.1
|
* @version 3.3.0
|
||||||
* @link https://github.com/amnuts/opcache-gui
|
* @link https://github.com/amnuts/opcache-gui
|
||||||
* @license MIT, http://acollington.mit-license.org/
|
* @license MIT, https://acollington.mit-license.org/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -35,7 +35,8 @@ $options = [
|
||||||
'highlight' => [
|
'highlight' => [
|
||||||
'memory' => true, // show the memory chart/big number
|
'memory' => true, // show the memory chart/big number
|
||||||
'hits' => true, // show the hit rate chart/big number
|
'hits' => true, // show the hit rate chart/big number
|
||||||
'keys' => true // show the keys used chart/big number
|
'keys' => true, // show the keys used chart/big number
|
||||||
|
'jit' => true // show the jit buffer chart/big number
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
{
|
{
|
||||||
"name": "Andrew Collington",
|
"name": "Andrew Collington",
|
||||||
"email": "andy@amnuts.com",
|
"email": "andy@amnuts.com",
|
||||||
"homepage": "http://www.amnuts.com/",
|
"homepage": "https://blog.amnuts.com/",
|
||||||
"role": "Developer"
|
"role": "Developer"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
"require": {
|
"require": {
|
||||||
"ext-Zend-OPcache": "*",
|
"ext-Zend-OPcache": "*",
|
||||||
"php": ">=7.1.0",
|
"php": ">=7.1.0",
|
||||||
"ext-json": "*"
|
"ext-json": "*"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4" : {
|
"psr-4" : {
|
||||||
|
|
103
index.php
103
index.php
|
@ -8,9 +8,9 @@ namespace Amnuts\Opcache;
|
||||||
* A simple but effective single-file GUI for the OPcache PHP extension.
|
* A simple but effective single-file GUI for the OPcache PHP extension.
|
||||||
*
|
*
|
||||||
* @author Andrew Collington, andy@amnuts.com
|
* @author Andrew Collington, andy@amnuts.com
|
||||||
* @version 3.2.1
|
* @version 3.3.0
|
||||||
* @link https://github.com/amnuts/opcache-gui
|
* @link https://github.com/amnuts/opcache-gui
|
||||||
* @license MIT, http://acollington.mit-license.org/
|
* @license MIT, https://acollington.mit-license.org/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -35,7 +35,8 @@ $options = [
|
||||||
'highlight' => [
|
'highlight' => [
|
||||||
'memory' => true, // show the memory chart/big number
|
'memory' => true, // show the memory chart/big number
|
||||||
'hits' => true, // show the hit rate chart/big number
|
'hits' => true, // show the hit rate chart/big number
|
||||||
'keys' => true // show the keys used chart/big number
|
'keys' => true, // show the keys used chart/big number
|
||||||
|
'jit' => true // show the jit buffer chart/big number
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ header('Pragma: no-cache');
|
||||||
|
|
||||||
class Service
|
class Service
|
||||||
{
|
{
|
||||||
const VERSION = '3.2.1';
|
const VERSION = '3.3.0';
|
||||||
|
|
||||||
protected $data;
|
protected $data;
|
||||||
protected $options;
|
protected $options;
|
||||||
|
@ -78,7 +79,47 @@ class Service
|
||||||
'highlight' => [
|
'highlight' => [
|
||||||
'memory' => true, // show the memory chart/big number
|
'memory' => true, // show the memory chart/big number
|
||||||
'hits' => true, // show the hit rate chart/big number
|
'hits' => true, // show the hit rate chart/big number
|
||||||
'keys' => true // show the keys used chart/big number
|
'keys' => true, // show the keys used chart/big number
|
||||||
|
'jit' => true // show the jit buffer chart/big number
|
||||||
|
]
|
||||||
|
];
|
||||||
|
protected $jitModes = [
|
||||||
|
[
|
||||||
|
'flag' => 'CPU-specific optimization',
|
||||||
|
'value' => [
|
||||||
|
'Disable CPU-specific optimization',
|
||||||
|
'Enable use of AVX, if the CPU supports it'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'flag' => 'Register allocation',
|
||||||
|
'value' => [
|
||||||
|
'Do not perform register allocation',
|
||||||
|
'Perform block-local register allocation',
|
||||||
|
'Perform global register allocation'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'flag' => 'Trigger',
|
||||||
|
'value' => [
|
||||||
|
'Compile all functions on script load',
|
||||||
|
'Compile functions on first execution',
|
||||||
|
'Profile functions on first request and compile the hottest functions afterwards',
|
||||||
|
'Profile on the fly and compile hot functions',
|
||||||
|
'Currently unused',
|
||||||
|
'Use tracing JIT. Profile on the fly and compile traces for hot code segments'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'flag' => 'Optimization level',
|
||||||
|
'value' => [
|
||||||
|
'No JIT',
|
||||||
|
'Minimal JIT (call standard VM handlers)',
|
||||||
|
'Inline VM handlers',
|
||||||
|
'Use type inference',
|
||||||
|
'Use call graph',
|
||||||
|
'Optimize whole script'
|
||||||
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -106,7 +147,6 @@ class Service
|
||||||
1 << 14 => '(unsafe) Collect constants',
|
1 << 14 => '(unsafe) Collect constants',
|
||||||
1 << 15 => 'Inline functions'
|
1 << 15 => 'Inline functions'
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->options = array_merge($this->defaults, $options);
|
$this->options = array_merge($this->defaults, $options);
|
||||||
$this->data = $this->compileState();
|
$this->data = $this->compileState();
|
||||||
}
|
}
|
||||||
|
@ -150,10 +190,8 @@ class Service
|
||||||
if ($name === null) {
|
if ($name === null) {
|
||||||
return $this->options;
|
return $this->options;
|
||||||
}
|
}
|
||||||
return (isset($this->options[$name])
|
|
||||||
? $this->options[$name]
|
return $this->options[$name] ?? null;
|
||||||
: null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -331,12 +369,25 @@ class Service
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($overview && !empty($status['jit'])) {
|
||||||
|
$overview['jit_buffer_used_percentage'] = ($status['jit']['buffer_size']
|
||||||
|
? round(100 * (($status['jit']['buffer_size'] - $status['jit']['buffer_free']) / $status['jit']['buffer_size']))
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
$overview['readable'] = array_merge($overview['readable'], [
|
||||||
|
'jit_buffer_size' => $this->size($status['jit']['buffer_size']),
|
||||||
|
'jit_buffer_free' => $this->size($status['jit']['buffer_free'])
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$this->options['highlight']['jit'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
$directives = [];
|
$directives = [];
|
||||||
ksort($config['directives']);
|
ksort($config['directives']);
|
||||||
foreach ($config['directives'] as $k => $v) {
|
foreach ($config['directives'] as $k => $v) {
|
||||||
if (in_array($k, ['opcache.max_file_size', 'opcache.memory_consumption']) && $v) {
|
if (in_array($k, ['opcache.max_file_size', 'opcache.memory_consumption', 'opcache.jit_buffer_size']) && $v) {
|
||||||
$v = $this->size($v) . " ({$v})";
|
$v = $this->size($v) . " ({$v})";
|
||||||
} elseif ($k == 'opcache.optimization_level') {
|
} elseif ($k === 'opcache.optimization_level') {
|
||||||
$levels = [];
|
$levels = [];
|
||||||
foreach ($this->optimizationLevels as $level => $info) {
|
foreach ($this->optimizationLevels as $level => $info) {
|
||||||
if ($level & $v) {
|
if ($level & $v) {
|
||||||
|
@ -344,6 +395,16 @@ class Service
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$v = $levels ?: 'none';
|
$v = $levels ?: 'none';
|
||||||
|
} elseif ($k === 'opcache.jit') {
|
||||||
|
if (is_numeric($v)) {
|
||||||
|
$levels = [];
|
||||||
|
foreach (str_split((string)$v) as $type => $level) {
|
||||||
|
$levels[] = "{$level}: {$this->jitModes[$type]['value'][$level]} ({$this->jitModes[$type]['flag']})";
|
||||||
|
}
|
||||||
|
$v = $levels;
|
||||||
|
} elseif (strtolower($v) === 'off' || $v === '') {
|
||||||
|
$v = 'Off';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$directives[] = [
|
$directives[] = [
|
||||||
'k' => $k,
|
'k' => $k,
|
||||||
|
@ -707,6 +768,11 @@ function OverviewCounts(props) {
|
||||||
title: 'keys',
|
title: 'keys',
|
||||||
show: props.highlight.keys,
|
show: props.highlight.keys,
|
||||||
value: props.overview.used_key_percentage
|
value: props.overview.used_key_percentage
|
||||||
|
}, {
|
||||||
|
id: 'jitUsageCanvas',
|
||||||
|
title: 'jit buffer',
|
||||||
|
show: props.highlight.jit,
|
||||||
|
value: props.overview.jit_buffer_used_percentage
|
||||||
}];
|
}];
|
||||||
return /*#__PURE__*/React.createElement("div", {
|
return /*#__PURE__*/React.createElement("div", {
|
||||||
id: "counts",
|
id: "counts",
|
||||||
|
@ -732,7 +798,10 @@ function OverviewCounts(props) {
|
||||||
free: props.overview.readable.free_memory,
|
free: props.overview.readable.free_memory,
|
||||||
wasted: props.overview.readable.wasted_memory,
|
wasted: props.overview.readable.wasted_memory,
|
||||||
preload: props.overview.readable.preload_memory || null,
|
preload: props.overview.readable.preload_memory || null,
|
||||||
wastedPercent: props.overview.wasted_percentage
|
wastedPercent: props.overview.wasted_percentage,
|
||||||
|
jitBuffer: props.overview.readable.jit_buffer_size || null,
|
||||||
|
jitBufferFree: props.overview.readable.jit_buffer_free || null,
|
||||||
|
jitBufferFreePercentage: props.overview.jit_buffer_used_percentage || null
|
||||||
}), /*#__PURE__*/React.createElement(StatisticsPanel, {
|
}), /*#__PURE__*/React.createElement(StatisticsPanel, {
|
||||||
num_cached_scripts: props.overview.readable.num_cached_scripts,
|
num_cached_scripts: props.overview.readable.num_cached_scripts,
|
||||||
hits: props.overview.readable.hits,
|
hits: props.overview.readable.hits,
|
||||||
|
@ -794,7 +863,7 @@ function Directives(props) {
|
||||||
}, /*#__PURE__*/React.createElement("td", {
|
}, /*#__PURE__*/React.createElement("td", {
|
||||||
title: 'View ' + directive.k + ' manual entry'
|
title: 'View ' + directive.k + ' manual entry'
|
||||||
}, /*#__PURE__*/React.createElement("a", {
|
}, /*#__PURE__*/React.createElement("a", {
|
||||||
href: 'http://php.net/manual/en/opcache.configuration.php#ini.' + directive.k.replace(/_/g, '-'),
|
href: 'https://php.net/manual/en/opcache.configuration.php#ini.' + directive.k.replace(/_/g, '-'),
|
||||||
target: "_blank"
|
target: "_blank"
|
||||||
}, dShow)), /*#__PURE__*/React.createElement("td", null, vShow));
|
}, dShow)), /*#__PURE__*/React.createElement("td", null, vShow));
|
||||||
});
|
});
|
||||||
|
@ -813,7 +882,7 @@ function Functions(props) {
|
||||||
}, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "Available functions"))), /*#__PURE__*/React.createElement("tbody", null, props.functions.map(f => /*#__PURE__*/React.createElement("tr", {
|
}, /*#__PURE__*/React.createElement("thead", null, /*#__PURE__*/React.createElement("tr", null, /*#__PURE__*/React.createElement("th", null, "Available functions"))), /*#__PURE__*/React.createElement("tbody", null, props.functions.map(f => /*#__PURE__*/React.createElement("tr", {
|
||||||
key: f
|
key: f
|
||||||
}, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("a", {
|
}, /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement("a", {
|
||||||
href: "http://php.net/" + f,
|
href: "https://php.net/" + f,
|
||||||
title: "View manual page",
|
title: "View manual page",
|
||||||
target: "_blank"
|
target: "_blank"
|
||||||
}, f)))))));
|
}, f)))))));
|
||||||
|
@ -1045,7 +1114,7 @@ function MemoryUsagePanel(props) {
|
||||||
className: "widget-header"
|
className: "widget-header"
|
||||||
}, "memory usage"), /*#__PURE__*/React.createElement("div", {
|
}, "memory usage"), /*#__PURE__*/React.createElement("div", {
|
||||||
className: "widget-value widget-info"
|
className: "widget-value widget-info"
|
||||||
}, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "total memory:"), " ", props.total), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "used memory:"), " ", props.used), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "free memory:"), " ", props.free), props.preload && /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "preload memory:"), " ", props.preload), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "wasted memory:"), " ", props.wasted, " (", props.wastedPercent, "%)")));
|
}, /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "total memory:"), " ", props.total), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "used memory:"), " ", props.used), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "free memory:"), " ", props.free), props.preload && /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "preload memory:"), " ", props.preload), /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "wasted memory:"), " ", props.wasted, " (", props.wastedPercent, "%)"), props.jitBuffer && /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "jit buffer:"), " ", props.jitBuffer), props.jitBufferFree && /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("b", null, "jit buffer free:"), " ", props.jitBufferFree, " (", 100 - props.jitBufferFreePercentage, "%)")));
|
||||||
}
|
}
|
||||||
|
|
||||||
function StatisticsPanel(props) {
|
function StatisticsPanel(props) {
|
||||||
|
@ -1170,7 +1239,7 @@ class CachedFiles extends React.Component {
|
||||||
onChange: e => {
|
onChange: e => {
|
||||||
this.setSearchTerm(e.target.value);
|
this.setSearchTerm(e.target.value);
|
||||||
}
|
}
|
||||||
})), /*#__PURE__*/React.createElement("h3", null, allFilesTotal, " files cached", showingTotal !== allFilesTotal && `, ${showingTotal} showing due to filter '${this.state.searchTerm}'`), this.state.searchTerm && showingTotal !== allFilesTotal && /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("a", {
|
})), /*#__PURE__*/React.createElement("h3", null, allFilesTotal, " files cached", showingTotal !== allFilesTotal && `, ${showingTotal} showing due to filter '${this.state.searchTerm}'`), this.props.allow.invalidate && this.state.searchTerm && showingTotal !== allFilesTotal && /*#__PURE__*/React.createElement("p", null, /*#__PURE__*/React.createElement("a", {
|
||||||
href: `?invalidate_searched=${encodeURIComponent(this.state.searchTerm)}`,
|
href: `?invalidate_searched=${encodeURIComponent(this.state.searchTerm)}`,
|
||||||
onClick: this.handleInvalidate
|
onClick: this.handleInvalidate
|
||||||
}, "Invalidate all matching files")), /*#__PURE__*/React.createElement("div", {
|
}, "Invalidate all matching files")), /*#__PURE__*/React.createElement("div", {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "opcache-gui",
|
"name": "opcache-gui",
|
||||||
"description": "A clean and responsive interface for Zend OPcache information, showing statistics, settings and cached files, and providing a real-time update for the information (using jQuery and React).",
|
"description": "A clean and responsive interface for Zend OPcache information, showing statistics, settings and cached files, and providing a real-time update for the information (using jQuery and React).",
|
||||||
"version": "3.2.1",
|
"version": "3.3.0",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.12.8",
|
"@babel/cli": "^7.12.8",
|
||||||
|
|
|
@ -4,7 +4,7 @@ namespace Amnuts\Opcache;
|
||||||
|
|
||||||
class Service
|
class Service
|
||||||
{
|
{
|
||||||
const VERSION = '3.2.1';
|
const VERSION = '3.3.0';
|
||||||
|
|
||||||
protected $data;
|
protected $data;
|
||||||
protected $options;
|
protected $options;
|
||||||
|
@ -25,7 +25,47 @@ class Service
|
||||||
'highlight' => [
|
'highlight' => [
|
||||||
'memory' => true, // show the memory chart/big number
|
'memory' => true, // show the memory chart/big number
|
||||||
'hits' => true, // show the hit rate chart/big number
|
'hits' => true, // show the hit rate chart/big number
|
||||||
'keys' => true // show the keys used chart/big number
|
'keys' => true, // show the keys used chart/big number
|
||||||
|
'jit' => true // show the jit buffer chart/big number
|
||||||
|
]
|
||||||
|
];
|
||||||
|
protected $jitModes = [
|
||||||
|
[
|
||||||
|
'flag' => 'CPU-specific optimization',
|
||||||
|
'value' => [
|
||||||
|
'Disable CPU-specific optimization',
|
||||||
|
'Enable use of AVX, if the CPU supports it'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'flag' => 'Register allocation',
|
||||||
|
'value' => [
|
||||||
|
'Do not perform register allocation',
|
||||||
|
'Perform block-local register allocation',
|
||||||
|
'Perform global register allocation'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'flag' => 'Trigger',
|
||||||
|
'value' => [
|
||||||
|
'Compile all functions on script load',
|
||||||
|
'Compile functions on first execution',
|
||||||
|
'Profile functions on first request and compile the hottest functions afterwards',
|
||||||
|
'Profile on the fly and compile hot functions',
|
||||||
|
'Currently unused',
|
||||||
|
'Use tracing JIT. Profile on the fly and compile traces for hot code segments'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'flag' => 'Optimization level',
|
||||||
|
'value' => [
|
||||||
|
'No JIT',
|
||||||
|
'Minimal JIT (call standard VM handlers)',
|
||||||
|
'Inline VM handlers',
|
||||||
|
'Use type inference',
|
||||||
|
'Use call graph',
|
||||||
|
'Optimize whole script'
|
||||||
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -53,7 +93,6 @@ class Service
|
||||||
1 << 14 => '(unsafe) Collect constants',
|
1 << 14 => '(unsafe) Collect constants',
|
||||||
1 << 15 => 'Inline functions'
|
1 << 15 => 'Inline functions'
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->options = array_merge($this->defaults, $options);
|
$this->options = array_merge($this->defaults, $options);
|
||||||
$this->data = $this->compileState();
|
$this->data = $this->compileState();
|
||||||
}
|
}
|
||||||
|
@ -97,10 +136,8 @@ class Service
|
||||||
if ($name === null) {
|
if ($name === null) {
|
||||||
return $this->options;
|
return $this->options;
|
||||||
}
|
}
|
||||||
return (isset($this->options[$name])
|
|
||||||
? $this->options[$name]
|
return $this->options[$name] ?? null;
|
||||||
: null
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -278,12 +315,25 @@ class Service
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($overview && !empty($status['jit'])) {
|
||||||
|
$overview['jit_buffer_used_percentage'] = ($status['jit']['buffer_size']
|
||||||
|
? round(100 * (($status['jit']['buffer_size'] - $status['jit']['buffer_free']) / $status['jit']['buffer_size']))
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
$overview['readable'] = array_merge($overview['readable'], [
|
||||||
|
'jit_buffer_size' => $this->size($status['jit']['buffer_size']),
|
||||||
|
'jit_buffer_free' => $this->size($status['jit']['buffer_free'])
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$this->options['highlight']['jit'] = false;
|
||||||
|
}
|
||||||
|
|
||||||
$directives = [];
|
$directives = [];
|
||||||
ksort($config['directives']);
|
ksort($config['directives']);
|
||||||
foreach ($config['directives'] as $k => $v) {
|
foreach ($config['directives'] as $k => $v) {
|
||||||
if (in_array($k, ['opcache.max_file_size', 'opcache.memory_consumption']) && $v) {
|
if (in_array($k, ['opcache.max_file_size', 'opcache.memory_consumption', 'opcache.jit_buffer_size']) && $v) {
|
||||||
$v = $this->size($v) . " ({$v})";
|
$v = $this->size($v) . " ({$v})";
|
||||||
} elseif ($k == 'opcache.optimization_level') {
|
} elseif ($k === 'opcache.optimization_level') {
|
||||||
$levels = [];
|
$levels = [];
|
||||||
foreach ($this->optimizationLevels as $level => $info) {
|
foreach ($this->optimizationLevels as $level => $info) {
|
||||||
if ($level & $v) {
|
if ($level & $v) {
|
||||||
|
@ -291,6 +341,16 @@ class Service
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$v = $levels ?: 'none';
|
$v = $levels ?: 'none';
|
||||||
|
} elseif ($k === 'opcache.jit') {
|
||||||
|
if (is_numeric($v)) {
|
||||||
|
$levels = [];
|
||||||
|
foreach (str_split((string)$v) as $type => $level) {
|
||||||
|
$levels[] = "{$level}: {$this->jitModes[$type]['value'][$level]} ({$this->jitModes[$type]['flag']})";
|
||||||
|
}
|
||||||
|
$v = $levels;
|
||||||
|
} elseif (strtolower($v) === 'off' || $v === '') {
|
||||||
|
$v = 'Off';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$directives[] = [
|
$directives[] = [
|
||||||
'k' => $k,
|
'k' => $k,
|
||||||
|
|
Loading…
Reference in a new issue