lib/core: Added prefetching of 4 chars at once on `NativeString`
authorLucas Bajolet <r4pass@hotmail.com>
Tue, 8 Dec 2015 18:12:05 +0000 (13:12 -0500)
committerLucas Bajolet <r4pass@hotmail.com>
Tue, 29 Dec 2015 04:49:28 +0000 (23:49 -0500)
Signed-off-by: Lucas Bajolet <r4pass@hotmail.com>

lib/core/text/native.nit
src/compiler/abstract_compiler.nit

index 9ea8382..d370ee8 100644 (file)
@@ -14,6 +14,24 @@ module native
 import kernel
 import math
 
+in "C" `{
+#ifdef __linux__
+       #include <endian.h>
+#endif
+#ifdef __APPLE__
+       #include <libkern/OSByteOrder.h>
+       #define be32toh(x) OSSwapBigToHostInt32(x)
+#endif
+
+#ifdef __pnacl__
+       #define be16toh(val) (((val) >> 8) | ((val) << 8))
+       #define be32toh(val) ((be16toh((val) << 16) | (be16toh((val) >> 16))))
+#endif
+#ifndef be32toh
+       #define be32toh(val) betoh32(val)
+#endif
+`}
+
 redef class Byte
        # Gives the length of the UTF-8 char starting with `self`
        fun u8len: Int do
@@ -200,4 +218,14 @@ extern class NativeString `{ char* `}
                end
                return ln
        end
+
+       # Fetch 4 chars in `self` at `pos`
+       fun fetch_4_chars(pos: Int): Int is intern do return fetch_4_ffi(pos)
+
+       # Fetch 4 chars in `self` at `pos`
+       fun fetch_4_hchars(pos: Int): Int is intern do return fetch_4h_ffi(pos)
+
+       # FIXME: To remove when bootstrap supports PR #1898
+       private fun fetch_4_ffi(pos: Int): Int `{ return (long)*((uint32_t*)(self+pos)); `}
+       private fun fetch_4h_ffi(pos: Int): Int `{ return (long)be32toh(*((uint32_t*)(self+pos))); `}
 end
index 905812e..86f79e7 100644 (file)
@@ -654,9 +654,21 @@ abstract class AbstractCompiler
                self.header.add_decl("#include <sys/types.h>\n")
                self.header.add_decl("#include <unistd.h>\n")
                self.header.add_decl("#include <stdint.h>\n")
+               self.header.add_decl("#ifdef __linux__")
+               self.header.add_decl("  #include <endian.h>")
+               self.header.add_decl("#endif")
                self.header.add_decl("#include <inttypes.h>\n")
                self.header.add_decl("#include \"gc_chooser.h\"")
+               self.header.add_decl("#ifdef __APPLE__")
+               self.header.add_decl("  #include <libkern/OSByteOrder.h>")
+               self.header.add_decl("  #define be32toh(x) OSSwapBigToHostInt32(x)")
+               self.header.add_decl("#endif")
+               self.header.add_decl("#ifdef __pnacl__")
+               self.header.add_decl("  #define be16toh(val) (((val) >> 8) | ((val) << 8))")
+               self.header.add_decl("  #define be32toh(val) ((be16toh((val) << 16) | (be16toh((val) >> 16))))")
+               self.header.add_decl("#endif")
                self.header.add_decl("#ifdef ANDROID")
+               self.header.add_decl("  #define be32toh(val) betoh32(val)")
                self.header.add_decl("  #include <android/log.h>")
                self.header.add_decl("  #define PRINT_ERROR(...) (void)__android_log_print(ANDROID_LOG_WARN, \"Nit\", __VA_ARGS__)")
                self.header.add_decl("#else")
@@ -2487,9 +2499,22 @@ redef class AMethPropdef
                        else if pname == "fast_cstring" then
                                v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null)))
                                return true
+                       else if pname == "==" then
+                               v.ret(v.equal_test(arguments[0], arguments[1]))
+                               return true
+                       else if pname == "!=" then
+                               var res = v.equal_test(arguments[0], arguments[1])
+                               v.ret(v.new_expr("!{res}", ret.as(not null)))
+                               return true
                        else if pname == "new" then
                                v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null)))
                                return true
+                       else if pname == "fetch_4_chars" then
+                               v.ret(v.new_expr("(long)*((uint32_t*)({arguments[0]} + {arguments[1]}))", ret.as(not null)))
+                               return true
+                       else if pname == "fetch_4_hchars" then
+                               v.ret(v.new_expr("(long)be32toh(*((uint32_t*)({arguments[0]} + {arguments[1]})))", ret.as(not null)))
+                               return true
                        end
                else if cname == "NativeArray" then
                        return v.native_array_def(pname, ret, arguments)