1. 12 4月, 2020 1 次提交
  2. 11 4月, 2020 1 次提交
  3. 10 4月, 2020 4 次提交
  4. 08 4月, 2020 1 次提交
  5. 18 3月, 2020 2 次提交
    • K
      Added link to the ticket [ci skip] · afd23ed0
      Kazuhiro NISHIYAMA 提交于
      afd23ed0
    • J
      Reduce allocations for keyword argument hashes · d2c41b1b
      Jeremy Evans 提交于
      Previously, passing a keyword splat to a method always allocated
      a hash on the caller side, and accepting arbitrary keywords in
      a method allocated a separate hash on the callee side.  Passing
      explicit keywords to a method that accepted a keyword splat
      did not allocate a hash on the caller side, but resulted in two
      hashes allocated on the callee side.
      
      This commit makes passing a single keyword splat to a method not
      allocate a hash on the caller side.  Passing multiple keyword
      splats or a mix of explicit keywords and a keyword splat still
      generates a hash on the caller side.  On the callee side,
      if arbitrary keywords are not accepted, it does not allocate a
      hash.  If arbitrary keywords are accepted, it will allocate a
      hash, but this commit uses a callinfo flag to indicate whether
      the caller already allocated a hash, and if so, the callee can
      use the passed hash without duplicating it.  So this commit
      should make it so that a maximum of a single hash is allocated
      during method calls.
      
      To set the callinfo flag appropriately, method call argument
      compilation checks if only a single keyword splat is given.
      If only one keyword splat is given, the VM_CALL_KW_SPLAT_MUT
      callinfo flag is not set, since in that case the keyword
      splat is passed directly and not mutable.  If more than one
      splat is used, a new hash needs to be generated on the caller
      side, and in that case the callinfo flag is set, indicating
      the keyword splat is mutable by the callee.
      
      In compile_hash, used for both hash and keyword argument
      compilation, if compiling keyword arguments and only a
      single keyword splat is used, pass the argument directly.
      
      On the caller side, in vm_args.c, the callinfo flag needs to
      be recognized and handled.  Because the keyword splat
      argument may not be a hash, it needs to be converted to a
      hash first if not.  Then, unless the callinfo flag is set,
      the hash needs to be duplicated.  The temporary copy of the
      callinfo flag, kw_flag, is updated if a hash was duplicated,
      to prevent the need to duplicate it again.  If we are
      converting to a hash or duplicating a hash, we need to update
      the argument array, which can including duplicating the
      positional splat array if one was passed.  CALLER_SETUP_ARG
      and a couple other places needs to be modified to handle
      similar issues for other types of calls.
      
      This includes fairly comprehensive tests for different ways
      keywords are handled internally, checking that you get equal
      results but that keyword splats on the caller side result in
      distinct objects for keyword rest parameters.
      
      Included are benchmarks for keyword argument calls.
      Brief results when compiled without optimization:
      
        def kw(a: 1) a end
        def kws(**kw) kw end
        h = {a: 1}
      
        kw(a: 1)       # about same
        kw(**h)        # 2.37x faster
        kws(a: 1)      # 1.30x faster
        kws(**h)       # 2.19x faster
        kw(a: 1, **h)  # 1.03x slower
        kw(**h, **h)   # about same
        kws(a: 1, **h) # 1.16x faster
        kws(**h, **h)  # 1.14x faster
      d2c41b1b
  6. 16 3月, 2020 1 次提交
    • Y
      hash.c: Do not use the fast path (rb_yield_values) for lambda blocks · 47141797
      Yusuke Endoh 提交于
      As a semantics, Hash#each yields a 2-element array (pairs of keys and
      values).  So, `{ a: 1 }.each(&->(k, v) { })` should raise an exception
      due to lambda's arity check.
      However, the optimization that avoids Array allocation by using
      rb_yield_values for blocks whose arity is more than 1 (introduced at
      b9d29603 and some commits), seemed to
      overlook the lambda case, and wrongly allowed the code above to work.
      
      This change experimentally attempts to make it strict; now the code
      above raises an ArgumentError.  This is an incompatible change; if the
      compatibility issue is bigger than our expectation, it may be reverted
      (until Ruby 3.0 release).
      
      [Bug #12706]
      47141797
  7. 11 3月, 2020 2 次提交
  8. 10 3月, 2020 2 次提交
  9. 09 3月, 2020 1 次提交
  10. 03 3月, 2020 1 次提交
  11. 29 2月, 2020 3 次提交
  12. 19 2月, 2020 1 次提交
  13. 17 2月, 2020 4 次提交
  14. 12 2月, 2020 1 次提交
  15. 24 1月, 2020 1 次提交
  16. 23 1月, 2020 1 次提交
  17. 19 1月, 2020 2 次提交
  18. 18 1月, 2020 3 次提交
  19. 16 1月, 2020 1 次提交
  20. 15 1月, 2020 2 次提交