Skip to content
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

Performance regression upgrading from v3.5.2 to v3.6.4 #3125

Closed
stanhu opened this issue Aug 24, 2020 · 5 comments
Closed

Performance regression upgrading from v3.5.2 to v3.6.4 #3125

stanhu opened this issue Aug 24, 2020 · 5 comments

Comments

@stanhu
Copy link

stanhu commented Aug 24, 2020

We use the ruby-sassc gem and attempted to upgrade GitLab to use v2.4.0, which upgrades our libsass version from v3.5.2 to v3.6.4. Now our assets compile step no longer finishes in a timely manner.

A perf report seems to suggest that the library is spending a lot of time in malloc() and free(). I'm not sure if this means there's a memory leak or just a performance regression in this upgrade:

image

A GDB backtrace is attached while this is running. See thread 1:

gdb.txt

This is an excerpt from another backtrace:

Thread 1 (Thread 0x7f76dea11d80 (LWP 23770)):
#0  0x00007f76ddf1fa52 in malloc_consolidate (av=av@entry=0x7f76de27ac40 <main_arena>) at malloc.c:4462
#1  0x00007f76ddf23848 in _int_malloc (av=av@entry=0x7f76de27ac40 <main_arena>, bytes=bytes@entry=1544) at malloc.c:3703
#2  0x00007f76ddf2635d in __GI___libc_malloc (bytes=1544) at malloc.c:3065
#3  0x00007f76c97e4298 in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007f76c32af86e in std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > > Sass::lcs<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > >(std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > > const&, std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > > const&, bool (*)(std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > const&, std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > const&, std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >&)) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#5  0x00007f76c32ab817 in Sass::weaveParents(std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#6  0x00007f76c32adb1b in Sass::weave(std::vector<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > >, std::allocator<std::vector<Sass::SharedImpl<Sass::SelectorComponent>, std::allocator<Sass::SharedImpl<Sass::SelectorComponent> > > > > const&) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#7  0x00007f76c3337190 in Sass::Extender::extendComplex(Sass::SharedImpl<Sass::ComplexSelector> const&, std::unordered_map<Sass::SharedImpl<Sass::SimpleSelector>, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > >, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::SimpleSelector> const, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > > > > > const&, Sass::SharedImpl<Sass::CssMediaRule> const&) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#8  0x00007f76c3337954 in Sass::Extender::extendExistingExtensions(std::vector<Sass::Extension, std::allocator<Sass::Extension> > const&, std::unordered_map<Sass::SharedImpl<Sass::SimpleSelector>, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > >, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::SimpleSelector> const, Sass::ordered_map<Sass::SharedImpl<Sass::ComplexSelector>, Sass::Extension, Sass::ObjHash, Sass::ObjEquality, std::allocator<std::pair<Sass::SharedImpl<Sass::ComplexSelector> const, Sass::Extension> > > > > > const&) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#9  0x00007f76c3339ed2 in Sass::Extender::addExtension(Sass::SharedImpl<Sass::SelectorList> const&, Sass::SharedImpl<Sass::SimpleSelector> const&, Sass::SharedImpl<Sass::CssMediaRule> const&, bool) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#10 0x00007f76c3326423 in Sass::Expand::operator()(Sass::ExtendRule*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#11 0x00007f76c332ddbd in Sass::Expand::append_block(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#12 0x00007f76c33280b9 in Sass::Expand::operator()(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#13 0x00007f76c332b07a in Sass::Expand::operator()(Sass::StyleRule*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#14 0x00007f76c332ddbd in Sass::Expand::append_block(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#15 0x00007f76c33280b9 in Sass::Expand::operator()(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#16 0x00007f76c332b07a in Sass::Expand::operator()(Sass::StyleRule*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#17 0x00007f76c332ddbd in Sass::Expand::append_block(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#18 0x00007f76c33280b9 in Sass::Expand::operator()(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#19 0x00007f76c332b07a in Sass::Expand::operator()(Sass::StyleRule*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#20 0x00007f76c332ddbd in Sass::Expand::append_block(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#21 0x00007f76c3328800 in Sass::Expand::operator()(Sass::Import_Stub*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#22 0x00007f76c332ddbd in Sass::Expand::append_block(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#23 0x00007f76c3328800 in Sass::Expand::operator()(Sass::Import_Stub*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#24 0x00007f76c332ddbd in Sass::Expand::append_block(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#25 0x00007f76c33280b9 in Sass::Expand::operator()(Sass::Block*) () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#26 0x00007f76c32e5499 in Sass::Context::compile() () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#27 0x00007f76c32e6de0 in Sass::Data_Context::parse() () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#28 0x00007f76c33f4e36 in sass_compiler_parse () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#29 0x00007f76c33f559f in sass_compile_data_context () from /home/stanhu/gdk-ee/gitlab/vendor/ruby/2.6.0/gems/sassc-2.4.0/lib/sassc/libsass.so
#30 0x00007f76ce226dae in ffi_call_unix64 () from /usr/lib/x86_64-linux-gnu/libffi.so.6
#31 0x00007f76ce22671f in ffi_call () from /usr/lib/x86_64-linux-gnu/libffi.so.6
#32 0x00007f76c8f1251e in rbffi_CallFunction (argc=<optimized out>, argv=<optimized out>, function=0x7f76c33f5500 <sass_compile_data_context>, fnInfo=0x5636d888d8f0) at Call.c:406
#33 0x00007f76c8f15ef4 in custom_trampoline (argc=<optimized out>, argv=<optimized out>, self=<optimized out>, handle=<optimized out>) at MethodHandle.c:224
#34 0x00007f76de4df60f in vm_call_cfunc_with_frame (ci=0x5636d8727eb0, cc=<optimized out>, calling=<optimized out>, reg_cfp=0x7f76dcdee1a0, ec=0x5636ce84f4b8) at vm_insnhelper.c:1908
#35 vm_call_cfunc (ec=0x5636ce84f4b8, reg_cfp=0x7f76dcdee1a0, calling=<optimized out>, ci=0x5636d8727eb0, cc=<optimized out>) at vm_insnhelper.c:1924
#36 0x00007f76de4eee13 in vm_call_method (ec=0x5636ce84f4b8, cfp=0x7f76dcdee1a0, calling=<optimized out>, ci=<optimized out>, cc=<optimized out>) at vm_insnhelper.c:2400
#37 0x00007f76de4e4ef2 in vm_exec_core (ec=ec@entry=0x5636ce84f4b8, initial=initial@entry=0) at insns.def:765
#38 0x00007f76de4ebdaf in rb_vm_exec (ec=0x5636ce84f4b8, mjit_enable_p=mjit_enable_p@entry=1) at vm.c:1885
#39 0x00007f76de4ec881 in invoke_block (ec=ec@entry=0x5636ce84f4b8, iseq=iseq@entry=0x5636d02f1310, self=self@entry=94793665443800, cref=cref@entry=0x0, type=type@entry=572653569, opt_pc=0, captured=<optimized out>) at vm.c:1021
#40 0x00007f76de4eca3e in invoke_iseq_block_from_c (me=<optimized out>, is_lambda=<optimized out>, cref=<optimized out>, passed_block_handler=<optimized out>, argv=<optimized out>, argc=<optimized out>, self=<optimized out>, captured=<optimized out>, ec=<optimized out>) at vm.c:1092
#41 invoke_block_from_c_bh (argc=<optimized out>, passed_block_handler=<optimized out>, cref=<optimized out>, is_lambda=<optimized out>, force_blockarg=<optimized out>, argv=<optimized out>, block_handler=<optimized out>, ec=<optimized out>) at vm.c:1110
#42 vm_yield (argc=<optimized out>, argv=<optimized out>, ec=<optimized out>) at vm.c:1155
#43 rb_yield_0 (argv=<optimized out>, argc=<optimized out>) at vm_eval.c:978
#44 rb_yield_1 (val=<optimized out>) at vm_eval.c:984
#45 rb_yield (val=<optimized out>) at vm_eval.c:994
#46 0x00007f76de2b3fc6 in rb_ary_reverse_each (ary=94793717443120) at array.c:2146
#47 0x00007f76de4df60f in vm_call_cfunc_with_frame (ci=0x5636d0e3a1b0, cc=<optimized out>, calling=<optimized out>, reg_cfp=0x7f76dcdee360, ec=0x5636ce84f4b8) at vm_insnhelper.c:1908
#48 vm_call_cfunc (ec=0x5636ce84f4b8, reg_cfp=0x7f76dcdee360, calling=<optimized out>, ci=0x5636d0e3a1b0, cc=<optimized out>) at vm_insnhelper.c:1924
#49 0x00007f76de4e4fb4 in vm_exec_core (ec=0x5636ce84f4b8, initial=initial@entry=0) at insns.def:750
#50 0x00007f76de4ec465 in rb_vm_exec (ec=0x5636ce84f4b8, mjit_enable_p=mjit_enable_p@entry=1) at vm.c:1894
#51 0x00007f76de4ec881 in invoke_block (ec=ec@entry=0x5636ce84f4b8, iseq=iseq@entry=0x5636d03870e0, self=self@entry=94793665443800, cref=cref@entry=0x0, type=type@entry=572653569, opt_pc=0, captured=<optimized out>) at vm.c:1021
#52 0x00007f76de4ef647 in invoke_iseq_block_from_c (me=0x0, is_lambda=<optimized out>, cref=0x0, passed_block_handler=<optimized out>, argv=0x5636dec177d8, argc=2, self=94793665443800, captured=0x5636e41a2850, ec=0x5636ce84f4b8) at vm.c:1092
#53 invoke_block_from_c_proc (me=0x0, is_lambda=<optimized out>, passed_block_handler=<optimized out>, argv=0x5636dec177d8, argc=2, self=94793665443800, proc=<optimized out>, ec=0x5636ce84f4b8) at vm.c:1192
#54 vm_invoke_proc (passed_block_handler=<optimized out>, argv=0x5636dec177d8, argc=2, self=94793665443800, proc=<optimized out>, ec=0x5636ce84f4b8) at vm.c:1210
#55 rb_vm_invoke_proc (ec=ec@entry=0x5636ce84f4b8, proc=<optimized out>, argc=2, argv=argv@entry=0x7fffcf986f30, passed_block_handler=<optimized out>) at vm.c:1231
#56 0x00007f76de4f046b in vm_call0_body (argv=0x7fffcf986f30, cc=0x7fffcf986e40, ci=0x7fffcf986e10, calling=0x7fffcf986e20, ec=0x5636ce84f4b8) at vm_eval.c:186
#57 rb_vm_call0 (ec=0x5636ce84f4b8, recv=<optimized out>, id=<optimized out>, argc=argc@entry=1864105578, argv=0x7fffcf986f30, argv@entry=0x7fffcf986ed0, me=<optimized out>) at vm_eval.c:60
#58 0x00007f76de4f2571 in rb_call0 (scope=CALL_FCALL, self=<optimized out>, argv=0x7fffcf986ed0, argc=1864105578, mid=<optimized out>, recv=<optimized out>, ec=<optimized out>) at vm_eval.c:308

version info:

  1. ruby-sass v2.4.0
  2. libsass v3.6.4
@xzyfer
Copy link
Contributor

xzyfer commented Aug 24, 2020 via email

@stanhu
Copy link
Author

stanhu commented Aug 24, 2020

After leaving the assets compilation to run overnight, the process got killed by the kernel due to out-of-memory. So it's definitely not an improvement with memory usage. 😄

@pravi
Copy link

pravi commented Feb 27, 2021

@xzyfer any update on this? We are forced to stay of older libsass because of this regression.

@HumanG33k
Copy link

HumanG33k commented Feb 27, 2021

Hello,
Same trouble here. News on it can be great.

@mgreter
Copy link
Contributor

mgreter commented Feb 28, 2021

What you are seeing is (AFAICT) unfortunately intrinsic to how dart-sass changed how @extend is working.
Since LibSass aims to match the latest Sass implementation (albeit very slowly catching up), this is an issue we can't fix.
You may try your code with latest dart-sass, but I suspect you will not get any better results, otherwise LibSass needs fixing.
So please don't shot the messenger, but the way you are using @extend will not be supported in future releases of any Sass.

I tried to mention the implication in the latest release notes, once I got aware of the issue:

First I hope this version finally fixes all regressions I introduced previously and I apologize for the
disturbance it may have brought to anybody. The compound selector extend changes may still
make your build very slow. The emitted warning should be correct now and if you get one,
chances are high that LibSass will output "unnecessary" big selectors. I will look into a solution for
next maintenance release to at least be able to detect this situation to avoid "endless" compilations.

Unfortunately we can't do much beside advising people to use @extend in a way to avoid this issue.
I know this sucks if you need to rework existing code, but LibSass is merely following the lead of Sass.
For reference: #3033 (comment)

@mgreter mgreter closed this as completed Feb 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants