summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro Matsumoto <[email protected]>2012-07-05 23:19:09 +0900
committerYukihiro Matsumoto <[email protected]>2012-07-05 23:19:09 +0900
commit5b3cc4a068ffab7973c819aafd054907f7e52349 (patch)
treedc1c02d152dfee741d600820d2c16b5ecdc7c863 /src
parentff42f8f4854525bfecb1a76252730aaad137080f (diff)
downloadmruby-5b3cc4a068ffab7973c819aafd054907f7e52349.tar.gz
mruby-5b3cc4a068ffab7973c819aafd054907f7e52349.zip
better object_id calculation
Diffstat (limited to 'src')
-rw-r--r--src/etc.c158
1 files changed, 58 insertions, 100 deletions
diff --git a/src/etc.c b/src/etc.c
index 36da0c943..10aba12a0 100644
--- a/src/etc.c
+++ b/src/etc.c
@@ -126,109 +126,67 @@ mrb_block_proc(void)
return mrb_nil_value();//proc_new(mrb_cProc, FALSE);
}
+#include <stdio.h>
+static mrb_int
+float_id(mrb_float f)
+{
+ const char *p = (const char*)&f;
+ int len = sizeof(f);
+ mrb_int id = 0;
+
+ while (len--) {
+ id = id*65599 + *p;
+ p++;
+ }
+ id = id + (id>>5);
+
+ return id;
+}
+
mrb_int
mrb_obj_id(mrb_value obj)
{
- /*
- * 32-bit mrb_value space
- * MSB ------------------------ LSB
- * false 00000000000000000000000000000000
- * true 00000000000000000000000000000010
- * nil 00000000000000000000000000000100
- * undef 00000000000000000000000000000110
- * symbol ssssssssssssssssssssssss00001110
- * object oooooooooooooooooooooooooooooo00 = 0 (mod sizeof(RVALUE))
- * fixnum fffffffffffffffffffffffffffffff1
- *
- * object_id space
- * LSB
- * false 00000000000000000000000000000000
- * true 00000000000000000000000000000010
- * nil 00000000000000000000000000000100
- * undef 00000000000000000000000000000110
- * symbol 000SSSSSSSSSSSSSSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4)
- * object oooooooooooooooooooooooooooooo0 o...o % A = 0
- * fixnum fffffffffffffffffffffffffffffff1 bignum if required
- *
- * where A = sizeof(RVALUE)/4
- *
- * sizeof(RVALUE) is
- * 20 if 32-bit, double is 4-byte aligned
- * 24 if 32-bit, double is 8-byte aligned
- * 40 if 64-bit
- */
- /*
- * 128-bit mrb_value space
- * MSB -------- LSB
- * x86 [0,1] [2,3] [4,5] [6,7] [8,9] [A,B] [C,D] [E,F]
- * 7 6 5 4 3 2 1 0
- * 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF 0123456789ABCDEF
- * FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210 FEDCBA9876543210
- * false 0000000000000000 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000001 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
- * true 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000010 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
- * nil 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000001 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
- * undef 0000000000000000 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000101 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
- * symbol ssssssssssssssss ssssssssssssssss xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000100 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
- * object oooooooooooooooo oooooooooooooo00 = 0 (mod sizeof(RVALUE))
- (1)fixnum 0000000000000001 0000000000000000 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxx00000011 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
- * float 0000000000000001 0000000000000000 0000000000000000 0000000000000000 xxxxxxxx00000011 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
- * <-- mrb_float --> xxxxxxxx00001101 xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx
- *
- * object_id space
- * LSB
- * false 0000000000000000 0000000000000000
- * true 0000000000000000 0000000000000010
- * nil 0000000000000000 0000000000000100
- * undef 0000000000000000 0000000000000110
- * symbol 000SSSSSSSSSSSS SSSSSSSSSSSSSSS0 S...S % A = 4 (S...S = s...s * A + 4)
- * object ooooooooooooooo ooooooooooooooo0 o...o % A = 0
- * fixnum ffffffffffffffff fffffffffffffff1 bignum if required
- *
- * where A = sizeof(RVALUE)/4
- *
- * sizeof(RVALUE) is
- * 20 if 32-bit, double is 4-byte aligned
- * 24 if 32-bit, double is 8-byte aligned
- * 40 if 64-bit
- */
- /* tt:0_27 */
- switch (mrb_type(obj)) {
- case MRB_TT_FREE:
- return 0; /* not define */
- case MRB_TT_FALSE:
- if (mrb_nil_p(obj))
- return 4;
- return 0;
- case MRB_TT_TRUE:
- return 2;
- case MRB_TT_FIXNUM:
- return mrb_fixnum(obj)*2+1; /* odd number */
- case MRB_TT_SYMBOL:
- return SYM2ID(obj) * 2;
- case MRB_TT_UNDEF:
- return 0; /* not define */
- case MRB_TT_FLOAT:
- return (int)mrb_float(obj)*2; /* even number */
- case MRB_TT_OBJECT:
- case MRB_TT_CLASS:
- case MRB_TT_MODULE:
- case MRB_TT_ICLASS:
- case MRB_TT_SCLASS:
- case MRB_TT_PROC:
- case MRB_TT_ARRAY:
- case MRB_TT_HASH:
- case MRB_TT_STRING:
- case MRB_TT_RANGE:
- case MRB_TT_REGEX:
- case MRB_TT_STRUCT:
- case MRB_TT_EXCEPTION:
- case MRB_TT_MATCH:
- case MRB_TT_FILE:
- case MRB_TT_DATA:
- case MRB_TT_THREAD:
- case MRB_TT_THREADGRP:
- default:
- return mrb_fixnum(obj); /* even number */
+ mrb_int tt = obj.tt;
+
+#define MakeID2(p,t) (((intptr_t)(p))^(t))
+#define MakeID(p) MakeID2(p,tt)
+
+ switch (tt) {
+ case MRB_TT_FREE:
+ case MRB_TT_UNDEF:
+ return MakeID(0); /* not define */
+ case MRB_TT_FALSE:
+ if (mrb_nil_p(obj))
+ return MakeID(1);
+ return MakeID(0);
+ case MRB_TT_TRUE:
+ return MakeID(1);
+ case MRB_TT_SYMBOL:
+ return MakeID(SYM2ID(obj));
+ case MRB_TT_FIXNUM:
+ return MakeID2(float_id((mrb_float)mrb_fixnum(obj)), MRB_TT_FLOAT);
+ case MRB_TT_FLOAT:
+ return MakeID(float_id(mrb_float(obj)));
+ case MRB_TT_STRING:
+ case MRB_TT_OBJECT:
+ case MRB_TT_CLASS:
+ case MRB_TT_MODULE:
+ case MRB_TT_ICLASS:
+ case MRB_TT_SCLASS:
+ case MRB_TT_PROC:
+ case MRB_TT_ARRAY:
+ case MRB_TT_HASH:
+ case MRB_TT_RANGE:
+ case MRB_TT_REGEX:
+ case MRB_TT_STRUCT:
+ case MRB_TT_EXCEPTION:
+ case MRB_TT_MATCH:
+ case MRB_TT_FILE:
+ case MRB_TT_DATA:
+ case MRB_TT_THREAD:
+ case MRB_TT_THREADGRP:
+ default:
+ return MakeID(obj.value.p);
}
}