<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[172777] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/172777">172777</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2014-08-19 16:25:37 -0700 (Tue, 19 Aug 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>LLInt build should be way faster
https://bugs.webkit.org/show_bug.cgi?id=136085

Reviewed by Geoffrey Garen.
        
This does three things to improve the LLInt build performance. One of them is only for
Xcode for now while the others should benefit all platforms:
        
- Don't exponentially build settings combinations that correspond to being on two backends
  simultaneously. This is by far the biggest win.
        
- Don't generate offset extraction code for backends that aren't supported by the current
  port. This currently only works on Xcode-based ports. This is a relatively small win.
        
- Remove the ALWAYS_ALLOCATE_SLOW option. Each option increases build time, and we haven't
  used this one in a long time. Anyway, setting this option could be emulated by just
  directly hacking the code.
        
This is an enormous speed-up in the LLInt build.

* JavaScriptCore.xcodeproj/project.pbxproj: Prune the set of backends that we should consider on Xcode-based platforms.
* llint/LLIntOfflineAsmConfig.h: Remove ALWAYS_ALLOCATE_SLOW
* llint/LowLevelInterpreter.asm: Remove ALWAYS_ALLOCATE_SLOW
* offlineasm/backends.rb: Add infrastructure for reasoning about valid backends.
* offlineasm/generate_offset_extractor.rb: Allow the client to specify a filtered set of valid backends.
* offlineasm/settings.rb: Improve the construction of settings combinations so that it doesn't traverse the enourmous set of obviously invalid multi-backend combinations. Also glue into support for valid backends.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntOfflineAsmConfigh">trunk/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmbackendsrb">trunk/Source/JavaScriptCore/offlineasm/backends.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmgenerate_offset_extractorrb">trunk/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoreofflineasmsettingsrb">trunk/Source/JavaScriptCore/offlineasm/settings.rb</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (172776 => 172777)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-08-19 23:20:37 UTC (rev 172776)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-08-19 23:25:37 UTC (rev 172777)
</span><span class="lines">@@ -1,5 +1,34 @@
</span><span class="cx"> 2014-08-19  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        LLInt build should be way faster
+        https://bugs.webkit.org/show_bug.cgi?id=136085
+
+        Reviewed by Geoffrey Garen.
+        
+        This does three things to improve the LLInt build performance. One of them is only for
+        Xcode for now while the others should benefit all platforms:
+        
+        - Don't exponentially build settings combinations that correspond to being on two backends
+          simultaneously. This is by far the biggest win.
+        
+        - Don't generate offset extraction code for backends that aren't supported by the current
+          port. This currently only works on Xcode-based ports. This is a relatively small win.
+        
+        - Remove the ALWAYS_ALLOCATE_SLOW option. Each option increases build time, and we haven't
+          used this one in a long time. Anyway, setting this option could be emulated by just
+          directly hacking the code.
+        
+        This is an enormous speed-up in the LLInt build.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj: Prune the set of backends that we should consider on Xcode-based platforms.
+        * llint/LLIntOfflineAsmConfig.h: Remove ALWAYS_ALLOCATE_SLOW
+        * llint/LowLevelInterpreter.asm: Remove ALWAYS_ALLOCATE_SLOW
+        * offlineasm/backends.rb: Add infrastructure for reasoning about valid backends.
+        * offlineasm/generate_offset_extractor.rb: Allow the client to specify a filtered set of valid backends.
+        * offlineasm/settings.rb: Improve the construction of settings combinations so that it doesn't traverse the enourmous set of obviously invalid multi-backend combinations. Also glue into support for valid backends.
+
+2014-08-19  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
</ins><span class="cx">         Fix indentation and style in LowLevelInterpreter.asm
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=136083
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (172776 => 172777)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-08-19 23:20:37 UTC (rev 172776)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2014-08-19 23:25:37 UTC (rev 172777)
</span><span class="lines">@@ -6788,7 +6788,7 @@
</span><span class="cx">                         );
</span><span class="cx">                         runOnlyForDeploymentPostprocessing = 0;
</span><span class="cx">                         shellPath = /bin/sh;
</span><del>-                        shellScript = &quot;set -e\n\nmkdir -p \&quot;${BUILT_PRODUCTS_DIR}/LLIntOffsets/\&quot;\n\n/usr/bin/env ruby \&quot;${SRCROOT}/offlineasm/generate_offset_extractor.rb\&quot; \&quot;-I${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\&quot; \&quot;${SRCROOT}/llint/LowLevelInterpreter.asm\&quot; \&quot;${BUILT_PRODUCTS_DIR}/LLIntOffsets/LLIntDesiredOffsets.h\&quot;\n&quot;;
</del><ins>+                        shellScript = &quot;set -e\n\nmkdir -p \&quot;${BUILT_PRODUCTS_DIR}/LLIntOffsets/\&quot;\n\n/usr/bin/env ruby \&quot;${SRCROOT}/offlineasm/generate_offset_extractor.rb\&quot; \&quot;-I${BUILT_PRODUCTS_DIR}/DerivedSources/JavaScriptCore\&quot; \&quot;${SRCROOT}/llint/LowLevelInterpreter.asm\&quot; \&quot;${BUILT_PRODUCTS_DIR}/LLIntOffsets/LLIntDesiredOffsets.h\&quot; \&quot;X86,X86_64,ARMv7,ARMv7s,ARM64,C_LOOP\&quot;\n&quot;;
</ins><span class="cx">                 };
</span><span class="cx">                 0FCEFAD91806191800472CE4 /* Copy LLVM Library Into Framework */ = {
</span><span class="cx">                         isa = PBXShellScriptBuildPhase;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntOfflineAsmConfigh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h (172776 => 172777)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h        2014-08-19 23:20:37 UTC (rev 172776)
+++ trunk/Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h        2014-08-19 23:25:37 UTC (rev 172777)
</span><span class="lines">@@ -154,12 +154,6 @@
</span><span class="cx"> #define OFFLINE_ASM_EXECUTION_TRACING 0
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if LLINT_ALWAYS_ALLOCATE_SLOW
-#define OFFLINE_ASM_ALWAYS_ALLOCATE_SLOW 1
-#else
-#define OFFLINE_ASM_ALWAYS_ALLOCATE_SLOW 0
-#endif
-
</del><span class="cx"> #if ENABLE(GGC)
</span><span class="cx"> #define OFFLINE_ASM_GGC 1
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (172776 => 172777)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-08-19 23:20:37 UTC (rev 172776)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2014-08-19 23:25:37 UTC (rev 172777)
</span><span class="lines">@@ -658,25 +658,21 @@
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro allocateJSObject(allocator, structure, result, scratch1, slowCase)
</span><del>-    if ALWAYS_ALLOCATE_SLOW
-        jmp slowCase
-    else
-        const offsetOfFirstFreeCell = 
-            MarkedAllocator::m_freeList + 
-            MarkedBlock::FreeList::head
</del><ins>+    const offsetOfFirstFreeCell = 
+        MarkedAllocator::m_freeList + 
+        MarkedBlock::FreeList::head
</ins><span class="cx"> 
</span><del>-        # Get the object from the free list.   
-        loadp offsetOfFirstFreeCell[allocator], result
-        btpz result, slowCase
-        
-        # Remove the object from the free list.
-        loadp [result], scratch1
-        storep scratch1, offsetOfFirstFreeCell[allocator]
</del><ins>+    # Get the object from the free list.   
+    loadp offsetOfFirstFreeCell[allocator], result
+    btpz result, slowCase
</ins><span class="cx">     
</span><del>-        # Initialize the object.
-        storep 0, JSObject::m_butterfly[result]
-        storeStructureWithTypeInfo(result, structure, scratch1)
-    end
</del><ins>+    # Remove the object from the free list.
+    loadp [result], scratch1
+    storep scratch1, offsetOfFirstFreeCell[allocator]
+
+    # Initialize the object.
+    storep 0, JSObject::m_butterfly[result]
+    storeStructureWithTypeInfo(result, structure, scratch1)
</ins><span class="cx"> end
</span><span class="cx"> 
</span><span class="cx"> macro doReturn()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmbackendsrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/backends.rb (172776 => 172777)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/backends.rb        2014-08-19 23:20:37 UTC (rev 172776)
+++ trunk/Source/JavaScriptCore/offlineasm/backends.rb        2014-08-19 23:25:37 UTC (rev 172777)
</span><span class="lines">@@ -67,6 +67,37 @@
</span><span class="cx"> 
</span><span class="cx"> BACKEND_PATTERN = Regexp.new('\\A(' + BACKENDS.join(')|(') + ')\\Z')
</span><span class="cx"> 
</span><ins>+$allBackends = {}
+$validBackends = {}
+BACKENDS.each {
+    | backend |
+    $validBackends[backend] = true
+    $allBackends[backend] = true
+}
+
+def includeOnlyBackends(list)
+    newValidBackends = {}
+    list.each {
+        | backend |
+        if $validBackends[backend]
+            newValidBackends[backend] = true
+        end
+    }
+    $validBackends = newValidBackends
+end
+
+def isBackend?(backend)
+    $allBackends[backend]
+end
+
+def isValidBackend?(backend)
+    $validBackends[backend]
+end
+
+def validBackends
+    $validBackends.keys
+end
+
</ins><span class="cx"> class Node
</span><span class="cx">     def lower(name)
</span><span class="cx">         begin
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmgenerate_offset_extractorrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb (172776 => 172777)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb        2014-08-19 23:20:37 UTC (rev 172776)
+++ trunk/Source/JavaScriptCore/offlineasm/generate_offset_extractor.rb        2014-08-19 23:25:37 UTC (rev 172777)
</span><span class="lines">@@ -39,6 +39,12 @@
</span><span class="cx"> inputFlnm = ARGV.shift
</span><span class="cx"> outputFlnm = ARGV.shift
</span><span class="cx"> 
</span><ins>+validBackends = ARGV.shift
+if validBackends
+    $stderr.puts &quot;Only dealing with backends: #{validBackends}&quot;
+    includeOnlyBackends(validBackends.split(&quot;,&quot;))
+end
+
</ins><span class="cx"> $stderr.puts &quot;offlineasm: Parsing #{inputFlnm} and creating offset extractor #{outputFlnm}.&quot;
</span><span class="cx"> 
</span><span class="cx"> def emitMagicNumber
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreofflineasmsettingsrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/offlineasm/settings.rb (172776 => 172777)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/offlineasm/settings.rb        2014-08-19 23:20:37 UTC (rev 172776)
+++ trunk/Source/JavaScriptCore/offlineasm/settings.rb        2014-08-19 23:25:37 UTC (rev 172777)
</span><span class="lines">@@ -54,8 +54,29 @@
</span><span class="cx">         settingsCombinator(settingsCombinations, newMap, remaining[1..-1])
</span><span class="cx">     end
</span><span class="cx">     
</span><del>-    settingsCombinator(settingsCombinations, {}, (ast.filter(Setting).uniq.collect{|v| v.name} + BACKENDS).uniq)
</del><ins>+    nonBackendSettings = ast.filter(Setting).uniq.collect{ |v| v.name }
+    nonBackendSettings.delete_if {
+        | setting |
+        isBackend? setting
+    }
</ins><span class="cx">     
</span><ins>+    allBackendsFalse = {}
+    BACKENDS.each {
+        | backend |
+        allBackendsFalse[backend] = false
+    }
+    
+    # This will create entries for invalid backends. That's fine. It's necessary
+    # because it ensures that generate_offsets_extractor (which knows about valid
+    # backends) has settings indices that are compatible with what asm will see
+    # (asm doesn't know about valid backends).
+    BACKENDS.each {
+        | backend |
+        map = allBackendsFalse.clone
+        map[backend] = true
+        settingsCombinator(settingsCombinations, map, nonBackendSettings)
+    }
+    
</ins><span class="cx">     settingsCombinations
</span><span class="cx"> end
</span><span class="cx"> 
</span><span class="lines">@@ -73,15 +94,13 @@
</span><span class="cx">     selectedBackend = nil
</span><span class="cx">     BACKENDS.each {
</span><span class="cx">         | backend |
</span><del>-        isSupported = concreteSettings[backend]
-        raise unless isSupported != nil
-        numClaimedBackends += if isSupported then 1 else 0 end
-        if isSupported
</del><ins>+        if concreteSettings[backend]
+            raise if selectedBackend
</ins><span class="cx">             selectedBackend = backend
</span><span class="cx">         end
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    return if numClaimedBackends &gt; 1
</del><ins>+    return unless isValidBackend? selectedBackend
</ins><span class="cx">     
</span><span class="cx">     # Resolve the AST down to a low-level form (no macros or conditionals).
</span><span class="cx">     lowLevelAST = ast.resolveSettings(concreteSettings)
</span></span></pre>
</div>
</div>

</body>
</html>