The Trunk: System-eem.938.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Trunk: System-eem.938.mcz

commits-2
Eliot Miranda uploaded a new version of System to project The Trunk:
http://source.squeak.org/trunk/System-eem.938.mcz

==================== Summary ====================

Name: System-eem.938
Author: eem
Time: 19 March 2017, 5:13:33.317857 pm
UUID: fd7c1495-541a-462b-97b8-335f767b8e50
Ancestors: System-ul.937

Update the vmStatisticsReportString to be aware of the tallied idle time in the latest VMs.  This allows he report to give meaningful percentage of runtime in GC figures.  Update vmParameterAt:[put:] with the idle time and Sista code zone proportion support.

Add [browse]allCallsOn:and:localToPackage:

=============== Diff against System-ul.937 ===============

Item was changed:
  ----- Method: SmalltalkImage>>vmParameterAt: (in category 'system attributes') -----
  vmParameterAt: parameterIndex
  "parameterIndex is a positive integer corresponding to one of the VM's internal parameter/metric registers.
  Answer with the current value of that register.  Fail if parameterIndex has no corresponding register.
  VM parameters are numbered as follows:
  1 byte size of old-space (read-only)
  2 byte size of young-space (read-only)
  3 byte size of object memory (read-only)
  4 allocationCount (read-only; nil in Cog VMs)
  5 allocations between GCs (read-write; nil in Cog VMs)
  6 survivor count tenuring threshold (read-write)
  7 full GCs since startup (read-only)
  8 total milliseconds in full GCs since startup (read-only)
  9 incremental GCs since startup (read-only; scavenging GCs on Spur)
  10 total milliseconds in incremental/scavenging GCs since startup (read-only)
  11 tenures of surving objects since startup (read-only)
+ 12-15 specific to the translating VM
+ 16 total microseconds in idle since startup
+ 17 proportion of code zone available for use (Sista VMs only; read-write)
- 12-17 specific to the translating VM (nil in Cog VMs)
  18 total milliseconds in full GC compaction since startup (a portion of parameter 8)
  19 scavenge threshold; the effective size of eden
  20 utc microseconds at VM start-up (actually at time initialization, which precedes image load) (newer Cog VMs only).
  21 root (remembered) table size (read-only)
  22 root (remembered) table overflows since startup (read-only)
  23 bytes of extra memory to reserve for VM buffers, plugins, etc.
  24 memory threshold above which to shrink object memory (read-write)
  25 ammount to grow by when growing object memory (read-write)
  26 interruptChecksEveryNms - force an ioProcessEvents every N milliseconds (read-write)
  27 number of times mark loop iterated for current IGC/FGC (read-only) includes ALL marking
  28 number of times sweep loop iterated for current IGC/FGC (read-only)
  29 number of times make forward loop iterated for current IGC/FGC (read-only)
  30 number of times compact move loop iterated for current IGC/FGC (read-only)
  31 number of grow memory requests (read-only)
  32 number of shrink memory requests (read-only)
  33 number of root table entries used for current IGC/FGC (read-only)
  34 number of allocations done before current IGC/FGC (read-only)
  35 number of survivor objects after current IGC/FGC (read-only)
  36 millisecond clock when current IGC/FGC completed (read-only)
  37 number of marked objects for Roots of the world, not including Root Table entries for current IGC/FGC (read-only)
  38 milliseconds taken by current IGC (read-only)
  39 Number of finalization signals for Weak Objects pending when current IGC/FGC completed (read-only)
  40 BytesPerWord for this image
  41 imageFormatVersion for the VM
  42 number of stack pages in use (Cog Stack VM only, otherwise nil)
  43 desired number of stack pages (stored in image file header, max 65535; Cog VMs only, otherwise nil)
  44 size of eden, in bytes (Cog VMs only, otherwise nil)
  45 desired size of eden, in bytes (stored in image file header; Cog VMs only, otherwise nil)
  46 size of machine code zone, in bytes (stored in image file header; Cog JIT VM only, otherwise nil)
  47 desired size of machine code zone, in bytes (applies at startup only, stored in image file header; Cog JIT VM only)
  48 various properties of the Cog VM as an integer encoding an array of bit flags.
  Bit 0: tells the VM that the image's Process class has threadId as its 5th inst var (after nextLink, suspendedContext, priority & myList)
  Bit 1: on Cog JIT VMs asks the VM to set the flag bit in interpreted methods
  Bit 2: if set, preempting a process puts it to the head of its run queue, not the back,
  i.e. preempting a process by a higher priority one will not cause the preempted process to yield
  to others at the same priority.
  Bit 3: in a muilt-threaded VM, if set, the Window system will only be accessed from the first VM thread
  Bit 4: in a Spur vm, if set, causes weaklings and ephemerons to be queued individually for finalization
  49 the size of the external semaphore table (read-write; Cog VMs only)
  50-51 reserved for VM parameters that persist in the image (such as eden above)
  52 root (remembered) table maximum size (read-only)
  53 the number of oldSpace segments (Spur only, otherwise nil)
  54 total size of free old space (Spur only, otherwise nil)
  55 ratio of growth and image size at or above which a GC will be performed post scavenge (Spur only, otherwise nil)
  56 number of process switches since startup (read-only)
  57 number of ioProcessEvents calls since startup (read-only)
  58 number of forceInterruptCheck (Cog VMs) or quickCheckInterruptCalls (non-Cog VMs) calls since startup (read-only)
  59 number of check event calls since startup (read-only)
  60 number of stack page overflows since startup (read-only; Cog VMs only)
  61 number of stack page divorces since startup (read-only; Cog VMs only)
  62 number of machine code zone compactions since startup (read-only; Cog VMs only)
  63 milliseconds taken by machine code zone compactions since startup (read-only; Cog VMs only)
  64 current number of machine code methods (read-only; Cog VMs only)
  65 In newer Cog VMs a set of flags describing VM features,
  if non-zero bit 0 implies multiple bytecode set support;
  if non-zero bit 0 implies read-only object support
  (read-only; Cog VMs only; nil in older Cog VMs, a boolean answering multiple bytecode support in not so old Cog VMs)
  66 the byte size of a stack page in the stack zone  (read-only; Cog VMs only)
  67 the maximum allowed size of old space in bytes, 0 implies no internal limit (Spur VMs only).
  68 - 69 reserved for more Cog-related info
  70 the value of VM_PROXY_MAJOR (the interpreterProxy major version number)
  71 the value of VM_PROXY_MINOR (the interpreterProxy minor version number)"
 
  <primitive: 254>
  self primitiveFailed!

Item was changed:
  ----- Method: SmalltalkImage>>vmParameterAt:put: (in category 'vm parameters') -----
  vmParameterAt: parameterIndex put: newValue
  "parameterIndex is a positive integer corresponding to one of the VM's internal
  parameter/metric registers.  Store newValue (a positive integer) into that
  register and answer with the previous value that was stored there.
  Fail if newValue is out of range, if parameterIndex has no corresponding
  register, or if the corresponding register is read-only.
 
  As of early 2016 the parameters which can be set are
  5 allocations between GCs (read-write; nil in Cog VMs)
  6 survivor count tenuring threshold (read-write)
+ 17 proportion of code zone available for use (Sista VMs only)
  23 bytes of extra memory to reserve for VM buffers, plugins, etc.
  24 memory threshold above whichto shrink object memory (read-write)
  25 memory headroom when growing object memory (read-write)
  26 interruptChecksEveryNms - force an ioProcessEvents every N milliseconds (read-write)
  43 desired number of stack pages (stored in image file header, max 65535; Cog VMs only, otherwise nil)
  45 desired size of eden, in bytes (stored in image file header; Cog VMs only, otherwise nil)
  47 desired size of machine code zone, in bytes (applies at startup only, stored in image file header; Cog JIT VM only)
  48 various properties of the Cog VM as an integer encoding an array of bit flags.
  Bit 0: tells the VM that the image's Process class has threadId as its 5th inst var (after nextLink, suspendedContext, priority & myList)
  Bit 1: on Cog JIT VMs asks the VM to set the flag bit in interpreted methods
  Bit 2: if set, preempting a process puts it to the head of its run queue, not the back,
  i.e. preempting a process by a higher priority one will not cause the preempted process to yield
  to others at the same priority.
  Bit 3: in a muilt-threaded VM, if set, the Window system will only be accessed from the first VM thread
  Bit 4: in a Spur vm, if set, causes weaklings and ephemerons to be queued individually for finalization
  49 the size of the external semaphore table (read-write; Cog VMs only)
  55 ratio of growth and image size at or above which a GC will be performed post scavenge (Spur only, otherwise nil)
  67 the maximum allowed size of old space in bytes, 0 implies no internal limit (Spur only)."
 
  <primitive: 254>
  self primitiveFailed!

Item was changed:
  ----- Method: SmalltalkImage>>vmStatisticsReportString (in category 'vm statistics') -----
  vmStatisticsReportString
  "(Workspace new contents: Smalltalk vmStatisticsReportString)
  openLabel: 'VM Statistics'"
  "StringHolderView
  open: (StringHolder new contents: Smalltalk vmStatisticsReportString)
  label: 'VM Statistics'"
 
  | params oldSpaceEnd youngSpaceEnd memorySize fullGCs fullGCTime fullGCCompactionTime incrGCs incrGCTime tenureCount upTime
+  upTime2 fullGCs2 fullGCTime2  incrGCs2 incrGCTime2 tenureCount2 str freeSize youngSize used spur timeReporter idleMs idleMs2 |
-  upTime2 fullGCs2 fullGCTime2  incrGCs2 incrGCTime2 tenureCount2 str freeSize youngSize used spur |
  params := self getVMParameters.
  oldSpaceEnd := params at: 1.
  youngSpaceEnd := params at: 2.
  memorySize := params at: 3.
  fullGCs := params at: 7.
  fullGCTime := params at: 8.
  incrGCs := params at: 9.
  incrGCTime := params at: 10.
  tenureCount := params at: 11.
  fullGCCompactionTime := params at: 18.
  upTime := (params at: 20) ~= 0 "utcMicrosecondClock at startup in later Spur VMs"
  ifTrue: [Time utcMicrosecondClock - (params at: 20) + 500 // 1000]
  ifFalse: [Time eventMillisecondClock]. "Fall back on old microsecond clock; Good for 47.5 days"
  spur := (params at: 41) anyMask: 16.
  str := WriteStream on: (String new: 2048).
+ timeReporter := [:time| | seconds |
+ seconds := time / 1000.
+ seconds >= (60*60*24)
+ ifTrue:
+ [str print: seconds / 60 // 60 // 24; nextPut: $d; space;
+ print: seconds / 60 // 60 \\ 24; nextPut: $h; space]
+ ifFalse:
+ [seconds >= (60*60) ifTrue:
+ [str print: (seconds / 60 // 60); nextPut: $h; space]].
+ str
+ print: (seconds / 60 \\ 60) asInteger; nextPut: $m; space;
+ print: (seconds \\ 60) asInteger; nextPut: $s].
  str nextPutAll: 'uptime '.
+ timeReporter value: upTime.
+ (params at: 16) ~= 0 ifTrue:
+ [str tab; nextPutAll: '(runtime '.
+ idleMs := (params at: 16) // 1000.
+ timeReporter value: upTime - idleMs.
+ str nextPutAll: ', idletime '.
+ timeReporter value: idleMs.
+ str nextPut: $)].
+ str cr.
- upTime >= (60*60*24*1000)
- ifTrue:
- [str print: (upTime / 1000 / 60 // 60 // 24); nextPut: $d; space;
- print: (upTime / 1000 / 60 // 60 \\ 24); nextPut: $h; space]
- ifFalse: [str print: (upTime / 1000 / 60 // 60); nextPut: $h; space].
- str
- print: (upTime / 1000 / 60 \\ 60) asInteger; nextPut: $m; space;
- print: (upTime / 1000 \\ 60) asInteger; nextPut: $s; cr.
 
  str nextPutAll: 'memory ';
  nextPutAll: memorySize asStringWithCommas; nextPutAll: ' bytes'; cr.
+ str nextPutAll: ' old ';
- str nextPutAll: ' old ';
  nextPutAll: oldSpaceEnd asStringWithCommas; nextPutAll: ' bytes (';
+ print: oldSpaceEnd / memorySize * 100 maxDecimalPlaces: 1; nextPutAll: '%)'; cr.
- print: (oldSpaceEnd / memorySize * 100) maxDecimalPlaces: 1; nextPutAll: '%)'; cr.
 
  spur ifTrue:
  [(youngSize := (params at: 19)  * 7 // 5) = 0 ifTrue: [params at: 44].
  youngSize := youngSize roundUpTo: 1024.
+ str nextPutAll: ' young ';
- str nextPutAll: ' young ';
  nextPutAll: youngSize asStringWithCommas; nextPutAll: ' bytes (';
  print: youngSize / memorySize * 100 maxDecimalPlaces: 1; nextPutAll: '%)'; cr.
  youngSize := youngSpaceEnd. "used eden"
  freeSize := (params at: 54) + (params at: 44) - youngSize.
  used := youngSize + oldSpaceEnd - freeSize.
  str nextPutAll: ' used ';
  nextPutAll: used asStringWithCommas; nextPutAll: ' bytes (';
  print: used / memorySize * 100 maxDecimalPlaces: 1; nextPutAll: '%)'; cr.
  str nextPutAll: ' free ';
  nextPutAll: freeSize asStringWithCommas; nextPutAll: ' bytes (';
+ print: freeSize / memorySize * 100 maxDecimalPlaces: 1; nextPutAll: '%)'; cr]
+ ifFalse: "Earlier VM and V3 object memory"
+ [str nextPutAll: ' young ';
- print: freeSize / memorySize * 100 maxDecimalPlaces: 1; nextPutAll: '%)'; cr
- ] ifFalse: [ "Earlier VM and V3 object memory"
- str nextPutAll: ' young ';
  nextPutAll: (youngSpaceEnd - oldSpaceEnd) asStringWithCommas; nextPutAll: ' bytes (';
  print: (youngSpaceEnd - oldSpaceEnd / memorySize * 100) maxDecimalPlaces: 1; nextPutAll: '%)'; cr.
  str nextPutAll: ' used ';
  nextPutAll: youngSpaceEnd asStringWithCommas; nextPutAll: ' bytes (';
  print: (youngSpaceEnd / memorySize * 100) maxDecimalPlaces: 1; nextPutAll: '%)'; cr.
  str nextPutAll: ' free ';
  nextPutAll: (memorySize - youngSpaceEnd) asStringWithCommas; nextPutAll: ' bytes (';
+ print: (memorySize - youngSpaceEnd / memorySize * 100) maxDecimalPlaces: 1; nextPutAll: '%)'; cr].
- print: (memorySize - youngSpaceEnd / memorySize * 100) maxDecimalPlaces: 1; nextPutAll: '%)'; cr.
- ].
 
  str nextPutAll: 'GCs ';
  nextPutAll: (fullGCs + incrGCs) asStringWithCommas.
+ fullGCs + incrGCs > 0 ifTrue:
+ [str
- fullGCs + incrGCs > 0 ifTrue: [
- str
  nextPutAll: ' (';
+ print: upTime / (fullGCs + incrGCs) maxDecimalPlaces: 1;
+ nextPutAll: ' ms between GCs'.
+ idleMs > 0 ifTrue:
+ [str
+ space;
+ print: upTime - idleMs / (fullGCs + incrGCs) maxDecimalPlaces: 1;
+ nextPutAll: ' ms runtime between GCs'].
+ str nextPut: $)].
- print: (upTime / (fullGCs + incrGCs)) maxDecimalPlaces: 1;
- nextPutAll: ' ms between GCs)'
- ].
  str cr.
  str nextPutAll: ' full ';
  nextPutAll: fullGCs asStringWithCommas; nextPutAll: ' totalling '; nextPutAll: fullGCTime asStringWithCommas; nextPutAll: ' ms (';
+ print: fullGCTime / (upTime - idleMs) * 100 maxDecimalPlaces: 2;
+ nextPutAll: '% runtime)';
- print: (fullGCTime / upTime * 100) maxDecimalPlaces: 2;
- nextPutAll: '% uptime)';
  nextPutAll: ', avg '; print: (fullGCTime / (fullGCs max: 1)) maxDecimalPlaces: 1; nextPutAll: ' ms'.
  (spur and: [fullGCCompactionTime ~= 0]) ifTrue:
  [str cr; nextPutAll: ' marking ';
  nextPutAll: (fullGCTime - fullGCCompactionTime) asStringWithCommas; nextPutAll: ' ms (';
  print: (fullGCTime - fullGCCompactionTime) / fullGCTime * 100 maxDecimalPlaces: 1;
  nextPutAll: '%) avg '; print: (fullGCTime - fullGCCompactionTime / (fullGCs max: 1)) maxDecimalPlaces: 1;
  nextPutAll: ' ms,'; cr;
  nextPutAll: ' compacting ';
+ nextPutAll: fullGCCompactionTime asStringWithCommas; nextPutAll: ' ms (';
- nextPutAll: (fullGCCompactionTime) asStringWithCommas; nextPutAll: ' ms (';
  print: fullGCCompactionTime / fullGCTime * 100 maxDecimalPlaces: 1;
+ nextPutAll: '%) avg '; print: fullGCCompactionTime / (fullGCs max: 1) maxDecimalPlaces: 1;
+ nextPutAll: ' ms'].
- nextPutAll: '%) avg '; print: (fullGCCompactionTime / (fullGCs max: 1)) maxDecimalPlaces: 1;
- nextPutAll: ' ms'.].
  str cr.
  str nextPutAll: (spur ifTrue: [' scavenges '] ifFalse: [' incr ']);
  nextPutAll: incrGCs asStringWithCommas; nextPutAll: ' totalling '; nextPutAll: incrGCTime asStringWithCommas; nextPutAll: ' ms (';
+ print: incrGCTime / (upTime - idleMs) * 100 maxDecimalPlaces: 2;
+ nextPutAll: '% runtime), avg '; print: incrGCTime / incrGCs maxDecimalPlaces: 1; nextPutAll: ' ms'; cr.
- print: (incrGCTime / upTime * 100) maxDecimalPlaces: 2;
- nextPutAll: '% uptime), avg '; print: (incrGCTime / incrGCs) maxDecimalPlaces: 1; nextPutAll: ' ms'; cr.
  str nextPutAll: ' tenures ';
  nextPutAll: tenureCount asStringWithCommas.
  tenureCount = 0 ifFalse:
  [spur
  ifTrue: [str nextPutAll: ' (avg '; print: tenureCount // (incrGCs max: 1); nextPutAll: ' tenures per scavenge)']
  ifFalse: [str nextPutAll: ' (avg '; print: incrGCs // tenureCount; nextPutAll: ' GCs/tenure)']].
  str cr.
 
+ LastStats ifNil: [LastStats := Array new: 7]
- LastStats ifNil: [LastStats := Array new: 6]
  ifNotNil: [
+ LastStats size < 7 ifTrue:
+ [LastStats := LastStats, (Array new: 7 - LastStats size withAll: 0)].
  upTime2 := upTime - (LastStats at: 1).
  fullGCs2 := fullGCs - (LastStats at: 2).
  fullGCTime2 := fullGCTime - (LastStats at: 3).
  incrGCs2 := incrGCs - (LastStats at: 4).
  incrGCTime2 := incrGCTime - (LastStats at: 5).
  tenureCount2 := tenureCount - (LastStats at: 6).
+ idleMs2 := idleMs - (LastStats at: 7).
 
  str nextPutAll: self textMarkerForShortReport ;
  nextPutAll: (fullGCs2 + incrGCs2) asStringWithCommas.
+ fullGCs2 + incrGCs2 > 0 ifTrue:
+ [str
- fullGCs2 + incrGCs2 > 0 ifTrue: [
- str
  nextPutAll: ' (';
  print: upTime2 // (fullGCs2 + incrGCs2);
+ nextPutAll: ' ms between GCs'.
+ idleMs2 > 0 ifTrue:
+ [str
+ nextPutAll: ', ';
+ print: upTime2 - idleMs2 // (fullGCs2 + incrGCs2);
+ nextPutAll: ' ms runtime between GCs'].
+ str nextPut: $)].
- nextPutAll: ' ms between GCs)'.
- ].
- str cr.
- str nextPutAll: ' uptime '; print: (upTime2 / 1000.0) maxDecimalPlaces: 1; nextPutAll: ' s'; cr.
- str nextPutAll: ' full ';
- nextPutAll: fullGCs2 asStringWithCommas; nextPutAll: ' totalling '; nextPutAll: fullGCTime2 asStringWithCommas; nextPutAll: ' ms (';
- print: (fullGCTime2 / upTime2 * 100) maxDecimalPlaces: 1;
- nextPutAll: '% uptime)'.
- fullGCs2 = 0 ifFalse:
- [str nextPutAll: ', avg '; print: (fullGCTime2 / fullGCs2) maxDecimalPlaces: 1; nextPutAll: ' ms'].
  str cr.
+ str nextPutAll: ' uptime '; print: (upTime2 / 1000.0) maxDecimalPlaces: 1;
+ nextPutAll: ' s, runtime ';   print: (upTime2 - idleMs2 / 1000.0) maxDecimalPlaces: 1;
+ nextPutAll: ' s, idletime ';   print: (idleMs2 / 1000.0) maxDecimalPlaces: 1; nextPutAll: ' s'; cr.
+ str nextPutAll: ' full ';
+ nextPutAll: fullGCs2 asStringWithCommas.
+ fullGCs2 + fullGCTime2 > 0 ifTrue:
+ [str nextPutAll: ' totalling '; nextPutAll: fullGCTime2 asStringWithCommas; nextPutAll: ' ms (';
+ print: fullGCTime2 / (upTime2 - idleMs2) * 100 maxDecimalPlaces: 1;
+ nextPutAll: '% runtime)'.
+ str nextPutAll: ', avg '; print: fullGCTime2 / (fullGCs2 max: 1) maxDecimalPlaces: 1; nextPutAll: ' ms'].
+ str cr.
+ str nextPutAll: (spur ifTrue: [' scavenge '] ifFalse: [' incr ']);
- str nextPutAll: ' incr ';
  nextPutAll: incrGCs2 asStringWithCommas; nextPutAll: ' totalling '; nextPutAll: incrGCTime2 asStringWithCommas; nextPutAll: ' ms (';
+ print: incrGCTime2 / (upTime2 - idleMs2) * 100 maxDecimalPlaces: 1;
+ nextPutAll: '% runtime), avg '; print: incrGCTime2 / (incrGCs2 max: 1) maxDecimalPlaces: 1; nextPutAll: ' ms'.
+ str cr.
- print: (incrGCTime2 / upTime2 * 100) maxDecimalPlaces: 1;
- nextPutAll: '% uptime), avg '.
- incrGCs2 > 0 ifTrue: [
- str print: (incrGCTime2 / incrGCs2) maxDecimalPlaces: 1; nextPutAll: ' ms'
- ].
- str cr.
  str nextPutAll: ' tenures ';
  nextPutAll: tenureCount2 asStringWithCommas.
  tenureCount2 = 0 ifFalse:
+ [spur
+ ifTrue: [str nextPutAll: ' (avg '; print: tenureCount2 // (incrGCs2 max: 1); nextPutAll: ' tenures per scavenge)']
+ ifFalse: [str nextPutAll: ' (avg '; print: incrGCs2 // tenureCount2; nextPutAll: ' GCs/tenure)']].
- [str nextPutAll: ' (avg '; print: incrGCs2 // tenureCount2; nextPutAll: ' GCs/tenure)'].
  str cr.
  ].
+ LastStats := { upTime. fullGCs. fullGCTime. incrGCs. incrGCTime. tenureCount. idleMs }.
- LastStats at: 1 put: upTime.
- LastStats at: 2 put: fullGCs.
- LastStats at: 3 put: fullGCTime.
- LastStats at: 4 put: incrGCs.
- LastStats at: 5 put: incrGCTime.
- LastStats at: 6 put: tenureCount.
 
+ ^str contents
- ^ str contents
  !

Item was added:
+ ----- Method: SystemNavigation>>allCallsOn:and:localToPackage: (in category 'query') -----
+ allCallsOn: firstLiteral and: secondLiteral localToPackage: packageNameOrInfo
+ "Answer a sorted collection of all the methods in the given package that call on both firstLiteral and secondLiteral."
+ "self systemNavigation browseAllCallsOn: #not and: #ifTrue: localToPackage: #Compiler"
+ | firstList secondList |
+ firstList := self allCallsOn: firstLiteral
+ fromBehaviors: (self packageInfoFor: packageNameOrInfo) classesAndMetaClasses
+ sorted: false.
+ secondList := (self
+ allCallsOn: secondLiteral
+ fromBehaviors: (firstList collect: [:each | each actualClass] as: IdentitySet)
+ sorted: false) asSet.
+ firstList removeAllSuchThat: [:each | (secondList includes: each) not].
+ ^firstList sort!

Item was added:
+ ----- Method: SystemNavigation>>browseAllCallsOn:and:localToPackage: (in category 'browse') -----
+ browseAllCallsOn: literal1 and: literal2 localToPackage: packageNameOrInfo
+ "Create and schedule a message browser on each method in the given package that refers to both literal1 and literal2."
+ "self default browseAllCallsOn: #open:label: localToPackage: 'Tools'."
+
+ self headingAndAutoselectForLiteral: literal1 do: [ :label :autoSelect |
+ self
+ browseMessageList: [
+ self
+ allCallsOn: literal1
+ and: literal2
+ localToPackage: packageNameOrInfo ]
+ name: label, ' local to package ', (self packageInfoFor: packageNameOrInfo) name
+ autoSelect: autoSelect ]!