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/05/28 13:36:57 UTC
[4/6] lucy-clownfish git commit: Don't over-optimize final methods.
Don't over-optimize final methods.
It is only valid to resolve a final method to a specific implementing
function when that function resides in the same parcel as the invocant.
A ancestor class in another parcel has the option of adding or removing
an implementation, so the descendant class cannot know for sure what
function it should resolve to.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/3c71bc73
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/3c71bc73
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/3c71bc73
Branch: refs/heads/master
Commit: 3c71bc735463cd58a831c515baa7301f5234038d
Parents: 5103537
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Wed May 20 16:40:56 2015 -0700
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Wed May 27 15:40:38 2015 -0700
----------------------------------------------------------------------
compiler/src/CFCBindMethod.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/3c71bc73/compiler/src/CFCBindMethod.c
----------------------------------------------------------------------
diff --git a/compiler/src/CFCBindMethod.c b/compiler/src/CFCBindMethod.c
index 567812b..925f481 100644
--- a/compiler/src/CFCBindMethod.c
+++ b/compiler/src/CFCBindMethod.c
@@ -39,7 +39,7 @@ S_method_def(CFCMethod *method, CFCClass *klass, int optimized_final_meth);
* directly, since this method may not be overridden.
*/
static char*
-S_final_method_def(CFCMethod *method, CFCClass *klass) {
+S_optimized_final_method_def(CFCMethod *method, CFCClass *klass) {
return S_method_def(method, klass, true);
}
@@ -52,12 +52,20 @@ S_virtual_method_def(CFCMethod *method, CFCClass *klass) {
char*
CFCBindMeth_method_def(CFCMethod *method, CFCClass *klass) {
+ // If the method is final and the class where it is declared final is in
+ // the same parcel as the invocant, we can optimize the call by resolving
+ // to the implementing function directly.
if (CFCMethod_final(method)) {
- return S_final_method_def(method, klass);
- }
- else {
- return S_virtual_method_def(method, klass);
+ CFCClass *ancestor = klass;
+ while (ancestor && !CFCMethod_is_fresh(method, ancestor)) {
+ ancestor = CFCClass_get_parent(ancestor);
+ }
+ if (CFCClass_get_parcel(ancestor) == CFCClass_get_parcel(klass)) {
+ return S_optimized_final_method_def(method, klass);
+ }
}
+
+ return S_virtual_method_def(method, klass);
}
static char*