Mercurial > projects > ldc
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 } |