-
Notifications
You must be signed in to change notification settings - Fork 189
Allow dart protos to be sent through sendports (and therefore to other isolates) #450
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow dart protos to be sent through sendports (and therefore to other isolates) #450
Conversation
Decoded protos in Dart are represented in memory as instances of `GeneratedMessage` subclasses. The `GeneratedMessage` stores the field state in a `_FieldSet` and `UnknownFieldSet`. The `_FieldSet._meta` field points to a `BuilderInfo` object, which represents the metadata of the proto message. Sending this reference to `BuilderInfo` makes it hard to send dart protos to other isolates, because a) `BuilderInfo` hangs on to non-static closures, which cannot be sent to to other isolates atm b) Sending a transitive copy would copy the `BuilderInfo` object (and it's transitive closure). That can cause big waste of memory since an isolate would have this metadata possibly many times. To avoid these two issues, this CL does the following: * We replace `_FieldSet._meta` with a getter that accesses the `BuilderInfo` via the `_FieldSet._message.info_` getter. This getter is implemented in `GeneratedMessage` subclasses and reads from a static field. => We effectively replace a load of the `_meta` field with load + interface call + static field load. * To avoid performance regressions we avoid accessing the new `_FieldSet._meta` getter in the hot decoding loops. Instead we obtain this metadata once and pass it down to various methods that are part of decoding. * For similar reasons, we remove the `PbMap._entryBuilderInfo` field - which also refers to a `BuilderInfo`. Instead we obtain the neccessary map-specific `BuilderInfo` in the main decoder loop. This CL has to remove the 2 year long deprecated `PbMap.add()` functiondeprecated.
I had written something similar earlier - but gave up because it caused the benchmarks to get slower. Did you try this in the golem benchmarks? Edit: I see that you have gone out of your way to always have the BuilderInfo at hand instead of getting it. I guess that means the performance won't suffer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Yes, I started out with your change https://github.com/dart-lang/protobuf/pull/212/files. The main performance regression for that change was caused by calling the I've tried to hoist this load of The only downside is that I had to remove this deprecated
After this hoisting it seemed to no longer cause big regressions. |
Not sure that's really a downside :) |
@iinozemtsev Could you give this change a trial run in g3 to see if it causes any issues? |
@mkustermann unfortunately we don't yet have automated copy process between g3 and github for protos. I can try porting this manually later today |
Closing this PR since we only want critical bugfixes to land on NNBD PR: #452 |
Decoded protos in Dart are represented in memory as instances of
GeneratedMessage
subclasses. TheGeneratedMessage
stores the fieldstate in a
_FieldSet
andUnknownFieldSet
.The
_FieldSet._meta
field points to aBuilderInfo
object, whichrepresents the metadata of the proto message.
Having this reference to
BuilderInfo
makes it hard to send dartprotos to other isolates, because
a)
BuilderInfo
hangs on to non-static closures, which cannotbe sent to to other isolates atm
b) Sending a transitive copy would copy the
BuilderInfo
object (andit's transitive closure). That can cause big waste of memory
since an isolate would have this metadata possibly many times.
To avoid these two issues, this CL does the following:
We replace
_FieldSet._meta
with a getter that accesses theBuilderInfo
via the_FieldSet._message.info_
getter. This getteris implemented in
GeneratedMessage
subclasses and reads from astatic field.
=> We effectively replace a load of the
_meta
field with load +interface call + static field load.
To avoid performance regressions we avoid accessing the new
_FieldSet._meta
getter in the hot decoding loops. Instead weobtain this metadata once and pass it down to various methods that
are part of decoding.
For similar reasons, we remove the
PbMap._entryBuilderInfo
field - which also refers to a
BuilderInfo
. Instead we obtain theneccessary map-specific
BuilderInfo
in the main decoder loop.This CL has to remove the 2 year long deprecated
PbMap.add()
function.Closes #167