SLX Update Policies

Documentation Updates

Copies of the Foreword, Chapter 1, and Chapter 2 of Simulation Using SLX, a new book about SLX, are now available for downloading.  (Revised 5/22/06)  Click here to download the PDF files into your Wolverine\SLX\Doc folder.

The Latest Version of SLX

The PR218 release of SLX incorporates the following fixes and improvements:

1.  C/C++-style casts for ints and doubles are now provided, e.g.

    MyFunc((int) x, (double) i);

2.  The first, last, successor, and predecessor set operators can now be used to specify a object whose attribute is used in a wait until statement, e.g.,

    wait until ((first widget in MySet) -> attrib > 10.0);

Note that in the above example, the first operator is not treated as a control variable; i.e., a change in the contents of MySet will not trigger reevaluation of the wait until statement.  Only changes in "attrib", which must be a control variable, will do so.

The example above is equivalent to the following:

    w = first widget in MySet;

    wait until (w -> attrib > 10.0);

3.  Saving checkpoint IDs in arrays now works properly.  Prior to this release, statements such as the following failed:

    check[i] = SLXCheckpoint(&x);

4.  An code generation error for the ceil operator has been fixed.  Prior to this fix, the ceil operator could fail in certain complicated contexts, e.g.,

    MyPointer = position(ceil(x)) in MySet;

5.  SLX now permits the same symbol to be used both as a module name and as an enumerated type.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the PR218 Update

The PR018 release of SLX incorporates the following fixes and improvements:

SLX now ignores backslashes when reading or writing string data.  SLX still processes backslashes in "picture" formats used with the "print" and "write" statements.

Prior to this change, backslashes in string data were processed as character string escape sequences.  If you tried to read a file name containing backslash characters into an SLX string, the backslash characters were "eaten" by SLX and did not appear in the string.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the PR018 Update

The AR138 release of SLX incorporates the following fixes and improvements:

1.  Recent changes to SLX's exception handler have greatly improved SLX's ability to diagnose execution errors such as overflow, division by zero, etc.  However, one revision to code that determines the source code associated with compiler-generated instructions could under certain circumstances result in asynchronous run-time failures when a 5-second periodic screen update was performed during a long run.  The circumstances leading to such problems were complex and not necessarily reproducible, since there was a real-time component.  This problem has been fixed.

2.  The exception handler for SLX-64 has been further enhanced to accommodate peculiarities of the 64-bit versions of Windows.

3.  A register allocation problem with cat= has been fixed.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the AR138 Update

The AR108 release of SLX incorporates the following fixes and improvements:

1.  The previous release of SLX (EB268) incorporated a number of code generation changes to take advantage of more modern CPUs.  Unfortunately, one such change made use of machine instructions introduced around 2003.  Several users with CPUs of 2003 or earlier vintage experienced difficulties.  The changes have been rolled back to be compatible with older hardware.

2.  A code generation problem has been fixed for expressions of the following form:

    global_pointer -> local_pointer -> attribute

3.  The SLX compiler now is able to resolve conflicts in which the same symbol is used as a module name and an enumerated type constant.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the AR108 Update

The EB268 release of SLX incorporates the following fixes and improvements:

1.  Code generation and run-time support for "wait until" have been further improved. Programs that make heavy use of wait until may exhibit 0-10% improvements in execution speed, depending on exactly what forms of wait until are used.

2.  Run-time support for time advances has been improved. Programs that perform large numbers of time delays will run 0-10% faster.

3.  Code generation has been improved to assure that diagnostic messages for floating point exceptions more accurately indicate offending operations. (This change affects only the 32-bit version of SLX. The floating point hardware used by SLX-64 generates inherently precise exceptions, so no software tricks are required to get good messages.) Prior to this change, it was possible for an exception such as floating point overflow to be recognized not at the point of occurrence, but at the next floating point operation. The user who reported this problem had a program that generated an exception at the bottom of a loop, but the exception was recognized at the top of the loop in the next iteration. While this reflected the way the hardware actually worked, it was extremely confusing.

4.  A minor problem with floating-point code generation for procedure calls has been fixed.  In certain circumstances, SLX failed to flush the contents of the floating point register stack across procedure calls.  There were several possible consequences when this happened.  First, if lower-level procedure calls also exhibited the same problem, the floating point register stack could have been exhausted.  This would have resulted in a run-time register stack overflow exception.  This error could not have occurred "silently."  If it happened, you would have known.  Second, if you placed a breakpoint in code in which the floating point register stack was non-empty, if the breakpoint was hit, and you resumed execution, a floating point register stack underflow exception would have occurred.  This is because SLX recognizes breakpoints only at points at which computational registers are all empty.  The debugger resets the floating point hardware, resulting in an empty register stack.  When execution resumed, and a value no longer on the stack, but presumed to be on the stack was popped from the stack, by definition a stack underflow exception would occur.

One consequence of fixing this problem is that code generated for floating point expressions containing function calls will now store intermediate results in memory (properly so), in situations where this was formerly not done.  The additional stores and loads can result in 1-bit differences, compared with the old style of code generation.  Such differences cannot be avoided.  Some programs may be affected by 1-bit differences.  One of the programs in our customer program test suite does exactly that.  Results are almost identical, but measurably different.

5.  The "retrieve" statement now properly resolves conflicts between names used both as class names and element names.

6.  Input buffer overruns are now detected and result in run-time errors. Prior to this improvement, SLX did not detect input record truncation performed by underlying C++ library routines.

7.  A preliminary version of Proof3D.slx is now available for users who want to use SLX to generate trace streams for Proof 3D.

8.  SLXDLL.h has been updated to reflect changes in SLX's run-time support. In particular, the internal structure of SLX sets has changed somewhat to resolve conflicts between 32- and 64-bit SLX. This change affects only users who are using C/C++ DLLs that manipulate SLX sets.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the EB268 Update

The AN148 release of SLX incorporates the following fixes and improvements:

1.  A problem with user-callable checkpoint/restore has been fixed.

2.  SLX's now treats "dangler errors" as non-fatal.  SLX now issues warnings that can be disabled through the Trap dialog.  Consider the following example:

    new widget -> MyMethod(x, y, z);

In this example, "MyMethod" is a method of the "widget" class.  The "new" operator creates a potentially dangling reference.  If "MyMethod" does not create any references to the  created widget, the widget will automatically be destroyed, because its use count will be zero.  Previously, SLX's philosophy was that dangling references were always unintentional.  This precluded the use of object creation purely for side effects, with immediate destruction at the end of such statements.

3.  SLX's handling of very complex wait until conditions has been improved to eliminate some overhead.  The benefits of this change will be observable only in models that make very heavy use of complicated wait until statements.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the AN148 Update

The OV217 release of SLX fixes a compiler problem with boolean expressions that include string comparisons for equality and occur in an if/else context.  While this might sound relatively common, in practice, the exact circumstances required to generate the problem were unusual.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the OV217 Update

The CT047 release of SLX incorporates some cosmetic changes and a handful fixes to rare problems encountered by a single user.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the CT027 Update

The UG287 release of SLX incorporates the following additions/changes:

1.  A "Compilation Error/Warning Limit" item has been added to the Options menu.  When compilation of a program elicits more than the specified number of error or warning messages, the compilation is terminated.  By default, the count is set to 200.

2.  Several changes have been made to improve detection and recovery from compile-time and run time errors.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the UG287 Update

The UG067 release of SLX incorporates the following fixes:

1.  Under certain circumstances, out produced by "print" statements of the form

    print (mystring)    "xxx_yyy";

could contain blank characters before and/or after the "_" substitution field, rather than producing the expected string of contiguous characters.  This error has been fixed.

2.  Recovery from math library errors has been improved in the 64-bit version of SLX.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the UG067 Update

The UL267 release of SLX fixes the following problem:

Assignments of the form

    s = substring(x, i, 1);

Are now handled properly when "s" is a static or global variable.  This was a code optimization bug.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the UL267 Update

The UL237 release of SLX includes the following improvements:

1.  A loophole in the "augment" statement has been closed.  Prior to this fix, attempts to augment a class from within a precursor module could cause unpredictable results.  SLX now requires that both the original class definition and any "augment" sections applied to the class both be contained in non-precursor modules.  It has always been the case that an augmented class be contained in a non-precursor module.  The requirement that any "augment" statements be placed in non-precursor modules is new.

SLX compiles all precursor modules before compiling any non-precursor modules.  Therefore, a class contained in a precursor module cannot subsequently be augmented, because its definition is frozen.  Likewise, a class defined in a non-precursor module cannot be augmented from within a precursor module, because it's impossible to freeze an addition to a class that hasn't yet been compiled.

2.  The coloring scheme used in SLX's development environment has been extended to highlight string constants in a brownish red color.  If you don't like this new feature, let us know, and we'll make it optional.

3.  A rare case involving the use of string variables as case selectors in "switch" statements has been fixed.

4.  A number of rare code generation problems have been fixed in 64-bit SLX.

5.  A number of debugger features have been cleaned up.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the UL237 Update

The UN297 release of SLX includes the following improvements:

1.  Pointer values returned by DLL functions are now validated by SLX.  Returned pointers that never were valid or were once valid, but no longer point to a "live" SLX object are trapped.

2.  A key detection issue with .RTS files has been fixed.  This fix affects only OEM versions of Proof.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

End of the UN297 Update

The UN087 release of SLX provides a further correction to the problem addressed in Release AY317.  The fixed problem involved comparisons of equality where both comparands were strings whose lengths were unknown at compile time, but were equal at run time, and the comparison was made in a "branch if TRUE" context.  Note that since "if" statements always use "branch if FALSE," one of the few contexts in which this error could occur was a "switch" statement for which the case selector was a string variable, and one or more case labels were either string variables or named string constants.  While perfectly valid, this usage is somewhat rare, so very few users should be affected by this error.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

The AY317 release of SLX fixes a problem with string equality/inequality comparisons where both comparands were strings of unknown and unequal length.  In certain contexts, SLX did a comparison that effectively always assumed equal comparand lengths.

Click here to download updates for 32-bit systems, and click here for 64-bit systems.

The AY177 release of SLX fixes two problems.

 Click here to download updates for 32-bit systems, and click here for 64-bit systems.

1.  A problem with single character substrings has been fixed.  This problem was the result of compiler optimizations implemented earlier this year for string operations.

2.  An error recovery problem resulting from using the same name in multiple definitions that included a mixture of private/public attributes has been resolved.

 Click here to download updates for 32-bit systems, and click here for 64-bit systems.

The AY047 release of SLX fixes a problem with "show-and-go" watchpoints in the SLX Debugger. (The SLX Debugger has an option to show all changes to a watched variable, but continue executing. Normally, execution pauses each time a watched variable changes.) Click here to download updates for 32-bit systems, and click here for 64-bit systems.

The PR057 release of SLX is the result of recompiling SLX using more aggressive C++ optimization options.  Programs that rely heavily on SLX run-time support that is written in C++, e.g., input/output support, will see faster runtimes.  This release also incorporates fixes to some SLX Debugger problems.  Click here to download updates for 32-bit systems, and click here for 64-bit systems.

The AR137 release of SLX includes the fixes described below.  Click here to download updates for 32-bit systems, and click here for 64-bit systems.

Note: The AR137 release replaces the AR087 release previously issued on the Testers page.

1.  The "Sticky Indentation" and Smart Indentation" options have been restored.  These options disappeared as a result of RichEdit incompatibilities exposed in the AR087 release.

2.  A number of problems with unusual combinations of class "destroy" and "final" properties have been resolved.  SLX now detects and prevents recursive entry into a "destroy" property.  (This can happen if code within a "destroy" property attempts to destroy the same object for which the "destroy" property is invoked.)

3.  DLL functions can be declared as returning string results.  This is a notational convenience within the SLX program that calls such functions.  Note, however, that string results are returned via an N+1st C/C++ argument that is tacked onto the function's actual argument list, if any.  This notation is necessary, because C/C++ functions must access a string descriptor that contains the maximum allowable length of a string result and the address of where the string's text is stored.

=== End of AR137 Update ===

The EB237 release of SLX includes the additions and enhancements described below.  Click here to download updates for 32-bit systems, and click here for 64-bit systems.

Note: The EB237 release corrects problems in and replaces the EB227 release issued previously.

This release is a finalized version of the EB167 release previously published on the Testers page.  It incorporates fixes to all outstanding issues.

This release will provide a substantial increase in performance for many SLX users.  The increase you will see depends on exactly what your program does.  We have seen increases ranging from 2-3% to as high as 30%.  The most dramatic speedups are in the following areas:

1.  Programs that make heavy use of set membership queries (the "is_in", "is_no_in", and "contains" operators) will see substantial increases in performance, due to improvements in the underlying algorithms and SLX's code generation.

2.  Programs that include large numbers of calls of short procedures will run faster.  Short procedures containing large string variables, e.g., "string(200) MyString" will run much faster.  However, bear in mind that SLX macros and user-defined statements provide an easy way to generate sequences of SLX statements.  In-line, macro-generated code runs considerably faster than short procedures.  For example, functions such as "DegreesToRadians" should be implemented using macros rather than procedures.

Procedure invocation and object creation require initialization of all local variables to known states.  Typical procedures and objects have many variables that must be zeroed.  In previous releases, SLX's run-time support zeroed out entire instances of objects and procedures when the instances were allocated.  Beginning with this release, zeroing and other forms of initialization are performed by carefully tailored sequences of compiler-generated instructions.  For example, in previous releases of SLX, string variables were zeroed in their entirety, when in fact, zeroing string header information would have sufficed.  (Setting a string's length to zero implies that no characters can be fetched from the string.)

3.  A number of commonplace special cases of string operations have been sped up.  For example, extraction of substrings of length 1 is now performed by in-line machine instructions, rather than by general-purpose run-time support.  Programs that do lots of parsing of ASCII input data will run much faster.

The following additions have been made to  SLX's Options menu:

1.  "Show Wait Until Statistics" enables collection of statistics characterizing the efficiency with which "wait until" statements operate.  Statistics include the total number of "wait until's" executed and the average number of attempts per success.  Low ratios of attempts to successes indicate that a program is using "wait until" effectively.  For example, consider a ratio of 2.  This indicates that a typical "wait until" consists of one FALSE (blocking) condition followed by success when the control variable(s) in the "wait until" change.  High ratios are indicative of "control variable abuse."  Consider a "wait until" statement that causes 1,000 pucks to wait.  If the "wait until" is used to enforce one-at-a-time logic, when the condition becomes TRUE, all 1,000 pucks will re-execute the "wait until".  It is very likely that one will succeed, and the remaining 999 will have to wait again.  Obviously, this sort of operation is very costly.  In such cases, you should use managed queues, in which reevaluation of blocking conditions is done less frequently.

2.  "Show is_in / is_not_in Statistics" enables collection of statistics on the efficiency of these operators.  Statistics include the total number of interrogations and the average number of iterations per interrogation.  The iteration count should be between 3 and 4.  If you see values greatly exceeding 4, let us know, because this is an indication of less than desirable performance.

3.  "Status Refresh Frequency" allows you to specify the frequency with which screen data is refresed as a program runs.  By default, the screen is refreshed every 5 seconds.  If you don't like having the screen refreshed, try specifying a large value, e.g., 5000 seconds.  Updated displays include all debugger windows, the Calls & Expansions window, and the status bar at the bottom of the screen.

=== End of EB237 Update ===

The AN267 release of SLX includes the additions and enhancements described below.  Click here to download updates for 32-bit systems, and click here for 64-bit systems.

1.  SLX now generates more efficient code for arithmetic operations.  Some Math/trig-intensive applications may now up to 7-8% faster.

2.  64-bit SLX now uses SSE instructions, rather than "legacy" (X87) instructions, for nearly all floating point operations.  Exceptions to this rule include math/trig functions, e.g., cos(x),  for which legacy hardware provides machine instruction implementations, but SSE hardware does not.  As a result of this change, some result of some arithmetic operations will differ in their lowest bits when compared to the corresponding operations using solely legacy hardware, so some small differences in output should be expected.  We have made this change for two reasons: (1) SSE is the native floating mode in 64-bit Windows, so generating SSE instructions speeds up the interfaces between SLX and C++ run-time support code, which uses SSE instructions by definition; and (2) it's almost always a good idea to avoid the use of "legacy" features whenever possible.

3.  A number of loopholes have been closed.  The use of the same name as both a variable and a procedure (method) within a class is no longer allowed.  Such usage could be allowed in theory, but a number of complicated restrictions would be required.  Since the restrictions would be difficult for us to describe and difficult for SLX users to remember, we opted to totally disallow this usage.

4.  A new command-line option, "/background" has been added.  This option forces SLX to run at background priority.  Since virtually all SLX applications are CPU-bound, running an SLX model at foreground priority makes it difficult to perform other tasks while the model is running.  Running at background priority greatly reduces interference with other tasks; however, some degree of interference will still be noticeable.  A "Run at background priority" option has been added to the bottom of the "Options" menu.

=== End of AN267 Update ===

The EC186 release of SLX includes the fixes described below. 

1.  A problem with constant boolean variables, e.g. "constant boolean Myswitch = TRUE", has been fixed.  The problem was caused by faulty handling of the "constant" specification.

2.  A problem with editing very large (greater than 2**31-1) floating-point output numbers with no fractional digits has been fixed in the 64-bit version of SLX.

3.  A problem with very complex object destruction has been fixed in the 64-bit version of SLX.

=== End of OV306 Update ====

The OV306 release of SLX includes the fixes described below. 

1.  A rare, random problem with creation of Run-Time SLX (RTS) files has been fixed.  The problem depended on random memory contents and was both extremely rare and not strictly reproducible.

2.  A minor problem with source code annotation has been fixed.  This problem affected onlt the appearance of source code.  It had no effect on program execution.

=== End of OV306 Update ====

The OV216 release of SLX includes the fixes and enhancements described below. 

1.  SLX's status bar (at the bottom of the SLX window) has been improved.  The total amount of memory acquired from Windows is now shown, and for long-running programs, the status bar is updated every five seconds.  The periodic updates and memory status display are useful in detecting infinite loops and memory leaks.

2.  SLX's performance monitor now does a better job of attributing time spent in run-time library functions to the points from which the functions are called.  For example, "Find Object in Set" used to appear as a large consumer of CPU time in many programs.  While accurate, such information wasn't very useful.  SLX now "charges" such CPU time consumption to the SLX statements that invoke the "Find Object in Set" function.  For most library functions, source attribution has been improved; however, for some functions that are used in a wide variety of contexts, e.g., memory management, source attribution is impossible.

One consequence of these changes is that most programs will show flatter CPU usage profiles, since peaks that used to appear for library functions are now spread out over potentially many points-of-call.

3.  A new keyword, "XML_NOBREAKS", has been added to the open and filedef statements.  This keyword defines a file as an XML file in which all data between two successive < ... > fields is returned as a single character string, ignoring blanks, tabs, commas, quotes, and any other punctuation.  Consider the following input record:

    <Names>Jim Tom Peter</Names>

If the above record is read with only the "XML" keyword in effect, "Jim", "Tom", and "Peter" are returned as individual (blank-separated) items.  If "XML_NOBREAKS" is in effect, "Jim Tom Peter" is returned as a single string.

4.  A problem affecting certain forms of wait until has been fixed in 64-bit SLX.  32-bit SLX was not affected.

=== End of OV216 Update ====

The OV146 release of SLX includes the fixes and enhancements described below. 

1.  Several problems with XML "< ... >" fields that span multiple lines in an XML file have been fixed.

2.  Code generation and run-time support for most forms of string assignment and comparison have been significantly improved.  Many string operations, which were fast to begin with, have doubled in speed.

=== End of OV146 Update ====

The OV086 release of SLX includes the fixes and enhancements described below. 

1.   Support has been added to make it easier to read XML files:

A.  SLX's "open" and "filedef" statements now support an XML keyword:

    filedef MyXML input options=XML name="Myfile.xml";     // XML specified in a file definition

    open MyXML input options=XML name="Myfile.xml";     // you can specify XML here, too

B.  The following rules apply to reading from XML files:

1.  For each read, leading whitespace (blanks, tabs), if any, is skipped.

2.  If the first character of an input field is "<", SLX reads everything from the "<" character up to and including the terminating ">" character.  The text between "<" and ">" can contain anything.  SLX does not detect the presence of any keywords within the text, nor does it apply any special handling to quoted strings.  In short, "< ... >" fields are returned in their entirety.  Note that if a "< ... >" field is too big to fit in the string variable into which it is read, it is truncated to the declared length of the string variable.  This is normal under SLX and is not considered an error.

3.  Because "< ... >" fields begin with a "<", they can be read only into SLX string variables.

4.  Some "< ... >" fields are followed by raw data.  Consider the following example:

        <Altitude>5000.0</Altitude>

An SLX program that reads the "<Altitude>" field can read the value "5000.0" directly into a floating point variable.  Note that "<" is interpreted as a delimiter when a program is reading from an XML file.  It terminates an input field exactly as a blank or comma would.  Thus, the next read following the read of "5000.0" will start with the "<" character that begins the next field.

5.  The following code fragment illustrates a typical approach for reading an XML file:

string(50)  token;        // read input tokens as strings until we recognize an item of interest

double       latitude;

 

filedef MyXML input options=XML name="Myfile.xml";

 

forever

    {

    read file=MyXML end=end_of_file (token);

    switch (token)

        {

default:

 

        print (token) "Skipped: _\n";

        break;

 

case "<Altitude>":

 

        read file=MyXML (altitude);

        print (altitude) "Altitude = _.___\n";

        continue;

        }

    }

 

Note that the code fragment above doe not explicitly look for "</Altitude>" keywords.  In most cases, it's easiest to ignore such items.  The simplest way to structure an SLX program for reading an XML file is to use one giant "switch" statement.  SLX string comparisons are very fast.  On a reasonably fast PC, a typical string comparison might take 10-20 nanoseconds.  However, if a program has to handle a large number of keywords, a more efficient approach may be advisable.  If you're writing a program that only looks for 20 keywords, it's probably not worth worrying about efficiency unless you're reading enormous files.

 

The first and safest thing you can do to improve efficiency is to place the most frequent cases at the top of the "switch" statement.  (SLX cycles through the cases in order.)  The second thing you can do, which is somewhat riskier, is to exploit any knowledge you have of the context in which keywords appear.  If an occurrence of a given keyword establishes a context in which only a limited number of keywords can be supplied until a keyword that terminates the context is encountered, you can add an inner loop and "switch" statement that processes that context.  Finally, and riskiest, if you have knowledge of the order in which optional keywords can appear, you can supply if/else logic that reacts to the presence of the optional keywords in the order in which they are known to occur.

2.  Support for attaching and detaching files to SLX's built-in "stdout" has been improved.  You can use explicit "open" and "close" statements to attach files to stdout.  Prior to this release, stdout was considered to be a file that could never be closed.  SLX would allow you to attach files to stdout, but would effectively ignore any explicit "close" operations.  Thus, output files so attached would remain open until the end of execution instead of being closed when you though they should be.

3.  The dialog box for reading from the keyboard now includes a button that allows you to terminate execution.

4.  Warning and error messages issued at times containing ten digits to the left of the decimal point, but less than 2147483648.0 could cause unpredictable failures arising from flawed editing of the time.  This problem has been fixed.

=== End of OV086 Update ====

The CT166 release of SLX includes the fixes and enhancements described below. 

1.  Updates on this page are now identified by operating system type (32-bit or 64-bit) rather than being identified as SLX-32 or SLX-64.  This is because Wolverine Software Products are installed in "c:\Windows\Program Files (x86)" under 64-bit versions of Windows and in "c:\Windows\Program Files" under 32-bit versions of Windows.  Updates for 64-bit systems include both SLX-64 and SLX-32, while updates for 32-bit systems include only SLX-32.

2.  The documentation and sample files for using DLLs in conjunction with SLX have been updated.  SLXDLL.PDF are located in the SLX\Doc folder, and the sample files are located in SLX\DLLs.  Note that SLX now assumes Microsoft standard alignment of data.  Doubles must be 8-byte aligned.  On 64-bit systems, pointers must be 8-byte aligned.  SLX formerly required only 4-byte alignment of doubles.  You can generate proper header files for your DLLs by compiling the SLX program that uses them and then clicking File, Write DLL Header File.  This has always been the recommended approach, since it guarantees agreement between SLX and your DLL functions.

3.  Problems with #ifdef have been fixed.  In addition, SLX source code following a false #ifdef is now shown in a gray color with strike-through annotation.

4.  Supplying more than one argument to the abs() function is now properly diagnosed as an error.  Previously, any arguments after the first argument were silently ignored.

5.  A problem with file qualifications in SLX "import" statements has been fixed.  By definition, SLX has always assumed and continues to assume that partially-qualified files names are relative to the directory containing the source code containing the import statements.  SLX constructs the full file name by appending the partially-qualified file name to the directory containing the SLX source code.  If the file cannot be found, SLX next attempts to treat the partially-qualified file name as relative to the directory containing the root file of a compilation.  This is the case that is fixed in this release of SLX.  Previously, when SLX found an imported file using the second step described above, it "remembered" the fully-qualified file name incorrectly.  This had no effect on program execution; however, if you tried to open such a file (to set a breakpoint, for example), the SLX Debugger was unable to detect the fact that the file had already been compiled.

6.  Several lingering 32-bit dependencies in SLX-64 have been fixed. 

The EP276 release of SLX includes the following fixes and enhancements:

1.  A number of DLL-related features have been improved.  "Write DLL Header" in the File menu now generates .h files that can be used when compiling under either a 32-bit or 64-bit environment.  The slxdll.cpp "starter" library and slxdll.h files, both located in the DLLs folder, have been revised to reflect changes into SLX and to achieve consistent operation on 32- and 64-bit platforms.

2.  A code generation problem with "position(1) in set" when the set is empty has been fixed.  This problem produced access violations, so you needn't wonder if any "silent" failures might have occurred in your code.

3.  A "describe" verb has been added, allowing you to supply textual descriptions for variable names, macro names, and defined statement names.  Supplied descriptions are kept in a program's symbol table, and the information is displayed when you right click on a variable name and then click on "About".  This feature is especially useful if you're writing macros and statement definitions that are used by others.  See the file assoc4x.slx in the Sample folder.

4.  A new option, "invocation", has been added to the diagnose statement, e.g.,

    diagnose invocation "You have specified the wrong kind of widget";

When executed, this form of the diagnose statement highlights the invocation of a macro or defined statement and displays the specified message beneath the invocation of the macro or statement.  Previously, the diagnose statement was limited to diagnosing the caller of a procedure, e.g., "diagnose caller", or diagnosing a function argument or macro/statement operand.  For an example, see assoc4x.slx.

The EP186 release of SLX includes the following fixes and enhancements:

1.  Recursive creation of objects is now permitted.  For example, if you're building a tree, it might be convenient to recursively create children of a given node from within the class's "initial" property.

Recursive object creation was allowed in earlier releases of SLX, however, when class arguments were recently converted to static memory allocation (to reduce the size of parameterized class instances), recursive allocation was no longer possible, because it would lead to overwriting the single, shared copies of a class's arguments.  SLX now generates code to push and pop class arguments, thereby making recursive allocation once again possible.

2.  Improvements have been made to compile-time semantic error recovery.

The EP086 release of SLX includes the following fixes and enhancements:

1.  Handling of destruction of nested objects has been improved.  Suppose that an object of class widget contains a local instance of an object of class inner_widget named Joe.  Each widget object has a use count, and each "Joe" inside each widget object has its own use count.  The use count of each "Joe" object starts out at 1, because containment in an outer object is a use.  The use count of a Joe object can be increased by placing it in a set or storing pointers to it.  When a widget object is destroyed, the use count of its Joe object is reduced by 1, and if the Joe object's use count goes to zero, it is released.  If the Joe object's use count is not reduced to zero, it cannot be released.  All of this works properly and has for a long time.  Given the architecture of SLX use counts, there really is no other way such behavior could be handled.

When a widget object is destroyed, but its Joe object cannot be destroyed, the Joe object should be severed from its containing widget.  Until this release, such severing was improperly done.  While this had no effect on program execution, it could cause all kinds of confusion for the SLX debugger, which under certain circumstances, could attempt to access information about a Joe object's containing widget, even though the widget object had been released.   Released objects are, of course, frequently recycled.  Thus a situation could arise in which a currently extant widget was interpreted by the SLX debugger as the widget containing multiple prior instances of Joe objects.

The problem has been remedied by properly severing the connection between Joe and its containing widget if the widget is destroyed.  One unavoidable ramification of severing is that after severing, a widget's Joe object is can no longer be known as "Joe", because "Joe" has meaning only in the context of a widget object.  After severing, each Joe object is known to the SLX debugger as inner_object n, where n is the inner_object's instance ID.

2.  The SLX debugger's ability to display large numbers of objects and pucks has been greatly improved.  Assume that you're using the debugger, and the program you're debugging has 100,000 objects.  In the past, opening the debugger's "All Objects" window took a very long time.  Beginning with this release, all SLX debugger windows that use Windows ListView controls, e.g. "All Objects", "All Pucks", etc., are implemented as so-called "virtual lists".  For such lists, SLX maintains all data internally (as it always has anyway), and provides upon demand from Windows only the information to be made visible within a window.  So, for example, even though there are 100,000 objects that could be displayed, overhead is incurred for only a small fraction of them.

In addition, you can now type the first few letters of items in the column by which a list is sorted, and the list will very quickly scroll to the closest match.  (A biniary search is performed.)

3.  The SLX menu bar now includes a "Find" item, available when a program is being debugged.  Clicking on this item brings up a dialog box that allows you to quickly locate objects or pucks by name/number.

4.  A number of 64-bit-specific code generation problems have been repaired.

Release AY226 has been posted on the Testers page.

Release AY026 of SLX includes the following updates:

SLX's on-line help has been updated.  The latest versions of Chapters 1 and 2 of Simulation Using SLX are included in this release. 

A problem with constant Boolean expressions has been fixed.

"Dangling" pointer references are now handled properly for set membership operators ("is_in", "is_not_in", and "contains").  "What is a dangling reference?" you ask.  A dangling reference is a reference to an object that is contextually transitory, that is, it's a reference that disappears automatically.  The following code contains three examples of dangling references:

class widget

    {

    int i;

    };

 

procedure main()

    {

    int j;

 

    if (new widget is_in wset)

        print "It's a miracle!\n";

    j = (*new widget).i;

 

    j = proc() -> i++;

 

    exit(0);

    }

 

procedure proc() returning pointer(widget)

    {

    return new widget;

    }

In each of the first three statements of main, a widget is created, but immediately disappears, because there are no further references to it.  SLX assumes such usage is unintentional and treats it as a run-time error.  The first statement of main is an example of the error that is corrected in this release.  Prior to this fix, SLX failed to decrement the use count of the created object.  This had several undesirable effects.  First, it was impossible to destroy such objects, because their use counts were always too high.  Second, if you tried to display all uses of such objects with the debugger, the debugger would complain that it couldn't find all the alleged references.  Finally, dangling references went undetected.

The set membership example shows how the new operator caused problems.  There are other ways in which similar problems could arise with set membership operators.  For example, the use of a pointer-valued procedure to specify the object whose set membership was to be tested also caused problems.  When a pointer value is returned by a procedure, the use count of the object to which the pointer points is incremented within the procedure.  This is necessary, because the procedure has no knowledge of how the returned pointer value will be used, and the use of the object really does go up by 1 for a very short period of time.  What was missing was the immediate decrementing of the object's use count by the caller during evaluation of the set membership operator.

Release PR246, located on the Testers page, incorporates a fix to the "retrieve" statement.  Under certain rare circumstances, entries in the data structures traversed by the retrieve statement could become cross-linked, resulting in one of two very bad things: access violations or infinite loops.  You needn't worry about whether this bug may have affected you in the past.  If it did, the chances are extremely high that you would have noticed it.

Releases AR136, PR036, and PR126 of SLX includes some improvements to SLX's I/O subsystem.  See details on the Testers page.

Release AR236 of SLX includes a performance upgrade and closes a loophole that existed in the use of SLX methods.

The hashing algorithm used for determining set membership has been improved.  An example was brought to our attention in which a highly stylized, repeated pattern of object addresses caused undesirable clustering that lead to reduced performance.  The hash algorithm has been tweaked.  This change has no effect on anything other than performance.

The loophole that existed in the use of SLX methods is illustrated below:

//*****************************************************************************

// Trap Illegal Backdoor Method Invocations

//*****************************************************************************

module Backdoor

    {

    class SomeClass()

        {

        int value;

 

        procedure VeryIndirectlyGetValue() returning int

            {

            return IndirectlyGetValue();

            }

 

        procedure IndirectlyGetValue() returning int

            {

            return DirectlyGetValue();

            }

 

        procedure DirectlyGetValue() returning int

            {

            return value;

            }

        };

 

    procedure main()

        {

        pointer(SomeClass) sc1;

 

        sc1 = new SomeClass();

        sc1 -> value = 999;

 

        print (sc1->IndirectlyGetValue()) "_\n";    // this is OK; SLX knows which object

        print (DirectlyGetValue()) "_\n";               // this is not OK; obvious

        print (IndirectlyGetValue()) "_\n";             // this is not OK; subtle (2 levels of call)

        print (VeryIndirectlyGetValue()) "_\n";     // this is not OK; very subtle (3 levels)

        }

    }

 

In the above example, the method named DirectlyGetValue() accesses a variable named "value" that is contained inside the class named SomeClass.  When DirectlyGetValue is called, it must be qualified by a pointer that identifies the instance of SomeClass on which the method is to operate.  The first print statement above illustrates a correctly qualified invocation.  The second print statement is illegal, because in the absence of pointer qualification, DirectlyGetValue doesn't "know" the instance of SomeClass from which "value" is to be fetched.  SLX has always caught such errors at compile-time.  The third print statement is more subtle, because IndirectlyGetValue contains no internal references to members of its containing class, SomeClass.  However, IndirectlyGetValue calls DirectlyGetValue, which does contain internal references to "value".  SLX failed to catch this "back door" form of access.  In the fourth print statement, the lack of qualification is further obscured by an additional level of call.

 

All of these errors are now properly caught at compile-time.

Release AR076 of SLX fixes a problem with constant Boolean expressions and includes a major retooling of algorithms used in wait until processing.

An SLX user recently provided us an example in which a Boolean expression containing a constant comparison, e.g., "if (... 1 == 1 ...)" was incorrectly compiled.  To shed further light on the problem, we used our RCG tool for testing Boolean expression evaluation.  "RCG" stands for random code generation.  The RCG tool is an SLX program that generates SLX source code containing large numbers of Boolean expressions with randomly selected terms.  In each case, the correct answers are computed by the RCG tool, and comparisons is generated, comparing the actual values computed by the SLX program when it runs with the pre-computed correct values.  This simulation-inspired approach allows us to test thousands of cases very quickly, change the random number seed, and test thousands more.

While we were at it, we ran the corresponding utility for testing "wait until" statements and found that in certain rare cases with very complex comparisons, ands and ors (all three required) nested in particular forms failures could occur.  The failure rate was extremely low, but non-zero.

Release AR076 incorporates retooled algorithms.  While this release has passed many thousands of tests, it is what we call a "foundation shaker", so we have taken the unusual step of posting the update here, rather than on the normal SLX Updates page.

Release EB286 of SLX fixes a problem with the successor and predecessor operators when used with indirectly referenced sets.  Consider the following example:

pointer(C)    c;

set(C)        testSet;

pointer(set)  testSet_p;

 

place new C into testSet;

place new C into testSet;

place new C into testSet;

 

testSet_p = &testSet;

 

c = first C in *testSet_p;

c = successor(c) in *testSet_p;

 

In the above example,  the SLX compiler was confused by "in *testSet_p" in the last statement.  The compiler keeps track of primary and secondary types of expressions, but not tertiary types.  In this statement, the primary type of "*testSet_p" is pointer, and its secondary type is set; i.e., it is a pointer(set).  The interesting question here is "set of what?"  Since "of what" is determined by values assigned to "testSet_p" at run-time, the compiler should have assumed "set(*)", and generated code to validate the assignment of the successor operator into "c".  Unfortunately the algorithm for doing so had a bug that resulted in a spurious compile-time error message.  The algorithm has been corrected.

Release EB246 of SLX includes the following additions/updates:

1.  DLL header files produced by the SLX compiler for DLL functions returning pointer values specified C/C++ keywords in the wrong order,

e.g.,

    EXTERN_C EXPORT struct obj CDECL *retptr();

SLX now generates the proper syntax, e.g.,

    EXTERN_C EXPORT struct obj * CDECL retptr();

2.  Consider the following wait until statement:

    wait until (ptr -> count > 0);

SLX requires that at least one variable in a wait until expression be a control variable.  In the above case, either "ptr" or "count", or both, must be a control variable.  If neither are control variables, the SLX compiler will complain.  The variable "count" can be an element of more than one class.  The particular version of "count" that is used is determined by the type of "ptr".  We recently encountered a situation in which "count" was a member of two different classes.  In one class, it was a control variable, and in the other class, it was not.  When the non-control version of "count" was used in a wait until statement (an error), the SLX compiler was confused by having previously seen the control version of "count", and the compiler failed to diagnose the error.  Under such circumstances, the behavior of the wait until statement was unpredictable.

The compiler's algorithm for resolving multiple definitions of class elements now properly recognizes the presence/absence of "control".

3.  Run-time support for wait until has been further tweaked to resolve an additional ambiguity of the sort described in the UG045 UN305 updates.  As a result of the tweak, users may notice slight differences in results, due to reordered processing of delayed pucks.  This problem should be very rare.  For example, our rather extensive suite of test programs was unaffected by this change.

Release EB166 of SLX includes the following additions/updates:

1.  A complex and presumably rare problem with boolean expression evaluation has been fixed.  The following example illustrates a context in which the error occurred:

procedure myfunc(boolean arg)

    {

    ...

    }

 

procedure xxx()

    {

    int    i;

    i = 1;

    while (i <= 10)

        {

        if (i == 3)

            break;

 

        myfunc(i != 3);                // boolean argument is an expression

        print (i)        "i = _\n";

        }

SLX evaluates boolean expressions as a sequence of conditional branches.  In a complex boolean expression, there can be many branches, all of which the compiler keeps on a list until it determines the ultimate TRUE and FALSE branch targest for the entire expression.

The problem that existed prior to this release of SLX is that the compiler failed to create a separate list for boolean procedure argument evaluation.  Thus, the lists of branches for "i <= 10" and "i != 3" became commingled, leading to incorrect branching.

2.  An error recovery problem with improperly delimited string constants has been fixed.

Release EB036 of SLX includes the following additions/updates:

The implementation of the switch statement when selecting cases of an enumerated type has been changed from a linear search to direct transfer via a compiler-generated table.  This optimization was added at the request of a user who makes use of very large switch statements that operate on enumerated types containing up to several hundred values.

The implementation of the switch statement on data types other than enumerated types remains unchanged.

Case labels for enumerated types are henceforth restricted to constant values.  Note that SLX's implementation of the switch statement for all other data types is very general.  Consider the following:

    switch (TRUE)

            {

case a < b: ...        // case label is an expression!

            break;

            ...

            }

Release AN256 of SLX includes the following additions/updates:

1.  A loophole in the use of the reactivate list= statement has been closed.  The reactivate list= statement was designed to be use only in conjunction with the wait list= statement; however, run-time support for reactivate list= failed to verify that the list upon which it was operating was legitimately constructed by wait list=.  The use of user-constructed, ad hoc lists could have disastrous consequences.  Run-time support has been improved to detect such erroneous usage.

2.  The Debugger's "smart cursor" and "right click on variable name" features have been further refined.  A number of cases in which they failed to properly recognize and provide access to lower-level information have been fixed.  Smart cursor descriptions have been refined to offer better consistency among differing contexts.

3.  A number of output formats in H7.slx, the SLX implementation of a subset of GPSS/H, have been revised to provide better output.  Any users who are using h6.slx, h5.slx, or even older files should upgrade to h7.slx

Release EC195 of SLX includes the following additions/updates:

SLX's browser window is now read-only.  To modify source code, you must open a conventional source window.  This change was made because (1) when the browser window, and an open source window contained the same source code, SLX did not apply changes made in one window to the other window, and (2) SLX never applied changes made in the browser window.  These shortcomings will be addressed in the future.

Release EC145 of SLX includes the following additions/updates:

1.  The SLXCheckpointExists function has been added to allow users who dynamically issue checkpoints and restores to test the existence of a given checkpoint.  The following example illustrates the use of the new function:

boolean    exists;

                ...

                exists = SLXCheckpointExists(ID);

2.  If a priority was specified in a fork statement, and the priority was inadvertently specified as a floating point value, the required conversion to integer produced unpredictable results.  (Priorities must be specified as integer values.)  Specification of a floating point priority now elicits a warning message, but the conversion is done correctly.

Release OV275 of SLX includes the following additions/updates:

1.  Under certain circumstances, the "retrieve" statement could fail to find objects to be retrieved from a set based on a combination of floating point attributes.  This problem has been fixed.

2.  Additional options have been added to the "for each" statement:

for (w = each widget in widget_set with w -> weight > 10)    // "with" clause selects only specified objects

for (w = each widget in widget_set after w0)    // begin searching after a specified object in a set

for (w = each widget in reverse widget_set before w0)    // begin searching before a specified object in a set (reverse order required)

for (c = each COLOR after RED)    // enumerated type iteration starting at a specified point

for (c = each reverse COLOR before GREEN)    // reverse enumerated iteration starting at a specified point

Release OV215 of SLX includes the following additions/updates:

1.  Memory management has been further improved for very large models.

2.  Additional details have been added to the Help, Memory Usage display.

3.  A problem that could cause SLX's built-in performance monitor to crash in memory-intensive applications has been fixed.

Release OV115 of SLX includes the following additions/updates:

1.  A number of enhancements have been made to SLX's memory management routines.  SLX now requests memory directly from Windows, rather than going through intermediate layers of software.  Furthermore, SLX now grabs memory from Windows in much larger chunks, so it asks for more only when it has allocated all available portions of a large chunk of memory.

2.  The Help, Memory Usage tool has been expanded to show additional information that may be helpful to users who are trying to run very large models.

3.  The performance of "wait until" reactivation of delayed pucks has been improved.  The revised algorithm produces results identical to the previous algorithm; however, it does so in a different order that is far more efficient.  Users who have large numbers of pucks piled up in wait until statements should see an improvement.  Of course, allowing large numbers of pucks to pile up in wait until statements is a bad thing to do.  Under such circumstances, one should take a more proactive approach to queue management.

4.  Some issues with respect to the debugger's state across checkpoint/restore have been resolved, resulting in better behavior.  For example, if you set a time trap, issue a checkpoint, run for a while, issue another time trap, and then restore model state to the saved checkpoint, the second time trap will be in effect after the restore.  Previously, the original time trap was restored, and the latest time trap was forgotten.

Release EP225 of SLX includes the following additions/updates:

A problem with network security keys has been fixed.  The problem was as follows:

1.  A network security key was being used.

2.  The key had permission for a "full" version of SLX, but lacked explicit permission for Run-Time SLX.

3.  An RTS file was run using a command-line invocation of SLX, e.g.,

    se /run/screen myprog.rts

Under the above circumstances, SLX failed to allow a "full" license to be used as a Run-Time license.

The set keyword of the empty set statement is now optional; i.e.,

    empty set myset;

and

    empty myset;

are now equivalent.

Release EP135 of SLX includes the following additions/updates:

A problem with the round function has been fixed.  The round function is used to round floating point values:

    x = 2.6;

    i = round(x);        // i = 3

A new statement, empty set, has been introduced:

    set(widget)    wset;

    ...

    place ... into wset;

    ...

    empty set wset;        // remove all members from wset

 

Note that "empty" is now a reserved word in SLX.  If you have programs that use "empty" as a variable name, you'll have to choose a different name.

Release UG195 of SLX includes the following additions/updates:

Final cleanup on the changes to set operations made in Release UG045 has been accomplished.  One last lingering problem with very large numbers of seta & objects has been fixed.

Release UG175 of SLX includes the following additions/updates:

A number of general  improvements have been made to security key interrogation.  Users who use more than one security key on the same machine should now see more logical behavior in the merger of product permissions and license dates retrieved from more than one key.

Release UG045 of SLX includes the following changes:

A further correction has been made to the changes implemented in Release UN305Under certain circumstances, reactivated pucks were merged into the CEC with higher importance given to original blockage chronology than to puck priorities; i.e., priorities didn't always work as expected.  As a consequence of this correction, some models will produce slightly different results.

A rare problem with sets has been fixed.  The circumstances under which the problem could arise were as follows:

1.  An object was being removed from a set, and the set was the last usage of the object; i.e., the object's use count was 1.  Note that for the use count to be 1, there could be no active pointers to the object.  Thus, the "remove" statement has to be something such as "remove first widget in myset from myset" (no stored pointer to the first widget).

2.  The object had to contain a set.  Implicit destruction of the object caused implicit destruction of the set, which in turn caused all members to be removed from the set.

3.  One of the objects in the destroyed set had to be in the same hash table thread as the original object being destroyed.  SLX uses a large hash table for quick access to (set, object) bindings.  Depending on the number of (set, object) pairs, the hash table can be quite large.  (SLX starts out with a table size of 1024 and doubles it when necessary.)  Thus the probability of condition 3 was at most 1/1024 and considerably smaller in large models.

4.  The above conditions lead to contamination of the hash table, with somewhat unpredictable consequences.  Typically, contamination would give rise to spurious complaints about objects not being in a particular set, even though the objects actually were in the set.

Release UL135 of SLX includes the following changes:

A problem with spurious privacy violations has been fixed.  Under certain circumstances, an attribute of the same name contained in multiple classes, but private in some classes

and public in others caused the SLX compiler to complain about nonexistent privacy violations.  The problem occurred when the compiler encountered a private version of an attribute from the "wrong" class.  The process of searching through multiple classes for attributes of the same name to find the "right" version was performed after privacy was considered; i.e., the search was performed too late.  The order of these two steps has been reversed, so that privacy is examined only after the "right" class is found.

Release UN305 of SLX includes the following changes:

A subtle problem with reactivation of pucks that were previously blocked in wait until statements has been resolved.  When a control variable is altered, and pucks have been delayed in wait until statements dependent on the state of the control variable, all such pucks are placed back on the current events chain (CEC) to retest their wait until conditions.  Such pucks are supposed to be placed on the CEC in their original order.  This approach guarantees that pucks previously blocked by a wait until will get to retest their blocking condition before pucks of equal priority that came in "later."  In simple queueing models, the SLX approach prevents new members of  a queue from "sneaking" by previous members.  The problem fixed in this release arose when pucks with equal move times were reactivated as a consequence of a change in a control variable.  Prior to this release, the merger of such pucks back into the CEC was done by comparing move times.  In the case of equal move times, this comparison yielded ambiguous results.  The problem has been rectified by using unique serial numbers to resolve ties, rather than move times.  Each time a new puck is created, and each time a puck comes out of an advance statement, it is assigned a new (higher) serial number.  As a consequence of removing this ambiguity, some models will produce slightly different results.  Unfortunately, there's nothing that can be done to prevent this, because we had to remove the ambiguity.

Release UN175 of SLX includes the following changes:

A number of user interface problems with SLX's performance monitor window have been fixed.  Scrolling through the lines of this window by means of up/down arrow keys and/or the PgUp/PgDn keys no longer causes disconcerting loss of keyboard focus.  Resizing and other window management functions have been cleaned up.

The SLX Debugger's smart cursor now properly handles scalar INOUT procedure arguments.  Hovering over these variables formerly caused display of incorrect data.

Release UN075 of SLX includes the following changes:

An option has been added to have SLX change modified source files any time you exit SLX.  (Take a look at the notes for Release UN025.)  You can control this option by clicking Options, Auto-Save Modified Source.  Note that this option causes saving of modified files any time you leave SLX, including occasions when you accidentally click outside SLX's main window.  The primary purpose for this option is to facilitate the use of external source file editors.  If this option is enabled, and  you temporarily switch out of SLX to edit a source file with your favorite editor, the file will be saved when SLX is suspended.  There is an obvious risk associated with enabling this option.  If you're in the habit of doing lots of experimental editing, and you're used to thinking "I can always exit and start over," you should not enable this option, because if you accidentally click outside SLX's main window, all modified source windows will be written back to their files.

A problem with display of very long strings in the SLX debugger's Local Data and Global Data windows has been fixed.

Release UN065 of SLX includes the following changes:

A column has been added to SLX's performance monitor, showing the number of bytes of code compiled for a statement.  The practical reason for including this information is that it gives you a measure of complexity of the source code.  If a line of source code is compiled into hundreds of bytes of code, and that statement consumes a lot of CPU time, there may be little you can do to improve performance, because the statement is inherently complex.  On the other hand, if a statement is compiled into a relatively small number of machine instructions but consumes large amounts of CPU time, it is because the statement is being executed many, many times.  In such cases, you may be able to rearrange your code to improve performance.  For example, you might be able to move loop-independent code out of a loop.

Release UN025 of SLX includes the following changes:

Several changes have been made to SLX's user interface.

A problem with the F2 key has been fixed.  (The F2 key is used to expunge error messages and statement/macro expansions from source code windows.)  When a window is cluttered with lots of messages, it can become difficult to edit source code.  F2 eliminates the clutter.  Under ceratin circumstances, pressing F2 could cause editing changes to be lost.  This problem has been fixed.

SLX no longer automatically saves source code files when you switch out of SLX to another application.  We have come to the realization that automatic updating of source files is just too insidious.  If you're in the habit of exiting SLX to edit source files using an external editor, you now will have to explicitly save the files if you've changed them within SLX before switching to your editor.  Most users either do all their exclusively within SLX or exclusively outside SLX.  This change affects only those who use a mixed approach.

If you make changes to a source file and save it within SLX, SLX will now refresh the source window containing the file.  If you close the window containing the source file and reopen the file, the saved version will be reread into memory.  In the past, under certain circumstances. SLX would appear to get "stuck" on the version of the source file that was most recently compiled.  To "unstick" SLX under such circumstances, you had to completely exit and restart SLX.

If you change a file outside SLX, when you return to SLX, you will by default be warned that the file has been modified, and you will be asked if you wish to replace SLX's copy with the externally changed copy.  Users who routinely edit source files with an external editor will find the default warning cumbersome, so we have added an option to suppress the warning.  You can control issuance of the warning by clicking Options, Auto-Apply External Edits.

A recent improvement to SLX in which unnecessary checks for NULL pointer were eliminated went too far and allowed some instances of NULL pointer references to go undetected, almost always resulting in run-time interrupts.  This problem has been fixed.

Release AY275 of SLX includes the following changes:

A rare problem with explicit qualification used to distinguish identically-named elements of different classes has been fixed.

For example, assume that classes widget1 and widget2 each contain the following:

    typedef enum { ON, OFF }    widget_state;

    widget_state    state_variable.

If w is a pointer(widget1), SLX had problems with constructs such as the following in certain contexts:

    w -> state_variable = widget1::ON;

This problem has been fixed.  This problem should have been extremely rare; however, it cropped up in h7.slx, a Wolverine-provided file that includes statement definitions and macros for supporting GPSS/H constructs.  Note that the in the above example, which parallels that of h7.slx, explicit qualification of ON is unnecessary, since w can only point to and object of class widget1, and the meaning of "state_variable" in this context is clear without qualification.  Further note that duplication of enumerated type definitions is usually a poor idea, anyway.  In the above example, a single definition of "widget_state" at the module level could have been used, rather than duplicating the typedef statement.  Of course, use of a single, shared typedef would also obviate the need for qualification, since there would be only one definition.

Release AY235 of SLX includes the following changes:

1.  Handling of an obscure form of "dangling" pointer references has been improved.  Consider the following example:

    i = (new widget) -> j;

Unless the initial property of widget saves one or more pointers to the created object, or places it into a set, the created object immediately disappears.  SLX has always treated the disappearance of a "dangling" reference ("new widget" in this case) as a run-time error, and it continues to do so.  However, in some cases the check for automatic disappearance was made before additional references to the object could be recorded; i.e., the test was performed too soon.  One such case was as follows:

    (new widget) -> my_method();

In this case, the test for disappearance was made prior to execution of my_method().

SLX now performs testing for disappearing references properly.

2.  The "clear" statement has always had rather obscure semantics.  This statement was adapted from GPSS/H with mixed success.  The most common use of the clear Is as follows:

    clear system;

Execution of the clear statement consists of two phases.  In the first phase, the object(s) or set(s) supplied as operands to the clear statement are cleared; i.e., the clear properties of their respective classes are executed.  In the second phase, all active pucks except the puck executing the clear statement are destroyed.  Note that SLX requires that the clear statement be executed only by a "main" puck (usually main 1/1).  This is because SLX requires at least one puck for a main program at all times.

A number of SLX users have requested a form of the clear statement that executes only phase 1, omitting phase 2.  A variant of the clear statement has been implemented to accomplish this.  By supplying the new  "object" keyword, one can request phase 1 execution only; e.g.,

    clear object qset;

Release AY115 of SLX includes the following:

The Debugger's smart cursor has been further enhanced.  If you hold the shift key down when the mouse hovers over the name of a macro or defined statement, the expansion of the macro/statement will be revealed or hidden if it's already visible.  This provides a very quick way of examining expansions.

In Release PR185, the SLX compiler's rules were relaxed to allow use of the same symbol as an enumeration constant and a class name.  This change had the unforeseen side effect of disabling detection of multiply-defined enumeration constants within the same enumerated type.  In the following example, the second (duplicate) use of OFF went undetected as a result of the change.  This problem has been fixed. 

    typedef enum { ON, OFF, OFF }    MachineState;

Release AY025 of SLX includes the following:

The Debugger's "smart cursor" is now enabled by default.

Performance monitor output has been expanded to include an additional column of subtotals.  For example, if you view performance results sorted by scope, subtotals will be shown for each procedure or class.  The example shown in the notes for Release PR135, below, has been updated to show this column.

Code that closed the loophole described in the notes for Release PR195 has been tweaked to eliminate an obscure case in which a correct construct was incorrectly flagged as a privacy violation.

Student SLX (available on the Download page) has been revised to properly enforce student version limits. 

Release PR275 of SLX includes the following:

Upon exiting, SLX now erases any checkpoint files that have been written during a run.  Since these files are valid only for the current run, erasing them causes no harm frees up disk space.

Performance monitor data captured in a file now includes a header identifying the name of the file and the date on which it was witten.

Release PR255 of SLX includes the following:

SLX's built-in performance monitor can now store its results in a file.  To do so, right click in the performance monitor window after running an experiment.  Note that results are written to a file in the same order in which they appear on the screen.  You can change the order by clicking on any of the first four column headings in the table of results.

A number of lingering performance monitor problems caused by very large models have been fixed.

The performance of SLX's user-callable checkpoint/restore feature has been significantly improved for very large models.  Prior to Release PR255, SLX stored user-callable checkpoint data in virtual memory.  For very large models, this strategy caused excessive consumption of virtual memory and lead to considerable page thrashing.  If the memory footprint of an SLX model exceeds a threshhold (currently 50MB), SLX now writes checkpoint data to disk files.

Release PR195 of SLX includes the following:

A number of  set operation problems introduced in Release PR185 have been fixed.

A loophole that existed with SLX methods has been closed.  Prior to this release, if you defined private SLX methods, their privacy could be violated by accessing them via universal pointers (pointer(*)).  Consider the following:

 

module m1

    {

    class widget

        {

        int    i;

 

        private procedure inc()

            {

            ++i;

            return;

            }

        };

    }

...

module m2

    {

     procedure main()

        {

         pointer(*)    w;

         w = new widget;

         w -> inc();                // this is a privacy violation that used to slip by the compiler

         }

     }

Release PR185 of SLX includes the following:

Additional improvements have been made to SLX's performance monitor.

The smart cursor has gotten a bit smarter.  It now can show the contents of variables that it previously couldn't display.

An obscure problem that prevented using the same variable name both as a class name and as an enumeration type has been fixed.

Performance of set operators has been improved.  These include first(), last(), successor(), and predecessor() operators.  The position() operator has also been improved, but use of position() is still potentially costly, since execution requires performing linear searches, which can take a lot of time.  On a reasonably fast machine, the time per element in a set position() search should be around one nanosecond.  Accessing a randomly selected i-th member of a 1,000-element set should take about 250 Ns.  SLX is smart enough to compare i to the size of the set and perform its search from the start of the set or backward from the end of the set.  This cuts the average search time in half.  If the members are uniformly distributed in the set, on the average a search terminates after examining one half of the potentially maximum number.  Half of half of the set implies a mean search time of 250 Ns.

Release PR145 of SLX includes enhancements and improvements to SLX's built-in performance monitor, introduced in release PR135.

The performance monitor is now capable of detecting time spent in DLL functions called by an SLX Model.  In addition, a number of improvements have been made to performance data displays, and the overhead of monitoring a program has been reduced.

Release PR135 of SLX includes one minor improvement and one very cool new feature.

The new major feature is that SLX can now monitor and display the distribution of CPU time consumed in the execution of an SLX program.  To enable this feature, click Monitor, CPU Time Consumption.  (The latter is at the bottom of the popup menu.)  A CPU Time Consumption window will appear.  The following example depicts the contents of this window after running a program:

The window shows percentages of time spent in your code and in SLX code.  For time spent in your code, the name of the file containing the code, the line number within the file, and source code (truncated if too long) are shown.  For time spent in SLX, this information is unavailable.

By default, the information is sorted by decreasing percentage.  In the above example, the largest single consumer of CPU time was SLX's internal code for allocating instances of objects procedures.  By clicking on the column headers for any of the first four columns, you can change the sorting.

The Scope column depicts the name of the procedure or object in which CPU time is consumed in your code, or a description of a function being performed in SLX code.  Clicking on a name in the Scope column of a row that shows time spent in your code will display the source code, in context and highlighted in red.  If necessary, a source code window will be created and/or placed on top of any other source code windows.

The Code Size column shows the number of bytes of machine code for comp