|
|
Created:
4 years, 5 months ago by dcheng Modified:
4 years, 5 months ago CC:
chromium-reviews, qsr+mojo_chromium.org, viettrungluu+watch_chromium.org, yzshen+watch_chromium.org, abarth-chromium, Aaron Boodman, darin (slow to review), ben+mojo_chromium.org, danakj Base URL:
https://chromium.googlesource.com/chromium/src.git@master Target Ref:
refs/pending/heads/master Project:
chromium Visibility:
Public. |
DescriptionUpdate mojo typemaps for base::Time* to pass by value.
BUG=none
Committed: https://crrev.com/7476fad831f6699a58ad1577ddfcec9c325228f6
Cr-Commit-Position: refs/heads/master@{#406232}
Patch Set 1 #
Total comments: 3
Patch Set 2 : . #
Messages
Total messages: 27 (6 generated)
dcheng@chromium.org changed reviewers: + erikchen@chromium.org, yzshen@chromium.org
+yzshen for //mojo +erikchen for //components This is (allegedly) the recommended way of passing around base::Time values, though it's passed by const reference a bunch too. To CCed base owners... do we even care? Is this worth the trouble? I compared the disassembly in release build and it's very similar a lot of the times. Sometimes the by-value version is a shorter assembly block, sometimes the by-ref version is shorter. It does look like the compiler is typically smart enough to store the by-value version directly in a register, whereas by-ref does incur one dereference, e.g.: mov (%rbx),%rsi vs mov %rbx,%rsi https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... File mojo/common/common_custom_types_unittest.cc (right): https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... mojo/common/common_custom_types_unittest.cc:60: }; I could make this more clever, but it didn't seem worth the effort (unless there's some mojo trait emitted in the bindings that I can use?)
Description was changed from ========== Update mojo typemaps for base::Time* to pass by value. BUG=none ========== to ========== Update mojo typemaps for base::Time* to pass by value. BUG=none ==========
(Fixed //base owners CC: please see my question in reply #1. Thanks!)
components/startup_metric_utils lgtm
https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... File mojo/common/common_custom_types.typemap (right): https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... mojo/common/common_custom_types.typemap:20: "mojo.common.mojom.Time=base::Time[pass_by_value]", I am planning to replace "pass_by_value" with "move_only". This change conflicts with that. The reason is explained in: https://docs.google.com/document/d/1dutUW6XUlbSJzsqmtmPnN-J7R8z-iEL-QJ_GR9hWK... In short, “pass_by_value” is not transitive. You want to pass TrivialStruct by value doesn’t necessarily mean that you want to pass std::vector<TrivialStruct> by value. On the other hand, "move_only" is transitive. It seems simpler to use "move_only" and apply the following rule consistently: pass primitive types and move-only types by value; pass other types by const ref.
https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... File mojo/common/common_custom_types.typemap (right): https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... mojo/common/common_custom_types.typemap:20: "mojo.common.mojom.Time=base::Time[pass_by_value]", On 2016/07/08 15:42:01, yzshen1 wrote: > I am planning to replace "pass_by_value" with "move_only". This change conflicts > with that. > > The reason is explained in: > https://docs.google.com/document/d/1dutUW6XUlbSJzsqmtmPnN-J7R8z-iEL-QJ_GR9hWK... > > In short, “pass_by_value” is not transitive. You want to pass TrivialStruct by > value doesn’t necessarily mean that you want to pass std::vector<TrivialStruct> > by value. On the other hand, "move_only" is transitive. It seems simpler to use > "move_only" and apply the following rule consistently: pass primitive types and > move-only types by value; pass other types by const ref. It seems unfortunate that we'll actively encourage people to go against the guidance to pass base::Time* types by value. There's some inconsistency in the codebase today (since this is something people often miss), but here's the breakdown today: base::Time: 155 by value, 199 by const ref base::TimeDelta: 505 by value, 237 by const ref base::TimeTicks: 328 by value, 258 by const ref What would be the harm in just s/pass_by_value/move_only in this CL? I guess it would cause some structs encapsulating this to be treated as move-only as well?
On 2016/07/08 16:21:45, dcheng wrote: > https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... > File mojo/common/common_custom_types.typemap (right): > > https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... > mojo/common/common_custom_types.typemap:20: > "mojo.common.mojom.Time=base::Time[pass_by_value]", > On 2016/07/08 15:42:01, yzshen1 wrote: > > I am planning to replace "pass_by_value" with "move_only". This change > conflicts > > with that. > > > > The reason is explained in: > > > https://docs.google.com/document/d/1dutUW6XUlbSJzsqmtmPnN-J7R8z-iEL-QJ_GR9hWK... > > > > In short, “pass_by_value” is not transitive. You want to pass TrivialStruct by > > value doesn’t necessarily mean that you want to pass > std::vector<TrivialStruct> > > by value. On the other hand, "move_only" is transitive. It seems simpler to > use > > "move_only" and apply the following rule consistently: pass primitive types > and > > move-only types by value; pass other types by const ref. > > It seems unfortunate that we'll actively encourage people to go against the > guidance to pass base::Time* types by value. There's some inconsistency in the > codebase today (since this is something people often miss), but here's the > breakdown today: > > base::Time: 155 by value, 199 by const ref > base::TimeDelta: 505 by value, 237 by const ref > base::TimeTicks: 328 by value, 258 by const ref > > What would be the harm in just s/pass_by_value/move_only in this CL? I guess it > would cause some structs encapsulating this to be treated as move-only as well? Right. That way we will consider std::vector<base::Time> "move-only" and pass it by value. void SomeMojoInterface(std::vector<base::Time> times); The caller may accidentally make a copy if they call the method this way: std::vector<base::Time> times; SomeMojoInterface(times);
On 2016/07/08 16:24:27, yzshen1 wrote: > On 2016/07/08 16:21:45, dcheng wrote: > > > https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... > > File mojo/common/common_custom_types.typemap (right): > > > > > https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... > > mojo/common/common_custom_types.typemap:20: > > "mojo.common.mojom.Time=base::Time[pass_by_value]", > > On 2016/07/08 15:42:01, yzshen1 wrote: > > > I am planning to replace "pass_by_value" with "move_only". This change > > conflicts > > > with that. > > > > > > The reason is explained in: > > > > > > https://docs.google.com/document/d/1dutUW6XUlbSJzsqmtmPnN-J7R8z-iEL-QJ_GR9hWK... > > > > > > In short, “pass_by_value” is not transitive. You want to pass TrivialStruct > by > > > value doesn’t necessarily mean that you want to pass > > std::vector<TrivialStruct> > > > by value. On the other hand, "move_only" is transitive. It seems simpler to > > use > > > "move_only" and apply the following rule consistently: pass primitive types > > and > > > move-only types by value; pass other types by const ref. > > > > It seems unfortunate that we'll actively encourage people to go against the > > guidance to pass base::Time* types by value. There's some inconsistency in the > > codebase today (since this is something people often miss), but here's the > > breakdown today: > > > > base::Time: 155 by value, 199 by const ref > > base::TimeDelta: 505 by value, 237 by const ref > > base::TimeTicks: 328 by value, 258 by const ref > > > > What would be the harm in just s/pass_by_value/move_only in this CL? I guess > it > > would cause some structs encapsulating this to be treated as move-only as > well? > > Right. That way we will consider std::vector<base::Time> "move-only" and pass it > by value. > > void SomeMojoInterface(std::vector<base::Time> times); > > The caller may accidentally make a copy if they call the method this way: > > std::vector<base::Time> times; > SomeMojoInterface(times); Supporting both attributes "pass_by_value" and "move_only" is another option, but I feel that the benefit doesn't outweigh the confusion it causes. WDYT?
On 2016/07/08 16:25:48, yzshen1 wrote: > On 2016/07/08 16:24:27, yzshen1 wrote: > > On 2016/07/08 16:21:45, dcheng wrote: > > > > > > https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... > > > File mojo/common/common_custom_types.typemap (right): > > > > > > > > > https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... > > > mojo/common/common_custom_types.typemap:20: > > > "mojo.common.mojom.Time=base::Time[pass_by_value]", > > > On 2016/07/08 15:42:01, yzshen1 wrote: > > > > I am planning to replace "pass_by_value" with "move_only". This change > > > conflicts > > > > with that. > > > > > > > > The reason is explained in: > > > > > > > > > > https://docs.google.com/document/d/1dutUW6XUlbSJzsqmtmPnN-J7R8z-iEL-QJ_GR9hWK... > > > > > > > > In short, “pass_by_value” is not transitive. You want to pass > TrivialStruct > > by > > > > value doesn’t necessarily mean that you want to pass > > > std::vector<TrivialStruct> > > > > by value. On the other hand, "move_only" is transitive. It seems simpler > to > > > use > > > > "move_only" and apply the following rule consistently: pass primitive > types > > > and > > > > move-only types by value; pass other types by const ref. > > > > > > It seems unfortunate that we'll actively encourage people to go against the > > > guidance to pass base::Time* types by value. There's some inconsistency in > the > > > codebase today (since this is something people often miss), but here's the > > > breakdown today: > > > > > > base::Time: 155 by value, 199 by const ref > > > base::TimeDelta: 505 by value, 237 by const ref > > > base::TimeTicks: 328 by value, 258 by const ref > > > > > > What would be the harm in just s/pass_by_value/move_only in this CL? I guess > > it > > > would cause some structs encapsulating this to be treated as move-only as > > well? > > > > Right. That way we will consider std::vector<base::Time> "move-only" and pass > it > > by value. > > > > void SomeMojoInterface(std::vector<base::Time> times); > > > > The caller may accidentally make a copy if they call the method this way: > > > > std::vector<base::Time> times; > > SomeMojoInterface(times); > > > Supporting both attributes "pass_by_value" and "move_only" is another option, > but I feel that the benefit doesn't outweigh the confusion it causes. WDYT? Let's see how the other //base OWNERS feel. I personally think this is useful: in the scheme of things, it's not going to make a huge difference, but when we can be efficient, we should: there are other pass by value things in Chrome too, like StringPiece (though probably not over IPC) and cc::SurfaceId. How complex is it to keep supporting this alongside move_only in the Mojo bindings?
On 2016/07/08 17:26:38, dcheng wrote: > On 2016/07/08 16:25:48, yzshen1 wrote: > > On 2016/07/08 16:24:27, yzshen1 wrote: > > > On 2016/07/08 16:21:45, dcheng wrote: > > > > > > > > > > https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... > > > > File mojo/common/common_custom_types.typemap (right): > > > > > > > > > > > > > > https://codereview.chromium.org/2131773003/diff/1/mojo/common/common_custom_t... > > > > mojo/common/common_custom_types.typemap:20: > > > > "mojo.common.mojom.Time=base::Time[pass_by_value]", > > > > On 2016/07/08 15:42:01, yzshen1 wrote: > > > > > I am planning to replace "pass_by_value" with "move_only". This change > > > > conflicts > > > > > with that. > > > > > > > > > > The reason is explained in: > > > > > > > > > > > > > > > https://docs.google.com/document/d/1dutUW6XUlbSJzsqmtmPnN-J7R8z-iEL-QJ_GR9hWK... > > > > > > > > > > In short, “pass_by_value” is not transitive. You want to pass > > TrivialStruct > > > by > > > > > value doesn’t necessarily mean that you want to pass > > > > std::vector<TrivialStruct> > > > > > by value. On the other hand, "move_only" is transitive. It seems simpler > > to > > > > use > > > > > "move_only" and apply the following rule consistently: pass primitive > > types > > > > and > > > > > move-only types by value; pass other types by const ref. > > > > > > > > It seems unfortunate that we'll actively encourage people to go against > the > > > > guidance to pass base::Time* types by value. There's some inconsistency in > > the > > > > codebase today (since this is something people often miss), but here's the > > > > breakdown today: > > > > > > > > base::Time: 155 by value, 199 by const ref > > > > base::TimeDelta: 505 by value, 237 by const ref > > > > base::TimeTicks: 328 by value, 258 by const ref > > > > > > > > What would be the harm in just s/pass_by_value/move_only in this CL? I > guess > > > it > > > > would cause some structs encapsulating this to be treated as move-only as > > > well? > > > > > > Right. That way we will consider std::vector<base::Time> "move-only" and > pass > > it > > > by value. > > > > > > void SomeMojoInterface(std::vector<base::Time> times); > > > > > > The caller may accidentally make a copy if they call the method this way: > > > > > > std::vector<base::Time> times; > > > SomeMojoInterface(times); > > > > > > Supporting both attributes "pass_by_value" and "move_only" is another option, > > but I feel that the benefit doesn't outweigh the confusion it causes. WDYT? > > Let's see how the other //base OWNERS feel. I personally think this is useful: > in the scheme of things, it's not going to make a huge difference, but when we > can be efficient, we should: there are other pass by value things in Chrome too, > like StringPiece (though probably not over IPC) and cc::SurfaceId. How complex > is it to keep supporting this alongside move_only in the Mojo bindings? The cost is mostly at the user side. They need to learn the difference between the two. Could you point me to the guideline of passing trivial structs by value? I don't think we are doing it consistently across the code base. For example, cc::SurfaceId has three data fields (two 32-bit and one 64-bit). I am pretty sure in our code base we pass many other structs with the same amount of data (or less) by const ref.
On 2016/07/08 17:37:23, yzshen1 wrote: > On 2016/07/08 17:26:38, dcheng wrote: > > Let's see how the other //base OWNERS feel. I personally think this is useful: > > in the scheme of things, it's not going to make a huge difference, but when we > > can be efficient, we should: there are other pass by value things in Chrome > too, > > like StringPiece (though probably not over IPC) and cc::SurfaceId. How complex > > is it to keep supporting this alongside move_only in the Mojo bindings? > > The cost is mostly at the user side. They need to learn the difference between > the two. > > Could you point me to the guideline of passing trivial structs by value? > I don't think we are doing it consistently across the code base. For example, > cc::SurfaceId has three data fields (two 32-bit and one 64-bit). I am pretty > sure in our code base we pass many other structs with the same amount of data > (or less) by const ref. I don't have strong feelings about this. My opinion is prefer passing by value, but if it's too much trouble, then don't stress out about it. Developers should be familiar with base/ classes and just have to remember StringPiece and Time* prefer passing by value, in the same way that English has some special spelling/grammar rules, and one just have to remember them. OTOH, not every developer works with cc/, so I wouldn't expect everyone to know that cc::SurfaceId prefers passing by value.
On 2016/07/08 19:13:02, Lei Zhang wrote: > On 2016/07/08 17:37:23, yzshen1 wrote: > > On 2016/07/08 17:26:38, dcheng wrote: > > > Let's see how the other //base OWNERS feel. I personally think this is > useful: > > > in the scheme of things, it's not going to make a huge difference, but when > we > > > can be efficient, we should: there are other pass by value things in Chrome > > too, > > > like StringPiece (though probably not over IPC) and cc::SurfaceId. How > complex > > > is it to keep supporting this alongside move_only in the Mojo bindings? > > > > The cost is mostly at the user side. They need to learn the difference between > > the two. > > > > Could you point me to the guideline of passing trivial structs by value? > > I don't think we are doing it consistently across the code base. For example, > > cc::SurfaceId has three data fields (two 32-bit and one 64-bit). I am pretty > > sure in our code base we pass many other structs with the same amount of data > > (or less) by const ref. > > I don't have strong feelings about this. My opinion is prefer passing by value, > but if it's too much trouble, then don't stress out about it. > > Developers should be familiar with base/ classes and just have to remember > StringPiece and Time* prefer passing by value, in the same way that English has > some special spelling/grammar rules, and one just have to remember them. OTOH, > not every developer works with cc/, so I wouldn't expect everyone to know that > cc::SurfaceId prefers passing by value. Drive-by comment: SurfaceId used to be smaller so it was passed by value. In the future, we may change that if there's a performance benefit. I just didn't see sufficient cause to go out of my way to update all parameter passing sites.
I don't think it's super important, but this looks like a good change to me.
Thanks for all the input. Although the change itself is a good change, my main concern is that it requires more complexity in mojo typemap configuration which increases developers' learning cost. As I said above, in order to support pass-by-value Time*, we will need to support both "pass_by_value" and "move_only" attributes in mojo typemap configuration: - "pass_by_value": the type T should be passed by value but a collection of such type (such as std::vector<T>) shouldn't be passed by value. - "move_only" (or maybe name it "transitively_pass_by_value" to be more consistent): the type T should be passed by value; this property is transitive -- any type containing T should also be passed by value as well. Comparing with this, I personally prefer the simpler solution: support only "move_only" attribute and apply the following rule: Mojo-generated interfaces always pass primitive types and move-only types by value; pass the rest by const ref. It means we will pass Time* by const ref, but the configuration is easier to understand. WDYT? Thanks!
On 2016/07/12 18:03:21, yzshen1 wrote: > Thanks for all the input. > > Although the change itself is a good change, my main concern is that it requires > more complexity in mojo typemap configuration which increases developers' > learning cost. > > As I said above, in order to support pass-by-value Time*, we will need to > support both "pass_by_value" and "move_only" attributes in mojo typemap > configuration: > - "pass_by_value": the type T should be passed by value but a collection of such > type (such as std::vector<T>) shouldn't be passed by value. > - "move_only" (or maybe name it "transitively_pass_by_value" to be more > consistent): the type T should be passed by value; this property is transitive > -- any type containing T should also be passed by value as well. > > Comparing with this, I personally prefer the simpler solution: support only > "move_only" attribute and apply the following rule: Mojo-generated interfaces > always pass primitive types and move-only types by value; pass the rest by const > ref. It means we will pass Time* by const ref, but the configuration is easier > to understand. > > WDYT? Thanks! I don't think there's going to be that much confusion about pass_by_value vs move_only. There are already other situations where we store pass-by-value types like integers in array<>, and I'm not aware of that causing confusion elsewhere. Most things are going to use the default or move_only anyway.
On 2016/07/13 12:10:59, dcheng wrote: > On 2016/07/12 18:03:21, yzshen1 wrote: > > Thanks for all the input. > > > > Although the change itself is a good change, my main concern is that it > requires > > more complexity in mojo typemap configuration which increases developers' > > learning cost. > > > > As I said above, in order to support pass-by-value Time*, we will need to > > support both "pass_by_value" and "move_only" attributes in mojo typemap > > configuration: > > - "pass_by_value": the type T should be passed by value but a collection of > such > > type (such as std::vector<T>) shouldn't be passed by value. > > - "move_only" (or maybe name it "transitively_pass_by_value" to be more > > consistent): the type T should be passed by value; this property is transitive > > -- any type containing T should also be passed by value as well. > > > > Comparing with this, I personally prefer the simpler solution: support only > > "move_only" attribute and apply the following rule: Mojo-generated interfaces > > always pass primitive types and move-only types by value; pass the rest by > const > > ref. It means we will pass Time* by const ref, but the configuration is easier > > to understand. > > > > WDYT? Thanks! > > I don't think there's going to be that much confusion about pass_by_value vs > move_only. There are already other situations where we store pass-by-value types > like integers in array<>, and I'm not aware of that causing confusion elsewhere. > Most things are going to use the default or move_only anyway. Hmm.. Okay, let's try supporting this. :) I suggest renaming "pass_by_value" to something like "pass_by_value_copyable" to emphasize that this attribute and "move_only" are exclusive. WDYT?
On 2016/07/13 15:39:12, yzshen1 wrote: > On 2016/07/13 12:10:59, dcheng wrote: > > On 2016/07/12 18:03:21, yzshen1 wrote: > > > Thanks for all the input. > > > > > > Although the change itself is a good change, my main concern is that it > > requires > > > more complexity in mojo typemap configuration which increases developers' > > > learning cost. > > > > > > As I said above, in order to support pass-by-value Time*, we will need to > > > support both "pass_by_value" and "move_only" attributes in mojo typemap > > > configuration: > > > - "pass_by_value": the type T should be passed by value but a collection of > > such > > > type (such as std::vector<T>) shouldn't be passed by value. > > > - "move_only" (or maybe name it "transitively_pass_by_value" to be more > > > consistent): the type T should be passed by value; this property is > transitive > > > -- any type containing T should also be passed by value as well. > > > > > > Comparing with this, I personally prefer the simpler solution: support only > > > "move_only" attribute and apply the following rule: Mojo-generated > interfaces > > > always pass primitive types and move-only types by value; pass the rest by > > const > > > ref. It means we will pass Time* by const ref, but the configuration is > easier > > > to understand. > > > > > > WDYT? Thanks! > > > > I don't think there's going to be that much confusion about pass_by_value vs > > move_only. There are already other situations where we store pass-by-value > types > > like integers in array<>, and I'm not aware of that causing confusion > elsewhere. > > Most things are going to use the default or move_only anyway. > > Hmm.. Okay, let's try supporting this. :) I suggest renaming "pass_by_value" to > something like "pass_by_value_copyable" to emphasize that this attribute and > "move_only" are exclusive. WDYT? SGTM. Thanks!
Updated this to use copyable_pass_by_value. PTAL.
On 2016/07/19 05:37:23, dcheng wrote: > Updated this to use copyable_pass_by_value. PTAL. LGTM Thanks!
The CQ bit was checked by dcheng@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from erikchen@chromium.org Link to the patchset: https://codereview.chromium.org/2131773003/#ps20001 (title: ".")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/v2/patch-status/codereview.chromium.or...
Message was sent while issue was closed.
Description was changed from ========== Update mojo typemaps for base::Time* to pass by value. BUG=none ========== to ========== Update mojo typemaps for base::Time* to pass by value. BUG=none ==========
Message was sent while issue was closed.
Committed patchset #2 (id:20001)
Message was sent while issue was closed.
Description was changed from ========== Update mojo typemaps for base::Time* to pass by value. BUG=none ========== to ========== Update mojo typemaps for base::Time* to pass by value. BUG=none Committed: https://crrev.com/7476fad831f6699a58ad1577ddfcec9c325228f6 Cr-Commit-Position: refs/heads/master@{#406232} ==========
Message was sent while issue was closed.
Patchset 2 (id:??) landed as https://crrev.com/7476fad831f6699a58ad1577ddfcec9c325228f6 Cr-Commit-Position: refs/heads/master@{#406232} |