lucy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mar...@apache.org
Subject [lucy-commits] [7/7] git commit: refs/heads/ivars-wip1 - Limit IVARS structs to members in this parcel.
Date Sun, 14 Jul 2013 00:14:53 GMT
Limit IVARS structs to members in this parcel.

Remove member variables declared in classes from other parcels from the
IVARS structs.  Modify IVARS_OFFSET variables to be non-zero, finishing
the implementation.

Add a dynamically assigned integer parcel_id to VTable which is used to
differentiate which classes belong to different parcels.  At some point
this might be superseded by an actual parcel object of some kind.


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

Branch: refs/heads/ivars-wip1
Commit: 38ad558311c6a8ec89e1827b8f8aff6fe9818a82
Parents: 06d86f1
Author: Marvin Humphrey <marvin@rectangular.com>
Authored: Fri Jul 12 17:22:12 2013 -0700
Committer: Marvin Humphrey <marvin@rectangular.com>
Committed: Sat Jul 13 17:13:19 2013 -0700

----------------------------------------------------------------------
 clownfish/compiler/src/CFCBindClass.c       | 49 ++++++++++++++++--------
 clownfish/compiler/src/CFCBindCore.c        |  3 +-
 clownfish/compiler/src/CFCClass.c           |  5 +++
 clownfish/compiler/src/CFCClass.h           |  3 ++
 clownfish/runtime/core/Clownfish/VTable.c   | 43 ++++++++++++++++++++-
 clownfish/runtime/core/Clownfish/VTable.cfh |  1 +
 6 files changed, 86 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/38ad5583/clownfish/compiler/src/CFCBindClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindClass.c b/clownfish/compiler/src/CFCBindClass.c
index a431d26..59c9093 100644
--- a/clownfish/compiler/src/CFCBindClass.c
+++ b/clownfish/compiler/src/CFCBindClass.c
@@ -26,6 +26,7 @@
 #include "CFCFunction.h"
 #include "CFCMethod.h"
 #include "CFCParamList.h"
+#include "CFCParcel.h"
 #include "CFCType.h"
 #include "CFCVariable.h"
 #include "CFCUtil.h"
@@ -378,19 +379,32 @@ CFCBindClass_to_c_data(CFCBindClass *self) {
 // Create the definition for the instantiable object struct.
 static char*
 S_struct_definition(CFCBindClass *self) {
+    CFCClass *const client = self->client;
     const char *struct_sym;
-    const char *prefix = CFCClass_get_prefix(self->client);
+    const char *prefix = CFCClass_get_prefix(client);
     if (strcmp(prefix, "cfish_") == 0) {
-        struct_sym = CFCClass_full_struct_sym(self->client);
+        struct_sym = CFCClass_full_struct_sym(client);
     }
     else {
-        struct_sym = CFCClass_full_ivars_struct(self->client);
+        struct_sym = CFCClass_full_ivars_struct(client);
     }
 
-    CFCVariable **member_vars = CFCClass_member_vars(self->client);
-    char *member_decs = CFCUtil_strdup("");
+    // Count the number of member variables declared in ancestor classes
+    // outside this package so that we can skip over them.
+    int num_non_package_members = 0;
+    CFCParcel *parcel = CFCClass_get_parcel(client);
+    CFCClass *ancestor = CFCClass_get_parent(client);
+    while (ancestor && CFCClass_get_parcel(ancestor) == parcel) {
+        ancestor = CFCClass_get_parent(ancestor);
+    }
+    if (ancestor) {
+        num_non_package_members = CFCClass_num_member_vars(ancestor);
+    }
 
-    for (int i = 0; member_vars[i] != NULL; i++) {
+    // Add all member variables declared by classes in this package.
+    CFCVariable **member_vars = CFCClass_member_vars(client);
+    char *member_decs = CFCUtil_strdup("");
+    for (int i = num_non_package_members; member_vars[i] != NULL; i++) {
         const char *member_dec = CFCVariable_local_declaration(member_vars[i]);
         size_t needed = strlen(member_decs) + strlen(member_dec) + 10;
         member_decs = (char*)REALLOCATE(member_decs, needed);
@@ -410,10 +424,13 @@ char*
 CFCBindClass_spec_def(CFCBindClass *self) {
     CFCClass *client = self->client;
 
-    CFCClass    *parent     = CFCClass_get_parent(client);
-    const char  *class_name = CFCClass_get_class_name(client);
-    const char  *vt_var     = CFCClass_full_vtable_var(client);
-    const char  *struct_sym = CFCClass_full_struct_sym(client);
+    CFCClass   *parent       = CFCClass_get_parent(client);
+    const char *class_name   = CFCClass_get_class_name(client);
+    const char *vt_var       = CFCClass_full_vtable_var(client);
+    const char *struct_sym   = CFCClass_full_struct_sym(client);
+    const char *ivars_struct = CFCClass_full_ivars_struct(client);
+    const char *prefix       = CFCClass_get_prefix(client);
+    const char *class_cnick  = CFCClass_get_cnick(client);
 
     // Create a pointer to the parent class's vtable.
     char *parent_ref;
@@ -436,23 +453,23 @@ CFCBindClass_spec_def(CFCBindClass *self) {
     FREEMEM(fresh_methods);
     const char *ms_var = num_fresh ? self->method_specs_var : "NULL";
 
-    // Hack to get size of object.  TODO: This will have to be replaced by
-    // dynamic initialization.
-    char *ivars_or_not = strcmp(CFCClass_get_prefix(client), "cfish_") == 0
-                         ? "" : "IVARS";
+    const char *ivars_or_not = strcmp(prefix, "cfish_") == 0
+                               ? struct_sym : ivars_struct;
+    const char *ivars_offset_name = CFCClass_full_ivars_offset(client);
 
     char pattern[] =
         "    {\n"
         "        &%s, /* vtable */\n"
         "        %s, /* parent */\n"
         "        \"%s\", /* name */\n"
-        "        sizeof(%s%s), /* obj_alloc_size */\n"
+        "        sizeof(%s), /* ivars_size */\n"
+        "        &%s, /* ivars_offset_ptr */\n"
         "        %d, /* num_fresh */\n"
         "        %d, /* num_novel */\n"
         "        %s /* method_specs */\n"
         "    }";
     char *code = CFCUtil_sprintf(pattern, vt_var, parent_ref, class_name,
-                                 struct_sym, ivars_or_not,
+                                 ivars_or_not, ivars_offset_name,
                                  num_fresh, num_novel, ms_var);
 
     FREEMEM(parent_ref);

http://git-wip-us.apache.org/repos/asf/lucy/blob/38ad5583/clownfish/compiler/src/CFCBindCore.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCBindCore.c b/clownfish/compiler/src/CFCBindCore.c
index 91721a2..7abc4c2 100644
--- a/clownfish/compiler/src/CFCBindCore.c
+++ b/clownfish/compiler/src/CFCBindCore.c
@@ -235,7 +235,8 @@ S_write_parcel_h(CFCBindCore *self, CFCParcel *parcel) {
         "    cfish_VTable     **vtable;\n"
         "    cfish_VTable     **parent;\n"
         "    const char        *name;\n"
-        "    size_t             obj_alloc_size;\n"
+        "    size_t             ivars_size;\n"
+        "    size_t            *ivars_offset_ptr;\n"
         "    size_t             num_fresh;\n"
         "    size_t             num_novel;\n"
         "    cfish_MethodSpec  *method_specs;\n"

http://git-wip-us.apache.org/repos/asf/lucy/blob/38ad5583/clownfish/compiler/src/CFCClass.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCClass.c b/clownfish/compiler/src/CFCClass.c
index a2eba89..ec65c6a 100644
--- a/clownfish/compiler/src/CFCClass.c
+++ b/clownfish/compiler/src/CFCClass.c
@@ -726,6 +726,11 @@ CFCClass_member_vars(CFCClass *self) {
     return self->member_vars;
 }
 
+size_t
+CFCClass_num_member_vars(CFCClass *self) {
+    return self->num_member_vars;
+}
+
 CFCVariable**
 CFCClass_inert_vars(CFCClass *self) {
     return self->inert_vars;

http://git-wip-us.apache.org/repos/asf/lucy/blob/38ad5583/clownfish/compiler/src/CFCClass.h
----------------------------------------------------------------------
diff --git a/clownfish/compiler/src/CFCClass.h b/clownfish/compiler/src/CFCClass.h
index 3d4d680..e247e3d 100644
--- a/clownfish/compiler/src/CFCClass.h
+++ b/clownfish/compiler/src/CFCClass.h
@@ -199,6 +199,9 @@ CFCClass_num_methods(CFCClass *self);
 struct CFCVariable**
 CFCClass_member_vars(CFCClass *self);
 
+size_t
+CFCClass_num_member_vars(CFCClass *self);
+
 /** Return an array of all inert (shared, class) variables.
  */
 struct CFCVariable**

http://git-wip-us.apache.org/repos/asf/lucy/blob/38ad5583/clownfish/runtime/core/Clownfish/VTable.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/VTable.c b/clownfish/runtime/core/Clownfish/VTable.c
index f278527..268664c 100644
--- a/clownfish/runtime/core/Clownfish/VTable.c
+++ b/clownfish/runtime/core/Clownfish/VTable.c
@@ -46,20 +46,42 @@ S_scrunch_charbuf(CharBuf *source, CharBuf *target);
 static Method*
 S_find_method(VTable *self, const char *meth_name);
 
+static int32_t
+S_claim_parcel_id(void);
+
 LockFreeRegistry *VTable_registry = NULL;
 
 void
 VTable_bootstrap(VTableSpec *specs, size_t num_specs)
 {
+    int32_t parcel_id = S_claim_parcel_id();
+
     /* Pass 1:
+     * - Initialize IVARS_OFFSET.
      * - Allocate memory.
      * - Initialize parent, flags, obj_alloc_size, vt_alloc_size.
+     * - Assign parcel_id.
      * - Initialize method pointers.
      */
     for (size_t i = 0; i < num_specs; ++i) {
         VTableSpec *spec   = &specs[i];
         VTable     *parent = spec->parent ? *spec->parent : NULL;
 
+        size_t ivars_offset = 0;
+        if (spec->ivars_offset_ptr != NULL) {
+            if (parent) {
+                VTable *ancestor = parent;
+                while (ancestor && ancestor->parcel_id == parcel_id) {
+                    ancestor = ancestor->parent;
+                }
+                ivars_offset = ancestor ? ancestor->obj_alloc_size : 0;
+                *spec->ivars_offset_ptr = ivars_offset;
+            }
+            else {
+                *spec->ivars_offset_ptr = 0;
+            }
+        }
+
         size_t vt_alloc_size = parent
                                ? parent->vt_alloc_size
                                : offsetof(VTable, method_ptrs);
@@ -67,8 +89,9 @@ VTable_bootstrap(VTableSpec *specs, size_t num_specs)
         VTable *vtable = (VTable*)Memory_wrapped_calloc(vt_alloc_size, 1);
 
         vtable->parent         = parent;
+        vtable->parcel_id      = parcel_id;
         vtable->flags          = 0;
-        vtable->obj_alloc_size = spec->obj_alloc_size;
+        vtable->obj_alloc_size = ivars_offset + spec->ivars_size;
         vtable->vt_alloc_size  = vt_alloc_size;
 
         if (parent) {
@@ -392,4 +415,22 @@ S_find_method(VTable *self, const char *name) {
     return NULL;
 }
 
+static size_t parcel_count;
+
+static int32_t
+S_claim_parcel_id(void) {
+    // TODO: use ordinary cas rather than cas_ptr.
+    union { size_t num; void *ptr; } old_value;
+    union { size_t num; void *ptr; } new_value;
+
+    bool succeeded = false;
+    do {
+        old_value.num = parcel_count;
+        new_value.num = old_value.num + 1;
+        succeeded = Atomic_cas_ptr((void*volatile*)&parcel_count,
+                                   old_value.ptr, new_value.ptr);
+    } while (!succeeded);
+
+    return new_value.num;
+}
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/38ad5583/clownfish/runtime/core/Clownfish/VTable.cfh
----------------------------------------------------------------------
diff --git a/clownfish/runtime/core/Clownfish/VTable.cfh b/clownfish/runtime/core/Clownfish/VTable.cfh
index 3c19d37..6d62f44 100644
--- a/clownfish/runtime/core/Clownfish/VTable.cfh
+++ b/clownfish/runtime/core/Clownfish/VTable.cfh
@@ -28,6 +28,7 @@ class Clownfish::VTable inherits Clownfish::Obj {
     VTable            *parent;
     CharBuf           *name;
     uint32_t           flags;
+    int32_t            parcel_id;
     size_t             obj_alloc_size;
     size_t             vt_alloc_size;
     VArray            *methods;


Mime
View raw message