[MLton-commit] r6885

Wesley Terpstra wesley at mlton.org
Tue Sep 23 08:05:24 PDT 2008


MLton currently uses two functions, GC_getText{Start,End}, to create a giant
lookup table for profiling. These two functions are among the hardest things
to supply when porting MLton. It becomes even harder once shared libraries
are considered, because then one needs to consider which text segment is
intended. After reading the i386 sys v abi specification, I still have no
idea how to do this correctly for shared libraries on elf.

Instead of using these non-portable functions, just rely on the label 
information and do a binary search.


----------------------------------------------------------------------

U   mlton/trunk/runtime/gc/profiling.c
U   mlton/trunk/runtime/gc/sources.c
U   mlton/trunk/runtime/gc/sources.h
U   mlton/trunk/runtime/platform/darwin.c
U   mlton/trunk/runtime/platform/freebsd.c
D   mlton/trunk/runtime/platform/getText.c
U   mlton/trunk/runtime/platform/hpux.c
U   mlton/trunk/runtime/platform/linux.c
U   mlton/trunk/runtime/platform/netbsd.c
U   mlton/trunk/runtime/platform/openbsd.c
U   mlton/trunk/runtime/platform/solaris.c
U   mlton/trunk/runtime/platform/windows.c
U   mlton/trunk/runtime/platform.h

----------------------------------------------------------------------

Modified: mlton/trunk/runtime/gc/profiling.c
===================================================================
--- mlton/trunk/runtime/gc/profiling.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/gc/profiling.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -360,13 +360,32 @@
       sourceSeqsIndex = s->sourceMaps.frameSources[frameIndex];
     else {
       if (PROFILE_TIME_LABEL == s->profiling.kind) {
-      if (s->sourceMaps.textStart <= pc and pc < s->sourceMaps.textEnd)
-        sourceSeqsIndex = s->sourceMaps.textSources [pc - s->sourceMaps.textStart];
-      else {
-        if (DEBUG_PROFILE)
-          fprintf (stderr, "pc out of bounds\n");
-        sourceSeqsIndex = SOURCE_SEQ_UNKNOWN;
-      }
+        uint32_t start, end, i;
+        
+        /* Binary search labels to find which method contains PC */
+        start = 0;
+        end = s->sourceMaps.sourceLabelsLength;
+        while (end - start > 1) {
+          i = (start+end)/2;
+          if ((uintptr_t)s->sourceMaps.sourceLabels[i].label <= (uintptr_t)pc)
+            start = i;
+          else
+            end = i;
+        }
+        i = start;
+        
+        /* The last label is dead code. Any address past it is thus unknown.
+         * The first label is before all SML code. Before it is also unknown.
+         */
+        if (i-1 == s->sourceMaps.sourceLabelsLength ||
+            (i == 0 && 
+             (uintptr_t)pc < (uintptr_t)s->sourceMaps.sourceLabels[i].label)) {
+          if (DEBUG_PROFILE)
+            fprintf (stderr, "pc out of bounds\n");
+          sourceSeqsIndex = SOURCE_SEQ_UNKNOWN;
+        } else {
+          sourceSeqsIndex = s->sourceMaps.sourceLabels[start].sourceSeqIndex;
+        }
       } else {
         sourceSeqsIndex = s->sourceMaps.curSourceSeqsIndex;
       }
@@ -380,7 +399,7 @@
 
   s->profiling.data = profileMalloc (s);
   if (PROFILE_TIME_LABEL == s->profiling.kind) {
-    initTextSources (s);
+    initSourceLabels (s);
   } else {
     s->sourceMaps.curSourceSeqsIndex = SOURCE_SEQ_UNKNOWN;
   }

Modified: mlton/trunk/runtime/gc/sources.c
===================================================================
--- mlton/trunk/runtime/gc/sources.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/gc/sources.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -49,50 +49,40 @@
          compareSourceLabels);
   if (0 == s->sourceMaps.sourceLabels[s->sourceMaps.sourceLabelsLength - 1].label)
     die ("Max source label is 0 -- something is wrong.");
-  if (DEBUG_SOURCES)
-    for (i = 0; i < s->sourceMaps.sourceLabelsLength; i++)
-      fprintf (stderr, FMTPTR"  %"PRIu32"\n",
-               (uintptr_t)s->sourceMaps.sourceLabels[i].label,
-               s->sourceMaps.sourceLabels[i].sourceSeqIndex);
   if (ASSERT)
     for (i = 1; i < s->sourceMaps.sourceLabelsLength; i++)
       assert (s->sourceMaps.sourceLabels[i-1].label
               <= s->sourceMaps.sourceLabels[i].label);
 }
 
-void initTextSources (GC_state s) {
-  GC_sourceLabelIndex i;
-  code_pointer p;
+void compressSourceLabels (GC_state s) {
+  GC_sourceLabelIndex in, out, i;
   GC_sourceSeqIndex sourceSeqIndex;
-
-  sortSourceLabels (s);
-  /* Initialize s->sourceMaps.textSources. */
-  s->sourceMaps.textEnd = GC_getTextEnd();
-  s->sourceMaps.textStart = GC_getTextStart();
-  if (ASSERT)
-    for (i = 0; i < s->sourceMaps.sourceLabelsLength; i++) {
-      code_pointer label;
-
-      label = s->sourceMaps.sourceLabels[i].label;
-      assert (0 == label
-              or (s->sourceMaps.textStart <= label
-                  and label < s->sourceMaps.textEnd));
-    }
-  s->sourceMaps.textSources =
-    (GC_sourceSeqIndex *)
-    (calloc_safe((size_t)(s->sourceMaps.textEnd - s->sourceMaps.textStart), 
-                 sizeof(*(s->sourceMaps.textSources))));
-  p = s->sourceMaps.textStart;
+  
+  /* Eliminate duplicate sourceLabels */
+  out = 0;
   sourceSeqIndex = SOURCE_SEQ_UNKNOWN;
-  for (i = 0; i < s->sourceMaps.sourceLabelsLength; i++) {
-    for ( ; p < s->sourceMaps.sourceLabels[i].label; p++)
-      s->sourceMaps.textSources[p - s->sourceMaps.textStart] = sourceSeqIndex;
-    sourceSeqIndex = s->sourceMaps.sourceLabels[i].sourceSeqIndex;
+  for (in = 0; in < s->sourceMaps.sourceLabelsLength; ++in) {
+    if (s->sourceMaps.sourceLabels[in].sourceSeqIndex != sourceSeqIndex) {
+      s->sourceMaps.sourceLabels[out++] = s->sourceMaps.sourceLabels[in];
+      sourceSeqIndex = s->sourceMaps.sourceLabels[in].sourceSeqIndex;
+    }
   }
-  for ( ; p < s->sourceMaps.textEnd; p++)
-    s->sourceMaps.textSources[p - s->sourceMaps.textStart] = sourceSeqIndex;
+  
+  s->sourceMaps.sourceLabelsLength = out;
+
+  if (DEBUG_SOURCES)
+    for (i = 0; i < s->sourceMaps.sourceLabelsLength; i++)
+      fprintf (stderr, FMTPTR"  %"PRIu32"\n",
+               (uintptr_t)s->sourceMaps.sourceLabels[i].label,
+               s->sourceMaps.sourceLabels[i].sourceSeqIndex);
 }
 
+void initSourceLabels (GC_state s) {
+  sortSourceLabels (s);
+  compressSourceLabels (s);
+}
+
 #endif
 
 void showSources (GC_state s) {

Modified: mlton/trunk/runtime/gc/sources.h
===================================================================
--- mlton/trunk/runtime/gc/sources.h	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/gc/sources.h	2008-09-23 15:05:23 UTC (rev 6885)
@@ -63,12 +63,6 @@
    */
   struct GC_source *sources;
   uint32_t sourcesLength;
-  code_pointer textEnd;
-  /* An array of indices, one entry for each address in the text
-   * segment, giving an index into sourceSeqs.
-   */
-  GC_sourceSeqIndex *textSources;
-  code_pointer textStart;
 };
 
 #endif /* (defined (MLTON_GC_INTERNAL_TYPES)) */
@@ -82,7 +76,8 @@
 #if HAS_TIME_PROFILING
 static inline int compareSourceLabels (const void *v1, const void *v2);
 static void sortSourceLabels (GC_state s);
-static void initTextSources (GC_state s);
+static void compressSourceLabels (GC_state s);
+static void initSourceLabels (GC_state s);
 #endif
 
 static void showSources (GC_state s);

Modified: mlton/trunk/runtime/platform/darwin.c
===================================================================
--- mlton/trunk/runtime/platform/darwin.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform/darwin.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -1,6 +1,5 @@
 #include "platform.h"
 
-#include <mach-o/getsect.h>  // for get_etext()
 #include <dlfcn.h>
 #include <stdio.h>
 
@@ -11,20 +10,6 @@
 #include "sysctl.c"
 #include "use-mmap.c"
 
-code_pointer GC_getTextEnd (void) {
-        return (code_pointer)(long)(get_etext ());
-}
-
-code_pointer GC_getTextStart (void) {
-        void* address;
-        Dl_info info;
-        
-        address = dlsym(RTLD_DEFAULT, "main");
-        dladdr(address, &info);
-        
-        return (code_pointer)info.dli_fbase;
-}
-
 void GC_displayMem (void) {
         static char buffer[256];
 

Modified: mlton/trunk/runtime/platform/freebsd.c
===================================================================
--- mlton/trunk/runtime/platform/freebsd.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform/freebsd.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -1,7 +1,6 @@
 #include "platform.h"
 
 #include "diskBack.unix.c"
-#include "getText.c"
 #include "mkdir2.c"
 #include "mmap-protect.c"
 #include "nonwin.c"

Deleted: mlton/trunk/runtime/platform/getText.c
===================================================================
--- mlton/trunk/runtime/platform/getText.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform/getText.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -1,19 +0,0 @@
-/* To get the beginning and end of the text segment. */
-#if defined(PIC)
-extern unsigned char _init;
-#else
-extern unsigned char _start;
-#endif
-extern unsigned char etext;
-
-code_pointer GC_getTextStart (void) {
-#if defined(PIC)
-        return &_init;
-#else
-        return &_start;
-#endif
-}
-
-code_pointer GC_getTextEnd (void) {
-        return &etext;
-}

Modified: mlton/trunk/runtime/platform/hpux.c
===================================================================
--- mlton/trunk/runtime/platform/hpux.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform/hpux.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -15,17 +15,6 @@
 #include "setenv.putenv.c"
 #include "use-mmap.c"
 
-extern unsigned char __text_start;
-extern unsigned char etext;
-
-code_pointer GC_getTextStart (void) {
-        return &__text_start;
-}
-
-code_pointer GC_getTextEnd (void) {
-        return &etext;
-}
-
 struct pstnames {
         int type;
         const char *name;

Modified: mlton/trunk/runtime/platform/linux.c
===================================================================
--- mlton/trunk/runtime/platform/linux.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform/linux.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -3,7 +3,6 @@
 #include "platform.h"
 
 #include "diskBack.unix.c"
-#include "getText.c"
 #include "mkdir2.c"
 #include "displayMem.linux.c"
 #include "mmap-protect.c"

Modified: mlton/trunk/runtime/platform/netbsd.c
===================================================================
--- mlton/trunk/runtime/platform/netbsd.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform/netbsd.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -1,7 +1,6 @@
 #include "platform.h"
 
 #include "diskBack.unix.c"
-#include "getText.c"
 #include "mkdir2.c"
 #include "displayMem.linux.c"
 #include "mmap-protect.c"

Modified: mlton/trunk/runtime/platform/openbsd.c
===================================================================
--- mlton/trunk/runtime/platform/openbsd.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform/openbsd.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -1,7 +1,6 @@
 #include "platform.h"
 
 #include "diskBack.unix.c"
-#include "getText.c"
 #include "mkdir2.c"
 #include "displayMem.linux.c"
 #include "mmap-protect.c"

Modified: mlton/trunk/runtime/platform/solaris.c
===================================================================
--- mlton/trunk/runtime/platform/solaris.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform/solaris.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -4,7 +4,6 @@
 
 #include "diskBack.unix.c"
 #include "float-math.c"
-#include "getText.c"
 #include "mkdir2.c"
 #include "mmap.c"
 #include "mmap-protect.c"

Modified: mlton/trunk/runtime/platform/windows.c
===================================================================
--- mlton/trunk/runtime/platform/windows.c	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform/windows.c	2008-09-23 15:05:23 UTC (rev 6885)
@@ -348,56 +348,3 @@
         }
         return 0;
 }
-
-static intptr_t text_start = 0;
-static intptr_t text_end   = 0;
-
-/* GNU binutils generate this symbol */
-extern char base_address asm("__image_base__");
-
-static void findTextSegment (void) {
-        PIMAGE_DOS_HEADER dosHeader;
-        PIMAGE_NT_HEADERS ntHeader;
-        PIMAGE_SECTION_HEADER sectionHeader;
-        DWORD entryPoint, start = 0, end = 0;
-        UINT sections, i;
-        char *base = &base_address;
-
-        dosHeader = (PIMAGE_DOS_HEADER)base;
-        if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
-                die("bad dos header magic");
-
-        ntHeader = (PIMAGE_NT_HEADERS)(base + dosHeader->e_lfanew);
-        if (ntHeader->Signature != IMAGE_NT_SIGNATURE)
-                die("bad NT header magic");
-
-        entryPoint = ntHeader->OptionalHeader.AddressOfEntryPoint;
-        sections = ntHeader->FileHeader.NumberOfSections;
-        sectionHeader = IMAGE_FIRST_SECTION(ntHeader);
-
-        for (i = 0; i < sections; ++i) {
-                start = sectionHeader->VirtualAddress;
-                end = start + sectionHeader->Misc.VirtualSize;
-                if (start <= entryPoint && entryPoint < end)
-                        break;
-                ++sectionHeader;
-        }
-
-        if (i == sections)
-                die("entry point has no containing section");
-
-        /* Factor in the loaded memory position */
-        text_start = (intptr_t)base + start;
-        text_end = (intptr_t)base + end;
-}
-
-code_pointer GC_getTextStart (void) {
-        if (!text_start) findTextSegment();
-        return (code_pointer)text_start;
-}
-
-code_pointer GC_getTextEnd (void) {
-        if (!text_end) findTextSegment();
-        return (code_pointer)text_end;
-}
-

Modified: mlton/trunk/runtime/platform.h
===================================================================
--- mlton/trunk/runtime/platform.h	2008-09-23 15:02:38 UTC (rev 6884)
+++ mlton/trunk/runtime/platform.h	2008-09-23 15:05:23 UTC (rev 6885)
@@ -181,13 +181,6 @@
 PRIVATE void *GC_diskBack_write (pointer buf, size_t size);
 
 /* ------------------------------------------------- */
-/*                Text Segment                       */
-/* ------------------------------------------------- */
-
-PRIVATE code_pointer GC_getTextEnd (void);
-PRIVATE code_pointer GC_getTextStart (void);
-
-/* ------------------------------------------------- */
 /*                SigProf Handler                    */
 /* ------------------------------------------------- */
 




More information about the MLton-commit mailing list