New issue
Advanced search Search tips

Issue 770266 link

Starred by 1 user

Issue metadata

Status: Fixed
Owner:
Closed: Oct 2017
Cc:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug

Blocking:
issue 341941



Sign in to add a comment

Avoid allocating std::string objects for string constants

Project Member Reported by brucedaw...@chromium.org, Sep 29 2017

Issue description

While running tools\win\static_initializers\static_initializers.exe on chrome.dll (canary, 64-bit) I saw the following reports:

obj/components/viz/service/service/shader.obj: `viz::FragmentShader::SetBlendModeFunctions'::`2'::`dynamic atexit destructor for 'kFunctionApplyBlendMode''
obj/components/viz/service/service/shader.obj: `viz::FragmentShader::GetHelperFunctions'::`2'::`dynamic atexit destructor for 'kFunctionColorBurnComponent''
obj/components/viz/service/service/shader.obj: `viz::FragmentShader::GetHelperFunctions'::`2'::`dynamic atexit destructor for 'kFunctionColorDodgeComponent''
obj/components/viz/service/service/shader.obj: `viz::FragmentShader::GetHelperFunctions'::`2'::`dynamic atexit destructor for 'kFunctionHardLight''
obj/components/viz/service/service/shader.obj: `viz::FragmentShader::GetHelperFunctions'::`2'::`dynamic atexit destructor for 'kFunctionLum''
obj/components/viz/service/service/shader.obj: `viz::FragmentShader::GetHelperFunctions'::`2'::`dynamic atexit destructor for 'kFunctionSat''
obj/components/viz/service/service/shader.obj: `viz::FragmentShader::GetHelperFunctions'::`2'::`dynamic atexit destructor for 'kFunctionSoftLightComponentPosDstAlpha''
obj/components/viz/service/service/shader.obj: `viz::FragmentShader::SetBlendModeFunctions'::`2'::`dynamic atexit destructor for 'kUniforms''

This is because StripLambda returns an std::string object. This is allocated when the helper functions are called the first time and then destroyed at process shutdown. This clearly wastes code size, and causes extra memory allocations. Is it possible to use StringPiece instead to avoid the extra code and data copying? Maybe throw in some constexpr for good measure.

 
I noticed that this was inefficient. I have a CL from a few weeks ago that removes them:
https://chromium-review.googlesource.com/c/chromium/src/+/648289

But I never sent it out because I hadn't noticed the (pre-existing) static destructors, and the APK size change (which is what I'd been aiming at while poking at that file) was small relative to the somewhat uglifying it.

I suppose I could send it out for review, if you think it's an improvement.
I think it would be worth completing. I think a full solution should use constexpr if possible to ensure that the static constructors go away. VS 2017 (required on Windows now) should make this easier.
Using constexpr is presently inconvenient, because we'd need a number of StringPiece operations to be constexpr, and these presently rely on std::char_traits (to get length, to compare string ranges, etc.), which isn't constexpr until C++17. (And this change hasn't even made it to our bleeding-edge libc++ yet, let alone other implementations.)

We can reimplement a bunch of those operations by hand for constexpr, but it'd be busywork and might even conceivably break the compiler's ability to use efficient memcmp where appropriate.

In practice compilers (at least clang and MSVC, in my experience) generally optimize away this sort of thing even without the constexpr help, but it would be nice to have an assurance.
Okay, good information. constexpr can indeed be tough to use in some places.
Urgh, nope, MSVC is being uncooperative. Can do constexpr to save the initializers at the cost of having to avoid measuring the length of the string using std::char_traits. :s
To be clear, MSVC -- at least on godbolt.org -- generates initializers in cases where it should be doable at compile time, unless I use constexpr.
Yes, I've definitely noticed that. In particular I'm trying to land crrev.com/c/696190 which will avoid >170 static initializers, and all my change does is add constexpr.
Blocking: 341941
Project Member

Comment 9 by bugdroid1@chromium.org, Oct 10 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/40a4dc1ee61b9ff8f531ceedaa9e895ca8d820f6

commit 40a4dc1ee61b9ff8f531ceedaa9e895ca8d820f6
Author: Jeremy Roman <jbroman@chromium.org>
Date: Tue Oct 10 18:04:47 2017

viz: Refactor FragmentShader to construct fewer std::strings.

Should be more efficient at runtime, and saves 8 kB of Android APK size.
This should also eliminate some static destructors for these strings.

Bug:  770266 ,341941
Change-Id: Idb471aa6f22288865ed80b0089c48ad7f8acbe65
Reviewed-on: https://chromium-review.googlesource.com/648289
Commit-Queue: Jeremy Roman <jbroman@chromium.org>
Reviewed-by: weiliangc <weiliangc@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Bruce Dawson <brucedawson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#507714}
[modify] https://crrev.com/40a4dc1ee61b9ff8f531ceedaa9e895ca8d820f6/base/strings/string_piece.h
[modify] https://crrev.com/40a4dc1ee61b9ff8f531ceedaa9e895ca8d820f6/components/viz/service/display/shader.cc
[modify] https://crrev.com/40a4dc1ee61b9ff8f531ceedaa9e895ca8d820f6/components/viz/service/display/shader.h

Status: Fixed (was: Untriaged)
Owner: jbroman@chromium.org

Sign in to add a comment