Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge branch 'integrate-with-ipad' of our main repository into update…

…-generated-sources

- preferred upstream source of the Cog repo
- preferred the code generated myself (intplugins)

Conflicts:
	.gitignore
	vm/src/externals/externals.cpp
	vm/src/externals/externals.h
	vm/src/from_squeak/Cross/plugins/FilePlugin/FilePlugin.h
	vm/src/from_squeak/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c
	vm/src/from_squeak/Cross/plugins/SocketPlugin/SocketPlugin.h
	vm/src/from_squeak/Cross/plugins/SoundPlugin/SoundPlugin.h
	vm/src/from_squeak/Cross/plugins/SqueakFFIPrims/sqFFI.h
	vm/src/from_squeak/Cross/vm/sq.h
	vm/src/from_squeak/Cross/vm/sqMemoryAccess.h
	vm/src/from_squeak/Cross/vm/sqNamedPrims.c
	vm/src/from_squeak/Cross/vm/sqVirtualMachine.c
	vm/src/from_squeak/Cross/vm/sqVirtualMachine.h
	vm/src/from_squeak/Mac OS/plugins/B3DAcceleratorPlugin/sqMacOpenGL.c
	vm/src/from_squeak/Mac OS/plugins/B3DAcceleratorPlugin/sqMacOpenGL.h
	vm/src/from_squeak/Mac OS/plugins/FilePlugin/sqMacUnixFileInterface.c
	vm/src/from_squeak/Mac OS/plugins/HostWindowPlugin/sqMacHostWindow.h
	vm/src/from_squeak/Mac OS/plugins/Mpeg3Plugin/mpeg3Plugin-Info.plist
	vm/src/from_squeak/Mac OS/plugins/Mpeg3Plugin/mpeglibAudioVideo.xcodeproj.zip
	vm/src/from_squeak/Mac OS/plugins/PrintJobPlugin/Info-PrintJobPlugin__Upgraded_.plist
	vm/src/from_squeak/Mac OS/plugins/PrintJobPlugin/sqMacPrinting.c
	vm/src/from_squeak/Mac OS/plugins/QuicktimePlugin/Info.plist
	vm/src/from_squeak/Mac OS/plugins/QuicktimePlugin/SqueakQuicktime.xcodeproj.zip
	vm/src/from_squeak/Mac OS/plugins/SecurityPlugin/sqMacSecurity.c
	vm/src/from_squeak/Mac OS/plugins/ServicesPlugin/SqueakServices.xcodeproj.zip
	vm/src/from_squeak/Mac OS/plugins/SoundPlugin/sqMacSound.c
	vm/src/from_squeak/Mac OS/plugins/SoundPlugin/sqMacUnixInterfaceSound.c
	vm/src/from_squeak/Mac OS/plugins/SpellingPlugin/SqueakSpelling.xcodeproj.zip
	vm/src/from_squeak/Mac OS/plugins/SqueakFFIPrims/Info-SqueakFFIPlugin__Upgraded_.plist
	vm/src/from_squeak/Mac OS/plugins/SqueakFFIPrims/SqueakFFI.xcodeproj.zip
	vm/src/from_squeak/Mac OS/plugins/SqueakFFIPrims/sqMacFFIPPC.c
	vm/src/from_squeak/Mac OS/plugins/SqueakFFIPrims/sqMacIntel-Win32.c
	vm/src/from_squeak/Mac OS/plugins/SqueakFFIPrims/x86-sysv-MacIntel.c
	vm/src/from_squeak/Mac OS/plugins/SqueakFFIPrims/x86-sysv-asm-MacIntel.S
	vm/src/from_squeak/Mac OS/plugins/TestOSAPlugin/TestOSAPlugin.xcodeproj.zip
	vm/src/from_squeak/Mac OS/vm/Developer/Squeak VM Universal-Info.plist
	vm/src/from_squeak/Mac OS/vm/Developer/SqueakVMUNIXPATHS.xcodeproj.zip
	vm/src/from_squeak/Mac OS/vm/Developer/sqGnu.h
	vm/src/from_squeak/Mac OS/vm/Developer/sqMacMinimal.c
	vm/src/from_squeak/Mac OS/vm/Documentation/3.8.x Release Notes.rtf
	vm/src/from_squeak/Mac OS/vm/NSCursorWrappers.m
	vm/src/from_squeak/Mac OS/vm/config.h
	vm/src/from_squeak/Mac OS/vm/sqConfig.h
	vm/src/from_squeak/Mac OS/vm/sqMacImageIO.c
	vm/src/from_squeak/Mac OS/vm/sqMacMain.c
	vm/src/from_squeak/Mac OS/vm/sqMacMemory.c
	vm/src/from_squeak/Mac OS/vm/sqMacNSPluginUILogic2.c
	vm/src/from_squeak/Mac OS/vm/sqMacTime.c
	vm/src/from_squeak/Mac OS/vm/sqMacUIClipBoard.c
	vm/src/from_squeak/Mac OS/vm/sqMacUIEvents.c
	vm/src/from_squeak/Mac OS/vm/sqMacUIEventsUniversal.c
	vm/src/from_squeak/Mac OS/vm/sqMacUIMenuBarUniversal.c
	vm/src/from_squeak/Mac OS/vm/sqMacUnixCommandLineInterface.h
	vm/src/from_squeak/Mac OS/vm/sqMacUnixExternalPrims.c
	vm/src/from_squeak/Mac OS/vm/sqMacWindowUniversal.c
	vm/src/from_squeak/Mac OS/vm/sqPlatformSpecific.h
	vm/src/from_squeak/iOS/plugins/SqueakObjectiveC/squeakProxy.m
	vm/src/from_squeak/iOS/vm/Common/Classes/sqSqueakMainApplication+imageReadWrite.m
	vm/src/from_squeak/iOS/vm/Common/Classes/sqSqueakMainApplication.m
	vm/src/from_squeak/iOS/vm/OSX/SqueakOSXAppDelegate.m
	vm/src/from_squeak/iOS/vm/OSX/sqMacUnixExternalPrims.m
	vm/src/from_squeak/iOS/vm/SqueakPureObjcCogVM.xcodeproj/project.pbxproj
	vm/src/from_squeak/iOS/vm/iPhone/Classes/SqueakNoOGLIPhoneAppDelegate.m
	vm/src/from_squeak/iOS/vm/iPhone/Classes/SqueakUIController.h
	vm/src/from_squeak/iOS/vm/iPhone/Classes/SqueakUIController.m
	vm/src/from_squeak/iOS/vm/iPhone/Classes/SqueakUIView.m
	vm/src/from_squeak/iOS/vm/iPhone/Classes/sqSqueakIPhoneApplication+events.h
	vm/src/from_squeak/iOS/vm/iPhone/Classes/sqSqueakIPhoneApplication+events.m
	vm/src/from_squeak/iOS/vm/iPhone/iPhone.changes
	vm/src/from_squeak/iOS/vm/iPhone/sqPlatformSpecific.h
	vm/src/from_squeak/intplugins/B2DPlugin/B2DPlugin.c
	vm/src/from_squeak/intplugins/BitBltPlugin/BitBltPlugin.c
	vm/src/from_squeak/intplugins/FloatArrayPlugin/FloatArrayPlugin.c
	vm/src/from_squeak/intplugins/LargeIntegers/LargeIntegers.c
	vm/src/from_squeak/intplugins/Matrix2x3Plugin/Matrix2x3Plugin.c
	vm/src/from_squeak/intplugins/MiscPrimitivePlugin/MiscPrimitivePlugin.c
	vm/src/from_squeak/intplugins/SocketPlugin/SocketPlugin.c
	vm/src/from_squeak/intplugins/SoundPlugin/SoundPlugin.c
	vm/src/from_squeak/unix/ChangeLog
	vm/src/from_squeak/unix/Makefile
	vm/src/from_squeak/unix/config/Makefile.in
	vm/src/from_squeak/unix/config/Makefile.install
	vm/src/from_squeak/unix/config/Squeak.spec.in
	vm/src/from_squeak/unix/config/acinclude.m4
	vm/src/from_squeak/unix/config/aclocal.m4
	vm/src/from_squeak/unix/config/config.h.in
	vm/src/from_squeak/unix/config/configure
	vm/src/from_squeak/unix/config/configure.ac
	vm/src/from_squeak/unix/config/make.cfg.in
	vm/src/from_squeak/unix/config/make.ext.in
	vm/src/from_squeak/unix/config/make.prg.in
	vm/src/from_squeak/unix/config/mkconfig.in
	vm/src/from_squeak/unix/config/mkinstalldirs
	vm/src/from_squeak/unix/config/mkmf
	vm/src/from_squeak/unix/doc/COPYING
	vm/src/from_squeak/unix/doc/COPYRIGHT
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/HowToBuildFromSource-img1.png
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/HowToBuildFromSource-node1.html
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/HowToBuildFromSource-node2.html
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/HowToBuildFromSource-node3.html
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/HowToBuildFromSource-node4.html
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/HowToBuildFromSource-node5.html
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/HowToBuildFromSource-node6.html
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/HowToBuildFromSource-node7.html
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/HowToBuildFromSource.html
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.html/index.html
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.pdf
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.ps
	vm/src/from_squeak/unix/doc/HowToBuildFromSource.txt
	vm/src/from_squeak/unix/doc/squeak.1
	vm/src/from_squeak/unix/npsqueak/Makefile
	vm/src/from_squeak/unix/npsqueak/README.npsqueak
	vm/src/from_squeak/unix/npsqueak/npsqueakregister.in
	vm/src/from_squeak/unix/npsqueak/npsqueakrun.in
	vm/src/from_squeak/unix/plugins/AsynchFilePlugin/sqUnixAsynchFile.c
	vm/src/from_squeak/unix/plugins/FileCopyPlugin/sqUnixFileCopyPlugin.c
	vm/src/from_squeak/unix/plugins/FloatMathPlugin/acinclude.m4
	vm/src/from_squeak/unix/plugins/SecurityPlugin/sqUnixSecurity.c
	vm/src/from_squeak/unix/plugins/SocketPlugin/sqUnixSocket.c
	vm/src/from_squeak/unix/plugins/SoundPlugin/sqUnixSound.c
	vm/src/from_squeak/unix/plugins/SoundPlugin/zzz/ring.h
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/00README
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/Makefile
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/Makefile.in
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/any-libffi.c
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/ffi-config
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/ffi-test-main.c
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/ffi-test.c
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/ppc-darwin-asm.S
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/ppc-darwin.c
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/ppc-sysv-asm.S
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/ppc-sysv.c
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/x86-sysv-asm.S
	vm/src/from_squeak/unix/plugins/SqueakFFIPrims/x86-sysv.c
	vm/src/from_squeak/unix/plugins/UUIDPlugin/Makefile.inc
	vm/src/from_squeak/unix/plugins/UUIDPlugin/sqUnixUUID.c
	vm/src/from_squeak/unix/plugins/UnixOSProcessPlugin/acinclude.m4
	vm/src/from_squeak/unix/vm-display-Quartz/Makefile.in
	vm/src/from_squeak/unix/vm-display-Quartz/sqUnixQuartz.m
	vm/src/from_squeak/unix/vm-display-Quartz/zzz/sqUnixQuartz.m
	vm/src/from_squeak/unix/vm-display-X11/Makefile.in
	vm/src/from_squeak/unix/vm-display-X11/acinclude.m4
	vm/src/from_squeak/unix/vm-display-X11/sqUnixX11.c
	vm/src/from_squeak/unix/vm-display-fbdev/Makefile.in
	vm/src/from_squeak/unix/vm-display-fbdev/sqUnixFBDev.c
	vm/src/from_squeak/unix/vm-display-fbdev/sqUnixFBDevFramebuffer.c
	vm/src/from_squeak/unix/vm-display-fbdev/sqUnixFBDevKeyboard.c
	vm/src/from_squeak/unix/vm-display-fbdev/sqUnixFBDevKeymap.c
	vm/src/from_squeak/unix/vm-display-fbdev/sqUnixFBDevMouse.c
	vm/src/from_squeak/unix/vm-display-fbdev/sqUnixFBDevMouseADB.c
	vm/src/from_squeak/unix/vm-display-fbdev/sqUnixFBDevMousePS2.c
	vm/src/from_squeak/unix/vm-sound-ALSA/sqUnixSoundALSA.c
	vm/src/from_squeak/unix/vm-sound-MacOSX/sqUnixSoundDebug.h
	vm/src/from_squeak/unix/vm-sound-MacOSX/sqUnixSoundMacOSX.c
	vm/src/from_squeak/unix/vm-sound-NAS/sqUnixSoundNAS.c
	vm/src/from_squeak/unix/vm-sound-OSS/acinclude.m4
	vm/src/from_squeak/unix/vm-sound-OSS/sqUnixSoundOSS.c
	vm/src/from_squeak/unix/vm-sound-Sun/sqUnixSoundSun.c
	vm/src/from_squeak/unix/vm-sound-custom/sqUnixCustomSound.c
	vm/src/from_squeak/unix/vm-sound-null/sqUnixSoundNull.c
	vm/src/from_squeak/unix/vm/Makefile.in
	vm/src/from_squeak/unix/vm/SqDisplay.h
	vm/src/from_squeak/unix/vm/SqSound.h
	vm/src/from_squeak/unix/vm/sqGnu.h
	vm/src/from_squeak/unix/vm/sqUnixCharConv.c
	vm/src/from_squeak/unix/vm/sqUnixEvent.c
	vm/src/from_squeak/unix/vm/sqUnixExternalPrims.c
	vm/src/from_squeak/unix/vm/sqUnixMain.c
	vm/src/interpreter/external_primitive_table.h
	vm/src/interpreter/squeak_interpreter.cpp
	vm/src/interpreter/squeak_interpreter.h
	vm/src/messages/message_statics.cpp
	vm/src/messages/message_statics.h
	vm/src/messages/message_stats.h
	vm/src/objects/object.cpp
	vm/src/objects/object.h
	vm/src/platform/ilib_os_interface.h
	vm/src/platform/posix_os_interface.h
	vm/src/runtime/debug_helper.cpp
	vm/src/runtime/debug_helper.h
	vm/src/runtime/headers.h
	vm/src/runtime/rvm_config.h
	vm/src/runtime/squeak_adapters.cpp
	vm/src/runtime/squeak_adapters.h
	vm/src/types/types.h

Signed-off-by: Stefan Marr <git@stefan-marr.de>
  • Loading branch information...
commit 8391479fab35bc72c18eee8039e7ca88f87d9550 2 parents c18ed60 + 968d2f7
@smarr authored
Showing with 26,029 additions and 15 deletions.
  1. +25 −1 .gitignore
  2. +3 −0  .gitmodules
  3. +90 −0 INSTALL.rst
  4. +5 −0 README
  5. +179 −0 README.rst
  6. +1 −0  icon.png
  7. +1 −0  image.st/RVM-multicore-support.mvc.st
  8. +2,052 −0 image.st/RVM-multicore-support.pharo.st
  9. +2,275 −0 image.st/RVM-multicore-support.squeak.st
  10. +1 −0  image.st/Sly3.mvc.st
  11. BIN  misc/RoarVM-logo-full.jpg
  12. +187 −0 misc/RoarVM-logo-full.svg
  13. BIN  misc/RoarVM-logo-squared.png
  14. +508 −0 misc/RoarVM-logo-squared.svg
  15. BIN  misc/RoarVM-logo-squared.white-background.png
  16. +1,496 −0 vm/RoarVM.xcodeproj/project.pbxproj
  17. +1 −0  vm/build/configure
  18. +1 −0  vm/googletest
  19. +44 −0 vm/run/reliability-test
  20. +10 −0 vm/run/tile-runner
  21. +12 −0 vm/run/tile-rvm
  22. +10 −0 vm/run/tile-rvm-db
  23. +31 −0 vm/src/compiler_check.cpp
  24. +313 −0 vm/src/from_squeak/Cross/plugins/B3DAcceleratorPlugin/B3DAcceleratorPlugin.h
  25. +1,067 −0 vm/src/from_squeak/Cross/plugins/B3DAcceleratorPlugin/sqOpenGLRenderer.c
  26. +76 −0 vm/src/from_squeak/Cross/plugins/B3DAcceleratorPlugin/sqOpenGLRenderer.h
  27. +62 −0 vm/src/from_squeak/Cross/plugins/BochsIA32Plugin/BochsIA32Plugin.h
  28. +572 −0 vm/src/from_squeak/Cross/plugins/BochsIA32Plugin/sqBochsIA32Plugin.cpp
  29. +27 −0 vm/src/from_squeak/Cross/plugins/CroquetPlugin/CroquetPlugin.h
  30. +1 −0  vm/src/from_squeak/Cross/plugins/CroquetPlugin/CroquetPlugin.st
  31. +112 −0 vm/src/from_squeak/Cross/plugins/CroquetPlugin/md5.h
  32. +195 −0 vm/src/from_squeak/Cross/plugins/CroquetPlugin/tribox.c
  33. +13 −0 vm/src/from_squeak/Cross/plugins/DropPlugin/DropPlugin.h
  34. +8 −0 vm/src/from_squeak/Cross/plugins/ExampleSurfacePlugin/ExampleSurfacePlugin.h
  35. +1 −0  vm/src/from_squeak/Cross/plugins/ExampleSurfacePlugin/SurfacePlugin-Examples.st
  36. +125 −0 vm/src/from_squeak/Cross/plugins/ExampleSurfacePlugin/sqMemorySurface.c
  37. +890 −0 vm/src/from_squeak/Cross/plugins/FilePlugin/FilePlugin.c
  38. +2 −2 vm/src/from_squeak/Cross/plugins/FilePlugin/FilePlugin.h
  39. +9 −12 vm/src/from_squeak/Cross/plugins/FilePlugin/sqFilePluginBasicPrims.c
  40. +262 −0 vm/src/from_squeak/Cross/plugins/FilePlugin/sqUnixFile.c
  41. +34 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/FloatMathPlugin.h
  42. +1 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/FloatMathPlugin.st
  43. +1 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/FloatMathPluginTests.st
  44. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/acos.c
  45. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/acosh.c
  46. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/asin.c
  47. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/asinh.c
  48. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/atan.c
  49. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/atan2.c
  50. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/atanh.c
  51. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/copysign.c
  52. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/cos.c
  53. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/cosh.c
  54. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/exp.c
  55. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/expm1.c
  56. +102 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/MD5
  57. +77 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/changes
  58. +3,309 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/configure
  59. +14 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/configure.in
  60. +105 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_acos.c
  61. +65 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_acosh.c
  62. +114 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_asin.c
  63. +123 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_atan2.c
  64. +68 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_atanh.c
  65. +89 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_cosh.c
  66. +156 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_exp.c
  67. +140 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_fmod.c
  68. +33 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_gamma.c
  69. +32 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_gamma_r.c
  70. +115 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_hypot.c
  71. +478 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_j0.c
  72. +477 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_j1.c
  73. +272 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_jn.c
  74. +33 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_lgamma.c
  75. +304 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_lgamma_r.c
  76. +139 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_log.c
  77. +91 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_log10.c
  78. +309 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_pow.c
  79. +175 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_rem_pio2.c
  80. +77 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_remainder.c
  81. +51 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_scalb.c
  82. +82 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_sinh.c
  83. +450 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/e_sqrt.c
  84. +217 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/fdlibm.h
  85. +168 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/index
  86. +180 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/index.html
  87. +92 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/k_cos.c
  88. +316 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/k_rem_pio2.c
  89. +74 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/k_sin.c
  90. +733 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/k_standard.c
  91. +148 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/k_tan.c
  92. +110 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/makefile
  93. +154 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/makefile.in
  94. +261 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/readme
  95. +61 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_asinh.c
  96. +134 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_atan.c
  97. +87 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_cbrt.c
  98. +78 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_ceil.c
  99. +31 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_copysign.c
  100. +78 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_cos.c
  101. +310 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_erf.c
  102. +215 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_expm1.c
  103. +29 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_fabs.c
  104. +31 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_finite.c
  105. +79 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_floor.c
  106. +56 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_frexp.c
  107. +46 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_ilogb.c
  108. +34 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_isnan.c
  109. +28 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_ldexp.c
  110. +35 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_lib_version.c
  111. +165 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_log1p.c
  112. +38 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_logb.c
  113. +26 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_matherr.c
  114. +80 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_modf.c
  115. +78 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_nextafter.c
  116. +84 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_rint.c
  117. +63 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_scalbn.c
  118. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_signgam.c
  119. +30 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_significand.c
  120. +78 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_sin.c
  121. +72 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_tan.c
  122. +82 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/s_tanh.c
  123. +39 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_acos.c
  124. +39 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_acosh.c
  125. +41 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_asin.c
  126. +40 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_atan2.c
  127. +42 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_atanh.c
  128. +38 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_cosh.c
  129. +48 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_exp.c
  130. +39 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_fmod.c
  131. +46 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_gamma.c
  132. +42 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_gamma_r.c
  133. +39 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_hypot.c
  134. +65 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_j0.c
  135. +66 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_j1.c
  136. +88 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_jn.c
  137. +46 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_lgamma.c
  138. +42 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_lgamma_r.c
  139. +39 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_log.c
  140. +42 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_log10.c
  141. +60 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_pow.c
  142. +38 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_remainder.c
  143. +56 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_scalb.c
  144. +38 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_sinh.c
  145. +38 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fdlibm/w_sqrt.c
  146. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/finite.c
  147. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/fmod.c
  148. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/hypot.c
  149. +14 −0 vm/src/from_squeak/Cross/plugins/FloatMathPlugin/ieee754names.h
  150. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/isnan.c
  151. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/k_cos.c
  152. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/k_rem_pio2.c
  153. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/k_sin.c
  154. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/k_tan.c
  155. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/ldexp.c
  156. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/log.c
  157. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/log10.c
  158. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/log1p.c
  159. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/modf.c
  160. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/pow.c
  161. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/rem_pio2.c
  162. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/rint.c
  163. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/scalb.c
  164. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/scalbn.c
  165. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/sin.c
  166. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/sinh.c
  167. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/sqrt.c
  168. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/tan.c
  169. +2 −0  vm/src/from_squeak/Cross/plugins/FloatMathPlugin/tanh.c
  170. +198 −0 vm/src/from_squeak/Cross/plugins/GStreamerPlugin/squeakAudioVideoPipeLineSignalInterface.c
  171. +51 −0 vm/src/from_squeak/Cross/plugins/GStreamerPlugin/squeakAudioVideoPipeLineSignalInterface.h
  172. +93 −0 vm/src/from_squeak/Cross/plugins/IA32ABI/dabusiness.h
  173. +42 −0 vm/src/from_squeak/Cross/plugins/IA32ABI/ia32abi.h
  174. +266 −0 vm/src/from_squeak/Cross/plugins/IA32ABI/ia32abicc.c
  175. +6 −0 vm/src/from_squeak/Cross/plugins/InternetConfigPlugin/InternetConfigPlugin.h
  176. +11 −0 vm/src/from_squeak/Cross/plugins/JoystickTabletPlugin/JoystickTabletPlugin.h
  177. +545 −0 vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/COPYING
  178. +1 −0  vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/JMMMpegBuffer.1.cs
  179. +1 −0  vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/JMMMpegBufferTest.1.cs
  180. +1 −0  vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/JMMMpegPluginBuffer.1.cs
  181. +1 −0  vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/JMMMpegPluginaddBufferOffsetting.1.cs
  182. +1 −0  vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/JMMMpegaddBufferOffsetting.1.cs
  183. +2 −0  vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/Mpeg3Plugin.h
  184. +40 −0 vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/README
  185. +306 −0 vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/docs/index.html
  186. +128 −0 vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/examplesSqueak.txt
  187. +128 −0 vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/libmpeg/Makefile
  188. +287 −0 vm/src/from_squeak/Cross/plugins/Mpeg3Plugin/libmpeg/audio/ac3.h
Sorry, we could not display the entire diff because too many files (658) changed.
View
26 .gitignore
@@ -1,2 +1,26 @@
+# OS X
.DS_Store
-xcuserdata
+
+# Xcode
+xcuserdata
+vm/RoarVM.xcodeproj/*.pbxuser
+vm/RoarVM.xcodeproj/*.perspectivev3
+*xcworkspace
+
+# Build dir
+vm/build/*.o
+vm/build/*.opt
+vm/build/Makefile
+vm/build/config.last
+vm/build/compiler_check
+vm/build/rvm
+vm/build/Debug/
+vm/build/Release/
+vm/build/RoarVM.build/
+vm/build/libgtest.a
+vm/build/rvm-test
+vm/src/tests/*.o
+
+# Unit tests
+vm/_trial_temp/
+*.pyc
View
3  .gitmodules
@@ -0,0 +1,3 @@
+[submodule "vm/googletest"]
+ path = vm/googletest
+ url = git://github.com/smarr/googletest.git
View
90 INSTALL.rst
@@ -0,0 +1,90 @@
+Installation and Usage Instructions for the RoarVM
+==================================================
+
+This file briefly describes how to compile and use the RoarVM.
+
+Installation
+------------
+
+Requirements:
+
+ - gcc, g++ (also tested with icc v11 on Linux)
+ - Ubuntu: libx11-dev, libxext-dev
+ - Mac OS X: Xcode Developer Tools
+
+Compilation:
+
+In the standard case, calling ./configure ; make in the build directory
+should be sufficient to compile the rvm executable::
+
+ $ cd build
+ $ ./configure
+ $ make
+
+Compilation for Debugging::
+
+ $ cd build
+ $ ./configure --debug
+ $ make
+
+Known Issues:
+
+The standard compiler on modern Linux systems is currently not fully
+supported. Some of its optimizations lead to crashes in the RoarVM. Configure
+supports a workaround which reduces the optimization level for affected files.
+Until the bug in the RoarVM is fixed, please use::
+
+ $ ./configure --opt-workaround
+
+Usage
+-----
+
+The RoarVM executable supports the following command-line interface::
+
+ ./rvm [options] <image-file> [app-params]
+
+ [options] optional command-line parameters as detailed below
+ <image-file> a relative path to a Smalltalk image
+ [app-params] parameters given the application executed by the RoarVM
+
+Command-line Parameters::
+
+ -headless initializes the RoarVM with a dummy display to avoid opening
+ an X11 session, useful for command-line applications or
+ benchmarks
+
+ -num_core N starts the RoarVM with N interpreter instances, each running
+ on a dedicated processor core
+
+ -geom N,M starts the RoarVM with N*M interpreter instances, each
+ running on a dedicated processor core. REMARK: this option is
+ meant for TILE64 processors, where the interpreter instances
+ are distributed on the 2D mesh of cores in an N*M layout
+
+ -min_heap_MB N sets the lower limit for the overall heap size
+
+
+Filing in RoarVM Changes
+''''''''''''''''''''''''
+
+To use your current image on top of the RoarVM, a few changes need to be
+applied to the image.
+
+ 1. Chose the suitable support file from /image.st/
+ 2. Open you image (depending on the image, you need to use the SqueakVM)
+ 3. Open a file list in your image
+ 4. Pick the chosen support file and install it or file it in
+ 5. Acknowledge the change to the Process class by pressing proceed in the
+ warning dialog window
+ 6. Save and quit the image
+ 7. Run RoarVM with a num_core setting > 1
+
+Remark:
+
+ The support for Squeak and Pharo has its limitations. Be aware that those
+ Smalltalks have not been developed with hardware parallelism in mind. It is
+ very likely that you will run into problems that are caused by the
+ assumption that only a single Smalltalk Process is active at a time, and
+ that the scheduler has certain properties like switching between processes
+ only at known places.
+
View
5 README
@@ -0,0 +1,5 @@
+This branch is used to prepare the code for integration into the RoarVM.
+The RoarVM uses a slightly different directory structure and supports only
+a subset of the standard platforms of the SqueakVMs.
+
+See https://github.com/smarr/RoarVM/blob/master/README.rst for details.
View
179 README.rst
@@ -0,0 +1,179 @@
+RoarVM - The Manycore SqueakVM
+==============================
+
+.. image:: https://github.com/smarr/RoarVM/raw/1591bb4e1c282f418231da77cf6d09ec31e2abe8/misc/RoarVM-logo-full.jpg
+ :align: left
+
+RoarVM, formerly known as the Renaissance Virtual Machine (RVM) is developed
+as part of a IBM Research project to investigate programming paradigms and
+languages for manycore systems of the future. Specifically, this VM is meant
+to support manycore systems with more than 1000 cores in the future.
+
+The RVM was open sourced by IBM Research under the `Eclipse Public License`_.
+Please see the `open source announcement`_ for further information.
+
+Today, the RoarVM supports the parallel execution of Smalltalk programs on x86
+compatible multicore systems and Tilera TILE64-based manycore systems. It is
+tested with standard Squeak 4.1 closure-enabled images, and with a stripped
+down version of a MVC-based Squeak 3.9 image.
+
+The RoarVM provides parallel execution of Smalltalk processes and thus, the
+programming model is a typical shared-memory model similar to Java with its
+threads and classical Pthreads for C/C++.
+
+.. _Eclipse Public License: http://www.eclipse.org/legal/epl-v10.html
+.. _open source announcement: http://soft.vub.ac.be/~smarr/rvm-open-source-release/
+
+Install and Use
+---------------
+
+Please see the INSTALL.rst file.
+
+Features
+--------
+
+The RoarVM is compatible with Squeak and its forks. However, the Smalltalk
+images needs a number of changes to enable it to utilize more than one core
+and to interact with the VM correctly.
+
+ - compatible with Squeak 4.1 and Pharo 1.2
+
+ - the RoarVM has full closure support
+
+ - Smalltalk processes are executed in parallel
+
+ - tested with 8 cores, 16 hyperthreads on Intel systems
+
+ - tested with 56 cores on Tilera TILE64/TILEPro64 processors
+
+ - tested with Linux and Mac OS X 10.6
+
+Purpose
+-------
+
+The source code of the RoarVM has been released as open source to enable the
+Smalltalk community to evaluate the ideas and possibly integrate them into
+their existing systems. The RoarVM provides the necessary functionality to
+experiment with Smalltalk systems on multi- and manycore machines, which we
+would like to encourage.
+
+However, we also welcome all contributions to the RoarVM itself. Either to
+bring it up to the speed of the existing VMs or to extend it for further
+experiments.
+
+
+Known Issues
+------------
+
+The RoarVM is a research project and is not as optimized for performance as
+the standard Squeak VM. Thus, its sequential performance is slower. This is
+due to the fact that the RoarVM misses optimizations like using the GCC label
+as value extension to speed up the interpreter.
+
+ - single core performance is slower than the Squeak VM
+
+ * Squeak 4.2.4beta1U, MVC image, OS X
+ 554,844,390 bytecodes/sec; 12,213,718 sends/sec
+
+ * RoarVM, MVC image, OS X, 1 core
+ 66,286,897 bytecodes/sec; 2,910,474 sends/sec
+
+ * RoarVM, MVC image, OS X, 8 cores
+ 470,588,235 bytecodes/sec; 19,825,677 sends/sec
+
+ - idle process does not yield when the RoarVM is run on more than one core
+
+ - the event processing is not adapted fully yet, thus, the idle process
+ is busy-waiting for performance reasons
+
+ - will drain your battery, on mobile devices
+
+ - Garbage collector is as simple as possible
+
+ - it is neither concurrent nor parallel
+
+ - performance can be problematic
+
+ - Graphical subsystem based on X11
+
+ - in contrast to todays Squeak VM, especially the OS X version,
+ the RoarVM uses solely X11 and does not integrate as well into the OS
+ as Squeak does
+
+ - Stability should be ok, however, crashes can happen occasionally
+
+
+Technical Overview
+------------------
+
+The implementation details of the RoarVM are currently documented in:
+
+ [1] Hosting an Object Heap on Manycore Hardware: An Exploration,
+ by David Ungar, and Sam S. Adams, in Proceedings of the 5th Symposium on
+ Dynamic Languages, ACM (2009), p. 99-110.
+ http://portal.acm.org/citation.cfm?id=1640134.1640149
+
+ As well as an VEE submission which is currently under review.
+
+Furthermore, the design is based on the following earlier work:
+
+ [2] Multiprocessor Smalltalk: A Case Study of a Multiprocessor-Based
+ Programming Environment
+ by Joseph Pallas, and David Ungar, in Proceedings of the ACM SIGPLAN
+ 1988 Conference on Programming Language Design and Implementation,
+ ACM (1988), p. 268-277.
+ http://portal.acm.org/citation.cfm?id=54017
+
+The RoarVM resembles the Squeak VM which is written in Smalltalk/Slang,
+however, it is rewritten in C++ to facilitate the development on manycore
+architectures. The C source code of for instance plugins to the Squeak VM has
+been reused directly. This code is located in /src/from squeak/.
+
+The support for x86 compatible multicore systems is currently based on POSIX
+threads. Thus, the RoarVM can be started with a number of threads which are
+executed on distinct processor cores. On Tilera TILE64-based systems, the iLib
+library is used and for each processor core a separate processes is started
+which executes an interpreter instance each. For both architectures, the VM
+provides the illusion of a single object heap, spanning all of the cores, to
+the Smalltalk user. Smalltalk processes are scheduled by a single scheduler on
+the available processor cores, and thus, the processes can execute in
+parallel. For synchronization, the standard Smalltalk mechanisms are
+available. Semaphores as well as mutexes work as in classical systems.
+Currently, the RoarVM uses a single central scheduler which is based on the
+design of Pallas[2]. Its data structures are accessible from the image and
+only require minimal modifications to the image, since the do not change the
+general model of execution.
+
+A distinct feature of the RoarVM is its use of an object table. It was
+introduced to reduce the necessary complexity to enable object migration
+between heaps on manycore architectures.
+
+TODO: add some remarks on the heap structure
+
+License
+-------
+
+Copyright (c) 2008 - 2010 IBM Corporation and others.
+All rights reserved. This RoarVM and the accompanying materials are made
+available under the terms of the Eclipse Public License v1.0 which accompanies
+this distribution, and is available at:
+
+ http://www.eclipse.org/legal/epl-v10.html
+
+All parts directly taken over from the original Squeak source code are
+licensed under their original licenses.
+
+Credits
+-------
+
+Since the RoarVM is based on the work which has been done for Squeak, we would
+like to acknowledge the Squeak community as a whole for its valuable work.
+
+The RoarVM was designed and implemented as 'Renaissance VM' by
+ David Ungar and Sam Adams at IBM Research.
+
+It was ported to x86 compatible multicore systems by
+ Stefan Marr at the Software Languages Lab, Vrije Universiteit Brussel.
+
+Special thanks go to Max OrHai for designing our logo.
+
View
1  icon.png
View
1  image.st/RVM-multicore-support.mvc.st
@@ -0,0 +1 @@
+'******************************************************************************
View
2,052 image.st/RVM-multicore-support.pharo.st
@@ -0,0 +1,2052 @@
+'******************************************************************************
+ * Copyright (c) 2008 - 2010 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * David Ungar, IBM Research - Initial Implementation
+ * Sam Adams, IBM Research - Initial Implementation
+ * Stefan Marr, Vrije Universiteit Brussel - Port to x86 Multi-Core Systems
+ ******************************************************************************'!
+DisplayText subclass: #Paragraph
+ instanceVariableNames: 'clippingRectangle compositionRectangle destinationForm rule mask marginTabsLevel lines lastLine destFormSema'
+ classVariableNames: ''
+ poolDictionaries: 'TextConstants'
+ category: 'ST80-Support'!
+Link subclass: #Process
+ instanceVariableNames: 'suspendedContext priority myList errorHandler name env hostCore coreMask'
+ classVariableNames: 'SemaForSuspensions'
+ poolDictionaries: ''
+ category: 'Kernel-Processes'!
+Object subclass: #RVMPrimitives
+ instanceVariableNames: ''
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'RVM-Support'!
+Object subclass: #ProcessorScheduler
+ instanceVariableNames: 'quiescentProcessLists activeProcess'
+ classVariableNames: 'BackgroundProcess EmergencyProcess HighIOPriority LowIOPriority SystemBackgroundPriority SystemRockBottomPriority TimingPriority UserBackgroundPriority UserInterruptPriority UserSchedulingPriority'
+ poolDictionaries: ''
+ category: 'Kernel-Processes'!
+FileStream subclass: #StandardFileStream
+ instanceVariableNames: 'name fileID buffer1 interlock'
+ classVariableNames: 'Registry'
+ poolDictionaries: ''
+ category: 'Files-Kernel'!
+!ProcessorScheduler methodsFor: 'accessing' stamp: 'dmu 11/25/2008 00:23'!
+activePriority
+ "Answer the priority level of the currently running Process."
+
+ ^self thisProcess priority! !
+!ProcessorScheduler methodsFor: 'accessing' stamp: 'dmu 9/16/2010 14:53'!
+preemptedProcess
+ "Return the process that the currently active process just preempted."
+ | list listWithoutMe |
+ self thisProcess priority to: 1 by: -1 do:[:priority|
+ list := quiescentProcessLists at: priority.
+ "RVM keeps running processes on the lists -- dmu 9/16/10"
+ listWithoutMe := list reject: [:p | p == Processor thisProcess].
+ listWithoutMe isEmpty ifFalse:[^listWithoutMe last].
+ ].
+ ^nil
+
+ "Processor preemptedProcess"! !
+!ProcessorScheduler methodsFor: 'process state change' stamp: 'dmu 11/25/2008 00:23'!
+terminateActive
+ "Terminate the process that is currently running."
+
+ self thisProcess terminate! !
+!ProcessorScheduler methodsFor: 'RVM' stamp: 'dmu 6/14/2010 15:39'!
+areRunningProcessesInSchedulerLists
+ "Our RVM follows Pallas' MS system and keeps runnable processes in the scheduler lists even when running."
+ ^RVMPrimitives isRVM! !
+!ProcessorScheduler methodsFor: 'RVM' stamp: 'dmu 11/25/2008 00:26'!
+isActive: aProcess
+ ^ aProcess suspendedContext == nil! !
+!ProcessorScheduler methodsFor: 'RVM' stamp: 'dmu 6/14/2010 15:32'!
+thisProcess
+ ^ RVMPrimitives thisProcess! !
+!ProcessorScheduler methodsFor: 'RVM' stamp: 'dmu 3/22/2010 13:03'!
+yieldIfFewerCoresThan: n
+ RVMPrimitives coreCount < n ifTrue: [self yield]! !
+!Project class methodsFor: 'utilities' stamp: 'dmu 11/25/2008 00:24'!
+spawnNewProcessAndTerminateOld: terminate
+
+ self spawnNewProcess.
+ terminate
+ ifTrue: [Processor terminateActive]
+ ifFalse: [Processor thisProcess suspend]! !
+!RVMPrimitives class methodsFor: 'debugging VM' stamp: 'dmu 6/8/2010 23:41'!
+breakpoint
+ <primitive: 'primitiveBreakpoint' module: 'RVMPrimitives'>
+ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'debugging VM' stamp: 'dmu 6/9/2010 00:02'!
+printExecutionTrace
+ <primitive: 'primitivePrintExecutionTrace' module: 'RVMPlugin'>! !
+!RVMPrimitives class methodsFor: 'debugging VM' stamp: 'dmu 6/9/2010 00:01'!
+printOnConsole: aString
+ "Prints a string onto the console"
+ <primitive: 'primitivePrint' module: 'RVMPlugin'>! !
+!RVMPrimitives class methodsFor: 'debugging VM' stamp: 'dmu 6/9/2010 00:00'!
+printStack
+ "Prints Smalltalk stack to console"
+ <primitive: 'primitivePrintStack' module: 'RVMPlugin'>! !
+!RVMPrimitives class methodsFor: 'debugging VM' stamp: 'dmu 6/9/2010 00:01'!
+printVMStatistics
+ <primitive: 'primitivePrintStats' module: 'RVMPlugin'>! !
+!RVMPrimitives class methodsFor: 'VM statistics' stamp: 'dmu 6/8/2010 23:04'!
+sampleRVM
+ "Grab some data from the VM and return it"
+ <primitive: 'primitiveSampleRVM' module: 'RVMPlugin'>
+ "RVMPrimitives sampleRVM"
+ ^ nil! !
+!RVMPrimitives class methodsFor: 'VM statistics' stamp: 'sm 10/27/2010 22:09'!
+getMainRank
+ "Get a sample from the VM and read out the main rank"
+ | sample |
+ sample := self sampleRVM.
+ ^ ((sample at: 6) at: 2) at: 6! !
+!RVMPrimitives class methodsFor: 'VM statistics' stamp: 'dmu 6/8/2010 23:40'!
+sampleSpecificData: flags
+ "Grab some data from the VM and return it"
+ "Bit offsets for flags; bit 0 is 1, bit 1 is 2, bit 2 is 4, etc.
+
+ allCores, // 0
+ runMask,
+ messageNames,
+ cpuCoreStats,
+ allCoreStats,
+ fence,
+
+ millisecs, // 6
+ cycles,
+ messageStats,
+ memorySystemStats,
+ interpreterStats,
+ objectTableStats,
+ interactionStats,
+
+ coreCoords, // 14
+ sendTallies,
+ receiveTallies,
+ bufferedMessageStats,
+ receiveCycles,
+
+ // memory system
+ gcStats, // 19
+ heapStats,
+
+ // interpreter
+ bytecodes, // 20
+ yieldCount,
+ cycleCounts,
+ interruptChecks,
+ movedMutatedObjectStats,
+ mutexStats,
+ interpreterLoopStats // 26"
+
+ <primitive: 'primitiveSampleRVM' module: 'RVMPlugin'>
+ ^ nil! !
+!RVMPrimitives class methodsFor: 'rearranging objects' stamp: 'dmu 6/8/2010 23:58'!
+moveAllToReadMostlyHeaps
+ "Move all objects into read-mostly heaps"
+ <primitive: 'primitiveMoveAllToReadMostlyHeaps' module: 'RVMPlugin'>
+ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'rearranging objects' stamp: 'dmu 6/8/2010 23:55'!
+shuffleToHeapsFrom: firstHeap to: lastHeap
+ "Deal out all objects in the system into heaps from firstHeap through lastHeap in round-robin fashion so that adjacent objects wind up in different heaps"
+ <primitive: 'primitiveShuffle' module: 'RVMPlugin'>
+ ^ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'rearranging objects' stamp: 'dmu 6/8/2010 23:56'!
+shuffleToHeapsFrom: firstHeap to: lastHeap movingReadWriteObjectsToReadMostlyHeap: rwToRM movingReadMostlyObjectsToReadWriteHeap: rmToRw
+ "Deal out all objects in the system into heaps from firstHeap through lastHeap in round-robin fashion so that adjacent objects wind up in different heaps"
+ "If rwToRM, move objects in read/write heaps to read-mostly heaps."
+ "If rmToRW, move objects in read-mostly heaps to read/write heaps."
+ <primitive: 'primitiveShuffle' module: 'RVMPlugin'>
+ ^ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'rearranging objects' stamp: 'dmu 6/8/2010 23:57'!
+spreadToHeapsFrom: firstHeap to: lastHeap
+ "Spread out all objects in the system into heaps from firstHeap through lastHeap so that each heap ends up about equally full."
+ <primitive: 'primitiveSpread' module: 'RVMPlugin'>
+ ^ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'rearranging objects' stamp: 'dmu 6/8/2010 23:57'!
+spreadToHeapsFrom: firstHeap to: lastHeap movingReadWriteObjectsToReadMostlyHeap: rwToRM movingReadMostlyObjectsToReadWriteHeap: rmToRw
+ "Spread out all objects in the system into heaps from firstHeap through lastHeap so that each heap ends up about equally full."
+ "If rwToRM, move objects in read/write heaps to read-mostly heaps."
+ "If rmToRW, move objects in read-mostly heaps to read/write heaps."
+ <primitive: 'primitiveSpread' module: 'RVMPlugin'>
+ ^ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'situating an object' stamp: 'dmu 6/8/2010 23:30'!
+for: anObject setRankTo: rank
+ <primitive: 'primitiveSetCoordinatesFor' module: 'RVMPlugin'>
+ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'situating an object' stamp: 'dmu 6/8/2010 23:31'!
+for: anObject setRankTo: rank isReadWrite: isRW
+ <primitive: 'primitiveSetCoordinatesFor' module: 'RVMPlugin'>
+ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'situating an object' stamp: 'dmu 6/8/2010 23:17'!
+getCoreOf: anObject
+ "RVMPrimitives getCoreOf: 2@3"
+ <primitive: 'primitiveGetCore' module: 'RVMPlugin'>
+ ^ -1! !
+!RVMPrimitives class methodsFor: 'situating an object' stamp: 'dmu 6/8/2010 23:47'!
+getMutabilityOf: anObject
+ "Return true if argument is in a read/write heap, false if in read-mostly heap"
+ <primitive: 'primitiveGetMutability' module: 'RVMPlugin'>
+ ^ true! !
+!RVMPrimitives class methodsFor: 'enumerating a heap' stamp: 'dmu 6/8/2010 23:10'!
+allObjectsInHeap: rank isReadWrite: trueForReadWriteFalseForReadMostly
+ "return array of all objects in either read/write or read-mostly heap specified by rank and trueForReadWriteFalseForReadMostly"
+ "RVMPrimitives allObjectsInHeap: 0 isReadWrite: true"
+ <primitive: 'primitiveAllObjectsInHeap' module: 'RVMPlugin'>
+ ^ nil! !
+!RVMPrimitives class methodsFor: 'processes' stamp: 'dmu 6/8/2010 23:18'!
+getCoreIAmRunningOn
+ "RVMPrimitives getCoreIAmRunningOn"
+ <primitive: 'primitiveGetCoreIAmRunningOn' module: 'RVMPlugin' >
+ ^ -1! !
+!RVMPrimitives class methodsFor: 'processes' stamp: 'dmu 6/8/2010 23:44'!
+getRunMask
+ "Return an integer with ones corresponding to cores RVM is allowed to use: 1 means core 0, 3 means cores 0 and 1, etc."
+ "RVMPrimitives getRunMask printStringBase: 16"
+ <primitive: 'primitiveRunMask' module: 'RVMPlugin'>
+ ^ -1! !
+!RVMPrimitives class methodsFor: 'processes' stamp: 'dmu 6/9/2010 00:07'!
+getRunningProcessesByCore
+ "Returns array of running processes, indexed by core (+1)"
+ <primitive: 'primitiveRunningProcessByCore' module: 'RVMPlugin'>
+ ^ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'processes' stamp: 'dmu 6/8/2010 23:46'!
+setRunMask: anInteger
+ "Sets run mask to argument and returns old run mask.
+ Only cores set in run mask will be used to run Smalltalk processes."
+ "RVMPrimitives setRunMask: 1"
+ <primitive: 'primitiveRunMask' module: 'RVMPlugin'>
+ ^ -1! !
+!RVMPrimitives class methodsFor: 'processes' stamp: 'dmu 6/9/2010 00:04'!
+thisProcess
+ "Return the process that is running; RVM does not use ActiveProcess for this state, since many may be running"
+ <primitive: 'primitiveThisProcess' module: 'RVMPlugin'>
+ ^ Processor activeProcess! !
+!RVMPrimitives class methodsFor: 'cores' stamp: 'dmu 6/8/2010 23:11'!
+coreCount
+ "RVMPrimitives coreCount"
+ <primitive: 'primitiveCoreCount' module: 'RVMPlugin'>
+ ^ 1! !
+!RVMPrimitives class methodsFor: 'tracing' stamp: 'dmu 6/8/2010 23:25'!
+getCoreTrace
+ "RVMPrimitives getCoreTrace"
+ <primitive: 'primitiveTraceCores' module: 'RVMPlugin'>
+ ^ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'tracing' stamp: 'dmu 6/8/2010 23:26'!
+getMutatedReplicatedObjectsTrace
+ <primitive: 'primitiveTraceMutatedReplicatedObjects' module: 'RVMPlugin'>
+ ^ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'tracing' stamp: 'dmu 6/8/2010 23:22'!
+startCoreTrace: size
+ "RVMPrimitives startCoreTrace: 1000"
+ <primitive: 'primitiveTraceCores' module: 'RVMPlugin'>
+ ^ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'tracing' stamp: 'dmu 6/8/2010 23:27'!
+startMutatedReplicatedObjectsTrace: size
+ <primitive: 'primitiveTraceMutatedReplicatedObjects' module: 'RVMPlugin'>
+ ^ self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'emergency evaluating' stamp: 'dmu 6/8/2010 23:19'!
+getEmergencySemaphore
+ "When you hit shift-control-a, the VM will signal the emergency semaphore, if it has been set to a semaphore"
+ "RVMPrimitives getEmergencySemaphore"
+ <primitive: 'primitiveEmergencySemaphore' module: 'RVMPlugin'>! !
+!RVMPrimitives class methodsFor: 'emergency evaluating' stamp: 'dmu 6/9/2010 00:06'!
+setEmergencySemaphore: aSema
+ "When you hit shift-control-a, the VM will signal the emergency semaphore, if it has been set to a semaphore"
+ "RVMPrimitives setEmergencySemaphore: Semaphore new"
+ <primitive: 'primitiveEmergencySemaphore' module: 'RVMPlugin'>! !
+!RVMPrimitives class methodsFor: 'using extra word' stamp: 'dmu 6/14/2010 15:27'!
+getExtraPreheaderWordOf: anObject
+ "Returns the extra preheader word of the argument."
+ "RVMPrimitives getExtraPreheaderWordOf: 3@4"
+ <primitive: 'primitiveGetExtraPreheaderWord' module: 'RVMPlugin'>! !
+!RVMPrimitives class methodsFor: 'using extra word' stamp: 'dmu 6/14/2010 15:27'!
+setExtraPreheaderWordOf: anObject to: newContents
+ "Sets the extra preheader word of the first argument."
+ "|n| n := 3@4.
+ RVMPrimitives setExtraPreheaderWordOf: n to: 17.
+ RVMPrimitives getExtraPreheaderWordOf: n"
+ <primitive: 'primitiveSetExtraPreheaderWord' module: 'RVMPlugin'>! !
+!RVMPrimitives class methodsFor: 'using extra word' stamp: 'dmu 6/9/2010 00:05'!
+setExtraWordSelector: aSelector
+ "returns the old one"
+ <primitive: 'primitiveSetExtraWordSelector' module: 'RVMPlugin'>
+ ^self primitiveFailed! !
+!RVMPrimitives class methodsFor: 'testing' stamp: 'dmu 6/14/2010 15:36'!
+isRVM
+ "RVMPrimitives isRVM"
+ ^ (self getCoreOf: nil) ~= -1! !
+!BlockClosure methodsFor: 'evaluating' stamp: 'dmu 6/14/2010 16:13'!
+valueAt: blockPriority
+ "Evaluate the receiver (block), with another priority as the actual one
+ and restore it afterwards. The caller should be careful with using
+ higher priorities."
+ | activeProcess result outsidePriority |
+ activeProcess := Processor thisProcess.
+ outsidePriority := activeProcess priority.
+ activeProcess priority: blockPriority.
+ result := self ensure: [activeProcess priority: outsidePriority].
+ "Yield after restoring lower priority to give the preempted processes a
+ chance to run."
+ blockPriority > outsidePriority
+ ifTrue: [Processor yield].
+ ^ result! !
+!BlockClosure methodsFor: 'evaluating' stamp: 'dmu 6/14/2010 16:13'!
+valueWithin: aDuration onTimeout: timeoutBlock
+ "Evaluate the receiver.
+ If the evaluation does not complete in less than aDuration evaluate the timeoutBlock instead"
+
+ | theProcess delay watchdog |
+
+ aDuration <= Duration zero ifTrue: [^ timeoutBlock value ].
+
+ "the block will be executed in the current process"
+ theProcess := Processor thisProcess.
+ delay := aDuration asDelay.
+
+ "make a watchdog process"
+ watchdog := [
+ delay wait. "wait for timeout or completion"
+ theProcess ifNotNil:[ theProcess signalException: TimedOut ]
+ ] newProcess.
+
+ "Watchdog needs to run at high priority to do its job (but not at timing priority)"
+ watchdog priority: Processor timingPriority-1.
+
+ "catch the timeout signal"
+ ^ [ watchdog resume. "start up the watchdog"
+ self ensure:[ "evaluate the receiver"
+ theProcess := nil. "it has completed, so ..."
+ delay delaySemaphore signal. "arrange for the watchdog to exit"
+ ]] on: TimedOut do: [ :e | timeoutBlock value ].
+! !
+!BlockClosure methodsFor: 'private' stamp: 'dmu 6/14/2010 16:13'!
+valueUnpreemptively
+ "Evaluate the receiver (block), without the possibility of preemption by higher priority processes. Use this facility VERY sparingly!!"
+ "Think about using Block>>valueUninterruptably first, and think about using Semaphore>>critical: before that, and think about redesigning your application even before that!!
+ After you've done all that thinking, go right ahead and use it..."
+ | activeProcess oldPriority result |
+ activeProcess := Processor thisProcess.
+ oldPriority := activeProcess priority.
+ activeProcess priority: Processor highestPriority.
+ result := self ensure: [activeProcess priority: oldPriority].
+ "Yield after restoring priority to give the preempted processes a chance to run"
+ Processor yield.
+ ^result! !
+!BlockContext methodsFor: 'evaluating' stamp: 'dmu 6/14/2010 16:14'!
+valueWithin: aDuration onTimeout: timeoutBlock
+ "Evaluate the receiver.
+ If the evaluation does not complete in less than aDuration evaluate the timeoutBlock instead"
+
+ | theProcess delay watchdog |
+
+ aDuration <= Duration zero ifTrue: [^ timeoutBlock value ].
+
+ "the block will be executed in the current process"
+ theProcess := Processor thisProcess.
+ delay := aDuration asDelay.
+
+ "make a watchdog process"
+ watchdog := [
+ delay wait. "wait for timeout or completion"
+ theProcess ifNotNil:[ theProcess signalException: TimedOut ]
+ ] newProcess.
+
+ "Watchdog needs to run at high priority to do its job (but not at timing priority)"
+ watchdog priority: Processor timingPriority-1.
+
+ "catch the timeout signal"
+ ^ [ watchdog resume. "start up the watchdog"
+ self ensure:[ "evaluate the receiver"
+ theProcess := nil. "it has completed, so ..."
+ delay delaySemaphore signal. "arrange for the watchdog to exit"
+ ]] on: TimedOut do: [ :e | timeoutBlock value ].
+! !
+!BlockContext methodsFor: 'scheduling' stamp: 'dmu 6/14/2010 16:14'!
+valueAt: blockPriority
+ "Evaluate the receiver (block), with another priority as the actual one
+ and restore it afterwards. The caller should be careful with using
+ higher priorities."
+ | activeProcess result outsidePriority |
+ activeProcess := Processor thisProcess.
+ outsidePriority := activeProcess priority.
+ activeProcess priority: blockPriority.
+ result := self
+ ensure: [activeProcess priority: outsidePriority].
+ "Yield after restoring lower priority to give the preempted processes a
+ chance to run."
+ blockPriority > outsidePriority
+ ifTrue: [Processor yield].
+ ^ result! !
+!BlockContext methodsFor: 'private' stamp: 'dmu 11/25/2008 00:18'!
+valueUnpreemptively
+ "Evaluate the receiver (block), without the possibility of preemption by higher priority processes. Use this facility VERY sparingly!!"
+ "Think about using Block>>valueUninterruptably first, and think about using Semaphore>>critical: before that, and think about redesigning your application even before that!!
+ After you've done all that thinking, go right ahead and use it..."
+ | activeProcess oldPriority result |
+ activeProcess := Processor thisProcess.
+ oldPriority := activeProcess priority.
+ activeProcess priority: Processor highestPriority.
+ result := self ensure: [activeProcess priority: oldPriority].
+ "Yield after restoring priority to give the preempted processes a chance to run"
+ Processor yield.
+ ^result! !
+!CPUWatcher methodsFor: 'process operations' stamp: 'dmu 11/25/2008 00:18'!
+debugProcess: aProcess
+ | uiPriority oldPriority |
+ uiPriority := Processor thisProcess priority.
+ aProcess priority >= uiPriority ifTrue: [
+ oldPriority := ProcessBrowser setProcess: aProcess toPriority: uiPriority - 1
+ ].
+ ProcessBrowser debugProcess: aProcess.! !
+!Cursor methodsFor: 'displaying' stamp: 'dmu 6/14/2010 16:15'!
+showWhile: aBlock
+ "While evaluating the argument, aBlock, make the receiver be the cursor shape."
+ "ar 2/2/2006: Only allow this if active process is ui process"
+ | oldcursor |
+ Processor thisProcess == Project uiProcess ifFalse:[^aBlock value].
+ oldcursor := Sensor currentCursor.
+ self show.
+ ^aBlock ensure: [oldcursor show]
+! !
+!Debugger class methodsFor: 'class initialization' stamp: 'dmu 6/14/2010 16:15'!
+openContext: aContext label: aString contents: contentsStringOrNil
+
+ "Open a notifier in response to an error, halt, or notify. A notifier view just shows a short view of the sender stack and provides a menu that lets the user open a full debugger."
+ <primitive: 19> "Simulation guard"
+ ErrorRecursion not & self logDebuggerStackToFile ifTrue:
+ [Smalltalk logError: aString inContext: aContext to: 'PharoDebug.log'].
+ ErrorRecursion ifTrue:[
+ ErrorRecursion := false.
+ self primitiveError: aString].
+ ErrorRecursion := true.
+ self informExistingDebugger: aContext label: aString.
+ (Debugger context: aContext)
+ openNotifierContents: contentsStringOrNil
+ label: aString.
+ ErrorRecursion := false.
+ Processor thisProcess suspend.
+! !
+!Debugger class methodsFor: 'instance creation' stamp: 'dmu 6/14/2010 16:15'!
+context: aContext
+ "Answer an instance of me for debugging the active process starting with the given context."
+
+ ^ self new
+ process: Processor thisProcess
+ controller: nil
+ context: aContext! !
+!DelayWaitTimeout methodsFor: 'private' stamp: 'dmu 6/14/2010 16:15'!
+setDelay: anInteger forSemaphore: aSemaphore
+ super setDelay: anInteger forSemaphore: aSemaphore.
+ process := Processor thisProcess.
+ expired := false.! !
+!HTTPLoader methodsFor: 'private' stamp: 'dmu 6/14/2010 16:15'!
+startDownload
+ | newDownloadProcess |
+
+ downloads size >= self maxNrOfConnections ifTrue: [^self].
+ requests size <= 0 ifTrue: [^self].
+
+ newDownloadProcess := [
+ [
+ self nextRequest startRetrieval
+ ] on: FTPConnectionException do: [ :ex |
+ Cursor normal show.
+ self removeProcess: Processor thisProcess.
+ self startDownload
+ ].
+ self removeProcess: Processor thisProcess.
+ self startDownload
+ ] newProcess.
+ downloads add: newDownloadProcess.
+ newDownloadProcess resume! !
+!MessageTally methodsFor: 'initialize-release' stamp: 'dmu 6/14/2010 16:16'!
+spyEvery: millisecs on: aBlock
+ "Create a spy and spy on the given block at the specified rate."
+ "Spy only on the active process (in which aBlock is run)"
+
+ | myDelay time0 observedProcess |
+ aBlock isBlock
+ ifFalse: [ self error: 'spy needs a block here' ].
+ self class: aBlock receiver class method: aBlock method.
+ "set up the probe"
+ observedProcess := Processor thisProcess.
+ myDelay := Delay forMilliseconds: millisecs.
+ time0 := Time millisecondClockValue.
+ gcStats := Smalltalk getVMParameters.
+ Timer ifNotNil: [ self error: 'it seems a tally is already running' ].
+ Timer := [
+ [ true ] whileTrue: [
+ | startTime |
+ startTime := Time millisecondClockValue.
+ myDelay wait.
+ self
+ tally: Processor preemptedProcess suspendedContext
+ in: (observedProcess == Processor preemptedProcess ifTrue: [observedProcess] ifFalse: [nil])
+ "tally can be > 1 if ran a long primitive"
+ by: (Time millisecondClockValue - startTime) // millisecs].
+ nil] newProcess.
+ Timer priority: Processor timingPriority-1.
+ "activate the probe and evaluate the block"
+ Timer resume.
+ ^ aBlock ensure: [
+ "cancel the probe and return the value"
+ "Could have already been terminated. See #terminateTimerProcess"
+ Timer ifNotNil: [
+ Timer terminate.
+ Timer := nil ].
+ "Collect gc statistics"
+ Smalltalk getVMParameters keysAndValuesDo: [ :idx :gcVal |
+ gcVal ifNotNil: [ gcStats at: idx put: (gcVal - (gcStats at: idx))]].
+ time := Time millisecondClockValue - time0]! !
+!Monitor methodsFor: 'private' stamp: 'dmu 6/14/2010 16:16'!
+enter
+ self isOwnerProcess ifTrue: [
+ nestingLevel := nestingLevel + 1.
+ ] ifFalse: [
+ mutex wait.
+ ownerProcess := Processor thisProcess.
+ nestingLevel := 1.
+ ].! !
+!Monitor methodsFor: 'private' stamp: 'dmu 6/14/2010 16:16'!
+isOwnerProcess
+ ^ Processor thisProcess == ownerProcess! !
+!Paragraph methodsFor: 'RVM' stamp: 'dmu 6/15/2010 11:36'!
+destFormSema: s
+ destFormSema := s! !
+!Paragraph methodsFor: 'private' stamp: 'dmu 4/1/2009 19:38'!
+compositionRectangle: compositionRect text: aText style: aTextStyle offset: aPoint
+
+ compositionRectangle := compositionRect copy.
+ text := aText.
+ textStyle := aTextStyle.
+ rule := DefaultRule.
+ mask := nil. "was DefaultMask "
+ marginTabsLevel := 0.
+ destFormSema := Semaphore forMutualExclusion.
+ destinationForm := Display.
+ offset := aPoint.
+ ^self composeAll! !
+!Paragraph methodsFor: 'private' stamp: 'ssa 4/7/2009 12:39'!
+displayOn: aDisplayMedium lines: lineInterval
+
+ | saveDestinationForm |
+ destFormSema isNil ifTrue:[self destFormSema: Semaphore forMutualExclusion].
+ destFormSema critical: [
+ saveDestinationForm := destinationForm.
+ self destinationForm: aDisplayMedium.
+ self displayLines: lineInterval.
+ destinationForm := saveDestinationForm
+ ]! !
+!Process methodsFor: 'accessing' stamp: 'ssa 2/17/2009 22:34'!
+isActiveProcess
+
+ ^ Processor areRunningProcessesInSchedulerLists
+ ifTrue: [ suspendedContext isNil and:[myList notNil]]
+ ifFalse: [self == Processor activeProcess]! !
+!Process methodsFor: 'accessing' stamp: 'dmu 6/18/2010 17:35'!
+isTerminated
+
+ self isActiveProcess ifTrue: [^ false].
+ ^suspendedContext isNil
+ or: ["If the suspendedContext is the bottomContext it is the block in Process>>newProcess.
+ If so, and the pc is greater than the startpc, the bock has alrteady sent and returned
+ from value and there is nothing more to do."
+ suspendedContext isBottomContext
+ and: [suspendedContext pc isNil or: [suspendedContext pc > suspendedContext startpc]]]! !
+!Process methodsFor: 'changing process state' stamp: 'dmu 6/14/2010 16:16'!
+run
+ "Suspend current process and execute self instead"
+
+ | proc |
+ proc := Processor thisProcess.
+ [ proc suspend.
+ self resume.
+ ] forkAt: Processor highestPriority! !
+!Process methodsFor: 'changing process state' stamp: 'dmu 6/18/2010 00:18'!
+suspend
+ "Primitive. Stop the process that the receiver represents in such a way
+ that it can be restarted at a later time (by sending the receiver the
+ message resume). If the receiver represents the activeProcess, suspend it.
+ Otherwise remove the receiver from the list of waiting processes.
+ The return value of this method is the list the receiver was previously on (if any)."
+ | oldList |
+ <primitive: 88>
+ "This is fallback code for VMs which only support the old primitiveSuspend which
+ would not accept processes that are waiting to be run."
+ RVMPrimitives isRVM ifTrue: [self error: 'suspend should never fail'].
+ myList ifNil:[^nil]. "this allows us to use suspend multiple times"
+ oldList := myList.
+ myList := nil.
+ oldList remove: self ifAbsent:[].
+ ^oldList! !
+!Process methodsFor: 'changing process state' stamp: 'dmu 6/17/2010 23:57'!
+terminate
+ "Stop the process that the receiver represents forever. Unwind to execute pending ensure:/ifCurtailed: blocks before terminating."
+
+ | ctxt unwindBlock oldList |
+ self == Processor thisProcess
+ ifTrue: [
+ ctxt := thisContext.
+ [ ctxt := ctxt findNextUnwindContextUpTo: nil.
+ ctxt isNil ] whileFalse:
+ [ (ctxt tempAt: 2) ifNil:
+ [ ctxt tempAt: 2 put: nil.
+ unwindBlock := ctxt tempAt: 1.
+ thisContext terminateTo: ctxt.
+ unwindBlock value ]].
+ thisContext terminateTo: nil.
+ self suspend ]
+ ifFalse: [
+ "Always suspend the process first so it doesn't accidentally get woken up"
+ oldList := self suspend.
+ suspendedContext ifNotNil:[
+ "Figure out if we are terminating the process while waiting in Semaphore>>critical:
+ In this case, pop the suspendedContext so that we leave the ensure: block inside
+ Semaphore>>critical: without signaling the semaphore."
+ (oldList class == Semaphore and:[
+ suspendedContext method == (Semaphore compiledMethodAt: #critical:)]) ifTrue:[
+ suspendedContext := suspendedContext home.].
+
+ "If we are terminating a process halfways through an unwind, try to complete that unwind block first."
+ (suspendedContext findNextUnwindContextUpTo: nil) ifNotNil: [ :outer |
+ (suspendedContext findContextSuchThat: [ :c | c closure == (outer tempAt: 1)])
+ ifNotNil: [ :inner |
+ "This is an unwind block currently under evaluation"
+ suspendedContext runUntilErrorOrReturnFrom: inner ]].
+
+ ctxt := self popTo: suspendedContext bottomContext.
+ ctxt == suspendedContext bottomContext ifFalse: [
+ self debug: ctxt title: 'Unwind error during termination']] ].
+! !
+!Process methodsFor: 'changing suspended state' stamp: 'dmu 12/2/2008 14:05'!
+activateReturn: aContext value: value
+ "Activate 'aContext return: value', so execution will return to aContext's sender"
+ self suspend.
+ ^ suspendedContext := suspendedContext activateReturn: aContext value: value! !
+!Process methodsFor: 'changing suspended state' stamp: 'dmu 12/2/2008 14:01'!
+complete: aContext
+ "Run self until aContext is popped or an unhandled error is raised. Return self's new top context, unless an unhandled error was raised then return the signaler context (rather than open a debugger)."
+
+ | ctxt pair error |
+ self suspend.
+ ctxt := suspendedContext.
+ suspendedContext := nil. "disable this process while running its stack in active process below"
+ pair := ctxt runUntilErrorOrReturnFrom: aContext.
+ suspendedContext := pair first.
+ error := pair second.
+ error ifNotNil: [^ error signalerContext].
+ ^ suspendedContext! !
+!Process methodsFor: 'changing suspended state' stamp: 'dmu 6/14/2010 16:06'!
+install: aContext
+ "Replace the suspendedContext with aContext."
+
+ (Processor isActive: self)
+ ifTrue: [^self error: 'An active process cannot install contexts'].
+ suspendedContext := aContext! !
+!Process methodsFor: 'changing suspended state' stamp: 'dmu 6/14/2010 16:07'!
+popTo: aContext
+ "Pop self down to aContext by remote returning from aContext's callee. Unwind blocks will be executed on the way.
+ This is done by pushing a new context on top which executes 'aContext callee return' then resuming self until aContext is reached. This way any errors raised in an unwind block will get handled by senders in self and not by senders in the activeProcess.
+ If an unwind block raises an error that is not handled then the popping stops at the error and the signalling context is returned, othewise aContext is returned."
+
+ | callee |
+ (Processor isActive: self)
+ ifTrue: [^ self error: 'An active process cannot pop contexts'].
+ callee := (self calleeOf: aContext) ifNil: [^ aContext]. "aContext is on top"
+ ^ self return: callee value: callee receiver! !
+!Process methodsFor: 'changing suspended state' stamp: 'dmu 6/14/2010 16:08'!
+popTo: aContext value: aValue
+ "Replace the suspendedContext with aContext, releasing all contexts
+ between the currently suspendedContext and it."
+
+ | callee |
+ (Processor isActive: self)
+ ifTrue: [^ self error: 'An active process cannot pop contexts'].
+ callee := (self calleeOf: aContext) ifNil: [^ self]. "aContext is on top"
+ self return: callee value: aValue! !
+!Process class methodsFor: 'accessing' stamp: 'ssa 3/25/2010 15:11'!
+semaForSuspensions
+
+ SemaForSuspensions isNil ifTrue:[SemaForSuspensions := Semaphore forMutualExclusion].
+ ^SemaForSuspensions! !
+!Process methodsFor: 'debugging' stamp: 'dmu 6/14/2010 16:09'!
+debug: context title: title full: bool
+ "Open debugger on self with context shown on top"
+
+ | topCtxt |
+ topCtxt := self == Processor thisProcess ifTrue: [thisContext]
+ ifFalse: [
+ self suspend.
+ self suspendedContextWaitingIfNecessary].
+ (topCtxt hasContext: context) ifFalse: [^ self error: 'context not in process'].
+ UIManager default onDebug: self context: context title: title full: bool
+! !
+!Process methodsFor: 'debugging' stamp: 'dmu 9/17/2010 12:03'!
+debugWithTitle: title
+ "Open debugger on self"
+
+ | context |
+ context := self == Processor thisProcess ifTrue: [thisContext] ifFalse: [ self suspend. self suspendedContextWaitingIfNecessary].
+ self debug: context title: title full: true.
+! !
+!Process methodsFor: 'signaling' stamp: 'ssa 2/17/2009 22:31'!
+pvtSignal: anException list: aList
+ "Private. This method is used to signal an exception from another
+ process...the receiver must be the active process. If the receiver
+ was previously waiting on a Semaphore, then return the process
+ to the waiting state after signaling the exception and if the Semaphore
+ has not been signaled in the interim"
+
+ "Since this method is not called in a normal way, we need to take care
+ that it doesn't directly return to the caller (because I believe that could
+ have the potential to push an unwanted object on the caller's stack)."
+
+ | blocker |
+ self == Processor thisProcess ifFalse: [^self].
+ self suspend.
+ anException signal.
+ blocker := Semaphore new.
+ [self suspend.
+ suspendedContext := suspendedContext swapSender: nil.
+ aList class == Semaphore
+ ifTrue:
+ [aList isSignaled
+ ifTrue:
+ [aList wait. "Consume the signal that would have restarted the receiver"
+ self resume]
+ ifFalse:
+ ["Add us back to the Semaphore's list (and remain blocked)"
+ myList := aList.
+ aList add: self]]
+ ifFalse: [self resume]] fork.
+ blocker wait.
+
+
+! !
+!Process methodsFor: 'signaling' stamp: 'dmu 6/14/2010 16:11'!
+signalException: anException
+ "Signal an exception in the receiver process...if the receiver is currently
+ suspended, the exception will get signaled when the receiver is resumed. If
+ the receiver is blocked on a Semaphore, it will be immediately re-awakened
+ and the exception will be signaled; if the exception is resumed, then the receiver
+ will return to a blocked state unless the blocking Semaphore has excess signals"
+ | oldList |
+ "If we are the active process, go ahead and signal the exception"
+ self == Processor thisProcess ifTrue: [^anException signal].
+
+ "Suspend myself first to ensure that I won't run away in the
+ midst of the following modifications."
+ myList ifNotNil:[oldList := self suspend].
+
+ "Add a new method context to the stack that will signal the exception"
+ suspendedContext := MethodContext
+ sender: suspendedContext
+ receiver: self
+ method: (self class lookupSelector: #pvtSignal:list:)
+ arguments: (Array with: anException with: oldList).
+
+ "If we are on a list to run, then suspend and restart the receiver
+ (this lets the receiver run if it is currently blocked on a semaphore). If
+ we are not on a list to be run (i.e. this process is suspended), then when the
+ process is resumed, it will signal the exception"
+
+ oldList ifNotNil: [self resume].
+! !
+!Process methodsFor: 'RVM' stamp: 'dmu 6/14/2010 15:40'!
+coreMask
+ ^ coreMask! !
+!Process methodsFor: 'RVM' stamp: 'dmu 6/14/2010 15:40'!
+coreMask: m
+ coreMask := m! !
+!Process methodsFor: 'RVM' stamp: 'dmu 6/14/2010 15:41'!
+hostCore
+ ^ hostCore! !
+!Process methodsFor: 'RVM' stamp: 'dmu 6/14/2010 15:31'!
+isRunning
+ Processor thisProcess == self ifTrue: [^ true].
+ self isActiveProcess ifTrue: [^ true].
+ myList ifNil: [^ false].
+ ^ myList class ~~ Semaphore! !
+!Process methodsFor: 'RVM' stamp: 'ssa 3/2/2010 18:23'!
+nilMyListUnlessRVM
+ Processor areRunningProcessesInSchedulerLists ifFalse: [
+ "primitiveSuspend will use myList to remove from list and will nil it out"
+ myList := nil.
+ ]! !
+!ProcessBrowser methodsFor: 'stack list' stamp: 'dmu 6/14/2010 16:17'!
+updateStackList: depth
+ | suspendedContext oldHighlight |
+ selectedProcess
+ ifNil: [^ self changeStackListTo: nil].
+ (stackList notNil and: [ stackListIndex > 0 ])
+ ifTrue: [oldHighlight := stackList at: stackListIndex].
+ selectedProcess == Processor thisProcess
+ ifTrue: [self
+ changeStackListTo: (thisContext stackOfSize: depth)]
+ ifFalse: [suspendedContext := selectedProcess suspendedContext.
+ suspendedContext
+ ifNil: [self changeStackListTo: nil]
+ ifNotNil: [self
+ changeStackListTo: (suspendedContext stackOfSize: depth)]].
+ self
+ stackListIndex: (stackList
+ ifNil: [0]
+ ifNotNil: [stackList indexOf: oldHighlight])! !
+!ProcessBrowser class methodsFor: 'class initialization' stamp: 'dmu 6/14/2010 16:17'!
+registerWellKnownProcesses
+ "Associate each well-known process with a nickname and two flags: allow-stop, and allow-debug.
+ Additional processes may be added to this list as required"
+
+ WellKnownProcesses := OrderedCollection new.
+ self registerWellKnownProcess: []
+ label: 'no process'
+ allowStop: false
+ allowDebug: false.
+ self registerWellKnownProcess: [Smalltalk lowSpaceWatcherProcess]
+ label: 'the low space watcher'
+ allowStop: false
+ allowDebug: false.
+ self registerWellKnownProcess: [WeakArray runningFinalizationProcess]
+ label: 'the WeakArray finalization process'
+ allowStop: false
+ allowDebug: false.
+ self registerWellKnownProcess: [Processor thisProcess]
+ label: 'the UI process'
+ allowStop: false
+ allowDebug: true.
+ self registerWellKnownProcess: [Processor backgroundProcess]
+ label: 'the idle process'
+ allowStop: false
+ allowDebug: false.
+ self registerWellKnownProcess: [Sensor interruptWatcherProcess]
+ label: 'the user interrupt watcher'
+ allowStop: false
+ allowDebug: false.
+ self registerWellKnownProcess: [Sensor eventTicklerProcess]
+ label: 'the event tickler'
+ allowStop: false
+ allowDebug: false.
+ self registerWellKnownProcess: [Project uiProcess]
+ label: 'the inactive Morphic UI process'
+ allowStop: false
+ allowDebug: false.
+ self
+ registerWellKnownProcess: [ Smalltalk globals at: #SoundPlayer ifPresent: [ :sp | sp playerProcess ] ]
+ label: 'the Sound Player'
+ allowStop: false
+ allowDebug: false.
+ self
+ registerWellKnownProcess: [ Smalltalk globals at: #CPUWatcher ifPresent: [ :cw | cw currentWatcherProcess ] ]
+ label: 'the CPUWatcher'
+ allowStop: false
+ allowDebug: false
+! !
+!StandardToolSet class methodsFor: 'debugging' stamp: 'dmu 6/14/2010 16:17'!
+debugError: anError
+ "Handle an otherwise unhandled error"
+ ^Processor thisProcess
+ debug: anError signalerContext
+ title: anError description! !
+!TestCase methodsFor: 'extensions' stamp: 'dmu 6/14/2010 16:18'!
+should: aBlock notTakeMoreThan: aDuration
+ "Evaluate aBlock in a forked process and if it takes more than anInteger milliseconds
+ to run we terminate the process and report a test failure. It'' important to
+ use the active process for the test failure so that the failure reporting works correctly
+ in the context of the exception handlers."
+
+ | succeeded evaluationProcess result delay testProcess |
+
+ succeeded := false.
+ delay := Delay forDuration: aDuration.
+ testProcess := Processor thisProcess.
+ "Create a new process to evaluate aBlock"
+ evaluationProcess := [
+ [result := aBlock value.
+ succeeded := true.] on: Exception do: [succeeded := false] .
+ delay unschedule.
+ testProcess resume ] newProcess name: 'Process to evaluate should: notTakeMoreThanMilliseconds:'.
+ evaluationProcess resume.
+ "Wait the milliseconds they asked me to"
+ delay wait.
+ "After this point either aBlock was evaluated if succeeded is not still nil"
+ succeeded ifNil: [
+ evaluationProcess terminate.
+ self assert: false description: ('Block evaluation took more than the expected <1p>' expandMacrosWith: aDuration)].
+ "If tests in block failed, rerun block in this context, so it's handled correctly"
+ succeeded ifFalse: [^aBlock value].
+
+ ^result! !
+!SemaphoreTest methodsFor: 'private' stamp: 'dmu 6/14/2010 16:17'!
+criticalError
+ Processor thisProcess terminate! !
+!TestFailure methodsFor: 'camp smalltalk' stamp: 'dmu 6/14/2010 16:18'!
+defaultAction
+
+ Processor thisProcess
+ debug: self signalerContext
+ title: self description! !
+!Utilities class methodsFor: 'fetching updates' stamp: 'dmu 6/14/2010 16:19'!
+retrieveUrls: urls ontoQueue: queue withWaitSema: waitSema
+ "download the given list of URLs. The queue will be loaded alternately
+ with url's and with the retrieved contents. If a download fails, the
+ contents will be #failed. If all goes well, a special pair with an empty
+ URL and the contents #finished will be put on the queue. waitSema is
+ waited on every time before a new document is downloaded; this keeps
+ the downloader from getting too far ahead of the main process"
+ "kill the existing downloader if there is one"
+ | updateCounter |
+ UpdateDownloader
+ ifNotNil: [UpdateDownloader terminate].
+ updateCounter := 0.
+ "fork a new downloading process"
+ UpdateDownloader := [
+ 'Downloading updates' displayProgressAt: Sensor cursorPoint from: 0 to: urls size during: [:bar |
+ urls
+ do: [:url | | front canPeek doc |
+ waitSema wait.
+ queue nextPut: url.
+ doc := HTTPClient httpGet: url.
+ doc isString
+ ifTrue: [queue nextPut: #failed.
+ UpdateDownloader := nil.
+ Processor thisProcess terminate]
+ ifFalse: [canPeek := 120 min: doc size.
+ front := doc next: canPeek. doc skip: -1 * canPeek.
+ (front beginsWith: '<!!DOCTYPE') ifTrue: [
+ (front includesSubString: 'Not Found') ifTrue: [
+ queue nextPut: #failed.
+ UpdateDownloader := nil.
+ Processor thisProcess terminate]]].
+ UpdateDownloader ifNotNil: [queue nextPut: doc. updateCounter := updateCounter + 1. bar value: updateCounter]]].
+ queue nextPut: ''.
+ queue nextPut: #finished.
+ UpdateDownloader := nil] newProcess.
+ UpdateDownloader priority: Processor userInterruptPriority.
+ "start the process running"
+ UpdateDownloader resume! !
+!Paragraph reorganize!
+('accessing' backgroundColor clippingRectangle clippingRectangle: compositionRectangle compositionRectangle: destinationForm fillColor fillColor: height indentationOfLineIndex:ifBlank: mask numberOfLines replaceFrom:to:with:displaying: rule rule: stringAtLineNumber: text:)
+('alignment' centered justified leftFlush rightFlush toggleAlignment)
+('character location' characterBlockAtPoint: characterBlockForIndex: defaultCharacterBlock)
+('composition' composeAll wrappingBox:clippingBox:)
+('converting' asForm asString asText)
+('display box access' boundingBox computeBoundingBox)
+('displaying' displayOn: displayOn:at: displayOn:at:clippingBox:rule:fillColor: displayOn:transformation:clippingBox:align:with:rule:fillColor:)
+('indicating' flash outline)
+('scrolling' scrollBy: scrollBy:withSelectionFrom:to: scrollDelta scrollUncheckedBy:withSelectionFrom:to:)
+('selecting' caretFormForDepth: clickAt:for:controller: extendSelectionAt:endBlock: extendSelectionMark:pointBlock: hiliteRect: mouseMovedFrom:pivotBlock:showingCaret: mouseSelect mouseSelect: reverseFrom:to: selectionRectsFrom:to:)
+('utilities' clearVisibleRectangle deepCopy destinationForm: fit lines: visibleRectangle)
+('RVM' destFormSema:)
+('private' bottomAtLineIndex: compositionRectangle:text:style:offset: compositionRectangleDelta displayLines: displayLines:affectedRectangle: displayOn:lines: leftMarginForCompositionForLine: leftMarginForDisplayForLine:alignment: lineAt:put: lineIndexOfCharacterIndex: lineIndexOfTop: lines moveBy: rightMarginForComposition rightMarginForDisplay setWithText:style: setWithText:style:compositionRectangle:clippingRectangle: setWithText:style:compositionRectangle:clippingRectangle:foreColor:backColor: topAtLineIndex: topAtLineIndex:using:and: trimLinesTo: updateCompositionHeight withClippingRectangle:do:)
+!
+
+!BitBlt methodsFor: 'accessing' stamp: 'dmu 4/4/2009 00:24'!
+copyBitsOnMain
+ "Primitive. Perform the movement of bits from the source form to the
+ destination form. Fail if any variables are not of the right type (Integer,
+ Float, or Form) or if the combination rule is not implemented.
+ In addition to the original 16 combination rules, this BitBlt supports
+ 16 fail (to simulate paint)
+ 17 fail (to simulate mask)
+ 18 sourceWord + destinationWord
+ 19 sourceWord - destinationWord
+ 20 rgbAdd: sourceWord with: destinationWord
+ 21 rgbSub: sourceWord with: destinationWord
+ 22 rgbDiff: sourceWord with: destinationWord
+ 23 tallyIntoMap: destinationWord
+ 24 alphaBlend: sourceWord with: destinationWord
+ 25 pixPaint: sourceWord with: destinationWord
+ 26 pixMask: sourceWord with: destinationWord
+ 27 rgbMax: sourceWord with: destinationWord
+ 28 rgbMin: sourceWord with: destinationWord
+ 29 rgbMin: sourceWord bitInvert32 with: destinationWord
+"
+ <primitive: 'primitiveCopyBits' module: 'BitBltPlugin'>
+
+ "Check for compressed source, destination or halftone forms"
+ (combinationRule >= 30 and: [combinationRule <= 31]) ifTrue:
+ ["No alpha specified -- re-run with alpha = 1.0"
+ ^ self copyBitsTranslucent: 255].
+ ((sourceForm isForm) and: [sourceForm unhibernate])
+ ifTrue: [^ self copyBits].
+ ((destForm isForm) and: [destForm unhibernate])
+ ifTrue: [^ self copyBits].
+ ((halftoneForm isForm) and: [halftoneForm unhibernate])
+ ifTrue: [^ self copyBits].
+
+ "Check for unimplmented rules"
+ combinationRule = Form oldPaint ifTrue: [^ self paintBits].
+ combinationRule = Form oldErase1bitShape ifTrue: [^ self eraseBits].
+
+ "Check if BitBlt doesn't support full color maps"
+ (colorMap notNil and:[colorMap isColormap]) ifTrue:[
+ colorMap := colorMap colors.
+ ^self copyBits].
+ "Check if clipping gots us way out of range"
+ self clipRange ifTrue:[^self copyBits].
+
+ self error: 'Bad BitBlt arg (Fraction?); proceed to convert.'.
+ "Convert all numeric parameters to integers and try again."
+ destX := destX asInteger.
+ destY := destY asInteger.
+ width := width asInteger.
+ height := height asInteger.
+ sourceX := sourceX asInteger.
+ sourceY := sourceY asInteger.
+ clipX := clipX asInteger.
+ clipY := clipY asInteger.
+ clipWidth := clipWidth asInteger.
+ clipHeight := clipHeight asInteger.
+ ^ self copyBitsAgain! !
+!BitBlt methodsFor: 'copying' stamp: 'dmu 4/4/2009 00:20'!
+copyBitsLocally
+ "Primitive. Perform the movement of bits from the source form to the
+ destination form. Fail if any variables are not of the right type (Integer,
+ Float, or Form) or if the combination rule is not implemented.
+ In addition to the original 16 combination rules, this BitBlt supports
+ 16 fail (to simulate paint)
+ 17 fail (to simulate mask)
+ 18 sourceWord + destinationWord
+ 19 sourceWord - destinationWord
+ 20 rgbAdd: sourceWord with: destinationWord
+ 21 rgbSub: sourceWord with: destinationWord
+ 22 rgbDiff: sourceWord with: destinationWord
+ 23 tallyIntoMap: destinationWord
+ 24 alphaBlend: sourceWord with: destinationWord
+ 25 pixPaint: sourceWord with: destinationWord
+ 26 pixMask: sourceWord with: destinationWord
+ 27 rgbMax: sourceWord with: destinationWord
+ 28 rgbMin: sourceWord with: destinationWord
+ 29 rgbMin: sourceWord bitInvert32 with: destinationWord
+"
+ <primitive: 'primitiveCopyBitsLocally'>
+
+ "Check for compressed source, destination or halftone forms"
+ (combinationRule >= 30 and: [combinationRule <= 31]) ifTrue:
+ ["No alpha specified -- re-run with alpha = 1.0"
+ ^ self copyBitsTranslucent: 255].
+ ((sourceForm isForm) and: [sourceForm unhibernate])
+ ifTrue: [^ self copyBits].
+ ((destForm isForm) and: [destForm unhibernate])
+ ifTrue: [^ self copyBits].
+ ((halftoneForm isForm) and: [halftoneForm unhibernate])
+ ifTrue: [^ self copyBits].
+
+ "Check for unimplmented rules"
+ combinationRule = Form oldPaint ifTrue: [^ self paintBits].
+ combinationRule = Form oldErase1bitShape ifTrue: [^ self eraseBits].
+
+ "Check if BitBlt doesn't support full color maps"
+ (colorMap notNil and:[colorMap isColormap]) ifTrue:[
+ colorMap := colorMap colors.
+ ^self copyBits].
+ "Check if clipping gots us way out of range"
+ self clipRange ifTrue:[^self copyBits].
+
+ self error: 'Bad BitBlt arg (Fraction?); proceed to convert.'.
+ "Convert all numeric parameters to integers and try again."
+ destX := destX asInteger.
+ destY := destY asInteger.
+ width := width asInteger.
+ height := height asInteger.
+ sourceX := sourceX asInteger.
+ sourceY := sourceY asInteger.
+ clipX := clipX asInteger.
+ clipY := clipY asInteger.
+ clipWidth := clipWidth asInteger.
+ clipHeight := clipHeight asInteger.
+ ^ self copyBitsAgain! !
+!BitBlt methodsFor: 'line drawing' stamp: 'dmu 4/3/2009 23:01'!
+drawLoopLocallyX: xDelta Y: yDelta
+ "Primitive. Implements the Bresenham plotting algorithm (IBM Systems
+ Journal, Vol. 4 No. 1, 1965). It chooses a principal direction, and
+ maintains a potential, P. When P's sign changes, it is time to move in
+ the minor direction as well. This particular version does not write the
+ first and last points, so that these can be called for as needed in client code.
+ Optional. See Object documentation whatIsAPrimitive."
+ | |
+ <primitive: 'primitiveDrawLoopLocally'>
+self primitiveFailed! !
+!BitBlt methodsFor: 'line drawing' stamp: 'ssa 4/3/2009 22:36'!
+globalDrawLoopX: xDelta Y: yDelta
+ "Primitive. Implements the Bresenham plotting algorithm (IBM Systems
+ Journal, Vol. 4 No. 1, 1965). It chooses a principal direction, and
+ maintains a potential, P. When P's sign changes, it is time to move in
+ the minor direction as well. This particular version does not write the
+ first and last points, so that these can be called for as needed in client code.
+ Optional. See Object documentation whatIsAPrimitive."
+ | dx dy px py P |
+ <primitive: 'primitiveDrawLoop' module: 'BitBltPlugin'>
+ dx := xDelta sign.
+ dy := yDelta sign.
+ px := yDelta abs.
+ py := xDelta abs.
+ "self copyBits."
+ py > px
+ ifTrue:
+ ["more horizontal"
+ P := py // 2.
+ 1 to: py do:
+ [:i |
+ destX := destX + dx.
+ (P := P - px) < 0 ifTrue:
+ [destY := destY + dy.
+ P := P + py].
+ i < py ifTrue: [self copyBits]]]
+ ifFalse:
+ ["more vertical"
+ P := px // 2.
+ 1 to: px do:
+ [:i |
+ destY := destY + dy.
+ (P := P - py) < 0 ifTrue:
+ [destX := destX + dx.
+ P := P + px].
+ i < px ifTrue: [self copyBits]]]! !
+!BitBlt methodsFor: 'line drawing' stamp: 'ssa 4/3/2009 22:52'!
+localDrawLoopX: xDelta Y: yDelta
+ "Primitive"
+ <primitive: 'primitiveDrawLoopLocally'>
+ ^self primitiveFailed! !
+
+!BlockContext methodsFor: 'scheduling' stamp: 'dmu 4/7/2009 02:38'!
+forkOn: aCore
+ "Create and schedule a Process running the code in the receiver."
+
+ ^ self newProcess resumeOn: aCore! !
+!BlockContext methodsFor: 'scheduling' stamp: 'ssa 4/8/2009 20:09'!
+forkOn: aCore with: anObject
+ "Create and schedule a Process running the code in the receiver."
+
+ ^ (self newProcessWith: anObject) resumeOn: aCore! !
+!BlockContext methodsFor: 'scheduling' stamp: 'ssa 4/8/2009 20:08'!
+forkOn: aCore with: anObject at: aPriority
+ "Create and schedule a Process running the code in the receiver."
+
+ | proc |
+ proc := self newProcessWith: anObject.
+ proc priority: aPriority.
+ ^proc resumeOn: aCore! !
+!BlockContext methodsFor: 'scheduling' stamp: 'dmu 4/7/2009 02:34'!
+forkWith: anObject
+ "Create and schedule a Process running the code in the receiver."
+
+ ^ (self newProcessWith: anObject) resume! !
+!BlockContext methodsFor: 'scheduling' stamp: 'dmu 4/7/2009 02:33'!
+newProcessWith: anObject
+ "Answer a Process running the code in the receiver. The process is not
+ scheduled."
+ <primitive: 19> "Simulation guard"
+ ^Process
+ forContext:
+ [self value: anObject.
+ Processor terminateActive]
+ priority: Processor activePriority! !
+!Delay class methodsFor: 'snapshotting' stamp: 'dmu 5/25/2010 11:02'!
+startUp
+ "Restart active delay, if any, when resuming a snapshot."
+
+ DelaySuspended ifFalse:[^self error: 'Trying to activate Delay twice'].
+ DelaySuspended := false.
+ self restoreResumptionTimes.
+ AccessProtect := Semaphore forMutualExclusion
+! !
+!Delay methodsFor: 'private' stamp: 'StefanMarr 11/9/2010 23:38' prior: 47886371!
+schedule
+ "Schedule this delay"
+
+ | delayDelivered |
+ delayDelivered := false.
+
+ beingWaitedOn ifTrue: [^self error: 'This Delay has already been scheduled.'].
+ resumptionTime := Time millisecondClockValue + delayDuration.
+
+ [AccessProtect critical: [
+ ScheduledDelay ifNil: [
+ ScheduledDelay := self.
+ TimingSemaphore signal.
+ delayDelivered := true.
+ ]
+ ]. delayDelivered ] whileFalse.! !
+!Delay methodsFor: 'private' stamp: 'StefanMarr 11/9/2010 23:39' prior: 47885691!
+unschedule
+ | delayDelivered |
+ delayDelivered := false.
+
+ [AccessProtect critical: [
+ ScheduledDelay ifNil: [
+ FinishedDelay := self.
+ TimingSemaphore signal.
+ delayDelivered := true.
+ ]
+ ]. delayDelivered ] whileFalse.! !
+!Delay class methodsFor: 'timer process' stamp: 'StefanMarr 11/9/2010 17:44' prior: 19672467!
+handleTimerEvent
+ "Handle a timer event; which can be either:
+ - a schedule request (ScheduledDelay notNil)
+ - an unschedule request (FinishedDelay notNil)
+ - a timer signal (not explicitly specified)
+ We check for timer expiry every time we get a signal."
+ | nowTick nextTick |
+ "Wait until there is work to do."
+ TimingSemaphore wait.
+
+ "Process any schedule requests"
+ ScheduledDelay ifNotNil:[
+ "Schedule the given delay"
+ self scheduleDelay: ScheduledDelay.
+ ScheduledDelay := nil.
+ ].
+
+ "Process any unschedule requests"
+ FinishedDelay ifNotNil:[
+ self unscheduleDelay: FinishedDelay.
+ FinishedDelay := nil.
+ ].
+
+ "Check for clock wrap-around."
+ nowTick := Time millisecondClockValue.
+ nowTick < ActiveDelayStartTime ifTrue: [
+ "clock wrapped"
+ self saveResumptionTimes.
+ self restoreResumptionTimes.
+ ].
+ ActiveDelayStartTime := nowTick.
+
+ "Signal any expired delays"
+ [ActiveDelay notNil and:[nowTick >= ActiveDelay resumptionTime]] whileTrue:[
+ ActiveDelay signalWaitingProcess.
+ SuspendedDelays isEmpty
+ ifTrue: [ActiveDelay := nil]
+ ifFalse:[ActiveDelay := SuspendedDelays removeFirst].
+ ].
+
+ "And signal when the next request is due. We sleep at most 1sec here
+ as a soft busy-loop so that we don't accidentally miss signals."
+ nextTick := nowTick + 1000.
+ ActiveDelay ifNotNil:[nextTick := nextTick min: ActiveDelay resumptionTime].
+ nextTick := nextTick min: SmallInteger maxVal.
+
+ "Since we have processed all outstanding requests, reset the timing semaphore so
+ that only new work will wake us up again. Do this RIGHT BEFORE setting the next
+ wakeup call from the VM because it is only signaled once so we mustn't miss it."
+ "No!!!! If running multicore, TimingSemaphore may have already been signalled!!!!
+ Do not reset signals, because then we will miss it -- dmu 9/26/10"
+ RVMPrimitives coreCount > 1 ifFalse: [TimingSemaphore initSignals].
+ "Do not wait till the next Delay if Semaphore already signaled. -- dmu 9/26/10"
+ TimingSemaphore isSignaled ifFalse: [
+ Delay primSignal: TimingSemaphore atMilliseconds: nextTick.
+ ].
+
+ "This last test is necessary for the obscure case that the msecs clock rolls over
+ after nowTick has been computed (unlikely but not impossible). In this case we'd
+ wait for MillisecondClockMask msecs (roughly six days) or until another delay gets
+ scheduled (which may not be any time soon). In any case, since handling the
+ condition is easy, let's just deal with it"
+ Time millisecondClockValue < nowTick ifTrue:[TimingSemaphore signal]. "retry"
+! !
+!Process methodsFor: 'accessing' stamp: 'dmu 3/8/2010 20:26'!
+hostCore: anObject
+ "Set the value of hostCore"
+
+ hostCore := anObject! !
+!Process methodsFor: 'accessing' stamp: 'dmu 3/8/2010 20:26'!
+myList
+ "Answer the value of myList"
+
+ myList isNil ifTrue:[self myList: nil].
+ ^ myList! !
+!Process methodsFor: 'accessing' stamp: 'dmu 3/8/2010 20:26'!
+myList: anObject
+ "Set the value of myList"
+
+ myList := anObject! !
+!Process methodsFor: 'changing process state' stamp: 'dmu 3/2/2010 17:02'!
+primitiveSuspend
+ "Primitive. Stop the process that self represents in such a way
+ that it can be restarted at a later time (by sending #resume).
+ ASSUMES self is the active process.
+ Essential. See Object documentation whatIsAPrimitive."
+
+ "Debugging code below causes terminated running processes to seem not terminated. -- dmu 3/2/10"
+ "(myList isNil and: [RVMPrimitives isRVM]) ifTrue:[self halt]."
+ <primitive: 88>
+ self primitiveFailed! !
+!Process methodsFor: 'changing process state' stamp: 'dmu 4/7/2009 02:41'!
+resumeOn: aCore
+ self useOnlyCore: aCore.
+ self resume! !
+!Process methodsFor: 'changing suspended state' stamp: 'dmu 12/2/2008 14:04'!
+return: aContext value: value
+ "Pop thread down to aContext's sender. Execute any unwind blocks on the way. See #popTo: comment and #runUntilErrorOrReturnFrom: for more details."
+ self suspend.
+ suspendedContext == aContext ifTrue: [
+ ^ suspendedContext := aContext return: value from: aContext].
+ self activateReturn: aContext value: value.
+ ^ self complete: aContext.
+! !
+!Process methodsFor: 'changing suspended state' stamp: 'dmu 12/2/2008 14:03'!
+step
+ self suspend.
+ ^ suspendedContext := suspendedContext step! !
+!Process methodsFor: 'changing suspended state' stamp: 'dmu 12/2/2008 14:04'!
+stepToCallee
+ "Step until top context changes"
+
+ | ctxt |
+ self suspend.
+ ctxt := suspendedContext.
+ [ctxt == suspendedContext] whileTrue: [
+ suspendedContext := suspendedContext step].
+ ^ suspendedContext! !
+!Process methodsFor: 'changing suspended state' stamp: 'dmu 12/2/2008 14:05'!
+stepToSendOrReturn
+self suspend.
+ ^ suspendedContext := suspendedContext stepToSendOrReturn! !
+!Process methodsFor: 'core assignment' stamp: 'ssa 2/26/2009 02:57'!
+avoidCore: anIndex
+ "Force this process to avoid this core (0-55)"
+ self coreMask: (self coreMask bitClear: (1 bitShift: anIndex))! !
+!Process methodsFor: 'core assignment' stamp: 'ssa 2/26/2009 03:49'!
+avoidCores: aCollectionOfIndicies
+ "Force this process to avoid these cores (0-55)"
+ | mask |
+ mask := 0.
+ aCollectionOfIndicies do:[:index| mask := mask bitOr: (1 bitShift: index)].
+ self coreMask: (self coreMask bitClear:mask)! !
+!Process methodsFor: 'core assignment' stamp: 'ssa 2/26/2009 02:59'!
+useAdditionalCore: anIndex
+ "Force this process to only urn on this core (0-55)"
+ self coreMask: (self coreMask bitOr:(1 bitShift: anIndex))! !
+!Process methodsFor: 'core assignment' stamp: 'ssa 2/26/2009 03:50'!
+useAdditionalCores: aCollectionOfIndicies
+ "Allow this process to run on these additional cores (0-55)"
+ | mask |
+ mask := 0.
+ aCollectionOfIndicies do:[:index| mask := mask bitOr: (1 bitShift: index)].
+ self coreMask: (self coreMask bitOr:mask)! !
+!Process methodsFor: 'core assignment' stamp: 'dmu 5/5/2009 01:32'!
+useOnlyCore: anIndex
+ "Force this process to only run on this core (0-55)"
+ self coreMask: (1 bitShift: anIndex)! !
+!Process methodsFor: 'core assignment' stamp: 'ssa 2/26/2009 03:02'!
+useOnlyCores: aCollectionOfIndicies
+ "Force this process to only run on these cores (0-55)"
+ | mask |
+ mask := 0.
+ aCollectionOfIndicies do:[:index| mask := mask bitOr: (1 bitShift: index)].
+ self coreMask: mask! !
+!Process methodsFor: 'core assignment' stamp: 'dmu 1/25/2010 11:06'!
+useOnlyMainCore
+ RVMPrimitives isRVM ifTrue: [self useOnlyCore: (RVMPrimitives getMainRank)]! !
+!Process methodsFor: 'signaling' stamp: 'ssa 2/17/2009 22:30'!
+signal: anException
+ "Signal an exception in the receiver process...if the receiver is currently
+ suspended, the exception will get signaled when the receiver is resumed. If
+ the receiver is blocked on a Semaphore, it will be immediately re-awakened
+ and the exception will be signaled; if the exception is resumed, then the receiver
+ will return to a blocked state unless the blocking Semaphore has excess signals"
+
+ "If we are the active process, go ahead and signal the exception"
+ self == Processor thisProcess ifTrue: [^anException signal].
+
+ self suspend.
+
+ "Add a new method context to the stack that will signal the exception"
+ suspendedContext := MethodContext
+ sender: suspendedContext
+ receiver: self
+ method: (self class methodDict at: #pvtSignal:list:)
+ arguments: (Array with: anException with: myList).
+
+ "If we are on a list to run, then suspend and restart the receiver
+ (this lets the receiver run if it is currently blocked on a semaphore). If
+ we are not on a list to be run (i.e. this process is suspended), then when the
+ process is resumed, it will signal the exception"
+
+ myList ifNotNil: [self suspend; resume].! !
+!Process class methodsFor: 'instance creation' stamp: 'dmu 3/24/2010 15:46'!
+forContext: aContext priority: anInteger
+ "Answer an instance of me that has suspended aContext at priority
+ anInteger."
+
+ | newProcess |
+ newProcess := self new.
+ newProcess suspendedContext: aContext.
+ newProcess priority: anInteger.
+ [newProcess coreMask:(1 bitShift: 27)].
+ ^newProcess! !
+!Process class methodsFor: 'instance creation' stamp: 'ssa 2/26/2009 02:45'!
+forContext: aContext priority: anInteger coreMask: anIntegerMask
+ "Answer an instance of me that has suspended aContext at priority
+ anInteger using this coreMask."
+
+ | newProcess |
+ newProcess := self forContext: aContext priority: anInteger.
+ newProcess coreMask:anIntegerMask.
+ ^newProcess! !
+!ProcessorScheduler methodsFor: 'removing' stamp: 'ssa 6/11/2010 14:37'!
+removeAllPossible
+ "Terminate and remove all processes that you can.
+ This should leave the standard set only"
+ self terminatableProcesses print do:[:proc| proc terminate]! !
+!ProcessorScheduler methodsFor: 'removing' stamp: 'ssa 6/11/2010 14:31'!
+terminatableProcesses
+ "Answer all current processes that may be user terminated like in the ProcessBrowser"
+ "self terminatableProcesses"
+ | processList |
+ Smalltalk garbageCollectMost. "lose defunct processes"
+
+ processList := Process allSubInstances
+ reject: [:each | each isTerminated].
+ processList := processList
+ sortBy: [:a :b | a priority >= b priority].
+ processList := WeakArray withAll: processList.
+ ^processList select:[:proc| (ProcessBrowser nameAndRulesFor: proc) at: 2]! !
+!Project methodsFor: 'menu messages' stamp: 'dmu 11/25/2008 00:23'!
+enterForEmergencyRecovery
+ "This version of enter invokes an absolute minimum of mechanism.
+ An unrecoverable error has been detected in an isolated project.
+ It is assumed that the old changeSet has already been revoked.
+ No new process gets spawned here. This will happen in the debugger."
+
+ self isCurrentProject ifTrue: [^ self].
+ CurrentProject saveState.
+ CurrentProject := self.
+ Display newDepthNoRestore: displayDepth.
+ Smalltalk newChanges: changeSet.
+ TranscriptStream newTranscript: transcript.
+
+
+ world isMorph
+ ifTrue:
+ ["Entering a Morphic project"
+ World := world.
+ world install.
+ world triggerOpeningScripts]
+ ifFalse:
+ ["Entering an MVC project"
+ World := nil.
+ Smalltalk at: #ScheduledControllers put: world.
+ ScheduledControllers restore].
+ UIProcess := Processor thisProcess.
+! !
+
+!StandardFileStream methodsFor: 'RVM' stamp: 'dmu 9/7/2010 14:07'!
+interlock
+ interlock ifNil: [self interlock: Semaphore forMutualExclusion].
+ ^ interlock! !
+!StandardFileStream methodsFor: 'RVM' stamp: 'dmu 9/7/2010 14:07'!
+interlock: aSemaphore
+ interlock := aSemaphore! !
+!StandardFileStream methodsFor: 'RVM' stamp: 'dmu 9/7/2010 14:14'!
+resetInterlock
+ self interlock signal.
+ self interlock: nil! !
+!StandardFileStream methodsFor: 'RVM' stamp: 'dmu 9/7/2010 14:09'!
+safelyDo: aBlock
+ ^ self interlock critical: aBlock! !
+!StandardFileStream class methodsFor: 'RVM' stamp: 'dmu 9/7/2010 14:14'!
+resetAllInterlocks
+ "self resetAllInterlocks"
+ self allSubInstancesDo: [:sfs| sfs resetInterlock]! !
+
+!RemoteString methodsFor: 'accessing' stamp: 'dmu 9/7/2010 17:19'!
+text
+ "Answer the receiver's string asText if remote files are enabled.
+ Use a read only copy to avoid syntax errors when accessed via
+ multiple processes."
+
+ | theFile |
+ (sourceFileNumber == nil or: [(SourceFiles at: sourceFileNumber) == nil]) ifTrue: [^ nil].
+ theFile := (SourceFiles at: sourceFileNumber) readOnlyCopy.
+ ^[theFile safelyDo: [
+ theFile position: filePositionHi.
+ theFile position > theFile size ifTrue: [
+ self error: 'RemoteString past end of file' ].
+ theFile nextChunkText string ]] ensure: [theFile close]! !
+
+!SyntaxError class methodsFor: 'instance creation' stamp: 'dmu 11/25/2008 00:25'!
+open: aSyntaxError
+ "Answer a standard system view whose model is an instance of me."
+ <primitive: 19>
+ "Simulation guard"
+ self buildMorphicViewOn: aSyntaxError.
+ Project spawnNewProcessIfThisIsUI: Processor activeProcess.
+ ^ Processor thisProcess suspend! !
+!SmalltalkImage methodsFor: 'snapshot and quit' stamp: 'dmu 9/7/2010 14:26'!
+snapshot: save andQuit: quit embedded: embeddedFlag
+ "Mark the changes file and close all files as part of #processShutdownList.
+ If save is true, save the current state of this Smalltalk in the image file.
+ If quit is true, then exit to the outer OS shell.
+ The latter part of this method runs when resuming a previously saved image. This resume logic checks for a document file to process when starting up."
+
+ | resuming msg |
+ Object flushDependents.
+ Object flushEvents.
+ (SourceFiles at: 2)
+ ifNotNil: [
+ msg := String
+ streamContents: [ :s |
+ s
+ nextPutAll: '----';
+ nextPutAll:
+ (save
+ ifTrue: [
+ quit
+ ifTrue: [ 'QUIT' ]
+ ifFalse: [ 'SNAPSHOT' ] ]
+ ifFalse: [
+ quit
+ ifTrue: [ 'QUIT/NOSAVE' ]
+ ifFalse: [ 'NOP' ] ]);
+ nextPutAll: '----';
+ print: Date dateAndTimeNow;
+ space;
+ nextPutAll: (FileDirectory default localNameFor: self imageName);
+ nextPutAll: ' priorSource: ';
+ print: LastQuitLogPosition ].
+ self assureStartupStampLogged.
+ save
+ ifTrue: [
+ (SourceFiles at: 2) safelyDo: [
+ LastQuitLogPosition := (SourceFiles at: 2)
+ setToEnd;
+ position ]].
+ self logChange: msg.
+ Transcript
+ cr;
+ show: msg ].
+ self processShutDownList: quit.
+ Cursor write show.
+ save
+ ifTrue: [
+ resuming := embeddedFlag
+ ifTrue: [ self snapshotEmbeddedPrimitive ]
+ ifFalse: [ self snapshotPrimitive ]. "<-- PC frozen here on image file"
+ resuming == false
+ ifTrue: [
+ "Time to reclaim segment files is immediately after a save"
+ Smalltalk globals at: #ImageSegment ifPresent: [ :theClass | theClass reclaimObsoleteSegmentFiles ] ] "guard against failure" ]
+ ifFalse: [ resuming := false ].
+ quit & (resuming == false)
+ ifTrue: [ self quitPrimitive ].
+ Cursor normal show.
+ self setGCParameters.
+ resuming == true
+ ifTrue: [ Smalltalk clearExternalObjects ].
+ self processStartUpList: resuming == true.
+ resuming == true
+ ifTrue: [ self recordStartupStamp ].
+ UIManager default onSnapshot. "Now it's time to raise an error"
+ resuming == nil
+ ifTrue: [ self error: 'Failed to write image file (disk full?)' ].
+ ^ resuming! !
+
+
+Cursor initialize!
+Controller initialize!
+!BitBlt methodsFor: 'copying' stamp: 'ssa 4/7/2009 13:44'!
+OLDcopyBits
+ "Primitive. Perform the movement of bits from the source form to the
+ destination form. Fail if any variables are not of the right type (Integer,
+ Float, or Form) or if the combination rule is not implemented.
+ In addition to the original 16 combination rules, this BitBlt supports
+ 16 fail (to simulate paint)
+ 17 fail (to simulate mask)
+ 18 sourceWord + destinationWord
+ 19 sourceWord - destinationWord
+ 20 rgbAdd: sourceWord with: destinationWord
+ 21 rgbSub: sourceWord with: destinationWord
+ 22 rgbDiff: sourceWord with: destinationWord
+ 23 tallyIntoMap: destinationWord
+ 24 alphaBlend: sourceWord with: destinationWord
+ 25 pixPaint: sourceWord with: destinationWord
+ 26 pixMask: sourceWord with: destinationWord
+ 27 rgbMax: sourceWord with: destinationWord
+ 28 rgbMin: sourceWord with: destinationWord
+ 29 rgbMin: sourceWord bitInvert32 with: destinationWord
+"
+ <primitive: 'primitiveCopyBits' module: 'BitBltPlugin'>
+
+ "Check for compressed source, destination or halftone forms"
+ (combinationRule >= 30 and: [combinationRule <= 31]) ifTrue:
+ ["No alpha specified -- re-run with alpha = 1.0"
+ ^ self copyBitsTranslucent: 255].
+ ((sourceForm isForm) and: [sourceForm unhibernate])
+ ifTrue: [^ self copyBits].
+ ((destForm isForm) and: [destForm unhibernate])
+ ifTrue: [^ self copyBits].
+ ((halftoneForm isForm) and: [halftoneForm unhibernate])
+ ifTrue: [^ self copyBits].
+
+ "Check for unimplmented rules"
+ combinationRule = Form oldPaint ifTrue: [^ self paintBits].
+ combinationRule = Form oldErase1bitShape ifTrue: [^ self eraseBits].
+
+ "Check if BitBlt doesn't support full color maps"
+ (colorMap notNil and:[colorMap isColormap]) ifTrue:[
+ colorMap := colorMap colors.
+ ^self copyBits].
+ "Check if clipping gots us way out of range"
+ self clipRange ifTrue:[^self copyBits].
+
+ self error: 'Bad BitBlt arg (Fraction?); proceed to convert.'.
+ "Convert all numeric parameters to integers and try again."
+ destX := destX asInteger.
+ destY := destY asInteger.
+ width := width asInteger.
+ height := height asInteger.
+ sourceX := sourceX asInteger.
+ sourceY := sourceY asInteger.
+ clipX := clipX asInteger.
+ clipY := clipY asInteger.
+ clipWidth := clipWidth asInteger.
+ clipHeight := clipHeight asInteger.
+ ^ self copyBitsAgain! !
+!BitBlt methodsFor: 'copying' stamp: 'dmu 5/10/2009 08:43'!
+copyBits
+ RVMPrimitives isRVM ifFalse:[^self OLDcopyBits].
+ destForm == Display ifTrue: [self copyBitsOnMain] ifFalse: [self copyBitsLocally]! !
+!BitBlt methodsFor: 'line drawing' stamp: 'dmu 4/10/2009 22:47'!
+drawFrom: startPoint to: stopPoint withFirstPoint: drawFirstPoint
+ "Draw a line whose end points are startPoint and stopPoint.
+ The line is formed by repeatedly calling copyBits at every
+ point along the line. If drawFirstPoint is false, then omit
+ the first point so as not to overstrike at line junctions."
+ | offset point1 point2 forwards |
+ "Always draw down, or at least left-to-right"
+ forwards := (startPoint y = stopPoint y and: [startPoint x < stopPoint x])
+ or: [startPoint y < stopPoint y].
+ forwards
+ ifTrue: [point1 := startPoint. point2 := stopPoint]
+ ifFalse: [point1 := stopPoint. point2 := startPoint].
+ sourceForm == nil ifTrue:
+ [destX := point1 x.
+ destY := point1 y]
+ ifFalse:
+ [width := sourceForm width.
+ height := sourceForm height.
+ offset := sourceForm offset.
+ destX := (point1 x + offset x) rounded.
+ destY := (point1 y + offset y) rounded].
+
+ "Note that if not forwards, then the first point is the last and vice versa.
+ We agree to always paint stopPoint, and to optionally paint startPoint."
+ (drawFirstPoint or: [forwards == false "ie this is stopPoint"])
+ ifTrue: [self copyBits].
+ (destForm == Display or:[RVMPrimitives isRVM not]) ifTrue: [
+ self drawLoopX: (point2 x - point1 x) rounded
+ Y: (point2 y - point1 y) rounded]
+ ifFalse: [self drawLoopLocallyX: (point2 x - point1 x) rounded
+ Y: (point2 y - point1 y) rounded].
+ (drawFirstPoint or: [forwards "ie this is stopPoint"])
+ ifTrue: [self copyBits].
+! !
+!BitBlt methodsFor: 'line drawing' stamp: 'dmu 4/10/2009 22:47'!
+drawLoopX: xDelta Y: yDelta
+ "Primitive. Implements the Bresenham plotting algorithm (IBM Systems
+ Journal, Vol. 4 No. 1, 1965). It chooses a principal direction, and
+ maintains a potential, P. When P's sign changes, it is time to move in
+ the minor direction as well. This particular version does not write the
+ first and last points, so that these can be called for as needed in client code.
+ Optional. See Object documentation whatIsAPrimitive."
+
+ ^(destForm == Display or:[RVMPrimitives isRVM not])
+ ifTrue:[self globalDrawLoopX:xDelta Y: yDelta ]
+ ifFalse:[self localDrawLoopX:xDelta Y: yDelta ]! !
+
+!ClassDescription methodsFor: 'fileIn/Out' stamp: 'dmu 9/7/2010 14:17'!
+classComment: aString stamp: aStamp
+ "Store the comment, aString or Text or RemoteString, associated with the class we are organizing. Empty string gets stored only if had a non-empty one before."
+
+ | ptr header file oldCommentRemoteStr oldComment oldStamp |
+ oldComment := self organization classComment.
+ oldStamp := self organization commentStamp.
+ (aString isKindOf: RemoteString) ifTrue:
+ [SystemChangeNotifier uniqueInstance class: self oldComment: oldComment newComment: aString string oldStamp: oldStamp newStamp: aStamp.
+ ^ self organization classComment: aString stamp: aStamp].
+
+ oldCommentRemoteStr := self organization commentRemoteStr.
+ (aString size = 0) & (oldCommentRemoteStr isNil) ifTrue: [^ self organization classComment: nil].
+ "never had a class comment, no need to write empty string out"
+
+ ptr := oldCommentRemoteStr ifNil: [0] ifNotNil: [oldCommentRemoteStr sourcePointer].
+ SourceFiles ifNotNil: [(file := SourceFiles at: 2) ifNotNil:
+ [file safelyDo:
+ [file setToEnd; cr; nextPut: $!!. "directly"
+ "Should be saying (file command: 'H3') for HTML, but ignoring it here"
+ header := String streamContents: [:strm | strm nextPutAll: self name;
+ nextPutAll: ' commentStamp: '.
+ aStamp storeOn: strm.
+ strm nextPutAll: ' prior: '; nextPutAll: ptr printString].
+ file nextChunkPut: header]]].
+ self organization classComment: (RemoteString newString: aString onFileNumber: 2) stamp: aStamp.
+ SystemChangeNotifier uniqueInstance class: self oldComment: oldComment newComment: aString oldStamp: oldStamp newStamp: aStamp
+! !
+!CompiledMethod methodsFor: 'source code management' stamp: 'dmu 9/7/2010 14:23'!
+putSource: sourceStr fromParseNode: methodNode inFile: fileIndex withPreamble: preambleBlock
+ "Store the source code for the receiver on an external file.
+ If no sources are available, i.e., SourceFile is nil, then store
+ temp names for decompilation at the end of the method.
+ If the fileIndex is 1, print on *.sources; if it is 2, print on *.changes,
+ in each case, storing a 4-byte source code pointer at the method end."
+
+ | file remoteString |
+ (SourceFiles == nil or: [(file := SourceFiles at: fileIndex) == nil]) ifTrue:
+ [^self become: (self copyWithTempsFromMethodNode: methodNode)].
+
+ SmalltalkImage current assureStartupStampLogged.
+
+ file safelyDo: [
+ file setToEnd.
+
+ preambleBlock value: file. "Write the preamble"
+ remoteString := RemoteString newString: sourceStr onFileNumber: fileIndex toFile: file.
+ file nextChunkPut: ' '.
+ InMidstOfFileinNotification signal ifFalse: [file flush].
+ self checkOKToAdd: sourceStr size at: remoteString position.
+ self setSourcePosition: remoteString position inFile: fileIndex].
+! !
+!RemoteString methodsFor: 'private' stamp: 'dmu 9/7/2010 14:23'!