logging in or signing up esug2006georgheeg Reva Download Post to : URL : Related Presentations : Share Add to Flag Embed Email Send to Blogs and Networks Add to Channel Uploaded from authorPOINTLite Insert YouTube videos in PowerPont slides with aS Desktop Copy embed code: (To copy code, click on the text box) Embed: URL: Thumbnail: WordPress Embed Customize Embed The presentation is successfully added In Your Favorites. Views: 68 Category: Education License: All Rights Reserved Like it (0) Dislike it (0) Added: May 02, 2008 This Presentation is Public Favorites: 0 Presentation Description No description available. Comments Posting comment... Premium member Presentation Transcript Slide1: Georg Heeg eK Baroper Str. 337 44227 Dortmund Germany Tel: +49-231-97599-0 Fax: +49-231-97599-20 Email: georg@heeg.de http://www.heeg.de Georg Heeg AG Seestraße 135 8027 Zürich Switzerland Tel: +41(848) 43 34 24 Georg Heeg eK Mühlenstr. 19 06366 Köthen Germany Tel: +49-3496-214 328 Fax: +49-3496-214 712Slide2: Georg Heeg Integration of Cincom Smalltalk Systems - e.g. ObjectStudio inside VisualWorks Prague, September 7th, 2006About Georg Heeg eK: About Georg Heeg eK Founded 1987, headquarter in Dortmund, since 1996 in Zurich, since 1999 in Koethen/Anhalt Consulting- and training company in Smalltalk Hotline support, maintenance, bug-fixes for ObjectStudio, VisualWorks and Visual Smalltalk VM-laboratory for VisualWorks and ObjectStudio Porting service of old VisualWorks applications to 5i/7 Technology-partner of Corporate Mission: Make Sophisticated Projects a Success for the Customer!Some Background: Some Background 1994/96 Cincom bought ObjectStudio 1999 Cincom bought VisualWorks ObjectStudio customers keep asking for VisualWorks features ObjectStudio 8 integrates VisualWorks and ObjectStudioObjectStudio and VisualWorks: ObjectStudio and VisualWorks Both ObjectStudio and VisualWorks are Smalltalk systems. Both are owned by the same company Cincom VisualWorks like Squeak goes back to the original Smalltalk-76/-78/-80 developments at Xerox PARC. Originally called Smalltalk-80, ObjectWorks later ObjectStudio was developed as “Enterprise Object-Oriented Development Environment” Originally called Enfin. Key Features: Key Features Enfin/ObjectStudio Ease of Use Enterprise Integration Smalltalk-80/ObjectWorks/VisualWorks Execution speed Sophisticated meta-modelling features Customers want both Speed: always Ease of use: to get started Enterprise integration: mostly meta-modeling: seldom but if they need it, they outperform having it. From Forbes.COM: From Forbes.COM “A press conference is called. “The media is alerted. “The top executives gather for much backslapping and multisyllabic descriptions of the synergistic opportunities abounding in this, a fresh new partnership. “There's a champagne toast “and then the most extraordinary thing happens “...nothing! Nothing at all.” http://www.forbes.com/2002/07/01/0701alliances.html Synergy doesn’t Work: Synergy doesn’t Work VisualWorks VM for ObjectStudio “HPOS” Was started and … was not completed Ideas to integrate ObjectStudio into .NET … didn‘t make it Theory: Smalltalk is Different: Theory: Smalltalk is Different In Smalltalk programming is modeling. Thus every theory can be modeled well. Thus every computer technology can be modeled well Thus every other Smalltalk system can be modeled well.ObjectStudio 8: ObjectStudio 8 Model ObjectStudio by VisualWorks in Smalltalk Use Meta-Modeling Use all reflection capabilities Compiler Debugger NamespacesThe Goal: The Goal Both ObjectStudio and VisualWorks live in the same image the same time Both Environments share the same Smalltalk kernel and base classes to provide identical functionality Mixing and matching is seamlessly possible Both ObjectStudio and VisualWorks application Smalltalk code works unchanged There will always be exceptions to this rule The Team: The Team Suzanne Fortman (Program Director, Cincom Smalltalk) Andreas Hiltner (ObjectStudio 8 Lead Engineer) Mark Grinnell (ObjectStudio Lead Engineer) Eduard Maydanik (GUI Engineer) Kim Thomas (Testing, Packaging, Support) Eliot Miranda (VisualWorks Lead Engineer) Alan Knight (Store Consultant) Jörg Belger (VisualWorks Wrapper) James Robertson (Product Manager) Georg Heeg (Idea) Helge Nowak (Sales Engineer) Monika Laurent (Marketing)The First Step: The First Step Vocal chords surgery in June 2004 No permission to speak for a week End of First Step: End of First Step Smalltalk works UI does not work Primitives don’t workThe Second Step: Primitives: The Second Step: Primitives Jörg Belger starts working at Georg Heeg eK Köthen October 1, 2004 Coauthor of the original Ce VM as intern (100 days) Coauthor of computer games Background in C++ ObjectStudio MFC DLL functions are implemented One per one at a timeThe First Window Opens: The First Window Opens User Conference in Frankfurt December 2004 First customers see it and are impressed Second Step: Proof of Concept: Second Step: Proof of Concept One primitive at a time One day per primitive But … There are alone 450 MFC primitives Second step is stopped in January 2005Third Step: Do it Completely: Third Step: Do it Completely Take the entire ObjectStudio C/C++-Code Make it a VisualWorks callable DLL Started in February 2005June 2005: June 2005 Alpha1 Version made First time complete But not tested or bug-freeForth step: Check for Compatibility: Forth step: Check for Compatibility Run all components of the system If they work differently Add compatibility Decide for incompatibility seldom and easy to understand E.g.: BOSS instead of BinaryObjectStreams Run real Customer Applications Details: see laterSeptember 2006: September 2006 Ready for Beta1 at the end of the month Architecture overview: Architecture overview Virtual Machine ObjectStudio DLL Base Classes VisualWorks Code ObjectStudio Code ObjectStudio Smalltalk compatibility layerImplementation Strategy: Implementation Strategy KISS Keep modifications of ObjectStudio source code to a minimum In Smalltalk and C/C++ Do not modify VisualWorks VM unnecessarily Fix bugs Additional features in VW 7.4.1/7.5 Use LoadLibraryEx() instead of LoadLibrary() Event handling in the image General Concepts: General Concepts Model ObjectStudio by VisualWorks Smalltalk Preserve syntax and semantics ObjectStudioCompiler Embed in a NameSpace Share code Collections Magnitude Semaphore Boolean Undefined Object …VisualWorks Namespaces: VisualWorks Namespaces Goal (In-)visibility of global names Successor to GlobalDictionary PoolDictionary ClassPoolsSystem, the GlobalDictionary: System, the GlobalDictionary In Classic ObjectStudio all global names live in the Globaldictionary called System In ObjectStudio 8 Classes live in Namespace ObjectStudio Globals live in Namespace ObjectStudio.Globals Non Identifier entries are Stored in an IdentityDictionaryPoolDictionaries: PoolDictionaries In Classic ObjectStudio PoolDictionaries are globals which are IdentityDictionaries OLEConstants := IdentyDictionary new. OLEConstants at: # ADVF_DATAONSTOP put: 64. In ObjectStudio 8 Extra declaration is needed (manually) ObjectStudio.Globals defineNameSpace: #OLEConstants Entries in these Dictionaries become SharedVariables with initializers (automatically) ObjectStudio.Globals.OLEConstants defineSharedVariable: #ADVF_DATAONSTOP private: false constant: false category: 'As yet unclassified' initializer: '64'Shared Classes: Shared Classes ActionSequence, Array, Association, Bag, Behavior, BlockClosure, Boolean, ByteArray, Character, Class, Collection, CompiledBlock, CompiledMethod, Compiler, Date, Dictionary, EncodedStream, False, Fraction, IdentityDictionary, IdentitySet, Integer, InternalStream, Magnitude, Metaclass, MethodContext, Number, OrderedCollection, PeekableStream, Point, PositionableStream, Random, ReadStream, ReadWriteStream, Rectangle, Semaphore, Set, SmallInteger, SortedCollection, Stream, String, Symbol, Time, Timestamp, True, UndefinedObject, UserPrimitiveMethod, WeakDictionary, WriteStream, Exception, Error, MessageNotUnderstood, Notification, StreamError, PositionOutOfBoundsError, IncompleteNextCountError, EndOfStreamNotification, SocketAccessor, SocketAddressSpecial Renaming: Special Renaming ObjectStudio defineSharedVariable: #Float private: false constant: true category: 'ObjectStudio Compatibility 2' initializer: ‘Core.Double'Source Differences: Source Differences ObjectStudio cls files One class per file With class definition: primary files Class extension: secondary file Different chunk file format Method syntax differences Semantic differencesParsing ObjectStudio Source Code: Parsing ObjectStudio Source Code ObjectStudioCompiler Calls ObjectStudioParser ObjectStudioParser Accepts ObjectStudio Syntax Creates ObjectStudio Syntax compliant Syntax tree Specifying to use ObjectStudio Syntax classCompilerClass compilerClass Automatic source transformation of methods of VisualWorks classes in cls filesSyntax differences: Arrays and cond: Syntax differences: Arrays and cond f: n ^{{[n <= 1] [1]} {[true] [(self f: n - 1) * n]}} cond f: n ^n < 1 ifTrue: [1] ifFalse: [true ifTrue: [(self f: n - 1) * n] ifFalse: [ObjectStudio.Message newValue: 'No condition satisfied']] Syntax differences: parameters: Syntax differences: parameters inc: n n isNil ifTrue: [n := 0]. ^n + 1 inc: __n | n | n := __n. n isNil ifTrue: [n := 0]. ^n + 1Some Semantic Differences: Some Semantic DifferencesModifying ObjectStudio Parse Tree: Modifying ObjectStudio Parse Tree ProgramNodeEnumerator subclass OStudioTreeTransformer modifies parse tree <osprim …> Blocks in literal arrays Assignments to arguments Enabling inner returns Condition results Substitutions All this allows for VisualWorks Code generationMessages with different Semantics: Messages with different Semantics Kernel.OStudioTreeTransformer defineSharedVariable: #Substitutions private: false constant: false category: 'constants' initializer: '(Dictionary new) at: #basicAt:put: put: #os_basicAt:put; …; yourself’Substituted Selectors: Substituted SelectorsDifferent file structure, first version: Different file structure, first version Reader for .txt and .cls files to get ObjectStudio code into VisualWorks ClassReader Reads txt files and calls ObjectStudioChangeScanner ObjectStudioChangeScanner Reads cls filesSecond Version: Source Code Integration: Second Version: Source Code Integration ObjectStudio.ApplicationDefintionStream Original Classic ObjectStudio class Reads .txt files OStudioChunkSourceFileFormat Lives in VisualWorks SourceFileFormat class hierarchy Reads and writes .cls files Controls that .cls files ObjectStudio Smalltalk and C: ObjectStudio Smalltalk and C Strong interconnection between C and Smalltalk They call each other all the time There are five ways to call C Direct primitives PrimSpecRec Numbered Primitives <primitive: 123> Named Primitives <osprim: MFC openWindow> <osprim: #myDll myfunc> Module/ENFINModule Programmatic creation of interface methods using osprim ExternalProcedures Programmatic creation of interface methods with C datatypesObjectStudioWrapperDLL: ObjectStudioWrapperDLL Regular VisualWorks DLL Uses _oop as parameter and return type Calls ObjectStudio primitives using a simulated ObjectStudio stack OPTR and _oop: OPTR and _oop In ObjectStudio object pointers OPTR never move In VisualWorks object pointer _oop are moved by the garbage collector ObjectStudio C code relies on not non moving OPTR Solution: Define class OPTR with wraps VisualWorks Oops for ObjectStudio including C++ reference counting The real object pointers _oop are stored in a Smalltalk array which is registered in the Visualworks registry the index to this array is stored in class OPTR as variable Reference counts are stored in a normal C array. OPTR class (extract): OPTR class (extract) class __declspec(dllexport) OPTR; typedef OPTR* POPTR; class OPTR { public: static OPTR& cpp_S2O(LONG value); […] private: […] enum Types {TYPE_NIL = 0, TYPE_NORMALOBJECT, TYPE_NOTNORMALOBJECT, TYPE_UNKNOWN}; INT m_IndexOrOop; // index in objecttable or not normal object INT m_Type; // type of object static INT s_NumObjects; // number of registered objects static INT s_NextFreeObject; // index of next free object in objecttable static INT s_ObjectTable; // index of objecttable array in visualworks registry static INT* s_LinkTable; // array with linked registry slots static INT* s_RefCounts; // array with reference counts Direct Primitives: Direct Primitives Look at definition Re-implement mostly in Smalltalk using existing VisualWorks functionality In rare cases replace by osprimNumbered Primitives: Numbered Primitives <Primitive: 45> Some are replaced by VisualWorks Primitive E.g. Object>>== <vwprimitive: 110> VisualWorks implementation For most Auto-generate calling codeAuto-Generated Primitive: Auto-Generated Primitive disable <primitive: 7> ^ self primitiveFailed. disable <osprimitive: 7> | argumentArray | argumentArray := Core.Array os_new: 0. ^ObjectStudioCallInterface os_new callPrim: 7 self: self arguments: argumentArray ifFail: [^self primitiveFailed]Primitive Calling Method: Primitive Calling Method Class ObjectStudioCallInterface callPrim: primitiveNumber self: oSelf arguments: args ifFail: failBlock self init. ^[self callPrim: primitiveNumber self: oSelf arguments: args] on: PrimitiveFailException do: [:ex| ^failBlock value] callPrim: primitiveNumber self: oSelf arguments: args <C: _oop callPrim(int primitiveNumber, _oop oSelf, _oop args)> _errorCode = 0 ifTrue: [PrimitiveFailException raise]. self externalAccessFailedWith: _errorCodeThe C++ side: The C++ side _oop callPrim(int primitiveNumber, _oop oSelf, _oop args) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); […] primReturnCode = CallUserPrimitiveFunc(primMethodOPTR); oSelf = PPop().getObject(); […] if (primReturnCode == FALSE) UPfail(0); return oSelf; }Autogenerated osprim: Autogenerated osprim activateExcludeChild: fExclude <osprim: MFC ActivateForm> ^ self primitiveFailed. activateExcludeChild: fExclude <osprim: MFC ActivateForm> <methodClass: ExternalAnnotatedMethod> | argumentArray | (argumentArray := Array new: 1) os_at: 1 put: fExclude. ^ObjectStudio.External.ObjectStudioCallInterface new callOSPrim: thisContext method functionSpecification self: self arguments: argumentArray ifFail: [^self primitiveFailed]Manually created osprim (Class Point): Manually created osprim (Class Point) translateFromForm: aFormOrFormItem to: anOther "<osprim: TRACK POINTTRANSLATEFROMFORM>" | args functionSpecification | args := Array new: 2. args at: 1 put: aFormOrFormItem. args at: 2 put: anOther. functionSpecification := OSPrimSpecifier new. functionSpecification module: Root.ObjectStudio.ENFINModule versionTag , 'TRACK'. functionSpecification function: 'POINTTRANSLATEFROMFORM'. functionSpecification numArgs: 2. ^Root.ObjectStudio.ObjectStudioCallInterface new callOSPrim: functionSpecification self: self arguments: args ifFail: [^self primitiveFailed] OSPrimSpecifier: OSPrimSpecifier Smalltalk.Kernel defineClass: #OSPrimSpecifier superclass: #{Object} indexedType: #none private: false instanceVariableNames: 'numArgs numTemps handle function module ' classInstanceVariableNames: '' imports: '' category: 'ObjectStudio Tools‚ExternalAnnotatedMethod: ExternalAnnotatedMethod Smalltalk.Kernel defineClass: #ExternalAnnotatedMethod superclass: #{Kernel.AnnotatedMethod} indexedType: #objects private: false instanceVariableNames: 'functionSpecification ' classInstanceVariableNames: '' imports: '' category: 'ExternalAnnotatedMethod‘ Variable functionSpecification stores instances of OSPrimSpecifierModule/EnfinModule: Module/EnfinModule Autogenerate osprim privateQueryVolumeName: aSmallInteger <osprim: FILES PRIVATEQUERYDRIVENAME> ":Section Reference privateQueryVolumeName: aSmallInteger Description: Returns the name of a drive. Assumptions: The drive number passed in is a small integer starting with 1 for drive A:. This function returns allways an empty strings on operating systems, which do not support a drive concept. […] External Procedures: External Procedures Just work unchangedObjectStudio Unicode: ObjectStudio Unicode In ObjectStudio 7 Two installations Two Virtual Machines Incompatible Images Compatible Source Code In ObjectStudio 8 One installation One Virtual Machine Two sets of DLLs One image Decision at start-upNative Widgets: Native Widgets Use MFC Callbacks to VisualWorksCalling Smalltalk from C: Calling Smalltalk from C PSend is implemented using OESendMessageMany() ASend is implemented using OESendMessageMany() whenIdleSend: aSelector to: aReceiver withArguments: anArray "inserts the asend into the queue " ASendSemaphore critical: [ASendQueue addLast: (Core.MessageSend receiver: aReceiver selector: aSelector arguments: (anArrayOrObject isArray ifTrue: [anArrayOrObject] ifFalse: [Array with: anArrayOrObject]))] The Process Model: The Process Model VisualWorks process model Many Smalltalk processes are running in different priority. Windows events are handled (almost) any time Shared queues move the events to target processes This is emplemented in C ObjectStudio process model The caller of all execution is the Windows Event Loop All Message Sends in the ASendQueue are executed when the Windows Event is empty This is implemented in C++Decision of July 2006: Decision of July 2006 Move EventLoop to Smalltalk Available in vw-dev since August 29, 2006 Initialzing in class EventProcessingManager: primCallbackEventInstall: aMethodSelector "Inform the VM of the callback class (the receiver) and the callback invocation method selector for event processing." | regNames | regNames := ObjectMemory registrationNames. ((regNames includes: 'callbackEventClass') and: [regNames includes: 'callbackEventSelector']) ifTrue: [ObjectMemory registerObject: self withEngineFor: 'callbackEventClass'. ObjectMemory registerObject: aMethodSelector withEngineFor: 'callbackEventSelector']Eventloop in Smalltalk: Eventloop in Smalltalk Class EventProcessingManager runs the loop delegates all actions to the handler Implemented in EventHandler class hierarchy processEvents | eventRecord | handler canHandleMultipleEvents ifFalse: [self blockEvents ifTrue: [^self]]. [eventRecord := handler eventRecord. [handler nextEvent: eventRecord] whileTrue: [handler handleEvent: eventRecord]. handler postHandleEvents] ensure: [self allowEvents]Subclasses of EventHandler: Subclasses of EventHandler Example methods in Win32EventHandler eventRecord ^self MSG gcMalloc nextEvent: anEventRecord ^(self peekMessageA: anEventRecord window: 0 filterMin: 0 filterMax: 0 flags: (self PM_REMOVE bitOr: self PM_NOYIELD)) ~= self FALSE postHandleEvents ^selfOStudioEventHandler: OStudioEventHandler Example methods in OStudioEventHandler preTranslateMessage: msg <C: BOOL PreTranslateMessage(LPMSG msg)> ^self externalAccessFailedWith: _errorCode postHandleEvents System wantsBusyCursor ifTrue: [UI.Cursor wait showWhile: [System drainASendQueue]] ifFalse: [System drainASendQueue]. self onIdleApp onIdleApp <C: void OnIdleApp(void)> ^self externalAccessFailedWith: _errorCodeHandling an event: Handling an event In Win32EventHandler handleEvent: anEventRecord self translateMessage: anEventRecord. self dispatchMessageA: anEventRecord In OStudioEventHandler handleEvent: anEventRecord (self preTranslateMessage: anEventRecord) = self FALSE ifTrue: [self translateMessage: anEventRecord. self dispatchMessageA: anEventRecord]User Interrupts : User Interrupts <ctrl> Y and <ctrl> <shift> Y work as in VisualWorks Implemented as Accelerator Keys <ctrl> Y interrupts the running process by sending self halt: in a callBack from CClass Proxies: Class Proxies Class Proxies work They are shared variables in Root.ObjectStudio.Global Loading puts class in Root.ObjectStudioApplication Loading: Application Loading Application loading works Performance Issues: Performance Issues In Classic ObjectStudio Smalltalk execution is slow Calling C primitives cost nothing In VisualWorks Smalltalk execution is fast Calling C is expensive In Classic ObjectStudio Performance critical methods are moved to C In ObjectStudio 8 Performance critical primitives are moved back to SmalltalkVisualWorks .st file-in is slow: VisualWorks .st file-in is slow Of 1000 seconds 900 are RB refresh Of 100 seconds 90 are repeatedly relinking the system Of 10 Seconds 9 are disk flush (Changes file) 1 second compiling At the end of the optimizations: Loading as alternative to file-in Loading a .st is similar speed as parcel loading Small .st/.cls files load faster than parcels Large parcel files load faster than .st/.cls filesNew Concepts for ObjectStudio: New Concepts for ObjectStudio Source Code Management Store Versioning system Database based Smalltalk Archives File based One file per application Code purity Undeclared Code Critic OverridesTime Line: Time Line June 2005 Internal Alpha October 2005 Internal Alpha2 March 2006 Cincom internal testing April 2006 First Customer August 2006 First independent Service Partner May-September 2006 Solve incompatabilities, Refactoring, Performance issues October 2006 Next few customers December 2006 PreviewPorting Process Theory: Porting Process Theory Theory Load application Start itPorting Process Practice: Porting Process Practice Look at base system modifications Like any other porting this is a source of many problems Known incompatibilities Immutability Declare Pool Dictionaries Export Modeling Tool definitions in ASCII Binary format is incompatibleUndeclareds: Undeclareds In Classic ObjectStudio Each undeclared variable is always considered a global In VisualWorks and ObjectStudio 8 Each undeclared variable is considered undeclared GHUndeclaredBrowser Shows all Undeclareds and their references It uncovered some very old ObjectStudio problems due to typoes.Target Look: Target Look After loading Modeling Tool: After loading Modeling Tool What can ESUG Audience learn?: What can ESUG Audience learn? Integration of Smalltalk systems is possible Which systems deserve to be integrated? VW and Squeak Very common systems VSE VA Smalltalk-X Dolphin Ruby Java Frost GemStone You do not have the permission to view this presentation. In order to view it, please contact the author of the presentation.
esug2006georgheeg Reva Download Post to : URL : Related Presentations : Share Add to Flag Embed Email Send to Blogs and Networks Add to Channel Uploaded from authorPOINTLite Insert YouTube videos in PowerPont slides with aS Desktop Copy embed code: (To copy code, click on the text box) Embed: URL: Thumbnail: WordPress Embed Customize Embed The presentation is successfully added In Your Favorites. Views: 68 Category: Education License: All Rights Reserved Like it (0) Dislike it (0) Added: May 02, 2008 This Presentation is Public Favorites: 0 Presentation Description No description available. Comments Posting comment... Premium member Presentation Transcript Slide1: Georg Heeg eK Baroper Str. 337 44227 Dortmund Germany Tel: +49-231-97599-0 Fax: +49-231-97599-20 Email: georg@heeg.de http://www.heeg.de Georg Heeg AG Seestraße 135 8027 Zürich Switzerland Tel: +41(848) 43 34 24 Georg Heeg eK Mühlenstr. 19 06366 Köthen Germany Tel: +49-3496-214 328 Fax: +49-3496-214 712Slide2: Georg Heeg Integration of Cincom Smalltalk Systems - e.g. ObjectStudio inside VisualWorks Prague, September 7th, 2006About Georg Heeg eK: About Georg Heeg eK Founded 1987, headquarter in Dortmund, since 1996 in Zurich, since 1999 in Koethen/Anhalt Consulting- and training company in Smalltalk Hotline support, maintenance, bug-fixes for ObjectStudio, VisualWorks and Visual Smalltalk VM-laboratory for VisualWorks and ObjectStudio Porting service of old VisualWorks applications to 5i/7 Technology-partner of Corporate Mission: Make Sophisticated Projects a Success for the Customer!Some Background: Some Background 1994/96 Cincom bought ObjectStudio 1999 Cincom bought VisualWorks ObjectStudio customers keep asking for VisualWorks features ObjectStudio 8 integrates VisualWorks and ObjectStudioObjectStudio and VisualWorks: ObjectStudio and VisualWorks Both ObjectStudio and VisualWorks are Smalltalk systems. Both are owned by the same company Cincom VisualWorks like Squeak goes back to the original Smalltalk-76/-78/-80 developments at Xerox PARC. Originally called Smalltalk-80, ObjectWorks later ObjectStudio was developed as “Enterprise Object-Oriented Development Environment” Originally called Enfin. Key Features: Key Features Enfin/ObjectStudio Ease of Use Enterprise Integration Smalltalk-80/ObjectWorks/VisualWorks Execution speed Sophisticated meta-modelling features Customers want both Speed: always Ease of use: to get started Enterprise integration: mostly meta-modeling: seldom but if they need it, they outperform having it. From Forbes.COM: From Forbes.COM “A press conference is called. “The media is alerted. “The top executives gather for much backslapping and multisyllabic descriptions of the synergistic opportunities abounding in this, a fresh new partnership. “There's a champagne toast “and then the most extraordinary thing happens “...nothing! Nothing at all.” http://www.forbes.com/2002/07/01/0701alliances.html Synergy doesn’t Work: Synergy doesn’t Work VisualWorks VM for ObjectStudio “HPOS” Was started and … was not completed Ideas to integrate ObjectStudio into .NET … didn‘t make it Theory: Smalltalk is Different: Theory: Smalltalk is Different In Smalltalk programming is modeling. Thus every theory can be modeled well. Thus every computer technology can be modeled well Thus every other Smalltalk system can be modeled well.ObjectStudio 8: ObjectStudio 8 Model ObjectStudio by VisualWorks in Smalltalk Use Meta-Modeling Use all reflection capabilities Compiler Debugger NamespacesThe Goal: The Goal Both ObjectStudio and VisualWorks live in the same image the same time Both Environments share the same Smalltalk kernel and base classes to provide identical functionality Mixing and matching is seamlessly possible Both ObjectStudio and VisualWorks application Smalltalk code works unchanged There will always be exceptions to this rule The Team: The Team Suzanne Fortman (Program Director, Cincom Smalltalk) Andreas Hiltner (ObjectStudio 8 Lead Engineer) Mark Grinnell (ObjectStudio Lead Engineer) Eduard Maydanik (GUI Engineer) Kim Thomas (Testing, Packaging, Support) Eliot Miranda (VisualWorks Lead Engineer) Alan Knight (Store Consultant) Jörg Belger (VisualWorks Wrapper) James Robertson (Product Manager) Georg Heeg (Idea) Helge Nowak (Sales Engineer) Monika Laurent (Marketing)The First Step: The First Step Vocal chords surgery in June 2004 No permission to speak for a week End of First Step: End of First Step Smalltalk works UI does not work Primitives don’t workThe Second Step: Primitives: The Second Step: Primitives Jörg Belger starts working at Georg Heeg eK Köthen October 1, 2004 Coauthor of the original Ce VM as intern (100 days) Coauthor of computer games Background in C++ ObjectStudio MFC DLL functions are implemented One per one at a timeThe First Window Opens: The First Window Opens User Conference in Frankfurt December 2004 First customers see it and are impressed Second Step: Proof of Concept: Second Step: Proof of Concept One primitive at a time One day per primitive But … There are alone 450 MFC primitives Second step is stopped in January 2005Third Step: Do it Completely: Third Step: Do it Completely Take the entire ObjectStudio C/C++-Code Make it a VisualWorks callable DLL Started in February 2005June 2005: June 2005 Alpha1 Version made First time complete But not tested or bug-freeForth step: Check for Compatibility: Forth step: Check for Compatibility Run all components of the system If they work differently Add compatibility Decide for incompatibility seldom and easy to understand E.g.: BOSS instead of BinaryObjectStreams Run real Customer Applications Details: see laterSeptember 2006: September 2006 Ready for Beta1 at the end of the month Architecture overview: Architecture overview Virtual Machine ObjectStudio DLL Base Classes VisualWorks Code ObjectStudio Code ObjectStudio Smalltalk compatibility layerImplementation Strategy: Implementation Strategy KISS Keep modifications of ObjectStudio source code to a minimum In Smalltalk and C/C++ Do not modify VisualWorks VM unnecessarily Fix bugs Additional features in VW 7.4.1/7.5 Use LoadLibraryEx() instead of LoadLibrary() Event handling in the image General Concepts: General Concepts Model ObjectStudio by VisualWorks Smalltalk Preserve syntax and semantics ObjectStudioCompiler Embed in a NameSpace Share code Collections Magnitude Semaphore Boolean Undefined Object …VisualWorks Namespaces: VisualWorks Namespaces Goal (In-)visibility of global names Successor to GlobalDictionary PoolDictionary ClassPoolsSystem, the GlobalDictionary: System, the GlobalDictionary In Classic ObjectStudio all global names live in the Globaldictionary called System In ObjectStudio 8 Classes live in Namespace ObjectStudio Globals live in Namespace ObjectStudio.Globals Non Identifier entries are Stored in an IdentityDictionaryPoolDictionaries: PoolDictionaries In Classic ObjectStudio PoolDictionaries are globals which are IdentityDictionaries OLEConstants := IdentyDictionary new. OLEConstants at: # ADVF_DATAONSTOP put: 64. In ObjectStudio 8 Extra declaration is needed (manually) ObjectStudio.Globals defineNameSpace: #OLEConstants Entries in these Dictionaries become SharedVariables with initializers (automatically) ObjectStudio.Globals.OLEConstants defineSharedVariable: #ADVF_DATAONSTOP private: false constant: false category: 'As yet unclassified' initializer: '64'Shared Classes: Shared Classes ActionSequence, Array, Association, Bag, Behavior, BlockClosure, Boolean, ByteArray, Character, Class, Collection, CompiledBlock, CompiledMethod, Compiler, Date, Dictionary, EncodedStream, False, Fraction, IdentityDictionary, IdentitySet, Integer, InternalStream, Magnitude, Metaclass, MethodContext, Number, OrderedCollection, PeekableStream, Point, PositionableStream, Random, ReadStream, ReadWriteStream, Rectangle, Semaphore, Set, SmallInteger, SortedCollection, Stream, String, Symbol, Time, Timestamp, True, UndefinedObject, UserPrimitiveMethod, WeakDictionary, WriteStream, Exception, Error, MessageNotUnderstood, Notification, StreamError, PositionOutOfBoundsError, IncompleteNextCountError, EndOfStreamNotification, SocketAccessor, SocketAddressSpecial Renaming: Special Renaming ObjectStudio defineSharedVariable: #Float private: false constant: true category: 'ObjectStudio Compatibility 2' initializer: ‘Core.Double'Source Differences: Source Differences ObjectStudio cls files One class per file With class definition: primary files Class extension: secondary file Different chunk file format Method syntax differences Semantic differencesParsing ObjectStudio Source Code: Parsing ObjectStudio Source Code ObjectStudioCompiler Calls ObjectStudioParser ObjectStudioParser Accepts ObjectStudio Syntax Creates ObjectStudio Syntax compliant Syntax tree Specifying to use ObjectStudio Syntax classCompilerClass compilerClass Automatic source transformation of methods of VisualWorks classes in cls filesSyntax differences: Arrays and cond: Syntax differences: Arrays and cond f: n ^{{[n <= 1] [1]} {[true] [(self f: n - 1) * n]}} cond f: n ^n < 1 ifTrue: [1] ifFalse: [true ifTrue: [(self f: n - 1) * n] ifFalse: [ObjectStudio.Message newValue: 'No condition satisfied']] Syntax differences: parameters: Syntax differences: parameters inc: n n isNil ifTrue: [n := 0]. ^n + 1 inc: __n | n | n := __n. n isNil ifTrue: [n := 0]. ^n + 1Some Semantic Differences: Some Semantic DifferencesModifying ObjectStudio Parse Tree: Modifying ObjectStudio Parse Tree ProgramNodeEnumerator subclass OStudioTreeTransformer modifies parse tree <osprim …> Blocks in literal arrays Assignments to arguments Enabling inner returns Condition results Substitutions All this allows for VisualWorks Code generationMessages with different Semantics: Messages with different Semantics Kernel.OStudioTreeTransformer defineSharedVariable: #Substitutions private: false constant: false category: 'constants' initializer: '(Dictionary new) at: #basicAt:put: put: #os_basicAt:put; …; yourself’Substituted Selectors: Substituted SelectorsDifferent file structure, first version: Different file structure, first version Reader for .txt and .cls files to get ObjectStudio code into VisualWorks ClassReader Reads txt files and calls ObjectStudioChangeScanner ObjectStudioChangeScanner Reads cls filesSecond Version: Source Code Integration: Second Version: Source Code Integration ObjectStudio.ApplicationDefintionStream Original Classic ObjectStudio class Reads .txt files OStudioChunkSourceFileFormat Lives in VisualWorks SourceFileFormat class hierarchy Reads and writes .cls files Controls that .cls files ObjectStudio Smalltalk and C: ObjectStudio Smalltalk and C Strong interconnection between C and Smalltalk They call each other all the time There are five ways to call C Direct primitives PrimSpecRec Numbered Primitives <primitive: 123> Named Primitives <osprim: MFC openWindow> <osprim: #myDll myfunc> Module/ENFINModule Programmatic creation of interface methods using osprim ExternalProcedures Programmatic creation of interface methods with C datatypesObjectStudioWrapperDLL: ObjectStudioWrapperDLL Regular VisualWorks DLL Uses _oop as parameter and return type Calls ObjectStudio primitives using a simulated ObjectStudio stack OPTR and _oop: OPTR and _oop In ObjectStudio object pointers OPTR never move In VisualWorks object pointer _oop are moved by the garbage collector ObjectStudio C code relies on not non moving OPTR Solution: Define class OPTR with wraps VisualWorks Oops for ObjectStudio including C++ reference counting The real object pointers _oop are stored in a Smalltalk array which is registered in the Visualworks registry the index to this array is stored in class OPTR as variable Reference counts are stored in a normal C array. OPTR class (extract): OPTR class (extract) class __declspec(dllexport) OPTR; typedef OPTR* POPTR; class OPTR { public: static OPTR& cpp_S2O(LONG value); […] private: […] enum Types {TYPE_NIL = 0, TYPE_NORMALOBJECT, TYPE_NOTNORMALOBJECT, TYPE_UNKNOWN}; INT m_IndexOrOop; // index in objecttable or not normal object INT m_Type; // type of object static INT s_NumObjects; // number of registered objects static INT s_NextFreeObject; // index of next free object in objecttable static INT s_ObjectTable; // index of objecttable array in visualworks registry static INT* s_LinkTable; // array with linked registry slots static INT* s_RefCounts; // array with reference counts Direct Primitives: Direct Primitives Look at definition Re-implement mostly in Smalltalk using existing VisualWorks functionality In rare cases replace by osprimNumbered Primitives: Numbered Primitives <Primitive: 45> Some are replaced by VisualWorks Primitive E.g. Object>>== <vwprimitive: 110> VisualWorks implementation For most Auto-generate calling codeAuto-Generated Primitive: Auto-Generated Primitive disable <primitive: 7> ^ self primitiveFailed. disable <osprimitive: 7> | argumentArray | argumentArray := Core.Array os_new: 0. ^ObjectStudioCallInterface os_new callPrim: 7 self: self arguments: argumentArray ifFail: [^self primitiveFailed]Primitive Calling Method: Primitive Calling Method Class ObjectStudioCallInterface callPrim: primitiveNumber self: oSelf arguments: args ifFail: failBlock self init. ^[self callPrim: primitiveNumber self: oSelf arguments: args] on: PrimitiveFailException do: [:ex| ^failBlock value] callPrim: primitiveNumber self: oSelf arguments: args <C: _oop callPrim(int primitiveNumber, _oop oSelf, _oop args)> _errorCode = 0 ifTrue: [PrimitiveFailException raise]. self externalAccessFailedWith: _errorCodeThe C++ side: The C++ side _oop callPrim(int primitiveNumber, _oop oSelf, _oop args) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); […] primReturnCode = CallUserPrimitiveFunc(primMethodOPTR); oSelf = PPop().getObject(); […] if (primReturnCode == FALSE) UPfail(0); return oSelf; }Autogenerated osprim: Autogenerated osprim activateExcludeChild: fExclude <osprim: MFC ActivateForm> ^ self primitiveFailed. activateExcludeChild: fExclude <osprim: MFC ActivateForm> <methodClass: ExternalAnnotatedMethod> | argumentArray | (argumentArray := Array new: 1) os_at: 1 put: fExclude. ^ObjectStudio.External.ObjectStudioCallInterface new callOSPrim: thisContext method functionSpecification self: self arguments: argumentArray ifFail: [^self primitiveFailed]Manually created osprim (Class Point): Manually created osprim (Class Point) translateFromForm: aFormOrFormItem to: anOther "<osprim: TRACK POINTTRANSLATEFROMFORM>" | args functionSpecification | args := Array new: 2. args at: 1 put: aFormOrFormItem. args at: 2 put: anOther. functionSpecification := OSPrimSpecifier new. functionSpecification module: Root.ObjectStudio.ENFINModule versionTag , 'TRACK'. functionSpecification function: 'POINTTRANSLATEFROMFORM'. functionSpecification numArgs: 2. ^Root.ObjectStudio.ObjectStudioCallInterface new callOSPrim: functionSpecification self: self arguments: args ifFail: [^self primitiveFailed] OSPrimSpecifier: OSPrimSpecifier Smalltalk.Kernel defineClass: #OSPrimSpecifier superclass: #{Object} indexedType: #none private: false instanceVariableNames: 'numArgs numTemps handle function module ' classInstanceVariableNames: '' imports: '' category: 'ObjectStudio Tools‚ExternalAnnotatedMethod: ExternalAnnotatedMethod Smalltalk.Kernel defineClass: #ExternalAnnotatedMethod superclass: #{Kernel.AnnotatedMethod} indexedType: #objects private: false instanceVariableNames: 'functionSpecification ' classInstanceVariableNames: '' imports: '' category: 'ExternalAnnotatedMethod‘ Variable functionSpecification stores instances of OSPrimSpecifierModule/EnfinModule: Module/EnfinModule Autogenerate osprim privateQueryVolumeName: aSmallInteger <osprim: FILES PRIVATEQUERYDRIVENAME> ":Section Reference privateQueryVolumeName: aSmallInteger Description: Returns the name of a drive. Assumptions: The drive number passed in is a small integer starting with 1 for drive A:. This function returns allways an empty strings on operating systems, which do not support a drive concept. […] External Procedures: External Procedures Just work unchangedObjectStudio Unicode: ObjectStudio Unicode In ObjectStudio 7 Two installations Two Virtual Machines Incompatible Images Compatible Source Code In ObjectStudio 8 One installation One Virtual Machine Two sets of DLLs One image Decision at start-upNative Widgets: Native Widgets Use MFC Callbacks to VisualWorksCalling Smalltalk from C: Calling Smalltalk from C PSend is implemented using OESendMessageMany() ASend is implemented using OESendMessageMany() whenIdleSend: aSelector to: aReceiver withArguments: anArray "inserts the asend into the queue " ASendSemaphore critical: [ASendQueue addLast: (Core.MessageSend receiver: aReceiver selector: aSelector arguments: (anArrayOrObject isArray ifTrue: [anArrayOrObject] ifFalse: [Array with: anArrayOrObject]))] The Process Model: The Process Model VisualWorks process model Many Smalltalk processes are running in different priority. Windows events are handled (almost) any time Shared queues move the events to target processes This is emplemented in C ObjectStudio process model The caller of all execution is the Windows Event Loop All Message Sends in the ASendQueue are executed when the Windows Event is empty This is implemented in C++Decision of July 2006: Decision of July 2006 Move EventLoop to Smalltalk Available in vw-dev since August 29, 2006 Initialzing in class EventProcessingManager: primCallbackEventInstall: aMethodSelector "Inform the VM of the callback class (the receiver) and the callback invocation method selector for event processing." | regNames | regNames := ObjectMemory registrationNames. ((regNames includes: 'callbackEventClass') and: [regNames includes: 'callbackEventSelector']) ifTrue: [ObjectMemory registerObject: self withEngineFor: 'callbackEventClass'. ObjectMemory registerObject: aMethodSelector withEngineFor: 'callbackEventSelector']Eventloop in Smalltalk: Eventloop in Smalltalk Class EventProcessingManager runs the loop delegates all actions to the handler Implemented in EventHandler class hierarchy processEvents | eventRecord | handler canHandleMultipleEvents ifFalse: [self blockEvents ifTrue: [^self]]. [eventRecord := handler eventRecord. [handler nextEvent: eventRecord] whileTrue: [handler handleEvent: eventRecord]. handler postHandleEvents] ensure: [self allowEvents]Subclasses of EventHandler: Subclasses of EventHandler Example methods in Win32EventHandler eventRecord ^self MSG gcMalloc nextEvent: anEventRecord ^(self peekMessageA: anEventRecord window: 0 filterMin: 0 filterMax: 0 flags: (self PM_REMOVE bitOr: self PM_NOYIELD)) ~= self FALSE postHandleEvents ^selfOStudioEventHandler: OStudioEventHandler Example methods in OStudioEventHandler preTranslateMessage: msg <C: BOOL PreTranslateMessage(LPMSG msg)> ^self externalAccessFailedWith: _errorCode postHandleEvents System wantsBusyCursor ifTrue: [UI.Cursor wait showWhile: [System drainASendQueue]] ifFalse: [System drainASendQueue]. self onIdleApp onIdleApp <C: void OnIdleApp(void)> ^self externalAccessFailedWith: _errorCodeHandling an event: Handling an event In Win32EventHandler handleEvent: anEventRecord self translateMessage: anEventRecord. self dispatchMessageA: anEventRecord In OStudioEventHandler handleEvent: anEventRecord (self preTranslateMessage: anEventRecord) = self FALSE ifTrue: [self translateMessage: anEventRecord. self dispatchMessageA: anEventRecord]User Interrupts : User Interrupts <ctrl> Y and <ctrl> <shift> Y work as in VisualWorks Implemented as Accelerator Keys <ctrl> Y interrupts the running process by sending self halt: in a callBack from CClass Proxies: Class Proxies Class Proxies work They are shared variables in Root.ObjectStudio.Global Loading puts class in Root.ObjectStudioApplication Loading: Application Loading Application loading works Performance Issues: Performance Issues In Classic ObjectStudio Smalltalk execution is slow Calling C primitives cost nothing In VisualWorks Smalltalk execution is fast Calling C is expensive In Classic ObjectStudio Performance critical methods are moved to C In ObjectStudio 8 Performance critical primitives are moved back to SmalltalkVisualWorks .st file-in is slow: VisualWorks .st file-in is slow Of 1000 seconds 900 are RB refresh Of 100 seconds 90 are repeatedly relinking the system Of 10 Seconds 9 are disk flush (Changes file) 1 second compiling At the end of the optimizations: Loading as alternative to file-in Loading a .st is similar speed as parcel loading Small .st/.cls files load faster than parcels Large parcel files load faster than .st/.cls filesNew Concepts for ObjectStudio: New Concepts for ObjectStudio Source Code Management Store Versioning system Database based Smalltalk Archives File based One file per application Code purity Undeclared Code Critic OverridesTime Line: Time Line June 2005 Internal Alpha October 2005 Internal Alpha2 March 2006 Cincom internal testing April 2006 First Customer August 2006 First independent Service Partner May-September 2006 Solve incompatabilities, Refactoring, Performance issues October 2006 Next few customers December 2006 PreviewPorting Process Theory: Porting Process Theory Theory Load application Start itPorting Process Practice: Porting Process Practice Look at base system modifications Like any other porting this is a source of many problems Known incompatibilities Immutability Declare Pool Dictionaries Export Modeling Tool definitions in ASCII Binary format is incompatibleUndeclareds: Undeclareds In Classic ObjectStudio Each undeclared variable is always considered a global In VisualWorks and ObjectStudio 8 Each undeclared variable is considered undeclared GHUndeclaredBrowser Shows all Undeclareds and their references It uncovered some very old ObjectStudio problems due to typoes.Target Look: Target Look After loading Modeling Tool: After loading Modeling Tool What can ESUG Audience learn?: What can ESUG Audience learn? Integration of Smalltalk systems is possible Which systems deserve to be integrated? VW and Squeak Very common systems VSE VA Smalltalk-X Dolphin Ruby Java Frost GemStone