You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2015/07/27 18:35:31 UTC

[3/4] lucy-clownfish git commit: Store MethSpecs in a single array

Store MethSpecs in a single array

Reduces size of ClassSpec struct and number of relocations.


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

Branch: refs/heads/master
Commit: 5c7144b6a63ef6d483496ce713c7f4a0184a1d1c
Parents: 05068aa
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Fri Jul 24 14:06:13 2015 +0200
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Mon Jul 27 18:26:18 2015 +0200

----------------------------------------------------------------------
 compiler/src/CFCBindSpecs.c      | 209 +++++++++++++---------------------
 runtime/core/Clownfish/Class.c   |  21 +++-
 runtime/core/Clownfish/Class.cfh |   5 +-
 3 files changed, 101 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5c7144b6/compiler/src/CFCBindSpecs.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindSpecs.c b/compiler/src/CFCBindSpecs.c
index ff64eca..f3b377d 100644
--- a/compiler/src/CFCBindSpecs.c
+++ b/compiler/src/CFCBindSpecs.c
@@ -43,21 +43,21 @@ struct CFCBindSpecs {
 static char*
 S_ivars_size(CFCClass *klass);
 
-static char*
-S_novel_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
-             int meth_index);
+static void
+S_add_novel_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
+                 int meth_index);
 
 static char*
 S_parent_offset(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
                 const char *meth_type, int meth_index);
 
-static char*
-S_overridden_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
-                  int meth_index);
+static void
+S_add_overridden_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
+                      int meth_index);
 
-static char*
-S_inherited_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
-                 int meth_index);
+static void
+S_add_inherited_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
+                     int meth_index);
 
 static const CFCMeta CFCBINDSPECS_META = {
     "Clownfish::CFC::Binding::Core::Specs",
@@ -125,9 +125,6 @@ CFCBindSpecs_get_typedefs() {
         "    uint32_t      num_novel_meths;\n"
         "    uint32_t      num_overridden_meths;\n"
         "    uint32_t      num_inherited_meths;\n"
-        "    const cfish_NovelMethSpec      *novel_meth_specs;\n"
-        "    const cfish_OverriddenMethSpec *overridden_meth_specs;\n"
-        "    const cfish_InheritedMethSpec  *inherited_meth_specs;\n"
         "} cfish_ClassSpec;\n"
         "\n";
 }
@@ -167,9 +164,6 @@ CFCBindSpecs_add_class(CFCBindSpecs *self, CFCClass *klass) {
         }
     }
 
-    char *novel_specs      = CFCUtil_strdup("");
-    char *overridden_specs = CFCUtil_strdup("");
-    char *inherited_specs  = CFCUtil_strdup("");
     int num_new_novel      = 0;
     int num_new_overridden = 0;
     int num_new_inherited  = 0;
@@ -180,91 +174,23 @@ CFCBindSpecs_add_class(CFCBindSpecs *self, CFCClass *klass) {
 
         if (CFCMethod_is_fresh(method, klass)) {
             if (CFCMethod_novel(method)) {
-                const char *sep = num_new_novel == 0 ? "" : ",\n";
-                char *def = S_novel_meth(self, method, klass, num_new_novel);
-                novel_specs = CFCUtil_cat(novel_specs, sep, def, NULL);
-                FREEMEM(def);
+                int meth_index = self->num_novel + num_new_novel;
+                S_add_novel_meth(self, method, klass, meth_index);
                 ++num_new_novel;
             }
             else {
-                const char *sep = num_new_overridden == 0 ? "" : ",\n";
-                char *def = S_overridden_meth(self, method, klass,
-                                              num_new_overridden);
-                overridden_specs = CFCUtil_cat(overridden_specs, sep, def,
-                                               NULL);
-                FREEMEM(def);
+                int meth_index = self->num_overridden + num_new_overridden;
+                S_add_overridden_meth(self, method, klass, meth_index);
                 ++num_new_overridden;
             }
         }
         else {
-            const char *sep = num_new_inherited == 0 ? "" : ",\n";
-            char *def = S_inherited_meth(self, method, klass,
-                                         num_new_inherited);
-            inherited_specs = CFCUtil_cat(inherited_specs, sep, def, NULL);
-            FREEMEM(def);
+            int meth_index = self->num_inherited + num_new_inherited;
+            S_add_inherited_meth(self, method, klass, meth_index);
             ++num_new_inherited;
         }
     }
 
-    char *novel_spec_var;
-
-    if (num_new_novel) {
-        novel_spec_var = CFCUtil_sprintf("%s_NOVEL_METHS", class_var);
-
-        const char *pattern =
-            "static cfish_NovelMethSpec %s[] = {\n"
-            "%s\n"
-            "};\n"
-            "\n";
-        char *spec_def = CFCUtil_sprintf(pattern, novel_spec_var, novel_specs);
-        self->novel_specs = CFCUtil_cat(self->novel_specs, spec_def, NULL);
-        FREEMEM(spec_def);
-    }
-    else {
-        novel_spec_var = CFCUtil_strdup("NULL");
-    }
-
-    char *overridden_spec_var;
-
-    if (num_new_overridden) {
-        overridden_spec_var = CFCUtil_sprintf("%s_OVERRIDDEN_METHS",
-                                              class_var);
-
-        const char *pattern =
-            "static cfish_OverriddenMethSpec %s[] = {\n"
-            "%s\n"
-            "};\n"
-            "\n";
-        char *spec_def = CFCUtil_sprintf(pattern, overridden_spec_var,
-                                         overridden_specs);
-        self->overridden_specs = CFCUtil_cat(self->overridden_specs, spec_def,
-                                             NULL);
-        FREEMEM(spec_def);
-    }
-    else {
-        overridden_spec_var = CFCUtil_strdup("NULL");
-    }
-
-    char *inherited_spec_var;
-
-    if (num_new_inherited) {
-        inherited_spec_var = CFCUtil_sprintf("%s_INHERITED_METHS", class_var);
-
-        const char *pattern =
-            "static cfish_InheritedMethSpec %s[] = {\n"
-            "%s\n"
-            "};\n"
-            "\n";
-        char *spec_def = CFCUtil_sprintf(pattern, inherited_spec_var,
-                                         inherited_specs);
-        self->inherited_specs = CFCUtil_cat(self->inherited_specs, spec_def,
-                                            NULL);
-        FREEMEM(spec_def);
-    }
-    else {
-        inherited_spec_var = CFCUtil_strdup("NULL");
-    }
-
     char pattern[] =
         "    {\n"
         "        &%s, /* class */\n"
@@ -274,20 +200,12 @@ CFCBindSpecs_add_class(CFCBindSpecs *self, CFCClass *klass) {
         "        &%s, /* ivars_offset_ptr */\n"
         "        %d, /* num_novel */\n"
         "        %d, /* num_overridden */\n"
-        "        %d, /* num_inherited */\n"
-        "        %s,\n"
-        "        %s,\n"
-        "        %s\n"
+        "        %d /* num_inherited */\n"
         "    }";
     char *class_spec
         = CFCUtil_sprintf(pattern, class_var, parent_ptr, class_name,
-                          ivars_size, ivars_offset_name,
-                          num_new_novel,
-                          num_new_overridden,
-                          num_new_inherited,
-                          novel_spec_var,
-                          overridden_spec_var,
-                          inherited_spec_var);
+                          ivars_size, ivars_offset_name, num_new_novel,
+                          num_new_overridden, num_new_inherited);
 
     const char *sep = self->num_specs == 0 ? "" : ",\n";
     self->class_specs = CFCUtil_cat(self->class_specs, sep, class_spec, NULL);
@@ -298,16 +216,42 @@ CFCBindSpecs_add_class(CFCBindSpecs *self, CFCClass *klass) {
     self->num_specs      += 1;
 
     FREEMEM(class_spec);
-    FREEMEM(inherited_spec_var);
-    FREEMEM(overridden_spec_var);
-    FREEMEM(novel_spec_var);
     FREEMEM(parent_ptr);
     FREEMEM(ivars_size);
 }
 
 char*
 CFCBindSpecs_defs(CFCBindSpecs *self) {
-    if (!self->class_specs[0]) { return CFCUtil_strdup(""); }
+    if (self->num_specs == 0) { return CFCUtil_strdup(""); }
+
+    const char *novel_pattern =
+        "static cfish_NovelMethSpec novel_specs[] = {\n"
+        "%s\n"
+        "};\n"
+        "\n";
+    char *novel_specs = self->num_novel == 0
+                        ? CFCUtil_strdup("")
+                        : CFCUtil_sprintf(novel_pattern, self->novel_specs);
+
+    const char *overridden_pattern =
+        "static cfish_OverriddenMethSpec overridden_specs[] = {\n"
+        "%s\n"
+        "};\n"
+        "\n";
+    char *overridden_specs = self->num_overridden == 0
+                             ? CFCUtil_strdup("")
+                             : CFCUtil_sprintf(overridden_pattern,
+                                               self->overridden_specs);
+
+    const char *inherited_pattern =
+        "static cfish_InheritedMethSpec inherited_specs[] = {\n"
+        "%s\n"
+        "};\n"
+        "\n";
+    char *inherited_specs = self->num_inherited == 0
+                            ? CFCUtil_strdup("")
+                            : CFCUtil_sprintf(inherited_pattern,
+                                              self->inherited_specs);
 
     const char *pattern =
         "%s"
@@ -316,9 +260,13 @@ CFCBindSpecs_defs(CFCBindSpecs *self) {
         "static cfish_ClassSpec class_specs[] = {\n"
         "%s\n"
         "};\n";
-    return CFCUtil_sprintf(pattern, self->novel_specs,
-                           self->overridden_specs, self->inherited_specs,
-                           self->class_specs);
+    char *defs = CFCUtil_sprintf(pattern, novel_specs, overridden_specs,
+                                 inherited_specs, self->class_specs);
+
+    FREEMEM(inherited_specs);
+    FREEMEM(overridden_specs);
+    FREEMEM(novel_specs);
+    return defs;
 }
 
 char*
@@ -328,7 +276,8 @@ CFCBindSpecs_init_func_def(CFCBindSpecs *self) {
         "S_bootstrap_specs() {\n"
         "%s"
         "\n"
-        "    cfish_Class_bootstrap(class_specs, %d);\n"
+        "    cfish_Class_bootstrap(class_specs, %d, novel_specs,\n"
+        "                          overridden_specs, inherited_specs);\n"
         "}\n";
     return CFCUtil_sprintf(pattern, self->init_code, self->num_specs);
 }
@@ -359,12 +308,11 @@ S_ivars_size(CFCClass *klass) {
     return ivars_size;
 }
 
-static char*
-S_novel_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
-             int meth_index) {
-    CHY_UNUSED_VAR(self);
-    CHY_UNUSED_VAR(meth_index);
+static void
+S_add_novel_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
+                 int meth_index) {
     const char *meth_name = CFCMethod_get_name(method);
+    const char *sep = meth_index == 0 ? "" : ",\n";
 
     char *full_override_sym;
     if (!CFCMethod_final(method)) {
@@ -387,11 +335,12 @@ S_novel_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
     char *def
         = CFCUtil_sprintf(pattern, full_offset_sym, meth_name, imp_func,
                           full_override_sym);
+    self->novel_specs = CFCUtil_cat(self->novel_specs, sep, def, NULL);
 
+    FREEMEM(def);
     FREEMEM(full_offset_sym);
     FREEMEM(imp_func);
     FREEMEM(full_override_sym);
-    return def;
 }
 
 static char*
@@ -412,9 +361,8 @@ S_parent_offset(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
     else {
         parent_offset = CFCUtil_strdup("NULL");
 
-        const char *class_var = CFCClass_full_class_var(klass);
-        char pattern[] = "    %s_%s_METHS[%d].parent_offset = &%s;\n";
-        char *code = CFCUtil_sprintf(pattern, class_var, meth_type, meth_index,
+        char pattern[] = "    %s_specs[%d].parent_offset = &%s;\n";
+        char *code = CFCUtil_sprintf(pattern, meth_type, meth_index,
                                      parent_offset_sym);
         self->init_code = CFCUtil_cat(self->init_code, code, NULL);
         FREEMEM(code);
@@ -425,12 +373,14 @@ S_parent_offset(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
     return parent_offset;
 }
 
-static char*
-S_overridden_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
-                  int meth_index) {
+static void
+S_add_overridden_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
+                      int meth_index) {
+    const char *sep = meth_index == 0 ? "" : ",\n";
+
     char *imp_func        = CFCMethod_imp_func(method, klass);
     char *full_offset_sym = CFCMethod_full_offset_sym(method, klass);
-    char *parent_offset   = S_parent_offset(self, method, klass, "OVERRIDDEN",
+    char *parent_offset   = S_parent_offset(self, method, klass, "overridden",
                                             meth_index);
 
     char pattern[] =
@@ -441,18 +391,22 @@ S_overridden_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
         "    }";
     char *def
         = CFCUtil_sprintf(pattern, full_offset_sym, parent_offset, imp_func);
+    self->overridden_specs
+        = CFCUtil_cat(self->overridden_specs, sep, def, NULL);
 
+    FREEMEM(def);
     FREEMEM(parent_offset);
     FREEMEM(full_offset_sym);
     FREEMEM(imp_func);
-    return def;
 }
 
-static char*
-S_inherited_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
-                 int meth_index) {
+static void
+S_add_inherited_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
+                     int meth_index) {
+    const char *sep = meth_index == 0 ? "" : ",\n";
+
     char *full_offset_sym = CFCMethod_full_offset_sym(method, klass);
-    char *parent_offset   = S_parent_offset(self, method, klass, "INHERITED",
+    char *parent_offset   = S_parent_offset(self, method, klass, "inherited",
                                             meth_index);
 
     char pattern[] =
@@ -461,9 +415,10 @@ S_inherited_meth(CFCBindSpecs *self, CFCMethod *method, CFCClass *klass,
         "        %s /* parent_offset */\n"
         "    }";
     char *def = CFCUtil_sprintf(pattern, full_offset_sym, parent_offset);
+    self->inherited_specs = CFCUtil_cat(self->inherited_specs, sep, def, NULL);
 
+    FREEMEM(def);
     FREEMEM(full_offset_sym);
     FREEMEM(parent_offset);
-    return def;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5c7144b6/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 47ada81..474e8a2 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -56,8 +56,10 @@ S_claim_parcel_id(void);
 static LockFreeRegistry *Class_registry;
 
 void
-Class_bootstrap(const ClassSpec *specs, size_t num_specs)
-{
+Class_bootstrap(const cfish_ClassSpec *specs, size_t num_specs,
+                const cfish_NovelMethSpec *novel_specs,
+                const cfish_OverriddenMethSpec *overridden_specs,
+                const cfish_InheritedMethSpec *inherited_specs) {
     int32_t parcel_id = S_claim_parcel_id();
 
     /* Pass 1:
@@ -99,6 +101,9 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
      * - Assign parcel_id.
      * - Initialize method pointers and offsets.
      */
+    uint32_t num_novel      = 0;
+    uint32_t num_overridden = 0;
+    uint32_t num_inherited  = 0;
     for (size_t i = 0; i < num_specs; ++i) {
         const ClassSpec *spec = &specs[i];
         Class *klass  = *spec->klass;
@@ -159,18 +164,19 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
         }
 
         for (size_t i = 0; i < spec->num_inherited_meths; ++i) {
-            const InheritedMethSpec *mspec = &spec->inherited_meth_specs[i];
+            const InheritedMethSpec *mspec = &inherited_specs[num_inherited++];
             *mspec->offset = *mspec->parent_offset;
         }
 
         for (size_t i = 0; i < spec->num_overridden_meths; ++i) {
-            const OverriddenMethSpec *mspec = &spec->overridden_meth_specs[i];
+            const OverriddenMethSpec *mspec
+                = &overridden_specs[num_overridden++];
             *mspec->offset = *mspec->parent_offset;
             Class_Override_IMP(klass, mspec->func, *mspec->offset);
         }
 
         for (size_t i = 0; i < spec->num_novel_meths; ++i) {
-            const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
+            const NovelMethSpec *mspec = &novel_specs[num_novel++];
             *mspec->offset = novel_offset;
             novel_offset += sizeof(cfish_method_t);
             Class_Override_IMP(klass, mspec->func, *mspec->offset);
@@ -183,6 +189,9 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
      * - Inititalize name and method array.
      * - Register class.
      */
+    num_novel      = 0;
+    num_overridden = 0;
+    num_inherited  = 0;
     for (size_t i = 0; i < num_specs; ++i) {
         const ClassSpec *spec = &specs[i];
         Class *klass = *spec->klass;
@@ -193,7 +202,7 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
 
         // Only store novel methods for now.
         for (size_t i = 0; i < spec->num_novel_meths; ++i) {
-            const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
+            const NovelMethSpec *mspec = &novel_specs[num_novel++];
             String *name = SSTR_WRAP_UTF8(mspec->name, strlen(mspec->name));
             Method *method = Method_new(name, mspec->callback_func,
                                         *mspec->offset);

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/5c7144b6/runtime/core/Clownfish/Class.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.cfh b/runtime/core/Clownfish/Class.cfh
index be8520e..733e06e 100644
--- a/runtime/core/Clownfish/Class.cfh
+++ b/runtime/core/Clownfish/Class.cfh
@@ -38,7 +38,10 @@ final class Clownfish::Class inherits Clownfish::Obj {
     inert size_t offset_of_parent;
 
     inert void
-    bootstrap(const cfish_ClassSpec *specs, size_t num_specs);
+    bootstrap(const cfish_ClassSpec *specs, size_t num_specs,
+              const cfish_NovelMethSpec *novel_specs,
+              const cfish_OverriddenMethSpec *overridden_specs,
+              const cfish_InheritedMethSpec *inherited_specs);
 
     /** Return a singleton.  If a Class can be found in the registry based on
      * the supplied class name, it will be returned.  Otherwise, a new Class