summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--compile.c3
-rw-r--r--id.c1
-rw-r--r--id.h2
-rw-r--r--insns.def37
-rw-r--r--vm.c1
-rw-r--r--vm_insnhelper.h1
7 files changed, 50 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index d980868eb8..dd7b9c9c16 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Sun Sep 6 17:31:28 2009 Koichi Sasada <ko1@atdot.net>
+
+ * compile.c (iseq_specialized_instruction), insns.def (opt_size):
+ optimize #size methods (by specialized instruction).
+
+ * id.c, id.h, vm.c, vm_insnhelper.h: ditto.
+
Sun Sep 6 16:13:06 2009 Koichi Sasada <ko1@atdot.net>
* insns.def (setinstancevariable), vm_insnhelper.c (vm_setivar):
diff --git a/compile.c b/compile.c
index 42828a802b..d3c26671a6 100644
--- a/compile.c
+++ b/compile.c
@@ -1803,6 +1803,9 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
if (mid == idLength) {
insn_set_specialized_instruction(iobj, BIN(opt_length));
}
+ else if (mid == idSize) {
+ insn_set_specialized_instruction(iobj, BIN(opt_size));
+ }
else if (mid == idSucc) {
insn_set_specialized_instruction(iobj, BIN(opt_succ));
}
diff --git a/id.c b/id.c
index 4fd760af03..2111751a37 100644
--- a/id.c
+++ b/id.c
@@ -34,6 +34,7 @@ Init_id(void)
REGISTER_SYMID(idEach, "each");
REGISTER_SYMID(idLength, "length");
+ REGISTER_SYMID(idSize, "size");
REGISTER_SYMID(idLambda, "lambda");
REGISTER_SYMID(idIntern, "intern");
REGISTER_SYMID(idGets, "gets");
diff --git a/id.h b/id.h
index 1f94dbb996..8087683cf5 100644
--- a/id.h
+++ b/id.h
@@ -98,6 +98,7 @@ enum ruby_method_ids {
tIntern,
tMethodMissing,
tLength,
+ tSize,
tGets,
tSucc,
tEach,
@@ -118,6 +119,7 @@ enum ruby_method_ids {
TOKEN2ID(Intern),
TOKEN2ID(MethodMissing),
TOKEN2ID(Length),
+ TOKEN2ID(Size),
TOKEN2ID(Gets),
TOKEN2ID(Succ),
TOKEN2ID(Each),
diff --git a/insns.def b/insns.def
index 98febf89b8..7de873d4bf 100644
--- a/insns.def
+++ b/insns.def
@@ -1921,8 +1921,8 @@ opt_length
(VALUE recv)
(VALUE val)
{
- if (!SPECIAL_CONST_P(recv) &&
- BASIC_OP_UNREDEFINED_P(BOP_LENGTH)) {
+ if (LIKELY(!SPECIAL_CONST_P(recv) &&
+ BASIC_OP_UNREDEFINED_P(BOP_LENGTH))) {
if (HEAP_CLASS_OF(recv) == rb_cString) {
val = rb_str_length(recv);
}
@@ -1945,6 +1945,39 @@ opt_length
/**
@c optimize
+ @e optimized size
+ @j 最適化された recv.size()。
+ */
+DEFINE_INSN
+opt_size
+()
+(VALUE recv)
+(VALUE val)
+{
+ if (LIKELY(BASIC_OP_UNREDEFINED_P(BOP_SIZE) &&
+ !SPECIAL_CONST_P(recv))) {
+ if (HEAP_CLASS_OF(recv) == rb_cString) {
+ val = rb_str_length(recv);
+ }
+ else if (HEAP_CLASS_OF(recv) == rb_cArray) {
+ val = LONG2NUM(RARRAY_LEN(recv));
+ }
+ else if (HEAP_CLASS_OF(recv) == rb_cHash) {
+ val = INT2FIX(RHASH_SIZE(recv));
+ }
+ else {
+ goto INSN_LABEL(normal_dispatch);
+ }
+ }
+ else {
+ INSN_LABEL(normal_dispatch):
+ PUSH(recv);
+ CALL_SIMPLE_METHOD(0, idSize, recv);
+ }
+}
+
+/**
+ @c optimize
@e optimized succ
@j 最適化された recv.succ()。
*/
diff --git a/vm.c b/vm.c
index 4af968653d..c794b08dcf 100644
--- a/vm.c
+++ b/vm.c
@@ -980,6 +980,7 @@ vm_init_redefined_flag(void)
OP(AREF, AREF), (C(Array), C(Hash));
OP(ASET, ASET), (C(Array), C(Hash));
OP(Length, LENGTH), (C(Array), C(String), C(Hash));
+ OP(Size, SIZE), (C(Array), C(String), C(Hash));
OP(Succ, SUCC), (C(Fixnum), C(String), C(Time));
OP(GT, GT), (C(Fixnum));
OP(GE, GE), (C(Fixnum));
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 055c43c16a..bb4cef553b 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -48,6 +48,7 @@ enum {
BOP_AREF,
BOP_ASET,
BOP_LENGTH,
+ BOP_SIZE,
BOP_SUCC,
BOP_GT,
BOP_GE,