Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours:
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004982.…
Name: Kernel-ul.625
Ancestors: Kernel-ul.624
Use #copyFrom: and #becomeForward: instead of #become: during changes of MethodDictionaries. These changes assume that #copyFrom: is atomic (just like #become: and #becomeForward:), so the MethodDictionaries never get into an inconsistent state.
These changes speed up #rehash, #removeAll, #removeKey:ifAbsent and also #compact if the dictionary already has the smallest possible capacity. This means that #rehashAllInstances and #rehashWithoutBecome is not necessary anymore, so those were removed.
=============================================
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004983.…
Name: Kernel-ul.626
Ancestors: Kernel-ul.625
MethodDictionary changes:
- fix: #compact shouldn't increase the load factor above 75% (see #sizeFor: on the class side)
- speed up #compact and #compactAllInstances by using #copyFrom: instead of #becomeForward: if the capacity of the dictionaries can't be reduced
- recategorized some class side methods
- use cascade in #at:put:
=============================================
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004984.…
Name: System-ul.453
Ancestors: System-dtl.452
Removed the last references to #rehashWithoutBecome.
=============================================
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004985.…
Name: Installer-Core-jmg.351
Ancestors: Installer-Core-nice.350
added 2 convenience methods to support the use of SqueakSource3 with the Installer. I don't think the camel-casing is correct but I wanted to remain the same as the other Squeak Source methods.
=============================================
Am 2011-09-18 um 17:10 schrieb commits(a)source.squeak.org:
> Nicolas Cellier uploaded a new version of Installer-Core to project The Trunk:
> http://source.squeak.org/trunk/Installer-Core-jmg.351.mcz
>
> ==================== Summary ====================
>
> Name: Installer-Core-jmg.351
> Author: jmg
> Time: 14 September 2011, 9:29:16.746 pm
> UUID: 47eb9fa0-6d3e-460f-95e5-23034b1ecf46
> Ancestors: Installer-Core-nice.350
>
> added 2 convenience methods to support the use of SqueakSource3 with the Installer. I don't think the camel-casing is correct but I wanted to remain the same as the other Squeak Source methods.
>
I'm fine with the non-camelcasing ;)
in fact squeakSource3 would look ridiculous
> =============== Diff against Installer-Core-nice.350 ===============
>
> Item was added:
> + ----- Method: Installer class>>squeaksource3 (in category 'repositories') -----
> + squeaksource3
> + ^ self monticello http: 'http://ss3.gemstone.com/ss/'!
>
> Item was added:
> + ----- Method: Installer class>>ss3 (in category 'repositories') -----
> + ss3
> + ^ self squeaksource3.!
Best
-Tobias
Nicolas Cellier uploaded a new version of Installer-Core to project The Trunk:
http://source.squeak.org/trunk/Installer-Core-jmg.351.mcz
==================== Summary ====================
Name: Installer-Core-jmg.351
Author: jmg
Time: 14 September 2011, 9:29:16.746 pm
UUID: 47eb9fa0-6d3e-460f-95e5-23034b1ecf46
Ancestors: Installer-Core-nice.350
added 2 convenience methods to support the use of SqueakSource3 with the Installer. I don't think the camel-casing is correct but I wanted to remain the same as the other Squeak Source methods.
=============== Diff against Installer-Core-nice.350 ===============
Item was added:
+ ----- Method: Installer class>>squeaksource3 (in category 'repositories') -----
+ squeaksource3
+ ^ self monticello http: 'http://ss3.gemstone.com/ss/'!
Item was added:
+ ----- Method: Installer class>>ss3 (in category 'repositories') -----
+ ss3
+ ^ self squeaksource3.!
Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.626.mcz
==================== Summary ====================
Name: Kernel-ul.626
Author: ul
Time: 18 September 2011, 3:18:04.315 pm
UUID: c917ec7b-b1ed-1849-bfb3-292cb3898035
Ancestors: Kernel-ul.625
MethodDictionary changes:
- fix: #compact shouldn't increase the load factor above 75% (see #sizeFor: on the class side)
- speed up #compact and #compactAllInstances by using #copyFrom: instead of #becomeForward: if the capacity of the dictionaries can't be reduced
- recategorized some class side methods
- use cascade in #at:put:
=============== Diff against Kernel-ul.625 ===============
Item was changed:
+ ----- Method: MethodDictionary class>>compactAllInstances (in category 'initialize-release') -----
- ----- Method: MethodDictionary class>>compactAllInstances (in category 'initialization') -----
compactAllInstances
+ | instancesToExchange newInstances |
+ instancesToExchange := Array streamContents: [ :oldStream |
+ newInstances := Array streamContents: [ :newStream |
+ self allInstances do: [ :each |
+ | newInstance |
+ newInstance := each compactWithoutBecome.
+ newInstance capacity = each capacity
+ ifTrue: [ each copyFrom: newInstance ]
+ ifFalse: [
+ oldStream nextPut: each.
+ newStream nextPut: newInstance ] ] ] ].
+ instancesToExchange elementsForwardIdentityTo: newInstances!
- | instances newInstances |
- instances := self allInstances asArray.
- newInstances := self allInstances collect: [ :each |
- each compactWithoutBecome ].
- instances elementsExchangeIdentityWith: newInstances!
Item was changed:
----- Method: MethodDictionary class>>new (in category 'instance creation') -----
new
+ "Create a new instance with 32 slots. See the comment of #sizeFor: why the argument is 16."
- "Create a new instance with 32 slots."
^self new: 16!
Item was changed:
----- Method: MethodDictionary class>>new: (in category 'instance creation') -----
+ new: numberOfElements
+ "Create an instance large enough to hold numberOfElements without growing. Note that the basic size must be a power of 2. It is VITAL (see grow) that size gets doubled if numberOfElements is a power of 2"
- new: nElements
- "Create a Dictionary large enough to hold nElements without growing.
- Note that the basic size must be a power of 2.
- It is VITAL (see grow) that size gets doubled if nElements is a power of 2"
| size |
+ size := self sizeFor: numberOfElements.
- size := 1 bitShift: nElements highBit.
^(self basicNew: size) initialize: size!
Item was added:
+ ----- Method: MethodDictionary class>>sizeFor: (in category 'sizing') -----
+ sizeFor: numberOfElements
+ "Return the minimum capacity of a dictionary that can hold numberOfElements elements. At least 25% of the array must be empty and the return value must be a power of 2."
+
+ ^1 bitShift: (numberOfElements * 4 // 3) highBit!
Item was changed:
----- Method: MethodDictionary>>at:put: (in category 'accessing') -----
at: key put: value
"Set the value at key to be value."
| index |
index := self scanFor: key.
(self basicAt: index)
ifNil: [
+ self
+ basicAt: index put: key;
+ atNewIndex: index put: value ]
- self basicAt: index put: key.
- self atNewIndex: index put: value ]
ifNotNil: [
(array at: index) flushCache.
array at: index put: value ].
^value!
Item was changed:
----- Method: MethodDictionary>>compact (in category 'private') -----
compact
+ "Make sure that I have the highest possible load factor (between 37.5% and 75%)."
- "Make sure that I have the highest possible load factor (at least 50%)."
| newInstance |
newInstance := self compactWithoutBecome.
+ newInstance capacity = self capacity
+ ifTrue: [ self copyFrom: newInstance ]
+ ifFalse: [ self becomeForward: newInstance ]!
- newInstance capacity = self capacity ifFalse: [
- self becomeForward: newInstance ]!
Item was changed:
----- Method: MethodDictionary>>compactWithoutBecome (in category 'private') -----
compactWithoutBecome
+ "Return a copy of self which has the highest possible load factor (between 37.5% and 75%)."
- "Return a copy of self which has the highest possible load factor (at least 50%)."
+ | newInstance |
+ newInstance := self species new: self size.
+ 1 to: self basicSize do: [ :index |
+ (self basicAt: index) ifNotNil: [ :key |
+ newInstance at: key put: (array at: index) ] ].
+ ^newInstance!
- | newSelf |
- newSelf := self class new: self size.
- self keysAndValuesDo: [ :key :value |
- newSelf at: key put: value ].
- ^newSelf!
Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.625.mcz
==================== Summary ====================
Name: Kernel-ul.625
Author: ul
Time: 18 September 2011, 11:54:02.722 am
UUID: 14b3a206-0a64-6049-83f2-fa4a151207cf
Ancestors: Kernel-ul.624
Use #copyFrom: and #becomeForward: instead of #become: during changes of MethodDictionaries. These changes assume that #copyFrom: is atomic (just like #become: and #becomeForward:), so the MethodDictionaries never get into an inconsistent state.
These changes speed up #rehash, #removeAll, #removeKey:ifAbsent and also #compact if the dictionary already has the smallest possible capacity. This means that #rehashAllInstances and #rehashWithoutBecome is not necessary anymore, so those were removed.
=============== Diff against Kernel-ul.624 ===============
Item was removed:
- ----- Method: MethodDictionary class>>rehashAllInstances (in category 'initialization') -----
- rehashAllInstances
-
- | instances newInstances |
- instances := self allInstances asArray.
- newInstances := self allInstances collect: [ :each |
- each rehashWithoutBecome ].
- instances elementsExchangeIdentityWith: newInstances!
Item was changed:
----- Method: MethodDictionary>>compact (in category 'private') -----
compact
"Make sure that I have the highest possible load factor (at least 50%)."
+ | newInstance |
+ newInstance := self compactWithoutBecome.
+ newInstance capacity = self capacity ifFalse: [
+ self becomeForward: newInstance ]!
- self become: self compactWithoutBecome!
Item was changed:
----- Method: MethodDictionary>>rehash (in category 'private') -----
rehash
+ | newInstance |
+ newInstance := self species new: self basicSize - 1. "Make sure it has the same capacity"
+ 1 to: self basicSize do: [ :index |
+ (self basicAt: index) ifNotNil: [ :key |
+ newInstance at: key put: (array at: index) ] ].
+ self copyFrom: newInstance!
- self become: self rehashWithoutBecome!
Item was removed:
- ----- Method: MethodDictionary>>rehashWithoutBecome (in category 'private') -----
- rehashWithoutBecome
-
- | newInstance |
- newInstance := self species new: self basicSize - 1. "Make sure it has the same capacity"
- 1 to: self basicSize do: [ :index |
- (self basicAt: index) ifNotNil: [ :key |
- newInstance at: key put: (array at: index) ] ].
- ^newInstance!
Item was changed:
----- Method: MethodDictionary>>removeAll (in category 'removing') -----
removeAll
"This provides a faster way than repeated become.
a single become is still in use to prevent system crash."
| newSelf |
tally = 0 ifTrue: [^self].
newSelf := self species new: self basicSize - 1. "This will preserve the capacity"
+ self copyFrom: newSelf!
- self become: newSelf!
Item was changed:
----- Method: MethodDictionary>>removeKey:ifAbsent: (in category 'removing') -----
removeKey: key ifAbsent: errorBlock
"The interpreter might be using this MethodDict while
this method is running!! Therefore we perform the removal
+ in a copy, and then atomically copy that copy"
- in a copy, and then atomically become that copy"
| copy |
copy := self copy.
copy removeDangerouslyKey: key ifAbsent: [^ errorBlock value].
+ self copyFrom: copy!
- self become: copy!
I have uploaded a new alpha of CogDroid:
http://squeakvm-tablet.googlecode.com/files/CogDroid-alpha-20110918.apk
Intent filtering has been added to the application. Also application
icon and Java package name (org.golubovsky.cogstack) have been
updated.
Intents in Android are messages that an application may pass around to
invoke other applications that subscribe to filtering intents with
some properties.
That is, another application may broadcast an Intent (via
startActivity()) with scheme "file", content-type
"application/x-squeak-image", and path to the image as data. CogDroid
will start right with the image given (provided that it exists)
without scanning the sdcard storage for available image files.
Sample Java code for this:
public void launchImage(String imgpath) {
Intent cog = new Intent();
cog.setAction(Intent.ACTION_VIEW);
Uri uri = new Uri.Builder().scheme("file").path(imgpath).build();
cog.setDataAndType(uri, "application/x-squeak-image");
try {
startActivity(cog);
} catch (Exception e) {
// process the exception: it is raised if no
recipients were found for this intent, e. g. CogDroid is not
installed.
}
}
Relevant section in CogDroid's AndroidManifest.xml:
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="file"
android:mimeType="application/x-squeak-image" />
</intent-filter>
I also created a simple launcher for two images (the application when
installed shows an icon for each image). Unfortunately image paths are
hardcoded (but just for illustration this should be OK), and a single
Activity subclass is required for each image file.
See under https://gitorious.org/~golubovsky/cogvm/dmg-blessed/trees/master/platforms/…
Thanks.
--
Dimitry Golubovsky
Anywhere on the Web
Changes to Trunk (http://source.squeak.org/trunk.html) in the last 24 hours:
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004976.…
Name: KernelTests-ul.201
Ancestors: KernelTests-ul.200, KernelTests-ul.199
- merged KernelTests-ul.199
- added a test which checks if ProcessLocalVariable class >> value: returns it's argument
=============================================
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004977.…
Name: Kernel-ul.624
Ancestors: Kernel-eem.623, Kernel-ul.613, Kernel-ul.619
- merged Kernel-ul.613 and Kernel-ul.619
- ProcessLocalVariable class >> value: returns it's argument just like assignments
=============================================
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004978.…
Name: KernelTests-ul.202
Ancestors: KernelTests-ul.201
- make sure that the test variables are removed from process' environment
=============================================
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004979.…
Name: KernelTests-ul.199
Ancestors: KernelTests-cmm.198
Tests for ProcessSpecific from Pharo.
=============================================
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004980.…
Name: Kernel-ul.619
Ancestors: Kernel-nice.618
Proposed solution to the Monitor bug (see MonitorTest >> #testMonitorNotGainingUnwantedSignalsDuringUnwinding). The cause of the bug is that the process exits the monitor while it's waiting and it's expected to enter again (see #exitAndWaitInQueue:maxMilliseconds:), but that doesn't happen if the process is terminated. If we ensure that it enters again, then the ensured exit in #critical: won't cause any trouble.
Also ensure that the delay is unscheduled. The goal of this change is to avoid accumulating MonitorDelays and Semaphores when a waiting process is terminated. This is unrelated to the bug described above.
=============================================
http://lists.squeakfoundation.org/pipermail/packages/2011-September/004981.…
Name: Kernel-ul.613
Ancestors: Kernel-cmm.612
Extracted and enhanced the ProcessSpecific from Pharo.
=============================================
Levente Uzonyi uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-ul.613.mcz
==================== Summary ====================
Name: Kernel-ul.613
Author: ul
Time: 16 August 2011, 11:33:03.744 am
UUID: cd3bc5e7-fabf-b74a-9f8c-18eee845bc9b
Ancestors: Kernel-cmm.612
Extracted and enhanced the ProcessSpecific from Pharo.
=============== Diff against Kernel-cmm.612 ===============
Item was changed:
SystemOrganization addCategory: #'Kernel-Chronology'!
SystemOrganization addCategory: #'Kernel-Classes'!
SystemOrganization addCategory: #'Kernel-Methods'!
+ SystemOrganization addCategory: #'Kernel-Models'!
SystemOrganization addCategory: #'Kernel-Numbers'!
SystemOrganization addCategory: #'Kernel-Objects'!
SystemOrganization addCategory: #'Kernel-Processes'!
+ SystemOrganization addCategory: #'Kernel-Processes-Variables'!
- SystemOrganization addCategory: #'Kernel-Models'!
Item was added:
+ ProcessSpecificVariable subclass: #DynamicVariable
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Kernel-Processes-Variables'!
+
+ !DynamicVariable commentStamp: 'mvl 3/13/2007 13:55' prior: 0!
+ My subclasses are dynamic variables: each subclass represents a variable
+ whose value persists inside the block passed to #value:during:. There is
+ no way to change the value inside such a block, but it is possible to
+ temporarirly rebind it in a nested manner.!
Item was added:
+ ----- Method: DynamicVariable class>>value:during: (in category 'accessing') -----
+ value: anObject during: aBlock
+
+ | p oldValue |
+ p := Processor activeProcess.
+ oldValue := p environmentAt: self ifAbsent: [self default].
+ ^[
+ p environmentAt: self put: anObject.
+ aBlock value ]
+ ensure: [ p environmentAt: self put: oldValue ].!
Item was added:
+ ----- Method: Process>>environmentAt: (in category 'process specific') -----
+ environmentAt: key
+ ^ self environmentAt: key ifAbsent: [self environmentKeyNotFound]!
Item was added:
+ ----- Method: Process>>environmentAt:ifAbsent: (in category 'process specific') -----
+ environmentAt: key ifAbsent: aBlock
+
+ ^(env ifNil: [ ^aBlock value ]) at: key ifAbsent: aBlock.!
Item was added:
+ ----- Method: Process>>environmentAt:put: (in category 'process specific') -----
+ environmentAt: key put: value
+
+ ^(env ifNil: [ env := Dictionary new ]) at: key put: value.!
Item was added:
+ ----- Method: Process>>environmentKeyNotFound (in category 'process specific') -----
+ environmentKeyNotFound
+ self error: 'Environment key not found'!
Item was added:
+ ----- Method: Process>>environmentRemoveKey: (in category 'process specific') -----
+ environmentRemoveKey: key
+ ^ self environmentRemoveKey: key ifAbsent: [self environmentKeyNotFound]!
Item was added:
+ ----- Method: Process>>environmentRemoveKey:ifAbsent: (in category 'process specific') -----
+ environmentRemoveKey: key ifAbsent: errorBlock
+
+ ^(env ifNil: [ ^errorBlock value ]) removeKey: key ifAbsent: errorBlock!
Item was added:
+ ProcessSpecificVariable subclass: #ProcessLocalVariable
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Kernel-Processes-Variables'!
+
+ !ProcessLocalVariable commentStamp: 'mvl 3/13/2007 12:28' prior: 0!
+ My subclasses have values specific to the active process. They can be read with #value and set with #value:!
Item was added:
+ ----- Method: ProcessLocalVariable class>>value: (in category 'accessing') -----
+ value: anObject
+ Processor activeProcess environmentAt: self put: anObject!
Item was added:
+ Object subclass: #ProcessSpecificVariable
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Kernel-Processes-Variables'!
+ ProcessSpecificVariable class
+ instanceVariableNames: 'hash'!
+
+ !ProcessSpecificVariable commentStamp: 'mvl 3/13/2007 13:53' prior: 0!
+ My subclasses (not instances of them) keep state specific to the current process.
+
+ There are two kinds of process-specific variables: process-local (state available
+ for read and write in all methods inside the process), and dynamic variables
+ (implementing dynamic scope).!
+ ProcessSpecificVariable class
+ instanceVariableNames: 'hash'!
Item was added:
+ ----- Method: ProcessSpecificVariable class>>default (in category 'accessing') -----
+ default
+ "Answer the default value for the variable. The default for the default value is nil."
+ ^nil!
Item was added:
+ ----- Method: ProcessSpecificVariable class>>hash (in category 'accessing') -----
+ hash
+
+ ^hash ifNil: [ hash := super hash ]!
Item was added:
+ ----- Method: ProcessSpecificVariable class>>value (in category 'accessing') -----
+ value
+ "Answer the current value for this variable in the current context."
+ ^Processor activeProcess environmentAt: self ifAbsent: [self default].!