limit symbols exported when using --enable-mergelibs

when doing LTO and --enable-mergelibs, we can improve the effectiveness
of LTO by marking more code as internal to the merged library.

So introduce a new macro UNLESS_MERGELIBS, which we can wrap around
*_DLLPUBLIC annotations

Also introduced here is a script that can be run on a completed build to
determine which classes can be marked with this macro.

Change-Id: I73fb87c897489da53791277d0b66b01f884ba061
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89991
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel Grandin 2020-03-04 20:27:36 +02:00
parent cedc8a942e
commit 47b4ee1a1a
7 changed files with 619 additions and 4 deletions

View file

@ -0,0 +1,448 @@
Accelerator
B3dCamera
B3dTransformationSet
B3dViewport
BitmapMedianFilter
BitmapMonochromeMatrixFilter
BitmapPalette
BitmapPopArtFilter
BitmapSobelGreyFilter
CalendarField
CodeCompleteDataCache
ConvertChar
CurrencyBox
CurrencyFormatter
CursorWrapper
DateBox
DateField
DdeGetPutItem
DdeHotLink
DdeItem
DdeLink
DdeService
DdeTopic
DockingAreaWindow
DockingManager
DoubleCurrencyField
DoubleNumericField
E3dCompoundObject
E3dDefaultAttributes
E3dExtrudeObj
E3dPolygonObj
EditAbstractDialogFactory
EditUndo
EditUndoManager
EditViewCallbacks
EnhancedCustomShape
EnhancedCustomShape::FunctionParser
FileChangedChecker
FilterMatch
FixedBitmap
FixedHyperlink
FmDesignModeChangedHint
FmFormObj
FmFormPageImpl
FmXFormShell
FontSelectPattern
FontSizeNames
FontSubsetInfo
FormattedField::StaticFormatter
FormatterBase
FreetypeManager::IFSD_Equal
GroupBox
HelpLinker
Hunspell
Hunzip
INetMIMEMessage
INetMIMEMessageStream
ImageControl
ImplJobSetup
IndexerPreProcessor
IntroWindow
ListenerMultiplexerBase
LongCurrencyBox
LongCurrencyField
LongCurrencyFormatter
MenuToggleButton
MetaAction
MetaArcAction
MetaBmpAction
MetaBmpExScalePartAction
MetaBmpScaleAction
MetaBmpScalePartAction
MetaChordAction
MetaClipRegionAction
MetaEllipseAction
MetaFontAction
MetaGradientExAction
MetaISectRectClipRegionAction
MetaISectRegionClipRegionAction
MetaLayoutModeAction
MetaMapModeAction
MetaMoveClipRegionAction
MetaOverlineColorAction
MetaPieAction
MetaPixelAction
MetaPolyLineAction
MetaPolyPolygonAction
MetaPolygonAction
MetaPopAction
MetaPushAction
MetaRasterOpAction
MetaRefPointAction
MetaRoundRectAction
MetaTextAlignAction
MetaTextArrayAction
MetaTextColorAction
MetaTextFillColorAction
MetaTextLanguageAction
MetaTextLineColorAction
MetaWallpaperAction
MetafileAccessor
ModuleSizeExceeded
MoreButton
MultiListBox
MyThes
NativeNumberWrapper
NfCurrencyEntry
NotebookbarTabControlBase
NotifyEvent
NumericBox
NumericField
OFlowChainedText
OpenFileDropTargetListener
OpenGLFramebuffer
OpenGLZone
PackedTextureAtlasManager
PatternBox
PatternField
PatternFormatter
PhysicalFontFamily
PlaceEditDialog
Point
PrinterOptions
ProgressBar
QueueInfo
RenderList
SalData
SalInfoPrinter
SalPrinter
SalSystem
SbClassModuleObject
SbMethod
SbxInfo
SbxObject
SdrEmbedObjectLink
SdrGrafBlueItem
SdrGrafContrastItem
SdrGrafCropItem
SdrGrafGamma100Item
SdrGrafGreenItem
SdrGrafLuminanceItem
SdrGrafModeItem
SdrGrafRedItem
SdrGrafTransparenceItem
SdrMeasureField
SdrMeasureObj
SdrSignedPercentItem
SdrTextFixedCellHeightItem
SdrUndoPageMasterPage
SelectionListenerMultiplexer
SfxAllEnumItem
SfxDocumentInfoItem
SfxItemSetHint
SfxMetricItem
SfxNavigator
SfxObjectItem
SfxStatusListener
SfxStyleSheetModifiedHint
SfxTemplatePanelControl
SfxViewFrameItem
SgaObject
SkiaPackedSurfaceAtlasManager
SkiaZone
SpinButton
SpinListenerMultiplexer
Storage
SvParser<HtmlTokenId>::TokenStackType
SvParser<int>::TokenStackType
SvtBasePrintOptions
SvtPrintFileOptions
SvtPrinterOptions
Svx3DCloseBackItem
Svx3DCloseFrontItem
Svx3DNormalsKindItem
Svx3DPerspectiveItem
Svx3DShadeModeItem
Svx3DTextureKindItem
Svx3DTextureModeItem
Svx3DTextureProjectionXItem
Svx3DTextureProjectionYItem
SvxCurrencyToolBoxControl
SvxEditSourceAdapter
SvxGraphicObject
SvxMetricField
SvxPasswordDialog
SvxPropertySetInfoPool
SvxTPage
SvxTextRotateItem
SyntaxHighlighter::Tokenizer
SystemWindow::ImplData
TETextDataObject
TabDialog
TabPaneValue
TextListenerMultiplexer
Throbber
TimeBox
TimeFormatter
TreeEditListenerMultiplexer
TreeExpansionListenerMultiplexer
TreeSelectionListenerMultiplexer
UFlowChainedText
UnoEditControl
UnoWrapperBase
VCLXDateField
VCLXEdit
VCLXMenuBar
VCLXSpinField
ValueSet
VclAlignment
VclBin
VclBuilder::MenuAndId
VclBuilder::ParserState
VclBuilder::sortIntoBestTabTraversalOrder
VclDrawingArea
VclGrid
VclWindowEvent
VersionCompat
XMLDashStyleExport
XMLDashStyleImport
XMLGradientStyleExport
XMLGradientStyleImport
XMLHatchStyleExport
XMLHatchStyleImport
XMLImageStyle
XMLMarkerStyleExport
XMLMarkerStyleImport
XMLShapeStyleContext
accessibility::AccessibleEditableTextPara
accessibility::AccessibleParaManager
avmedia::MediaControlBase
avmedia::MediaFloater
basegfx::B2DTrapezoid
basegfx::B3DPoint
basegfx::B3DTuple
basegfx::BColorModifier
basegfx::BColorModifierStack
basegfx::BColorModifier_RGBLuminanceContrast
basegfx::BColorModifier_black_and_white
basegfx::BColorModifier_gamma
basegfx::BColorModifier_gray
basegfx::BColorModifier_invert
basegfx::BColorModifier_replace
basegfx::MinimalSystemDependentDataManager
basegfx::ODFGradientInfo
basegfx::RasterConverter3D
basegfx::SystemDependentDataHolder
basegfx::SystemDependentDataManager
basegfx::triangulator
canvas
char& std::vector<char, std::allocator<char> >
comphelper::IndexAccessIterator
comphelper::OAccessibleSelectionHelper
comphelper::OEventListenerHelper
comphelper::OPropertySetAggregationHelper
comphelper::OPropertyStateHelper
comphelper::OSequenceOutputStream
comphelper::OStatefulPropertySet
comphelper::OStreamSection
comphelper::OWeakEventListenerAdapter
comphelper::OWrappedAccessibleChildrenManager
comphelper::PropertyBag
comphelper::StillReadWriteInteraction
comphelper::service_decl::ServiceDecl::Factory
connectivity::sdbcx::IObjectCollection
connectivity::sdbcx::OGroup
connectivity::sdbcx::OKey
dbtools::param::ParameterWrapper
desktop::CallbackFlushHandler::CallbackData
dp_misc::AbortChannel
drawinglayer::animation::AnimationEntry
drawinglayer::animation::AnimationEntryFixed
drawinglayer::animation::AnimationEntryLinear
drawinglayer::animation::AnimationEntryList
drawinglayer::animation::AnimationEntryLoop
drawinglayer::attribute::FillGraphicAttribute
drawinglayer::attribute::FillHatchAttribute
drawinglayer::attribute::LineStartEndAttribute
drawinglayer::attribute::MaterialAttribute3D
drawinglayer::attribute::Sdr3DLightAttribute
drawinglayer::attribute::Sdr3DObjectAttribute
drawinglayer::attribute::SdrFillGraphicAttribute
drawinglayer::attribute::SdrGlowAttribute
drawinglayer::attribute::SdrLightingAttribute
drawinglayer::attribute::SdrLineAttribute
drawinglayer::attribute::SdrLineFillShadowAttribute3D
drawinglayer::attribute::SdrLineStartEndAttribute
drawinglayer::attribute::SdrSceneAttribute
drawinglayer::attribute::SdrShadowAttribute
drawinglayer::primitive2d::AnimatedBlinkPrimitive2D
drawinglayer::primitive2d::AnimatedInterpolatePrimitive2D
drawinglayer::primitive2d::AnimatedSwitchPrimitive2D
drawinglayer::primitive2d::BackgroundColorPrimitive2D
drawinglayer::primitive2d::ControlPrimitive2D
drawinglayer::primitive2d::DiscreteShadowPrimitive2D
drawinglayer::primitive2d::Embedded3DPrimitive2D
drawinglayer::primitive2d::FillGraphicPrimitive2D
drawinglayer::primitive2d::GlowPrimitive2D
drawinglayer::primitive2d::GridPrimitive2D
drawinglayer::primitive2d::GroupPrimitive2D
drawinglayer::primitive2d::HelplinePrimitive2D
drawinglayer::primitive2d::InvertPrimitive2D
drawinglayer::primitive2d::MarkerArrayPrimitive2D
drawinglayer::primitive2d::MediaPrimitive2D
drawinglayer::primitive2d::MetafilePrimitive2D
drawinglayer::primitive2d::ObjectAndViewTransformationDependentPrimitive2D
drawinglayer::primitive2d::PagePreviewPrimitive2D
drawinglayer::primitive2d::PolyPolygonGradientPrimitive2D
drawinglayer::primitive2d::PolyPolygonGraphicPrimitive2D
drawinglayer::primitive2d::PolyPolygonHatchPrimitive2D
drawinglayer::primitive2d::PolyPolygonSelectionPrimitive2D
drawinglayer::primitive2d::PolygonMarkerPrimitive2D
drawinglayer::primitive2d::PolygonStrokeArrowPrimitive2D
drawinglayer::primitive2d::ScenePrimitive2D
drawinglayer::primitive2d::SdrFrameBorderData::SdrConnectStyleData
drawinglayer::primitive2d::ShadowPrimitive2D
drawinglayer::primitive2d::TextHierarchyBlockPrimitive2D
drawinglayer::primitive2d::TextHierarchyBulletPrimitive2D
drawinglayer::primitive2d::TextHierarchyEditPrimitive2D
drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D
drawinglayer::primitive2d::TextHierarchyLinePrimitive2D
drawinglayer::primitive2d::TextHierarchyParagraphPrimitive2D
drawinglayer::primitive2d::ViewTransformationDependentPrimitive2D
drawinglayer::primitive2d::ViewportDependentPrimitive2D
drawinglayer::primitive2d::WrongSpellPrimitive2D
drawinglayer::primitive3d
drawinglayer::primitive3d::BasePrimitive3D
drawinglayer::primitive3d::BufferedDecompositionPrimitive3D
drawinglayer::primitive3d::GroupPrimitive3D
drawinglayer::primitive3d::ModifiedColorPrimitive3D
drawinglayer::primitive3d::PolyPolygonMaterialPrimitive3D
drawinglayer::primitive3d::PolygonHairlinePrimitive3D
drawinglayer::primitive3d::Primitive3DContainer
drawinglayer::primitive3d::SdrCubePrimitive3D
drawinglayer::primitive3d::SdrExtrudePrimitive3D
drawinglayer::primitive3d::SdrLathePrimitive3D
drawinglayer::primitive3d::SdrPolyPolygonPrimitive3D
drawinglayer::primitive3d::SdrPrimitive3D
drawinglayer::primitive3d::SdrSpherePrimitive3D
drawinglayer::primitive3d::TransformPrimitive3D
drawinglayer::processor2d::HitTestProcessor2D
drawinglayer::processor3d::BaseProcessor3D
drawinglayer::processor3d::CutFindProcessor
emfio::WinMtfFontStyle
formula::FormulaTokenIterator::Item
framework
framework::AddonMenuManager
framework::AddonsOptions
framework::ConfigAccess
framework::ConstItemContainer
framework::Converter
framework::DispatchHelper
framework::FrameListAnalyzer
framework::HandlerCache
framework::InteractionRequest
framework::MenuAttributes
framework::MenuConfiguration
framework::RequestFilterSelect
framework::RootItemContainer
framework::SaxNamespaceFilter
framework::StatusBarConfiguration
framework::ToolBoxConfiguration
framework::TransactionManager
framework::UIConfigurationImporterOOo1x
i18nutil::casefolding
i18nutil::oneToOneMapping
i18nutil::widthfolding
legacy::CntInt32
legacy::SfxBool
legacy::SvxAdjust
legacy::SvxBox
legacy::SvxBrush
legacy::SvxColor
legacy::SvxCrossedOut
legacy::SvxFont
legacy::SvxFontHeight
legacy::SvxHorJustify
legacy::SvxLine
legacy::SvxPosture
legacy::SvxTextLine
legacy::SvxVerJustify
legacy::SvxWeight
linguistic::HyphenatedWord
linguistic::PossibleHyphens
linguistic::PropertyChgHelper
linguistic::PropertyHelper_Hyphenation
linguistic::PropertyHelper_Spell
linguistic::PropertyHelper_Spelling
linguistic::PropertyHelper_Thesaurus
linguistic::SpellAlternatives
psp::PrintFontManager::PrintFont
sdr::SelectionController
sdr::ViewSelection
sdr::animation::primitiveAnimator
sdr::contact::ObjectContactPainter
sdr::properties::BaseProperties
sdr::table::Cell
sfx2::sidebar::Panel
sfx2::sidebar::SidebarToolBox
sfx2::sidebar::TabBar
sfx2::sidebar::TabBar::Item
svt
svt::AddressBookSourceDialog
svt::GenericToolboxController
svt::GraphicAccess
svt::IEditImplementation
svt::MultiLineEditImplementation
svt::MultiLineTextCell
svt::OStringTransferable
svt::PopupMenuControllerBase
svt::SpinCellController
svt::TemplateFolderCache
svtools::AsynchronLink
svtools::ToolbarPopup
svx::DialControl::DialControl_Impl
svx::IPropertyValueProvider
svx::sidebar::GalleryControl
svxform
svxform::DataNavigatorManager
svxform::NavigatorFrameManager
svxform::OLocalExchange
svxform::OLocalExchangeHelper
svxform::OSQLParserClient
toolkitform
tools::WeakBase
ucbhelper::ActiveDataSink
ucbhelper::InteractionApprove
ucbhelper::InteractionDisapprove
ucbhelper::InteractionSupplyAuthentication
ucbhelper::InterceptedInteraction
ucbhelper::SimpleNameClashResolveRequest
utl::Bootstrap::Impl
utl::DefaultFontConfiguration
utl::DesktopTerminationObserver
utl::FontSubstConfiguration
utl::OConfigurationValueContainer
utl::ProgressHandlerWrap
utl::ZipPackageHelper
utl::detail::Options
vcl::AccessibleFactoryAccess
vcl::EventPoster
vcl::ExtOutDevData
vcl::ILibreOfficeKitNotifier
vcl::ORoadmap
vcl::OldStylePrintAdaptor
vcl::PDFWriter::AnyWidget
vcl::test::OutputDeviceTestGradient
void OpenGLTexture
wchar_t& std::vector<wchar_t, std::allocator<wchar_t> >

View file

@ -0,0 +1,152 @@
#!/usr/bin/python2
#
# Generate a custom linker script/map file for the --enabled-mergedlibs merged library
# which reduces the startup time and enables further optimisations with --enable-lto because 60% or more
# of the symbols become internal only.
#
import subprocess
import sys
import re
exported_symbols = set()
imported_symbols = set()
# Copied from solenv/gbuild/extensions/pre_MergedLibsList.mk
# TODO there has to be a way to run gmake and get it to dump this list for me
merged_libs = { \
"avmedia" \
,"basctl" \
,"basprov" \
,"basegfx" \
,"canvasfactory" \
,"canvastools" \
,"comphelper" \
,"configmgr" \
,"cppcanvas" \
,"crashreport)" \
,"dbtools" \
,"deployment" \
,"deploymentmisc" \
,"desktopbe1)" \
,"desktop_detector)" \
,"drawinglayer" \
,"editeng" \
,"expwrap" \
,"filterconfig" \
,"fsstorage" \
,"fwe" \
,"fwi" \
,"fwk" \
,"helplinker)" \
,"i18npool" \
,"i18nutil" \
,"lng" \
,"localebe1" \
,"mcnttype" \
,"msfilter" \
,"mtfrenderer" \
,"opencl" \
,"package2" \
,"sax" \
,"sb" \
,"simplecanvas" \
,"sfx" \
,"sofficeapp" \
,"sot" \
,"spl" \
,"stringresource" \
,"svl" \
,"svt" \
,"svx" \
,"svxcore" \
,"tk" \
,"tl" \
,"ucb1" \
,"ucbhelper" \
,"ucpexpand1" \
,"ucpfile1" \
,"unoxml" \
,"utl" \
,"uui" \
,"vcl" \
,"xmlscript" \
,"xo" \
,"xstor" }
classes_with_exported_symbols = set()
classes_with_imported_symbols = set()
# look for symbols exported by libmerged
subprocess_nm = subprocess.Popen("nm -D instdir/program/libmergedlo.so", stdout=subprocess.PIPE, shell=True)
with subprocess_nm.stdout as txt:
# We are looking for lines something like:
# 0000000000036ed0 T flash_component_getFactory
line_regex = re.compile(r'^[0-9a-fA-F]+ T ')
for line in txt:
line = line.strip()
if line_regex.match(line):
exported_symbols.add(line.split(" ")[2])
subprocess_nm.terminate()
# look for symbols imported from libmerged
subprocess_find = subprocess.Popen("(find instdir/program/ -type f; ls ./workdir/LinkTarget/CppunitTest/*.so) | xargs grep -l mergedlo",
stdout=subprocess.PIPE, shell=True)
with subprocess_find.stdout as txt:
for line in txt:
sharedlib = line.strip()
s = sharedlib[sharedlib.find("/lib") + 4 : len(sharedlib) - 3]
if s in merged_libs: continue
# look for imported symbols
subprocess_objdump = subprocess.Popen("objdump -T " + sharedlib, stdout=subprocess.PIPE, shell=True)
with subprocess_objdump.stdout as txt2:
# ignore some header bumpf
txt2.readline()
txt2.readline()
txt2.readline()
txt2.readline()
# We are looking for lines something like (noting that one of them uses spaces, and the other tabs)
# 0000000000000000 DF *UND* 0000000000000000 _ZN16FilterConfigItem10WriteInt32ERKN3rtl8OUStringEi
for line2 in txt2:
line2 = line2.strip()
if line2.find("*UND*") == -1: continue
tokens = line2.split(" ")
sym = tokens[len(tokens)-1].strip()
imported_symbols.add(sym)
subprocess_objdump.terminate()
subprocess_find.terminate()
intersec_symbols = exported_symbols.intersection(imported_symbols)
print("no symbols exported from libmerged = " + str(len(exported_symbols)))
print("no symbols that can be made internal = " + str(len(intersec_symbols)))
# Now look for classes where none of the class symbols are imported,
# i.e. we can mark the whole class as hidden
def extract_class(sym, add_to_set):
filtered_sym = subprocess.check_output(["c++filt", sym]).strip()
if filtered_sym.startswith("vtable for "):
classname = filtered_sym[11:]
add_to_set.add(classname)
return
if filtered_sym.startswith("non-virtual thunk to "):
filtered_sym = filtered_sym[21:]
elif filtered_sym.startswith("virtual thunk to "):
filtered_sym = filtered_sym[17:]
i = filtered_sym.find("(")
if i != -1:
i = filtered_sym.rfind("::", 0, i)
if i != -1:
classname = filtered_sym[:i]
add_to_set.add(classname)
for sym in exported_symbols:
extract_class(sym, classes_with_exported_symbols)
for sym in imported_symbols:
extract_class(sym, classes_with_imported_symbols)
with open("bin/find-mergedlib-can-be-private.classes.results", "wt") as f:
for sym in sorted(classes_with_exported_symbols - classes_with_imported_symbols):
if sym.startswith("std::") or sym.startswith("void std::"): continue
f.write(sym + "\n")

View file

@ -11,6 +11,17 @@
*/
#define STATIC_LINKING 0
#define ENABLE_MERGELIBS 0
#define ENABLE_RUNTIME_OPTIMIZATIONS 0
// Used to turn off visibility for some classes/symbols when linking with --enable-mergelibs
//
#if ENABLE_MERGELIBS
#define UNLESS_MERGELIBS(x)
#else
#define UNLESS_MERGELIBS(x) x
#endif
#endif

View file

@ -12875,6 +12875,7 @@ if test -n "$enable_mergelibs" -a "$enable_mergelibs" != "no"; then
fi
MERGELIBS="TRUE"
AC_MSG_RESULT([yes])
AC_DEFINE(ENABLE_MERGELIBS)
else
AC_MSG_RESULT([no])
fi

View file

@ -22,6 +22,7 @@
#include <memory>
#include <vcl/dllapi.h>
#include <config_options.h>
#include <tools/link.hxx>
#include <tools/date.hxx>
#include <tools/time.hxx>
@ -228,7 +229,7 @@ private:
OUString maCustomUnitText;
};
class VCL_DLLPUBLIC DateFormatter : public FormatterBase
class UNLESS_MERGELIBS(VCL_DLLPUBLIC) DateFormatter : public FormatterBase
{
private:
std::unique_ptr<CalendarWrapper> mxCalendarWrapper;
@ -474,7 +475,7 @@ public:
virtual void dispose() override;
};
class VCL_DLLPUBLIC TimeField final : public SpinField, public TimeFormatter
class UNLESS_MERGELIBS(VCL_DLLPUBLIC) TimeField final : public SpinField, public TimeFormatter
{
private:
tools::Time maFirst;

View file

@ -23,9 +23,10 @@
#include <vcl/dllapi.h>
#include <vcl/edit.hxx>
#include <vcl/timer.hxx>
#include <config_options.h>
class VCL_DLLPUBLIC SpinField : public Edit
class UNLESS_MERGELIBS(VCL_DLLPUBLIC) SpinField : public Edit
{
public:
explicit SpinField( vcl::Window* pParent, WinBits nWinStyle );

View file

@ -25,6 +25,7 @@
#endif
#include <vcl/field.hxx>
#include <config_options.h>
class VCL_DLLPUBLIC CurrencyFormatter : public NumericFormatter
{
@ -42,7 +43,7 @@ public:
virtual OUString CreateFieldText( sal_Int64 nValue ) const override;
};
class VCL_DLLPUBLIC CurrencyField final : public SpinField, public CurrencyFormatter
class UNLESS_MERGELIBS(VCL_DLLPUBLIC) CurrencyField final : public SpinField, public CurrencyFormatter
{
public:
CurrencyField( vcl::Window* pParent, WinBits nWinStyle );