Open GoogleCodeExporter opened 8 years ago
Hi there,
thank you for taking the time comment! And my sincere apologies for responding
so late!
I'm afraid the fine-grained parsing of the type info is just not possible due
to the way a SWF is serialized.
It will always be necessary to parse the entire constant pool at the start of
the SWF, otherwise there will be no context for the indexes that are read in
the rest of the file, so that is already a step we can't skip.
After that, it isn't so straightforward to just parse out one class. The way
that this info is layed out internally isn't the way that you would expect it
initially. A class isn't serialzied into one continuous block of bytecode I'm
afraid. First ALL the mehods of ALL classes are serialized, then all of the
metadata, after that the instance infos/traits, class infos/traits, script
infos/traits and finally all of the method bodies and exception infos.
All fo these blocks do not have any boundary information stored. I.e. at the
beginning of a block of class info it doesn't tell me how LONG this block is.
Therefore I can't conveniently skip over parts. Event if I know the number of
U30 entries in the next block of bytearray, I will still need to parse them all
since U30 is of variable length in the bytearray.
So, in order to parse out all of the offsets it would require me to parse the
entire file, hence negating the benefit of storing these offsets.
The largest part of the, memory wise, of the type info is of course the
constantpool, but I'm afraid I need to parse this one completely as well for
the same reasons.
The SWF format was designed to store information as efficiently as possible,
which makes it a lot harder to progressively parse...
Storing the entries as SoftReferences will also yield strange results, what if
you request a piece of typeinfo, then request it again sometime later in the
application lifecycle and its gone all of a sudden?
One of the developers on the as3commons team is experimenting with adding a bit
of Alchemy magic to the parsing process, this way the parsing step will become
as efficient as possible.
Also, do note that the parsing steps take quite a bit longer in the debug
player and while parsing a SWF that is compiled in debug mode. Try testing it
in a regular player with a release build of your code and you will probably
notice a significant increase in parsing speeds.
Your last comment does make sense actually, it will not be easy to implement
but if I find the time somewhere in the near future I will try to look into
implementing some kind of green threading in order to be able to prevent the
application from freezing while parsing the bytecode.
cheers!
Roland
Original comment by ihatelivelyids
on 29 Jun 2011 at 6:49
Roland, thanks for the detailed reply.
I understand the kinds of issues you describe. That is shame, however, because
it can make using org.as3commons.reflect.bytecode.* untenable in larger
projects (because it takes so much time/memory to parse/store the typeinfo).
Parsing asynchronously would at least help with keeping the app responsive, but
use of the typeinfo would still be delayed (which could still be an issue).
One of my biggest problems, for example, is that I use
ByteCodeType.fromLoader() and ByteCodeType.getClassesWithMetadata() at startup
to obtain a list of special classes. However, this makes my large project take
FOREVER to start. Okay, it doesn't take forever :), but running under the
profiler is every more painful... there, startup takes *minutes* as thousands
and thousands and thousands of strings/objects are allocated while all the
typeinfo is built).
Is there a more efficient way to simply obtain a list of tagged classes that I
could use? If not, since such a class list is so useful, perhaps you could
consider creating a special-purpose faster/smaller parse for just this one
common/useful task? If there were an efficient way to obtain even just the
complete class list, I would then perhaps look up the metadata tags using the
non-bytecode org.as3commons.reflect.* APIs (which can do so much more
efficiently).
Thanks,
- Matt
Re: memory usage. Would you consider providing an option to selectively purge
things from the cache (for example, when the client knows they will never be
needed). Perhaps some kind of include/exclude filter specification (e.g., keep
everything parsed for "com.mystuff.*", but purge other stuff).
Re: weak references. What I meant of course was that the metadata would simply
be reparsed when it fell out of memory and was needed again later (and this
process would be transparent to the library client). But, as you've explained,
"progressively" and/or "selectively" parsing the SWF format is difficult.
Original comment by idontneedthisacct@gmail.com
on 21 Jul 2011 at 2:03
Hey,
if you just want the metadata info then I suggest you use
ByteCodeType.metadataLookupFromLoader(), this will do exactly what you suggest.
It only deserializes the constantpool and constructs the lookup for
metadata->classnames. You can use the 'normal' reflection functionality on
those classnames.
Its described here:
http://www.as3commons.org/as3-commons-bytecode/introduction.html
Under the header 'metadata scan'.
This is indeed quite a bit faster than doing the full bytecode reflection.
Someone on the as3commons team is also experimenting with some Apparat/Alchemy
optimizations which will speed up the process a bit more. I'm not sure when
that'll be finished though.
My *real* hope actually is that Adobe will some day implement *proper*
reflection in the Flash player. From that day on we can ditch the bytecode
reflection alltogether. But you know, we'll have to wait and pray I guess...
I'm sure there's already JIRA tickets opened for that, I suggest you look them
up and vote for them. (Every vote counts! :))
I'm also thinking of re-writing a bit of the bytecode reflection to use the
constantpool for string lookup. Now for every type every string is looked up in
the constantpool and copied into the instance. I guess passing in an instance
of the constantpool and having each string looked up at runtime could safe a
massive amount of memory...
Hmmm, lots of things to consider... So little time...
cheers,
Roland
Original comment by ihatelivelyids
on 21 Jul 2011 at 8:31
Thanks Roland, ByteCodeType.metadataLookupFromLoader() is indeed faster.
But, now I am faced with the problem of the limitations of the "normal"
typeinfo accessed via plain old Type instances... they do not expose method
argument names or default values. Only ByteCodeType can supply that
information. :( That is why I wanted to be able to selectively parse only the
classes/methods I was interested in... I want efficient access to typeinfo,
but also need stuff that only ByteCodeType can provide.
Re: memory usage. Yes, if there is currently any "wasteful" duplication of
strings (or other data) when parsing typeinfo, then please by all means
consider adding some kind of "coalescing" to reduce the memory footprint (it
would probably also speed things up). When I call ByteCodeType.fromLoader() in
my large project, an *amazing* amount of memory is allocated. ;)
If nothing can be done about the need to parse/store *all* typeinfo when using
ByteCodeType, then more efficient memory usage and asynchronous parsing (as
mentioned previously) would help make things palatable for large, real-world
projects. The ByteCodeType stuff is very, very cool... but the current
implementation can be somewhat impractical for some purposes.
Thanks,
- Matt
Original comment by idontneedthisacct@gmail.com
on 23 Jul 2011 at 2:27
Original comment by mastakan...@gmail.com
on 11 Sep 2011 at 6:24
Original comment by martin.h...@gmail.com
on 12 Sep 2011 at 6:13
Hi there,
I've been busy optimizing the bytecodetype parsing. I think I've managed to
signficantly speed it up. I'm not finished yet, I still think there's plenty of
opportunity to tweak it further, but perhaps you can give it a testdrive and
see if you notice the difference.
The changes are currently only available in the trunk.
Cheers,
Roland
Original comment by ihatelivelyids
on 13 Sep 2011 at 11:14
This is great, thanks for doing some work on this! Sorry, I haven't had time
to try it out yet. Is the new code available in .swc form yet?
Original comment by idontneedthisacct@gmail.com
on 26 Sep 2011 at 6:17
its part of the 1.0 release, you yes, its available for download here:
http://www.as3commons.org/as3-commons-bytecode/index.html
cheers,
Roland
Original comment by rol...@stackandheap.com
on 26 Sep 2011 at 6:46
Original issue reported on code.google.com by
idontneedthisacct@gmail.com
on 27 May 2011 at 10:03