O2 and O1 compilation produce a segmentation fault due to stack corruption (when debugging we saw some extra pushes from the stack) on callbacks return. This happens on windows 32, when compiling with mingw gcc 7.4.0.
The issue can be reproduced easily by running the Alien qsort example in latest vms in both Pharo and Squeak.
This PR proposes to patch just the thunkEntry function. Not optimizing just that function solves the issue in our environment, though maybe there is a more fine-grained solution. We should still investigate what is the particular optimization that causes the problem.
You can view, comment on, or merge this pull request online at:
https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/353
-- Commit Summary --
* Patch callback thunkEntry to not optimize, failing in win32 using gcc 7.4.0
-- File Changes --
M platforms/Cross/plugins/IA32ABI/ia32abicc.c (2)
-- Patch Links --
https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/353.patchhttps://github.com/OpenSmalltalk/opensmalltalk-vm/pull/353.diff
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/pull/353
In addition to the existing alpha blending rules (24 and 34), I propose 3 new additional rules.
Check https://en.wikipedia.org/wiki/Alpha_compositing
Existing rule 34 is a correct implementation of Alpha Blending for scaled forms, i.e. if premultiplied alpha is used. But rule 24 is a correct implementation of non-scaled forms, only for the case where destination is opaque (i.e. it's alpha is 1.0 in every pixel). If destination includes translucency (or it is completely transparent), the result is not correct. In order to fix it, the RGB of each pixel need to be divided by the pixel alpha.
The proposed blendUnscaled is the basic (for non-scaled forms) alpha blending described in Wikipedia. Note that users knowing that destination background is opaque might call the faster rule 24 instead.
The other two additional proposed rules are for converting to and from premultiplied alpha.
EXISTING blend 24 alphaBlend
resultAlpha = srcAlpha + destAlpha*(1-srcAlpha)
resultRGB = srcAlpha*source + (1-srcAlpha)*dest
EXISTING blendAlphaScaled 34 alphaBlendScaled
resultRGBA = source + (1-srcAlpha)*dest
NEW PROPOSED multiplyRGBByAlpha
Non premultiplied alpha -> premultiplied alpha. Only uses destination. Alpha unmodified. For each RGB component,
resultRGB = dest*destAlpha
NEW PROPOSED divideRGBByAlpha
Premultiplied alpha -> non premultiplied alpha. Only uses destination. Alpha unmodified. For each RGB component,
resultRGB = dest/destAlpha
NEW PROPOSED blendUnscaled
Equivalent to blend, and then divideRGBByAlpha
resultAlpha = srcAlpha + destAlpha*(1-srcAlpha)
resultRGB = (srcAlpha*source + (1-srcAlpha)*dest) / resultAlpha
This would allow handling of scaled (premultiplied-alpha) forms, and blending of regular forms including translucency, without the need to call slower smalltalk code to fix the results.
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/505
I am trying to build the unix sources for this project, exactly following the `HowToBuildFromSources` manual (the easy way). But unfortunately, when running `make` I get an error that `bld/plugins.int` is missing:
```
$ make
[ -d bld ] || mkdir bld
[ -f bld/Makefile ] || ( cd bld; ../config/configure; )
checking for gcc... gcc
# ... (75 lines skipped)
checking whether to build static libraries... no
/workspace/opensmalltalk-vm/src
/workspace/opensmalltalk-vm/src/plugins
checking sanity of generated src directory... bad
missing file: /workspace/opensmalltalk-vm/platforms/unix/bld/plugins.int
make: *** [Makefile:5: all] Error 1
```
See yourself:
[](https://gitpod.io/#snapshot/9bc102f3-ba84-437f-a226-a8851782c41b)
Is it me or is the documentation of the build process not up to date? Looking forward to your help!
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/507
UnixProcess class>>forkSqueak is no longer working. The forked child process VM crashes with segmentation fault. Testing with VMs from bintray shows that version 5.0-202009300634 works, and any version 5.0-202010192227 or later fails. Stack dump sometimes (but not always) shows failure in aioPoll() for example:
*/usr/local/bin/../lib/squeak/5.0-202101160259/squeak(aioPoll+0x12e)[0x4bc0fe]
I am not able to catch the failure in gdb because it happens in the child process. My initial guess is that it may be related to the epoll enhancements added in this time frame, because forking the VM requires initializing things like this in the new child VM process.
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/548
VM: win32x86.cog.spur (202011160746, VMMaker.oscog-eem.2887)
OS: Windows 10
SQ: Squeak6.0alpha #20077
I suppose that `Context >> #objectClass:` (primitive 111) answers `Context` from time to time. I cannot really debug it, though. Sometimes `Context >> #printOn:` does the right thing.

--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/536
`build.win32x86/HowToBuild` describes how we can build the VM using cygwin. However, I have installed WSL instead. When running `mvm`, it gives me:
```
../../platforms/win32/vm/sqWin32Utils.c:11:10: fatal error: Windows.h: No such file or directory
```
What do I have to do to enable mingw to find these header files? Any help is appreciated.
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/510
Eliot Miranda uploaded a new version of VMMaker to project VM Maker Inbox:
http://source.squeak.org/VMMakerInbox/VMMaker.oscog-eem.2765.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.2765
Author: eem
Time: 23 June 2020, 6:41:19.556484 pm
UUID: 91b9976e-60b9-4b5c-a2f8-b621dd454a07
Ancestors: VMMaker.oscog-eem.2764
Spur: Rewrite the revised followForwardedObjectFields:toDepth: soi it can be correctly inlined.
Slang: Change the order of application of ensureConditionalAssignmentsAreTransformedIn: so it is always the last thing done in tryToInlineMethodsIn:.
Straight-forward optimization of bindVariablesIn: in the common case of methods being inlined swith unchanged parameters.
=============== Diff against VMMaker.oscog-eem.2764 ===============
Item was changed:
----- Method: Spur32BitCoMemoryManager>>followForwardedObjectFields:toDepth: (in category 'as yet unclassified') -----
followForwardedObjectFields: objOop toDepth: depth
"Follow pointers in the object to depth.
Answer if any forwarders were found.
How to avoid cyclic structures?? A temporary mark bit? eem 6/22/2020 no need since depth is always finite."
<api>
<inline: false>
+ | found fmt limit |
- | oop found fmt |
found := false.
self assert: ((self isPointers: objOop) or: [self isOopCompiledMethod: objOop]).
fmt := self formatOf: objOop.
+ limit := (self numPointerSlotsOf: objOop format: fmt) - 1.
"It is essential to skip the first field of a method because it may be a
reference to a Cog method in the method zone, not a real object at all."
((self isCompiledMethodFormat: fmt)
ifTrue: [1]
ifFalse: [0])
+ to: limit
+ do: [:i| | oop |
- to: (self numPointerSlotsOf: objOop format: fmt) - 1
- do: [:i|
oop := self fetchPointer: i ofObject: objOop.
(self isNonImmediate: oop) ifTrue:
[(self isForwarded: oop) ifTrue:
[found := true.
oop := self followForwarded: oop.
self storePointer: i ofObject: objOop withValue: oop].
(depth > 0
and: [(self hasPointerFields: oop)
and: [self followForwardedObjectFields: oop toDepth: depth - 1]]) ifTrue:
[found := true]]].
^found!
Item was changed:
----- Method: Spur64BitCoMemoryManager>>followForwardedObjectFields:toDepth: (in category 'forwarding') -----
followForwardedObjectFields: objOop toDepth: depth
"Follow pointers in the object to depth.
Answer if any forwarders were found.
How to avoid cyclic structures?? A temporary mark bit? eem 6/22/2020 no need since depth is always finite."
<api>
<inline: false>
+ | found fmt limit |
- | oop found fmt |
found := false.
self assert: ((self isPointers: objOop) or: [self isOopCompiledMethod: objOop]).
fmt := self formatOf: objOop.
+ limit := (self numPointerSlotsOf: objOop format: fmt) - 1.
"It is essential to skip the first field of a method because it may be a
reference to a Cog method in the method zone, not a real object at all."
((self isCompiledMethodFormat: fmt)
ifTrue: [1]
ifFalse: [0])
+ to: limit
+ do: [:i| | oop |
- to: (self numPointerSlotsOf: objOop format: fmt) - 1
- do: [:i|
oop := self fetchPointer: i ofObject: objOop.
(self isNonImmediate: oop) ifTrue:
[(self isForwarded: oop) ifTrue:
[found := true.
oop := self followForwarded: oop.
self storePointer: i ofObject: objOop withValue: oop].
(depth > 0
and: [(self hasPointerFields: oop)
and: [self followForwardedObjectFields: oop toDepth: depth - 1]]) ifTrue:
[found := true]]].
^found!
Item was changed:
----- Method: TMethod>>exitVar:label:in: (in category 'inlining') -----
exitVar: exitVar label: exitLabel in: aCodeGen
"Replace each return statement in this method with an assignment to the
exit variable followed by either a return or a goto to the given label.
Answer if a goto was generated."
"Optimization: If exitVar is nil, the return value of the inlined method is not being used, so don't add the assignment statement."
| labelUsed map elisions eliminateReturnSelfs |
labelUsed := false.
map := Dictionary new.
elisions := Set new.
"Conceivably one might ^self from a struct class and mean it. In most cases though
^self means `get me outta here, fast'. So unless this method is from a VMStruct class,
elide any ^self's"
eliminateReturnSelfs := ((definingClass inheritsFrom: VMClass) and: [definingClass isStructClass]) not
and: [returnType = #void or: [returnType = #sqInt]].
parseTree nodesDo:
[:node | | replacement |
node isReturn ifTrue:
[self transformReturnSubExpression: node
toAssignmentOf: exitVar
andGoto: exitLabel
unless: eliminateReturnSelfs
into: [:rep :labelWasUsed|
replacement := rep.
labelWasUsed ifTrue: [labelUsed := true]]
in: aCodeGen.
"replaceNodesIn: is strictly top-down, so any replacement for ^expr ifTrue: [...^fu...] ifFalse: [...^bar...]
will prevent replacement of either ^fu or ^bar. The corollary is that ^expr ifTrue: [foo] ifFalse: [^bar]
must be transformed into expr ifTrue: [^foo] ifFalse: [^bar]"
(node expression isConditionalSend
and: [node expression hasExplicitReturn])
ifTrue:
[elisions add: node.
(node expression args reject: [:arg| arg endsWithReturn]) do:
[:nodeNeedingReturn|
self transformReturnSubExpression: nodeNeedingReturn statements last
toAssignmentOf: exitVar
andGoto: exitLabel
unless: eliminateReturnSelfs
into: [:rep :labelWasUsed|
replacement := rep.
+ labelWasUsed ifTrue: [labelUsed := true]]
+ in: aCodeGen.
- labelWasUsed ifTrue: [labelUsed := true]].
map
at: nodeNeedingReturn statements last
put: replacement]]
ifFalse:
[map
at: node
put: (replacement ifNil:
[TLabeledCommentNode new setComment: 'return ', node expression printString])]]].
map isEmpty ifTrue:
[self deny: labelUsed.
^false].
"Now do a top-down replacement for all returns that should be mapped to assignments and gotos"
parseTree replaceNodesIn: map.
"Now it is safe to eliminate the returning ifs..."
elisions isEmpty ifFalse:
[| elisionMap |
elisionMap := Dictionary new.
elisions do: [:returnNode| elisionMap at: returnNode put: returnNode expression].
parseTree replaceNodesIn: elisionMap].
"Now flatten any new statement lists..."
parseTree nodesDo:
[:node| | list |
(node isStmtList
and: [node statements notEmpty
and: [node statements last isStmtList]]) ifTrue:
[list := node statements last statements.
node statements removeLast; addAllLast: list]].
^labelUsed!
Item was changed:
----- Method: TMethod>>inlineFunctionCall:in: (in category 'inlining') -----
inlineFunctionCall: aSendNode in: aCodeGen
"Answer the body of the called function, substituting the actual
parameters for the formal argument variables in the method body.
Assume caller has established that:
1. the method arguments are all substitutable nodes, and
2. the method to be inlined contains no additional embedded returns."
| sel meth doNotRename argsForInlining substitutionDict |
+ aCodeGen maybeBreakForInlineOf: aSendNode in: self.
sel := aSendNode selector.
meth := (aCodeGen methodNamed: sel) copy.
meth ifNil:
[^self inlineBuiltin: aSendNode in: aCodeGen].
doNotRename := Set withAll: args.
argsForInlining := aSendNode argumentsForInliningCodeGenerator: aCodeGen.
meth args with: argsForInlining do:
[ :argName :exprNode |
exprNode isLeaf ifTrue:
[doNotRename add: argName]].
(meth statements size = 2
and: [meth statements first isSend
and: [meth statements first selector == #flag:]]) ifTrue:
[meth statements removeFirst].
meth renameVarsForInliningInto: self except: doNotRename in: aCodeGen.
meth renameLabelsForInliningInto: self.
self addVarsDeclarationsAndLabelsOf: meth except: doNotRename.
substitutionDict := Dictionary new: meth args size * 2.
meth args with: argsForInlining do:
[ :argName :exprNode |
+ (exprNode isVariable and: [exprNode name = argName]) ifFalse:
+ [substitutionDict at: argName put: exprNode].
- substitutionDict at: argName put: exprNode.
(doNotRename includes: argName) ifFalse:
[locals remove: argName]].
meth parseTree bindVariablesIn: substitutionDict.
^meth parseTree endsWithReturn
ifTrue: [meth parseTree copyWithoutReturn]
ifFalse: [meth parseTree]!
Item was changed:
----- Method: TMethod>>tryToInlineMethodsIn: (in category 'inlining') -----
tryToInlineMethodsIn: aCodeGen
"Expand any (complete) inline methods sent by this method.
Set the complete flag when all inlining has been done.
Answer if something was inlined."
| didSomething statementLists |
"complete ifTrue:
[^false]."
self definedAsMacro ifTrue:
[complete ifTrue:
[^false].
^complete := true].
- self ensureConditionalAssignmentsAreTransformedIn: aCodeGen.
didSomething := self tryToInlineMethodStatementsIn: aCodeGen statementListsInto: [:stmtLists| statementLists := stmtLists].
didSomething := (self tryToInlineMethodExpressionsIn: aCodeGen) or: [didSomething].
+ self ensureConditionalAssignmentsAreTransformedIn: aCodeGen.
didSomething ifTrue:
[writtenToGlobalVarsCache := nil].
complete ifFalse:
[self checkForCompletenessIn: aCodeGen.
complete ifTrue: [didSomething := true]]. "marking a method complete is progress"
^didSomething!
Item was changed:
----- Method: TStmtListNode>>bindVariablesIn: (in category 'transformations') -----
bindVariablesIn: aDictionary
+ aDictionary notEmpty ifTrue:
+ [statements := statements collect: [:s| s bindVariablesIn: aDictionary]]!
- statements := statements collect: [ :s | s bindVariablesIn: aDictionary ].!
I noticed this a few times, and today I observed it a bit: After resuming my Win10 message from sleep, my two open Squeak.exe processes both made up each ~14% CPU load. I suspect this performance gap is caused by the VM because, in one image, a nearly empty Morphic world was open (two non-stepping windows only) and in the other one, a completely empty MVC world; both images were responsive; and according to Squeak's CPU watcher, only ~20% of time were spent in the UI process but 80% in idle. After a few minutes, both VM instances fall back to ~0.1% of total CPU usage.
Is there any chance to find an explanation for this behavior in the VM implementation, are there any hidden background operations (maybe certain WM_MESSAGES) that are triggered after resuming from sleep? Does anyone else notice similar behavior?
For sake of completeness, I should mention that my RAM and disk usage are chronically near maximum (90% of RAM in use, 25 GB on SSD free. Squeak images are so large 😐). But this does not change after a few minutes so I don't think it explains the observed slowdown completely.
VM build 202010232046; but I could already have experienced similar issues a few months ago.
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/OpenSmalltalk/opensmalltalk-vm/issues/537