[macruby-changes] [1709] MacRuby/branches/fp-optimized-experimental
source_changes at macosforge.org
source_changes at macosforge.org
Wed Jun 3 12:46:19 PDT 2009
Revision: 1709
http://trac.macosforge.org/projects/ruby/changeset/1709
Author: pthomson at apple.com
Date: 2009-06-03 12:46:18 -0700 (Wed, 03 Jun 2009)
Log Message:
-----------
First attempt at adding floating-point optimization.
Floats that do not use their last two bits will be represented as FixFloats.
THIS ONLY WORKS ON 64-BIT. PROCEED WITH CAUTION.
Modified Paths:
--------------
MacRuby/branches/fp-optimized-experimental/compiler.cpp
MacRuby/branches/fp-optimized-experimental/include/ruby/ruby.h
MacRuby/branches/fp-optimized-experimental/numeric.c
MacRuby/branches/fp-optimized-experimental/object.c
MacRuby/branches/fp-optimized-experimental/vm.cpp
Modified: MacRuby/branches/fp-optimized-experimental/compiler.cpp
===================================================================
--- MacRuby/branches/fp-optimized-experimental/compiler.cpp 2009-06-03 19:43:40 UTC (rev 1708)
+++ MacRuby/branches/fp-optimized-experimental/compiler.cpp 2009-06-03 19:46:18 UTC (rev 1709)
@@ -4301,7 +4301,12 @@
static inline double
rval_to_double(VALUE rval)
{
- return RFLOAT_VALUE(rb_Float(bool_to_fix(rval)));
+ // workaround for C++'s refusal to cast union types.
+ VALUE r = rb_Float(bool_to_fix(rval));
+ if (FIXFLOAT_P(r)) {
+ return *(double*)(&r);
+ }
+ return RFLOAT(r)->float_value;
}
extern "C"
Modified: MacRuby/branches/fp-optimized-experimental/include/ruby/ruby.h
===================================================================
--- MacRuby/branches/fp-optimized-experimental/include/ruby/ruby.h 2009-06-03 19:43:40 UTC (rev 1708)
+++ MacRuby/branches/fp-optimized-experimental/include/ruby/ruby.h 2009-06-03 19:46:18 UTC (rev 1709)
@@ -167,10 +167,10 @@
# endif
#endif
-#define FIXNUM_MAX (LONG_MAX>>1)
-#define FIXNUM_MIN RSHIFT((long)LONG_MIN,1)
+#define FIXNUM_MAX (LONG_MAX>>2)
+#define FIXNUM_MIN RSHIFT((long)LONG_MIN,2)
-#define INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<1 | FIXNUM_FLAG))
+#define INT2FIX(i) ((VALUE)(((SIGNED_VALUE)(i))<<2 | FIXNUM_FLAG))
#define LONG2FIX(i) INT2FIX(i)
#define rb_fix_new(v) INT2FIX(v)
VALUE rb_int2inum(SIGNED_VALUE);
@@ -224,15 +224,35 @@
#define NUM2GIDT(v) NUM2LONG(v)
#endif
-#define FIX2LONG(x) RSHIFT((SIGNED_VALUE)x,1)
-#define FIX2ULONG(x) ((((VALUE)(x))>>1)&LONG_MAX)
-#define FIXNUM_P(f) (((SIGNED_VALUE)(f))&FIXNUM_FLAG)
+#define FIX2LONG(x) RSHIFT((SIGNED_VALUE)x,2)
+#define FIX2ULONG(x) ((((VALUE)(x))>>2)&LONG_MAX)
+#define FIXNUM_P(f) ((((SIGNED_VALUE)(f)) & IMMEDIATE_MASK) == FIXNUM_FLAG)
#define POSFIXABLE(f) ((f) < FIXNUM_MAX+1)
#define NEGFIXABLE(f) ((f) >= FIXNUM_MIN)
#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
#define IMMEDIATE_P(x) ((VALUE)(x) & IMMEDIATE_MASK)
+// We can't directly cast a void* to a double, so we cast it to a union
+// and then extract its double member. Hacky, but effective.
+// This doesn't work in C++, though. I need suggestions on how to do it there.
+typedef union {VALUE val; void* vd; double d;} hack_t;
+
+static inline double coerce_ptr_to_double(hack_t h)
+{
+ h.val ^= 3; // unset the last two bits.
+ return h.d;
+}
+
+
+#define VOODOO_DOUBLE(d) (*(VALUE*)(&d))
+#define DBL2FIXFLOAT(d) (VOODOO_DOUBLE(d) | FIXFLOAT_FLAG)
+#define FIXABLE_DBL(d) (!(VOODOO_DOUBLE(d) & FIXFLOAT_FLAG))
+#define FIXFLOAT_P(v) (((VALUE)v & FIXFLOAT_FLAG) == FIXFLOAT_FLAG)
+#define FIXFLOAT2DBL(v) coerce_ptr_to_double((hack_t)v)
+
+
+
#if WITH_OBJC
# define SYMBOL_P(x) (TYPE(x) == T_SYMBOL)
# define ID2SYM(x) (rb_id2str((ID)x))
@@ -252,6 +272,7 @@
RUBY_IMMEDIATE_MASK = 0x03,
RUBY_FIXNUM_FLAG = 0x01,
+ RUBY_FIXFLOAT_FLAG = 0x03,
#if !WITH_OBJC
RUBY_SYMBOL_FLAG = 0x0e,
#endif
@@ -264,6 +285,7 @@
#define Qundef ((VALUE)RUBY_Qundef) /* undefined value for placeholder */
#define IMMEDIATE_MASK RUBY_IMMEDIATE_MASK
#define FIXNUM_FLAG RUBY_FIXNUM_FLAG
+#define FIXFLOAT_FLAG RUBY_FIXFLOAT_FLAG
#if !WITH_OBJC
# define SYMBOL_FLAG RUBY_SYMBOL_FLAG
#endif
@@ -300,6 +322,7 @@
#if WITH_OBJC
RUBY_T_NATIVE = 0x16,
#endif
+ RUBY_T_FIXFLOAT = 0x17,
RUBY_T_UNDEF = 0x1b,
RUBY_T_NODE = 0x1c,
@@ -323,6 +346,7 @@
#define T_BIGNUM RUBY_T_BIGNUM
#define T_FILE RUBY_T_FILE
#define T_FIXNUM RUBY_T_FIXNUM
+#define T_FIXFLOAT RUBY_T_FIXFLOAT
#if WITH_OBJC
# define T_NATIVE RUBY_T_NATIVE
#endif
@@ -535,7 +559,7 @@
struct RBasic basic;
double float_value;
};
-#define RFLOAT_VALUE(v) (RFLOAT(v)->float_value)
+#define RFLOAT_VALUE(v) (FIXFLOAT_P(v) ? FIXFLOAT2DBL(v) : RFLOAT(v)->float_value)
#define DOUBLE2NUM(dbl) rb_float_new(dbl)
#if WITH_OBJC
@@ -1020,6 +1044,7 @@
RUBY_EXTERN VALUE rb_cEnumerator;
RUBY_EXTERN VALUE rb_cFile;
RUBY_EXTERN VALUE rb_cFixnum;
+RUBY_EXTERN VALUE rb_cFixFloat;
RUBY_EXTERN VALUE rb_cFloat;
RUBY_EXTERN VALUE rb_cHash;
RUBY_EXTERN VALUE rb_cInteger;
@@ -1149,6 +1174,7 @@
#define CONDITION_TO_BOOLEAN(c) ((c) ? Qtrue : Qfalse)
VALUE rb_box_fixnum(VALUE);
+VALUE rb_box_fixfloat(VALUE);
static inline id
rb_rval_to_ocid(VALUE obj)
@@ -1165,7 +1191,10 @@
}
if (FIXNUM_P(obj)) {
return (id)rb_box_fixnum(obj);
- }
+ }
+ if (FIXFLOAT_P(obj)) {
+ return (id)rb_box_fixfloat(obj);
+ }
}
return (id)obj;
}
@@ -1185,6 +1214,10 @@
if (*(Class *)obj == (Class)rb_cFixnum) {
return LONG2FIX(RFIXNUM(obj)->value);
}
+ if (*(Class *)obj == (Class)rb_cFixFloat) {
+ extern VALUE rb_float_new(double);
+ return rb_float_new(RFLOAT(obj)->float_value);
+ }
if (*(Class *)obj == (Class)rb_cCFNumber) {
/* TODO NSNumber should implement the Numeric primitive methods */
if (CFNumberIsFloatType((CFNumberRef)obj)) {
@@ -1218,6 +1251,7 @@
{
if (IMMEDIATE_P(obj)) {
if (FIXNUM_P(obj)) return rb_cFixnum;
+ if (FIXFLOAT_P(obj)) return rb_cFixFloat;
if (obj == Qtrue) return rb_cTrueClass;
#if !WITH_OBJC
if (SYMBOL_P(obj)) return rb_cSymbol;
@@ -1238,6 +1272,9 @@
if (FIXNUM_P(obj)) {
return T_FIXNUM;
}
+ if (FIXFLOAT_P(obj)) {
+ return T_FLOAT;
+ }
if (obj == Qtrue) {
return T_TRUE;
}
@@ -1289,6 +1326,9 @@
if (k == (Class)rb_cFixnum) {
return T_FIXNUM;
}
+ if (k == (Class)rb_cFixFloat) {
+ return T_FLOAT;
+ }
if (NATIVE(obj)) {
return T_NATIVE;
}
Modified: MacRuby/branches/fp-optimized-experimental/numeric.c
===================================================================
--- MacRuby/branches/fp-optimized-experimental/numeric.c 2009-06-03 19:43:40 UTC (rev 1708)
+++ MacRuby/branches/fp-optimized-experimental/numeric.c 2009-06-03 19:46:18 UTC (rev 1709)
@@ -87,6 +87,7 @@
VALUE rb_cFloat;
VALUE rb_cInteger;
VALUE rb_cFixnum;
+VALUE rb_cFixFloat;
VALUE rb_eZeroDivError;
VALUE rb_eFloatDomainError;
@@ -95,6 +96,15 @@
static struct RFixnum *fixnum_cache = NULL;
VALUE
+rb_box_fixfloat(VALUE fixfloat)
+{
+ struct RFloat *val = malloc(sizeof(struct RFloat));
+ (val->basic).klass = rb_cFixFloat;
+ val->float_value = NUM2DBL(fixfloat);
+ return (VALUE)val;
+}
+
+VALUE
rb_box_fixnum(VALUE fixnum)
{
struct RFixnum *val;
@@ -532,6 +542,7 @@
VALUE
rb_float_new(double d)
{
+ if (FIXABLE_DBL(d)) return DBL2FIXFLOAT(d);
NEWOBJ(flt, struct RFloat);
OBJSETUP(flt, rb_cFloat, T_FLOAT);
@@ -3368,6 +3379,9 @@
rb_objc_define_method(rb_cFloat, "nan?", flo_is_nan_p, 0);
rb_objc_define_method(rb_cFloat, "infinite?", flo_is_infinite_p, 0);
rb_objc_define_method(rb_cFloat, "finite?", flo_is_finite_p, 0);
-
+
+ rb_cFixFloat = rb_define_class("FixFloat", rb_cFloat);
+ rb_undef_method(CLASS_OF(rb_cFixFloat), "new");
+
rb_install_nsnumber_primitives();
}
Modified: MacRuby/branches/fp-optimized-experimental/object.c
===================================================================
--- MacRuby/branches/fp-optimized-experimental/object.c 2009-06-03 19:43:40 UTC (rev 1708)
+++ MacRuby/branches/fp-optimized-experimental/object.c 2009-06-03 19:46:18 UTC (rev 1709)
@@ -2484,7 +2484,6 @@
switch (TYPE(val)) {
case T_FLOAT:
return RFLOAT_VALUE(val);
-
case T_STRING:
rb_raise(rb_eTypeError, "no implicit conversion to float from string");
break;
Modified: MacRuby/branches/fp-optimized-experimental/vm.cpp
===================================================================
--- MacRuby/branches/fp-optimized-experimental/vm.cpp 2009-06-03 19:43:40 UTC (rev 1708)
+++ MacRuby/branches/fp-optimized-experimental/vm.cpp 2009-06-03 19:46:18 UTC (rev 1709)
@@ -207,7 +207,7 @@
emp = new ExistingModuleProvider(RoxorCompiler::module);
jmm = new RoxorJITManager;
- ee = ExecutionEngine::createJIT(emp, 0, jmm, CodeGenOpt::None);
+ ee = ExecutionEngine::createJIT(emp, 0, jmm, CodeGenOpt::None);
assert(ee != NULL);
fpm = new FunctionPassManager(emp);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20090603/812ed2c1/attachment-0001.html>
More information about the macruby-changes
mailing list