Commits

Anonymous committed 28d8cd8

Testing new method of adding memory ranges to GC by querying the kernel for a memory map. Implementation will change in the future by cleaning it up.

Fixed duplicate symbol in std.math on FreeBSD

  • Participants
  • Parent commits 528cb6a

Comments (0)

Files changed (3)

File d/druntime/gc/gcx.d

         size_t pcache = 0;
         uint changes = 0;
 
-        //printf("marking range: %p -> %p\n", pbot, ptop);
+        debug(PRINTF) printf("marking range: %p -> %p\n", pbot, ptop);
         for (; p1 < p2; p1++)
         {
             auto p = cast(byte *)(*p1);
                 if ((cast(size_t)p & ~(PAGESIZE-1)) == pcache)
                     continue;
 
-		auto pool = findPool(p);
+		          auto pool = findPool(p);
                 if (pool)
                 {
                     size_t offset = cast(size_t)(p - pool.baseAddr);

File d/druntime/rt/memory.d

     {
         extern (C)
         {
-            extern __gshared
-            {
-                int etext;
-                int _end;
-            }
+            int getpid();
+            int sysctl(int*,uint,void*,size_t*,void*,size_t);
+            int printf(const char* fmt, ...);
         }
     }
     else version( Solaris )
     }
 }
 
-
+/**
+ * TODO: Write some OS abstraction so this is tucked away in some C code
+ **/
 void initStaticDataGC()
 {
     version( MinGW )
     }
     else version( FreeBSD )
     {
-        gc_addRange( &etext, cast(size_t) &_end - cast(size_t) &etext );
+        enum
+        {
+            KVME_TYPE_NONE		= 0,
+            KVME_TYPE_DEFAULT	= 1,
+            KVME_TYPE_VNODE		= 2,
+            KVME_TYPE_SWAP		= 3,
+            KVME_TYPE_DEVICE	= 4,
+            KVME_TYPE_PHYS		= 5,
+            KVME_TYPE_DEAD		= 6,
+            KVME_TYPE_SG		= 7,
+            KVME_TYPE_UNKNOWN	= 255,
+
+            KVME_PROT_READ		= 0x00000001,
+            KVME_PROT_WRITE		= 0x00000002,
+            KVME_PROT_EXEC		= 0x00000004,
+
+            KVME_FLAG_COW		= 0x00000001,
+            KVME_FLAG_NEEDS_COPY = 0x00000002,
+        }
+        alias ulong uint64_t;
+        alias uint uint32_t;
+        struct struct_kinfo_vmentry
+        {
+	        int	 kve_structsize;		/* Variable size of record. */
+	        int	 kve_type;			/* Type of map entry. */
+	        uint64_t kve_start;			/* Starting address. */
+	        uint64_t kve_end;			/* Finishing address. */
+	        uint64_t kve_offset;			/* Mapping offset in object */
+	        uint64_t kve_fileid;			/* inode number if vnode */
+	        uint32_t kve_fsid;			/* dev_t of vnode location */
+	        int	 kve_flags;			/* Flags on map entry. */
+	        int	 kve_resident;			/* Number of resident pages. */
+	        int	 kve_private_resident;		/* Number of private pages. */
+	        int	 kve_protection;		/* Protection bitmask. */
+	        int	 kve_ref_count;			/* VM obj ref count. */
+	        int	 kve_shadow_count;		/* VM obj shadow count. */
+	        int	 _kve_pad0;			/* 64bit align next field */
+	        int	 _kve_ispare[16];		/* Space for more stuff. */
+	        /* Truncated before copyout in sysctl */
+	        char	 kve_path[1024];		/* Path to VM obj, if any. */
+        }
+
+        enum size_t VMMAP_BUF_SIZE_MAX_ENT = 256 * struct_kinfo_vmentry.sizeof;
+        int mib[4] = [
+            1,  /* CTL_KERN */
+            14, /* KERN_PROC */
+            32, /* KERN_PROC_VMMAP */
+            getpid  /* pid */
+        ];
+        size_t len;
+        int error;
+
+        // maybe we should just malloc this and free it before returning?
+        char[VMMAP_BUF_SIZE_MAX_ENT] buf;
+
+        error = sysctl(mib.ptr, mib.length, null, &len, null, 0);
+
+        // error from sysctl getting the size of the vmmap
+        if (error)
+            return; // what else can we do at this point?
+
+        len = len * 4 / 3;
+        if (len > VMMAP_BUF_SIZE_MAX_ENT)
+            return; // our buffer isn't big enough
+
+        // error from sysctl getting the vm map
+        error = sysctl(mib.ptr, mib.length, buf.ptr, &len, null, 0);
+
+        int cnt = 0;
+        char* bp = buf.ptr;
+        char* ep = cast(char*)(cast(size_t)buf.ptr + cast(size_t)len);
+
+        while (bp < ep)
+        {
+            struct_kinfo_vmentry* kv = cast(struct_kinfo_vmentry*)bp;
+            bp = cast(char*)(cast(size_t)bp + cast(size_t)kv.kve_structsize);
+            cnt++;
+
+            if (kv.kve_type == KVME_TYPE_DEFAULT &&
+               ( kv.kve_protection & KVME_PROT_READ )
+            )
+            {
+                gc_addRange(cast(void*)kv.kve_start,
+                            cast(size_t)(kv.kve_end - kv.kve_start) );
+            }
+        }
     }
     else version( Solaris )
     {

File d/phobos/std/math.d

     }    
 }
  
-version (GNU_Need_exp2_log2) real exp2(real x) { return std.c.math.powl(2, x); } else
-//real exp2(real x)               { return std.c.math.exp2l(x); }
-
 /******************************************
  * Calculates the value of the natural logarithm base (e)
  * raised to the power of x, minus 1.
         ret PARAMSIZE;
       }
     } else {
-        return std.c.math.exp2(x);
+        version (GNU_Need_exp2_log2)
+        {
+            return std.c.math.powl(2, x);
+        } else {
+            return std.c.math.exp2(x);
+        }
     }    
 }