Merge: Inline intern methods in standard objects
authorJean Privat <jean@pryen.org>
Tue, 3 Mar 2015 15:05:12 +0000 (22:05 +0700)
committerJean Privat <jean@pryen.org>
Tue, 3 Mar 2015 15:05:12 +0000 (22:05 +0700)
Those in primitive types where already inlined, this time it is the ones in Object, NativeArray and other.

A special case remain for `object_id` since the value in standard objects is redefined in primitive type.
So this one is not inlined.

The gain in nitc/nitc/nitc is less that I expected but not that bad.
before: 0m7.276s
after: 0m7.100s (-2.5%)

Bonus: an old bug related to native arrays in --semi-global related to inlining is also fixed.

Pull-Request: #1180
Reviewed-by: Lucas Bajolet <r4pass@hotmail.com>
Reviewed-by: Alexis Laferrière <alexis.laf@xymus.net>
Reviewed-by: Alexandre Terrasa <alexandre@moz-code.org>

src/compiler/separate_compiler.nit
tests/sav/nitg-sg/fixme/test_gen.res [deleted file]

index da2ed1e..a33c098 100644 (file)
@@ -1156,25 +1156,37 @@ class SeparateCompilerVisitor
        redef fun compile_callsite(callsite, args)
        do
                var rta = compiler.runtime_type_analysis
-               var mmethod = callsite.mproperty
                # TODO: Inlining of new-style constructors with initializers
                if compiler.modelbuilder.toolcontext.opt_direct_call_monomorph.value and rta != null and callsite.mpropdef.initializers.is_empty then
                        var tgs = rta.live_targets(callsite)
                        if tgs.length == 1 then
-                               # DIRECT CALL
-                               var res0 = before_send(mmethod, args)
-                               var res = call(tgs.first, tgs.first.mclassdef.bound_mtype, args)
-                               if res0 != null then
-                                       assert res != null
-                                       self.assign(res0, res)
-                                       res = res0
-                               end
-                               add("\}") # close the before_send
-                               return res
+                               return direct_call(tgs.first, args)
                        end
                end
+               # Shortcut intern methods as they are not usually redefinable
+               if callsite.mpropdef.is_intern and callsite.mproperty.name != "object_id" then
+                       # `object_id` is the only redefined intern method, so it can not be directly called.
+                       # TODO find a less ugly approach?
+                       return direct_call(callsite.mpropdef, args)
+               end
                return super
        end
+
+       # Fully and directly call a mpropdef
+       #
+       # This method is used by `compile_callsite`
+       private fun direct_call(mpropdef: MMethodDef, args: Array[RuntimeVariable]): nullable RuntimeVariable
+       do
+               var res0 = before_send(mpropdef.mproperty, args)
+               var res = call(mpropdef, mpropdef.mclassdef.bound_mtype, args)
+               if res0 != null then
+                       assert res != null
+                       self.assign(res0, res)
+                       res = res0
+               end
+               add("\}") # close the before_send
+               return res
+       end
        redef fun send(mmethod, arguments)
        do
                if arguments.first.mcasttype.ctype != "val*" then
@@ -1852,7 +1864,10 @@ class SeparateCompilerVisitor
                var nclass = self.get_class("NativeArray")
                var recv = "((struct instance_{nclass.c_name}*){arguments[0]})->values"
                if pname == "[]" then
-                       self.ret(self.new_expr("{recv}[{arguments[1]}]", ret_type.as(not null)))
+                       # Because the objects are boxed, return the box to avoid unnecessary (or broken) unboxing/reboxing
+                       var res = self.new_expr("{recv}[{arguments[1]}]", compiler.mainmodule.object_type)
+                       res.mcasttype = ret_type.as(not null)
+                       self.ret(res)
                        return
                else if pname == "[]=" then
                        self.add("{recv}[{arguments[1]}]={arguments[2]};")
diff --git a/tests/sav/nitg-sg/fixme/test_gen.res b/tests/sav/nitg-sg/fixme/test_gen.res
deleted file mode 100644 (file)
index 4ad3dc3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-UNDEFINED