summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcharliesome <charliesome@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-11-09 21:17:06 +0000
committercharliesome <charliesome@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-11-09 21:17:06 +0000
commit07ac58747f84412ea476b911fd25219093c581ed (patch)
tree6d1a97aa0c4f5e55f767ea4f602da32b894a393c
parentd6f5e30df87b4dfa4d66d8f4cb74da7dde949e8d (diff)
* 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
-rw-r--r--ChangeLog20
-rw-r--r--compile.c11
-rw-r--r--defs/id.def1
-rw-r--r--insns.def14
-rw-r--r--string.c1
-rw-r--r--vm.c1
-rw-r--r--vm_insnhelper.h1
7 files changed, 49 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 9ba9221..d80d395 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+Sun Nov 10 06:14:39 2013 Charlie Somerville <charliesome@ruby-lang.org>
+
+ * 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 <ko1@atdot.net>
* gc.c (vm_malloc_increase): sweep immediately on GC due to malloc().
diff --git a/compile.c b/compile.c
index f3f5f2d..00ae301 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 57c0ae9..53ed377 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 6075d98..63a36b3 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 dbfce96..ca73d41 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 7d07b66..77a77ea 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 8870fca..c637407 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -56,6 +56,7 @@ enum {
BOP_NOT,
BOP_NEQ,
BOP_MATCH,
+ BOP_FREEZE,
BOP_LAST_
};