Patches/changes to the base Pharo Image
We can make patches in three ways :
Installer Patches
They are done by compiling methods from the installer before loading any code. Should be done for core patches that we need before loading GT. Should be done in fewer cases.
Current file with patches: load-patches.st
PostLoad Patches
These are chages that we do as postload actions after loading a baseline.
InImage Patches
These are just method/classes moved to a different repo. This is the most common one.
Installer Patches
ExternalAddress int primitives
Primitives for int operations in ExternalAddress
can randomly crash the VM. As a workaround we remove the primitive:
pragma and make FFI calls which pass.
Patched in installer: get rid of PharoPatcher and update pharo vms
Pharo Issue: Running a script crashes the VM
RBCommentChange>>#primitiveExecute
Raises a broken ClassCommented
event with nil
as values, which confuses Epicea.
Patched in installer: Patch RBCommentChange>>primitiveExecute
MCPackageLoader>>tryToLoad: loads classes twice
The method MCPackageLoader>>#tryToLoad:
loads classes twice. This is mentioned in in the comment if MCPackageLoader>>#basicLoadDefinitions
. However, the fact that classes is loaded twice leads to a significant slowdown especially in code that uses traits.
We patch it in the installer by ignoring class definitions in that method.
MCMethodDefinition>>#addMethodAdditionTo: sets the compiled method in MethodAddition
The method MCMethodDefinition>>#addMethodAdditionTo:
when creating a MethodAddition
uses MethodAddition>>#createCompiledMethod
to create the compiled method that will be later added to the class. However, depending on the actual chages, if some class definitions have errors, not all class definitions might be compiled at that point resulting in compiled methods that point to undeclared variables.
Patched in installer: Do not set a compiled method in MethoddAddition
This issue is specific to Pharo 10/11.
CompiledMethod >>basicAsMCMethodDefinition is slow
The method CompiledMethod>>#basicAsMCMethodDefinition
computes the method timestamp using CompiledCode>>#stamp
which parses the time from the sources file.
It does not look like MCMethodDefinition
needs the timestamp during normal operations.
We patch it in the installer by not setting the timestamp when creating MCMethodDefinition
for compiled methods.
Pharo Issue: Enhance Iceberg or CompiledMethod>>timeStamp to not read the timestamp from the source file
RBParser>>parseKeywordMessageWith:
We override it to use a WriteStream
to create the selector, instead of concatenating strings.
RPackage>>toTagName:
We override it to avoid creating a symbol.
Month class>>#indexOfMonth:
We override it to get a faster comparison.
Pharo Issue: Improve performance of Month class>>indexOfMonth:
Object>>#setPinnedInMemory:
This method was causing crashes. Most likely fixed in the vm for Pharo 11, maybe also Pharo 10.
ExternalData>>readStringUTF8
ExternalData>>#readStringUTF8
(which is part of the UnifiedFFI package in the threadedFFI-Plugin repository) is currently strict about interpreting strings as UTF8 encoded.
Moving to threaded FFI means that readStringUTF8 is used to read strings such as the commit message in git, which are not guaranteed to be UTF8 encoded.
Modify the method so that if the UTF8 conversion fails the string is returned as a null encoded string.
Metaclass>>classVariableNamed:ifAbsent:
Metaclass is not polymorphic with Class in all contexts. We add Metaclass>>#classVariableNamed:ifAbsent:
as a patch.
Inconsistency when comparing compiled methods
When comparing two compiled methods that have the same code but different selectors, they can either be equal of different depending on whether or not they have pragmas
We added CompiledMethod>>#=
that just calls super and adds a check for the selector.
Pharo Issue: Inconsistency when comparing compiled methods
ShMetaclassChanged>>propagateToSubclasses: and ShMetaclassChangeDetector>>newChanges
Adding an instance variable to a class, which has subclasses with variables and references to those variables, will require recompiling the methods since the instance variable references are index based in the compiled methods. None of the recompiles show up as announcements, so a cache that holds on to compiled methods becomes invalid.
FFIUnixLibraryFinder>>basePaths
On linux we extend the places for placing libraries with the lib
folder next to the vm directory by changing FFIUnixLibraryFinder>>#basePaths
.
(Smalltalk vm directory asFileReference parent / 'lib')
Library names for LGitLibrary and CairoLibrary
We change the FFI library names to use names that do not have versions in them:
LGitLibrary>>#macLibraryName
: libgit2.dylib
LGitLibrary>>#unix64LibraryName
: libgit2.so
LGitLibrary>>#unix32LibraryName
: git2.dll
CairoLibrary>>#macLibraryName
: libcairo.dylib
CairoLibrary>>#win32LibraryName
: cairo.dll
Other Patches
EpBehaviorCategoryChange misses old package name
EpBehaviorCategoryChange
does not have the name of the old package name. This means we cannot distinguish package/tag name by looking at the event. Makes it harder to group changes by package in Epicea.
Patched in gt4changes in a hack-ish way. In the postload of BaselineOfGToolkit4Changes
we add the trait TGtEpBehaviorCategoryChangeOldPackageName
to EpBehaviorCategoryChange
and override EpBehaviorCategoryChange>>#initializeOldCategory:newCategory:class:
in GToolkit4Epicea
to extract the old package name.
EpMethodModification has incorrect previous package name
When transforming a method into an extension method, EpMethodModification
does not store the previous package name of the method. Makes it harder to group method changes by package.
Patched in gt4changes in a hack-ish way. In the postload of BaselineOfGToolkit4Changes
we add the trait TGtEpMethodModificationClassPackagename
to EpMethodModification
and override EpMethodModification>>#initializeWithOldMethod:newMethod:
in GToolkit4Epicea
to extract the old package name.
Change Formatting of Generated Accessors
Accessors generated by the base image have an extra newline in them.
Patched by fixing the template strings. Changes are linked to the original issue: Keep code formatting consistent when one creates accessors for slots in an object/class
Remove Transcript Spam from FFI
Transcript is spammed with Returning an object but pool is full
. Changes are linked to the original issue: "Returning an object but pool is full" spammed in Transcript
FastSubscriptionRegistry instead of SubscriptionRegistry
FastSubscriptionRegistry
optimises how users can check if an object is registered as a subscriber within an announcer.
This checks happens many times in Bloc when delivering events.
The class side method FastSubscriptionRegistry>>#initialize
registers this registry as default when the class is initialize.
Class installer that triggers class changes once
There are current several operations related to classes that lead to methods being recompiled in subclasses without that being announced.
Pharo Issue: Announcements not signalled for method recompilations in subclasses when a superclass is changed
Pharo issue: some announcements are not signaled on class changes
EvaluateCommandLineHandler doesn't allow other options
EvaluateCommandLineHandler
will fail to parse the command to be evaluated correctly if other global options are present, e.g. --pharoDebugLog
.
Patch commit: gtoolkit-utility#1da66e56
PositionableStream>>#on: precondition
We add an explicit precondition in PositionableStream>>#on:
for ensuring that the given collection is not nil
. We do this to ensure the method works correctly in case a size
method is defined in UndefinedObject
, for example for compatibility with other Smalltalk dialects.
Extensions
These are extensions to the basic image, rather than overrides
ZnEasy class>>gtGetPng:
When reading some PNGs, ImageReadWriter
can trigger errors. We added ZnEasy>>#gtGetPng:
that uses SkiaImage
to create a form.
Patch Commit: Add #gtGetPng: