<!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>[194017] trunk/Source</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/194017">194017</a></dd>
<dt>Author</dt> <dd>akling@apple.com</dd>
<dt>Date</dt> <dd>2015-12-13 12:03:24 -0800 (Sun, 13 Dec 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>CachedScript could have a copy-free path for all-ASCII scripts.
<https://webkit.org/b/152203>
Source/JavaScriptCore:
Reviewed by Antti Koivisto.
Make SourceProvider vend a StringView instead of a String.
This relaxes the promises that providers have to make about string lifetimes.
This means that on the WebCore side, CachedScript is free to cache a String
internally, while only ever exposing it as a temporary StringView.
A few extra copies (CPU, not memory) are introduced, none of them on hot paths.
* API/JSScriptRef.cpp:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::sourceCodeForTools):
(JSC::CodeBlock::dumpSource):
* inspector/ScriptDebugServer.cpp:
(Inspector::ScriptDebugServer::dispatchDidParseSource):
(Inspector::ScriptDebugServer::dispatchFailedToParseSource):
* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* jsc.cpp:
(functionFindTypeForExpression):
(functionHasBasicBlockExecuted):
(functionBasicBlockExecutionCount):
* parser/Lexer.cpp:
(JSC::Lexer<T>::setCode):
* parser/Lexer.h:
(JSC::Lexer<LChar>::setCodeStart):
(JSC::Lexer<UChar>::setCodeStart):
* parser/Parser.h:
(JSC::Parser::getToken):
* parser/SourceCode.cpp:
(JSC::SourceCode::toUTF8):
* parser/SourceCode.h:
(JSC::SourceCode::hash):
(JSC::SourceCode::view):
(JSC::SourceCode::toString): Deleted.
* parser/SourceCodeKey.h:
(JSC::SourceCodeKey::SourceCodeKey):
(JSC::SourceCodeKey::string):
* parser/SourceProvider.h:
(JSC::SourceProvider::getRange):
* runtime/Completion.cpp:
(JSC::loadAndEvaluateModule):
(JSC::loadModule):
* runtime/ErrorInstance.cpp:
(JSC::appendSourceToError):
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
* tools/FunctionOverrides.cpp:
(JSC::initializeOverrideInfo):
(JSC::FunctionOverrides::initializeOverrideFor):
Source/WebCore:
Reviewed by ANtti Koivisto.
Many (if not most) of script resources on the web contain nothing but ASCII characters.
Such resources, when streamed through a text decoder, will yield the exact same byte
sequence, except in anonymous heap memory instead of delicious file-backed pages.
Care is taken to ensure that the wrapper StringImpl is updated to target newly cached
resource data if an asynchronous caching notification comes in.
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource::tryReplaceEncodedData):
* loader/cache/CachedResource.h:
(WebCore::CachedResource::didReplaceSharedBufferContents):
* loader/cache/CachedScript.cpp:
(WebCore::encodingMayBeAllASCII):
(WebCore::CachedScript::script):
(WebCore::CachedScript::didReplaceSharedBufferContents):
* loader/cache/CachedScript.h:
* platform/SharedBuffer.h:
* platform/cf/SharedBufferCF.cpp:
(WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer):</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreAPIJSScriptRefcpp">trunk/Source/JavaScriptCore/API/JSScriptRef.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptDebugServercpp">trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserLexercpp">trunk/Source/JavaScriptCore/parser/Lexer.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserLexerh">trunk/Source/JavaScriptCore/parser/Lexer.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserParserh">trunk/Source/JavaScriptCore/parser/Parser.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserSourceCodecpp">trunk/Source/JavaScriptCore/parser/SourceCode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserSourceCodeh">trunk/Source/JavaScriptCore/parser/SourceCode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserSourceCodeKeyh">trunk/Source/JavaScriptCore/parser/SourceCodeKey.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreparserSourceProviderh">trunk/Source/JavaScriptCore/parser/SourceProvider.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeCompletioncpp">trunk/Source/JavaScriptCore/runtime/Completion.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeErrorInstancecpp">trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeFunctionPrototypecpp">trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoretoolsFunctionOverridescpp">trunk/Source/JavaScriptCore/tools/FunctionOverrides.cpp</a></li>
<li><a href="#trunkSourceWTFwtfPrintStreamcpp">trunk/Source/WTF/wtf/PrintStream.cpp</a></li>
<li><a href="#trunkSourceWTFwtfPrintStreamh">trunk/Source/WTF/wtf/PrintStream.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsCachedScriptSourceProviderh">trunk/Source/WebCore/bindings/js/CachedScriptSourceProvider.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsScriptSourceCodeh">trunk/Source/WebCore/bindings/js/ScriptSourceCode.h</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorPageAgentcpp">trunk/Source/WebCore/inspector/InspectorPageAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourcecpp">trunk/Source/WebCore/loader/cache/CachedResource.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceh">trunk/Source/WebCore/loader/cache/CachedResource.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedScriptcpp">trunk/Source/WebCore/loader/cache/CachedScript.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedScripth">trunk/Source/WebCore/loader/cache/CachedScript.h</a></li>
<li><a href="#trunkSourceWebCoreplatformSharedBufferh">trunk/Source/WebCore/platform/SharedBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformcfSharedBufferCFcpp">trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformsoupSharedBufferSoupcpp">trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp</a></li>
<li><a href="#trunkSourceWebKitmacWebViewWebScriptDebuggermm">trunk/Source/WebKit/mac/WebView/WebScriptDebugger.mm</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreAPIJSScriptRefcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSScriptRef.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSScriptRef.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/API/JSScriptRef.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -46,8 +46,13 @@
</span><span class="cx"> return WTF::adoptRef(*new OpaqueJSScript(vm, url, startingLineNumber, source));
</span><span class="cx"> }
</span><span class="cx">
</span><del>- virtual const String& source() const override
</del><ins>+ unsigned hash() const override
</ins><span class="cx"> {
</span><ins>+ return m_source.impl()->hash();
+ }
+
+ StringView source() const override
+ {
</ins><span class="cx"> return m_source;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -1,3 +1,60 @@
</span><ins>+2015-12-13 Andreas Kling <akling@apple.com>
+
+ CachedScript could have a copy-free path for all-ASCII scripts.
+ <https://webkit.org/b/152203>
+
+ Reviewed by Antti Koivisto.
+
+ Make SourceProvider vend a StringView instead of a String.
+ This relaxes the promises that providers have to make about string lifetimes.
+
+ This means that on the WebCore side, CachedScript is free to cache a String
+ internally, while only ever exposing it as a temporary StringView.
+
+ A few extra copies (CPU, not memory) are introduced, none of them on hot paths.
+
+ * API/JSScriptRef.cpp:
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::sourceCodeForTools):
+ (JSC::CodeBlock::dumpSource):
+ * inspector/ScriptDebugServer.cpp:
+ (Inspector::ScriptDebugServer::dispatchDidParseSource):
+ (Inspector::ScriptDebugServer::dispatchFailedToParseSource):
+ * interpreter/Interpreter.cpp:
+ (JSC::Interpreter::execute):
+ * jsc.cpp:
+ (functionFindTypeForExpression):
+ (functionHasBasicBlockExecuted):
+ (functionBasicBlockExecutionCount):
+ * parser/Lexer.cpp:
+ (JSC::Lexer<T>::setCode):
+ * parser/Lexer.h:
+ (JSC::Lexer<LChar>::setCodeStart):
+ (JSC::Lexer<UChar>::setCodeStart):
+ * parser/Parser.h:
+ (JSC::Parser::getToken):
+ * parser/SourceCode.cpp:
+ (JSC::SourceCode::toUTF8):
+ * parser/SourceCode.h:
+ (JSC::SourceCode::hash):
+ (JSC::SourceCode::view):
+ (JSC::SourceCode::toString): Deleted.
+ * parser/SourceCodeKey.h:
+ (JSC::SourceCodeKey::SourceCodeKey):
+ (JSC::SourceCodeKey::string):
+ * parser/SourceProvider.h:
+ (JSC::SourceProvider::getRange):
+ * runtime/Completion.cpp:
+ (JSC::loadAndEvaluateModule):
+ (JSC::loadModule):
+ * runtime/ErrorInstance.cpp:
+ (JSC::appendSourceToError):
+ * runtime/FunctionPrototype.cpp:
+ (JSC::functionProtoFuncToString):
+ * tools/FunctionOverrides.cpp:
+ (JSC::initializeOverrideInfo):
+ (JSC::FunctionOverrides::initializeOverrideFor):
+
</ins><span class="cx"> 2015-12-12 Benjamin Poulain <benjamin@webkit.org>
</span><span class="cx">
</span><span class="cx"> [JSC] Add lowering for B3's Store8 opcode
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -196,7 +196,7 @@
</span><span class="cx"> unsigned rangeEnd = delta + unlinked->startOffset() + unlinked->sourceLength();
</span><span class="cx"> return toCString(
</span><span class="cx"> "function ",
</span><del>- provider->source().impl()->utf8ForRange(rangeStart, rangeEnd - rangeStart));
</del><ins>+ provider->source().substring(rangeStart, rangeEnd - rangeStart).utf8());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> CString CodeBlock::sourceCodeOnOneLine() const
</span><span class="lines">@@ -554,14 +554,14 @@
</span><span class="cx"> ScriptExecutable* executable = ownerScriptExecutable();
</span><span class="cx"> if (executable->isFunctionExecutable()) {
</span><span class="cx"> FunctionExecutable* functionExecutable = reinterpret_cast<FunctionExecutable*>(executable);
</span><del>- String source = functionExecutable->source().provider()->getRange(
</del><ins>+ StringView source = functionExecutable->source().provider()->getRange(
</ins><span class="cx"> functionExecutable->parametersStartOffset(),
</span><span class="cx"> functionExecutable->typeProfilingEndOffset() + 1); // Type profiling end offset is the character before the '}'.
</span><span class="cx">
</span><span class="cx"> out.print("function ", inferredName(), source);
</span><span class="cx"> return;
</span><span class="cx"> }
</span><del>- out.print(executable->source().toString());
</del><ins>+ out.print(executable->source().view());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void CodeBlock::dumpBytecode()
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptDebugServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/inspector/ScriptDebugServer.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -199,7 +199,7 @@
</span><span class="cx">
</span><span class="cx"> ScriptDebugListener::Script script;
</span><span class="cx"> script.url = sourceProvider->url();
</span><del>- script.source = sourceProvider->source();
</del><ins>+ script.source = sourceProvider->source().toString();
</ins><span class="cx"> script.startLine = sourceProvider->startPosition().m_line.zeroBasedInt();
</span><span class="cx"> script.startColumn = sourceProvider->startPosition().m_column.zeroBasedInt();
</span><span class="cx"> script.isContentScript = isContentScript;
</span><span class="lines">@@ -231,7 +231,7 @@
</span><span class="cx"> void ScriptDebugServer::dispatchFailedToParseSource(const ListenerSet& listeners, SourceProvider* sourceProvider, int errorLine, const String& errorMessage)
</span><span class="cx"> {
</span><span class="cx"> String url = sourceProvider->url();
</span><del>- const String& data = sourceProvider->source();
</del><ins>+ String data = sourceProvider->source().toString();
</ins><span class="cx"> int firstLine = sourceProvider->startPosition().m_line.oneBasedInt();
</span><span class="cx">
</span><span class="cx"> Vector<ScriptDebugListener*> copy;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -849,7 +849,7 @@
</span><span class="cx">
</span><span class="cx"> Vector<JSONPData> JSONPData;
</span><span class="cx"> bool parseResult;
</span><del>- const String programSource = program->source().toString();
</del><ins>+ StringView programSource = program->source().view();
</ins><span class="cx"> if (programSource.isNull())
</span><span class="cx"> return jsUndefined();
</span><span class="cx"> if (programSource.is8Bit()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -1464,7 +1464,7 @@
</span><span class="cx">
</span><span class="cx"> RELEASE_ASSERT(exec->argument(1).isString());
</span><span class="cx"> String substring = exec->argument(1).getString(exec);
</span><del>- String sourceCodeText = executable->source().toString();
</del><ins>+ String sourceCodeText = executable->source().view().toString();
</ins><span class="cx"> unsigned offset = static_cast<unsigned>(sourceCodeText.find(substring) + executable->source().startOffset());
</span><span class="cx">
</span><span class="cx"> String jsonString = exec->vm().typeProfiler()->typeInformationForExpressionAtOffset(TypeProfilerSearchDescriptorNormal, offset, executable->sourceID(), exec->vm());
</span><span class="lines">@@ -1502,7 +1502,7 @@
</span><span class="cx">
</span><span class="cx"> RELEASE_ASSERT(exec->argument(1).isString());
</span><span class="cx"> String substring = exec->argument(1).getString(exec);
</span><del>- String sourceCodeText = executable->source().toString();
</del><ins>+ String sourceCodeText = executable->source().view().toString();
</ins><span class="cx"> RELEASE_ASSERT(sourceCodeText.contains(substring));
</span><span class="cx"> int offset = sourceCodeText.find(substring) + executable->source().startOffset();
</span><span class="cx">
</span><span class="lines">@@ -1520,7 +1520,7 @@
</span><span class="cx">
</span><span class="cx"> RELEASE_ASSERT(exec->argument(1).isString());
</span><span class="cx"> String substring = exec->argument(1).getString(exec);
</span><del>- String sourceCodeText = executable->source().toString();
</del><ins>+ String sourceCodeText = executable->source().view().toString();
</ins><span class="cx"> RELEASE_ASSERT(sourceCodeText.contains(substring));
</span><span class="cx"> int offset = sourceCodeText.find(substring) + executable->source().startOffset();
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserLexercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Lexer.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Lexer.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/parser/Lexer.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -543,10 +543,10 @@
</span><span class="cx"> m_lineNumber = source.firstLine();
</span><span class="cx"> m_lastToken = -1;
</span><span class="cx">
</span><del>- const String& sourceString = source.provider()->source();
</del><ins>+ StringView sourceString = source.provider()->source();
</ins><span class="cx">
</span><span class="cx"> if (!sourceString.isNull())
</span><del>- setCodeStart(sourceString.impl());
</del><ins>+ setCodeStart(sourceString);
</ins><span class="cx"> else
</span><span class="cx"> m_codeStart = 0;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserLexerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Lexer.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Lexer.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/parser/Lexer.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -139,7 +139,7 @@
</span><span class="cx"> ALWAYS_INLINE const T* currentSourcePtr() const;
</span><span class="cx"> ALWAYS_INLINE void setOffsetFromSourcePtr(const T* sourcePtr, unsigned lineStartOffset) { setOffset(offsetFromSourcePtr(sourcePtr), lineStartOffset); }
</span><span class="cx">
</span><del>- ALWAYS_INLINE void setCodeStart(const StringImpl*);
</del><ins>+ ALWAYS_INLINE void setCodeStart(const StringView&);
</ins><span class="cx">
</span><span class="cx"> ALWAYS_INLINE const Identifier* makeIdentifier(const LChar* characters, size_t length);
</span><span class="cx"> ALWAYS_INLINE const Identifier* makeIdentifier(const UChar* characters, size_t length);
</span><span class="lines">@@ -289,17 +289,17 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template <>
</span><del>-ALWAYS_INLINE void Lexer<LChar>::setCodeStart(const StringImpl* sourceString)
</del><ins>+ALWAYS_INLINE void Lexer<LChar>::setCodeStart(const StringView& sourceString)
</ins><span class="cx"> {
</span><del>- ASSERT(sourceString->is8Bit());
- m_codeStart = sourceString->characters8();
</del><ins>+ ASSERT(sourceString.is8Bit());
+ m_codeStart = sourceString.characters8();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template <>
</span><del>-ALWAYS_INLINE void Lexer<UChar>::setCodeStart(const StringImpl* sourceString)
</del><ins>+ALWAYS_INLINE void Lexer<UChar>::setCodeStart(const StringView& sourceString)
</ins><span class="cx"> {
</span><del>- ASSERT(!sourceString->is8Bit());
- m_codeStart = sourceString->characters16();
</del><ins>+ ASSERT(!sourceString.is8Bit());
+ m_codeStart = sourceString.characters16();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> template <typename T>
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/Parser.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/Parser.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/parser/Parser.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -990,7 +990,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void printUnexpectedTokenText(WTF::PrintStream&);
</span><del>- ALWAYS_INLINE String getToken() {
</del><ins>+ ALWAYS_INLINE StringView getToken() {
</ins><span class="cx"> SourceProvider* sourceProvider = m_source->provider();
</span><span class="cx"> return sourceProvider->getRange(tokenStart(), tokenEndPosition().offset);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSourceCodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SourceCode.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SourceCode.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/parser/SourceCode.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx"> if (!m_provider)
</span><span class="cx"> return CString("", 0);
</span><span class="cx">
</span><del>- return m_provider->source().impl()->utf8ForRange(m_startChar, m_endChar - m_startChar);
</del><ins>+ return m_provider->source().substring(m_startChar, m_endChar - m_startChar).utf8();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSourceCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SourceCode.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SourceCode.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/parser/SourceCode.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -79,10 +79,16 @@
</span><span class="cx">
</span><span class="cx"> bool isHashTableDeletedValue() const { return m_provider.isHashTableDeletedValue(); }
</span><span class="cx">
</span><del>- String toString() const
</del><ins>+ unsigned hash() const
</ins><span class="cx"> {
</span><ins>+ ASSERT(m_provider);
+ return m_provider->hash();
+ }
+
+ StringView view() const
+ {
</ins><span class="cx"> if (!m_provider)
</span><del>- return String();
</del><ins>+ return StringView();
</ins><span class="cx"> return m_provider->getRange(m_startChar, m_endChar);
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSourceCodeKeyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SourceCodeKey.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SourceCodeKey.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/parser/SourceCodeKey.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx"> : m_sourceCode(sourceCode)
</span><span class="cx"> , m_name(name)
</span><span class="cx"> , m_flags((static_cast<unsigned>(codeType) << 3) | (static_cast<unsigned>(builtinMode) << 2) | (static_cast<unsigned>(strictMode) << 1) | static_cast<unsigned>(thisTDZMode))
</span><del>- , m_hash(string().impl()->hash())
</del><ins>+ , m_hash(sourceCode.hash())
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -64,7 +64,7 @@
</span><span class="cx">
</span><span class="cx"> // To save memory, we compute our string on demand. It's expected that source
</span><span class="cx"> // providers cache their strings to make this efficient.
</span><del>- String string() const { return m_sourceCode.toString(); }
</del><ins>+ StringView string() const { return m_sourceCode.view(); }
</ins><span class="cx">
</span><span class="cx"> bool operator==(const SourceCodeKey& other) const
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreparserSourceProviderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/parser/SourceProvider.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/parser/SourceProvider.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/parser/SourceProvider.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -43,10 +43,11 @@
</span><span class="cx">
</span><span class="cx"> JS_EXPORT_PRIVATE virtual ~SourceProvider();
</span><span class="cx">
</span><del>- virtual const String& source() const = 0;
- String getRange(int start, int end) const
</del><ins>+ virtual unsigned hash() const = 0;
+ virtual StringView source() const = 0;
+ StringView getRange(int start, int end) const
</ins><span class="cx"> {
</span><del>- return source().substringSharingImpl(start, end - start);
</del><ins>+ return source().substring(start, end - start);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> const String& url() const { return m_url; }
</span><span class="lines">@@ -86,8 +87,13 @@
</span><span class="cx"> {
</span><span class="cx"> return adoptRef(*new StringSourceProvider(source, url, startPosition));
</span><span class="cx"> }
</span><ins>+
+ unsigned hash() const override
+ {
+ return m_source.impl()->hash();
+ }
</ins><span class="cx">
</span><del>- virtual const String& source() const override
</del><ins>+ virtual StringView source() const override
</ins><span class="cx"> {
</span><span class="cx"> return m_source;
</span><span class="cx"> }
</span><span class="lines">@@ -110,8 +116,13 @@
</span><span class="cx"> return adoptRef(*new WebAssemblySourceProvider(data, url));
</span><span class="cx"> }
</span><span class="cx">
</span><del>- virtual const String& source() const override
</del><ins>+ unsigned hash() const override
</ins><span class="cx"> {
</span><ins>+ return m_source.impl()->hash();
+ }
+
+ virtual StringView source() const override
+ {
</ins><span class="cx"> return m_source;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeCompletioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Completion.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Completion.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/runtime/Completion.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -167,7 +167,7 @@
</span><span class="cx"> JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
</span><span class="cx">
</span><span class="cx"> // Insert the given source code to the ModuleLoader registry as the fetched registry entry.
</span><del>- globalObject->moduleLoader()->provide(exec, key, ModuleLoaderObject::Status::Fetch, source.toString());
</del><ins>+ globalObject->moduleLoader()->provide(exec, key, ModuleLoaderObject::Status::Fetch, source.view().toString());
</ins><span class="cx"> if (exec->hadException())
</span><span class="cx"> return rejectPromise(exec, globalObject);
</span><span class="cx">
</span><span class="lines">@@ -204,7 +204,7 @@
</span><span class="cx"> JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
</span><span class="cx">
</span><span class="cx"> // Insert the given source code to the ModuleLoader registry as the fetched registry entry.
</span><del>- globalObject->moduleLoader()->provide(exec, key, ModuleLoaderObject::Status::Fetch, source.toString());
</del><ins>+ globalObject->moduleLoader()->provide(exec, key, ModuleLoaderObject::Status::Fetch, source.view().toString());
</ins><span class="cx"> if (exec->hadException())
</span><span class="cx"> return rejectPromise(exec, globalObject);
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeErrorInstancecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx"> int expressionStart = divotPoint - startOffset;
</span><span class="cx"> int expressionStop = divotPoint + endOffset;
</span><span class="cx">
</span><del>- const String& sourceString = codeBlock->source()->source();
</del><ins>+ StringView sourceString = codeBlock->source()->source();
</ins><span class="cx"> if (!expressionStop || expressionStart > static_cast<int>(sourceString.length()))
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="lines">@@ -71,24 +71,23 @@
</span><span class="cx">
</span><span class="cx"> String message = asString(jsMessage)->value(callFrame);
</span><span class="cx"> if (expressionStart < expressionStop)
</span><del>- message = appender(message, codeBlock->source()->getRange(expressionStart, expressionStop) , type, ErrorInstance::FoundExactSource);
</del><ins>+ message = appender(message, codeBlock->source()->getRange(expressionStart, expressionStop).toString(), type, ErrorInstance::FoundExactSource);
</ins><span class="cx"> else {
</span><span class="cx"> // No range information, so give a few characters of context.
</span><del>- const StringImpl* data = sourceString.impl();
</del><span class="cx"> int dataLength = sourceString.length();
</span><span class="cx"> int start = expressionStart;
</span><span class="cx"> int stop = expressionStart;
</span><span class="cx"> // Get up to 20 characters of context to the left and right of the divot, clamping to the line.
</span><span class="cx"> // Then strip whitespace.
</span><del>- while (start > 0 && (expressionStart - start < 20) && (*data)[start - 1] != '\n')
</del><ins>+ while (start > 0 && (expressionStart - start < 20) && sourceString[start - 1] != '\n')
</ins><span class="cx"> start--;
</span><del>- while (start < (expressionStart - 1) && isStrWhiteSpace((*data)[start]))
</del><ins>+ while (start < (expressionStart - 1) && isStrWhiteSpace(sourceString[start]))
</ins><span class="cx"> start++;
</span><del>- while (stop < dataLength && (stop - expressionStart < 20) && (*data)[stop] != '\n')
</del><ins>+ while (stop < dataLength && (stop - expressionStart < 20) && sourceString[stop] != '\n')
</ins><span class="cx"> stop++;
</span><del>- while (stop > expressionStart && isStrWhiteSpace((*data)[stop - 1]))
</del><ins>+ while (stop > expressionStart && isStrWhiteSpace(sourceString[stop - 1]))
</ins><span class="cx"> stop--;
</span><del>- message = appender(message, codeBlock->source()->getRange(start, stop), type, ErrorInstance::FoundApproximateSource);
</del><ins>+ message = appender(message, codeBlock->source()->getRange(start, stop).toString(), type, ErrorInstance::FoundApproximateSource);
</ins><span class="cx"> }
</span><span class="cx"> exception->putDirect(*vm, vm->propertyNames->message, jsString(vm, message));
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeFunctionPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/runtime/FunctionPrototype.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -92,7 +92,7 @@
</span><span class="cx">
</span><span class="cx"> String functionHeader = executable->isArrowFunction() ? "" : "function ";
</span><span class="cx">
</span><del>- String source = executable->source().provider()->getRange(
</del><ins>+ StringView source = executable->source().provider()->getRange(
</ins><span class="cx"> executable->parametersStartOffset(),
</span><span class="cx"> executable->parametersStartOffset() + executable->source().length());
</span><span class="cx"> return JSValue::encode(jsMakeNontrivialString(exec, functionHeader, function->name(exec), source));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretoolsFunctionOverridescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tools/FunctionOverrides.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tools/FunctionOverrides.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/JavaScriptCore/tools/FunctionOverrides.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -106,7 +106,7 @@
</span><span class="cx">
</span><span class="cx"> static void initializeOverrideInfo(const SourceCode& origCode, const String& newBody, FunctionOverrides::OverrideInfo& info)
</span><span class="cx"> {
</span><del>- String origProviderStr = origCode.provider()->source();
</del><ins>+ String origProviderStr = origCode.provider()->source().toString();
</ins><span class="cx"> unsigned origBraceStart = origCode.startOffset();
</span><span class="cx"> unsigned origFunctionStart = origProviderStr.reverseFind("function", origBraceStart);
</span><span class="cx"> unsigned headerLength = origBraceStart - origFunctionStart;
</span><span class="lines">@@ -135,7 +135,7 @@
</span><span class="cx"> ASSERT(Options::functionOverrides());
</span><span class="cx"> FunctionOverrides& overrides = FunctionOverrides::overrides();
</span><span class="cx">
</span><del>- auto it = overrides.m_entries.find(origCode.toString());
</del><ins>+ auto it = overrides.m_entries.find(origCode.view().toString());
</ins><span class="cx"> if (it == overrides.m_entries.end())
</span><span class="cx"> return false;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWTFwtfPrintStreamcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/PrintStream.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/PrintStream.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WTF/wtf/PrintStream.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -53,6 +53,11 @@
</span><span class="cx"> out.printf("%s", string);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void printInternal(PrintStream& out, const StringView& string)
+{
+ out.print(string.utf8());
+}
+
</ins><span class="cx"> void printInternal(PrintStream& out, const CString& string)
</span><span class="cx"> {
</span><span class="cx"> out.print(string.data());
</span></span></pre></div>
<a id="trunkSourceWTFwtfPrintStreamh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/PrintStream.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/PrintStream.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WTF/wtf/PrintStream.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> class CString;
</span><span class="cx"> class String;
</span><span class="cx"> class StringImpl;
</span><ins>+class StringView;
</ins><span class="cx"> class UniquedStringImpl;
</span><span class="cx">
</span><span class="cx"> class PrintStream {
</span><span class="lines">@@ -70,6 +71,7 @@
</span><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const char*);
</span><ins>+WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const StringView&);
</ins><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const CString&);
</span><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const String&);
</span><span class="cx"> WTF_EXPORT_PRIVATE void printInternal(PrintStream&, const StringImpl*);
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/ChangeLog        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2015-12-13 Andreas Kling <akling@apple.com>
+
+ CachedScript could have a copy-free path for all-ASCII scripts.
+ <https://webkit.org/b/152203>
+
+ Reviewed by ANtti Koivisto.
+
+ Many (if not most) of script resources on the web contain nothing but ASCII characters.
+ Such resources, when streamed through a text decoder, will yield the exact same byte
+ sequence, except in anonymous heap memory instead of delicious file-backed pages.
+
+ Care is taken to ensure that the wrapper StringImpl is updated to target newly cached
+ resource data if an asynchronous caching notification comes in.
+
+ * loader/cache/CachedResource.cpp:
+ (WebCore::CachedResource::tryReplaceEncodedData):
+ * loader/cache/CachedResource.h:
+ (WebCore::CachedResource::didReplaceSharedBufferContents):
+ * loader/cache/CachedScript.cpp:
+ (WebCore::encodingMayBeAllASCII):
+ (WebCore::CachedScript::script):
+ (WebCore::CachedScript::didReplaceSharedBufferContents):
+ * loader/cache/CachedScript.h:
+ * platform/SharedBuffer.h:
+ * platform/cf/SharedBufferCF.cpp:
+ (WebCore::SharedBuffer::tryReplaceContentsWithPlatformBuffer):
+
</ins><span class="cx"> 2015-12-13 Zalan Bujtas <zalan@apple.com>
</span><span class="cx">
</span><span class="cx"> Clean up absolute positioned map properly.
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsCachedScriptSourceProviderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/CachedScriptSourceProvider.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/CachedScriptSourceProvider.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/bindings/js/CachedScriptSourceProvider.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -44,7 +44,8 @@
</span><span class="cx"> m_cachedScript->removeClient(this);
</span><span class="cx"> }
</span><span class="cx">
</span><del>- const String& source() const { return m_cachedScript->script(); }
</del><ins>+ unsigned hash() const override { return m_cachedScript->scriptHash(); }
+ StringView source() const override { return m_cachedScript->script(); }
</ins><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> CachedScriptSourceProvider(CachedScript* cachedScript)
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsScriptSourceCodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/ScriptSourceCode.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/ScriptSourceCode.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/bindings/js/ScriptSourceCode.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -61,7 +61,7 @@
</span><span class="cx">
</span><span class="cx"> const JSC::SourceCode& jsSourceCode() const { return m_code; }
</span><span class="cx">
</span><del>- const String& source() const { return m_provider->source(); }
</del><ins>+ StringView source() const { return m_provider->source(); }
</ins><span class="cx">
</span><span class="cx"> int startLine() const { return m_code.firstLine(); }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorPageAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorPageAgent.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/inspector/InspectorPageAgent.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/inspector/InspectorPageAgent.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -161,7 +161,7 @@
</span><span class="cx"> *result = downcast<CachedCSSStyleSheet>(*cachedResource).sheetText();
</span><span class="cx"> return !result->isNull();
</span><span class="cx"> case CachedResource::Script:
</span><del>- *result = downcast<CachedScript>(*cachedResource).script();
</del><ins>+ *result = downcast<CachedScript>(*cachedResource).script().toString();
</ins><span class="cx"> return true;
</span><span class="cx"> case CachedResource::RawResource: {
</span><span class="cx"> auto* buffer = cachedResource->resourceBuffer();
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResource.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -787,7 +787,10 @@
</span><span class="cx"> if (m_data->size() != newBuffer.size() || memcmp(m_data->data(), newBuffer.data(), m_data->size()))
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- m_data->tryReplaceContentsWithPlatformBuffer(newBuffer);
</del><ins>+ if (m_data->tryReplaceContentsWithPlatformBuffer(newBuffer)) {
+ didReplaceSharedBufferContents();
+ // FIXME: Should we call checkNotify() here to move already-decoded images to the new data source?
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedResource.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/loader/cache/CachedResource.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -267,6 +267,8 @@
</span><span class="cx"> void setDecodedSize(unsigned);
</span><span class="cx"> void didAccessDecodedData(double timeStamp);
</span><span class="cx">
</span><ins>+ virtual void didReplaceSharedBufferContents() { }
+
</ins><span class="cx"> // FIXME: Make the rest of these data members private and use functions in derived classes instead.
</span><span class="cx"> HashCountedSet<CachedResourceClient*> m_clients;
</span><span class="cx"> ResourceRequest m_resourceRequest;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedScriptcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedScript.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedScript.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/loader/cache/CachedScript.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -69,16 +69,52 @@
</span><span class="cx"> return extractMIMETypeFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType)).lower();
</span><span class="cx"> }
</span><span class="cx">
</span><del>-const String& CachedScript::script()
</del><ins>+static bool encodingMayBeAllASCII(const String& encoding)
</ins><span class="cx"> {
</span><ins>+ return encoding == "UTF-8" || encoding == "ISO-8859-1" || encoding == "ASCII";
+}
+
+StringView CachedScript::script()
+{
</ins><span class="cx"> if (!m_script && m_data) {
</span><ins>+ if (m_ASCIIOptimizationState == Unknown
+ && encodingMayBeAllASCII(encoding())
+ && m_data->size()
+ && charactersAreAllASCII(reinterpret_cast<const LChar*>(m_data->data()), m_data->size())) {
+
+ m_script = StringImpl::createWithoutCopying(reinterpret_cast<const LChar*>(m_data->data()), m_data->size());
+ m_ASCIIOptimizationState = DataAndDecodedStringHaveSameBytes;
+
+ // If the encoded and decoded data are the same, there is no decoded data cost!
+ setDecodedSize(0);
+ m_decodedDataDeletionTimer.stop();
+ return m_script;
+ }
</ins><span class="cx"> m_script = m_decoder->decodeAndFlush(m_data->data(), encodedSize());
</span><ins>+ m_ASCIIOptimizationState = DataAndDecodedStringHaveDifferentBytes;
</ins><span class="cx"> setDecodedSize(m_script.sizeInBytes());
</span><span class="cx"> }
</span><del>- m_decodedDataDeletionTimer.restart();
</del><ins>+ if (m_ASCIIOptimizationState == DataAndDecodedStringHaveDifferentBytes)
+ m_decodedDataDeletionTimer.restart();
</ins><span class="cx"> return m_script;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+unsigned CachedScript::scriptHash()
+{
+ script();
+ return m_script.impl()->hash();
+}
+
+void CachedScript::didReplaceSharedBufferContents()
+{
+ // We receive this callback when the CachedResource's internal SharedBuffer has had its contents
+ // replaced by the memory-mapping-of-file-backed-resources optimization. If m_script is just a
+ // non-copying wrapper around the old SharedBuffer contents, we have to retarget it.
+ if (m_ASCIIOptimizationState == DataAndDecodedStringHaveSameBytes)
+ m_script = StringImpl::createWithoutCopying(reinterpret_cast<const LChar*>(m_data->data()), m_data->size());
+ CachedResource::didReplaceSharedBufferContents();
+}
+
</ins><span class="cx"> void CachedScript::finishLoading(SharedBuffer* data)
</span><span class="cx"> {
</span><span class="cx"> m_data = data;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedScripth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedScript.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/cache/CachedScript.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/loader/cache/CachedScript.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -37,7 +37,8 @@
</span><span class="cx"> CachedScript(const ResourceRequest&, const String& charset, SessionID);
</span><span class="cx"> virtual ~CachedScript();
</span><span class="cx">
</span><del>- const String& script();
</del><ins>+ StringView script();
+ unsigned scriptHash();
</ins><span class="cx">
</span><span class="cx"> String mimeType() const;
</span><span class="cx">
</span><span class="lines">@@ -45,6 +46,8 @@
</span><span class="cx"> bool mimeTypeAllowedByNosniff() const;
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+ void didReplaceSharedBufferContents() override;
+
</ins><span class="cx"> private:
</span><span class="cx"> virtual bool mayTryReplaceEncodedData() const override { return true; }
</span><span class="cx">
</span><span class="lines">@@ -57,6 +60,10 @@
</span><span class="cx"> virtual void destroyDecodedData() override;
</span><span class="cx">
</span><span class="cx"> String m_script;
</span><ins>+
+ enum ASCIIResourceOptimizationState { Unknown, DataAndDecodedStringHaveSameBytes, DataAndDecodedStringHaveDifferentBytes };
+ ASCIIResourceOptimizationState m_ASCIIOptimizationState { Unknown };
+
</ins><span class="cx"> RefPtr<TextResourceDecoder> m_decoder;
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformSharedBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/SharedBuffer.h (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/SharedBuffer.h        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/platform/SharedBuffer.h        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -119,7 +119,7 @@
</span><span class="cx"> // }
</span><span class="cx"> WEBCORE_EXPORT unsigned getSomeData(const char*& data, unsigned position = 0) const;
</span><span class="cx">
</span><del>- void tryReplaceContentsWithPlatformBuffer(SharedBuffer&);
</del><ins>+ bool tryReplaceContentsWithPlatformBuffer(SharedBuffer&);
</ins><span class="cx"> WEBCORE_EXPORT bool hasPlatformData() const;
</span><span class="cx">
</span><span class="cx"> struct DataBuffer : public ThreadSafeRefCounted<DataBuffer> {
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcfSharedBufferCFcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -92,13 +92,14 @@
</span><span class="cx"> m_cfData = 0;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
</del><ins>+bool SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
</ins><span class="cx"> {
</span><span class="cx"> if (!newContents.m_cfData)
</span><del>- return;
</del><ins>+ return false;
</ins><span class="cx">
</span><span class="cx"> clear();
</span><span class="cx"> m_cfData = newContents.m_cfData;
</span><ins>+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> bool SharedBuffer::maybeAppendPlatformData(SharedBuffer* newContents)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformsoupSharedBufferSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -78,14 +78,15 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
</del><ins>+bool SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer& newContents)
</ins><span class="cx"> {
</span><span class="cx"> if (!newContents.hasPlatformData())
</span><del>- return;
</del><ins>+ return false;
</ins><span class="cx">
</span><span class="cx"> clear();
</span><span class="cx"> // FIXME: Use GRefPtr instead of GUniquePtr for the SoupBuffer.
</span><span class="cx"> m_soupBuffer.swap(newContents.m_soupBuffer);
</span><ins>+ return true;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebViewWebScriptDebuggermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebView/WebScriptDebugger.mm (194016 => 194017)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebView/WebScriptDebugger.mm        2015-12-13 16:18:07 UTC (rev 194016)
+++ trunk/Source/WebKit/mac/WebView/WebScriptDebugger.mm        2015-12-13 20:03:24 UTC (rev 194017)
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx">
</span><span class="cx"> static NSString *toNSString(SourceProvider* sourceProvider)
</span><span class="cx"> {
</span><del>- const String& sourceString = sourceProvider->source();
</del><ins>+ const String& sourceString = sourceProvider->source().toString();
</ins><span class="cx"> if (sourceString.isEmpty())
</span><span class="cx"> return nil;
</span><span class="cx"> return sourceString;
</span></span></pre>
</div>
</div>
</body>
</html>