summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-12-08 07:54:58 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-12-08 07:54:58 +0000
commitea07884a413f62348a47a574b1818555271f6d96 (patch)
tree0704099a6e3e299071e747e8cac6e00a8103c4f9 /compile.c
parent05f891cbbb4ee3b09e83e50924d96bddb8f67b91 (diff)
compile.c: optimize literal nodes
* compile.c (static_literal_node_p): optimize literal nodes for true, false, and nil, which are static literals in specific nodes but not in NODE_LIT. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57025 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/compile.c b/compile.c
index e579586ee6..05fb807352 100644
--- a/compile.c
+++ b/compile.c
@@ -2962,6 +2962,29 @@ enum compile_array_type_t {
};
static int
+static_literal_node_p(NODE *node, VALUE *val)
+{
+ node = node->nd_head;
+ switch (nd_type(node)) {
+ case NODE_LIT:
+ *val = node->nd_lit;
+ break;
+ case NODE_NIL:
+ *val = Qnil;
+ break;
+ case NODE_TRUE:
+ *val = Qtrue;
+ break;
+ case NODE_FALSE:
+ *val = Qfalse;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static int
compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE* node_root,
enum compile_array_type_t type, struct rb_call_info_kw_arg **keywords_ptr, int popped)
{
@@ -2985,6 +3008,7 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE* node_root,
while (node) {
NODE *start_node = node, *end_node;
NODE *kw = 0;
+ VALUE elem[2];
const int max = 0x100;
DECL_ANCHOR(anchor);
INIT_ANCHOR(anchor);
@@ -3004,7 +3028,7 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE* node_root,
}
break;
}
- if (opt_p && nd_type(node->nd_head) != NODE_LIT) {
+ if (opt_p && !static_literal_node_p(node, elem)) {
opt_p = 0;
}
@@ -3024,15 +3048,15 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE* node_root,
node = start_node;
while (node != end_node) {
- rb_ary_push(ary, node->nd_head->nd_lit);
+ static_literal_node_p(node, elem);
+ rb_ary_push(ary, elem[0]);
node = node->nd_next;
}
- while (node && nd_type(node->nd_head) == NODE_LIT &&
- node->nd_next && nd_type(node->nd_next->nd_head) == NODE_LIT) {
- rb_ary_push(ary, node->nd_head->nd_lit);
- node = node->nd_next;
- rb_ary_push(ary, node->nd_head->nd_lit);
- node = node->nd_next;
+ while (node && node->nd_next &&
+ static_literal_node_p(node, &elem[0]) &&
+ static_literal_node_p(node->nd_next, &elem[1])) {
+ rb_ary_cat(ary, elem, 2);
+ node = node->nd_next->nd_next;
len++;
}