comparison runtime/internal/memory.d @ 900:177afbf5297b

Solaris compatibility and proc map parsing #183, thanks BlueZeniX!
author Christian Kamm <kamm incasoftware de>
date Thu, 22 Jan 2009 18:53:32 +0100
parents 23d36edea021
children 493d42562733
comparison
equal deleted inserted replaced
899:23d36edea021 900:177afbf5297b
25 */ 25 */
26 module memory; 26 module memory;
27 27
28 version = GC_Use_Dynamic_Ranges; 28 version = GC_Use_Dynamic_Ranges;
29 29
30 // does Posix suffice?
31 version(Posix) 30 version(Posix)
31 {
32 version = GC_Use_Data_Proc_Maps;
33 }
34 version(solaris)
32 { 35 {
33 version = GC_Use_Data_Proc_Maps; 36 version = GC_Use_Data_Proc_Maps;
34 } 37 }
35 38
36 version(GC_Use_Data_Proc_Maps) 39 version(GC_Use_Data_Proc_Maps)
165 { 168 {
166 extern (C) 169 extern (C)
167 { 170 {
168 extern int _data_start__; 171 extern int _data_start__;
169 extern int _bss_end__; 172 extern int _bss_end__;
170 173 }
171 alias _data_start__ Data_Start; 174
172 alias _bss_end__ Data_End; 175 alias _data_start__ Data_Start;
173 } 176 alias _bss_end__ Data_End;
174 } 177 }
175 else version( linux ) 178 else version( linux )
176 { 179 {
177 extern (C) 180 extern (C)
178 { 181 {
184 extern int _bss_start__; 187 extern int _bss_start__;
185 extern int _bss_end__; 188 extern int _bss_end__;
186 extern int __fini_array_end; 189 extern int __fini_array_end;
187 } 190 }
188 191
189 alias __data_start Data_Start; 192 alias __data_start Data_Start;
190 alias _end Data_End; 193 alias _end Data_End;
194 }
195 else version( solaris )
196 {
197 extern(C)
198 {
199 extern int _edata;
200 extern int _end;
201 }
202
203 alias _edata Data_Start;
204 alias _end Data_End;
191 } 205 }
192 206
193 version( GC_Use_Dynamic_Ranges ) 207 version( GC_Use_Dynamic_Ranges )
194 { 208 {
195 private import tango.stdc.stdlib; 209 private import tango.stdc.stdlib;
278 else version(linux) 292 else version(linux)
279 { 293 {
280 dataStart = adjust_up( &Data_Start ); 294 dataStart = adjust_up( &Data_Start );
281 dataEnd = adjust_down( &Data_End ); 295 dataEnd = adjust_down( &Data_End );
282 } 296 }
297 else version(solaris)
298 {
299 dataStart = adjust_up( &Data_Start );
300 dataEnd = adjust_down( &Data_End );
301 }
283 else 302 else
284 { 303 {
285 static assert( false, "Operating system not supported." ); 304 static assert( false, "Operating system not supported." );
286 } 305 }
287 306
288 //TODO: This could use cleanup!
289 version( GC_Use_Data_Proc_Maps ) 307 version( GC_Use_Data_Proc_Maps )
308 {
309 parseDataProcMaps();
310 }
311 }
312
313 version( GC_Use_Data_Proc_Maps )
314 {
315 version(solaris)
316 {
317 typedef long offset_t;
318 enum : uint { PRMAPSZ = 64, MA_WRITE = 0x02 }
319 extern(C)
320 {
321 struct prmap {
322 uintptr_t pr_vaddr; /* virtual address of mapping */
323 size_t pr_size; /* size of mapping in bytes */
324 char[PRMAPSZ] pr_mapname; /* name in /proc/<pid>/object */
325 private offset_t pr_offset; /* offset into mapped object, if any */
326 int pr_mflags; /* protection and attribute flags (see below) */
327 int pr_pagesize; /* pagesize (bytes) for this mapping */
328 int pr_shmid; /* SysV shmid, -1 if not SysV shared memory */
329
330 private int[1] pr_filler;
331 }
332 }
333
334 void parseDataProcMaps()
335 {
336 debug (ProcMaps) printf("initStaticDataPtrs()\n");
337 // http://docs.sun.com/app/docs/doc/816-5174/proc-4
338 prmap pr;
339
340 int fd = open("/proc/self/map", O_RDONLY);
341 scope (exit) close(fd);
342
343 while (prmap.sizeof == read(fd, &pr, prmap.sizeof))
344 if (pr.pr_mflags & MA_WRITE)
345 {
346 void* start = cast(void*) pr.pr_vaddr;
347 void* end = cast(void*)(pr.pr_vaddr + pr.pr_size);
348 debug (ProcMaps) printf(" vmem at %p - %p with size %d bytes\n", start, end, pr.pr_size);
349
350 // Exclude stack and dataStart..dataEnd
351 if ( ( !dataEnd ||
352 !( dataStart >= start && dataEnd <= end ) ) &&
353 !( &pr >= start && &pr < end ) )
354 {
355 // we already have static data from this region. anything else
356 // is heap (%% check)
357 debug (ProcMaps) printf(" Adding map range %p - %p\n", start, end);
358 _d_gc_add_range(start, end);
359 }
360 }
361 }
362 }
363 else
364 {
365 const int S = (void*).sizeof;
366
367 // TODO: This could use cleanup!
368 void parseDataProcMaps()
290 { 369 {
291 // TODO: Exclude zero-mapped regions 370 // TODO: Exclude zero-mapped regions
292 371
293 int fd = open("/proc/self/maps", O_RDONLY); 372 int fd = open("/proc/self/maps", O_RDONLY);
294 ptrdiff_t count; // %% need to configure ret for read.. 373 ptrdiff_t count; // %% need to configure ret for read..
413 } 492 }
414 close(fd); 493 close(fd);
415 } 494 }
416 } 495 }
417 } 496 }
497 }