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;