From 07ac58747f84412ea476b911fd25219093c581ed Mon Sep 17 00:00:00 2001 From: charliesome Date: Sat, 9 Nov 2013 21:17:06 +0000 Subject: * compile.c (iseq_compile_each): emit opt_str_freeze if the #freeze method is called on a static string literal with no arguments. * defs/id.def (firstline): add freeze so idFreeze is available * insns.def (opt_str_freeze): add opt_str_freeze instruction which pushes a frozen string literal without allocating a new object if String#freeze is not overriden * string.c (Init_String): define String#freeze * vm.c (vm_init_redefined_flag): define BOP_FREEZE on String class as a basic operation * vm_insnhelper.h: ditto git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43627 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 20 ++++++++++++++++++++ compile.c | 11 +++++++++++ defs/id.def | 1 + insns.def | 14 ++++++++++++++ string.c | 1 + vm.c | 1 + vm_insnhelper.h | 1 + 7 files changed, 49 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9ba9221a08..d80d3953cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +Sun Nov 10 06:14:39 2013 Charlie Somerville + + * compile.c (iseq_compile_each): emit opt_str_freeze if the #freeze + method is called on a static string literal with no arguments. + + * defs/id.def (firstline): add freeze so idFreeze is available + + * insns.def (opt_str_freeze): add opt_str_freeze instruction which + pushes a frozen string literal without allocating a new object if + String#freeze is not overriden + + * string.c (Init_String): define String#freeze + + * vm.c (vm_init_redefined_flag): define BOP_FREEZE on String class as + a basic operation + + * vm_insnhelper.h: ditto + + [Feature #8992] [ruby-core:57705] + Sun Nov 10 01:34:14 2013 Koichi Sasada * gc.c (vm_malloc_increase): sweep immediately on GC due to malloc(). diff --git a/compile.c b/compile.c index f3f5f2d75a..00ae3011e7 100644 --- a/compile.c +++ b/compile.c @@ -4314,6 +4314,17 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) break; } case NODE_CALL: + if (node->nd_recv && nd_type(node->nd_recv) == NODE_STR && + node->nd_mid == idFreeze && node->nd_args == NULL) + { + VALUE str = rb_fstring(node->nd_recv->nd_lit); + iseq_add_mark_object(iseq, str); + ADD_INSN1(ret, line, opt_str_freeze, str); + if (poped) { + ADD_INSN(ret, line, pop); + } + break; + } case NODE_FCALL: case NODE_VCALL:{ /* VCALL: variable or call */ /* diff --git a/defs/id.def b/defs/id.def index 57c0ae9f14..53ed3775ad 100644 --- a/defs/id.def +++ b/defs/id.def @@ -1,5 +1,6 @@ # -*- mode: ruby; coding: us-ascii -*- firstline, predefined = __LINE__+1, %[\ + freeze inspect intern object_id diff --git a/insns.def b/insns.def index 6075d98db2..63a36b3979 100644 --- a/insns.def +++ b/insns.def @@ -999,6 +999,20 @@ send CALL_METHOD(ci); } +DEFINE_INSN +opt_str_freeze +(VALUE str) +() +(VALUE val) +{ + if (BASIC_OP_UNREDEFINED_P(BOP_FREEZE, STRING_REDEFINED_OP_FLAG)) { + val = str; + } + else { + val = rb_funcall(rb_str_resurrect(str), idFreeze, 0); + } +} + /** @c optimize @e Invoke method without block, splat diff --git a/string.c b/string.c index dbfce96788..ca73d41f98 100644 --- a/string.c +++ b/string.c @@ -8745,6 +8745,7 @@ Init_String(void) rb_define_method(rb_cString, "byteslice", rb_str_byteslice, -1); rb_define_method(rb_cString, "scrub", str_scrub, -1); rb_define_method(rb_cString, "scrub!", str_scrub_bang, -1); + rb_define_method(rb_cString, "freeze", rb_obj_freeze, 0); rb_define_method(rb_cString, "to_i", rb_str_to_i, -1); rb_define_method(rb_cString, "to_f", rb_str_to_f, 0); diff --git a/vm.c b/vm.c index 7d07b66a32..77a77ea97b 100644 --- a/vm.c +++ b/vm.c @@ -1082,6 +1082,7 @@ vm_init_redefined_flag(void) OP(EmptyP, EMPTY_P), (C(Array), C(String), C(Hash)); OP(Succ, SUCC), (C(Fixnum), C(String), C(Time)); OP(EqTilde, MATCH), (C(Regexp), C(String)); + OP(Freeze, FREEZE), (C(String)); #undef C #undef OP } diff --git a/vm_insnhelper.h b/vm_insnhelper.h index 8870fca47c..c637407cbc 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -56,6 +56,7 @@ enum { BOP_NOT, BOP_NEQ, BOP_MATCH, + BOP_FREEZE, BOP_LAST_ }; -- cgit v1.2.3