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*