Переглянути джерело

+ data formats
+ heap algorithm
+ start of alignment information

carl 24 роки тому
батько
коміт
2a3a3f1732
1 змінених файлів з 293 додано та 43 видалено
  1. 293 43
      docs/prog.tex

+ 293 - 43
docs/prog.tex

@@ -2327,6 +2327,11 @@ are as follows:
 \item Public and private typed constants in a unit have their unit name prepended to them :TC\_\_UNITNAME\$\$
 \end{itemize}
 
+Currently, in \fpc v1.0, if you declare a variable in unit name \var{tunit},
+with the name \var{\_a}, and you declare the same variable with name \var{a}
+in unit name \var{tunit\_}, you will get the same mangled name. This is
+a limitation of the compiler which will be fixed in release v1.1.
+
 Examples
 
 \begin{verbatim}
@@ -2553,7 +2558,7 @@ register & Left-to-right & Caller & default & None \\ \hline
 
 More about this can be found in \seec{Linking} on linking. Information
 on GCC registers saved, GCC stack alignment and general stack alignment
-on an operating system basis can be found in \seec{AppI}. The \var{register}
+on an operating system basis can be found in Appendix \ref{ch:AppI}. The \var{register}
 modifier is currently not supported, and maps to the default calling
 convention.
 
@@ -2692,7 +2697,7 @@ from one operating system to another. For example, passing a
 byte as a value parameter to a routine could either decrement the
 stack pointer by 1, 2, 4 or even 8 bytes depending on the target
 operating system and processor. The minimal default stack pointer decrement
-value is given in \seec{AppI}.
+value is given in Appendix \ref{ch:AppI}.
 
 For example, on \freebsd, all parameters passed to a routine guarantee
 a minimal stack decrease of four bytes per parameter, even if the
@@ -2715,11 +2720,14 @@ Motorola 680x0 & 32K \\ \hline
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Local variables
-\section{Local variables}
-\label{se:LocalVars}
-
-Stack alignment for local variables to complete!!!
-
+%\section{Local variables}
+%\label{se:LocalVars}
+%
+% Stack alignment for local variables to complete -
+% Currently the FPC version 1.0 stack alignment is
+% simply too messy to describe consistently.
+%
+%
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Linking issues
@@ -3315,18 +3323,42 @@ alignment will also be given.
 
 \subsection{integer types}
 
+The storage size of the default integer types are given in
+\refref. In the case of user defined-types, the storage space
+occupied depends on the bounds of the type:
+
+\begin{itemize}
+\item If both bounds are within range -128..127, the variable
+is stored as a shortint (signed 8-bit quantity).
+\item If both bounds are within the range 0..255, the variable
+is stored as a byte (unsigned 8-bit quantity).
+\item If both bounds are within the range -32768..32767, the variable
+is stored as a smallint (signed 16-bit quantity).
+\item If both bounds are within the range 0..65535, the variable
+is stored as a word (unsigned 16-bit quantity)
+\item If both bounds are within the range 0..4294967295, the
+variable is stored as a cardinal (unsigned 32-bit quantity).
+\item Otherwise the variable is stored as a longint (signed
+32-bit quantity).
+\end{itemize}
+
 \subsection{char types}
 
 A \var{char}, or a subrange of the char type is stored
-as an unsigned byte.
+as a byte.
 
 \subsection{boolean types}
 
+The \var{boolean} type is stored as a byte and can take
+a value of \var{true} or \var{false}.
 
+A \var{ByteBool} is stored as a byte, a \var{WordBool}
+type is stored as a word, and a \var{longbool} is stored
+as a longint.
 
-\subsection{enumerations}
+\subsection{enumeration types}
 
-By default all enumerations are stored as an unsigned
+By default all enumerations are stored as a
 cardinal (4 bytes), which is equivalent to specifying
 the \var{\{\$Z4\}}, \var{\{\$PACKENUM 4\}} or
 \var{\{\$PACKENUM DEFAULT\}} switches.
@@ -3354,37 +3386,122 @@ value is stored as a 4 byte value (cardinal).
 
 \subsection{floating point types}
 
-\subsubsection{Intel 80x86 specific}
+Floating point type sizes and mapping vary from one
+processor to another. Except for the Intel 80x86
+architecture, the \var{extended} type maps to the IEEE
+double type.
 
-All normal floating point types map to their real type, including
-\var{comp} and \var{extended}.
+\begin{FPCltable}{lr}{Processor mapping of real type}{RealMapping}
+Processor & Real type mapping\\
+\hline
+Intel 80x86 &   \var{double}\\
+Motorola 680x0 (with \{\$E-\} switch) & \var{double}\\
+Motorola 680x0 (with \{\$E+\} switch) & \var{single}\\
+\hline
+\end{FPCltable}
 
-\subsubsection{Motorola 680x0 specific}
+Floating point types have a storage binary format divided
+into three distinct fields : the mantissa, the exponent
+and the sign bit which stores the sign of the floating
+pointer value.
 
-Early generations of the Motorola 680x0 processors did not have integrated
-floating point units, so to circumvent this fact, all floating point
-operations are emulated (with the \var{\$E+} switch, which is the default)
-using the IEEE \var{Single} floating point type. In other words when
-emulation is on, Real, Single, Double and Extended all map to the
-\var{single} floating point type.
+\subsubsection{single}
 
-When the \var{\$E} switch is turned off, normal 68882/68881/68040
-floating point opcodes are emitted. The Real type still maps to
-\var{Single} but the other types map to their true floating point
-types. Only basic FPU opcodes are used, which means that it can
-work on 68040 processors correctly.
+The \var{single} type occupies 4 bytes of storage space,
+and its memory structures is the same as the IEEE-754 single
+type.
 
-\begin{remark}\var{Double} and \var{Extended} types in true floating
-point mode have not been extensively tested as of version 0.99.5.
-\end{remark}
-\begin{remark}The \var{comp} data type is currently not supported.
-\end{remark}
+The memory format of the \var{single} format looks like
+\begin{htmlonly}
+this:
+\fpcaddimg{./single.png}
+\end{htmlonly}
+\begin{latexonly}
+\seefig{singleformat}.
+\begin{figure}
+\begin{center}
+\caption{The single format}
+\label{fig:singleformat}
+\ifpdf
+\epsfig{file=single.png}
+\else
+\epsfig{file=single.eps}
+\fi
+\end{center}
+\end{figure}
+\end{latexonly}
+
+
+\subsubsection{double}
+
+The \var{double} type occupies 8 bytes of storage space,
+and its memory structures is the same as the IEEE-754 double
+type.
 
+The memory format of the \var{double} format looks like
+\begin{htmlonly}
+this:
+\fpcaddimg{./double.png}
+\end{htmlonly}
+\begin{latexonly}
+\seefig{doubleformat}.
+\begin{figure}
+\begin{center}
+\caption{The double format}
+\label{fig:doubleformat}
+\ifpdf
+\epsfig{file=double.png}
+\else
+\epsfig{file=double.eps}
+\fi
+\end{center}
+\end{figure}
+\end{latexonly}
+
+
+On processors which do not support co-processor operations (and which have
+the \$\{E-\} switch), the \var{double} type does not exist.
+
+
+
+\subsubsection{extended}
+
+For Intel 80x86 processors, the \var{extended} type has
+the format shown in figure XXX, and takes up 10 bytes of
+storage.
+
+For all other processors which support floating point operations,
+the \var{extended} type is a nickname for the \var{double} type. 
+It has the same format and size as the \var{double} type. On
+processors which do not support co-processor operations (and which have
+the \$\{E-\} switch), the
+\var{extended} type does not exist.
+
+\subsubsection{comp}
+
+For Intel 80x86 processors, the \var{comp} type has
+the format shown in figure XXX, and can contain
+integer values only. The \var{comp} type takes up
+8 bytes of storage space. 
+
+On other processors, the \var{comp} type is not supported.
+
+\subsubsection{real}
+
+Contrary to Turbo Pascal, where the \var{real} type had
+a special internal format, under \fpc the \var{real} type
+simply maps to one of the other real types. It maps to the
+\var{double} type on processors which support floating
+point operations, while it maps to the \var{single} type
+on processors which do not support floating point operations
+in hardware. See \seet{RealMapping} for more information
+on this.
 
 \subsection{pointer types}
 
-A \var{pointer} type is stored as an unsigned 32-bit value on
-32-bit processors, and is stored as a 64-bit unsigned value
+A \var{pointer} type is stored as a cardinal (unsigned 32-bit value) on
+32-bit processors, and is stored as a 64-bit unsigned value\footnote{this
+is actually the \var{qword} type, which is not supported in \fpc v1.0}
 on 64-bit processors.
 
 \subsection{string types}
@@ -3406,7 +3523,7 @@ Offset & Contains \\ \hline
 -12  & Longint with maximum string size. \\
 -8   & Longint with actual string size.\\
 -4   & Longint with reference count.\\
-0    & Actual string, null-terminated. \\ \hline
+0    & Actual array of \var{char}, null-terminated. \\ \hline
 \end{FPCltable}
 
 
@@ -3414,14 +3531,14 @@ Offset & Contains \\ \hline
 
 A shortstring occupies as many bytes as its maximum length plus one.
 The first byte contains the current dynamic length of the string. The
-following bytes contain the actual characters (unsigned 8-bit quantities)
+following bytes contain the actual characters (of type \var{char})
 of the string. The maximum size of a short string is the length
 byte followed by 255 characters.
 
 \subsubsection{widestring types}
 
 The widestring (composed of unicode characters) is not supported
-in \fpc v1.0.x.
+in \fpc v1.0.
 
 \subsection{set types}
 
@@ -3431,12 +3548,12 @@ number of elements in a set is 256.
 
 If a set has less than 32 elements, it is coded as an unsigned
 32-bit value. Otherwise it is coded as a 32 element array of
-32-bit unsigned values (hence a size of 256 bytes).
+32-bit unsigned values (cardinal) (hence a size of 256 bytes).
 
-The longint number of a specific elment \var{E} is given by :
+The cardinal number of a specific element \var{E} is given by :
 
 \begin{verbatim}
- LongNumber = (E div 32);
+ CardinalNumber = (E div 32);
 \end{verbatim}
 
 and the bit number within that 32-bit value is given by:
@@ -3446,8 +3563,23 @@ and the bit number within that 32-bit value is given by:
 
 \subsection{array types}
 
+An array is stored as a contiguous sequence of variables
+of the components of the array. The components with the
+lowest indexes are stored first in memory. No alignment
+is done between each element of the array. A multi-dimensional
+array is stored with the rightmost dimension increasing first.
+
 \subsection{record types}
 
+Each field of a record are stored in a contigous sequence
+of variables, where the first field is stored at the
+lowest address in memory. In case of variant fields in
+a record, each variant starts at the same address in
+memory. Fields of record are usually aligned, unless
+the \var{packed} directive is specified when declaring
+the record type. For more information on field alignment,
+consult \sees{StructuredAlignment}.
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % memory storage of Objects
 \subsection{object types}
@@ -3455,7 +3587,8 @@ and the bit number within that 32-bit value is given by:
 
 Objects are stored in memory just as ordinary records with an extra field:
 a pointer to the Virtual Method Table (VMT). This field is stored first, and
-all fields in the object are stored in the order they are declared.
+all fields in the object are stored in the order they are declared (with possible
+alignment of field addresses, uness the object was declared as being \var{packed}).
 
 This field is initialized by the call to the object's \var{Constructor} method.
 If the \var{new} operator was used to call the constructor, the data fields
@@ -3610,9 +3743,45 @@ the address of the routine.
 
 \subsection{Typed constants and variable alignment}
 
-\subsection{Structured types alignment}
+All static data (variables and typed constants) are usually aligned
+on a power of two boundary. The exact alignment depends on the target processor 
+and the optimization flags. This applies only to the start address of the
+variables, and not the alignment of fields within structures or objects
+for example. For more information on structured alignment, \sees{StructuredAlignment}.
+
+\subsubsection{Intel 80x86 data alignment}
+
+\begin{FPCltable}{llll}{80x86 Data alignment}{DataAlignmentx86}
+\hline
+Size of the data (in bytes) & Alignment (small size) & Alignment (fast)\\
+1\\
+2\\
+3\\
+4\\
+5-8\\
+8+\\
+\hline
+\end{FPCltable}
+
+\subsubsection{Motorola 680x0 alignment}
 
 
+\begin{FPCltable}{llll}{680x0 Data alignment}{DataAlignment68k}
+\hline
+Size of the data (in bytes) & Alignment (small size) & Alignment (fast)\\
+1\\
+2\\
+3\\
+4\\
+5-8\\
+8+\\
+\hline
+\end{FPCltable}
+
+
+\subsection{Structured types alignment}
+\label{se:StructuredAlignment}
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % The heap
 \section{The heap}
@@ -3627,6 +3796,58 @@ Pascal. These extra possibilities are explained in the next subsections.
 \subsection{Heap allocation strategy}
 
 
+The heap is a memory structure which is organized as a stack. The heap
+bottom is stored in the variable \var{HeapOrg}. Initially the heap
+pointer (\var{HeapPtr}) points to the bottom of the heap. When a
+variable is allocated on the heap, \var{HeapPtr} is incremented by the
+size of the allocated memory block. This has the effect of stacking
+dynamic variables on top of each other.
+
+Each time a block is allocated, its size is normalized to have
+a granularity of 16 bytes.
+
+When \var{Dispose} or \var{FreeMem} is called to dispose of a
+memory block which is not on the top of the heap, the heap becomes
+fragmented. The deallocation routines also add the freed blocks to
+the \var{freelist} which is actually a linked list of free blocks.
+Furthermore, if the deallocated block was less then 8K in size, the
+free list cache is also updated.
+
+The free list cache is actually a cache of free heap blocks which
+have specific lengths (the adjusted block size divided by 16 gives the
+index into the free list cache table). It is faster to access then
+searching through the entire \var{freelist}.
+
+The format of an entry in the \var{freelist} is as follows:
+
+\begin{verbatim}
+ PFreeRecord = ^TFreeRecord;
+ TFreeRecord = record
+   Size : longint;
+   Next : PFreeRecord;
+   Prev : PFreeRecord;
+ end;
+
+\end{verbatim}
+
+The \var{Next} field points to the next free block, while
+the \var{Prev} field points to the previous free block.
+
+The algorithm for allocating memory is as follows:
+
+\begin{enumerate}
+\item The size of the block to allocate is adjusted to a 16 byte granularity.
+\item The cached free list is searched to find a free block of the specified
+ size or bigger size, if so it is allocated and the routine exits.
+\item The \var{freelist} is searched to find a free block of the specified size
+or of bigger size, if so it is allocated and the routine exits.
+\item If not found in the \var{freelist} the heap is grown to allocate the
+specified memory, and the routine exits.
+\item If the heap cannot be grown anymore, a call to the operating system
+is made to grow the heap further. If the block to allocate < 256Kb, then
+the heap is grown by 256Kb, otherwise it is grown by 1024Kb.
+\end{enumerate}
+
 % The heap grows
 \subsection{The heap grows}
 \fpc supports the \var{HeapError} procedural variable. If this variable is
@@ -3635,9 +3856,10 @@ is full. By default, \var{HeapError} points to the \var{GrowHeap} function,
 which tries to increase the heap.
 
 The growheap function issues a system call to try to increase the size of the
-memory available to your program. It first tries to increase memory in a 1 MB
-chunk. If this fails, it tries to increase the heap by the amount you
-requested from the heap.
+memory available to your program. It first tries to increase memory in a 256Kb
+chunk if the size to allocate is less than 256Kb, or 1024K otherwise.
+If this fails, it tries to increase the heap by the amount you requested
+from the heap.
 
 If the call to \var{GrowHeap} has failed, then a run-time error is generated,
 or nil is returned, depending on the \var{GrowHeap} result.
@@ -4548,6 +4770,7 @@ windows & .dll & <none> \\
 os/2    & .dll & <none>\\
 BeOS    & .so  & lib \\
 FreeBSD & .so & lib \\
+NetBSD  & .so & lib \\
 \hline
 \end{FPCltable}
 
@@ -6458,5 +6681,32 @@ on stack checking when compiling for this target platform.
 \chapter{Operating system specific behavior}
 \label{ch:AppI}
 
+This appendix describes some special behaviors which vary
+from operating system to operating system. This is described
+in \seet{OSBehave}. The GCC version column indicates the GCC compiler
+version used to get the values for both the GCC stack alignment and
+GCC saved registers of the previous columns. This means that this GCC
+compiler version should be used (or compilers with the same register and
+stack alignment conventions)
+
+\begin{FPCltable}{lllll}{Operating system specific behavior}{OSBehave}
+Operating systems & Min. param. stack align  &  GCC stack alignment &  GCC saved registers & GCC version\\
+\hline
+Amiga & & & &\\
+Atari & & & &\\
+BeOS-x86 & & & &\\
+DOS & & & &\\
+FreeBSD & & & &\\
+linux-m68k & & & &\\
+linux-x86 & & & &\\
+MacOS-68k & & & &\\
+NetBSD & & & &\\
+OS/2 & & & &\\
+PalmOS & & & &\\
+QNX-x86 & & & &\\
+Solaris-x86 & & && \\
+Win32 & & & & \\
+\hline
+\end{FPCltable}
 
 \end{document}