Project

General

Profile

Feature #10329 » 0002-optimize-foo-literal-string.patch

normalperson (Eric Wong), 10/06/2014 02:31 AM

View differences:

benchmark/bm_vm2_streq1.rb
1
i = 0
2
foo = "literal"
3
while i<6_000_000 # benchmark loop 2
4
  i += 1
5
  foo == "literal"
6
end
compile.c
4287 4287
	    }
4288 4288
	    break;
4289 4289
	}
4290

  
4291
	if (node->nd_mid == idEq && !private_recv_p(node) && node->nd_args &&
4292
	    nd_type(node->nd_args) == NODE_ARRAY &&
4293
	    node->nd_args->nd_alen == 1)
4294
	{
4295
	    /* optimization shortcut
4296
	     *   obj == "literal" -> opt_streq1(obj, "literal")
4297
	     */
4298
	    if (nd_type(node->nd_args->nd_head) == NODE_STR) {
4299
		VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit);
4300
		node->nd_args->nd_head->nd_lit = str;
4301
		COMPILE(ret, "recv", node->nd_recv);
4302
		ADD_INSN2(ret, line, opt_streq1,
4303
			  new_callinfo(iseq, node->nd_mid, 1, 0, 0), str);
4304
		if (poped) {
4305
		    ADD_INSN(ret, line, pop);
4306
		}
4307
		break;
4308
	    }
4309
	    /* TODO: optimization shortcut
4310
	     *   "yoda" == other -> opt_streq2("yoda", other)
4311
	     */
4312
	}
4290 4313
      case NODE_FCALL:
4291 4314
      case NODE_VCALL:{		/* VCALL: variable or call */
4292 4315
	/*
insns.def
1967 1967

  
1968 1968
/**
1969 1969
  @c optimize
1970
  @e recv == "literal string"
1971
 */
1972
DEFINE_INSN
1973
opt_streq1
1974
(CALL_INFO ci, VALUE lit)
1975
(VALUE recv)
1976
(VALUE val)
1977
{
1978
    if (!SPECIAL_CONST_P(recv) && RBASIC_CLASS(recv) == rb_cString &&
1979
        BASIC_OP_UNREDEFINED_P(BOP_EQ, STRING_REDEFINED_OP_FLAG)) {
1980
	val = rb_str_equal(recv, lit);
1981
    }
1982
    else {
1983
	PUSH(recv);
1984
	PUSH(rb_str_resurrect(lit));
1985
	CALL_SIMPLE_METHOD(recv);
1986
    }
1987
}
1988

  
1989
/**
1990
  @c optimize
1970 1991
  @e optimized length
1971 1992
  @j 最適化された recv.length()。
1972 1993
 */
test/ruby/test_string.rb
2303 2303
      assert_equal before + nr, GC.stat(:total_allocated_objects)
2304 2304
    end
2305 2305
  end
2306

  
2307
  def test_opt_streq1
2308
    assert_separately([], <<-RUBY)
2309
      class String
2310
        undef ==
2311
        def ==(str)
2312
          :TROO
2313
        end
2314
      end
2315
      assert_equal(:TROO, ("foo" == "foo"))
2316
    RUBY
2317

  
2318
    if @cls == String
2319
      nr = 10
2320

  
2321
      recv = "something"
2322
      res = []
2323
      before = GC.stat(:total_allocated_objects)
2324
      nr.times { res << (recv == "constant") }
2325
      assert_equal before, GC.stat(:total_allocated_objects)
2326
      assert_equal [ false ], res.uniq!
2327

  
2328
      res.clear
2329
      before = GC.stat(:total_allocated_objects)
2330
      nr.times { res << (recv == "something") }
2331
      assert_equal before, GC.stat(:total_allocated_objects)
2332
      assert_equal [ true ], res.uniq!
2333
    end
2334
  end
2306 2335
end
2307 2336

  
2308 2337
class TestString2 < TestString
2309
-