diff --git a/composer.json b/composer.json index ee23d02d..48248e36 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "JVM emulator by PHP", "type": "library", "license": "MIT", - "version": "0.0.6.4-dev", + "version": "0.0.6.5-dev", "authors": [ { "name": "memory" @@ -17,7 +17,8 @@ "php-java/java-util-package": "*", "php-java/java-io-package": "*", "php-java/java-net-package": "*", - "php-java/java-nio-package": "*" + "php-java/java-nio-package": "*", + "gabrielelana/byte-units": "dev-master" }, "autoload": { "psr-4": { diff --git a/src/Core/JVM/Cache/Cache.php b/src/Core/JVM/Cache/Cache.php new file mode 100644 index 00000000..73cbbea0 --- /dev/null +++ b/src/Core/JVM/Cache/Cache.php @@ -0,0 +1,15 @@ +items[$key])) { + return $this->items[$key]; + } + return $this->items[$key] = $pushFunction(...$parameters); + } +} diff --git a/src/Core/JVM/Cache/HeapCache.php b/src/Core/JVM/Cache/HeapCache.php new file mode 100644 index 00000000..626eaf8d --- /dev/null +++ b/src/Core/JVM/Cache/HeapCache.php @@ -0,0 +1,6 @@ +debugTool->getLogger()->debug( + vsprintf( + 'Used Memory: %s, Used Memory Peak: %s', + [ + Metric::bytes(memory_get_usage())->format(), + Metric::bytes(memory_get_peak_usage())->format(), + ] + ) + ); + + $operationCache = new OperationCache(); while ($reader->getOffset() < $codeAttribute->getOpCodeLength()) { if (++$executedCounter > ($this->options['max_stack_exceeded'] ?? GlobalOptions::get('max_stack_exceeded') ?? Runtime::MAX_STACK_EXCEEDED)) { throw new RuntimeException( @@ -248,6 +261,16 @@ function ($item) { $debugTraces['mnemonic_indexes'][] = $pointer; } + $this->debugTool->getLogger()->debug( + vsprintf( + 'Used Memory: %s, Used Memory Peak: %s', + [ + Metric::bytes(memory_get_usage())->format(), + Metric::bytes(memory_get_peak_usage())->format(), + ] + ) + ); + $this->debugTool->getLogger()->debug( vsprintf( 'OpCode: 0x%02X, Mnemonic: %s, Stacks: %d, PC: %d', @@ -274,17 +297,23 @@ function ($item) { /** * @var OperationInterface|Accumulator|ConstantPool $executor */ - $executor = new $fullName(); - $executor->setConstantPool($currentConstantPool); - $executor->setParameters( - $method->getAttributes(), - $this->javaClassInvoker, - $reader, - $localStorage, - $stacks, - $pointer + $executor = $operationCache->fetchOrPush( + $fullName, + function () use ($fullName) { + return new $fullName(); + } ); - $returnValue = $executor->execute(); + $returnValue = $executor + ->setConstantPool($currentConstantPool) + ->setParameters( + $method->getAttributes(), + $this->javaClassInvoker, + $reader, + $localStorage, + $stacks, + $pointer + ) + ->execute(); $afterTrigger = $this->options['operations']['injections']['after'] ?? GlobalOptions::get('operations.injections.after'); if (is_callable($afterTrigger)) { @@ -298,13 +327,17 @@ function ($item) { } if ($returnValue !== null) { - $this->javaClassInvoker->getJavaClass()->appendDebug($debugTraces); + if ($isEnabledTrace) { + $this->javaClassInvoker->getJavaClass()->appendDebug($debugTraces); + } $this->debugTool->getLogger()->info('Finish operations: ' . $methodBeautified); return $returnValue; } } - $this->javaClassInvoker->getJavaClass()->appendDebug($debugTraces); + if ($isEnabledTrace) { + $this->javaClassInvoker->getJavaClass()->appendDebug($debugTraces); + } $this->debugTool->getLogger()->info('Finish operations: ' . $methodBeautified); return null; } diff --git a/src/Core/JVM/Parameters/GlobalOptions.php b/src/Core/JVM/Parameters/GlobalOptions.php index bcd7cc2a..92860f3d 100644 --- a/src/Core/JVM/Parameters/GlobalOptions.php +++ b/src/Core/JVM/Parameters/GlobalOptions.php @@ -25,7 +25,7 @@ public static function get($name) return $ref; } - public function reset() + public static function reset() { static::$settings = []; } diff --git a/src/Core/JVM/Parameters/Runtime.php b/src/Core/JVM/Parameters/Runtime.php index 9d1fa198..98b45679 100644 --- a/src/Core/JVM/Parameters/Runtime.php +++ b/src/Core/JVM/Parameters/Runtime.php @@ -13,7 +13,7 @@ final class Runtime const PRELOAD = false; const DRY_RUN_ATTRIBUTE = false; - const OPERATIONS_ENABLE_TRACE = true; + const OPERATIONS_ENABLE_TRACE = false; const OPERATIONS_TEMPORARY_CODE_STREAM = 'php://memory'; const VALIDATION_METHOD_ARGUMENTS_COUNT_ONLY = false; diff --git a/src/Core/JavaClass.php b/src/Core/JavaClass.php index 66331157..93d46272 100644 --- a/src/Core/JavaClass.php +++ b/src/Core/JavaClass.php @@ -6,8 +6,11 @@ use PHPJava\Core\JVM\ActiveInterface; use PHPJava\Core\JVM\ActiveMethods; use PHPJava\Core\JVM\ConstantPool; +use PHPJava\Core\JVM\Parameters\GlobalOptions; +use PHPJava\Core\JVM\Parameters\Runtime; use PHPJava\Core\JVM\Validations\MagicByte; use PHPJava\Core\Stream\Reader\ReaderInterface; +use PHPJava\Exceptions\DebugTraceIsDisabledException; use PHPJava\Exceptions\ValidatorException; use PHPJava\Kernel\Attributes\AttributeInterface; use PHPJava\Kernel\Attributes\InnerClassesAttribute; @@ -302,6 +305,12 @@ public function getSuperClass() public function debug(): void { + $isEnabledTrace = $this->options['operations']['enable_trace'] ?? GlobalOptions::get('operations.enable_trace') ?? Runtime::OPERATIONS_ENABLE_TRACE; + if (!$isEnabledTrace) { + throw new DebugTraceIsDisabledException( + "Debug trace is disabled. If you want to show debug trace then enable to `enable_trace` option." + ); + } $cpInfo = $this->getConstantPool(); foreach ($this->debugTraces as $debugTraces) { printf("[method]\n"); diff --git a/src/Core/PHPJava.php b/src/Core/PHPJava.php index 4d42bf86..aad57825 100644 --- a/src/Core/PHPJava.php +++ b/src/Core/PHPJava.php @@ -12,5 +12,5 @@ final class PHPJava /** * As same as composer version. */ - const VERSION = 0x000064; + const VERSION = 0x000065; } diff --git a/src/Exceptions/DebugTraceIsDisabledException.php b/src/Exceptions/DebugTraceIsDisabledException.php new file mode 100644 index 00000000..5b7c59a0 --- /dev/null +++ b/src/Exceptions/DebugTraceIsDisabledException.php @@ -0,0 +1,6 @@ + [ + 'enable_trace' => true, + ], + ]); + $calculatedValue = $this->initiatedJavaClasses['OutputDebugTraceTest'] ->getInvoker() ->getStatic() @@ -30,5 +37,7 @@ public function testCallMain() file_get_contents(__DIR__ . '/templates/DebugTraceTest.txt'), $result ); + + GlobalOptions::reset(); } }