Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

a more efficient class flags mechanism, reduced the number of default…

… slots in RubyObjects to 4, misc fixes

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@4153 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
commit f82d58b7fecb8c0145e2985a24f0be9d900e2877 1 parent 4d43c05
Laurent Sansonetti authored
Showing with 88 additions and 36 deletions.
  1. +6 −24 class.c
  2. +68 −2 class.h
  3. +2 −0  eval.c
  4. +2 −2 object.c
  5. +6 −6 vm.cpp
  6. +4 −2 vm.h
View
30 class.c
@@ -42,7 +42,7 @@ static void *
rb_obj_imp_allocWithZone(void *rcv, SEL sel, void *zone)
{
// XXX honor zone?
- return (void *)rb_robject_allocate_instance((VALUE)rcv);
+ return (void *)rb_vm_new_rb_object((VALUE)rcv);
}
static void *
@@ -1253,32 +1253,14 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
return 0;
}
-static void *rb_class_flags_key = NULL;
-
-static unsigned long
-rb_class_get_mask(Class k)
-{
- return (unsigned long)rb_objc_get_associative_ref(k, &rb_class_flags_key);
-}
-
-static void
-rb_class_set_mask(Class k, unsigned long mask)
-{
- rb_objc_set_associative_ref(k, &rb_class_flags_key, (void *)mask);
-}
-
-#define RCLASS_MASK_TYPE_SHIFT 16
-
-unsigned long
-rb_class_get_flags(Class k)
-{
- return rb_class_get_mask(k) >> RCLASS_MASK_TYPE_SHIFT;
-}
+rb_class_flags_cache_t *rb_class_flags;
void
-rb_class_set_flags(Class k, unsigned long flags)
+Init_PreClass(void)
{
- rb_class_set_mask(k, flags << RCLASS_MASK_TYPE_SHIFT);
+ rb_class_flags = (rb_class_flags_cache_t *)calloc(CACHE_SIZE,
+ sizeof(rb_class_flags_cache_t));
+ assert(rb_class_flags != NULL);
}
static int
View
70 class.h
@@ -24,8 +24,74 @@ extern "C" {
#define RCLASS_SCOPE_MOD_FUNC (1<<14) /* class opened for module_function methods */
#define RCLASS_KVO_CHECK_DONE (1<<15) /* class created by KVO and flags merged */
-unsigned long rb_class_get_flags(Class k);
-void rb_class_set_flags(Class k, unsigned long flags);
+typedef struct rb_class_flags_cache {
+ Class klass;
+ unsigned long value;
+ struct rb_class_flags_cache *next;
+} rb_class_flags_cache_t;
+
+#define CACHE_SIZE 0x1000
+
+extern rb_class_flags_cache_t *rb_class_flags;
+
+static unsigned int
+rb_class_flags_hash(Class k)
+{
+ return ((unsigned long)k >> 2) & (CACHE_SIZE - 1);
+}
+
+static inline unsigned long
+rb_class_get_mask(Class k)
+{
+ rb_class_flags_cache_t *e = &rb_class_flags[rb_class_flags_hash(k)];
+ while (e != NULL) {
+ if (e->klass == k) {
+ return e->value;
+ }
+ e = e->next;
+ }
+ return 0;
+}
+
+static inline void
+rb_class_set_mask(Class k, unsigned long mask)
+{
+ rb_class_flags_cache_t *e = &rb_class_flags[rb_class_flags_hash(k)];
+again:
+ if (e->klass == k) {
+set_value:
+ e->value = mask;
+ return;
+ }
+ if (e->klass == 0) {
+ e->klass = k;
+ goto set_value;
+ }
+ if (e->next != NULL) {
+ e = e->next;
+ goto again;
+ }
+ rb_class_flags_cache_t *ne = (rb_class_flags_cache_t *)malloc(
+ sizeof(rb_class_flags_cache_t));
+ ne->klass = k;
+ ne->value = mask;
+ ne->next = NULL;
+ e->next = ne;
+}
+
+#define RCLASS_MASK_TYPE_SHIFT 16
+
+static inline unsigned long
+rb_class_get_flags(Class k)
+{
+ return rb_class_get_mask(k) >> RCLASS_MASK_TYPE_SHIFT;
+}
+
+static inline void
+rb_class_set_flags(Class k, unsigned long flags)
+{
+ rb_class_set_mask(k, flags << RCLASS_MASK_TYPE_SHIFT);
+}
#define RCLASS_VERSION(m) (rb_class_get_flags((Class)m))
#define RCLASS_SET_VERSION(m,f) (rb_class_set_flags((Class)m, (unsigned long)f))
View
2  eval.c
@@ -39,6 +39,7 @@ void rb_call_inits(void);
void Init_ext(void);
void Init_PreGC(void);
void Init_PreVM(void);
+void Init_PreClass(void);
void Init_PreGCD(void);
void Init_PreEncoding(void);
@@ -74,6 +75,7 @@ ruby_init(void)
}
}
+ Init_PreClass(); // requires nothing
Init_PreGC(); // requires nothing
Init_PreVM(); // requires nothing
Init_PreGCD(); // requires nothing
View
4 object.c
@@ -362,7 +362,7 @@ rb_nsobj_dup(VALUE obj, VALUE sel)
return (VALUE)objc_msgSend((id)obj, selCopy);
}
- VALUE copy = rb_robject_allocate_instance(klass);
+ VALUE copy = rb_vm_new_rb_object(klass);
rb_obj_init_copy(copy, 0, (VALUE)obj);
return copy;
}
@@ -1894,7 +1894,7 @@ rb_obj_alloc0(VALUE klass)
if ((RCLASS_VERSION(*(void **)klass) & RCLASS_HAS_ROBJECT_ALLOC) == RCLASS_HAS_ROBJECT_ALLOC) {
// Fast path!
- return rb_robject_allocate_instance(klass);
+ return rb_vm_new_rb_object(klass);
}
return rb_vm_call_with_cache(allocCache, klass, selAlloc, 0, NULL);
}
View
12 vm.cpp
@@ -1022,7 +1022,7 @@ RoxorCore::add_method(Class klass, SEL sel, IMP imp, IMP ruby_imp,
sel_getName(sel));
#endif
assert(val != NULL);
- *(bool *)val = true;
+ *(unsigned char *)val = 1;
}
}
@@ -1039,8 +1039,8 @@ RoxorCore::add_method(Class klass, SEL sel, IMP imp, IMP ruby_imp,
VALUE included_in_classes = rb_attr_get((VALUE)klass,
idIncludedInClasses);
if (included_in_classes != Qnil) {
- int i, count = RARRAY_LEN(included_in_classes);
- for (i = 0; i < count; i++) {
+ for (int i = 0, count = RARRAY_LEN(included_in_classes);
+ i < count; i++) {
VALUE mod = RARRAY_AT(included_in_classes, i);
#if ROXOR_VM_DEBUG
printf("forward %c[%s %s] with imp %p node %p types %s\n",
@@ -1781,7 +1781,7 @@ RoxorCore::resolve_method(Class klass, SEL sel, Function *func,
if (iter == objc_to_ruby_stubs.end()) {
Function *objc_func = RoxorCompiler::shared->compile_objc_stub(func,
imp, arity, types);
- objc_imp = compile(objc_func, false);
+ objc_imp = compile(objc_func);
objc_to_ruby_stubs[imp] = objc_imp;
}
else {
@@ -4695,8 +4695,8 @@ resources_path(char *path, size_t len)
url = CFBundleCopyResourcesDirectoryURL(bundle);
*path = '-';
*(path+1) = 'I';
- assert(CFURLGetFileSystemRepresentation(
- url, true, (UInt8 *)&path[2], len - 2));
+ assert(CFURLGetFileSystemRepresentation(url, true, (UInt8 *)&path[2],
+ len - 2));
CFRelease(url);
return path;
View
6 vm.h
@@ -343,6 +343,8 @@ typedef struct {
#define SLOT_CACHE_VIRGIN -2
#define SLOT_CACHE_CANNOT -1
+#define RB_OBJECT_DEFAULT_NUM_SLOTS 4
+
typedef struct {
struct RBasic basic;
rb_object_ivar_slot_t *slots;
@@ -386,9 +388,9 @@ rb_vm_set_ivar_from_slot(VALUE obj, VALUE val, int slot)
}
static inline VALUE
-rb_robject_allocate_instance(VALUE klass)
+rb_vm_new_rb_object(VALUE klass)
{
- const int num_slots = 10;
+ const int num_slots = RB_OBJECT_DEFAULT_NUM_SLOTS;
rb_object_t *obj = (rb_object_t *)rb_objc_newobj(sizeof(rb_object_t));
GC_WB(&obj->slots, xmalloc(sizeof(rb_object_ivar_slot_t) * num_slots));
Please sign in to comment.
Something went wrong with that request. Please try again.