diff --git a/Thamsen_2014_Thesis-names.tex b/Thamsen_2014_Thesis-names.tex index b1e7f71..4501d7e 100644 --- a/Thamsen_2014_Thesis-names.tex +++ b/Thamsen_2014_Thesis-names.tex @@ -1,12 +1,5 @@ -% -% Automatically included file. -% -% Should contain: -% * hyphenation; -% * macros for, eg, product names; -% * acronyms -% \hyphenation{Small-talk} +\hyphenation{Java-Script} \newacronym{cop}{Context-oriented Programming} \newacronym{dom}{Document Object Model} @@ -16,10 +9,3 @@ \newacronym{api}{application programming interface} \newacronym{http}{Hypertext Transfer Protocol} \newacronym{uml}{Unified Modeling Language} - -% \newacronym{vm}{Virtual Machine} -% \newacronym{ast}{abstract syntax tree} - -%%% Local Variables: -%%% mode: latex -%%% End: diff --git a/Thamsen_2014_Thesis.tex b/Thamsen_2014_Thesis.tex index d08141d..dc80ef0 100644 --- a/Thamsen_2014_Thesis.tex +++ b/Thamsen_2014_Thesis.tex @@ -5,7 +5,7 @@ % \PassOptionsToPackage{final}{graphics} -\documentclass[draft,master]{swathesis} +\documentclass[final,master]{swathesis} \def\fromname{by} @@ -13,6 +13,9 @@ \lstset{language=JavaScript,extendedchars=true} +\usepackage{geometry} +\special{papersize=210mm,297mm} + \usepackage{pifont} \newcounter{dingdistance} \setcounter{dingdistance}{191} @@ -33,9 +36,8 @@ Bastian Steinert } -% ABGABEDATUM -% \setdate{2012}{04}{05} -% \date{\datedate} +\setdate{2014}{05}{13} +\date{\datedate} \author{Lauritz Thamsen} \location{Potsdam} @@ -44,13 +46,13 @@ \begin{document} \frontmatter +\newpage +\newpage \maketitle \input{content/0_1_abstract} \input{content/0_2_acknowledgment} \tableofcontents \listoffigures -% \listoftables -% \lstlistoflistings \mainmatter \input{content/1_introduction} @@ -63,8 +65,6 @@ \input{content/8_future_work} \input{content/9_summary} -% \listofacronyms - \printbibliography \clearpage diff --git a/content/0_1_abstract.tex b/content/0_1_abstract.tex index 6e6bfab..842f35b 100755 --- a/content/0_1_abstract.tex +++ b/content/0_1_abstract.tex @@ -1,7 +1,7 @@ \begin{abstract} % Background -In programming systems such as the Lively Kernel programmers construct applications from objects. +In programming systems such as the Lively Kernel, programmers construct applications from objects. Dedicated tools allow them to manipulate the state and behavior of objects at runtime. Programmers are encouraged to make changes directly and receive immediate feedback on their actions. @@ -43,13 +43,9 @@ Der Ansatz basiert auf \emph{versionsbewusste Referenzen}. Diese können zu mehreren Versionen von Objekten aufgelöst werden und erlauben so vorherige Systemzustände wiederherzustellen. -Die Arbeit beschreibt eine auf Proxys basierende Implementierung in JavaScript. +Die Arbeit beschreibt einen auf Proxys basierenden Entwurf und eine Implementierung in JavaScript. Die Evaluierung der Implementierung zeigt, dass Systemzustände des Lively Kernels damit erhalten und wiederhergestellt werden können. Der zusätzlich nötige Arbeitsspeicher für die versionsbewussten Referenzen ist dabei vertretbar, während die Programmausführung erheblich verlangsamt wird. Mit Verbesserungen könnte die vorgestellte Lösung allerdings benutzt werden, um Entwickler mit praktikablen Wiederherstellungs-Werkzeugen zu unterstützen. \end{zusammenfassung} - -%%% Local Variables: -%%% mode: latex -%%% End: diff --git a/content/0_2_acknowledgment.tex b/content/0_2_acknowledgment.tex index 257a095..08b3752 100644 --- a/content/0_2_acknowledgment.tex +++ b/content/0_2_acknowledgment.tex @@ -14,8 +14,4 @@ \chapter*{Acknowledgments} \label{cha:acknowledgments} \begin{quotation} \noindent I thank Oliver Buck for his comments on drafts of this thesis. -\end{quotation} - -%%% Local Variables: -%%% mode: latex -%%% End: +\end{quotation} \ No newline at end of file diff --git a/content/2_background.tex b/content/2_background.tex index bb906af..8f7badd 100755 --- a/content/2_background.tex +++ b/content/2_background.tex @@ -50,7 +50,7 @@ \section{The Lively Kernel} Thus, programmers can create versions of the Lively Kernel with the Lively Kernel. The Lively Kernel is a browser-based system. -It is implemented in JavaScript and renders to \ac{HTML}. +It is implemented in JavaScript and renders to \ac{html}. \subsubsection{Programming with Prototypes and Classes} @@ -74,10 +74,6 @@ \subsubsection{Direct Manipulation of Morphs} When a morph is grabbed, it can be added to another morph and becomes that morph's submorph. This way, a morph does not have to be a basic shapes or simple widgets, but can be the interface of any application. -The Lively Kernel provides a set of manipulation tools, called \emph{Halos}, as shown in Figure~\ref{fig:Halos}. -Developers can bring up these tools for each morph. -The different buttons of a morph's halo allow, for example, to resize, rotate, and copy morphs. - \begin{figure}[h] \centering \includegraphics[width=0.3\textwidth]{figures/2_background/1_halos.pdf} @@ -85,14 +81,11 @@ \subsubsection{Direct Manipulation of Morphs} \label{fig:Halos} \end{figure} -Other halo buttons open specific tools, which are shown in Figure~\ref{fig:LivelyTools}: +The Lively Kernel provides a set of manipulation tools, called \emph{Halos}, as shown in Figure~\ref{fig:Halos}. +Developers can bring up these tools for each morph. +The different buttons of a morph's halo allow, for example, to resize, rotate, and copy morphs. -\begin{figure}[h] - \centering - \includegraphics[width=\textwidth]{figures/2_background/2_LivelyTools.pdf} - \caption{Three Lively Kernel's tools to manipulate morphs: the Inspector, the Style Editor, and the Object Editor.} - \label{fig:LivelyTools} -\end{figure} +Other halo buttons open specific tools, which are shown in Figure~\ref{fig:LivelyTools}: \begin{enumerate} \item The \emph{Inspector}~\circnum{1} presents all the values that make up a morph's current state. It also has a small code pane at the bottom that can be used to manipulate the morph's properties programmatically. @@ -100,6 +93,12 @@ \subsubsection{Direct Manipulation of Morphs} \item The \emph{Object Editor}~\circnum{3} is a tool to edit the object-specific behavior of morphs. It shows all scripts of a particular morph and allows programmers to add, remove, and edit scripts. \end{enumerate} +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{figures/2_background/2_LivelyTools.pdf} + \caption{Three Lively Kernel's tools to manipulate morphs: the Inspector, the Style Editor, and the Object Editor.} + \label{fig:LivelyTools} +\end{figure} \subsubsection{Saving Morphs to the Shared Parts Bin Repository} @@ -131,14 +130,7 @@ \section{CoExist} \subsubsection{Tools to Recover Previous Development States} -CoExist provides two tools to help programmers benefit from the preserved histories, shown in Figure~\ref{fig:CoExist}: - -\begin{figure}[h] - \centering - \includegraphics[width=\textwidth]{figures/2_background/4_coexistTools.pdf} - \caption{CoExist's tools to manage the preserved development states: the \emph{Timeline} and the \emph{Version Browser}.} - \label{fig:CoExist} -\end{figure} +CoExist provides two tools to help programmers benefit from the preserved histories, shown in Figure~\ref{fig:CoExist}. \paragraph{Timeline} CoExist's \emph{Timeline} tool is located at the bottom of the development environment. @@ -156,6 +148,12 @@ \subsubsection{Tools to Recover Previous Development States} The tools support programmers in re-tracing their steps, understanding the impact of their actions, and in recovering previous development states. They can withdraw changes permanently or recover only specific information from previous versions. +\begin{figure}[h] + \centering + \includegraphics[width=\textwidth]{figures/2_background/4_coexistTools.pdf} + \caption{CoExist's tools to manage the preserved development states: the \emph{Timeline} and the \emph{Version Browser}.} + \label{fig:CoExist} +\end{figure} \subsubsection{Benefits of Continuous Versioning} diff --git a/content/3_motivation.tex b/content/3_motivation.tex index 4db8210..f4f671b 100644 --- a/content/3_motivation.tex +++ b/content/3_motivation.tex @@ -8,13 +8,6 @@ \section{Part Development By Example} To exemplify how developers work directly on objects in the Lively Kernel, we will outline how a Lively Kernel user adds a new feature to the Object Editor. -\begin{figure}[h] - \centering - \includegraphics[width=0.7\textwidth]{figures/3_motivation/1_magnifierButton.png} - \caption{The Object Editor with its magnifier button highlighted with a red outline.} - \label{fig:MagnifierButton} -\end{figure} - The editor has been developed by composing and editing graphical objects. Thus, the user does not adapt any source code modules to change the editor, but rather manipulates objects directly. @@ -22,6 +15,13 @@ \section{Part Development By Example} The magnifier tool helps finding the editor's target, which is the object the editor currently presents scripts for. Implementing the new feature requires to create a new button morph and to add it to the editor, as shown in Figure~\ref{fig:MagnifierButton}. +\begin{figure}[h] + \centering + \includegraphics[width=0.7\textwidth]{figures/3_motivation/1_magnifierButton.png} + \caption{The Object Editor's magnifier button highlighted with a red outline.} + \label{fig:MagnifierButton} +\end{figure} + The magnifier button has two features: \begin{enumerate} \item When a programmer hovers over the button, the Object Editor's current target is highlighted with a rectangular overlay. @@ -33,7 +33,7 @@ \section{Part Development By Example} \begin{figure}[h] \centering \includegraphics[width=0.8\textwidth]{figures/3_motivation/2_magnifierBehavior.png} - \caption{Hovering the Object Editor's magnifier button highlights the current target object.} + \caption{The Object Editor's magnifier button as it highlights the editor's target.} \label{fig:MagnifierBehavior} \end{figure} @@ -48,6 +48,11 @@ \section{Part Development By Example} Moving the button around will then move the image accordingly. Finally, the users adds the result of these manipulations, visible in \circnum{4}, to the Object Editor. +All these changes are made directly to the state of objects: the button morph, the magnifier image morph, and the editor morph.\\ +When programmers edit parts in this way, they often see the effects of their actions immediately. +For example, when adding the new button to the Object Editor, the button is visible at all times. +Programmers do not need to run any code to see and test the button. + \begin{figure}[h] \centering \includegraphics[width=0.8\textwidth]{figures/3_motivation/3_buildingTheButton.pdf} @@ -55,11 +60,6 @@ \section{Part Development By Example} \label{fig:ButtonBuilding} \end{figure} -All these changes are made directly to the state of objects: the button morph, the magnifier image morph, and the editor morph.\\ -When programmers edit parts in this way, they often see the effects of their actions immediately. -For example, when adding the new button to the Object Editor, the button is visible at all times. -Programmers do not need to run any code to see and test the button. - \paragraph{Scripting the Button Morph} Now the user implements the button's behavior. The user adds scripts to the button that lay a translucent rectangle over the current target. @@ -93,13 +93,6 @@ \section{Recovery Needs When Developing Parts} \item \textbf{Inappropriate changes through scripts}: The user could make a mistake in a workspace snippet that is intended to manipulate morph properties programmatically. Such a snippet can change many properties of many objects. \end{itemize} -\begin{figure}[h] - \centering - \includegraphics[width=0.7\textwidth]{figures/3_motivation/4_workspaceDoIt.png} - \caption{The button's \lstinline{onMouseMove} script with a text selection.} - \label{fig:onMouseOverScript} -\end{figure} - \paragraph{Explorative Script Evaluation} Undesirable changes can also be introduced when a programmer explores the behavior of objects by evaluating scripts. The Object Editor allows evaluating code directly for its target object. @@ -109,18 +102,18 @@ \section{Recovery Needs When Developing Parts} Only evaluating the selected lines would, however, neither check the conditions usually checked above nor set the state usually set below the selected lines. Therefore, evaluating this selection allows to test the highlighting behavior but leaves the system in a state it normally would not be in. +\begin{figure}[h] + \centering + \includegraphics[width=0.7\textwidth]{figures/3_motivation/4_workspaceDoIt.png} + \caption{The button's \lstinline{onMouseMove} script with a text selection.} + \label{fig:onMouseOverScript} +\end{figure} + The examples show that there are many situations in which the user might want to undo previous actions. In programming systems like the Lively Kernel, where programmers work on objects, changes are always made to the state of objects. Functions are properties of objects. Even classes and modules are objects. -\begin{figure}[h] - \centering - \includegraphics[width=0.6\textwidth]{figures/3_motivation/5_stateChanges.pdf} - \caption{Adding a submorph changes the state of a morph.} - \label{fig:changedCharacter} -\end{figure} - For example, evaluating the text selection in Figure~\ref{fig:onMouseOverScript} changes the \lstinline{world} object's state. The \lstinline{world} object has now one more submorph, as shown in Figure~\ref{fig:changedCharacter}. Thus, the \lstinline{world}'s collection of submorphs is changed. @@ -128,3 +121,10 @@ \section{Recovery Needs When Developing Parts} To undo the side-effect of the script and re-establish the previous situation, the change to the \lstinline{world} object needs to be undone. The \lstinline{submorphs} property of \lstinline{world} has to be as it previously was.\\ When the state of all objects is preserved and can be re-established, previous system states can be recovered when necessary. + +\begin{figure}[h] + \centering + \includegraphics[width=0.6\textwidth]{figures/3_motivation/5_stateChanges.pdf} + \caption{Adding a submorph changes the state of a morph.} + \label{fig:changedCharacter} +\end{figure} diff --git a/content/4_approach.tex b/content/4_approach.tex index a94c0ec..d87c97f 100755 --- a/content/4_approach.tex +++ b/content/4_approach.tex @@ -17,7 +17,7 @@ \subsubsection{Versions of Objects} \begin{figure}[h] \centering \includegraphics[width=0.22\textwidth]{figures/4_approach/1_singleObject.pdf} - \caption{An \emph{address} object with three properties.} + \caption{An \lstinline{address} object with three properties.} \label{fig:SingleObject} \end{figure} @@ -28,7 +28,7 @@ \subsubsection{Versions of Objects} \begin{figure}[h] \centering \includegraphics[width=0.7\textwidth]{figures/4_approach/2_objectChange.pdf} - \caption{Two versions of an \emph{address} object in two versions of the system.} + \caption{Two versions of an \lstinline{address} object in two versions of the system.} \label{fig:ObjectChanged} \end{figure} @@ -37,25 +37,26 @@ \subsubsection{Versions of Objects} A version of an object is, in the simplest case, a copy of an object. When the \lstinline{address} object is changed in version \emph{v2} of the system, the system does not change the orginal \lstinline{address} object but the copy. -\begin{figure}[h!] +As shown in Figure~\ref{fig:VersionPreserved}, there are now two versions of the \lstinline{address} objects in version \emph{v2} of the system. +One of the objects holds the original state, while the other holds the state the object should have in version \emph{v2} of the system. +The two objects hold no information that indicates to which version of the system they belong. +They also do not store any information showing that one object is a copy of the other. + +\begin{figure}[h] \centering \includegraphics[width=0.7\textwidth]{figures/4_approach/3_previousVersionPreserved.pdf} - \caption{Preserving the previous version of the \emph{address} object.} + \caption{Preserving the previous version of the \lstinline{address} object.} \label{fig:VersionPreserved} \end{figure} -As shown in Figure~\ref{fig:VersionPreserved}, there are now two versions of the \lstinline{address} objects in version \emph{v2} of the system. -One of the objects holds the original state, while the other holds the state the object should have in version \emph{v2} of the system. -The two objects hold no information that indicates to which version of the system they belong. -They also do not store any information showing that one object is a copy of the other. At the same time, references to objects remain unchanged. For example, there could have been a \lstinline{person} object referring to the \lstinline{address} object. This reference would still be referring to the original \lstinline{address} object, even in version \emph{v2} of the system, as shown in Figure~\ref{fig:ReferenceFixedToPreviousVersion}. -\begin{figure}[h!] +\begin{figure}[h] \centering \includegraphics[width=\textwidth]{figures/4_approach/4_referenceToPreviousVersion.pdf} - \caption{A reference refers to the previous version of the \emph{address} object.} + \caption{A reference refers to the previous version of the \lstinline{address} object.} \label{fig:ReferenceFixedToPreviousVersion} \end{figure} @@ -88,7 +89,7 @@ \subsubsection{Version-aware References} \begin{figure}[h] \centering \includegraphics[width=0.8\textwidth]{figures/4_approach/5_versionAwareReferenceFollowingVersion2.pdf} - \caption{A version-aware reference relates a \emph{person} object to two versions of its \emph{address} property.} + \caption{A version-aware reference relates a \lstinline{person} object to two versions of its \lstinline{address} property.} \label{fig:VersionAwareReferenceFollowingVersion2} \end{figure} @@ -104,7 +105,7 @@ \subsubsection{Version-aware References} \begin{figure}[h] \centering \includegraphics[width=\textwidth]{figures/4_approach/6_objectGraphWithVersonAwareReferences.pdf} - \caption{Three versions of a \emph{company} object, in which objects are connected through version-aware references.} + \caption{An object graph with version-aware references.} \label{fig:ObjectGraphWithReferencesResolvedAlongVersion2} \end{figure} @@ -171,7 +172,7 @@ \subsubsection{Proxies as Version-aware References} \begin{figure}[h] \centering \includegraphics[width=\textwidth]{figures/4_approach/7_proxyBasedVersionAwareReference.pdf} - \caption{Using a proxy as version-aware reference to connect a \emph{person} object with two versions of an \emph{address} object.} + \caption{Using a proxy as version-aware reference to connect a \lstinline{person} object to two versions of an \lstinline{address} object.} \label{fig:ProxyBasedVersionAwareReference} \end{figure} @@ -253,20 +254,20 @@ \subsubsection{Versions of the System} \begin{figure}[h] \centering \includegraphics[width=0.65\textwidth]{figures/4_approach/8_systemVersions.pdf} - \caption{Four objects representing four linear versions of the system.} + \caption{Four versions of the system.} \label{fig:SystemVersions} \end{figure} The current version of the system is accessible to the proxies. Proxies use it to decide to which version of an object they currently should forward to. -Figure~\ref{fig:ProxyUseSystemVersion} shows a proxy with \emph{versions of an object} in the context of \emph{versions of the system}. +Figure~\ref{fig:ProxyUseSystemVersion} shows a proxy, versions of an object, and versions of the system. In this example, there are two object versions that correspond to the two system versions. The current version of the system is \emph{v2} and, therefore, the version the proxy currently forwards to is version \emph{v2} of the object. \begin{figure}[h] \centering \includegraphics[width=\textwidth]{figures/4_approach/9_proxyUsesSystemVersion.pdf} - \caption{A proxy with two versions of an object in context of the versions of the system.} + \caption{A proxy with two object versions in context of the system versions.} \label{fig:ProxyUseSystemVersion} \end{figure} @@ -279,17 +280,17 @@ \subsubsection{Versions of the System} \emph{To preserve the current version}, the system version has to be set to a different version. The proxies forward interactions to other object versions or, when no such version of the object exist, create new versions. +A situation in which a new version of an object is created is shown in Figure~\ref{fig:NewVersion}. +In a new version \emph{v3} of the system, the proxy intercepts a manipulation but has no object version it can forward to. +It, therefore, copies the most recent version of the object and forwards to the copy. + \begin{figure}[h] \centering \includegraphics[width=0.86\textwidth]{figures/4_approach/10_newVersionOfAnObject.pdf} - \caption{A new version of an object needs is created for a new version of the system.} + \caption{A new version of an object is created for a new version of the system.} \label{fig:NewVersion} \end{figure} -A situation in which a new version of an object is created is shown in Figure~\ref{fig:NewVersion}. -In a new version \emph{v3} of the system, the proxy intercepts a manipulation but has no object version it can forward to. -It, therefore, copies the most recent version of the object and forwards to the copy. - New versions are only necessary when a proxy is about to delegate manipulations. As long as the state of an object is only read, the proxy reports values from a previous version as the old version of the object still reflects the current state. To create a new version, a proxy copies the most recent previous version of the object. diff --git a/content/5_implementation.tex b/content/5_implementation.tex index 6624465..f1dd212 100755 --- a/content/5_implementation.tex +++ b/content/5_implementation.tex @@ -1,6 +1,3 @@ -% Proxies stand in for multiple versions, intercept all access, and forward to the correct version. - - \chapter{Implementation} \label{chapter:IMPLEMENTATION} This chapter describes how we used the ECMAScript 6 proxies\footnote{\url{http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies}, accessed February 3rd, 2014} to implement version-aware references for the Lively Kernel. @@ -8,7 +5,7 @@ \chapter{Implementation} \label{chapter:IMPLEMENTATION} The chapter also presents workarounds for the current state of ECMAScript 6 proxies. It concludes with current limitations. -\section{ECMAScript 6 Proxies as Version-aware References} \label{sec:IMPLEMENTATION:1} +\section{Using the ECMAScript 6 Proxies as Version-aware References} \label{sec:IMPLEMENTATION:1} This section first describes the proxies proposed with the next version of JavaScript's standard. It then explains how the proxies are used in our implementation. @@ -161,7 +158,7 @@ \subsection{Using the Proxies for Object Versioning} \label{subsec:IMPLEMENTATIO \end{figure} Our handler uses all traps to forward to the current version of an object. -For example, its \lstinline{get} trap is implemented as shown in Listing~\ref{lst:getTrap}\footnote{The code in this chapter is a simplified version of the actual code. It omits special cases for workarounds (Section \ref{sec:IMPLEMENTATION:4}) and debugging the implementation. The actual code is available at \url{http://github.com/LivelyKernel/LivelyKernel/commits/50181548}.}. +For example, its \lstinline{get} trap is implemented as shown in Listing~\ref{lst:getTrap}\footnote{The code in this chapter is a simplified version of the actual code. It omits special cases for workarounds (Section~\ref{sec:IMPLEMENTATION:4}) and debugging the implementation. The actual code is available at \url{http://github.com/LivelyKernel/LivelyKernel/commits/50181548}.}. \iffalse \begin{verbatim}\fi @@ -257,6 +254,9 @@ \subsection{Using the Proxies for Object Versioning} \label{subsec:IMPLEMENTATIO Changing the global version is an undo, redo, or commit depending on whether the version is set to a previous, following, or new version. The system provides the following three functions for this: \lstinline{lively.undo} (Listing~\ref{lst:undo}), \lstinline{lively.redo} (Listing~\ref{lst:redo}), and \lstinline{lively.commit} (Listing~\ref{lst:commit}). +Using a global version of the system is reasonable as JavaScript is executed single-threaded and scheduled cooperatively by the JavaScript engines. +Therefore, while a script runs, the global version cannot be changed by another script. + \iffalse \begin{verbatim}\fi \begin{code}[lst:undo]{The \lstinline{lively.undo} method.}{float,numbers=left} @@ -309,9 +309,6 @@ \subsection{Using the Proxies for Object Versioning} \label{subsec:IMPLEMENTATIO \iffalse \end{verbatim}\fi -Using a global version of the system is reasonable as JavaScript is executed single-threaded and scheduled cooperatively by the JavaScript engines. -Therefore, while a script runs, the global version cannot be changed by another script. - \subsubsection{Scope of the Versioning} \label{subsubsec:IMPLEMENTATION:5.2.1} @@ -329,7 +326,7 @@ \subsubsection{Scope of the Versioning} \label{subsubsec:IMPLEMENTATION:5.2.1} -\section{Proxies For All Mutable JavaScript Objects} +\section{Accessing All Mutable JavaScript Objects Through Proxies} To be able to re-establish the system state with our versioning, our proxies need to be used to access all objects, arrays, and functions. This is necessary because objects, arrays, and functions are mutable in JavaScript. @@ -450,9 +447,9 @@ \subsubsection{Accessor Functions} \iffalse \end{verbatim}\fi -Wrapping the accessor function into the \lstinline{proxyFor} function would not yield valid JavaScript syntax. +Wrapping the accessor function into a call to the \lstinline{proxyFor} function would not yield valid JavaScript syntax. However, accessor functions can also be defined using the \lstinline{Object.defineProperty} function. -For this reason, the object is first created without accessor functions and the accessor function defined separately using \lstinline{Object.defineProperty} in our implementation. +For this reason, the object is first created without the accessor function and the function is added afterwards using \lstinline{Object.defineProperty}. Listing~\ref{lst:accessorTransformed} shows the result of transforming the example in Listing~\ref{lst:accessorOriginal} in this way. The object literal and the call to \lstinline{Object.defineProperty} are wrapped into an anonymous functions that is applied directly. This allows to have the object be available in a variable for the \lstinline{Object.defineProperty} function call without polluting the variable bindings of the originally surrounding scope. @@ -530,7 +527,7 @@ \subsection{Returning Proxies from Constructor Functions} These are not created from function literals and, therefore, cannot be proxied by transforming function literals. -\subsection{Wrapping Built-in Functions} +\subsection{Wrapping Built-in Functions Into Proxies} Some built-in functions can be used to create new objects. For example, the built-in constructors \lstinline{Object} and \lstinline{Array} can be used to create new objects and arrays. @@ -827,7 +824,7 @@ \section{Limitations of the Implementation} \paragraph{Availability of ECMAScript 6 Proxies} Our implementation requires the ECMAScript 6 proxies to be available. -The proxies are part of the next version of ECMAScript, which has currently neither been finalized nor completely implemented, as described in \ref{sec:IMPLEMENTATION:4}. +The proxies are part of the next version of ECMAScript, which has currently neither been finalized nor completely implemented, as described in Section~\ref{sec:IMPLEMENTATION:4}. For this reason, our implementation works only in versions of Firefox and Chrome that already implement preliminary versions of the proxies. Furthermore, Chrome users need to enable the proxies explicitly\footnote{\url{http://plus.google.com/+PaulIrish/posts/T615Md5JPQG}, accessed May 13, 2014}. diff --git a/content/6_evaluation.tex b/content/6_evaluation.tex index 5739399..16e1426 100755 --- a/content/6_evaluation.tex +++ b/content/6_evaluation.tex @@ -10,7 +10,6 @@ \section{Test Setup} \label{sec:EVALUATION:1} \subsection{Octane Benchmark Suite} -% what? We used the \emph{Octance} benchmark suite\footnote{\url{http://code.google.com/p/octane-benchmark/}, accessed February 3, 2014, at version 26} to evaluate the behavior and performance of our implementation. Octane consists of eight JavaScript benchmarks. It is a suite of real programs such as the \emph{DeltaBlue}~\cite{FreemanBenson1990ICS} constraint solver. @@ -18,7 +17,6 @@ \subsection{Octane Benchmark Suite} Octane is used for evaluating the performance of \emph{v8}, the engine used by Chrome and Node.js. It is part of v8's official source code repository\footnote{\url{http://v8.googlecode.com/svn/}, accessed April 23, 2014, at revision 20901}. -% why? We use Octane for three reasons: \begin{itemize} @@ -30,7 +28,6 @@ \subsection{Octane Benchmark Suite} \subsection{Lively Kernel} -% what? During the implementation of our approach, we tested our prototype continuously with the Lively Kernel. We developed our system in the Lively Kernel repository. @@ -39,7 +36,6 @@ \subsection{Lively Kernel} All modules loaded after these parts are transformed at load-time to enable versioning for them. This includes, for example, all classes of the Lively Kernel. -% why? We tested our implementation with the Lively Kernel for two reasons: \begin{itemize} @@ -50,12 +46,10 @@ \subsection{Lively Kernel} \subsection{Machine Configuration} -% what? All tests and measurements were done on May 9, 2014 using a Macbook Air with a 2 GHz Intel Core i7 and 8 GB main memory, Mac OS X 10.9.2, and version 34.0.1847.131 of Chrome. The presented measurement results were averaged over five runs. -% why? We used Chrome for all experiments as the Lively Kernel currently works best in Chrome. @@ -69,9 +63,7 @@ \subsection{Testing with Benchmarks} We ran the Octane benchmark suite to test the functionality of our implementation. \paragraph{Method} -% what was done? We transformed the Octane benchmarks with our source transformations, executed the resulting code, and then checked for JavaScript errors and compared the results of the transformed benchmarks to their usual results.\\ -% why / to test what? We did this to test two aspects. First, to test whether our source transformations yield syntactically correct JavaScript code for the benchmarks. Second, to test whether our proxy-based version-aware references, inserted by the source transformations, allow to run the benchmarks without errors and with the expected results. @@ -96,11 +88,9 @@ \subsection{Testing with the Lively Kernel} Moreover, we tested whether versions of its state can be preserved with our implementation. \paragraph{Method} -% what was done? We transformed the JavaScript modules of the Lively Kernel at load-time to test whether it loads and works correctly with our proxy-based version-aware references.\\ Furthermore, we tested whether the system allows re-establishing versions of the Lively Kernel's state in practice. Here, we tried multiple example scenarios, including the undo of changes to the state and behavior of basic morphs, morph compositions, and the state of more complicated graphical applications such as text editors and developer tools.\\ -% why / to test what? With this, we tested that the source transformations yield valid JavaScript code for the modules of the Lively Kernel, that the version-aware references delegate to the correct versions of objects, and that the version-aware references are used consistently. @@ -134,12 +124,9 @@ \subsection{Memory Overhead of Version-aware References} We measured how much more memory is required when loading the Lively Kernel with version-aware references. \paragraph{Method} -% what was done? We measured the memory required for loading a Lively Kernel world with and without version-aware references. We took heap snapshots right after the world was completely loaded without interacting with the system. We used an empty Lively Kernel world for this experiment and did not preserve any versions. -% why / to test what? -% We decided to use an empty Lively Kernel world to measure the minimal overhead, while we expect the add to grow linearly with the number of proxied objects. \paragraph{Results} As shown in Figure~\ref{fig:MemoryOverheadForReferences}, loading an empty Lively Kernel world requires three times more space with proxies than without proxies. @@ -160,18 +147,14 @@ \subsection{Memory Overhead of Version-aware References} In particular, it does not create proxies for objects that are present before our implementation of object versioning is loaded and all objects used by our implemenation itself. We expect the number of objects that are excluded from versioning to be relatively stable. All additional objects created at runtime will be accompanied by proxies.\\ -% Currently, the proxies are not optimized to consume as little space as possible. -% Two improvements of the current implementation would be to not create a dictionary for managing multiple versions as long as a proxy stands in for only one version and to have all proxy handler objects share their behavior. -% However, the memory overhead does not appear to be problematic at the moment. The memory overhead does not appear to be problematic at the moment. -\subsection{Memory Used When Preserving Versions} +\subsection{Memory Consumption When Preserving Versions} Besides the memory required for the version-aware references, memory is consumed when versions of the system are preserved. \subsubsection{Method} -% what? We measured how much memory is consumed when multiple versions of the system are preserved while working on a group of morphs. The three states for which we took snapshots are shown as \circnum{1}, \circnum{2}, and \circnum{3} in the upper half of Figure~\ref{fig:MemoryOverheadForVersions}. In particular, we did the following in this experiment: @@ -199,7 +182,7 @@ \subsubsection{Results} State \circnum{2} requires 1.8 MB more memory. It also requires 0.3 MB more memory than State \circnum{3}. -\begin{figure}[h!] +\begin{figure}[h] \centering \includegraphics[width=0.76\textwidth]{figures/6_evaluation/2_memoryForVersions.pdf} \caption{Memory consumed for three different states when the previous states are preserved in separate versions.} @@ -216,7 +199,7 @@ \subsubsection{Discussion} The results also show that the memory consumption does not always increase even when previous states are preserved: State \circnum{3} requires less memory than State \circnum{2}. One explanation for this is that not all objects are preserved with the versions. -One category of such objects are the objects that only provide access to the elements of the browser's \ac{dom}, as described in \ref{subsubsec:IMPLEMENTATION:5.2.1}. +One category of such objects are the objects that only provide access to the elements of the browser's \ac{dom}, as described in Section~\ref{subsubsec:IMPLEMENTATION:5.2.1}. \section{Practicability: Impact on Execution Speed} \label{sec:EVALUATION:4} @@ -225,7 +208,7 @@ \section{Practicability: Impact on Execution Speed} \label{sec:EVALUATION:4} A discussion of the results follows at the end of this section. -\subsection{Running Benchmarks} +\subsection{Execution of Benchmarks} The Octane benchmark suite shows how the proxies currently slow down a variety of different JavaScript programs.\\ A microbenchmarks shows the specific cost of having proxies forward object interactions. @@ -235,21 +218,21 @@ \subsubsection{Octane Benchmark Suite} Measuring the Octane benchmark suite highlights how the execution of eight JavaScript programs is affected by the proxies. \paragraph{Method} -We ran the Octane benchmarks\footnote{Note: We reduced the input size of the Splay benchmark by an order of magnitude to prevent the browser from prompting for user input during the benchmark's execution. The prompt is triggered due to the long time required to run the benchmark. It cannot be disabled and would influence the benchmark result.} with and without previous transformation of the benchmark code and, therefore, with or without version-aware references. +We ran the Octane benchmarks\footnote{Note: We reduced the input size of the Splay benchmark by an order of magnitude to prevent the browser from prompting for user input during the benchmark's execution. The prompt is triggered due to the long time required to run the benchmark. It cannot be disabled and would influence the benchmark result.} with and without previous transformation of the benchmark code and, therefore, with and without version-aware references. The source transformations for this were done separately before measuring the execution times. +\paragraph{Results} +Figure~\ref{fig:ExecutionOverhead} shows how much more time the benchmarks take when their source is transformed before execution and references are, therefore, version-aware. +Executing individual benchmarks takes between 90 and 405 times longer with version-aware references than without. +On average the execution is slowed down by a factor of 187.5. + \begin{figure}[h] \centering \includegraphics[width=\textwidth]{figures/6_evaluation/3_executionOverhead.pdf} - \caption{Execution overhead of proxy-based version-aware references for the Octane benchmark suite.} + \caption{Execution overhead for the Octane benchmark suite.} \label{fig:ExecutionOverhead} \end{figure} -\paragraph{Results} -Figure~\ref{fig:ExecutionOverhead} shows how much more time the benchmarks take when their source is transformed before execution and references are, therefore, version-aware. -Executing individual benchmarks takes between 90 and 405 times longer with version-aware references than without. -On average the execution is slowed down by a factor of 187.5. - \subsubsection{Microbenchmarks} @@ -257,7 +240,6 @@ \subsubsection{Microbenchmarks} In particular, the microbenchmark shows how much time the proxies require to intercept and forward property reads to the single version of an object. \paragraph{Method} -% We resolved a reference that connects a \lstinline{client} object to a \lstinline{server} object a million times to read and call a function property. We measured how long it takes to resolve a reference as well as read and call a function property a million times. The reference connects a \lstinline{client} object to a \lstinline{server} object. The code of which we measured the execution time is shown in Listing~\ref{lst:microbenchmark}. @@ -276,18 +258,12 @@ \subsubsection{Microbenchmarks} \begin{description} \item[Setup 1] The \lstinline{client} object holds a reference directly to the \lstinline{server}. - \item[Setup 2] The \lstinline{client} object holds a proxy as its \lstinline{server} property. In this setup, we used the proxy handler described in Section~\ref{sec:IMPLEMENTATION:1} for the proxy. The proxy has access to the actual \lstinline{server} object as one of its version objects. It selects the \lstinline{server} object when it intercepts the property read. + \item[Setup 2] The \lstinline{client} object holds a proxy as its \lstinline{server} property. In this setup, we used the proxy handler described in Section~\ref{subsec:IMPLEMENTATION:1.2} for the proxy. The proxy has access to the actual \lstinline{server} object as one of its version objects. It selects the \lstinline{server} object when it intercepts the property read. \item[Setup 3] The \lstinline{client} object's \lstinline{server} property is also a proxy but one created with a fixed target and without proxy handler. The fixed target is the \lstinline{server} object to which the proxy then forwards by default. \end{description} In all setups, the \lstinline{server} object holds a reference that directly refers to the \lstinline{foo} function. -% The \lstinline{client}'s reference is either an ordinary reference or version-aware. -% In the latter case, an ordinary reference refers from the \lstinline{client} to a proxy and that proxy forwards all object interactions to the \emph{server} object.\\ -% In a first version of this setup, we provided the handler object described in \ref{sec:IMPLEMENTATION:1} when creating the proxy, so the proxy provides our versioning behavior: it has no fixed target object, but chooses the \lstinline{server} object dynamically following the global version identifier.\\ -% In a second version of this microbenchmark, we provided no handler object when creating the proxy. -% In this case, the proxy falls back on the default proxy behavior, which is forwarding to a fixed target. -% The fixed target is the \lstinline{server} object. \paragraph{Results} Table~\ref{table:microbenchmarkResults} shows the results of running the microbenchmark in the three setups. @@ -318,27 +294,24 @@ \subsubsection{Typical Lively Kernel Interactions} As our goal is to provide recovery support for development in Lively Kernel, the overhead imposed on user interactions is especially interesting as it directly affects developers. \paragraph{Method} -% what? We measured the time three user interactions take when using proxies and compared this to the time the interactions usually take. We measured the time from the user events until the single-threaded JavaScript engine becomes responsive again programmatically. The three typical interaction we chose to investigate are: bringing up the halo buttons on a particular morph, opening the Lively Kernel's main menu, and opening the Lively Kernel's System Code Browser.\\ -% why? We chose these three interactions as we expect them to be more impacted by the version-aware references compared to interactions that are more browser-supported and less reliant on the execution of JavaScript code such as dragging elements around the screen. All three interaction trigger code from multiple different modules, including event handling code, rendering code, and tool-specific code. \begin{figure}[h!] \centering - \includegraphics[width=0.8\textwidth]{figures/6_evaluation/4_LivelyInteractionsOverhead.pdf} + \includegraphics[width=0.76\textwidth]{figures/6_evaluation/4_LivelyInteractionsOverhead.pdf} \caption{Execution overhead for three user interactions in the Lively Kernel.} \label{fig:LivelyInteractionsOverhead} \end{figure} \paragraph{Results} -Figure \ref{fig:LivelyInteractionsOverhead} shows the results. +Figure~\ref{fig:LivelyInteractionsOverhead} shows the results. Each of the three interactions takes on average 43 times the time when triggered after the system was loaded with proxies. - \subsubsection{Loading a Lively Kernel World} Another performance-related question specific to the Lively Kernel is how long it takes to load a world with proxies. diff --git a/content/7_related_work.tex b/content/7_related_work.tex index 47f92f0..3d96e09 100755 --- a/content/7_related_work.tex +++ b/content/7_related_work.tex @@ -4,7 +4,7 @@ \chapter{Related Work} \label{chapter:RELATED_WORK} \begin{enumerate} \item Approaches related to our motivation and, thus, to providing access to previous versions of the system state. - \item Approaches related to technical solution and, thus, to combining changes into first-class objects that can be used to scope changes dynamically. + \item Approaches related to our technical solution and, thus, to combining changes into first-class objects that can be used to scope changes. \end{enumerate} diff --git a/content/9_summary.tex b/content/9_summary.tex index 252fe91..bfe787d 100755 --- a/content/9_summary.tex +++ b/content/9_summary.tex @@ -10,21 +10,21 @@ \chapter{Summary} \label{chapter:SUMMARY} We presented a design for our approach that uses proxies for version-aware references. Instead of actually using alternative references, ordinary references refer to proxies and proxies forward all interactions transparently to the right versions. The design allows implementing version-aware references without any adaptions to existing execution engines---neither for alternative references nor for the garbage collection of versions.\\ -For each new object that is created, a proxy is created and returned instead of the new object. +For each object that is created, a proxy is created and returned instead of the object. Thus, references to proxies are passed around and all access goes through the proxies. Moreover, only the proxies refer to the versions of an object. -Consequentely, all versions of an object are reclaimed together with their proxy by the ordinary garbage collector.\\ +Consequentely, the versions of an object are reclaimed together with their proxy by the ordinary garbage collector.\\ Returning proxies for new objects is achieved using source transformations. -Program sources are transformed when loaded and do not have to be adapted manually. +The program sources are transformed when loaded and do not have to be adapted manually. % Significance, Practical applications We implemented our approach to object versioning in JavaScript. -It allows preserving and re-establishing versions of systems. -The implementation is optimized for fine-grained histories.\\ +The implementation allows preserving and re-establishing versions of the system's state. +It is optimized for fine-grained histories.\\ To switch the version of the system, only a global version identifier has to be changed. Using this identifier, the proxies choose versions of objects dynamically. -This way, it is not necessary to re-configure all proxies for switching versions.\\ -To preserve versions of the system, the proxies copy object versions on write: When a proxy intercepts a write operation in a \emph{system version} for which no \emph{object version} exists, it copies a previous \emph{object version}. +This way, it is not necessary to re-configure all proxies to switch versions.\\ +To preserve versions of the system, the proxies copy object versions on writes: When a proxy intercepts a mutating operation to an object for which no current version exists, it copies a previous version of the object. Until then, proxies reuse object versions from previous system versions. We integrated our implementation into the Lively Kernel and made it work with our version-aware references. diff --git a/thesis.bib b/thesis.bib index eaa6f73..a839cff 100644 --- a/thesis.bib +++ b/thesis.bib @@ -1844,7 +1844,7 @@ @techreport{Kay2005Etoys month = {February}, url = {http://www.vpri.org/pdf/rn2005002_authoring.pdf}, publisher = {{Viewpoints Research Institute}}, - note = {Retrieved March 7, 2014, at \url{http://www.vpri.org/pdf/rn2005002_authoring.pdf}}, + note = {Published February 2005. Available at \url{http://www.vpri.org/pdf/rn2005002_authoring.pdf}. Accessed March 7, 2014.}, month = {February} } @@ -2139,7 +2139,7 @@ @misc{Ecma2014ES6 author = {{Ecma/TS39}}, title = {{ECMAScript Language Specification (Draft for 6th Edition)}}, year = {2014}, - note = {Published April 27, 2014 (Draft, Revision 24). Available at \url{http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts}, accessed May 11, 2014.} + note = {Published April 27, 2014 (Draft, Revision 24). Available at \url{http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts}. Accessed May 11, 2014.} } @inproceedings{Denker2007EEC,