[前][次][番号順一覧][スレッド一覧]

ruby-changes:24747

From: ko1 <ko1@a...>
Date: Thu, 23 Aug 2012 16:22:57 +0900 (JST)
Subject: [ruby-changes:24747] ko1:r36798 (trunk): * include/ruby/ruby.h: introduce flonum technique for

ko1	2012-08-23 16:22:40 +0900 (Thu, 23 Aug 2012)

  New Revision: 36798

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=36798

  Log:
    * include/ruby/ruby.h: introduce flonum technique for
      64bit CPU environment (sizeof(double) == sizeof(VALUE)).
      flonum technique enables to avoid double object creation
      if the double value d is in range about between
      1.72723e-77 < |d| <= 1.15792e+77 or 0.0.
      flonum Float value is immediate and their lowest two bits
      are b10.
      If flonum is activated, then USE_FLONUM macro is 1.
      I'll write detailed in this technique on
      https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/Flonum_tech
    * benchmark/bmx_temp.rb: add an benchmark for simple
      Float calculation.
    * gc.c (id2ref, rb_obj_id): add flonum Float support.
    * include/ruby/intern.h: move decl of rb_float_new(double)
      to include/ruby/ruby.h.
    * insns.def, vm.c, vm_insnhelper.c: add flonum optimization
      and simplify source code.
    * vm_insnhelper.h (FLONUM_2_P): added.
    * marshal.c: support flonum output.
    * numeric.c (rb_float_new_in_heap): added.
    * parse.y: support flonum.
    * random.c: ditto.

  Modified files:
    trunk/ChangeLog
    trunk/benchmark/bmx_temp.rb
    trunk/gc.c
    trunk/include/ruby/intern.h
    trunk/include/ruby/ruby.h
    trunk/insns.def
    trunk/marshal.c
    trunk/numeric.c
    trunk/parse.y
    trunk/random.c
    trunk/vm.c
    trunk/vm_insnhelper.c
    trunk/vm_insnhelper.h

Index: include/ruby/intern.h
===================================================================
--- include/ruby/intern.h	(revision 36797)
+++ include/ruby/intern.h	(revision 36798)
@@ -516,7 +516,6 @@
 VALUE rb_num_coerce_bin(VALUE, VALUE, ID);
 VALUE rb_num_coerce_cmp(VALUE, VALUE, ID);
 VALUE rb_num_coerce_relop(VALUE, VALUE, ID);
-VALUE rb_float_new(double);
 VALUE rb_num2fix(VALUE);
 VALUE rb_fix2str(VALUE, int);
 VALUE rb_dbl_cmp(double, double);
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 36797)
+++ include/ruby/ruby.h	(revision 36798)
@@ -350,11 +350,59 @@
 #define ID2SYM(x) (((VALUE)(x)<<RUBY_SPECIAL_SHIFT)|SYMBOL_FLAG)
 #define SYM2ID(x) RSHIFT((unsigned long)(x),RUBY_SPECIAL_SHIFT)
 
+#ifndef USE_FLONUM
+#if SIZEOF_VALUE >= SIZEOF_DOUBLE
+#define USE_FLONUM 1
+#else
+#define USE_FLONUM 0
+#endif
+#endif
+
+#if USE_FLONUM
+#define FLONUM_P(x) ((((int)(SIGNED_VALUE)(x))&FLONUM_MASK) == FLONUM_FLAG)
+#else
+#define FLONUM_P(x) 0
+#endif
+
 /* Module#methods, #singleton_methods and so on return Symbols */
 #define USE_SYMBOL_AS_METHOD_NAME 1
 
+/*
+!USE_FLONUM
+-------------------------
+...xxxx xxx1 Fixnum
+...0000 1110 Symbol
+...0000 0000 Qfalse
+...0000 0010 Qtrue
+...0000 0100 Qnil
+...0000 0110 Qundef
+
+USE_FLONUM
+-------------------------
+...xxxx xxx1 Fixnum
+...xxxx xx10 Flonum
+...0000 1100 Symbol
+...0000 0000 Qfalse  0x00 =  0
+...0000 1000  Qnil   0x08 =  8
+...0001 0100 Qtrue   0x14 = 20
+...0011 0100 Qundef  0x34 = 52
+ */
+
 /* special constants - i.e. non-zero and non-fixnum constants */
 enum ruby_special_consts {
+#if USE_FLONUM
+    RUBY_Qfalse = 0x00,
+    RUBY_Qtrue  = 0x14,
+    RUBY_Qnil   = 0x08,
+    RUBY_Qundef = 0x34,
+
+    RUBY_IMMEDIATE_MASK = 0x07,
+    RUBY_FIXNUM_FLAG    = 0x01,
+    RUBY_FLONUM_MASK    = 0x03,
+    RUBY_FLONUM_FLAG    = 0x02,
+    RUBY_SYMBOL_FLAG    = 0x0c,
+    RUBY_SPECIAL_SHIFT  = 8
+#else
     RUBY_Qfalse = 0,
     RUBY_Qtrue  = 2,
     RUBY_Qnil   = 4,
@@ -364,6 +412,7 @@
     RUBY_FIXNUM_FLAG    = 0x01,
     RUBY_SYMBOL_FLAG    = 0x0e,
     RUBY_SPECIAL_SHIFT  = 8
+#endif
 };
 
 #define Qfalse ((VALUE)RUBY_Qfalse)
@@ -372,6 +421,10 @@
 #define Qundef ((VALUE)RUBY_Qundef)	/* undefined value for placeholder */
 #define IMMEDIATE_MASK RUBY_IMMEDIATE_MASK
 #define FIXNUM_FLAG RUBY_FIXNUM_FLAG
+#if USE_FLONUM
+#define FLONUM_MASK RUBY_FLONUM_MASK
+#define FLONUM_FLAG RUBY_FLONUM_FLAG
+#endif
 #define SYMBOL_FLAG RUBY_SYMBOL_FLAG
 
 #define RTEST(v) (((VALUE)(v) & ~Qnil) != 0)
@@ -669,7 +722,87 @@
     struct RBasic basic;
     double float_value;
 };
-#define RFLOAT_VALUE(v) (RFLOAT(v)->float_value)
+
+VALUE rb_float_new_in_heap(double);
+
+#if USE_FLONUM
+#define RUBY_BIT_ROTL(v, n) (((v) << (n)) | ((v) >> ((sizeof(v) * 8) - n)))
+#define RUBY_BIT_ROTR(v, n) (((v) >> (n)) | ((v) << ((sizeof(v) * 8) - n)))
+
+static inline double
+rb_float_value(VALUE v)
+{
+    if (FLONUM_P(v)) {
+	if (v == (VALUE)0x8000000000000002) {
+	    return 0.0;
+	}
+	else {
+	    union {
+		double d;
+		VALUE v;
+	    } t;
+
+	    VALUE b63 = (v >> 63);
+	    /* e: xx1... -> 011... */
+	    /*    xx0... -> 100... */
+	    /*      ^b63           */
+	    t.v = RUBY_BIT_ROTR(((b63 ^ 1) << 1) | b63 | (v & ~0x03), 3);
+	    return t.d;
+	}
+    }
+    else {
+	return ((struct RFloat *)v)->float_value;
+    }
+}
+
+static inline VALUE
+rb_float_new(double d)
+{
+    union {
+	double d;
+	VALUE v;
+    } t;
+    int bits;
+
+    t.d = d;
+    bits = (int)((VALUE)(t.v >> 60) & 0x7);
+    /* bits contains 3 bits of b62..b60. */
+    /* bits - 3 = */
+    /*   b011 -> b000 */
+    /*   b100 -> b001 */
+
+    if (t.v != 0x3000000000000000 /* 1.72723e-77 */ &&
+	!((bits-3) & ~0x01)) {
+	return (RUBY_BIT_ROTL(t.v, 3) & ~0x01 | 0x02);
+    }
+    else {
+	if (t.v == (VALUE)0) {
+	    /* +0.0 */
+	    return 0x8000000000000002;
+	}
+	else {
+	    /* out of range */
+	    return rb_float_new_in_heap(d);
+	}
+    }
+}
+
+#else /* USE_FLONUM */
+
+static inline double
+rb_float_value(VALUE v)
+{
+    return ((struct RFloat *)v)->float_value;
+}
+
+static inline VALUE
+rb_float_new(double d)
+{
+    return rb_float_new_in_heap(d);
+}
+#endif
+
+#define RFLOAT_VALUE(v) rb_float_value(v)
 #define DBL2NUM(dbl)  rb_float_new(dbl)
 
 #define ELTS_SHARED FL_USER2
@@ -990,7 +1123,11 @@
 #define OBJ_TAINT(x) FL_SET((x), FL_TAINT)
 #define OBJ_UNTRUSTED(x) (!!FL_TEST((x), FL_UNTRUSTED))
 #define OBJ_UNTRUST(x) FL_SET((x), FL_UNTRUSTED)
-#define OBJ_INFECT(x,s) do {if (FL_ABLE(x) && FL_ABLE(s)) RBASIC(x)->flags |= RBASIC(s)->flags & (FL_TAINT | FL_UNTRUSTED);} while (0)
+#define OBJ_INFECT(x,s) do { \
+  if (FL_ABLE(x) && FL_ABLE(s)) \
+    RBASIC(x)->flags |= RBASIC(s)->flags & \
+                        (FL_TAINT | FL_UNTRUSTED); \
+} while (0)
 
 #define OBJ_FROZEN(x) (!!FL_TEST((x), FL_FREEZE))
 #define OBJ_FREEZE(x) FL_SET((x), FL_FREEZE)
@@ -1332,6 +1469,7 @@
 {
     if (IMMEDIATE_P(obj)) {
 	if (FIXNUM_P(obj)) return rb_cFixnum;
+	if (FLONUM_P(obj)) return rb_cFloat;
 	if (obj == Qtrue)  return rb_cTrueClass;
 	if (SYMBOL_P(obj)) return rb_cSymbol;
     }
@@ -1347,17 +1485,24 @@
 {
     if (IMMEDIATE_P(obj)) {
 	if (FIXNUM_P(obj)) return T_FIXNUM;
-	if (obj == Qtrue) return T_TRUE;
+        if (FLONUM_P(obj)) return T_FLOAT;
+        if (obj == Qtrue)  return T_TRUE;
 	if (SYMBOL_P(obj)) return T_SYMBOL;
 	if (obj == Qundef) return T_UNDEF;
     }
     else if (!RTEST(obj)) {
-	if (obj == Qnil) return T_NIL;
+	if (obj == Qnil)   return T_NIL;
 	if (obj == Qfalse) return T_FALSE;
     }
     return BUILTIN_TYPE(obj);
 }
 
+#if USE_FLONUM
+#define RB_FLOAT_TYPE_P(obj) (FLONUM_P(obj) || TYPE(obj) == T_FLOAT)
+#else
+#define RB_FLOAT_TYPE_P(obj) (!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == T_FLOAT)
+#endif
+
 #define RB_TYPE_P(obj, type) ( \
 	((type) == T_FIXNUM) ? FIXNUM_P(obj) : \
 	((type) == T_TRUE) ? ((obj) == Qtrue) : \
@@ -1365,6 +1510,7 @@
 	((type) == T_NIL) ? ((obj) == Qnil) : \
 	((type) == T_UNDEF) ? ((obj) == Qundef) : \
 	((type) == T_SYMBOL) ? SYMBOL_P(obj) : \
+        ((type) == T_FLOAT) ? RB_FLOAT_TYPE_P(obj) : \
 	(!SPECIAL_CONST_P(obj) && BUILTIN_TYPE(obj) == (type)))
 
 #ifdef __GNUC__
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 36797)
+++ ChangeLog	(revision 36798)
@@ -1,3 +1,37 @@
+Thu Aug 23 16:20:04 2012  Koichi Sasada  <ko1@a...>
+
+	* include/ruby/ruby.h: introduce flonum technique for
+	  64bit CPU environment (sizeof(double) == sizeof(VALUE)).
+	  flonum technique enables to avoid double object creation
+	  if the double value d is in range about between
+	  1.72723e-77 < |d| <= 1.15792e+77 or 0.0.
+	  flonum Float value is immediate and their lowest two bits
+	  are b10.
+	  If flonum is activated, then USE_FLONUM macro is 1.
+	  I'll write detailed in this technique on
+	  https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/Flonum_tech
+
+	* benchmark/bmx_temp.rb: add an benchmark for simple
+	  Float calculation.
+
+	* gc.c (id2ref, rb_obj_id): add flonum Float support.
+
+	* include/ruby/intern.h: move decl of rb_float_new(double)
+	  to include/ruby/ruby.h.
+
+	* insns.def, vm.c, vm_insnhelper.c: add flonum optimization
+	  and simplify source code.
+
+	* vm_insnhelper.h (FLONUM_2_P): added.
+
+	* marshal.c: support flonum output.
+
+	* numeric.c (rb_float_new_in_heap): added.
+
+	* parse.y: support flonum.
+
+	* random.c: ditto.
+
 Thu Aug 23 16:12:40 2012  NAKAMURA Usaku  <usa@r...>
 
 	* lib/mkmf.rb (create_makefile): add dependency to header files when
Index: insns.def
===================================================================
--- insns.def	(revision 36797)
+++ insns.def	(revision 36798)
@@ -1333,12 +1333,8 @@
 (VALUE recv, VALUE obj)
 (VALUE val)
 {
-    if (0) {
-
-    }
-#if 1
-    else if (FIXNUM_2_P(recv, obj) &&
-	     BASIC_OP_UNREDEFINED_P(BOP_PLUS,FIXNUM_REDEFINED_OP_FLAG)) {
+    if (FIXNUM_2_P(recv, obj) &&
+	BASIC_OP_UNREDEFINED_P(BOP_PLUS,FIXNUM_REDEFINED_OP_FLAG)) {
 	/* fixnum + fixnum */
 #ifndef LONG_LONG_VALUE
 	val = (recv + (obj & (~1)));
@@ -1360,38 +1356,29 @@
 	}
 #endif
     }
-#endif
-
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
+	val = DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
+    }
     else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
-	if (0) {
-	}
-#if 1
-	else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
-		 HEAP_CLASS_OF(obj) == rb_cFloat &&
-		 BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
+	if (HEAP_CLASS_OF(recv) == rb_cFloat && HEAP_CLASS_OF(obj) == rb_cFloat &&
+	    BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
 	    val = DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
 	}
-#endif
-
-#if 1
-	else if (HEAP_CLASS_OF(recv) == rb_cString &&
-		 HEAP_CLASS_OF(obj) == rb_cString &&
+	else if (HEAP_CLASS_OF(recv) == rb_cString && HEAP_CLASS_OF(obj) == rb_cString &&
 		 BASIC_OP_UNREDEFINED_P(BOP_PLUS, STRING_REDEFINED_OP_FLAG)) {
 	    val = rb_str_plus(recv, obj);
 	}
-#endif
-#if 1
 	else if (HEAP_CLASS_OF(recv) == rb_cArray &&
 		 BASIC_OP_UNREDEFINED_P(BOP_PLUS, ARRAY_REDEFINED_OP_FLAG)) {
 	    val = rb_ary_plus(recv, obj);
 	}
-#endif
 	else {
 	    goto INSN_LABEL(normal_dispatch);
 	}
     }
     else {
-      INSN_LABEL(normal_dispatch):
+	INSN_LABEL(normal_dispatch):
 	PUSH(recv);
 	PUSH(obj);
 	CALL_SIMPLE_METHOD(1, idPLUS, recv);
@@ -1424,16 +1411,15 @@
 	    val = rb_big_minus(rb_int2big(a), rb_int2big(b));
 	}
     }
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
+	val = DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
+    }
     else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
-	if (0) {
-	}
-#if 1
-	else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
-		 HEAP_CLASS_OF(obj) == rb_cFloat  &&
-		 BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
+	if (HEAP_CLASS_OF(recv) == rb_cFloat && HEAP_CLASS_OF(obj) == rb_cFloat  &&
+	    BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
 	    val = DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
 	}
-#endif
 	else {
 	    goto INSN_LABEL(normal_dispatch);
 	}
@@ -1479,16 +1465,15 @@
 	    }
 	}
     }
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
+	val = DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
+    }
     else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
-	if (0) {
-	}
-#if 1
-	else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
-		 HEAP_CLASS_OF(obj) == rb_cFloat  &&
-		 BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
+	if (HEAP_CLASS_OF(recv) == rb_cFloat && HEAP_CLASS_OF(obj) == rb_cFloat  &&
+	    BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
 	    val = DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
 	}
-#endif
 	else {
 	    goto INSN_LABEL(normal_dispatch);
 	}
@@ -1543,16 +1528,15 @@
 	}
 	val = LONG2NUM(div);
     }
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
+	val = DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
+    }
     else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
-	if (0) {
-	}
-#if 1
-	else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
-		 HEAP_CLASS_OF(obj) == rb_cFloat  &&
-		 BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
+	if (HEAP_CLASS_OF(recv) == rb_cFloat && HEAP_CLASS_OF(obj) == rb_cFloat  &&
+	    BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
 	    val = DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
 	}
-#endif
 	else {
 	    goto INSN_LABEL(normal_dispatch);
 	}
@@ -1608,12 +1592,13 @@
 	}
 	val = LONG2FIX(mod);
     }
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
+	val = DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
+    }
     else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
-	if (0) {
-	}
-	else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
-		 HEAP_CLASS_OF(obj) == rb_cFloat &&
-		 BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
+	if (HEAP_CLASS_OF(recv) == rb_cFloat && HEAP_CLASS_OF(obj) == rb_cFloat &&
+	    BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
 	    val = DBL2NUM(ruby_float_mod(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj)));
 	}
 	else {
@@ -1702,22 +1687,16 @@
 	    val = Qfalse;
 	}
     }
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
+	/* flonum is not NaN */
+	val = RFLOAT_VALUE(recv) < RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
+    }
     else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
-	if (0) {
+	if (HEAP_CLASS_OF(recv) == rb_cFloat && HEAP_CLASS_OF(obj) == rb_cFloat  &&
+	    BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
+	    val = double_cmp_lt(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
 	}
-#if 1
-	else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
-		 HEAP_CLASS_OF(obj) == rb_cFloat  &&
-		 BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
-	    double a = RFLOAT_VALUE(recv);
-	    double b = RFLOAT_VALUE(obj);
-#if defined(_MSC_VER) && _MSC_VER < 1300
-	    if (isnan(a) || isnan(b)) val = Qfalse;
-	    else
-#endif
-	    val = a < b ? Qtrue : Qfalse;
-	}
-#endif
 	else {
 	    goto INSN_LABEL(normal_dispatch);
 	}
@@ -1752,6 +1731,11 @@
 	    val = Qfalse;
 	}
     }
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_LE, FLOAT_REDEFINED_OP_FLAG)) {
+	/* flonum is not NaN */
+	val = RFLOAT_VALUE(recv) <= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
+    }
     else {
 	/* other */
 	PUSH(recv);
@@ -1782,22 +1766,16 @@
 	    val = Qfalse;
 	}
     }
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
+	/* flonum is not NaN */
+	val = RFLOAT_VALUE(recv) > RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
+    }
     else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
-	if (0) {
+	if (HEAP_CLASS_OF(recv) == rb_cFloat && HEAP_CLASS_OF(obj) == rb_cFloat  &&
+	    BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
+	    val = double_cmp_gt(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
 	}
-#if 1
-	else if (HEAP_CLASS_OF(recv) == rb_cFloat &&
-		 HEAP_CLASS_OF(obj) == rb_cFloat  &&
-		 BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
-	    double a = RFLOAT_VALUE(recv);
-	    double b = RFLOAT_VALUE(obj);
-#if defined(_MSC_VER) && _MSC_VER < 1300
-	    if (isnan(a) || isnan(b)) val = Qfalse;
-	    else
-#endif
-	    val = a > b ? Qtrue : Qfalse;
-	}
-#endif
 	else {
 	    goto INSN_LABEL(normal_dispatch);
 	}
@@ -1832,6 +1810,11 @@
 	    val = Qfalse;
 	}
     }
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_GE, FLOAT_REDEFINED_OP_FLAG)) {
+	/* flonum is not NaN */
+	val = RFLOAT_VALUE(recv) >= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
+    }
     else {
 	PUSH(recv);
 	PUSH(obj);
@@ -1851,10 +1834,8 @@
 (VALUE val)
 {
     if (!SPECIAL_CONST_P(recv)) {
-	if (0) {
-	}
-	else if (HEAP_CLASS_OF(recv) == rb_cString &&
-		 BASIC_OP_UNREDEFINED_P(BOP_LTLT, STRING_REDEFINED_OP_FLAG)) {
+	if (HEAP_CLASS_OF(recv) == rb_cString &&
+	    BASIC_OP_UNREDEFINED_P(BOP_LTLT, STRING_REDEFINED_OP_FLAG)) {
 	    val = rb_str_concat(recv, obj);
 	}
 	else if (HEAP_CLASS_OF(recv) == rb_cArray &&
Index: gc.c
===================================================================
--- gc.c	(revision 36797)
+++ gc.c	(revision 36798)
@@ -1606,6 +1606,7 @@
     if (ptr == Qfalse) return Qfalse;
     if (ptr == Qnil) return Qnil;
     if (FIXNUM_P(ptr)) return (VALUE)ptr;
+    if (FLONUM_P(ptr)) return (VALUE)ptr;
     ptr = objid ^ FIXNUM_FLAG;	/* unset FIXNUM_FLAG */
 
     if ((ptr % sizeof(RVALUE)) == (4 << 2)) {
@@ -1685,9 +1686,16 @@
     if (SYMBOL_P(obj)) {
         return (SYM2ID(obj) * sizeof(RVALUE) + (4 << 2)) | FIXNUM_FLAG;
     }
-    if (SPECIAL_CONST_P(obj)) {
-        return LONG2NUM((SIGNED_VALUE)obj);
+    else if (FLONUM_P(obj)) {
+#if SIZEOF_LONG == SIZEOF_VOIDP
+	return LONG2NUM((SIGNED_VALUE)obj);
+#else
+	return LL2NUM((SIGNED_VALUE)obj);
+#endif
     }
+    else if (SPECIAL_CONST_P(obj)) {
+	return LONG2NUM((SIGNED_VALUE)obj);
+    }
     return nonspecial_obj_id(obj);
 }
 
Index: parse.y
===================================================================
--- parse.y	(revision 36797)
+++ parse.y	(revision 36798)
@@ -9346,7 +9346,16 @@
 	node->nd_lit = rb_funcall(node->nd_lit,tUMINUS,0,0);
 	break;
       case T_FLOAT:
+#if USE_FLONUM
+	if (FLONUM_P(node->nd_lit)) {
+	    node->nd_lit = DBL2NUM(-RFLOAT_VALUE(node->nd_lit));
+	}
+	else {
+	    RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
+	}
+#else
 	RFLOAT(node->nd_lit)->float_value = -RFLOAT_VALUE(node->nd_lit);
+#endif
 	break;
       default:
 	break;
Index: numeric.c
===================================================================
--- numeric.c	(revision 36797)
+++ numeric.c	(revision 36798)
@@ -615,7 +615,7 @@
  */
 
 VALUE
-rb_float_new(double d)
+rb_float_new_in_heap(double d)
 {
     NEWOBJ(flt, struct RFloat);
     OBJSETUP(flt, rb_cFloat, T_FLOAT);
Index: vm.c
===================================================================
--- vm.c	(revision 36797)
+++ vm.c	(revision 36798)
@@ -990,22 +990,22 @@
 #define OP(mid_, bop_) (mid = id##mid_, bop = BOP_##bop_, ruby_vm_redefined_flag[bop] = 0)
 #define C(k) add_opt_method(rb_c##k, mid, bop)
     OP(PLUS, PLUS), (C(Fixnum), C(Float), C(String), C(Array));
-    OP(MINUS, MINUS), (C(Fixnum));
+    OP(MINUS, MINUS), (C(Fixnum), C(Float));
     OP(MULT, MULT), (C(Fixnum), C(Float));
     OP(DIV, DIV), (C(Fixnum), C(Float));
     OP(MOD, MOD), (C(Fixnum), C(Float));
     OP(Eq, EQ), (C(Fixnum), C(Float), C(String));
     OP(Eqq, EQQ), (C(Fixnum), C(Bignum), C(Float), C(Symbol), C(String));
-    OP(LT, LT), (C(Fixnum));
-    OP(LE, LE), (C(Fixnum));
+    OP(LT, LT), (C(Fixnum), C(Float));
+    OP(LE, LE), (C(Fixnum), C(Float));
+    OP(GT, GT), (C(Fixnum), C(Float));
+    OP(GE, GE), (C(Fixnum), C(Float));
     OP(LTLT, LTLT), (C(String), C(Array));
     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));
 #undef C
 #undef OP
 }
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 36797)
+++ vm_insnhelper.c	(revision 36798)
@@ -1776,10 +1776,14 @@
 	BASIC_OP_UNREDEFINED_P(BOP_EQ, FIXNUM_REDEFINED_OP_FLAG)) {
 	return (recv == obj) ? Qtrue : Qfalse;
     }
+    else if (FLONUM_2_P(recv, obj) &&
+	     BASIC_OP_UNREDEFINED_P(BOP_EQ, FLOAT_REDEFINED_OP_FLAG)) {
+	return (recv == obj) ? Qtrue : Qfalse;
+    }
     else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
 	if (HEAP_CLASS_OF(recv) == rb_cFloat &&
 		 HEAP_CLASS_OF(obj) == rb_cFloat &&
-		 BASIC_OP_UNREDEFINED_P(BOP_EQ, FLOAT_REDEFINED_OP_FLAG)) {
+	    BASIC_OP_UNREDEFINED_P(BOP_EQ, FLOAT_REDEFINED_OP_FLAG)) {
 	    double a = RFLOAT_VALUE(recv);
 	    double b = RFLOAT_VALUE(obj);
 
@@ -1865,3 +1869,37 @@
     }
 }
 
+
+#if defined(_MSC_VER) && _MSC_VER < 1300
+#define CHECK_CMP_NAN(a, b) if (isnan(a) || isnan(b)) return Qfalse;
+#else
+#define CHECK_CMP_NAN(a, b) 
+#endif
+
+static inline VALUE
+double_cmp_lt(double a, double b)
+{
+    CHECK_CMP_NAN(a, b);
+    return a < b ? Qtrue : Qfalse;
+}
+
+static inline VALUE
+double_cmp_le(double a, double b)
+{
+    CHECK_CMP_NAN(a, b);
+    return a <= b ? Qtrue : Qfalse;
+}
+
+static inline VALUE
+double_cmp_gt(double a, double b)
+{
+    CHECK_CMP_NAN(a, b);
+    return a > b ? Qtrue : Qfalse;
+}
+
+static inline VALUE
+double_cmp_ge(double a, double b)
+{
+    CHECK_CMP_NAN(a, b);
+    return a >= b ? Qtrue : Qfalse;
+}
Index: benchmark/bmx_temp.rb
=== (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]