<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>alert debugging &#187; Objective-J</title>
	<atom:link href="http://www.alertdebugging.com/tag/objective-j/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alertdebugging.com</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Thu, 05 Nov 2009 11:50:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Building a Better JavaScript Profiler with WebKit</title>
		<link>http://www.alertdebugging.com/2009/04/29/building-a-better-javascript-profiler-with-webkit/</link>
		<comments>http://www.alertdebugging.com/2009/04/29/building-a-better-javascript-profiler-with-webkit/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 20:14:13 +0000</pubDate>
		<dc:creator>tolmasky</dc:creator>
				<category><![CDATA[Cappuccino]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[debugging]]></category>
		<category><![CDATA[Objective-J]]></category>
		<category><![CDATA[WebKit]]></category>

		<guid isPermaLink="false">http://www.alertdebugging.com/?p=18</guid>
		<description><![CDATA[I had the pleasure of showing off some the cool new features we&#8217;ve been adding to the WebKit inspector at JSConf last week. It&#8217;s no secret that debugging basically sucks in JavaScript, and until recently, it was a little bit worse in Objective-J. Up until now we&#8217;ve focused mainly on adding stop gap measures to [...]]]></description>
			<content:encoded><![CDATA[<p>I had the pleasure of showing off some the cool new features we&#8217;ve been adding to the WebKit inspector at <a href="http://www.jsconf2009.com/">JSConf</a> last week. It&#8217;s no secret that debugging basically sucks in JavaScript, and until recently, it was a little bit worse in <a href="http://cappuccino.org">Objective-J</a>. Up until now we&#8217;ve focused mainly on adding stop gap measures to our own code, but recently we&#8217;ve decided to shift gears and attack the problem head on in the browsers themselves. This is why these past couple of weeks I&#8217;ve set aside the JavaScript code and instead focused on working with the great guys on the WebKit team on providing a solid debugging experience both in Objective-J and JavaScript in general. We first decided to focus on profiling, since this is an area of considerable interest for a framework. All the code I&#8217;ve committed is now available in the latest WebKit nightly, so if you want you can <a href="http://nightly.webkit.org/">download</a> it to follow along. I&#8217;ve also added to the end of this post links to both the WebKit commits we added, as well as the accompanying code we put in Cappuccino in an effort to show how to make the best use of these new features and encourage others to take a stab at adding some debugging features to WebKit. Surprisingly enough, the folks over at <a href="http://joose-js.blogspot.com/">Joose</a> wasted no time incorporating this into their own library, so I&#8217;ve included links to their additions as well.</p>
<h2>Anonymous and Poorly Named Functions</h2>
<p>Had you run a Cappuccino application through Firebug&#8217;s profiler back in September when we originally open sourced the framework, you would have probably seen something that looked like this:</p>
<div id="attachment_44" class="wp-caption aligncenter" style="width: 387px"><img class="size-full wp-image-44" title="Anonymous Functions in Firebug" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/firebug-anonymous.png" alt="Anonymous Functions in Firebug" width="377" height="252" /><p class="wp-caption-text">Anonymous Functions in Firebug</p></div>
<p>Anyone who&#8217;s done a significant amount of profiling with Firebug has probably run into the dreaded question mark functions at some point or another, but as you can see from above, it used to be particularly egregious in Objective-J. The reason these question marks show up is because somewhere the script in question contains an <strong>anonymous function</strong>. Anonymous functions, or lambdas as they&#8217;re sometimes referred to, are functions that you can declare just about anywhere in your program and not bother naming. Take the following code for example:<br />
<!-- First Code Snippet --></p>
<pre class="textmate-source"><span class="source source_js"><span class="support support_class support_class_js">document</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>addEventListener<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>click<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span> <span class="comment comment_block comment_block_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">/*</span>...<span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">*/</span></span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="constant constant_language constant_language_boolean constant_language_boolean_false constant_language_boolean_false_js">false</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p><!-- End First Code Snippet --></p>
<p>Here we&#8217;re using an anonymous function to perform special behavior on a mouse click event, and when profiled, this function will show up as a question mark. The obvious workaround is to simply declare this function normally somewhere else in the code, but this isn&#8217;t always possible because you might need it inline in the code so as to form a closure. So instead the recommended solution today is to simply give it a name with the following syntax:</p>
<p><!--Second Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="support support_class support_class_js">document</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>addEventListener<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>click<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">clicked</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span> <span class="comment comment_block comment_block_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">/*</span>...<span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">*/</span></span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="constant constant_language constant_language_boolean constant_language_boolean_false constant_language_boolean_false_js">false</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p><!--End Second Code Snippet-->And in this particular case, this will work quite well and allow this function to appear in profile as <span class="inline-code">clicked</span>. However, there are certain cases where this won&#8217;t work. Let&#8217;s look at a different snippet of code to see such a case:</p>
<p><!-- Third Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">generator</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">/*Number*/ iterations</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="keyword keyword_control keyword_control_js">return</span> <span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span>
    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
        <span class="keyword keyword_control keyword_control_js">for</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">var</span> i <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="constant constant_numeric constant_numeric_js">0</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i <span class="keyword keyword_operator keyword_operator_js">&lt;</span> iterations<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="keyword keyword_operator keyword_operator_js">++</span>i<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> do something
</span>    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!-- End Third Code Snippet-->Here we&#8217;ve created a function called <span class="inline-code">generator</span> that creates other functions when executed. As is, these functions will show up as question marks just as before, but this time we can&#8217;t simply name them inline because then <strong>all</strong> the generated functions would show up with the exact same name:<br />
<!-- Fourth Code Snippet --></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">generator</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">/*Number*/ iterations</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="keyword keyword_control keyword_control_js">return</span> <span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">iterate</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
        <span class="keyword keyword_control keyword_control_js">for</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">var</span> i <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="constant constant_numeric constant_numeric_js">0</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i <span class="keyword keyword_operator keyword_operator_js">&lt;</span> iterations<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="keyword keyword_operator keyword_operator_js">++</span>i<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> do something
</span>    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!-- End Fourth Snippet-->Unfortunately, there is really very little we can do to remedy this situation short of using an eval statement, which would change the performance characteristics of this method so drastically that the entire exercise would become moot. It&#8217;s not just floating anonymous functions that suffer from poor naming though. Imagine that you have created the following prototypal classes and methods in your application or library:<br />
<!--Fifth Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyClass</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass class method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_prototype meta_function_prototype_js"><span class="support support_class support_class_js">MyClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_prototype meta_function_prototype_js"><span class="support support_class support_class_js">MyOtherClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyOtherClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!--End Fifth Code Snippet-->Both in Firebug and Safari, this code will generate a largely useless profile:</p>
<div id="attachment_113" class="wp-caption aligncenter" style="width: 387px"><img class="size-full wp-image-113" title="Profiling object methods in Firebug or Safari" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/picture-12-copy1.png" alt="Profiling object methods in Firebug or Safari" width="377" height="165" /><p class="wp-caption-text">Profiling object methods in Firebug or Safari</p></div>
<p>This profile is almost as ambiguous as when it was all question marks. We can&#8217;t tell whether <span class="inline-code">MyClass.myMethod</span>, <span class="inline-code">MyClass.prototype.myMethod</span>, or <span class="inline-code">MyOtherClass.prototype.myMethod</span> is the bottleneck here. If we aren&#8217;t generating these methods in any special way, we could try to name them inline, but we&#8217;d have to mangle the names considerably to pack in all the information we need:<!--Sixth Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js">MyClass<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span><span class="support support_constant support_constant_dom support_constant_dom_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">$_MyClass__class__method</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass class method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">$_MyClass__method</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyOtherClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">$_MyOtherClass__method</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyOtherClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!--End Sixth Code Snippet-->This is clearly not the most elegant solution, and doesn&#8217;t scale given the fact that you have limited visual room in Firebug and Safari (you actually can&#8217;t stretch the function name column in either profiler). This also runs the risk, albeit a small one, of clashing with an existing function name. But the important thing to notice here is that it is not necessarily anonymous functions that are the source of the problem, but the fact that functions don&#8217;t <strong>actually</strong> have real names in JavaScript. It is only the variables that are bound to them that are named. So in order to solve this issue once and for all, we decided to define a way to explicitly give functions a name for debugging: the <strong>displayName</strong> attribute. In WebKit, you can now simply set this property with any arbitrary name you desire. Let&#8217;s revisit our <span class="inline-code">generator</span> example from earlier and see what we can do with this slightly modified code:<br />
<!--Seventh Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="storage storage_type storage_type_function storage_type_function_js">function</span> <span class="entity entity_name entity_name_function entity_name_function_js">generator</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">/*Number*/ iterations</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="storage storage_type storage_type_js">var</span> <span class="meta meta_function meta_function_js"><span class="entity entity_name entity_name_function entity_name_function_js">generated</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
        <span class="keyword keyword_control keyword_control_js">for</span> <span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">var</span> i <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="constant constant_numeric constant_numeric_js">0</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> i <span class="keyword keyword_operator keyword_operator_js">&lt;</span> iterations<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span> <span class="keyword keyword_operator keyword_operator_js">++</span>i<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
            <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> do something
</span>    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

    generated<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>displayName <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>iterating <span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span> <span class="keyword keyword_operator keyword_operator_js">+</span> iterations <span class="keyword keyword_operator keyword_operator_js">+</span> <span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span> times<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>

    <span class="keyword keyword_control keyword_control_js">return</span> generated<span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span></span></pre>
<p><!--End Seventh Code Snippet--><br />
If we now rerun this profile in a recent WebKit nightly, we should see something like this:</p>
<div id="attachment_104" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-104" title="Explicitly named functions in WebKit Profiles" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/untitled-4.png" alt="Explicitly named functions in WebKit Profiles" width="516" height="184" /><p class="wp-caption-text">Explicitly named functions in WebKit Profiles</p></div>
<p>Each function is now clearly identifiable in the results, allowing us to actually make use of this data. We can extend this same approach to our prototypal classes we defined above to achieve a similar effect:<br />
<!--Eighth Code Snippet--></p>
<pre class="textmate-source"><span class="source source_js"><span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyClass</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass class method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

MyClass<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span><span class="support support_constant support_constant_dom support_constant_dom_js">method</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>displayName <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>MyClass.method (class)<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>

<span class="meta meta_function meta_function_prototype meta_function_prototype_js"><span class="support support_class support_class_js">MyClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method.displayName</span> <span class="keyword keyword_operator keyword_operator_js">=</span> </span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>MyClass.method<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>

<span class="meta meta_function meta_function_prototype meta_function_prototype_js"><span class="support support_class support_class_js">MyOtherClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span>
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> MyOtherClass instance method
</span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span>

<span class="meta meta_function meta_function_js"><span class="support support_class support_class_js">MyOtherClass</span>.<span class="support support_constant support_constant_js">prototype</span>.<span class="entity entity_name entity_name_function entity_name_function_js">method.displayName</span> <span class="keyword keyword_operator keyword_operator_js">=</span> </span><span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>MyOtherClass.method<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">"</span></span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>
<p><!--End Eighth Code Snippet-->If we were to profile this now, the much more descriptive displayNames would show up instead of simply seeing <span class="inline-code">method()</span> used in every case. This is the basic idea behind what Objective-J does in the latest Cappuccino 0.7 betas, but it takes place completely automatically behind the scenes, so that with no code changes of your own, applications now look something like this when profiled:</p>
<div id="attachment_102" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-102" title="Profiling Objective-J in WebKit" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/picture-82.png" alt="Profiling Objective-J in WebKit" width="516" height="313" /><p class="wp-caption-text">Profiling Objective-J in WebKit</p></div>
<p>As you can see from this profile, Objective-J now has first class profiling support in WebKit. The best part about this though is that it&#8217;s not just limited to Objective-J: any language abstraction now has the opportunity to make the same use of these tools. Objective-J happens to be a great candidate because it is such a thin wrapper around JavaScript, but a project such as processing.js could show the actual processing functions instead of their generated JavaScript analogues, or perhaps GWT could have a flag where it shows the Java methods in the profiler instead of the generated JavaScript as well. We&#8217;ve actually taken this one step further in Objective-J though, and used this feature to display information that you actually can&#8217;t presently see with normal JavaScript scripts. Currently both Safari and Firebug are incapable of profiling code that doesn&#8217;t execute explicitly in a function. This means that if a good portion of your profile is taking place at the top level of a script file, it will be completely left out in Firebug and lumped into the overly generic <span class="inline-code">(program)</span> category in Safari. But thanks to the special way we handle files in Objective-J, we are able to tell our users precisely how much time they are spending in a specific file:</p>
<div id="attachment_107" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-107" title="Objective-J is smart about files in profiles" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/files.png" alt="Objective-J is smart about files in profiles" width="516" height="186" /><p class="wp-caption-text">Objective-J profiling is smart about files in WebKit</p></div>
<p>This is actually what I found most exciting about this seemingly simple property addition. In less than a day I was able to apply it in a completely new way to supply WebKit with even more information than we had originally designed it for. I feel that there is something really interesting in the idea that the code can interact directly with the debugging tools, and its why I believe that despite the debugging situation being so poor in JavaScript today, it has the potential of being much better than that of traditional languages. Expect to see us experiment more with this new kind of debugging here at <a href="http://280north.com">280 North</a> in the future, because this is clearly just the tip of the iceberg.</p>
<h2>More Fine-Grained Profiling</h2>
<p>The other thing we focused heavily on doing these last couple of weeks was completely rewriting the Bottom Up View of the WebKit profiler. To get a better idea of what this is, lets first take look at the other alternative WebKit currently gives you for analyzing your profiles, known as the Top Down View:</p>
<div id="attachment_147" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-147" title="Top Down View in WebKit" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/tree-view.png" alt="Top Down View in Safari" width="516" height="177" /><p class="wp-caption-text">Top Down View in WebKit</p></div>
<p>The Top Down View shows you a graph of the actual flow of your application, a call stack with the very first functions that were executed as the root nodes and the functions they called as their children. Thus, the data in each row represents the statistics for the call stack starting with the root node, and ending in the child node. I&#8217;ve fully expanded all the nodes here to be able to see the entire call graph. If we look at the second to last line of this view, we can see that it represents a recursive call to <span class="inline-code">aFunction</span> that took place from within a call to <span class="inline-code">caller3</span>:</p>
<div id="attachment_186" class="wp-caption aligncenter" style="width: 464px"><img class="size-full wp-image-186" title="Call stack represented in Top Down View" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/picture-9.png" alt="Call stack represented in Top Down View" width="454" height="137" /><p class="wp-caption-text">Call stack represented in Top Down View</p></div>
<p>We&#8217;d read this by saying that 0.41% of the time was spent in 5 calls to <span class="inline-code">aFunction</span> with this call stack. While this representation of your profile certainly gives you a very holistic view of what happened in your program and can help you get a better idea of the general flow of functions taking place, it&#8217;s harder to draw conclusions such as which function most of the time is being spent in. To do this, we would need to add up all the individual child times and then compare them to eachother. In this simple example this doesn&#8217;t seem that daunting, but you can imagine that it can quickly become quite complex.</p>
<p>This is where the Bottom Up View comes in. Let&#8217;s take a look at the same profile using this view:</p>
<div id="attachment_143" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-143" title="Bottom Up View Collapsed" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/heavy-collapsed.png" alt="Bottom Up View Collapsed" width="516" height="177" /><p class="wp-caption-text">Bottom Up View Collapsed</p></div>
<p>If we leave the children collapsed, this should look very familiar to Firebug users: it is a flat list of every function called in your program, and how much time was spent in each. However, where things really get interesting is when you expand the children:</p>
<div id="attachment_144" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-144" title="Bottom Up View Expanded" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/heavy-expanded.png" alt="Bottom Up View Expanded" width="516" height="177" /><p class="wp-caption-text">Bottom Up View Expanded</p></div>
<p>Unlike in the Top Down View, the children here represent the parents, or callers, of the root function in question. For example, the second row represents the call stack <strong>starting</strong> at <span class="inline-code">caller3</span> and <strong>ending</strong> at <span class="inline-code">aFunction</span>:</p>
<div id="attachment_187" class="wp-caption aligncenter" style="width: 296px"><img class="size-full wp-image-187" title="The call stack represented in the Bottom Up View" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/picture-10.png" alt="The call stack represented in the Bottom Up View" width="286" height="125" /><p class="wp-caption-text">The call stack represented in the Bottom Up View</p></div>
<p>Because of this, the statistics on each row actually still refer to the original root node, and not the child as in the Top Down View. So on the second row you&#8217;d say &#8220;1000 calls to aFunction took place <strong>originating from</strong> caller3&#8243;. Essentially we are just flipping the Top Down View on its head. In order to understand why this information is so powerful, let&#8217;s take a look at a real world example I recently ran into in Cappuccino. Now, the following is an Objective-J profile, but the principles are exactly the same in normal JavaScript:</p>
<div id="attachment_133" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-133" title="Objective-J Profile in Bottom Up View" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/collapsed.png" alt="Objective-J Profile in Bottom Up View" width="516" height="313" /><p class="wp-caption-text">Objective-J Profile in Bottom Up View</p></div>
<p>If we were using Firebug or any other flat listing tool, the naive interpretation of this profile would be that <span class="inline-code">setFrameSize:</span> is probably something worth tuning since it is third on our list and takes about 4.58% of our profile&#8217;s total time. This diagnosis is not wrong in the strict sense, but we may find it difficult to find out exactly why this method is so slow if we simply jump into <span class="inline-code">setFrameSize:</span>&#8217;s implementation and start hacking away.  Remember that functions can be quite complex internally as well, and you may spend your time needlessly optimizing a code path in this method that was not even reached during the profile. However, we may get a better idea if we instead inspect this further and look at <span class="inline-code">setFrameSize:</span>&#8217;s callers:</p>
<div id="attachment_138" class="wp-caption aligncenter" style="width: 526px"><img class="size-full wp-image-138" title="Examining setFrameSize:'s callers" src="http://www.alertdebugging.com/wp-content/uploads/2009/04/expanded1.png" alt="Examining setFrameSize:'s callers" width="516" height="313" /><p class="wp-caption-text">Examining setFrameSize:</p></div>
<p>Interestingly enough, after expanding this node we find that it is not necessarily <span class="inline-code">setFrameSize:</span> which is universally slow, but rather some special interaction between <span class="inline-code">setFrameSize:</span> and its caller <span class="inline-code">sizeToFit</span>. We know this because this method usually takes an average of 0.01% to 0.04%, but specifically when called from <span class="inline-code">sizeToFit</span> it takes a whopping 4.34%, over 200 times as long. Not only that, but all this time is concentrated in just 1 actual call, profiling gold! Perhaps there is something in <span class="inline-code">sizeToFit</span> that is purging a cache that <span class="inline-code">setFrameSize:</span> relies on, or perhaps <span class="inline-code">sizeToFit</span> causes <span class="inline-code">setFrameSize:</span> to take a completely different code path internally than normal. It could be any number of reasons, but we are now empowered with a much better understanding of what exactly is happening in the program that is causing this slowdown. In other words, this allows us to profile not only the functions themselves, but the relationship between functions as well.</p>
<h2>What&#8217;s Next?</h2>
<p>Debugging in JavaScript still has a long way to go. These changes are like night and day for frameworks like Cappuccino, but we have a bunch of other ideas we&#8217;d like to get implemented in WebKit&#8217;s inspector as well. We also think its important to try to take some of the work we&#8217;ve done here and get it placed into Firebug. Given that there is no one browser your code will run in, it is important to have a great set of tools on as many browsers as possible. We&#8217;ve used a hacked version of Firebug internally before, and if I recall correctly it shouldn&#8217;t be too difficult to add support for the displayName property to function objects, so hopefully we&#8217;ll get a patch out for that soon.</p>
<h2>Addendum</h2>
<p>As promised earlier, I have included a list of links to the WebKit, Cappuccino, and Joose commits below. The Cappuccino and Joose commits should help you integrate support for these new WebKit features in your own application or library, and hopefully the WebKit commits will inspire you to report/fix/write new features for JavaScript debugging:</p>
<h3>WebKit</h3>
<ul>
<li><a href="http://trac.webkit.org/changeset/42808">Bottom Up View Re-implementation</a></li>
<li><a href="http://trac.webkit.org/changeset/42478">function.displayName property</a></li>
</ul>
<h3>Cappuccino</h3>
<ul>
<li><a href="http://github.com/280north/cappuccino/commit/0e8e725f59daa041ebfed84d7173e39499617e25">Displaying Objective-J methods in the WebKit profiler</a></li>
<li><a href="http://github.com/280north/cappuccino/commit/2f790c650338e235bab0af749a5a11edb3282704">Displaying files in the WebKit profiler</a></li>
</ul>
<h3>Joose</h3>
<ul>
<li><a href="http://code.google.com/p/joose-js/source/detail?r=756#">Support for function.displayName</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.alertdebugging.com/2009/04/29/building-a-better-javascript-profiler-with-webkit/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
	</channel>
</rss>
