Skip to content

Optimize UnresolvedAVM2Item.resolve for replaceAS3 of very large files - #266

Open
NutchapolSal wants to merge 7 commits into
jindrapetrik:devfrom
NutchapolSal:optimize-avm2-resolve
Open

Optimize UnresolvedAVM2Item.resolve for replaceAS3 of very large files#266
NutchapolSal wants to merge 7 commits into
jindrapetrik:devfrom
NutchapolSal:optimize-avm2-resolve

Conversation

@NutchapolSal

@NutchapolSal NutchapolSal commented Jun 21, 2026

Copy link
Copy Markdown

redo of #265 but merging into the correct branch this time

A game I'm modding has an extremely large MainTimeline AS3 file, compiling the file takes minutes each time. Using VisualVM sampler, I found places that needed optimizations and implemented them.

Changes:

  • optimized AVM2SourceGenerator.searchPrototypeChain by memoizing the entire call to abc.findProperty
  • change DottedChain.parseWithSuffix and addWithSuffix to use a pre-compiled regex
  • refactor UnresolvedAVM2Item.resolve into multiple private functions (helps in pin-pointing where performance problem is in VisualVM). they're named resolve1 to resolve10 for now
  • add classes for storing data and precomputed hash maps for optimizing across resolve calls
  • optimized UnresolvedAVM2Item.resolve1 using a precomputed hash map
  • optimized PropertyAVM2Item.resolve by refactoring parts of it into individual functions and memoizing name index lookup. (interestingly, just refactoring the loopobjType for loop into its own function with a custom return value class already cuts down the runtime by half without any other optimizations.)

Results:
I've tested on two different SWFs and scripts
First one ActionScript3Parser.compile total time from 65.8s to 6.6s
Second ActionScript3Parser.compile total time from 268.2 to 19.4s

also a question, Is having an inner class like UnresolvedAVM2Item.ResolveAccelerator fine? or should it be in a separate file instead? note that PropertyAVM2Item also has its own ResolveAccelerator

@jindrapetrik

Copy link
Copy Markdown
Owner

Thank you for your contribution.

I think there can be a problem in searchPrototypeChain.
This is(was) a static method with no inner state.
If you add caching, you need to ensure that it is cached only on the current script compilation and not interfere with any previous compilations.
Let's say you edit script A on step 1, then on saving, the calls to searchPrototypeChain are cached (e.g. resolving property on script B),
but then you want to edit script B, change it, but the searchPrototypeChain calls are cached from previous editation. This may lead to incorrect handling of properties.
In other words: There should be a way to invalidate the cache. And it should happen probably on each script compilation.

Other way could be to searchPrototypeChain to be not static, but that would require to put the correct AVM2SourceGenerator object to all its calls (?).

This is also reason why I did not merge your previous PR.
Please try to figure it out somehow.

And for the ResolveAccelerator: I think it is okay to have it the same file.

@NutchapolSal

Copy link
Copy Markdown
Author

I think it'll be a while until I can get back to working on this.
And about the static abcFindPropertyCache, maybe it should be a property on AbcIndexing or ABC instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants