diff --git a/bin/prof.php b/bin/prof.php new file mode 100755 index 00000000..f8d0ceb1 --- /dev/null +++ b/bin/prof.php @@ -0,0 +1,8 @@ +#!/usr/bin/env php + profile.pdf"); diff --git a/examples/EightQueue.php b/examples/EightQueue.php index 22872c26..35023540 100644 --- a/examples/EightQueue.php +++ b/examples/EightQueue.php @@ -113,11 +113,13 @@ function main() echo "\n"; } -// 测试不同规模 + // 测试不同规模 + $begin = microtime(true); echo "\n=== 不同规模的皇后问题 ===\n"; for ($n = 4; $n <= 10; $n++) { $q = new EightQueensOptimized($n); $count = $q->countSolutions(); echo "{$n} 皇后问题有 {$count} 个解\n"; } + echo "耗时: " . (microtime(true) - $begin) . " 秒\n"; } diff --git a/src/Php/AstNodeType.php b/src/Php/AstNodeType.php index 48cb266a..4c7a8eea 100644 --- a/src/Php/AstNodeType.php +++ b/src/Php/AstNodeType.php @@ -4,6 +4,7 @@ namespace PhpAot\Php; use PhpParser\Node\Expr; use PhpParser\NodeAbstract; +use PhpParser\Node; trait AstNodeType { @@ -12,6 +13,11 @@ trait AstNodeType return $expr instanceof Expr\Variable; } + protected function isIdExpr(NodeAbstract $expr): bool + { + return $expr instanceof Node\Identifier; + } + protected function isPropertyFetch(NodeAbstract $expr): bool { return $expr instanceof Expr\PropertyFetch; diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 680939d0..61956e2d 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -39,6 +39,7 @@ class CompilerBase extends \PhpAot\Core\Translator public const string VALUE_NAN = 'std::numeric_limits::quiet_NaN()'; public const string VALUE_INF = 'std::numeric_limits::infinity()'; public const string LITERAL_STRINGS = '_literal_strings'; + public const string PROPERTY_OFFSETS = '_property_offsets'; public const string EXPR_VARIABLE = 'Expr_Variable'; public const string EXPR_NEW = 'Expr_New'; public const string EXPR_ARRAY_DIM_FETCH = 'Expr_ArrayDimFetch'; @@ -235,12 +236,17 @@ class CompilerBase extends \PhpAot\Core\Translator protected function getFunctionName(FunctionLike $v): string { - return $this->getNativeFunctionName($this->parseIdentifier($v->name), $this->namespace, $this->class); + return $this->getNativeName($this->parseIdentifier($v->name), $this->namespace, $this->class); } - protected function getNativeFunctionName(string $fn, string $ns = '', string $class = ''): string + protected function getPropertyOffset(string $property, string $class, string $namespace = ''): string { - $names[] = $this->escapeFunction($fn); + return $this->getNativeName('property_offset_' . $property, $namespace, $class); + } + + protected function getNativeName(string $fn, string $ns = '', string $class = ''): string + { + $names[] = $this->escapeName($fn); if ($ns) { $names[] = $this->escapeNamespace($ns); } @@ -1371,7 +1377,7 @@ class CompilerBase extends \PhpAot\Core\Translator */ protected function findNativeFunction(string $fname): string|false { - $possibleFunctionNames = [$this->escapeFunction($fname),]; + $possibleFunctionNames = [$this->escapeName($fname),]; if ($this->namespace) { $possibleFunctionNames[] = $this->escapeNamespace($this->namespace) . self::NAMESPACE_SEPARATOR . $fname; } @@ -1918,9 +1924,9 @@ class CompilerBase extends \PhpAot\Core\Translator return str_replace('\\', self::NAMESPACE_SEPARATOR, strtolower($ns)); } - protected function escapeFunction(string $fname): string + protected function escapeName(string $name): string { - return strtolower($fname); + return strtolower($name); } protected function escapeClass(string $class): string @@ -2015,7 +2021,15 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePropertyFetch(Node\Expr\PropertyFetch $expr): string { - return $this->convertToObject($expr->var) . '.getPropertyIndirect("' . $this->parseIdentifier($expr->name) . '")'; + $object = $expr->var; + $property = $expr->name; + $id = $this->identifierToStr($property); + if ($this->isVarExpr($object) and $this->isIdExpr($property)) { + if ($this->parseIdentifier($object) === 'this_') { + $id = self::PREFIX . $this->getPropertyOffset($property, $this->class, $this->namespace); + } + } + return $this->convertToObject($object) . '.getPropertyIndirect(' . $id . ')'; } protected function parseAssignOpShiftRight(Node $node): string @@ -2371,7 +2385,7 @@ class CompilerBase extends \PhpAot\Core\Translator { $object = $this->convertToObject($expr->var); $method = $this->parseIdentifier($expr->name); - $nativeFunc = $this->getNativeFunctionName($method, $this->namespace, $this->class); + $nativeFunc = $this->getNativeName($method, $this->namespace, $this->class); if ($this->isNativeMethod($object, $nativeFunc)) { return $this->parseNativeMethodCall($object, $nativeFunc, $expr->args); } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index c9ddf173..d54089e9 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -283,6 +283,13 @@ class Translator extends Preprocessor $lines[] = 'extern ' . self::TYPE_VAR . ' ' . $name . ';'; } + // property offset + foreach ($this->classes as $classDef) { + foreach ($classDef->properties as $propertyDef) { + $lines[] = 'extern uint32_t ' . self::PREFIX . $this->getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace) . ';'; + } + } + $literalStringsCount = count($this->literalStrings); $lines[] = 'extern php::Var ' . self::LITERAL_STRINGS . '[' . $literalStringsCount . '];' . PHP_EOL; $code = implode(PHP_EOL, $lines) . PHP_EOL . PHP_EOL; @@ -446,7 +453,7 @@ class Translator extends Preprocessor protected function getNativeMethodName(ClassDef $classDef, MethodDef $methodDef): string { - return $this->getNativeFunctionName($methodDef->name, $classDef->namespace, $classDef->name); + return $this->getNativeName($methodDef->name, $classDef->namespace, $classDef->name); } protected function parseNamespace(Node\Stmt\Namespace_ $node): string @@ -576,6 +583,8 @@ class Translator extends Preprocessor foreach ($classDef->methods as $method) { $code .= $methodCodes[$method->name] . PHP_EOL; } + $code .= PHP_EOL; + return $code; } diff --git a/src/cpp/main.cc b/src/cpp/main.cc index e2111494..6b6ad624 100644 --- a/src/cpp/main.cc +++ b/src/cpp/main.cc @@ -29,7 +29,7 @@ int main(int cpp_argc, char **cpp_argv) { int rc = 0; #if PPROF_ON - ProfilerStart("myapp.prof"); + ProfilerStart("profile.out"); #endif zend_first_try { php_app_init(); diff --git a/src/template/extension.cc.php b/src/template/extension.cc.php index a35d4e28..cd2a7561 100644 --- a/src/template/extension.cc.php +++ b/src/template/extension.cc.php @@ -43,6 +43,17 @@ foreach ($this->nativeConstants as $name => $constant): type?> ; +// property offset +classes as $classDef): + foreach ($classDef->properties as $propertyDef): +?> +uint32_t getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace)?>; + + static ZEND_FUNCTION(main) { php_main(); } @@ -82,6 +93,17 @@ foreach ($this->globalVars as $name => $type): ?> = php::global(""); + + // property offset +classes as $classDef): + foreach ($classDef->properties as $propertyDef): + ?> + getPropertyOffset($propertyDef->name, $classDef->name, $classDef->namespace)?> = php::getPropertyOffset("getNamespacedName()?>", "name?>"); + } void php_app_clean() {