You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2015/02/13 22:46:01 UTC

[11/16] lucy-clownfish git commit: Optimize special cases during refcounting.

Optimize special cases during refcounting.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/2dab35a4
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/2dab35a4
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/2dab35a4

Branch: refs/heads/master
Commit: 2dab35a40af89271a193a6b6614968c8cfad96d3
Parents: 886c347
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Sat Feb 7 17:06:53 2015 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Sun Feb 8 12:50:30 2015 -0800

----------------------------------------------------------------------
 compiler/src/CFCBindCore.c     |  2 ++
 runtime/c/src/Clownfish/Obj.c  | 67 +++++++++++++++++++++++++------------
 runtime/core/Clownfish/Class.c | 13 ++++++-
 runtime/perl/xs/XSBind.c       | 47 +++++++++++++++++++-------
 4 files changed, 94 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dab35a4/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindCore.c b/compiler/src/CFCBindCore.c
index 80080b5..c4d7f91 100644
--- a/compiler/src/CFCBindCore.c
+++ b/compiler/src/CFCBindCore.c
@@ -296,6 +296,8 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         "#define CFISH_REFCOUNT_NN(_self) \\\n"
         "    cfish_get_refcount(_self)\n"
         "\n"
+        "/* Flags for internal use. */\n"
+        "#define CFISH_fREFCOUNTSPECIAL 0x00000001\n"
         ;
     const char *cfish_defs_2 =
         "/* Structs for Class initialization.\n"

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dab35a4/runtime/c/src/Clownfish/Obj.c
----------------------------------------------------------------------
diff --git a/runtime/c/src/Clownfish/Obj.c b/runtime/c/src/Clownfish/Obj.c
index 222b283..3db144f 100644
--- a/runtime/c/src/Clownfish/Obj.c
+++ b/runtime/c/src/Clownfish/Obj.c
@@ -15,20 +15,16 @@
  */
 
 #define C_CFISH_OBJ
+#define C_CFISH_CLASS
 #define CFISH_USE_SHORT_NAMES
 
 #include "charmony.h"
 
 #include "Clownfish/Obj.h"
+#include "Clownfish/Class.h"
 #include "Clownfish/Err.h"
 #include "Clownfish/String.h"
 
-uint32_t
-cfish_get_refcount(void *vself) {
-    cfish_Obj *self = (cfish_Obj*)vself;
-    return self->refcount;
-}
-
 static CFISH_INLINE bool
 SI_immortal(cfish_Class *klass) {
     if (klass == CFISH_CLASS
@@ -42,39 +38,66 @@ SI_immortal(cfish_Class *klass) {
 }
 
 static CFISH_INLINE bool
-SI_is_string(cfish_Class *klass) {
+SI_is_string_type(cfish_Class *klass) {
     if (klass == CFISH_STRING || klass == CFISH_STACKSTRING) {
         return true;
     }
     return false;
 }
 
+static CFISH_INLINE bool
+SI_threadsafe_but_not_immortal(cfish_Class *klass) {
+    if (klass == CFISH_LOCKFREEREGISTRY) {
+        return true;
+    }
+    return false;
+}
+
+uint32_t
+cfish_get_refcount(void *vself) {
+    cfish_Obj *self = (cfish_Obj*)vself;
+    return self->refcount;
+}
+
 Obj*
 cfish_inc_refcount(void *vself) {
     Obj *self = (Obj*)vself;
+
+    // Handle special cases.
     cfish_Class *const klass = self->klass;
-    if (SI_immortal(klass)) {
-        return self;
-    }
-    else if (SI_is_string(klass)
-             && CFISH_Str_Is_Copy_On_IncRef((cfish_String*)self)
-            ) {
-        const char *utf8 = CFISH_Str_Get_Ptr8((cfish_String*)self);
-        size_t size = CFISH_Str_Get_Size((cfish_String*)self);
-        return (cfish_Obj*)cfish_Str_new_from_trusted_utf8(utf8, size);
-    }
-    else {
-        self->refcount++;
-        return self;
+    if (klass->flags & CFISH_fREFCOUNTSPECIAL) {
+        if (SI_is_string_type(klass)) {
+            // Only copy-on-incref Strings get special-cased.  Ordinary
+            // strings fall through to the general case.
+            if (CFISH_Str_Is_Copy_On_IncRef((cfish_String*)self)) {
+                const char *utf8 = CFISH_Str_Get_Ptr8((cfish_String*)self);
+                size_t size = CFISH_Str_Get_Size((cfish_String*)self);
+                return (cfish_Obj*)cfish_Str_new_from_trusted_utf8(utf8, size);
+            }
+        }
+        else if (SI_immortal(klass)) {
+            return self;
+        }
+        else if (SI_threadsafe_but_not_immortal(klass)) {
+            // TODO: use atomic operation
+        }
     }
+
+    self->refcount++;
+    return self;
 }
 
 uint32_t
 cfish_dec_refcount(void *vself) {
     cfish_Obj *self = (Obj*)vself;
     cfish_Class *klass = self->klass;
-    if (SI_immortal(klass)) {
-        return self->refcount;
+    if (klass->flags & CFISH_fREFCOUNTSPECIAL) {
+        if (SI_immortal(klass)) {
+            return self->refcount;
+        }
+        else if (SI_threadsafe_but_not_immortal(klass)) {
+            // TODO: use atomic operation
+        }
     }
 
     uint32_t modified_refcount = INT32_MAX;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dab35a4/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index b30b124..478bd6c 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -93,10 +93,21 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
 
         klass->parent           = parent;
         klass->parcel_id        = parcel_id;
-        klass->flags            = 0;
         klass->obj_alloc_size   = ivars_offset + spec->ivars_size;
         klass->class_alloc_size = class_alloc_size;
 
+        klass->flags = 0;
+        if (spec->klass == &CLASS
+            || spec->klass == &METHOD
+            || spec->klass == &BOOLNUM
+            || spec->klass == &HASHTOMBSTONE
+            || spec->klass == &STRING
+            || spec->klass == &STACKSTRING
+            || spec->klass == &LOCKFREEREGISTRY
+           ) {
+            klass->flags |= CFISH_fREFCOUNTSPECIAL;
+        }
+
         if (parent) {
             // Copy parent vtable.
             size_t parent_vt_size = parent->class_alloc_size

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/2dab35a4/runtime/perl/xs/XSBind.c
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index d624ff7..659ab35 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -609,13 +609,21 @@ SI_immortal(cfish_Class *klass) {
 }
 
 static CFISH_INLINE bool
-SI_is_string(cfish_Class *klass) {
+SI_is_string_type(cfish_Class *klass) {
     if (klass == CFISH_STRING || klass == CFISH_STACKSTRING) {
         return true;
     }
     return false;
 }
 
+static CFISH_INLINE bool
+SI_threadsafe_but_not_immortal(cfish_Class *klass) {
+    if (klass == CFISH_LOCKFREEREGISTRY) {
+        return true;
+    }
+    return false;
+}
+
 static void
 S_lazy_init_host_obj(cfish_Obj *self) {
     SV *inner_obj = newSV(0);
@@ -653,16 +661,25 @@ cfish_get_refcount(void *vself) {
 cfish_Obj*
 cfish_inc_refcount(void *vself) {
     cfish_Obj *self = (cfish_Obj*)vself;
+
+    // Handle special cases.
     cfish_Class *const klass = self->klass;
-    if (SI_immortal(klass)) {
-        return self;
-    }
-    else if (SI_is_string(klass)
-             && CFISH_Str_Is_Copy_On_IncRef((cfish_String*)self)
-            ) {
-        const char *utf8 = CFISH_Str_Get_Ptr8((cfish_String*)self);
-        size_t size = CFISH_Str_Get_Size((cfish_String*)self);
-        return (cfish_Obj*)cfish_Str_new_from_trusted_utf8(utf8, size);
+    if (klass->flags & CFISH_fREFCOUNTSPECIAL) {
+        if (SI_is_string_type(klass)) {
+            // Only copy-on-incref Strings get special-cased.  Ordinary
+            // Strings fall through to the general case.
+            if (CFISH_Str_Is_Copy_On_IncRef((cfish_String*)self)) {
+                const char *utf8 = CFISH_Str_Get_Ptr8((cfish_String*)self);
+                size_t size = CFISH_Str_Get_Size((cfish_String*)self);
+                return (cfish_Obj*)cfish_Str_new_from_trusted_utf8(utf8, size);
+            }
+        }
+        else if (SI_immortal(klass)) {
+            return self;
+        }
+        else if (SI_threadsafe_but_not_immortal(klass)) {
+            // TODO: use atomic operation
+        }
     }
 
     if (self->ref.count & XSBIND_REFCOUNT_FLAG) {
@@ -680,9 +697,15 @@ cfish_inc_refcount(void *vself) {
 uint32_t
 cfish_dec_refcount(void *vself) {
     cfish_Obj *self = (cfish_Obj*)vself;
+
     cfish_Class *klass = self->klass;
-    if (SI_immortal(klass)) {
-        return 1;
+    if (klass->flags & CFISH_fREFCOUNTSPECIAL) {
+        if (SI_immortal(klass)) {
+            return 1;
+        }
+        else if (SI_threadsafe_but_not_immortal(klass)) {
+            // TODO: use atomic operation
+        }
     }
 
     uint32_t modified_refcount = I32_MAX;