Permalink
Browse files

* rewrite method/block parameter fitting logic to optimize

  keyword arguments/parameters and a splat argument.
  [Feature #10440] (Details are described in this ticket)
  Most of complex part is moved to vm_args.c.
  Now, ISeq#to_a does not catch up new instruction format.
* vm_core.h: change iseq data structures.
  * introduce rb_call_info_kw_arg_t to represent keyword arguments.
  * add rb_call_info_t::kw_arg.
  * rename rb_iseq_t::arg_post_len to rb_iseq_t::arg_post_num.
  * rename rb_iseq_t::arg_keywords to arg_keyword_num.
  * rename rb_iseq_t::arg_keyword to rb_iseq_t::arg_keyword_bits.
    to represent keyword bitmap parameter index.
    This bitmap parameter shows that which keyword parameters are given
    or not given (0 for given).
    It is refered by `checkkeyword' instruction described bellow.
  * rename rb_iseq_t::arg_keyword_check to rb_iseq_t::arg_keyword_rest
    to represent keyword rest parameter index.
  * add rb_iseq_t::arg_keyword_default_values to represent default
    keyword values.
  * rename VM_CALL_ARGS_SKIP_SETUP to VM_CALL_ARGS_SIMPLE
    to represent
      (ci->flag & (SPLAT|BLOCKARG)) &&
      ci->blockiseq == NULL &&
      ci->kw_arg == NULL.
* vm_insnhelper.c, vm_args.c: rewrite with refactoring.
  * rewrite splat argument code.
  * rewrite keyword arguments/parameters code.
  * merge method and block parameter fitting code into one code base.
* vm.c, vm_eval.c: catch up these changes.
* compile.c (new_callinfo): callinfo requires kw_arg parameter.
* compile.c (compile_array_): check the last argument Hash object or
  not. If Hash object and all keys are Symbol literals, they are
  compiled to keyword arguments.
* insns.def (checkkeyword): add new instruction.
  This instruction check the availability of corresponding keyword.
  For example, a method "def foo k1: 'v1'; end" is cimpiled to the
  following instructions.
    0000 checkkeyword     2, 0  # check k1 is given.
    0003 branchif         9     # if given, jump to address #9
    0005 putstring        "v1"
    0007 setlocal_OP__WC__0 3   # k1 = 'v1'
    0009 trace            8
    0011 putnil
    0012 trace            16
    0014 leave
* insns.def (opt_send_simple): removed and add new instruction
  "opt_send_without_block".
* parse.y (new_args_tail_gen): reorder variables.
  Before this patch, a method "def foo(k1: 1, kr1:, k2: 2, **krest, &b)"
  has parameter variables "k1, kr1, k2, &b, internal_id, krest",
  but this patch reorders to "kr1, k1, k2, internal_id, krest, &b".
  (locate a block variable at last)
* parse.y (vtable_pop): added.
  This function remove latest `n' variables from vtable.
* iseq.c: catch up iseq data changes.
* proc.c: ditto.
* class.c (keyword_error): export as rb_keyword_error().
* common.mk: depend vm_args.c for vm.o.
* hash.c (rb_hash_has_key): export.
* internal.h: ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48239 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information...
ko1 committed Nov 2, 2014
1 parent 055a465 commit fbebd502f9f374d1eef31c63c10c7d8adcd63280
Showing with 1,375 additions and 671 deletions.
  1. +84 −0 ChangeLog
  2. +5 −5 class.c
  3. +1 −1 common.mk
  4. +247 −156 compile.c
  5. +1 −1 hash.c
  6. +30 −10 insns.def
  7. +2 −0 internal.h
  8. +25 −15 iseq.c
  9. +55 −9 parse.y
  10. +3 −3 proc.c
  11. +1 −1 vm.c
  12. +783 −0 vm_args.c
  13. +27 −19 vm_core.h
  14. +1 −0 vm_eval.c
  15. +110 −451 vm_insnhelper.c
@@ -1,3 +1,87 @@
Mon Nov 03 03:02:38 2014 Koichi Sasada <ko1@atdot.net>
* rewrite method/block parameter fitting logic to optimize
keyword arguments/parameters and a splat argument.
[Feature #10440] (Details are described in this ticket)
Most of complex part is moved to vm_args.c.
Now, ISeq#to_a does not catch up new instruction format.
* vm_core.h: change iseq data structures.
* introduce rb_call_info_kw_arg_t to represent keyword arguments.
* add rb_call_info_t::kw_arg.
* rename rb_iseq_t::arg_post_len to rb_iseq_t::arg_post_num.
* rename rb_iseq_t::arg_keywords to arg_keyword_num.
* rename rb_iseq_t::arg_keyword to rb_iseq_t::arg_keyword_bits.
to represent keyword bitmap parameter index.
This bitmap parameter shows that which keyword parameters are given
or not given (0 for given).
It is refered by `checkkeyword' instruction described bellow.
* rename rb_iseq_t::arg_keyword_check to rb_iseq_t::arg_keyword_rest
to represent keyword rest parameter index.
* add rb_iseq_t::arg_keyword_default_values to represent default
keyword values.
* rename VM_CALL_ARGS_SKIP_SETUP to VM_CALL_ARGS_SIMPLE
to represent
(ci->flag & (SPLAT|BLOCKARG)) &&
ci->blockiseq == NULL &&
ci->kw_arg == NULL.
* vm_insnhelper.c, vm_args.c: rewrite with refactoring.
* rewrite splat argument code.
* rewrite keyword arguments/parameters code.
* merge method and block parameter fitting code into one code base.
* vm.c, vm_eval.c: catch up these changes.
* compile.c (new_callinfo): callinfo requires kw_arg parameter.
* compile.c (compile_array_): check the last argument Hash object or
not. If Hash object and all keys are Symbol literals, they are
compiled to keyword arguments.
* insns.def (checkkeyword): add new instruction.
This instruction check the availability of corresponding keyword.
For example, a method "def foo k1: 'v1'; end" is cimpiled to the
following instructions.
0000 checkkeyword 2, 0 # check k1 is given.
0003 branchif 9 # if given, jump to address #9
0005 putstring "v1"
0007 setlocal_OP__WC__0 3 # k1 = 'v1'
0009 trace 8
0011 putnil
0012 trace 16
0014 leave
* insns.def (opt_send_simple): removed and add new instruction
"opt_send_without_block".
* parse.y (new_args_tail_gen): reorder variables.
Before this patch, a method "def foo(k1: 1, kr1:, k2: 2, **krest, &b)"
has parameter variables "k1, kr1, k2, &b, internal_id, krest",
but this patch reorders to "kr1, k1, k2, internal_id, krest, &b".
(locate a block variable at last)
* parse.y (vtable_pop): added.
This function remove latest `n' variables from vtable.
* iseq.c: catch up iseq data changes.
* proc.c: ditto.
* class.c (keyword_error): export as rb_keyword_error().
* common.mk: depend vm_args.c for vm.o.
* hash.c (rb_hash_has_key): export.
* internal.h: ditto.
Mon Nov 3 02:35:32 2014 Koichi Sasada <ko1@atdot.net>
* sample/simple-bench.rb: added to measure performance of simple
10 class.c
@@ -1862,9 +1862,9 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
return argc;
}
NORETURN(static void keyword_error(const char *error, VALUE keys));
static void
keyword_error(const char *error, VALUE keys)
NORETURN(void rb_keyword_error(const char *error, VALUE keys));
void
rb_keyword_error(const char *error, VALUE keys)
{
const char *msg = "";
if (RARRAY_LEN(keys) == 1) {
@@ -1890,7 +1890,7 @@ unknown_keyword_error(VALUE hash, const ID *table, int keywords)
}
keys = rb_funcall(hash, rb_intern("keys"), 0, 0);
if (!RB_TYPE_P(keys, T_ARRAY)) rb_raise(rb_eArgError, "unknown keyword");
keyword_error("unknown", keys);
rb_keyword_error("unknown", keys);
}
static int
@@ -1957,7 +1957,7 @@ rb_get_kwargs(VALUE keyword_hash, const ID *table, int required, int optional, V
rb_ary_push(missing, keyword);
}
if (!NIL_P(missing)) {
keyword_error("missing", missing);
rb_keyword_error("missing", missing);
}
}
j = i;
@@ -824,7 +824,7 @@ iseq.$(OBJEXT): {$(VPATH)}iseq.c {$(VPATH)}gc.h {$(VPATH)}iseq.h \
{$(VPATH)}insns_info.inc {$(VPATH)}node_name.inc {$(VPATH)}internal.h \
{$(VPATH)}vm_opts.h {$(VPATH)}ruby_atomic.h {$(VPATH)}eval_intern.h \
{$(VPATH)}util.h
vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}gc.h {$(VPATH)}iseq.h \
vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}gc.h {$(VPATH)}iseq.h {$(VPATH)}vm_args.c \
{$(VPATH)}eval_intern.h $(RUBY_H_INCLUDES) $(ENCODING_H_INCLUDES) \
$(VM_CORE_H_INCLUDES) {$(VPATH)}vm_method.c {$(VPATH)}vm_eval.c \
{$(VPATH)}vm_insnhelper.c {$(VPATH)}vm_insnhelper.h {$(VPATH)}vm_exec.c \
Oops, something went wrong.

0 comments on commit fbebd50

Please sign in to comment.