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 2013/07/14 02:14:53 UTC

[lucy-commits] [7/7] git commit: refs/heads/ivars-wip1 - Limit IVARS structs to members in this parcel.

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 <ma...@rectangular.com>
Authored: Fri Jul 12 17:22:12 2013 -0700
Committer: Marvin Humphrey <ma...@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;