From 93bde32fe2df8413ba8ea0d7e81f6316cb7ba423 Mon Sep 17 00:00:00 2001 From: Dmitriy Zayceff Date: Sat, 22 Feb 2020 15:46:15 +0300 Subject: [PATCH] Improve performance (toImmutable() method). --- bench/.gitignore | 3 + bench/package.php.yml | 18 +++++ bench/src/benchmarks/NewObjectBenchmark.php | 1 + jphp-core/api-docs/README.md | 4 +- jphp-core/api-docs/README.ru.md | 4 +- jphp-core/package.php.yml | 4 +- .../jvm/statement/ExpressionStmtCompiler.java | 4 +- jphp-runtime/api-docs/README.md | 4 +- jphp-runtime/api-docs/README.ru.md | 4 +- jphp-runtime/package.php.yml | 4 +- jphp-runtime/src/php/runtime/Memory.java | 46 +++++++++++-- .../src/php/runtime/env/Environment.java | 18 ++++- .../php/runtime/ext/core/MathFunctions.java | 8 +-- .../ext/core/classes/lib/ItemsUtils.java | 16 ++--- .../ext/core/classes/lib/SharedUtils.java | 8 +-- .../ext/support/compile/CompileFunction.java | 7 +- .../runtime/invoke/InvokeArgumentHelper.java | 8 +-- .../src/php/runtime/lang/IObject.java | 2 +- .../src/php/runtime/memory/ArrayMemory.java | 66 ++++++++----------- .../src/php/runtime/memory/DoubleMemory.java | 2 +- .../src/php/runtime/memory/FalseMemory.java | 2 +- .../src/php/runtime/memory/LongMemory.java | 2 +- .../src/php/runtime/memory/ObjectMemory.java | 10 +-- .../php/runtime/memory/ReferenceMemory.java | 11 +--- .../runtime/memory/StringBuilderMemory.java | 2 +- .../src/php/runtime/memory/StringMemory.java | 1 - .../src/php/runtime/memory/TrueMemory.java | 2 +- .../memory/support/ArrayMemoryMap.java | 15 +++-- .../runtime/memory/support/MemoryUtils.java | 2 +- .../php/runtime/reflection/ClassEntity.java | 11 ++-- .../reflection/CompileFunctionEntity.java | 4 +- .../reflection/CompileMethodEntity.java | 4 +- .../runtime/reflection/PropertyEntity.java | 2 +- .../support/AbstractFunctionEntity.java | 2 +- 34 files changed, 183 insertions(+), 118 deletions(-) create mode 100644 bench/.gitignore create mode 100644 bench/package.php.yml diff --git a/bench/.gitignore b/bench/.gitignore new file mode 100644 index 000000000..9eb7f5645 --- /dev/null +++ b/bench/.gitignore @@ -0,0 +1,3 @@ + +vendor/ +package-lock.php.yml \ No newline at end of file diff --git a/bench/package.php.yml b/bench/package.php.yml new file mode 100644 index 000000000..dbfe91d0f --- /dev/null +++ b/bench/package.php.yml @@ -0,0 +1,18 @@ +name: bench +version: 1.0.0 + +plugins: [App] + +deps: + jphp-core: '*' + jphp-zend-ext: '*' + jphp-json-ext: '*' + +app: + encoding: UTF-8 + +sources: + - src + +includes: + - 'bench.php' diff --git a/bench/src/benchmarks/NewObjectBenchmark.php b/bench/src/benchmarks/NewObjectBenchmark.php index 8c91f287a..f1d01eea0 100644 --- a/bench/src/benchmarks/NewObjectBenchmark.php +++ b/bench/src/benchmarks/NewObjectBenchmark.php @@ -33,6 +33,7 @@ public function run() { for ($i = 0; $i < self::DEFAULT_ITERATIONS; $i++) { $o1 = new stdClass(); + $o2 = new NewObjectBenchmark_A(); $o3 = new NewObjectBenchmark_B(); $o4 = new NewObjectBenchmark_C(); diff --git a/jphp-core/api-docs/README.md b/jphp-core/api-docs/README.md index 2c64f9de1..f70f8df39 100644 --- a/jphp-core/api-docs/README.md +++ b/jphp-core/api-docs/README.md @@ -3,13 +3,13 @@ --- ## jphp-core -> version 1.1.1, created by JPPM. +> version 1.1.2, created by JPPM. Compiler and Launcher for JPHP. ### Install ``` -jppm add jphp-core@1.1.1 +jppm add jphp-core@1.1.2 ``` ### API diff --git a/jphp-core/api-docs/README.ru.md b/jphp-core/api-docs/README.ru.md index 54497d0ac..f15e176a5 100644 --- a/jphp-core/api-docs/README.ru.md +++ b/jphp-core/api-docs/README.ru.md @@ -3,13 +3,13 @@ --- ## jphp-core -> версия 1.1.1, создано с помощью JPPM. +> версия 1.1.2, создано с помощью JPPM. Compiler and Launcher for JPHP. ### Установка ``` -jppm add jphp-core@1.1.1 +jppm add jphp-core@1.1.2 ``` ### АПИ diff --git a/jphp-core/package.php.yml b/jphp-core/package.php.yml index dda00fb93..575f14722 100644 --- a/jphp-core/package.php.yml +++ b/jphp-core/package.php.yml @@ -1,10 +1,10 @@ name: jphp-core -version: 1.1.1 +version: 1.1.2 description: Compiler and Launcher for JPHP. deps: - jphp-runtime: '~1.1.0' + jphp-runtime: '~1.1.3' plugins: [Doc, Hub] diff --git a/jphp-core/src/org/develnext/jphp/core/compiler/jvm/statement/ExpressionStmtCompiler.java b/jphp-core/src/org/develnext/jphp/core/compiler/jvm/statement/ExpressionStmtCompiler.java index ba68ad9b0..08138f94d 100644 --- a/jphp-core/src/org/develnext/jphp/core/compiler/jvm/statement/ExpressionStmtCompiler.java +++ b/jphp-core/src/org/develnext/jphp/core/compiler/jvm/statement/ExpressionStmtCompiler.java @@ -2138,7 +2138,9 @@ public void writeSysStaticCall(Class clazz, String method, Class returnClazz, Cl public void writePopImmutable() { if (!stackPeek().immutable) { - writeSysDynamicCall(Memory.class, "toImmutable", Memory.class); + writeSysStaticCall(Memory.class, "__static_fast_toImmutable", Memory.class, Memory.class); + + //writeSysDynamicCall(Memory.class, "fast_toImmutable", Memory.class); setStackPeekAsImmutable(); } } diff --git a/jphp-runtime/api-docs/README.md b/jphp-runtime/api-docs/README.md index e094bea45..ed432b441 100644 --- a/jphp-runtime/api-docs/README.md +++ b/jphp-runtime/api-docs/README.md @@ -3,13 +3,13 @@ --- ## jphp-runtime -> version 1.1.1, created by JPPM. +> version 1.1.3, created by JPPM. Runtime for JPHP + Standard library. ### Install ``` -jppm add jphp-runtime@1.1.1 +jppm add jphp-runtime@1.1.3 ``` ### API diff --git a/jphp-runtime/api-docs/README.ru.md b/jphp-runtime/api-docs/README.ru.md index dbcfcfdeb..1059972b4 100644 --- a/jphp-runtime/api-docs/README.ru.md +++ b/jphp-runtime/api-docs/README.ru.md @@ -3,13 +3,13 @@ --- ## jphp-runtime -> версия 1.1.1, создано с помощью JPPM. +> версия 1.1.3, создано с помощью JPPM. Runtime for JPHP + Standard library. ### Установка ``` -jppm add jphp-runtime@1.1.1 +jppm add jphp-runtime@1.1.3 ``` ### АПИ diff --git a/jphp-runtime/package.php.yml b/jphp-runtime/package.php.yml index 2fd801a84..01c7a16d6 100644 --- a/jphp-runtime/package.php.yml +++ b/jphp-runtime/package.php.yml @@ -1,6 +1,6 @@ name: jphp-runtime -version: 1.1.2 +version: 1.1.3 description: Runtime for JPHP + Standard library. plugins: [Doc, Hub] @@ -14,6 +14,8 @@ config: ignore: ['/package.hub.yml'] history: + 1.1.2: + - Improve call stack performance. 1.1.1: - Improve arrays performance. 1.1.0: diff --git a/jphp-runtime/src/php/runtime/Memory.java b/jphp-runtime/src/php/runtime/Memory.java index 0da9cef5b..58bcb6ea6 100644 --- a/jphp-runtime/src/php/runtime/Memory.java +++ b/jphp-runtime/src/php/runtime/Memory.java @@ -159,13 +159,13 @@ public Memory toBinary() { public Memory toArray() { ArrayMemory result = new ArrayMemory(); - result.add(toImmutable()); + result.add(fast_toImmutable()); return result.toConstant(); } public Memory toObject(Environment env) { StdClass stdClass = new StdClass(env); - stdClass.getProperties().refOfIndex("scalar").assign(toImmutable()); + stdClass.getProperties().refOfIndex("scalar").assign(fast_toImmutable()); return new ObjectMemory(stdClass); } @@ -354,9 +354,9 @@ public Memory pow(long value) { public Memory pow(boolean value) { Memory real = toNumeric(); if (real instanceof LongMemory) { - return value ? real.toImmutable() : Memory.CONST_INT_1; + return value ? real.fast_toImmutable() : Memory.CONST_INT_1; } - return value ? real.toImmutable() : Memory.CONST_DOUBLE_1; + return value ? real.fast_toImmutable() : Memory.CONST_DOUBLE_1; } public Memory pow(String value) { return pow(StringMemory.toNumeric(value)); } @@ -428,7 +428,7 @@ private static boolean _xor(boolean... args) { abstract public boolean identical(Memory memory); public boolean identical(long value) { return type == Type.INT && toLong() == value; } public boolean identical(double value) { return type == Type.DOUBLE && DoubleMemory.almostEqual(toDouble(), value); } - public boolean identical(boolean value) { return type == Type.BOOL && value ? toImmutable() == TRUE : toImmutable() == FALSE; } + public boolean identical(boolean value) { return type == Type.BOOL && value ? fast_toImmutable() == TRUE : fast_toImmutable() == FALSE; } public boolean identical(String value) { return type == Type.STRING && toString().equals(value); } // NOT EQUAL @@ -641,8 +641,42 @@ public Memory toImmutable(){ return this; } + /** + * This method more faster than toImmutable because is not overrided and is final + */ + final public Memory fast_toImmutable() { + switch (type) { + case INT: + case BOOL: + case NULL: + case DOUBLE: + case STRING: + case OBJECT: + return this; + default: + return toImmutable(); + } + } + + /** + * For compiler. + */ + static public Memory __static_fast_toImmutable(Memory value) { + switch (value.type) { + case INT: + case BOOL: + case NULL: + case DOUBLE: + case STRING: + case OBJECT: + return value; + default: + return value.toImmutable(); + } + } + public Memory toImmutable(Environment env, TraceInfo trace){ - return toImmutable(); + return fast_toImmutable(); } @SuppressWarnings("unchecked") diff --git a/jphp-runtime/src/php/runtime/env/Environment.java b/jphp-runtime/src/php/runtime/env/Environment.java index 382530d87..28921fb2d 100644 --- a/jphp-runtime/src/php/runtime/env/Environment.java +++ b/jphp-runtime/src/php/runtime/env/Environment.java @@ -767,7 +767,7 @@ public ArrayMemory getConfigValues(String prefix, boolean includingGlobal) { String key = entry.getKey(); if (prefix != null && !key.startsWith(prefix)) continue; - result.put(key, entry.getValue().toImmutable()); + result.put(key, entry.getValue().fast_toImmutable()); } } @@ -775,7 +775,7 @@ public ArrayMemory getConfigValues(String prefix, boolean includingGlobal) { String key = entry.getKey(); if (prefix != null && !key.startsWith(prefix)) continue; - result.put(key, entry.getValue().toImmutable()); + result.put(key, entry.getValue().fast_toImmutable()); } return result; } @@ -1578,6 +1578,20 @@ public Memory __throwException(InvocationTargetException e) { return Memory.NULL; } + public Memory __throwThrowable(Throwable throwable) { + if (throwable instanceof FinallyException) { + return Memory.NULL; + } + + if (throwable instanceof JPHPException) + throw (RuntimeException) throwable; + else { + JavaReflection.exception(this, throwable); + } + + return Memory.NULL; + } + public void __throwException(BaseBaseException e) { __throwException(e, true); } diff --git a/jphp-runtime/src/php/runtime/ext/core/MathFunctions.java b/jphp-runtime/src/php/runtime/ext/core/MathFunctions.java index 4bb97d905..15048e8d6 100644 --- a/jphp-runtime/src/php/runtime/ext/core/MathFunctions.java +++ b/jphp-runtime/src/php/runtime/ext/core/MathFunctions.java @@ -201,7 +201,7 @@ public static Memory max(Memory value, Memory... args){ if (max == null || one.greater(max)) max = one; } - return max == null ? Memory.NULL : max.toImmutable(); + return max == null ? Memory.NULL : max.fast_toImmutable(); } else { Memory max = value; if (args != null) @@ -209,7 +209,7 @@ public static Memory max(Memory value, Memory... args){ if (one.greater(max)) max = one; } - return max.toImmutable(); + return max.fast_toImmutable(); } } @@ -221,14 +221,14 @@ public static Memory min(Memory value, Memory... args){ if (min == null || one.smaller(min)) min = one; } - return min == null ? Memory.NULL : min.toImmutable(); + return min == null ? Memory.NULL : min.fast_toImmutable(); } else { Memory min = value; for(Memory one : args){ if (one.smaller(min)) min = one; } - return min.toImmutable(); + return min.fast_toImmutable(); } } diff --git a/jphp-runtime/src/php/runtime/ext/core/classes/lib/ItemsUtils.java b/jphp-runtime/src/php/runtime/ext/core/classes/lib/ItemsUtils.java index 849a3d035..aab51ccc3 100644 --- a/jphp-runtime/src/php/runtime/ext/core/classes/lib/ItemsUtils.java +++ b/jphp-runtime/src/php/runtime/ext/core/classes/lib/ItemsUtils.java @@ -172,9 +172,9 @@ public static Memory toArray(Environment env, Memory... args) { ArrayMemory r = new ArrayMemory(); while (iterator.next()) { if (withKeys) - r.put(iterator.getMemoryKey(), iterator.getValue().toImmutable()); + r.put(iterator.getMemoryKey(), iterator.getValue().fast_toImmutable()); else - r.add(iterator.getValue().toImmutable()); + r.add(iterator.getValue().fast_toImmutable()); } return r.toConstant(); @@ -206,7 +206,7 @@ public static Memory combine(Environment env, Memory... args) { while (keyIterator.next()) { if (valueIterator.next()) { - r.refOfIndex(keyIterator.getValue()).assign(valueIterator.getValue().toImmutable()); + r.refOfIndex(keyIterator.getValue()).assign(valueIterator.getValue().fast_toImmutable()); } else { return Memory.NULL; } @@ -276,9 +276,9 @@ public static Memory toList(Environment env, Memory... args) { if (arg.isTraversable()) { ForeachIterator iterator = arg.getNewIterator(env); while (iterator.next()) - r.add(iterator.getValue().toImmutable()); + r.add(iterator.getValue().fast_toImmutable()); } else - r.add(arg.toImmutable()); + r.add(arg.fast_toImmutable()); } return r.toConstant(); } @@ -306,7 +306,7 @@ protected static void flatten(Environment env, ForeachIterator iterator, Set= maxLevel && maxLevel > -1)) { - array.add(el.toImmutable()); + array.add(el.fast_toImmutable()); } else { if (used.add(el.getPointer())) { flatten(env, innerIterator, used, array, level + 1, maxLevel); @@ -390,7 +390,7 @@ public static Memory push(Environment env, Memory... args) throws Throwable { Memory array = args[0]; for (int i = 1; i < args.length; i++) { - array.toValue(ArrayMemory.class).add(args[i].toImmutable()); + array.toValue(ArrayMemory.class).add(args[i].fast_toImmutable()); } return Memory.NULL; @@ -431,7 +431,7 @@ public static Memory reverse(Environment env, Memory... args) { ArrayMemory result = new ArrayMemory(); while (iterator.next()) { - result.unshift(iterator.getValue().toImmutable()); + result.unshift(iterator.getValue().fast_toImmutable()); } return result.toConstant(); diff --git a/jphp-runtime/src/php/runtime/ext/core/classes/lib/SharedUtils.java b/jphp-runtime/src/php/runtime/ext/core/classes/lib/SharedUtils.java index e6ee0e794..3e11efc4d 100644 --- a/jphp-runtime/src/php/runtime/ext/core/classes/lib/SharedUtils.java +++ b/jphp-runtime/src/php/runtime/ext/core/classes/lib/SharedUtils.java @@ -246,7 +246,7 @@ synchronized public void __clone(Environment env, TraceInfo trace) throws Throwa } else if (value.isObject()) { this.value = value.clone(env, trace); } else { - this.value = value.toImmutable(); + this.value = value.fast_toImmutable(); } } } @@ -298,7 +298,7 @@ public void __construct(ForeachIterator iterator) { queue = new LinkedList(); while (iterator.next()) { - queue.add(iterator.getValue().toImmutable()); + queue.add(iterator.getValue().fast_toImmutable()); } } @@ -417,7 +417,7 @@ public void __construct(ForeachIterator iterator) { stack = new Stack(); while (iterator.next()) { - stack.push(iterator.getValue().toImmutable()); + stack.push(iterator.getValue().fast_toImmutable()); } } @@ -557,7 +557,7 @@ public void __construct(ForeachIterator iterator) { map = new LinkedHashMap(); while (iterator.next()) { - map.put(iterator.getKey().toString(), iterator.getValue().toImmutable()); + map.put(iterator.getKey().toString(), iterator.getValue().fast_toImmutable()); } } diff --git a/jphp-runtime/src/php/runtime/ext/support/compile/CompileFunction.java b/jphp-runtime/src/php/runtime/ext/support/compile/CompileFunction.java index c5b0e4c67..7d3d05cad 100644 --- a/jphp-runtime/src/php/runtime/ext/support/compile/CompileFunction.java +++ b/jphp-runtime/src/php/runtime/ext/support/compile/CompileFunction.java @@ -10,9 +10,11 @@ import php.runtime.exceptions.support.ErrorType; import php.runtime.memory.ArrayMemory; import php.runtime.memory.support.MemoryUtils; +import php.runtime.reflection.support.Entity; import php.runtime.reflection.support.ReflectionUtils; import java.lang.annotation.Annotation; +import java.lang.invoke.MethodHandle; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; @@ -360,12 +362,15 @@ public Memory call(Environment env, Memory... arguments) { if (resultType == void.class){ method.invoke(null, passed); return Memory.NULL; - } else + } else { return MemoryUtils.valueOf(method.invoke(null, passed)); + } } catch (InvocationTargetException e){ return env.__throwException(e); } catch (IllegalAccessException e) { throw new CriticalException(e); + } catch (Throwable throwable) { + return env.__throwThrowable(throwable); } } } diff --git a/jphp-runtime/src/php/runtime/invoke/InvokeArgumentHelper.java b/jphp-runtime/src/php/runtime/invoke/InvokeArgumentHelper.java index 86f7bfaa4..8494fe19b 100644 --- a/jphp-runtime/src/php/runtime/invoke/InvokeArgumentHelper.java +++ b/jphp-runtime/src/php/runtime/invoke/InvokeArgumentHelper.java @@ -65,7 +65,7 @@ private static Memory makeNormalArg(Environment env, TraceInfo trace, ParameterE return arg; } else { - return param.isMutable() ? arg.toImmutable() : arg.toValue(); + return param.isMutable() ? arg.fast_toImmutable() : arg.toValue(); } } @@ -182,7 +182,7 @@ public static Memory[] makeArguments(Environment env, Memory[] args, private static void makeImmutable(Memory[] passed, ParameterEntity[] parameters) { for (int j = parameters.length ; j < passed.length; j++) { - passed[j] = passed[j].toImmutable(); + passed[j] = passed[j].fast_toImmutable(); } } @@ -229,7 +229,7 @@ public static Memory[] unpackArgs(Environment env, TraceInfo trace, Memory[] pas isRef = parameterEntity != null && parameterEntity.isReference(); Memory value = foreachIterator.getValue(); - varPassed.add(isRef ? value : value.toImmutable()); + varPassed.add(isRef ? value : value.fast_toImmutable()); paramCnt++; @@ -378,7 +378,7 @@ public static Memory makeValue(ParameterEntity param, Memory arg, Environment en arg = new ReferenceMemory(arg); } } else { - arg = param.isMutable() ? arg.toImmutable() : arg.toValue(); + arg = param.isMutable() ? arg.fast_toImmutable() : arg.toValue(); } return arg; diff --git a/jphp-runtime/src/php/runtime/lang/IObject.java b/jphp-runtime/src/php/runtime/lang/IObject.java index 82908b49c..e65e4c852 100644 --- a/jphp-runtime/src/php/runtime/lang/IObject.java +++ b/jphp-runtime/src/php/runtime/lang/IObject.java @@ -31,7 +31,7 @@ default Memory getProp(String name) { } default void setProp(String name, Memory value) { - getProperties().putAsKeyString(name, value.toImmutable()); + getProperties().putAsKeyString(name, value.fast_toImmutable()); } default void setProp(String name, String value) { diff --git a/jphp-runtime/src/php/runtime/memory/ArrayMemory.java b/jphp-runtime/src/php/runtime/memory/ArrayMemory.java index 0cb98c67b..5e63a5fc9 100644 --- a/jphp-runtime/src/php/runtime/memory/ArrayMemory.java +++ b/jphp-runtime/src/php/runtime/memory/ArrayMemory.java @@ -206,7 +206,7 @@ public ArrayMemory duplicate() { result.map = new ArrayMemoryMap(); for (Map.Entry entry : map.entrySet()) { - result.map.put(entry.getKey(), entry.getValue().toImmutable()); + result.map.put(entry.getKey(), entry.getValue().fast_toImmutable()); } } @@ -385,7 +385,7 @@ public void addNull() { public ReferenceMemory add(Memory value) { if (value instanceof KeyValueMemory) { KeyValueMemory keyValue = (KeyValueMemory) value; - return put(keyValue.getArrayKey(), keyValue.getValue().toImmutable()); + return put(keyValue.getArrayKey(), keyValue.getValue().fast_toImmutable()); } ReferenceMemory ref; @@ -415,7 +415,7 @@ public void merge(ArrayMemory array, boolean recursive, Set done) { if (map == null && array.map == null) { for (ReferenceMemory reference : array.getList()) - getList().add(new ReferenceMemory(reference.toImmutable())); + getList().add(new ReferenceMemory(reference.fast_toImmutable())); size = getList().size(); lastLongIndex = size - 1; @@ -426,13 +426,13 @@ public void merge(ArrayMemory array, boolean recursive, Set done) { if (array.map == null) { for (ReferenceMemory reference : array.getList()) { - add(reference.toImmutable()); + add(reference.fast_toImmutable()); } } else { for (Map.Entry entry : array.map.entrySet()) { Object key = entry.getKey(); if (key instanceof Long) { - add(entry.getValue().toImmutable()); + add(entry.getValue().fast_toImmutable()); } else { Memory value = entry.getValue(); if (recursive && value.isArray()) { @@ -440,10 +440,10 @@ public void merge(ArrayMemory array, boolean recursive, Set done) { throw new RecursiveException(); ReferenceMemory byScalar = getByScalar(key); - Memory current = byScalar != null ? byScalar.toImmutable() : null; + Memory current = byScalar != null ? byScalar.fast_toImmutable() : null; if (byScalar != null && current.isArray()) { - value = value.toImmutable(); + value = value.fast_toImmutable(); int pointer = value.getPointer(); done.add(pointer); // for check recursive @@ -454,9 +454,9 @@ public void merge(ArrayMemory array, boolean recursive, Set done) { done.remove(pointer); } else - put(key, value.toImmutable()); + put(key, value.fast_toImmutable()); } else { - put(key, value.toImmutable()); + put(key, value.fast_toImmutable()); } } } @@ -469,7 +469,7 @@ public void putAll(ArrayMemory array) { long i = 0; for (ReferenceMemory memory : array.getList()) { if (memory != null) - put(i, memory.toImmutable()); + put(i, memory.fast_toImmutable()); i++; } } else { @@ -481,7 +481,7 @@ public void putAll(ArrayMemory array) { lastLongIndex = array.lastLongIndex; for (Map.Entry entry : array.map.entrySet()) { - put(entry.getKey(), entry.getValue().toImmutable()); + put(entry.getKey(), entry.getValue().fast_toImmutable()); } } } @@ -512,13 +512,7 @@ public ReferenceMemory putAsKeyString(String key, Memory value) { convertToMap(); } - Pair result = map.putWithEntry(key, value); - - if (!result.hasA()) { - size++; - } - - return result.getB(); + return map.putWithCallback(key, value, () -> size++); } public ReferenceMemory put(Object key, String value) { @@ -581,13 +575,7 @@ public ReferenceMemory put(Object key, Memory value) { } } - Pair result = map.putWithEntry(key, value); - - if (!result.hasA()) { - size++; - } - - return result.getB(); + return map.putWithCallback(key, value, () -> size++); } public Memory removeByScalar(Object key) { @@ -973,7 +961,7 @@ public Memory[] values(boolean asImmutable) { Memory[] result = new Memory[size]; int i = 0; for (ReferenceMemory el : this) { - result[i++] = asImmutable ? el.toImmutable() : el.toValue(); + result[i++] = asImmutable ? el.fast_toImmutable() : el.toValue(); } return result; } @@ -1034,7 +1022,7 @@ public Memory plus(Memory memory) { Memory origin = getByScalar(key); if (origin == null) { left.checkCopied(); - left.put(key, iterator.getValue().toImmutable()); + left.put(key, iterator.getValue().fast_toImmutable()); } } return left; @@ -1715,7 +1703,7 @@ public Object toMapOrList(Environment env) { public static ArrayMemory ofPair(String key, Memory value) { ArrayMemory r = new ArrayMemory(); - r.refOfIndex(key).assign(value.toImmutable()); + r.refOfIndex(key).assign(value.fast_toImmutable()); return r; } @@ -1866,7 +1854,7 @@ public static ArrayMemory of(Memory... array) { if (array != null) { for (Memory el : array) { - result.add(el.toImmutable()); + result.add(el.fast_toImmutable()); } } @@ -1904,7 +1892,7 @@ public static ArrayMemory ofCollection(Collection list) { ArrayMemory result = new ArrayMemory(); for (Memory el : list) { - result.add(el.toImmutable()); + result.add(el.fast_toImmutable()); } return result; @@ -1914,7 +1902,7 @@ public static ArrayMemory ofMap(Map map) { ArrayMemory result = new ArrayMemory(); for (Map.Entry entry : map.entrySet()) { - result.putAsKeyString(entry.getKey(), entry.getValue().toImmutable()); + result.putAsKeyString(entry.getKey(), entry.getValue().fast_toImmutable()); } return result; @@ -2160,9 +2148,9 @@ public ArrayMemory slice(int offset, boolean saveKeys) { try { for (ReferenceMemory referenceMemory : getList().subList(offset, getList().size())) { if (saveKeys) { - result.refOfIndex(i + offset).assign(referenceMemory.toImmutable()); + result.refOfIndex(i + offset).assign(referenceMemory.fast_toImmutable()); } else { - result.add(referenceMemory.toImmutable()); + result.add(referenceMemory.fast_toImmutable()); } i++; @@ -2178,9 +2166,9 @@ public ArrayMemory slice(int offset, boolean saveKeys) { while (iterator.next()) { if (i >= offset) { if (saveKeys || !iterator.isLongKey()) { - result.put(iterator.getKey(), iterator.getValue().toImmutable()); + result.put(iterator.getKey(), iterator.getValue().fast_toImmutable()); } else { - result.add(iterator.getValue().toImmutable()); + result.add(iterator.getValue().fast_toImmutable()); } } @@ -2207,9 +2195,9 @@ public ArrayMemory slice(int offset, int length, boolean saveKeys) { try { for (ReferenceMemory referenceMemory : getList().subList(offset, offset + length)) { if (saveKeys) { - result.refOfIndex(i + offset).assign(referenceMemory.toImmutable()); + result.refOfIndex(i + offset).assign(referenceMemory.fast_toImmutable()); } else { - result.add(referenceMemory.toImmutable()); + result.add(referenceMemory.fast_toImmutable()); } i++; @@ -2227,9 +2215,9 @@ public ArrayMemory slice(int offset, int length, boolean saveKeys) { count++; if (saveKeys || !iterator.isLongKey()) { - result.put(iterator.getKey(), iterator.getValue().toImmutable()); + result.put(iterator.getKey(), iterator.getValue().fast_toImmutable()); } else { - result.add(iterator.getValue().toImmutable()); + result.add(iterator.getValue().fast_toImmutable()); } if (count >= length) { diff --git a/jphp-runtime/src/php/runtime/memory/DoubleMemory.java b/jphp-runtime/src/php/runtime/memory/DoubleMemory.java index dd05700eb..ce7e25d41 100644 --- a/jphp-runtime/src/php/runtime/memory/DoubleMemory.java +++ b/jphp-runtime/src/php/runtime/memory/DoubleMemory.java @@ -165,7 +165,7 @@ public Memory pow(Memory memory) { switch (memory.type){ case INT: return new DoubleMemory(Math.pow(value, ((LongMemory)memory).value)); case DOUBLE: return new DoubleMemory(Math.pow(value, ((LongMemory)memory).value)); - case REFERENCE: return mul(memory.toImmutable()); + case REFERENCE: return mul(memory.fast_toImmutable()); default: return pow(memory.toNumeric()); } } diff --git a/jphp-runtime/src/php/runtime/memory/FalseMemory.java b/jphp-runtime/src/php/runtime/memory/FalseMemory.java index 6e334ea2d..ea54d9496 100644 --- a/jphp-runtime/src/php/runtime/memory/FalseMemory.java +++ b/jphp-runtime/src/php/runtime/memory/FalseMemory.java @@ -138,7 +138,7 @@ public Memory mul(Memory memory) { public Memory pow(Memory memory) { switch (memory.type){ case DOUBLE: return Memory.CONST_INT_0; - case REFERENCE: return pow(memory.toImmutable()); + case REFERENCE: return pow(memory.fast_toImmutable()); default: return Memory.CONST_INT_0; } } diff --git a/jphp-runtime/src/php/runtime/memory/LongMemory.java b/jphp-runtime/src/php/runtime/memory/LongMemory.java index 04dab177e..132f97c56 100644 --- a/jphp-runtime/src/php/runtime/memory/LongMemory.java +++ b/jphp-runtime/src/php/runtime/memory/LongMemory.java @@ -150,7 +150,7 @@ public Memory pow(Memory memory) { switch (memory.type){ case INT: return pow(((LongMemory) memory).value); case DOUBLE: return pow(((DoubleMemory) memory).value); - case REFERENCE: return pow(memory.toImmutable()); + case REFERENCE: return pow(memory.fast_toImmutable()); default: return pow(memory.toNumeric()); } } diff --git a/jphp-runtime/src/php/runtime/memory/ObjectMemory.java b/jphp-runtime/src/php/runtime/memory/ObjectMemory.java index 6bdf3fcc1..cdb6fbd4e 100644 --- a/jphp-runtime/src/php/runtime/memory/ObjectMemory.java +++ b/jphp-runtime/src/php/runtime/memory/ObjectMemory.java @@ -388,7 +388,7 @@ public boolean next() { try { currentValue = iterator.current(env); if (!getReferences) - currentValue = currentValue.toImmutable(); + currentValue = currentValue.fast_toImmutable(); } finally { if (!isNative) env.popCall(); @@ -417,7 +417,7 @@ public Memory getMemoryKey() { if (!isNative) env.pushCall(trace, ObjectMemory.this.value, null, "key", className, null); try { - currentKey = iterator.key(env).toImmutable(); + currentKey = iterator.key(env).fast_toImmutable(); keyInit = true; return (Memory) currentKey; } finally { @@ -528,14 +528,14 @@ public Memory toArray() { while (iterator.next()) { Object key = iterator.getKey(); - Memory value = iterator.getValue().toImmutable(); + Memory value = iterator.getValue().fast_toImmutable(); if (key instanceof String) { String keyS = (String) key; PropertyEntity prop = reflection.properties.get(keyS); if (prop == null || prop.getModifier() == Modifier.PUBLIC) { - result.refOfIndex(keyS).assign(iterator.getValue().toImmutable()); + result.refOfIndex(keyS).assign(iterator.getValue().fast_toImmutable()); } else { if (prop.getModifier() == Modifier.PROTECTED) { result.refOfIndex("\0*\0" + keyS).assign(value); @@ -1028,7 +1028,7 @@ public ReferenceMemory getReference() { @Override public Memory toImmutable() { - return toValue().toImmutable(); + return toValue().fast_toImmutable(); } @Override diff --git a/jphp-runtime/src/php/runtime/memory/ReferenceMemory.java b/jphp-runtime/src/php/runtime/memory/ReferenceMemory.java index 1328dce25..7a15bd959 100644 --- a/jphp-runtime/src/php/runtime/memory/ReferenceMemory.java +++ b/jphp-runtime/src/php/runtime/memory/ReferenceMemory.java @@ -31,7 +31,7 @@ public ReferenceMemory() { } public ReferenceMemory duplicate(){ - return new ReferenceMemory(getValue().toImmutable()); + return new ReferenceMemory(getValue().fast_toImmutable()); } public Memory getValue() { @@ -609,12 +609,7 @@ public Memory newKeyValue(String memory) { @Override public Memory toImmutable() { - switch (getValue().type){ - case NULL: - case REFERENCE: - case ARRAY: return getValue().toImmutable(); - default: return getValue(); - } + return getValue().fast_toImmutable(); } @Override @@ -717,7 +712,7 @@ private StringMemory typeString(){ assign(new StringMemory(getValue().toString())); } - return (StringMemory)toImmutable(); + return (StringMemory) toImmutable(); } @Override diff --git a/jphp-runtime/src/php/runtime/memory/StringBuilderMemory.java b/jphp-runtime/src/php/runtime/memory/StringBuilderMemory.java index 03d352a6e..eecb4d55e 100644 --- a/jphp-runtime/src/php/runtime/memory/StringBuilderMemory.java +++ b/jphp-runtime/src/php/runtime/memory/StringBuilderMemory.java @@ -60,7 +60,7 @@ public void append(Memory memory){ case INT: builder.append(((LongMemory)memory).value); break; case DOUBLE: builder.append(((DoubleMemory)memory).value); break; case STRING: builder.append(memory.toString()); break; - case REFERENCE: append(memory.toImmutable()); break; + case REFERENCE: append(memory.fast_toImmutable()); break; default: builder.append(memory.toString()); } diff --git a/jphp-runtime/src/php/runtime/memory/StringMemory.java b/jphp-runtime/src/php/runtime/memory/StringMemory.java index 118a955cb..87b21c914 100644 --- a/jphp-runtime/src/php/runtime/memory/StringMemory.java +++ b/jphp-runtime/src/php/runtime/memory/StringMemory.java @@ -689,7 +689,6 @@ public Memory toImmutable() { return this; } - @Override public boolean isNull() { return false; diff --git a/jphp-runtime/src/php/runtime/memory/TrueMemory.java b/jphp-runtime/src/php/runtime/memory/TrueMemory.java index 27ff9750e..ddb1c571e 100644 --- a/jphp-runtime/src/php/runtime/memory/TrueMemory.java +++ b/jphp-runtime/src/php/runtime/memory/TrueMemory.java @@ -163,7 +163,7 @@ public Memory mul(Memory memory) { public Memory pow(Memory memory) { switch (memory.type) { case DOUBLE: return Memory.CONST_DOUBLE_1; - case REFERENCE: return pow(memory.toImmutable()); + case REFERENCE: return pow(memory.fast_toImmutable()); default: return Memory.CONST_INT_1; } } diff --git a/jphp-runtime/src/php/runtime/memory/support/ArrayMemoryMap.java b/jphp-runtime/src/php/runtime/memory/support/ArrayMemoryMap.java index 24bad194c..501c0db0a 100644 --- a/jphp-runtime/src/php/runtime/memory/support/ArrayMemoryMap.java +++ b/jphp-runtime/src/php/runtime/memory/support/ArrayMemoryMap.java @@ -1,7 +1,6 @@ package php.runtime.memory.support; import php.runtime.Memory; -import php.runtime.common.Pair; import php.runtime.common.collections.*; import php.runtime.common.collections.iterators.*; import php.runtime.common.collections.list.UnmodifiableList; @@ -383,26 +382,30 @@ public boolean containsValue(Object value) { * @return the value previously mapped to this key, null if none */ public Memory put(Object key, Memory value) { - return putWithEntry(key, value).getA(); + return putWithCallback(key, value, null); } - public Pair putWithEntry(Object key, Memory value) { + public ArrayMapEntryMemory putWithCallback(Object key, Memory value, Runnable onAdd) { int hashCode = hash((key == null) ? NULL : key); int index = hashIndex(hashCode, data.length); ArrayMapEntryMemory entry = data[index]; while (entry != null) { if (entry.hashCode == hashCode && isEqualKey(key, entry.getKey())) { - Memory oldValue = entry.getValue(); + //Memory oldValue = entry.getValue(); updateEntry(entry, value); - return new Pair<>(oldValue, entry); + return entry; } entry = entry.next; } entry = addMapping(index, hashCode, key, value); - return new Pair<>(null, entry); + if (onAdd != null) { + onAdd.run(); + } + + return entry; } /** diff --git a/jphp-runtime/src/php/runtime/memory/support/MemoryUtils.java b/jphp-runtime/src/php/runtime/memory/support/MemoryUtils.java index 3061a73cb..ca30a72f3 100644 --- a/jphp-runtime/src/php/runtime/memory/support/MemoryUtils.java +++ b/jphp-runtime/src/php/runtime/memory/support/MemoryUtils.java @@ -193,7 +193,7 @@ public Memory[] run(Environment env, TraceInfo trace, Memory value) { if (value.isArray()){ List result = new ArrayList(); for(Memory one : (ArrayMemory)value){ - result.add(one.toImmutable()); + result.add(one.fast_toImmutable()); } return result.toArray(new Memory[]{}); } else { diff --git a/jphp-runtime/src/php/runtime/reflection/ClassEntity.java b/jphp-runtime/src/php/runtime/reflection/ClassEntity.java index 6ec55c594..36d566cf0 100644 --- a/jphp-runtime/src/php/runtime/reflection/ClassEntity.java +++ b/jphp-runtime/src/php/runtime/reflection/ClassEntity.java @@ -934,9 +934,10 @@ public T newObject(Environment env, TraceInfo trace, boolean for (PropertyEntity property : getProperties()) { if (id == property.clazz.getId() && property.getGetter() == null) { + //value.isImmutable(); props.putAsKeyString( property.getSpecificName(), - property.getDefaultValue(env).toImmutable() + property.getDefaultValue(env).fast_toImmutable() ); } } @@ -949,7 +950,7 @@ public T newObject(Environment env, TraceInfo trace, boolean if (property.modifier != Modifier.PROTECTED || props.getByScalar(property.getName()) == null) props.getByScalarOrCreate( property.getSpecificName(), - property.getDefaultValue(env).toImmutable() + property.getDefaultValue(env).fast_toImmutable() ); } } @@ -977,11 +978,11 @@ public T cloneObject(T value, Environment env, TraceInfo tra PropertyEntity entity = properties.get(name); if (entity != null) { if (props.getByScalar(entity.getSpecificName()) == null) - props.put(entity.getSpecificName(), iterator.getValue().toImmutable()); + props.put(entity.getSpecificName(), iterator.getValue().fast_toImmutable()); } else - props.put(key, iterator.getValue().toImmutable()); + props.put(key, iterator.getValue().fast_toImmutable()); } else - props.put(key, iterator.getValue().toImmutable()); + props.put(key, iterator.getValue().fast_toImmutable()); } if (methodMagicClone != null) { diff --git a/jphp-runtime/src/php/runtime/reflection/CompileFunctionEntity.java b/jphp-runtime/src/php/runtime/reflection/CompileFunctionEntity.java index c0d3332ef..b67048001 100644 --- a/jphp-runtime/src/php/runtime/reflection/CompileFunctionEntity.java +++ b/jphp-runtime/src/php/runtime/reflection/CompileFunctionEntity.java @@ -75,7 +75,7 @@ public Memory invoke(Environment env, TraceInfo trace, Memory[] arguments) throw if (clazz == Memory.class) { Memory argument = arguments[j]; - passed[i] = isRef ? argument : (mutableValue ? argument.toImmutable() : argument.toValue()); + passed[i] = isRef ? argument : (mutableValue ? argument.fast_toImmutable() : argument.toValue()); j++; } else if (converter != null) { passed[i] = converter.run(arguments[j]); @@ -89,7 +89,7 @@ public Memory invoke(Environment env, TraceInfo trace, Memory[] arguments) throw if (!isRef){ for(int k = 0; k < arg.length; k++) - arg[i] = arguments[i].toImmutable(); + arg[i] = arguments[i].fast_toImmutable(); } else { System.arraycopy(arguments, j, arg, 0, arg.length); } diff --git a/jphp-runtime/src/php/runtime/reflection/CompileMethodEntity.java b/jphp-runtime/src/php/runtime/reflection/CompileMethodEntity.java index 0bfa8d2c0..a6fb97ece 100644 --- a/jphp-runtime/src/php/runtime/reflection/CompileMethodEntity.java +++ b/jphp-runtime/src/php/runtime/reflection/CompileMethodEntity.java @@ -213,7 +213,7 @@ public Memory invokeDynamic(Object _this, Environment env, TraceInfo trace, Memo MemoryOperation operation = method.argumentOperations[i]; if (clazz == Memory.class) { - passed[i] = isRef ? arguments[j] : (mutableValue ? arguments[j].toValue() : arguments[j].toImmutable()); + passed[i] = isRef ? arguments[j] : (mutableValue ? arguments[j].toValue() : arguments[j].fast_toImmutable()); j++; } else if (operation != null) { if (operation instanceof InjectMemoryOperation) { @@ -226,7 +226,7 @@ public Memory invokeDynamic(Object _this, Environment env, TraceInfo trace, Memo Memory[] arg = new Memory[arguments.length - i + 1]; if (!isRef){ for(int k = 0; k < arg.length; k++) - arg[i] = arguments[i].toImmutable(); + arg[i] = arguments[i].fast_toImmutable(); } else { System.arraycopy(arguments, j, arg, 0, arg.length); } diff --git a/jphp-runtime/src/php/runtime/reflection/PropertyEntity.java b/jphp-runtime/src/php/runtime/reflection/PropertyEntity.java index 91e40804c..28b234d99 100644 --- a/jphp-runtime/src/php/runtime/reflection/PropertyEntity.java +++ b/jphp-runtime/src/php/runtime/reflection/PropertyEntity.java @@ -266,7 +266,7 @@ public Memory assignValue(Environment env, TraceInfo trace, Object object, Strin public Memory getStaticValue(Environment env, TraceInfo trace) { return env.getOrCreateStatic( specificName, - getDefaultValue(env).toImmutable() + getDefaultValue(env).fast_toImmutable() ); } diff --git a/jphp-runtime/src/php/runtime/reflection/support/AbstractFunctionEntity.java b/jphp-runtime/src/php/runtime/reflection/support/AbstractFunctionEntity.java index 7bbf994b5..1da27e44a 100644 --- a/jphp-runtime/src/php/runtime/reflection/support/AbstractFunctionEntity.java +++ b/jphp-runtime/src/php/runtime/reflection/support/AbstractFunctionEntity.java @@ -126,7 +126,7 @@ public boolean isImmutable() { public Memory getImmutableResult(){ if ((isImmutable || isEmpty) && !abstractable) { Memory result = getResult(); - return result == null ? null : result.toImmutable(); + return result == null ? null : result.fast_toImmutable(); } return null;