Optimizing VM - #575
Optimizing VM#575
Conversation
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #575 +/- ##
==========================================
- Coverage 85.61% 85.47% -0.14%
==========================================
Files 41 41
Lines 2606 2720 +114
Branches 338 345 +7
==========================================
+ Hits 2231 2325 +94
- Misses 287 304 +17
- Partials 88 91 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Jim8y
left a comment
There was a problem hiding this comment.
SETITEM now removes the new value with PopNoRef() before validating the array index. If the array branch then throws the catchable out-of-range exception, the value has already been removed from the evaluation stack but its stack reference is never removed. A script can catch that exception and continue with an inflated ReferenceCounter.Count, which can later trigger incorrect MaxStackSize failures.\n\nI reproduced this with a TRY/CATCH around an out-of-range array SETITEM: the same test passes on base with count 0 after the catch, but this PR leaves count 1. Please either keep the normal Pop() until all catchable validation is complete, or remove the value reference on every failure path before rethrowing.
shargon
left a comment
There was a problem hiding this comment.
It's better to use internal because these calls can desynchronize the reference counter
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Jim8y
left a comment
There was a problem hiding this comment.
Thanks for updating the reference-counter helpers to internal and fixing the array out-of-range path. I found one remaining blocker in the Buffer SETITEM branch: the value is removed before validating the buffer index, then removed again on the out-of-range catchable path. A handled script such as TRY; PUSH1; NEWBUFFER; PUSH2; PUSH0; SETITEM; DROP; ENDTRY halts with ReferenceCounter.Count == -1 instead of 0. I reproduced it by adding a focused UT_ReferenceCounter test and running dotnet test tests/Neo.VM.Tests/Neo.VM.Tests.csproj --filter TestSetItemBufferCatchableIndexFailureBalancesReferences --verbosity minimal.
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Jim8y
left a comment
There was a problem hiding this comment.
Rechecked the latest head. The Buffer SETITEM catchable out-of-range path now keeps the reference counter balanced, and the new JSON case covers it. I also ran Determining projects to restore...
All projects are up-to-date for restore.
Neo.VM -> /private/tmp/neo-vm-review-575/src/Neo.VM/bin/Debug/net10.0/Neo.VM.dll
Neo.VM.Tests -> /private/tmp/neo-vm-review-575/tests/Neo.VM.Tests/bin/Debug/net10.0/Neo.VM.Tests.dll
Test run for /private/tmp/neo-vm-review-575/tests/Neo.VM.Tests/bin/Debug/net10.0/Neo.VM.Tests.dll (.NETCoreApp,Version=v10.0)
A total of 1 test files matched the specified pattern.
Passed! - Failed: 0, Passed: 156, Skipped: 0, Total: 156, Duration: 647 ms - Neo.VM.Tests.dll (net10.0) successfully.
|
On neo-project/neo#4546 there was a question about optimizing the Old
New
|
Signed-off-by: Tural Devrishev <tural@nspcc.ru>
Use these helpers instead of adding/removal virtual Null stackitems for more eplicity. No functional changes. Signed-off-by: Anna Shaleva <shaleva.ann@nspcc.ru>
AnnaShaleva
left a comment
There was a problem hiding this comment.
LGTM. The code is compatible with NeoGo. Let's merge this PR firstly, it contains optimisations only, and then we'll rebase the #571 onto fresh master.
@neo-project/core please, review.
|
I'm testing data compatibility... |
superboyiii
left a comment
There was a problem hiding this comment.
@AnnaShaleva @Turalchik Data is compatible.
shargon
left a comment
There was a problem hiding this comment.
@AnnaShaleva is this required for 3.10.1?
Not strictly required. But I'd suggest to include it to v3.10.1 to proceed with dynamic opcodes step-by step. This PR doesn't contain any incompatible changes. |
|
Merge? Then we can begin to release vm. |
Yes. |
|
@shargon could you merge? |
|
In my opinion this should wait to next release, it's not critical and it's related to dynamic prices |
|
I believe this PR should be merged for N4 only, and battle tested for 3.11.0 together with dynamic opcodes price |
|
VM v3.10.1 is released, it's good to merge now. |
C# VM <= 3.10.1 checks the parameter first and then looks into the stack (checking its length), this means that ROLL(0) is effectively NOP in that it can work even with empty stack. C# master (with neo-project/neo-vm#575) is the same as NeoGo, so we have no reason to change the behavior as well. Add a test similar to neo-project/neo-vm#589. Reported-by: Majid Mohammed <majidcoderlun3x@gmail.com> Signed-off-by: Roman Khimov <roman@nspcc.ru>
This pull request brings the asymptotic complexity of the opcodes closer to https://github.com/nspcc-dev/neo-go. Basically, this PR presents refcounting optimizations in opcodes, in which items are removed from the stack, which shortly after that will be there on the stack.