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