<!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>[191215] trunk</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/191215">191215</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2015-10-16 15:18:42 -0700 (Fri, 16 Oct 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add Intrinsic Getters and use them to fix performance on the getters of TypedArray properties.
https://bugs.webkit.org/show_bug.cgi?id=149687

Patch by Keith Miller &lt;keith@Keiths-MacBook-Pro-5.local&gt; on 2015-10-16
Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

Add the ability to create intrinsic getters in both the inline cache and the DFG/FTL. When the
getter fetched by a GetById has an intrinsic we know about we add a new intrinsic access case.
Once we get to the DFG, we observe that the access case was an intrinsic and add an appropriate
GetByIdVariant. We then parse the intrinsic into an appropriate DFG node.

The first intrinsics are the new TypedArray prototype getters length, byteLength, and byteOffset.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/GetByIdStatus.cpp:
(JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
(JSC::GetByIdStatus::computeFor):
* bytecode/GetByIdVariant.cpp:
(JSC::GetByIdVariant::GetByIdVariant):
(JSC::GetByIdVariant::operator=):
(JSC::GetByIdVariant::canMergeIntrinsicStructures):
(JSC::GetByIdVariant::attemptToMerge):
(JSC::GetByIdVariant::dumpInContext):
* bytecode/GetByIdVariant.h:
(JSC::GetByIdVariant::intrinsicFunction):
(JSC::GetByIdVariant::intrinsic):
(JSC::GetByIdVariant::callLinkStatus): Deleted.
* bytecode/PolymorphicAccess.cpp:
(JSC::AccessGenerationState::addWatchpoint):
(JSC::AccessGenerationState::restoreScratch):
(JSC::AccessGenerationState::succeed):
(JSC::AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling):
(JSC::AccessGenerationState::preserveLiveRegistersToStackForCall):
(JSC::AccessGenerationState::restoreLiveRegistersFromStackForCall):
(JSC::AccessGenerationState::restoreLiveRegistersFromStackForCallWithThrownException):
(JSC::AccessGenerationState::callSiteIndexForExceptionHandlingOrOriginal):
(JSC::AccessGenerationState::originalExceptionHandler):
(JSC::AccessGenerationState::originalCallSiteIndex):
(JSC::AccessCase::getIntrinsic):
(JSC::AccessCase::clone):
(JSC::AccessCase::visitWeak):
(JSC::AccessCase::generate):
(WTF::printInternal):
(JSC::AccessCase::AccessCase): Deleted.
(JSC::AccessCase::get): Deleted.
(JSC::AccessCase::replace): Deleted.
(JSC::AccessCase::transition): Deleted.
* bytecode/PolymorphicAccess.h:
(JSC::AccessCase::isGet):
(JSC::AccessCase::isPut):
(JSC::AccessCase::isIn):
(JSC::AccessCase::intrinsicFunction):
(JSC::AccessCase::intrinsic):
(JSC::AccessGenerationState::AccessGenerationState):
(JSC::AccessGenerationState::liveRegistersForCall):
(JSC::AccessGenerationState::callSiteIndexForExceptionHandling):
(JSC::AccessGenerationState::numberOfStackBytesUsedForRegisterPreservation):
(JSC::AccessGenerationState::needsToRestoreRegistersIfException):
(JSC::AccessGenerationState::liveRegistersToPreserveAtExceptionHandlingCallSite):
* bytecode/PutByIdVariant.h:
(JSC::PutByIdVariant::intrinsic):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGArrayMode.cpp:
(JSC::DFG::ArrayMode::alreadyChecked):
(JSC::DFG::arrayTypeToString):
(JSC::DFG::toTypedArrayType):
(JSC::DFG::refineTypedArrayType):
(JSC::DFG::permitsBoundsCheckLowering):
* dfg/DFGArrayMode.h:
(JSC::DFG::ArrayMode::supportsLength):
(JSC::DFG::ArrayMode::isSomeTypedArrayView):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::attemptToInlineCall):
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
(JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
(JSC::DFG::ByteCodeParser::load):
(JSC::DFG::ByteCodeParser::handleGetById):
(JSC::DFG::ByteCodeParser::presenceLike): Deleted.
(JSC::DFG::ByteCodeParser::store): Deleted.
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
(JSC::DFG::FixupPhase::convertToGetArrayLength): Deleted.
(JSC::DFG::FixupPhase::prependGetArrayLength): Deleted.
(JSC::DFG::FixupPhase::fixupChecksInBlock): Deleted.
* dfg/DFGGraph.cpp:
(JSC::DFG::Graph::tryGetFoldableView):
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::checkArray):
(JSC::DFG::SpeculativeJIT::compileGetArrayLength):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileGetArrayLength):
* jit/IntrinsicEmitter.cpp: Added.
(JSC::AccessCase::canEmitIntrinsicGetter):
(JSC::AccessCase::emitIntrinsicGetter):
* jit/Repatch.cpp:
(JSC::tryCacheGetByID):
* runtime/Intrinsic.h:
* runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::put):
(JSC::JSArrayBufferView::defineOwnProperty):
(JSC::JSArrayBufferView::deleteProperty):
(JSC::JSArrayBufferView::getOwnNonIndexPropertyNames):
(JSC::JSArrayBufferView::getOwnPropertySlot): Deleted.
(JSC::JSArrayBufferView::finalize): Deleted.
* runtime/JSDataView.cpp:
(JSC::JSDataView::getOwnPropertySlot):
(JSC::JSDataView::put):
(JSC::JSDataView::defineOwnProperty):
(JSC::JSDataView::deleteProperty):
(JSC::JSDataView::getOwnNonIndexPropertyNames):
* runtime/JSDataView.h:
* runtime/JSFunction.h:
* runtime/JSFunctionInlines.h:
(JSC::JSFunction::intrinsic):
* runtime/JSGenericTypedArrayView.h:
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::getOwnPropertySlot):
(JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::defineOwnProperty):
(JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::deleteProperty):
(JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::getOwnPropertySlotByIndex): Deleted.
(JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::visitChildren): Deleted.
* runtime/JSObject.cpp:
(JSC::JSObject::putDirectNativeIntrinsicGetter):
* runtime/JSObject.h:
* runtime/JSTypedArrayViewPrototype.cpp:
(JSC::JSTypedArrayViewPrototype::finishCreation):
* tests/stress/typedarray-add-property-to-base-object.js: Added.
(body.foo):
(body):
* tests/stress/typedarray-bad-getter.js: Added.
(body.foo):
(body.get Bar):
(body):
* tests/stress/typedarray-getter-on-self.js: Added.
(body.foo):
(body.bar):
(body.baz):
(body.get for):
(body):
* tests/stress/typedarray-intrinsic-getters-change-prototype.js: Added.
(body.foo):
(body.bar):
(body.baz):
(body):

LayoutTests:

Fix test since typedarrays no longer have length as a own property.

* js/dom/getOwnPropertyDescriptor-expected.txt:
* js/resources/getOwnPropertyDescriptor.js:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsjsdomgetOwnPropertyDescriptorexpectedtxt">trunk/LayoutTests/js/dom/getOwnPropertyDescriptor-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsresourcesgetOwnPropertyDescriptorjs">trunk/LayoutTests/js/resources/getOwnPropertyDescriptor.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<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="#trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp">trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdVariantcpp">trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeGetByIdVarianth">trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePolymorphicAccessh">trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodePutByIdVarianth">trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArrayModecpp">trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGArrayModeh">trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGGraphcpp">trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitRepatchcpp">trunk/Source/JavaScriptCore/jit/Repatch.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeIntrinsich">trunk/Source/JavaScriptCore/runtime/Intrinsic.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSArrayBufferViewcpp">trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSDataViewcpp">trunk/Source/JavaScriptCore/runtime/JSDataView.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSDataViewh">trunk/Source/JavaScriptCore/runtime/JSDataView.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFunctionh">trunk/Source/JavaScriptCore/runtime/JSFunction.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFunctionInlinesh">trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGenericTypedArrayViewh">trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGenericTypedArrayViewInlinesh">trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjectcpp">trunk/Source/JavaScriptCore/runtime/JSObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSObjecth">trunk/Source/JavaScriptCore/runtime/JSObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTypedArrayViewPrototypecpp">trunk/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorejitIntrinsicEmittercpp">trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresstypedarrayaddpropertytobaseobjectjs">trunk/Source/JavaScriptCore/tests/stress/typedarray-add-property-to-base-object.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresstypedarraybadgetterjs">trunk/Source/JavaScriptCore/tests/stress/typedarray-bad-getter.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresstypedarraygetteronselfjs">trunk/Source/JavaScriptCore/tests/stress/typedarray-getter-on-self.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresstypedarrayintrinsicgetterschangeprototypejs">trunk/Source/JavaScriptCore/tests/stress/typedarray-intrinsic-getters-change-prototype.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/LayoutTests/ChangeLog        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-10-16  Keith Miller  &lt;keith@Keiths-MacBook-Pro-5.local&gt;
+
+        Add Intrinsic Getters and use them to fix performance on the getters of TypedArray properties.
+        https://bugs.webkit.org/show_bug.cgi?id=149687
+
+        Reviewed by Geoffrey Garen.
+
+        Fix test since typedarrays no longer have length as a own property.
+
+        * js/dom/getOwnPropertyDescriptor-expected.txt:
+        * js/resources/getOwnPropertyDescriptor.js:
+
</ins><span class="cx"> 2015-10-16  Brent Fulgham  &lt;bfulgham@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Hide all plugin names except Flash, Java, and QuickTime
</span></span></pre></div>
<a id="trunkLayoutTestsjsdomgetOwnPropertyDescriptorexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/dom/getOwnPropertyDescriptor-expected.txt (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/dom/getOwnPropertyDescriptor-expected.txt        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/LayoutTests/js/dom/getOwnPropertyDescriptor-expected.txt        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -157,11 +157,6 @@
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(document.getElementsByClassName('pass'), 'length').hasOwnProperty('writable') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(document.getElementsByClassName('pass'), 'length').enumerable is true
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(document.getElementsByClassName('pass'), 'length').configurable is false
</span><del>-PASS Object.getOwnPropertyDescriptor(canvasPixelArray, 'length').value is canvasPixelArray.length
-PASS Object.getOwnPropertyDescriptor(canvasPixelArray, 'length').hasOwnProperty('get') is false
-PASS Object.getOwnPropertyDescriptor(canvasPixelArray, 'length').hasOwnProperty('set') is false
-PASS Object.getOwnPropertyDescriptor(canvasPixelArray, 'length').enumerable is true
-PASS Object.getOwnPropertyDescriptor(canvasPixelArray, 'length').configurable is false
</del><span class="cx"> PASS Object.getOwnPropertyDescriptor(canvasPixelArray, 0).value is canvasPixelArray[0]
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(canvasPixelArray, 0).hasOwnProperty('get') is false
</span><span class="cx"> PASS Object.getOwnPropertyDescriptor(canvasPixelArray, 0).hasOwnProperty('set') is false
</span></span></pre></div>
<a id="trunkLayoutTestsjsresourcesgetOwnPropertyDescriptorjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/js/resources/getOwnPropertyDescriptor.js (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/resources/getOwnPropertyDescriptor.js        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/LayoutTests/js/resources/getOwnPropertyDescriptor.js        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -51,7 +51,6 @@
</span><span class="cx"> descriptorShouldBe(&quot;document.getElementsByClassName('pass')&quot;, &quot;'length'&quot;, {get: undefined, set: undefined, enumerable: true, configurable: false});
</span><span class="cx"> var canvas = document.createElement(&quot;canvas&quot;);
</span><span class="cx"> var canvasPixelArray = canvas.getContext(&quot;2d&quot;).createImageData(10,10).data;
</span><del>-descriptorShouldBe(&quot;canvasPixelArray&quot;, &quot;'length'&quot;, {writable: false, enumerable: true, configurable: false, value:&quot;canvasPixelArray.length&quot;});
</del><span class="cx"> descriptorShouldBe(&quot;canvasPixelArray&quot;, &quot;0&quot;, {writable: true, enumerable: true, configurable: false, value:&quot;canvasPixelArray[0]&quot;});
</span><span class="cx"> var select = document.createElement(&quot;select&quot;);
</span><span class="cx"> select.innerHTML = &quot;&lt;option&gt;foo&lt;/option&gt;&quot;;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -373,6 +373,7 @@
</span><span class="cx">     jit/ExecutableAllocatorFixedVMPool.cpp
</span><span class="cx">     jit/GCAwareJITStubRoutine.cpp
</span><span class="cx">     jit/HostCallReturnValue.cpp
</span><ins>+    jit/IntrinsicEmitter.cpp
</ins><span class="cx">     jit/JIT.cpp
</span><span class="cx">     jit/JITArithmetic.cpp
</span><span class="cx">     jit/JITArithmetic32_64.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -1,3 +1,157 @@
</span><ins>+2015-10-16  Keith Miller  &lt;keith@Keiths-MacBook-Pro-5.local&gt;
+
+        Add Intrinsic Getters and use them to fix performance on the getters of TypedArray properties.
+        https://bugs.webkit.org/show_bug.cgi?id=149687
+
+        Reviewed by Geoffrey Garen.
+
+        Add the ability to create intrinsic getters in both the inline cache and the DFG/FTL. When the
+        getter fetched by a GetById has an intrinsic we know about we add a new intrinsic access case.
+        Once we get to the DFG, we observe that the access case was an intrinsic and add an appropriate
+        GetByIdVariant. We then parse the intrinsic into an appropriate DFG node.
+
+        The first intrinsics are the new TypedArray prototype getters length, byteLength, and byteOffset.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/GetByIdStatus.cpp:
+        (JSC::GetByIdStatus::computeForStubInfoWithoutExitSiteFeedback):
+        (JSC::GetByIdStatus::computeFor):
+        * bytecode/GetByIdVariant.cpp:
+        (JSC::GetByIdVariant::GetByIdVariant):
+        (JSC::GetByIdVariant::operator=):
+        (JSC::GetByIdVariant::canMergeIntrinsicStructures):
+        (JSC::GetByIdVariant::attemptToMerge):
+        (JSC::GetByIdVariant::dumpInContext):
+        * bytecode/GetByIdVariant.h:
+        (JSC::GetByIdVariant::intrinsicFunction):
+        (JSC::GetByIdVariant::intrinsic):
+        (JSC::GetByIdVariant::callLinkStatus): Deleted.
+        * bytecode/PolymorphicAccess.cpp:
+        (JSC::AccessGenerationState::addWatchpoint):
+        (JSC::AccessGenerationState::restoreScratch):
+        (JSC::AccessGenerationState::succeed):
+        (JSC::AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling):
+        (JSC::AccessGenerationState::preserveLiveRegistersToStackForCall):
+        (JSC::AccessGenerationState::restoreLiveRegistersFromStackForCall):
+        (JSC::AccessGenerationState::restoreLiveRegistersFromStackForCallWithThrownException):
+        (JSC::AccessGenerationState::callSiteIndexForExceptionHandlingOrOriginal):
+        (JSC::AccessGenerationState::originalExceptionHandler):
+        (JSC::AccessGenerationState::originalCallSiteIndex):
+        (JSC::AccessCase::getIntrinsic):
+        (JSC::AccessCase::clone):
+        (JSC::AccessCase::visitWeak):
+        (JSC::AccessCase::generate):
+        (WTF::printInternal):
+        (JSC::AccessCase::AccessCase): Deleted.
+        (JSC::AccessCase::get): Deleted.
+        (JSC::AccessCase::replace): Deleted.
+        (JSC::AccessCase::transition): Deleted.
+        * bytecode/PolymorphicAccess.h:
+        (JSC::AccessCase::isGet):
+        (JSC::AccessCase::isPut):
+        (JSC::AccessCase::isIn):
+        (JSC::AccessCase::intrinsicFunction):
+        (JSC::AccessCase::intrinsic):
+        (JSC::AccessGenerationState::AccessGenerationState):
+        (JSC::AccessGenerationState::liveRegistersForCall):
+        (JSC::AccessGenerationState::callSiteIndexForExceptionHandling):
+        (JSC::AccessGenerationState::numberOfStackBytesUsedForRegisterPreservation):
+        (JSC::AccessGenerationState::needsToRestoreRegistersIfException):
+        (JSC::AccessGenerationState::liveRegistersToPreserveAtExceptionHandlingCallSite):
+        * bytecode/PutByIdVariant.h:
+        (JSC::PutByIdVariant::intrinsic):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGArrayMode.cpp:
+        (JSC::DFG::ArrayMode::alreadyChecked):
+        (JSC::DFG::arrayTypeToString):
+        (JSC::DFG::toTypedArrayType):
+        (JSC::DFG::refineTypedArrayType):
+        (JSC::DFG::permitsBoundsCheckLowering):
+        * dfg/DFGArrayMode.h:
+        (JSC::DFG::ArrayMode::supportsLength):
+        (JSC::DFG::ArrayMode::isSomeTypedArrayView):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::attemptToInlineCall):
+        (JSC::DFG::ByteCodeParser::handleIntrinsicCall):
+        (JSC::DFG::ByteCodeParser::handleIntrinsicGetter):
+        (JSC::DFG::ByteCodeParser::load):
+        (JSC::DFG::ByteCodeParser::handleGetById):
+        (JSC::DFG::ByteCodeParser::presenceLike): Deleted.
+        (JSC::DFG::ByteCodeParser::store): Deleted.
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        (JSC::DFG::FixupPhase::convertToGetArrayLength): Deleted.
+        (JSC::DFG::FixupPhase::prependGetArrayLength): Deleted.
+        (JSC::DFG::FixupPhase::fixupChecksInBlock): Deleted.
+        * dfg/DFGGraph.cpp:
+        (JSC::DFG::Graph::tryGetFoldableView):
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::checkArray):
+        (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileGetArrayLength):
+        * jit/IntrinsicEmitter.cpp: Added.
+        (JSC::AccessCase::canEmitIntrinsicGetter):
+        (JSC::AccessCase::emitIntrinsicGetter):
+        * jit/Repatch.cpp:
+        (JSC::tryCacheGetByID):
+        * runtime/Intrinsic.h:
+        * runtime/JSArrayBufferView.cpp:
+        (JSC::JSArrayBufferView::put):
+        (JSC::JSArrayBufferView::defineOwnProperty):
+        (JSC::JSArrayBufferView::deleteProperty):
+        (JSC::JSArrayBufferView::getOwnNonIndexPropertyNames):
+        (JSC::JSArrayBufferView::getOwnPropertySlot): Deleted.
+        (JSC::JSArrayBufferView::finalize): Deleted.
+        * runtime/JSDataView.cpp:
+        (JSC::JSDataView::getOwnPropertySlot):
+        (JSC::JSDataView::put):
+        (JSC::JSDataView::defineOwnProperty):
+        (JSC::JSDataView::deleteProperty):
+        (JSC::JSDataView::getOwnNonIndexPropertyNames):
+        * runtime/JSDataView.h:
+        * runtime/JSFunction.h:
+        * runtime/JSFunctionInlines.h:
+        (JSC::JSFunction::intrinsic):
+        * runtime/JSGenericTypedArrayView.h:
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::getOwnPropertySlot):
+        (JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::defineOwnProperty):
+        (JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::deleteProperty):
+        (JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::getOwnPropertySlotByIndex): Deleted.
+        (JSC::JSGenericTypedArrayView&lt;Adaptor&gt;::visitChildren): Deleted.
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::putDirectNativeIntrinsicGetter):
+        * runtime/JSObject.h:
+        * runtime/JSTypedArrayViewPrototype.cpp:
+        (JSC::JSTypedArrayViewPrototype::finishCreation):
+        * tests/stress/typedarray-add-property-to-base-object.js: Added.
+        (body.foo):
+        (body):
+        * tests/stress/typedarray-bad-getter.js: Added.
+        (body.foo):
+        (body.get Bar):
+        (body):
+        * tests/stress/typedarray-getter-on-self.js: Added.
+        (body.foo):
+        (body.bar):
+        (body.baz):
+        (body.get for):
+        (body):
+        * tests/stress/typedarray-intrinsic-getters-change-prototype.js: Added.
+        (body.foo):
+        (body.bar):
+        (body.baz):
+        (body):
+
</ins><span class="cx"> 2015-10-16  Keith Miller  &lt;keith_miller@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix some issues with TypedArrays
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -1724,6 +1724,7 @@
</span><span class="cx">                 C4F4B6F51A05C984005CAB76 /* generate_objc_protocol_types_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D71A05C76F005CAB76 /* generate_objc_protocol_types_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D81A05C76F005CAB76 /* objc_generator_templates.py */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */ = {isa = PBXBuildFile; fileRef = DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */; };
</span><ins>+                DE5A0A001BA3AC3E003D4424 /* IntrinsicEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */; };
</ins><span class="cx">                 DEA7E2441BBC677200D78440 /* JSTypedArrayViewPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */; };
</span><span class="cx">                 DEA7E2451BBC677F00D78440 /* JSTypedArrayViewPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 E124A8F70E555775003091F1 /* OpaqueJSString.h in Headers */ = {isa = PBXBuildFile; fileRef = E124A8F50E555775003091F1 /* OpaqueJSString.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -3617,6 +3618,7 @@
</span><span class="cx">                 D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPreciseLocalClobberize.h; path = dfg/DFGPreciseLocalClobberize.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicEmitter.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 E124A8F50E555775003091F1 /* OpaqueJSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueJSString.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E124A8F60E555775003091F1 /* OpaqueJSString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OpaqueJSString.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E178633F0D9BEC0000D74E75 /* InitializeThreading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeThreading.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4171,6 +4173,7 @@
</span><span class="cx">                                 0F24E53F17EA9F5900ABB217 /* GPRInfo.h */,
</span><span class="cx">                                 0F4680D014BBC5F800BFE272 /* HostCallReturnValue.cpp */,
</span><span class="cx">                                 0F4680D114BBC5F800BFE272 /* HostCallReturnValue.h */,
</span><ins>+                                DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */,
</ins><span class="cx">                                 1429D92D0ED22D7000B89619 /* JIT.cpp */,
</span><span class="cx">                                 1429D92E0ED22D7000B89619 /* JIT.h */,
</span><span class="cx">                                 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */,
</span><span class="lines">@@ -7506,6 +7509,7 @@
</span><span class="cx">                                 A77F1821164088B200640A47 /* CodeCache.cpp in Sources */,
</span><span class="cx">                                 0F8F9446166764F100D61971 /* CodeOrigin.cpp in Sources */,
</span><span class="cx">                                 86B5826714D2796C00A9C306 /* CodeProfile.cpp in Sources */,
</span><ins>+                                DE5A0A001BA3AC3E003D4424 /* IntrinsicEmitter.cpp in Sources */,
</ins><span class="cx">                                 86B5826914D2797000A9C306 /* CodeProfiling.cpp in Sources */,
</span><span class="cx">                                 0F8F943C1667631300D61971 /* CodeSpecializationKind.cpp in Sources */,
</span><span class="cx">                                 0F8F94421667633500D61971 /* CodeType.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdStatuscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdStatus.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -207,10 +207,16 @@
</span><span class="cx">                  
</span><span class="cx">             case ComplexGetStatus::Inlineable: {
</span><span class="cx">                 std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus;
</span><ins>+                JSFunction* intrinsicFunction = nullptr;
+
</ins><span class="cx">                 switch (access.type()) {
</span><span class="cx">                 case AccessCase::Load: {
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><ins>+                case AccessCase::IntrinsicGetter: {
+                    intrinsicFunction = access.intrinsicFunction();
+                    break;
+                }
</ins><span class="cx">                 case AccessCase::Getter: {
</span><span class="cx">                     CallLinkInfo* callLinkInfo = access.callLinkInfo();
</span><span class="cx">                     ASSERT(callLinkInfo);
</span><span class="lines">@@ -227,8 +233,9 @@
</span><span class="cx">                  
</span><span class="cx">                 GetByIdVariant variant(
</span><span class="cx">                     StructureSet(structure), complexGetStatus.offset(),
</span><del>-                    complexGetStatus.conditionSet(), WTF::move(callLinkStatus));
-                 
</del><ins>+                    complexGetStatus.conditionSet(), WTF::move(callLinkStatus),
+                    intrinsicFunction);
+
</ins><span class="cx">                 if (!result.appendVariant(variant))
</span><span class="cx">                     return GetByIdStatus(slowPathState, true);
</span><span class="cx">                 break;
</span><span class="lines">@@ -314,7 +321,7 @@
</span><span class="cx">         if (!isValidOffset(offset))
</span><span class="cx">             return GetByIdStatus(TakesSlowPath); // It's probably a prototype lookup. Give up on life for now, even though we could totally be way smarter about it.
</span><span class="cx">         if (attributes &amp; Accessor)
</span><del>-            return GetByIdStatus(MakesCalls); // We could be smarter here, like strenght-reducing this to a Call.
</del><ins>+            return GetByIdStatus(MakesCalls); // We could be smarter here, like strength-reducing this to a Call.
</ins><span class="cx">         
</span><span class="cx">         if (!result.appendVariant(GetByIdVariant(structure, offset)))
</span><span class="cx">             return GetByIdStatus(TakesSlowPath);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdVariantcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -35,16 +35,20 @@
</span><span class="cx"> GetByIdVariant::GetByIdVariant(
</span><span class="cx">     const StructureSet&amp; structureSet, PropertyOffset offset,
</span><span class="cx">     const ObjectPropertyConditionSet&amp; conditionSet,
</span><del>-    std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus)
</del><ins>+    std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus,
+    JSFunction* intrinsicFunction)
</ins><span class="cx">     : m_structureSet(structureSet)
</span><span class="cx">     , m_conditionSet(conditionSet)
</span><span class="cx">     , m_offset(offset)
</span><span class="cx">     , m_callLinkStatus(WTF::move(callLinkStatus))
</span><ins>+    , m_intrinsicFunction(intrinsicFunction)
</ins><span class="cx"> {
</span><span class="cx">     if (!structureSet.size()) {
</span><span class="cx">         ASSERT(offset == invalidOffset);
</span><span class="cx">         ASSERT(conditionSet.isEmpty());
</span><span class="cx">     }
</span><ins>+    if (intrinsicFunction)
+        ASSERT(intrinsic() != NoIntrinsic);
</ins><span class="cx"> }
</span><span class="cx">                      
</span><span class="cx"> GetByIdVariant::~GetByIdVariant() { }
</span><span class="lines">@@ -60,6 +64,7 @@
</span><span class="cx">     m_structureSet = other.m_structureSet;
</span><span class="cx">     m_conditionSet = other.m_conditionSet;
</span><span class="cx">     m_offset = other.m_offset;
</span><ins>+    m_intrinsicFunction = other.m_intrinsicFunction;
</ins><span class="cx">     if (other.m_callLinkStatus)
</span><span class="cx">         m_callLinkStatus = std::make_unique&lt;CallLinkStatus&gt;(*other.m_callLinkStatus);
</span><span class="cx">     else
</span><span class="lines">@@ -67,6 +72,27 @@
</span><span class="cx">     return *this;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline bool GetByIdVariant::canMergeIntrinsicStructures(const GetByIdVariant&amp; other) const
+{
+    if (m_intrinsicFunction != other.m_intrinsicFunction)
+        return false;
+    switch (intrinsic()) {
+    case TypedArrayByteLengthIntrinsic: {
+        // We can merge these sets as long as the element size of the two sets is the same.
+        TypedArrayType thisType = (*m_structureSet.begin())-&gt;classInfo()-&gt;typedArrayStorageType;
+        TypedArrayType otherType = (*other.m_structureSet.begin())-&gt;classInfo()-&gt;typedArrayStorageType;
+
+        ASSERT(isTypedView(thisType) &amp;&amp; isTypedView(otherType));
+
+        return logElementSize(thisType) == logElementSize(otherType);
+    }
+
+    default:
+        return true;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
</ins><span class="cx"> bool GetByIdVariant::attemptToMerge(const GetByIdVariant&amp; other)
</span><span class="cx"> {
</span><span class="cx">     if (m_offset != other.m_offset)
</span><span class="lines">@@ -74,6 +100,9 @@
</span><span class="cx">     if (m_callLinkStatus || other.m_callLinkStatus)
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!canMergeIntrinsicStructures(other))
+        return false;
+
</ins><span class="cx">     if (m_conditionSet.isEmpty() != other.m_conditionSet.isEmpty())
</span><span class="cx">         return false;
</span><span class="cx">     
</span><span class="lines">@@ -107,6 +136,8 @@
</span><span class="cx">     out.print(&quot;, offset = &quot;, offset());
</span><span class="cx">     if (m_callLinkStatus)
</span><span class="cx">         out.print(&quot;, call = &quot;, *m_callLinkStatus);
</span><ins>+    if (m_intrinsicFunction)
+        out.print(&quot;, intrinsic = &quot;, *m_intrinsicFunction);
</ins><span class="cx">     out.print(&quot;&gt;&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeGetByIdVarianth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/bytecode/GetByIdVariant.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -43,8 +43,9 @@
</span><span class="cx">     GetByIdVariant(
</span><span class="cx">         const StructureSet&amp; structureSet = StructureSet(), PropertyOffset offset = invalidOffset,
</span><span class="cx">         const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet(),
</span><del>-        std::unique_ptr&lt;CallLinkStatus&gt; callLinkStatus = nullptr);
-    
</del><ins>+        std::unique_ptr&lt;CallLinkStatus&gt; = nullptr,
+        JSFunction* = nullptr);
+
</ins><span class="cx">     ~GetByIdVariant();
</span><span class="cx">     
</span><span class="cx">     GetByIdVariant(const GetByIdVariant&amp;);
</span><span class="lines">@@ -60,7 +61,9 @@
</span><span class="cx">     
</span><span class="cx">     PropertyOffset offset() const { return m_offset; }
</span><span class="cx">     CallLinkStatus* callLinkStatus() const { return m_callLinkStatus.get(); }
</span><del>-    
</del><ins>+    JSFunction* intrinsicFunction() const { return m_intrinsicFunction; }
+    Intrinsic intrinsic() const { return m_intrinsicFunction ? m_intrinsicFunction-&gt;intrinsic() : NoIntrinsic; }
+
</ins><span class="cx">     bool attemptToMerge(const GetByIdVariant&amp; other);
</span><span class="cx">     
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="lines">@@ -68,11 +71,14 @@
</span><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     friend class GetByIdStatus;
</span><ins>+
+    bool canMergeIntrinsicStructures(const GetByIdVariant&amp;) const;
</ins><span class="cx">     
</span><span class="cx">     StructureSet m_structureSet;
</span><span class="cx">     ObjectPropertyConditionSet m_conditionSet;
</span><span class="cx">     PropertyOffset m_offset;
</span><span class="cx">     std::unique_ptr&lt;CallLinkStatus&gt; m_callLinkStatus;
</span><ins>+    JSFunction* m_intrinsicFunction;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -47,168 +47,108 @@
</span><span class="cx"> 
</span><span class="cx"> static const bool verbose = false;
</span><span class="cx"> 
</span><del>-struct AccessGenerationState {
-    AccessGenerationState() 
-        : m_calculatedRegistersForCallAndExceptionHandling(false)
-        , m_needsToRestoreRegistersIfException(false)
-        , m_calculatedCallSiteIndex(false)
-    {
-    }
-    CCallHelpers* jit { nullptr };
-    ScratchRegisterAllocator* allocator;
-    unsigned numberOfBytesUsedToPreserveReusedRegisters { 0 };
-    PolymorphicAccess* access { nullptr };
-    StructureStubInfo* stubInfo { nullptr };
-    CCallHelpers::JumpList success;
-    CCallHelpers::JumpList failAndRepatch;
-    CCallHelpers::JumpList failAndIgnore;
-    GPRReg baseGPR { InvalidGPRReg };
-    JSValueRegs valueRegs;
-    GPRReg scratchGPR { InvalidGPRReg };
-    Vector&lt;std::function&lt;void(LinkBuffer&amp;)&gt;&gt; callbacks;
-    const Identifier* ident;
-    std::unique_ptr&lt;WatchpointsOnStructureStubInfo&gt; watchpoints;
-    Vector&lt;WriteBarrier&lt;JSCell&gt;&gt; weakReferences;
</del><ins>+Watchpoint* AccessGenerationState::addWatchpoint(const ObjectPropertyCondition&amp; condition)
+{
+    return WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint(
+        watchpoints, jit-&gt;codeBlock(), stubInfo, condition);
+}
</ins><span class="cx"> 
</span><del>-    Watchpoint* addWatchpoint(const ObjectPropertyCondition&amp; condition = ObjectPropertyCondition())
-    {
-        return WatchpointsOnStructureStubInfo::ensureReferenceAndAddWatchpoint(
-            watchpoints, jit-&gt;codeBlock(), stubInfo, condition);
-    }
</del><ins>+void AccessGenerationState::restoreScratch()
+{
+    allocator-&gt;restoreReusedRegistersByPopping(*jit, numberOfBytesUsedToPreserveReusedRegisters);
+}
</ins><span class="cx"> 
</span><del>-    void restoreScratch()
-    {
-        allocator-&gt;restoreReusedRegistersByPopping(*jit, numberOfBytesUsedToPreserveReusedRegisters);
-    }
</del><ins>+void AccessGenerationState::succeed()
+{
+    restoreScratch();
+    success.append(jit-&gt;jump());
+}
</ins><span class="cx"> 
</span><del>-    void succeed()
-    {
-        restoreScratch();
-        success.append(jit-&gt;jump());
-    }
</del><ins>+void AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling()
+{
+    if (!m_calculatedRegistersForCallAndExceptionHandling) {
+        m_calculatedRegistersForCallAndExceptionHandling = true;
</ins><span class="cx"> 
</span><del>-    void calculateLiveRegistersForCallAndExceptionHandling()
-    {
-        if (!m_calculatedRegistersForCallAndExceptionHandling) {
-            m_calculatedRegistersForCallAndExceptionHandling = true;
</del><ins>+        m_liveRegistersToPreserveAtExceptionHandlingCallSite = jit-&gt;codeBlock()-&gt;jitCode()-&gt;liveRegistersToPreserveAtExceptionHandlingCallSite(jit-&gt;codeBlock(), stubInfo-&gt;callSiteIndex);
+        m_needsToRestoreRegistersIfException = m_liveRegistersToPreserveAtExceptionHandlingCallSite.numberOfSetRegisters() &gt; 0;
+        if (m_needsToRestoreRegistersIfException)
+            RELEASE_ASSERT(JITCode::isOptimizingJIT(jit-&gt;codeBlock()-&gt;jitType()));
</ins><span class="cx"> 
</span><del>-            m_liveRegistersToPreserveAtExceptionHandlingCallSite = jit-&gt;codeBlock()-&gt;jitCode()-&gt;liveRegistersToPreserveAtExceptionHandlingCallSite(jit-&gt;codeBlock(), stubInfo-&gt;callSiteIndex);
-            m_needsToRestoreRegistersIfException = m_liveRegistersToPreserveAtExceptionHandlingCallSite.numberOfSetRegisters() &gt; 0;
-            if (m_needsToRestoreRegistersIfException)
-                RELEASE_ASSERT(JITCode::isOptimizingJIT(jit-&gt;codeBlock()-&gt;jitType()));
-
-            m_liveRegistersForCall = RegisterSet(m_liveRegistersToPreserveAtExceptionHandlingCallSite, allocator-&gt;usedRegisters());
-            m_liveRegistersForCall.exclude(RegisterSet::registersToNotSaveForCall());
-        }
</del><ins>+        m_liveRegistersForCall = RegisterSet(m_liveRegistersToPreserveAtExceptionHandlingCallSite, allocator-&gt;usedRegisters());
+        m_liveRegistersForCall.exclude(RegisterSet::registersToNotSaveForCall());
</ins><span class="cx">     }
</span><ins>+}
</ins><span class="cx"> 
</span><del>-    void preserveLiveRegistersToStackForCall()
-    {
-        unsigned extraStackPadding = 0;
-        unsigned numberOfStackBytesUsedForRegisterPreservation = ScratchRegisterAllocator::preserveRegistersToStackForCall(*jit, liveRegistersForCall(), extraStackPadding);
-        if (m_numberOfStackBytesUsedForRegisterPreservation != std::numeric_limits&lt;unsigned&gt;::max())
-            RELEASE_ASSERT(numberOfStackBytesUsedForRegisterPreservation == m_numberOfStackBytesUsedForRegisterPreservation);
-        m_numberOfStackBytesUsedForRegisterPreservation = numberOfStackBytesUsedForRegisterPreservation;
-    }
</del><ins>+void AccessGenerationState::preserveLiveRegistersToStackForCall()
+{
+    unsigned extraStackPadding = 0;
+    unsigned numberOfStackBytesUsedForRegisterPreservation = ScratchRegisterAllocator::preserveRegistersToStackForCall(*jit, liveRegistersForCall(), extraStackPadding);
+    if (m_numberOfStackBytesUsedForRegisterPreservation != std::numeric_limits&lt;unsigned&gt;::max())
+        RELEASE_ASSERT(numberOfStackBytesUsedForRegisterPreservation == m_numberOfStackBytesUsedForRegisterPreservation);
+    m_numberOfStackBytesUsedForRegisterPreservation = numberOfStackBytesUsedForRegisterPreservation;
+}
</ins><span class="cx"> 
</span><del>-    void restoreLiveRegistersFromStackForCall(bool isGetter)
-    {
-        RegisterSet dontRestore;
-        if (isGetter) {
-            // This is the result value. We don't want to overwrite the result with what we stored to the stack.
-            // We sometimes have to store it to the stack just in case we throw an exception and need the original value.
-            dontRestore.set(valueRegs); 
-        }
-        restoreLiveRegistersFromStackForCall(dontRestore);
</del><ins>+void AccessGenerationState::restoreLiveRegistersFromStackForCall(bool isGetter)
+{
+    RegisterSet dontRestore;
+    if (isGetter) {
+        // This is the result value. We don't want to overwrite the result with what we stored to the stack.
+        // We sometimes have to store it to the stack just in case we throw an exception and need the original value.
+        dontRestore.set(valueRegs);
</ins><span class="cx">     }
</span><ins>+    restoreLiveRegistersFromStackForCall(dontRestore);
+}
</ins><span class="cx"> 
</span><del>-    void restoreLiveRegistersFromStackForCallWithThrownException()
-    {
-        // Even if we're a getter, we don't want to ignore the result value like we normally do 
-        // because the getter threw, and therefore, didn't return a value that means anything. 
-        // Instead, we want to restore that register to what it was upon entering the getter 
-        // inline cache. The subtlety here is if the base and the result are the same register, 
-        // and the getter threw, we want OSR exit to see the original base value, not the result 
-        // of the getter call.
-        RegisterSet dontRestore = liveRegistersForCall();
-        // As an optimization here, we only need to restore what is live for exception handling.
-        // We can construct the dontRestore set to accomplish this goal by having it contain only
-        // what is live for call but not live for exception handling. By ignoring things that are 
-        // only live at the call but not the exception handler, we will only restore things live 
-        // at the exception handler.
-        dontRestore.exclude(liveRegistersToPreserveAtExceptionHandlingCallSite());
-        restoreLiveRegistersFromStackForCall(dontRestore);
-    }
</del><ins>+void AccessGenerationState::restoreLiveRegistersFromStackForCallWithThrownException()
+{
+    // Even if we're a getter, we don't want to ignore the result value like we normally do
+    // because the getter threw, and therefore, didn't return a value that means anything.
+    // Instead, we want to restore that register to what it was upon entering the getter
+    // inline cache. The subtlety here is if the base and the result are the same register,
+    // and the getter threw, we want OSR exit to see the original base value, not the result
+    // of the getter call.
+    RegisterSet dontRestore = liveRegistersForCall();
+    // As an optimization here, we only need to restore what is live for exception handling.
+    // We can construct the dontRestore set to accomplish this goal by having it contain only
+    // what is live for call but not live for exception handling. By ignoring things that are
+    // only live at the call but not the exception handler, we will only restore things live
+    // at the exception handler.
+    dontRestore.exclude(liveRegistersToPreserveAtExceptionHandlingCallSite());
+    restoreLiveRegistersFromStackForCall(dontRestore);
+}
</ins><span class="cx"> 
</span><del>-    void restoreLiveRegistersFromStackForCall(const RegisterSet&amp; dontRestore)
-    {
-        unsigned extraStackPadding = 0;
-        ScratchRegisterAllocator::restoreRegistersFromStackForCall(*jit, liveRegistersForCall(), dontRestore, m_numberOfStackBytesUsedForRegisterPreservation, extraStackPadding);
-    }
</del><ins>+void AccessGenerationState::restoreLiveRegistersFromStackForCall(const RegisterSet&amp; dontRestore)
+{
+    unsigned extraStackPadding = 0;
+    ScratchRegisterAllocator::restoreRegistersFromStackForCall(*jit, liveRegistersForCall(), dontRestore, m_numberOfStackBytesUsedForRegisterPreservation, extraStackPadding);
+}
</ins><span class="cx"> 
</span><del>-    const RegisterSet&amp; liveRegistersForCall()
-    {
-        RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
-        return m_liveRegistersForCall;
-    }
</del><ins>+CallSiteIndex AccessGenerationState::callSiteIndexForExceptionHandlingOrOriginal()
+{
+    RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
</ins><span class="cx"> 
</span><del>-    CallSiteIndex callSiteIndexForExceptionHandlingOrOriginal()
-    {
-        RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
</del><ins>+    if (!m_calculatedCallSiteIndex) {
+        m_calculatedCallSiteIndex = true;
</ins><span class="cx"> 
</span><del>-        if (!m_calculatedCallSiteIndex) {
-            m_calculatedCallSiteIndex = true;
-
-            if (m_needsToRestoreRegistersIfException)
-                m_callSiteIndex = jit-&gt;codeBlock()-&gt;newExceptionHandlingCallSiteIndex(stubInfo-&gt;callSiteIndex);
-            else
-                m_callSiteIndex = originalCallSiteIndex();
-        }
-
-        return m_callSiteIndex;
</del><ins>+        if (m_needsToRestoreRegistersIfException)
+            m_callSiteIndex = jit-&gt;codeBlock()-&gt;newExceptionHandlingCallSiteIndex(stubInfo-&gt;callSiteIndex);
+        else
+            m_callSiteIndex = originalCallSiteIndex();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    CallSiteIndex callSiteIndexForExceptionHandling()
-    {
-        RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
-        RELEASE_ASSERT(m_needsToRestoreRegistersIfException);
-        RELEASE_ASSERT(m_calculatedCallSiteIndex);
-        return m_callSiteIndex;
-    }
</del><ins>+    return m_callSiteIndex;
+}
</ins><span class="cx"> 
</span><del>-    const HandlerInfo&amp; originalExceptionHandler() const
-    { 
-        RELEASE_ASSERT(m_needsToRestoreRegistersIfException);
-        HandlerInfo* exceptionHandler = jit-&gt;codeBlock()-&gt;handlerForIndex(stubInfo-&gt;callSiteIndex.bits());
-        RELEASE_ASSERT(exceptionHandler);
-        return *exceptionHandler;
-    }
</del><ins>+const HandlerInfo&amp; AccessGenerationState::originalExceptionHandler() const
+{
+    RELEASE_ASSERT(m_needsToRestoreRegistersIfException);
+    HandlerInfo* exceptionHandler = jit-&gt;codeBlock()-&gt;handlerForIndex(stubInfo-&gt;callSiteIndex.bits());
+    RELEASE_ASSERT(exceptionHandler);
+    return *exceptionHandler;
+}
</ins><span class="cx"> 
</span><del>-    unsigned numberOfStackBytesUsedForRegisterPreservation() const 
-    {
-        RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
-        return m_numberOfStackBytesUsedForRegisterPreservation; 
-    }
</del><ins>+CallSiteIndex AccessGenerationState::originalCallSiteIndex() const { return stubInfo-&gt;callSiteIndex; }
</ins><span class="cx"> 
</span><del>-    bool needsToRestoreRegistersIfException() const { return m_needsToRestoreRegistersIfException; }
-    CallSiteIndex originalCallSiteIndex() const { return stubInfo-&gt;callSiteIndex; }
-
-private:
-    const RegisterSet&amp; liveRegistersToPreserveAtExceptionHandlingCallSite()
-    {
-        RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
-        return m_liveRegistersToPreserveAtExceptionHandlingCallSite;
-    }
-    
-    RegisterSet m_liveRegistersToPreserveAtExceptionHandlingCallSite;
-    RegisterSet m_liveRegistersForCall;
-    CallSiteIndex m_callSiteIndex { CallSiteIndex(std::numeric_limits&lt;unsigned&gt;::max()) };
-    unsigned m_numberOfStackBytesUsedForRegisterPreservation { std::numeric_limits&lt;unsigned&gt;::max() };
-    bool m_calculatedRegistersForCallAndExceptionHandling : 1;
-    bool m_needsToRestoreRegistersIfException : 1;
-    bool m_calculatedCallSiteIndex : 1;
-};
-
</del><span class="cx"> AccessCase::AccessCase()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -319,6 +259,23 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+std::unique_ptr&lt;AccessCase&gt; AccessCase::getIntrinsic(
+    VM&amp; vm, JSCell* owner, JSFunction* getter, PropertyOffset offset,
+    Structure* structure, const ObjectPropertyConditionSet&amp; conditionSet)
+{
+    std::unique_ptr&lt;AccessCase&gt; result(new AccessCase());
+
+    result-&gt;m_type = IntrinsicGetter;
+    result-&gt;m_structure.set(vm, owner, structure);
+    result-&gt;m_conditionSet = conditionSet;
+    result-&gt;m_offset = offset;
+
+    result-&gt;m_rareData = std::make_unique&lt;RareData&gt;();
+    result-&gt;m_rareData-&gt;intrinsicFunction.set(vm, owner, getter);
+
+    return result;
+}
+
</ins><span class="cx"> AccessCase::~AccessCase()
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -355,6 +312,7 @@
</span><span class="cx">         // NOTE: We don't copy the callLinkInfo, since that's created during code generation.
</span><span class="cx">         result-&gt;m_rareData-&gt;customAccessor.opaque = rareData-&gt;customAccessor.opaque;
</span><span class="cx">         result-&gt;m_rareData-&gt;customSlotBase = rareData-&gt;customSlotBase;
</span><ins>+        result-&gt;m_rareData-&gt;intrinsicFunction = rareData-&gt;intrinsicFunction;
</ins><span class="cx">     }
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -440,6 +398,8 @@
</span><span class="cx">             m_rareData-&gt;callLinkInfo-&gt;visitWeak(vm);
</span><span class="cx">         if (m_rareData-&gt;customSlotBase &amp;&amp; !Heap::isMarked(m_rareData-&gt;customSlotBase.get()))
</span><span class="cx">             return false;
</span><ins>+        if (m_rareData-&gt;intrinsicFunction &amp;&amp; !Heap::isMarked(m_rareData-&gt;intrinsicFunction.get()))
+            return false;
</ins><span class="cx">     }
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="lines">@@ -1106,6 +1066,22 @@
</span><span class="cx">         jit.boxInt32(valueRegs.payloadGPR(), valueRegs);
</span><span class="cx">         state.succeed();
</span><span class="cx">         return;
</span><ins>+    }
+
+    case IntrinsicGetter: {
+        RELEASE_ASSERT(isValidOffset(offset()));
+
+        // We need to ensure the getter value does not move from under us. Note that GetterSetters
+        // are immutable so we just need to watch the property not any value inside it.
+        Structure* currStructure;
+        if (m_conditionSet.isEmpty())
+            currStructure = structure();
+        else
+            currStructure = m_conditionSet.slotBaseCondition().object()-&gt;structure();
+        currStructure-&gt;startWatchingPropertyForReplacements(vm, offset());
+
+        emitIntrinsicGetter(state);
+        return;
</ins><span class="cx">     } }
</span><span class="cx">     
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="lines">@@ -1441,6 +1417,9 @@
</span><span class="cx">     case AccessCase::CustomSetter:
</span><span class="cx">         out.print(&quot;CustomSetter&quot;);
</span><span class="cx">         return;
</span><ins>+    case AccessCase::IntrinsicGetter:
+        out.print(&quot;IntrinsicGetter&quot;);
+        return;
</ins><span class="cx">     case AccessCase::InHit:
</span><span class="cx">         out.print(&quot;InHit&quot;);
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePolymorphicAccessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(JIT)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CodeOrigin.h&quot;
</span><ins>+#include &quot;JSFunctionInlines.h&quot;
</ins><span class="cx"> #include &quot;MacroAssembler.h&quot;
</span><span class="cx"> #include &quot;ObjectPropertyConditionSet.h&quot;
</span><span class="cx"> #include &quot;Opcode.h&quot;
</span><span class="lines">@@ -41,6 +42,7 @@
</span><span class="cx"> class PolymorphicAccess;
</span><span class="cx"> class StructureStubInfo;
</span><span class="cx"> class WatchpointsOnStructureStubInfo;
</span><ins>+class ScratchRegisterAllocator;
</ins><span class="cx"> 
</span><span class="cx"> struct AccessGenerationState;
</span><span class="cx"> 
</span><span class="lines">@@ -57,6 +59,7 @@
</span><span class="cx">         Setter,
</span><span class="cx">         CustomGetter,
</span><span class="cx">         CustomSetter,
</span><ins>+        IntrinsicGetter,
</ins><span class="cx">         InHit,
</span><span class="cx">         InMiss,
</span><span class="cx">         ArrayLength,
</span><span class="lines">@@ -77,6 +80,7 @@
</span><span class="cx">         case Miss:
</span><span class="cx">         case Getter:
</span><span class="cx">         case CustomGetter:
</span><ins>+        case IntrinsicGetter:
</ins><span class="cx">         case ArrayLength:
</span><span class="cx">         case StringLength:
</span><span class="cx">             return true;
</span><span class="lines">@@ -90,6 +94,7 @@
</span><span class="cx">         case Miss:
</span><span class="cx">         case Getter:
</span><span class="cx">         case CustomGetter:
</span><ins>+        case IntrinsicGetter:
</ins><span class="cx">         case InHit:
</span><span class="cx">         case InMiss:
</span><span class="cx">         case ArrayLength:
</span><span class="lines">@@ -110,6 +115,7 @@
</span><span class="cx">         case Miss:
</span><span class="cx">         case Getter:
</span><span class="cx">         case CustomGetter:
</span><ins>+        case IntrinsicGetter:
</ins><span class="cx">         case Transition:
</span><span class="cx">         case Replace:
</span><span class="cx">         case Setter:
</span><span class="lines">@@ -147,6 +153,7 @@
</span><span class="cx">         const ObjectPropertyConditionSet&amp; = ObjectPropertyConditionSet());
</span><span class="cx"> 
</span><span class="cx">     static std::unique_ptr&lt;AccessCase&gt; getLength(VM&amp;, JSCell* owner, AccessType);
</span><ins>+    static std::unique_ptr&lt;AccessCase&gt; getIntrinsic(VM&amp;, JSCell* owner, JSFunction* intrinsic, PropertyOffset, Structure*, const ObjectPropertyConditionSet&amp;);
</ins><span class="cx">     
</span><span class="cx">     static std::unique_ptr&lt;AccessCase&gt; fromStructureStubInfo(VM&amp;, JSCell* owner, StructureStubInfo&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -173,6 +180,15 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     ObjectPropertyConditionSet conditionSet() const { return m_conditionSet; }
</span><ins>+    JSFunction* intrinsicFunction() const
+    {
+        ASSERT(type() == IntrinsicGetter &amp;&amp; m_rareData);
+        return m_rareData-&gt;intrinsicFunction.get();
+    }
+    Intrinsic intrinsic() const
+    {
+        return intrinsicFunction()-&gt;intrinsic();
+    }
</ins><span class="cx"> 
</span><span class="cx">     WatchpointSet* additionalSet() const
</span><span class="cx">     {
</span><span class="lines">@@ -220,6 +236,8 @@
</span><span class="cx">     // Is it still possible for this case to ever be taken?
</span><span class="cx">     bool couldStillSucceed() const;
</span><span class="cx"> 
</span><ins>+    static bool canEmitIntrinsicGetter(JSFunction*, Structure*);
+
</ins><span class="cx">     // If this method returns true, then it's a good idea to remove 'other' from the access once 'this'
</span><span class="cx">     // is added. This method assumes that in case of contradictions, 'this' represents a newer, and so
</span><span class="cx">     // more useful, truth. This method can be conservative; it will return false when it doubt.
</span><span class="lines">@@ -242,6 +260,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Fall through on success, add a jump to the failure list on failure.
</span><span class="cx">     void generate(AccessGenerationState&amp;);
</span><ins>+    void emitIntrinsicGetter(AccessGenerationState&amp;);
</ins><span class="cx">     
</span><span class="cx">     AccessType m_type { Load };
</span><span class="cx">     PropertyOffset m_offset { invalidOffset };
</span><span class="lines">@@ -271,6 +290,7 @@
</span><span class="cx">             void* opaque;
</span><span class="cx">         } customAccessor;
</span><span class="cx">         WriteBarrier&lt;JSObject&gt; customSlotBase;
</span><ins>+        WriteBarrier&lt;JSFunction&gt; intrinsicFunction;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;RareData&gt; m_rareData;
</span><span class="lines">@@ -320,6 +340,83 @@
</span><span class="cx">     std::unique_ptr&lt;Vector&lt;WriteBarrier&lt;JSCell&gt;&gt;&gt; m_weakReferences;
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+struct AccessGenerationState {
+    AccessGenerationState()
+    : m_calculatedRegistersForCallAndExceptionHandling(false)
+    , m_needsToRestoreRegistersIfException(false)
+    , m_calculatedCallSiteIndex(false)
+    {
+    }
+    CCallHelpers* jit { nullptr };
+    ScratchRegisterAllocator* allocator;
+    unsigned numberOfBytesUsedToPreserveReusedRegisters { 0 };
+    PolymorphicAccess* access { nullptr };
+    StructureStubInfo* stubInfo { nullptr };
+    MacroAssembler::JumpList success;
+    MacroAssembler::JumpList failAndRepatch;
+    MacroAssembler::JumpList failAndIgnore;
+    GPRReg baseGPR { InvalidGPRReg };
+    JSValueRegs valueRegs;
+    GPRReg scratchGPR { InvalidGPRReg };
+    Vector&lt;std::function&lt;void(LinkBuffer&amp;)&gt;&gt; callbacks;
+    const Identifier* ident;
+    std::unique_ptr&lt;WatchpointsOnStructureStubInfo&gt; watchpoints;
+    Vector&lt;WriteBarrier&lt;JSCell&gt;&gt; weakReferences;
+
+    Watchpoint* addWatchpoint(const ObjectPropertyCondition&amp; = ObjectPropertyCondition());
+
+    void restoreScratch();
+    void succeed();
+
+    void calculateLiveRegistersForCallAndExceptionHandling();
+
+    void preserveLiveRegistersToStackForCall();
+
+    void restoreLiveRegistersFromStackForCall(bool isGetter);
+    void restoreLiveRegistersFromStackForCallWithThrownException();
+    void restoreLiveRegistersFromStackForCall(const RegisterSet&amp; dontRestore);
+
+    const RegisterSet&amp; liveRegistersForCall()
+    {
+        RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
+        return m_liveRegistersForCall;
+    }
+
+    CallSiteIndex callSiteIndexForExceptionHandlingOrOriginal();
+    CallSiteIndex callSiteIndexForExceptionHandling()
+    {
+        RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
+        RELEASE_ASSERT(m_needsToRestoreRegistersIfException);
+        RELEASE_ASSERT(m_calculatedCallSiteIndex);
+        return m_callSiteIndex;
+    }
+
+    const HandlerInfo&amp; originalExceptionHandler() const;
+    unsigned numberOfStackBytesUsedForRegisterPreservation() const
+    {
+        RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
+        return m_numberOfStackBytesUsedForRegisterPreservation;
+    }
+
+    bool needsToRestoreRegistersIfException() const { return m_needsToRestoreRegistersIfException; }
+    CallSiteIndex originalCallSiteIndex() const;
+    
+private:
+    const RegisterSet&amp; liveRegistersToPreserveAtExceptionHandlingCallSite()
+    {
+        RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling);
+        return m_liveRegistersToPreserveAtExceptionHandlingCallSite;
+    }
+    
+    RegisterSet m_liveRegistersToPreserveAtExceptionHandlingCallSite;
+    RegisterSet m_liveRegistersForCall;
+    CallSiteIndex m_callSiteIndex { CallSiteIndex(std::numeric_limits&lt;unsigned&gt;::max()) };
+    unsigned m_numberOfStackBytesUsedForRegisterPreservation { std::numeric_limits&lt;unsigned&gt;::max() };
+    bool m_calculatedRegistersForCallAndExceptionHandling : 1;
+    bool m_needsToRestoreRegistersIfException : 1;
+    bool m_calculatedCallSiteIndex : 1;
+};
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodePutByIdVarianth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/bytecode/PutByIdVariant.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -110,6 +110,9 @@
</span><span class="cx">     
</span><span class="cx">     const ObjectPropertyConditionSet&amp; conditionSet() const { return m_conditionSet; }
</span><span class="cx">     
</span><ins>+    // We don't support intrinsics for Setters (it would be sweet if we did) but we need this for templated helpers.
+    Intrinsic intrinsic() const { return NoIntrinsic; }
+    
</ins><span class="cx">     PropertyOffset offset() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(isSet());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -2022,6 +2022,9 @@
</span><span class="cx">         case Array::Float64Array:
</span><span class="cx">             filter(node-&gt;child1(), SpecFloat64Array);
</span><span class="cx">             break;
</span><ins>+        case Array::AnyTypedArray:
+            filter(node-&gt;child1(), SpecTypedArrayView);
+            break;
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">             break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArrayModecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/dfg/DFGArrayMode.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -485,7 +485,10 @@
</span><span class="cx"> 
</span><span class="cx">     case Array::Float64Array:
</span><span class="cx">         return speculationChecked(value.m_type, SpecFloat64Array);
</span><del>-        
</del><ins>+
+    case Array::AnyTypedArray:
+        return speculationChecked(value.m_type, SpecTypedArrayView);
+
</ins><span class="cx">     case Array::SelectUsingPredictions:
</span><span class="cx">     case Array::Unprofiled:
</span><span class="cx">     case Array::SelectUsingArguments:
</span><span class="lines">@@ -545,6 +548,8 @@
</span><span class="cx">         return &quot;Float32Array&quot;;
</span><span class="cx">     case Array::Float64Array:
</span><span class="cx">         return &quot;Float64Array&quot;;
</span><ins>+    case Array::AnyTypedArray:
+        return &quot;AnyTypedArray&quot;;
</ins><span class="cx">     default:
</span><span class="cx">         // Better to return something then it is to crash. Remember, this method
</span><span class="cx">         // is being called from our main diagnostic tool, the IR dumper. It's like
</span><span class="lines">@@ -639,6 +644,9 @@
</span><span class="cx">         return TypeFloat32;
</span><span class="cx">     case Array::Float64Array:
</span><span class="cx">         return TypeFloat64;
</span><ins>+    case Array::AnyTypedArray:
+        RELEASE_ASSERT_NOT_REACHED();
+        return NotTypedArray;
</ins><span class="cx">     default:
</span><span class="cx">         return NotTypedArray;
</span><span class="cx">     }
</span><span class="lines">@@ -670,6 +678,19 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Array::Type refineTypedArrayType(Array::Type oldType, TypedArrayType newType)
+{
+    if (oldType == Array::Generic)
+        return oldType;
+    Array::Type newArrayType = toArrayType(newType);
+    if (newArrayType == Array::Generic)
+        return newArrayType;
+
+    if (oldType != newArrayType)
+        return Array::AnyTypedArray;
+    return oldType;
+}
+
</ins><span class="cx"> bool permitsBoundsCheckLowering(Array::Type type)
</span><span class="cx"> {
</span><span class="cx">     switch (type) {
</span><span class="lines">@@ -685,6 +706,7 @@
</span><span class="cx">     case Array::Uint32Array:
</span><span class="cx">     case Array::Float32Array:
</span><span class="cx">     case Array::Float64Array:
</span><ins>+    case Array::AnyTypedArray:
</ins><span class="cx">         return true;
</span><span class="cx">     default:
</span><span class="cx">         // These don't allow for bounds check lowering either because the bounds
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGArrayModeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/dfg/DFGArrayMode.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -77,7 +77,8 @@
</span><span class="cx">     Uint16Array,
</span><span class="cx">     Uint32Array,
</span><span class="cx">     Float32Array,
</span><del>-    Float64Array
</del><ins>+    Float64Array,
+    AnyTypedArray
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> enum Class {
</span><span class="lines">@@ -110,6 +111,7 @@
</span><span class="cx"> 
</span><span class="cx"> TypedArrayType toTypedArrayType(Array::Type);
</span><span class="cx"> Array::Type toArrayType(TypedArrayType);
</span><ins>+Array::Type refineTypedArrayType(Array::Type, TypedArrayType);
</ins><span class="cx"> 
</span><span class="cx"> bool permitsBoundsCheckLowering(Array::Type);
</span><span class="cx"> 
</span><span class="lines">@@ -354,6 +356,16 @@
</span><span class="cx">         case Array::Unprofiled:
</span><span class="cx">         case Array::ForceExit:
</span><span class="cx">         case Array::Generic:
</span><ins>+        // TypedArrays do not have a self length property as of ES6.
+        case Array::Int8Array:
+        case Array::Int16Array:
+        case Array::Int32Array:
+        case Array::Uint8Array:
+        case Array::Uint8ClampedArray:
+        case Array::Uint16Array:
+        case Array::Uint32Array:
+        case Array::Float32Array:
+        case Array::Float64Array:
</ins><span class="cx">             return false;
</span><span class="cx">         case Array::Int32:
</span><span class="cx">         case Array::Double:
</span><span class="lines">@@ -430,6 +442,11 @@
</span><span class="cx">     {
</span><span class="cx">         return toTypedArrayType(type());
</span><span class="cx">     }
</span><ins>+
+    bool isSomeTypedArrayView() const
+    {
+        return type() == Array::AnyTypedArray || isTypedView(typedArrayType());
+    }
</ins><span class="cx">     
</span><span class="cx">     bool operator==(const ArrayMode&amp; other) const
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -201,8 +201,10 @@
</span><span class="cx">     void cancelLinkingForBlock(InlineStackEntry*, BasicBlock*); // Only works when the given block is the last one to have been added for that inline stack entry.
</span><span class="cx">     // Handle intrinsic functions. Return true if it succeeded, false if we need to plant a call.
</span><span class="cx">     template&lt;typename ChecksFunctor&gt;
</span><del>-    bool handleIntrinsic(int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor&amp; insertChecks);
</del><ins>+    bool handleIntrinsicCall(int resultOperand, Intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor&amp; insertChecks);
</ins><span class="cx">     template&lt;typename ChecksFunctor&gt;
</span><ins>+    bool handleIntrinsicGetter(int resultOperand, const GetByIdVariant&amp; intrinsicVariant, Node* thisNode, const ChecksFunctor&amp; insertChecks);
+    template&lt;typename ChecksFunctor&gt;
</ins><span class="cx">     bool handleTypedArrayConstructor(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, TypedArrayType, const ChecksFunctor&amp; insertChecks);
</span><span class="cx">     template&lt;typename ChecksFunctor&gt;
</span><span class="cx">     bool handleConstantInternalFunction(int resultOperand, InternalFunction*, int registerOffset, int argumentCountIncludingThis, CodeSpecializationKind, const ChecksFunctor&amp; insertChecks);
</span><span class="lines">@@ -1590,7 +1592,7 @@
</span><span class="cx">     
</span><span class="cx">         Intrinsic intrinsic = callee.intrinsicFor(specializationKind);
</span><span class="cx">         if (intrinsic != NoIntrinsic) {
</span><del>-            if (handleIntrinsic(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
</del><ins>+            if (handleIntrinsicCall(resultOperand, intrinsic, registerOffset, argumentCountIncludingThis, prediction, insertChecksWithAccounting)) {
</ins><span class="cx">                 RELEASE_ASSERT(didInsertChecks);
</span><span class="cx">                 addToGraph(Phantom, callTargetNode);
</span><span class="cx">                 emitArgumentPhantoms(registerOffset, argumentCountIncludingThis);
</span><span class="lines">@@ -1980,9 +1982,12 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename ChecksFunctor&gt;
</span><del>-bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor&amp; insertChecks)
</del><ins>+bool ByteCodeParser::handleIntrinsicCall(int resultOperand, Intrinsic intrinsic, int registerOffset, int argumentCountIncludingThis, SpeculatedType prediction, const ChecksFunctor&amp; insertChecks)
</ins><span class="cx"> {
</span><span class="cx">     switch (intrinsic) {
</span><ins>+
+    // Intrinsic Functions:
+
</ins><span class="cx">     case AbsIntrinsic: {
</span><span class="cx">         if (argumentCountIncludingThis == 1) { // Math.abs()
</span><span class="cx">             insertChecks();
</span><span class="lines">@@ -2269,6 +2274,80 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename ChecksFunctor&gt;
</span><ins>+bool ByteCodeParser::handleIntrinsicGetter(int resultOperand, const GetByIdVariant&amp; variant, Node* thisNode, const ChecksFunctor&amp; insertChecks)
+{
+    switch (variant.intrinsic()) {
+    case TypedArrayByteLengthIntrinsic: {
+        insertChecks();
+
+        TypedArrayType type = (*variant.structureSet().begin())-&gt;classInfo()-&gt;typedArrayStorageType;
+        Array::Type arrayType = toArrayType(type);
+        size_t logSize = logElementSize(type);
+
+        variant.structureSet().forEach([&amp;] (Structure* structure) {
+            TypedArrayType curType = structure-&gt;classInfo()-&gt;typedArrayStorageType;
+            ASSERT(logSize == logElementSize(curType));
+            arrayType = refineTypedArrayType(arrayType, curType);
+            ASSERT(arrayType != Array::Generic);
+        });
+
+        Node* lengthNode = addToGraph(GetArrayLength, OpInfo(ArrayMode(arrayType).asWord()), thisNode);
+
+        if (!logSize) {
+            set(VirtualRegister(resultOperand), lengthNode);
+            return true;
+        }
+
+        // We can use a BitLShift here because typed arrays will never have a byteLength
+        // that overflows int32.
+        Node* shiftNode = jsConstant(jsNumber(logSize));
+        set(VirtualRegister(resultOperand), addToGraph(BitLShift, lengthNode, shiftNode));
+
+        return true;
+    }
+
+    case TypedArrayLengthIntrinsic: {
+        insertChecks();
+
+        TypedArrayType type = (*variant.structureSet().begin())-&gt;classInfo()-&gt;typedArrayStorageType;
+        Array::Type arrayType = toArrayType(type);
+
+        variant.structureSet().forEach([&amp;] (Structure* structure) {
+            TypedArrayType curType = structure-&gt;classInfo()-&gt;typedArrayStorageType;
+            arrayType = refineTypedArrayType(arrayType, curType);
+            ASSERT(arrayType != Array::Generic);
+        });
+
+        set(VirtualRegister(resultOperand), addToGraph(GetArrayLength, OpInfo(ArrayMode(arrayType).asWord()), thisNode));
+
+        return true;
+
+    }
+
+    case TypedArrayByteOffsetIntrinsic: {
+        insertChecks();
+
+        TypedArrayType type = (*variant.structureSet().begin())-&gt;classInfo()-&gt;typedArrayStorageType;
+        Array::Type arrayType = toArrayType(type);
+
+        variant.structureSet().forEach([&amp;] (Structure* structure) {
+            TypedArrayType curType = structure-&gt;classInfo()-&gt;typedArrayStorageType;
+            arrayType = refineTypedArrayType(arrayType, curType);
+            ASSERT(arrayType != Array::Generic);
+        });
+
+        set(VirtualRegister(resultOperand), addToGraph(GetTypedArrayByteOffset, OpInfo(ArrayMode(arrayType).asWord()), thisNode));
+
+        return true;
+    }
+
+    default:
+        return false;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+template&lt;typename ChecksFunctor&gt;
</ins><span class="cx"> bool ByteCodeParser::handleTypedArrayConstructor(
</span><span class="cx">     int resultOperand, InternalFunction* function, int registerOffset,
</span><span class="cx">     int argumentCountIncludingThis, TypedArrayType type, const ChecksFunctor&amp; insertChecks)
</span><span class="lines">@@ -2692,7 +2771,7 @@
</span><span class="cx">     
</span><span class="cx">     SpeculatedType loadPrediction;
</span><span class="cx">     NodeType loadOp;
</span><del>-    if (variant.callLinkStatus()) {
</del><ins>+    if (variant.callLinkStatus() || variant.intrinsic() != NoIntrinsic) {
</ins><span class="cx">         loadPrediction = SpecCellOther;
</span><span class="cx">         loadOp = GetGetterSetterByOffset;
</span><span class="cx">     } else {
</span><span class="lines">@@ -2763,6 +2842,12 @@
</span><span class="cx">         //    optimal, if there is some rarely executed case in the chain that requires a lot
</span><span class="cx">         //    of checks and those checks are not watchpointable.
</span><span class="cx">         for (const GetByIdVariant&amp; variant : getByIdStatus.variants()) {
</span><ins>+            if (variant.intrinsic() != NoIntrinsic) {
+                set(VirtualRegister(destinationOperand),
+                    addToGraph(getById, OpInfo(identifierNumber), OpInfo(prediction), base));
+                return;
+            }
+
</ins><span class="cx">             if (variant.conditionSet().isEmpty()) {
</span><span class="cx">                 cases.append(
</span><span class="cx">                     MultiGetByOffsetCase(
</span><span class="lines">@@ -2805,14 +2890,25 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_graph.compilation())
</span><span class="cx">         m_graph.compilation()-&gt;noticeInlinedGetById();
</span><del>-    
-    if (!variant.callLinkStatus()) {
</del><ins>+
+    if (!variant.callLinkStatus() &amp;&amp; variant.intrinsic() == NoIntrinsic) {
</ins><span class="cx">         set(VirtualRegister(destinationOperand), loadedValue);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     Node* getter = addToGraph(GetGetter, loadedValue);
</span><del>-    
</del><ins>+
+    if (handleIntrinsicGetter(destinationOperand, variant, base,
+            [&amp;] () {
+                addToGraph(CheckCell, OpInfo(m_graph.freeze(variant.intrinsicFunction())), getter, base);
+            })) {
+        addToGraph(Phantom, getter);
+        return;
+    }
+
+    if (variant.intrinsic() != NoIntrinsic)
+        ASSERT(variant.intrinsic() == NoIntrinsic);
+
</ins><span class="cx">     // Make a call. We don't try to get fancy with using the smallest operand number because
</span><span class="cx">     // the stack layout phase should compress the stack anyway.
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -575,6 +575,11 @@
</span><span class="cx">             read(MiscFields);
</span><span class="cx">             def(HeapLocation(IndexedPropertyLoc, TypedArrayProperties, node-&gt;child1(), node-&gt;child2()), LazyNode(node));
</span><span class="cx">             return;
</span><ins>+        // We should not get an AnyTypedArray in a GetByVal as AnyTypedArray is only created from intrinsics, which
+        // are only added from Inline Caching a GetById.
+        case Array::AnyTypedArray:
+            DFG_CRASH(graph, node, &quot;impossible array mode for get&quot;);
+            return;
</ins><span class="cx">         }
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         return;
</span><span class="lines">@@ -679,6 +684,7 @@
</span><span class="cx">             // FIXME: We can't def() anything here because these operations truncate their inputs.
</span><span class="cx">             // https://bugs.webkit.org/show_bug.cgi?id=134737
</span><span class="cx">             return;
</span><ins>+        case Array::AnyTypedArray:
</ins><span class="cx">         case Array::String:
</span><span class="cx">         case Array::DirectArguments:
</span><span class="cx">         case Array::ScopedArguments:
</span><span class="lines">@@ -818,15 +824,15 @@
</span><span class="cx">         case Array::String:
</span><span class="cx">             def(PureValue(node, mode.asWord()));
</span><span class="cx">             return;
</span><del>-            
</del><ins>+
</ins><span class="cx">         case Array::DirectArguments:
</span><span class="cx">         case Array::ScopedArguments:
</span><span class="cx">             read(MiscFields);
</span><span class="cx">             def(HeapLocation(ArrayLengthLoc, MiscFields, node-&gt;child1()), LazyNode(node));
</span><span class="cx">             return;
</span><del>-            
</del><ins>+
</ins><span class="cx">         default:
</span><del>-            ASSERT(mode.typedArrayType() != NotTypedArray);
</del><ins>+            ASSERT(mode.isSomeTypedArrayView());
</ins><span class="cx">             read(MiscFields);
</span><span class="cx">             def(HeapLocation(ArrayLengthLoc, MiscFields, node-&gt;child1()), LazyNode(node));
</span><span class="cx">             return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -1036,14 +1036,6 @@
</span><span class="cx">                     attemptToMakeGetArrayLength(node);
</span><span class="cx">                     break;
</span><span class="cx">                 }
</span><del>-                if (uid == vm().propertyNames-&gt;byteLength.impl()) {
-                    attemptToMakeGetTypedArrayByteLength(node);
-                    break;
-                }
-                if (uid == vm().propertyNames-&gt;byteOffset.impl()) {
-                    attemptToMakeGetTypedArrayByteOffset(node);
-                    break;
-                }
</del><span class="cx">             }
</span><span class="cx">             fixEdge&lt;CellUse&gt;(node-&gt;child1());
</span><span class="cx">             break;
</span><span class="lines">@@ -1163,11 +1155,19 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        case GetArrayLength:
</del><ins>+        case GetArrayLength: {
+            fixEdge&lt;KnownCellUse&gt;(node-&gt;child1());
+            break;
+        }
+
+        case GetTypedArrayByteOffset: {
+            fixEdge&lt;KnownCellUse&gt;(node-&gt;child1());
+            break;
+        }
+
</ins><span class="cx">         case Phi:
</span><span class="cx">         case Upsilon:
</span><span class="cx">         case GetIndexedPropertyStorage:
</span><del>-        case GetTypedArrayByteOffset:
</del><span class="cx">         case LastNodeType:
</span><span class="cx">         case CheckTierUpInLoop:
</span><span class="cx">         case CheckTierUpAtReturn:
</span><span class="lines">@@ -2064,39 +2064,7 @@
</span><span class="cx">         convertToGetArrayLength(node, arrayMode);
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><del>-    
-    bool attemptToMakeGetTypedArrayByteLength(Node* node)
-    {
-        if (!isInt32Speculation(node-&gt;prediction()))
-            return false;
-        
-        TypedArrayType type = typedArrayTypeFromSpeculation(node-&gt;child1()-&gt;prediction());
-        if (!isTypedView(type))
-            return false;
-        
-        if (elementSize(type) == 1) {
-            convertToGetArrayLength(node, ArrayMode(toArrayType(type)));
-            return true;
-        }
-        
-        Node* length = prependGetArrayLength(
-            node-&gt;origin, node-&gt;child1().node(), ArrayMode(toArrayType(type)));
-        
-        Node* shiftAmount = m_insertionSet.insertNode(
-            m_indexInBlock, SpecInt32, JSConstant, node-&gt;origin,
-            OpInfo(m_graph.freeze(jsNumber(logElementSize(type)))));
-        
-        // We can use a BitLShift here because typed arrays will never have a byteLength
-        // that overflows int32.
-        node-&gt;setOp(BitLShift);
-        node-&gt;clearFlags(NodeMustGenerate);
-        observeUseKindOnNode(length, Int32Use);
-        observeUseKindOnNode(shiftAmount, Int32Use);
-        node-&gt;child1() = Edge(length, Int32Use);
-        node-&gt;child2() = Edge(shiftAmount, Int32Use);
-        return true;
-    }
-    
</del><ins>+
</ins><span class="cx">     void convertToGetArrayLength(Node* node, ArrayMode arrayMode)
</span><span class="cx">     {
</span><span class="cx">         node-&gt;setOp(GetArrayLength);
</span><span class="lines">@@ -2119,25 +2087,6 @@
</span><span class="cx">             OpInfo(arrayMode.asWord()), Edge(child, KnownCellUse), Edge(storage));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    bool attemptToMakeGetTypedArrayByteOffset(Node* node)
-    {
-        if (!isInt32Speculation(node-&gt;prediction()))
-            return false;
-        
-        TypedArrayType type = typedArrayTypeFromSpeculation(node-&gt;child1()-&gt;prediction());
-        if (!isTypedView(type))
-            return false;
-        
-        checkArray(
-            ArrayMode(toArrayType(type)), node-&gt;origin, node-&gt;child1().node(),
-            0, neverNeedsStorage);
-        
-        node-&gt;setOp(GetTypedArrayByteOffset);
-        node-&gt;clearFlags(NodeMustGenerate);
-        fixEdge&lt;KnownCellUse&gt;(node-&gt;child1());
-        return true;
-    }
-    
</del><span class="cx">     void fixupChecksInBlock(BasicBlock* block)
</span><span class="cx">     {
</span><span class="cx">         if (!block)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGGraphcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -1215,7 +1215,7 @@
</span><span class="cx"> 
</span><span class="cx"> JSArrayBufferView* Graph::tryGetFoldableView(JSValue value, ArrayMode arrayMode)
</span><span class="cx"> {
</span><del>-    if (arrayMode.typedArrayType() == NotTypedArray)
</del><ins>+    if (arrayMode.type() != Array::AnyTypedArray &amp;&amp; arrayMode.typedArrayType() == NotTypedArray)
</ins><span class="cx">         return nullptr;
</span><span class="cx">     return tryGetFoldableView(value);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -230,6 +230,12 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><ins>+        case GetTypedArrayByteOffset:
+        case GetArrayLength: {
+            changed |= setPrediction(SpecInt32);
+            break;
+        }
+
</ins><span class="cx">         case StringCharCodeAt: {
</span><span class="cx">             changed |= setPrediction(SpecInt32);
</span><span class="cx">             break;
</span><span class="lines">@@ -540,8 +546,6 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         case PutByValAlias:
</span><del>-        case GetArrayLength:
-        case GetTypedArrayByteOffset:
</del><span class="cx">         case DoubleAsInt32:
</span><span class="cx">         case GetLocalUnlinked:
</span><span class="cx">         case CheckArray:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -767,6 +767,7 @@
</span><span class="cx">     const ClassInfo* expectedClassInfo = 0;
</span><span class="cx">     
</span><span class="cx">     switch (node-&gt;arrayMode().type()) {
</span><ins>+    case Array::AnyTypedArray:
</ins><span class="cx">     case Array::String:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED(); // Should have been a Phantom(String:)
</span><span class="cx">         break;
</span><span class="lines">@@ -4665,7 +4666,7 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx">     default: {
</span><del>-        ASSERT(isTypedView(node-&gt;arrayMode().typedArrayType()));
</del><ins>+        ASSERT(node-&gt;arrayMode().isSomeTypedArrayView());
</ins><span class="cx">         SpeculateCellOperand base(this, node-&gt;child1());
</span><span class="cx">         GPRTemporary result(this, Reuse, base);
</span><span class="cx">         GPRReg baseGPR = base.gpr();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -251,7 +251,7 @@
</span><span class="cx">         case Array::ScopedArguments:
</span><span class="cx">             break;
</span><span class="cx">         default:
</span><del>-            if (isTypedView(node-&gt;arrayMode().typedArrayType()))
</del><ins>+            if (node-&gt;arrayMode().isSomeTypedArrayView())
</ins><span class="cx">                 break;
</span><span class="cx">             return CannotCompile;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -2410,7 +2410,7 @@
</span><span class="cx">         }
</span><span class="cx">             
</span><span class="cx">         default:
</span><del>-            if (isTypedView(m_node-&gt;arrayMode().typedArrayType())) {
</del><ins>+            if (m_node-&gt;arrayMode().isSomeTypedArrayView()) {
</ins><span class="cx">                 setInt32(
</span><span class="cx">                     m_out.load32NonNegative(lowCell(m_node-&gt;child1()), m_heaps.JSArrayBufferView_length));
</span><span class="cx">                 return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitIntrinsicEmittercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp (0 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -0,0 +1,130 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Inc. (&quot;Apple&quot;) nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+
+#include &quot;CCallHelpers.h&quot;
+#include &quot;CallFrame.h&quot;
+#include &quot;CodeBlock.h&quot;
+#include &quot;JSArrayBufferView.h&quot;
+#include &quot;JSCJSValueInlines.h&quot;
+#include &quot;JSCellInlines.h&quot;
+#include &quot;PolymorphicAccess.h&quot;
+
+namespace JSC {
+
+typedef CCallHelpers::TrustedImm32 TrustedImm32;
+typedef CCallHelpers::Imm32 Imm32;
+typedef CCallHelpers::TrustedImmPtr TrustedImmPtr;
+typedef CCallHelpers::ImmPtr ImmPtr;
+typedef CCallHelpers::TrustedImm64 TrustedImm64;
+typedef CCallHelpers::Imm64 Imm64;
+
+bool AccessCase::canEmitIntrinsicGetter(JSFunction* getter, Structure* structure)
+{
+
+    switch (getter-&gt;intrinsic()) {
+    case TypedArrayByteOffsetIntrinsic:
+    case TypedArrayByteLengthIntrinsic:
+    case TypedArrayLengthIntrinsic: {
+        TypedArrayType type = structure-&gt;classInfo()-&gt;typedArrayStorageType;
+
+        if (!isTypedView(type))
+            return false;
+        
+        return true;
+    }
+    default:
+        return false;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+void AccessCase::emitIntrinsicGetter(AccessGenerationState&amp; state)
+{
+    CCallHelpers&amp; jit = *state.jit;
+    JSValueRegs valueRegs = state.valueRegs;
+    GPRReg baseGPR = state.baseGPR;
+    GPRReg valueGPR = valueRegs.payloadGPR();
+
+    switch (intrinsic()) {
+    case TypedArrayLengthIntrinsic: {
+        jit.load32(MacroAssembler::Address(state.baseGPR, JSArrayBufferView::offsetOfLength()), valueGPR);
+        jit.boxInt32(valueGPR, valueRegs);
+        state.succeed();
+        return;
+    }
+
+    case TypedArrayByteLengthIntrinsic: {
+        TypedArrayType type = structure()-&gt;classInfo()-&gt;typedArrayStorageType;
+
+        jit.load32(MacroAssembler::Address(state.baseGPR, JSArrayBufferView::offsetOfLength()), valueGPR);
+
+        if (elementSize(type) &gt; 1) {
+            // We can use a bitshift here since we TypedArrays cannot have byteLength that overflows an int32.
+            jit.lshift32(valueGPR, Imm32(logElementSize(type)), valueGPR);
+        }
+
+        jit.boxInt32(valueGPR, valueRegs);
+        state.succeed();
+        return;
+    }
+
+    case TypedArrayByteOffsetIntrinsic: {
+        GPRReg scratchGPR = state.scratchGPR;
+
+        CCallHelpers::Jump emptyByteOffset = jit.branch32(
+            MacroAssembler::NotEqual,
+            MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfMode()),
+            TrustedImm32(WastefulTypedArray));
+
+        jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR);
+        jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfVector()), valueGPR);
+        jit.loadPtr(MacroAssembler::Address(scratchGPR, Butterfly::offsetOfArrayBuffer()), scratchGPR);
+        jit.loadPtr(MacroAssembler::Address(scratchGPR, ArrayBuffer::offsetOfData()), scratchGPR);
+        jit.subPtr(scratchGPR, valueGPR);
+
+        CCallHelpers::Jump done = jit.jump();
+        
+        emptyByteOffset.link(&amp;jit);
+        jit.move(TrustedImmPtr(0), valueGPR);
+        
+        done.link(&amp;jit);
+        
+        jit.boxInt32(valueGPR, valueRegs);
+        state.succeed();
+        return;
+    }
+
+    default:
+        break;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace JSC
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitRepatchcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/Repatch.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/Repatch.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/jit/Repatch.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -224,18 +224,31 @@
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;AccessCase&gt; newCase;
</span><ins>+    JSFunction* getter = nullptr;
+    ObjectPropertyConditionSet conditionSet;
+    JSCell* baseCell = baseValue.asCell();
+    Structure* structure = baseCell-&gt;structure(vm);
</ins><span class="cx"> 
</span><ins>+    if (slot.isCacheableGetter())
+        getter = jsDynamicCast&lt;JSFunction*&gt;(slot.getterSetter()-&gt;getter());
+
</ins><span class="cx">     if (isJSArray(baseValue) &amp;&amp; propertyName == exec-&gt;propertyNames().length)
</span><span class="cx">         newCase = AccessCase::getLength(vm, codeBlock, AccessCase::ArrayLength);
</span><span class="cx">     else if (isJSString(baseValue) &amp;&amp; propertyName == exec-&gt;propertyNames().length)
</span><span class="cx">         newCase = AccessCase::getLength(vm, codeBlock, AccessCase::StringLength);
</span><del>-    else {
</del><ins>+    else if (getter &amp;&amp; AccessCase::canEmitIntrinsicGetter(getter, structure)) {
+        if (slot.slotBase() != baseValue) {
+            conditionSet = generateConditionsForPrototypePropertyHit(vm, codeBlock-&gt;ownerExecutable(), exec, structure, slot.slotBase(), propertyName.impl());
+            if (!conditionSet.isValid())
+                return GiveUpOnCache;
+        }
+
+        newCase = AccessCase::getIntrinsic(vm, codeBlock, getter, slot.cachedOffset(), structure, conditionSet);
+
+    } else {
</ins><span class="cx">         if (!slot.isCacheable() &amp;&amp; !slot.isUnset())
</span><span class="cx">             return GiveUpOnCache;
</span><span class="cx"> 
</span><del>-        JSCell* baseCell = baseValue.asCell();
-        Structure* structure = baseCell-&gt;structure(vm);
-
</del><span class="cx">         bool loadTargetFromProxy = false;
</span><span class="cx">         if (baseCell-&gt;type() == PureForwardingProxyType) {
</span><span class="cx">             baseValue = jsCast&lt;JSProxy*&gt;(baseCell)-&gt;target();
</span><span class="lines">@@ -265,8 +278,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         PropertyOffset offset = slot.isUnset() ? invalidOffset : slot.cachedOffset();
</span><del>-        
-        ObjectPropertyConditionSet conditionSet;
</del><ins>+
</ins><span class="cx">         if (slot.isUnset() || slot.slotBase() != baseValue) {
</span><span class="cx">             if (structure-&gt;typeInfo().prohibitsPropertyCaching() || structure-&gt;isDictionary())
</span><span class="cx">                 return GiveUpOnCache;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeIntrinsich"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Intrinsic.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/Intrinsic.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> enum Intrinsic {
</span><ins>+    // Call intrinsics.
</ins><span class="cx">     NoIntrinsic,
</span><span class="cx">     AbsIntrinsic,
</span><span class="cx">     MinIntrinsic,
</span><span class="lines">@@ -54,6 +55,11 @@
</span><span class="cx">     IMulIntrinsic,
</span><span class="cx">     FRoundIntrinsic,
</span><span class="cx"> 
</span><ins>+    // Getter intrinsics.
+    TypedArrayLengthIntrinsic,
+    TypedArrayByteLengthIntrinsic,
+    TypedArrayByteOffsetIntrinsic,
+
</ins><span class="cx">     // Debugging intrinsics. These are meant to be used as testing hacks within
</span><span class="cx">     // jsc.cpp and should never be exposed to users.
</span><span class="cx">     DFGTrueIntrinsic,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSArrayBufferViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -140,10 +140,6 @@
</span><span class="cx">     JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot&amp; slot)
</span><span class="cx"> {
</span><span class="cx">     JSArrayBufferView* thisObject = jsCast&lt;JSArrayBufferView*&gt;(object);
</span><del>-    if (propertyName == exec-&gt;propertyNames().byteOffset) {
-        slot.setValue(thisObject, DontDelete | ReadOnly, jsNumber(thisObject-&gt;byteOffset()));
-        return true;
-    }
</del><span class="cx">     
</span><span class="cx">     if (propertyName == exec-&gt;propertyNames().buffer) {
</span><span class="cx">         slot.setValue(
</span><span class="lines">@@ -160,9 +156,7 @@
</span><span class="cx">     PutPropertySlot&amp; slot)
</span><span class="cx"> {
</span><span class="cx">     JSArrayBufferView* thisObject = jsCast&lt;JSArrayBufferView*&gt;(cell);
</span><del>-    if (propertyName == exec-&gt;propertyNames().byteLength
-        || propertyName == exec-&gt;propertyNames().byteOffset
-        || propertyName == exec-&gt;propertyNames().buffer) {
</del><ins>+    if (propertyName == exec-&gt;propertyNames().buffer) {
</ins><span class="cx">         reject(exec, slot.isStrictMode(), &quot;Attempting to write to read-only typed array property.&quot;);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -175,9 +169,7 @@
</span><span class="cx">     const PropertyDescriptor&amp; descriptor, bool shouldThrow)
</span><span class="cx"> {
</span><span class="cx">     JSArrayBufferView* thisObject = jsCast&lt;JSArrayBufferView*&gt;(object);
</span><del>-    if (propertyName == exec-&gt;propertyNames().byteLength
-        || propertyName == exec-&gt;propertyNames().byteOffset
-        || propertyName == exec-&gt;propertyNames().buffer)
</del><ins>+    if (propertyName == exec-&gt;propertyNames().buffer)
</ins><span class="cx">         return reject(exec, shouldThrow, &quot;Attempting to define read-only typed array property.&quot;);
</span><span class="cx">     
</span><span class="cx">     return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
</span><span class="lines">@@ -187,9 +179,7 @@
</span><span class="cx">     JSCell* cell, ExecState* exec, PropertyName propertyName)
</span><span class="cx"> {
</span><span class="cx">     JSArrayBufferView* thisObject = jsCast&lt;JSArrayBufferView*&gt;(cell);
</span><del>-    if (propertyName == exec-&gt;propertyNames().byteLength
-        || propertyName == exec-&gt;propertyNames().byteOffset
-        || propertyName == exec-&gt;propertyNames().buffer)
</del><ins>+    if (propertyName == exec-&gt;propertyNames().buffer)
</ins><span class="cx">         return false;
</span><span class="cx">     
</span><span class="cx">     return Base::deleteProperty(thisObject, exec, propertyName);
</span><span class="lines">@@ -200,12 +190,9 @@
</span><span class="cx"> {
</span><span class="cx">     JSArrayBufferView* thisObject = jsCast&lt;JSArrayBufferView*&gt;(object);
</span><span class="cx">     
</span><del>-    // length/byteOffset/byteLength are DontEnum, at least in Firefox.
-    if (mode.includeDontEnumProperties()) {
-        array.add(exec-&gt;propertyNames().byteOffset);
-        array.add(exec-&gt;propertyNames().byteLength);
</del><ins>+    if (mode.includeDontEnumProperties())
</ins><span class="cx">         array.add(exec-&gt;propertyNames().buffer);
</span><del>-    }
</del><ins>+
</ins><span class="cx">     
</span><span class="cx">     Base::getOwnNonIndexPropertyNames(thisObject, exec, array, mode);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSDataViewcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSDataView.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSDataView.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSDataView.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;DataView.h&quot;
</span><span class="cx"> #include &quot;Error.h&quot;
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><ins>+#include &quot;Reject.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -102,10 +103,64 @@
</span><span class="cx">         slot.setValue(thisObject, DontEnum | ReadOnly, jsNumber(thisObject-&gt;m_length));
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><del>-    
</del><ins>+    if (propertyName == exec-&gt;propertyNames().byteOffset) {
+        slot.setValue(thisObject, DontEnum | ReadOnly, jsNumber(thisObject-&gt;byteOffset()));
+        return true;
+    }
+
</ins><span class="cx">     return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JSDataView::put(
+    JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value,
+    PutPropertySlot&amp; slot)
+{
+    JSDataView* thisObject = jsCast&lt;JSDataView*&gt;(cell);
+    if (propertyName == exec-&gt;propertyNames().byteLength
+        || propertyName == exec-&gt;propertyNames().byteOffset) {
+        reject(exec, slot.isStrictMode(), &quot;Attempting to write to read-only typed array property.&quot;);
+        return;
+    }
+
+    Base::put(thisObject, exec, propertyName, value, slot);
+}
+
+bool JSDataView::defineOwnProperty(
+    JSObject* object, ExecState* exec, PropertyName propertyName,
+    const PropertyDescriptor&amp; descriptor, bool shouldThrow)
+{
+    JSDataView* thisObject = jsCast&lt;JSDataView*&gt;(object);
+    if (propertyName == exec-&gt;propertyNames().byteLength
+        || propertyName == exec-&gt;propertyNames().byteOffset)
+        return reject(exec, shouldThrow, &quot;Attempting to define read-only typed array property.&quot;);
+
+    return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
+}
+
+bool JSDataView::deleteProperty(
+    JSCell* cell, ExecState* exec, PropertyName propertyName)
+{
+    JSDataView* thisObject = jsCast&lt;JSDataView*&gt;(cell);
+    if (propertyName == exec-&gt;propertyNames().byteLength
+        || propertyName == exec-&gt;propertyNames().byteOffset)
+        return false;
+
+    return Base::deleteProperty(thisObject, exec, propertyName);
+}
+
+void JSDataView::getOwnNonIndexPropertyNames(
+    JSObject* object, ExecState* exec, PropertyNameArray&amp; array, EnumerationMode mode)
+{
+    JSDataView* thisObject = jsCast&lt;JSDataView*&gt;(object);
+    
+    if (mode.includeDontEnumProperties()) {
+        array.add(exec-&gt;propertyNames().byteOffset);
+        array.add(exec-&gt;propertyNames().byteLength);
+    }
+    
+    Base::getOwnNonIndexPropertyNames(thisObject, exec, array, mode);
+}
+
</ins><span class="cx"> ArrayBuffer* JSDataView::slowDownAndWasteMemory(JSArrayBufferView*)
</span><span class="cx"> {
</span><span class="cx">     UNREACHABLE_FOR_PLATFORM();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSDataViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSDataView.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSDataView.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSDataView.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -59,7 +59,12 @@
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&amp;);
</span><ins>+    static void put(JSCell*, ExecState*, PropertyName, JSValue, PutPropertySlot&amp;);
+    static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&amp;, bool shouldThrow);
+    static bool deleteProperty(JSCell*, ExecState*, PropertyName);
</ins><span class="cx"> 
</span><ins>+    static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&amp;, EnumerationMode);
+
</ins><span class="cx">     static ArrayBuffer* slowDownAndWasteMemory(JSArrayBufferView*);
</span><span class="cx">     static PassRefPtr&lt;ArrayBufferView&gt; getTypedArrayImpl(JSArrayBufferView*);
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFunctionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSFunction.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFunction.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSFunction.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -84,9 +84,10 @@
</span><span class="cx"> 
</span><span class="cx">     ExecutableBase* executable() const { return m_executable.get(); }
</span><span class="cx"> 
</span><del>-    // To call either of these methods include Executable.h
</del><ins>+    // To call any of these methods include JSFunctionInlines.h
</ins><span class="cx">     bool isHostFunction() const;
</span><span class="cx">     FunctionExecutable* jsExecutable() const;
</span><ins>+    Intrinsic intrinsic() const;
</ins><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE const SourceCode* sourceCode() const;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFunctionInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSFunctionInlines.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -73,6 +73,11 @@
</span><span class="cx">     return m_executable-&gt;isHostFunction();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline Intrinsic JSFunction::intrinsic() const
+{
+    return executable()-&gt;intrinsic();
+}
+
</ins><span class="cx"> inline bool JSFunction::isBuiltinFunction() const
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGenericTypedArrayViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -277,7 +277,6 @@
</span><span class="cx">     static void putByIndex(JSCell*, ExecState*, unsigned propertyName, JSValue, bool shouldThrow);
</span><span class="cx">     static bool deletePropertyByIndex(JSCell*, ExecState*, unsigned propertyName);
</span><span class="cx">     
</span><del>-    static void getOwnNonIndexPropertyNames(JSObject*, ExecState*, PropertyNameArray&amp;, EnumerationMode);
</del><span class="cx">     static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&amp;, EnumerationMode);
</span><span class="cx">     
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGenericTypedArrayViewInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -293,16 +293,7 @@
</span><span class="cx">     JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot&amp; slot)
</span><span class="cx"> {
</span><span class="cx">     JSGenericTypedArrayView* thisObject = jsCast&lt;JSGenericTypedArrayView*&gt;(object);
</span><del>-    if (propertyName == exec-&gt;propertyNames().length) {
-        slot.setValue(thisObject, DontDelete | ReadOnly, jsNumber(thisObject-&gt;length()));
-        return true;
-    }
-    
-    if (propertyName == exec-&gt;propertyNames().byteLength) {
-        slot.setValue(thisObject, DontDelete | ReadOnly, jsNumber(thisObject-&gt;byteLength()));
-        return true;
-    }
-    
</del><ins>+
</ins><span class="cx">     Optional&lt;uint32_t&gt; index = parseIndex(propertyName);
</span><span class="cx">     if (index &amp;&amp; thisObject-&gt;canGetIndexQuickly(index.value())) {
</span><span class="cx">         slot.setValue(thisObject, DontDelete | ReadOnly, thisObject-&gt;getIndexQuickly(index.value()));
</span><span class="lines">@@ -319,12 +310,6 @@
</span><span class="cx"> {
</span><span class="cx">     JSGenericTypedArrayView* thisObject = jsCast&lt;JSGenericTypedArrayView*&gt;(cell);
</span><span class="cx">     
</span><del>-    if (propertyName == exec-&gt;propertyNames().length) {
-        // Firefox appears to simply ignore attempts to store to the length property.
-        // Even in strict mode. I will do the same.
-        return;
-    }
-    
</del><span class="cx">     if (Optional&lt;uint32_t&gt; index = parseIndex(propertyName)) {
</span><span class="cx">         putByIndex(thisObject, exec, index.value(), value, slot.isStrictMode());
</span><span class="cx">         return;
</span><span class="lines">@@ -343,7 +328,7 @@
</span><span class="cx">     // This is matching Firefox behavior. In particular, it rejects all attempts to
</span><span class="cx">     // defineOwnProperty for indexed properties on typed arrays, even if they're out
</span><span class="cx">     // of bounds.
</span><del>-    if (propertyName == exec-&gt;propertyNames().length || parseIndex(propertyName))
</del><ins>+    if (parseIndex(propertyName))
</ins><span class="cx">         return reject(exec, shouldThrow, &quot;Attempting to write to a read-only typed array property.&quot;);
</span><span class="cx">     
</span><span class="cx">     return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
</span><span class="lines">@@ -355,7 +340,7 @@
</span><span class="cx"> {
</span><span class="cx">     JSGenericTypedArrayView* thisObject = jsCast&lt;JSGenericTypedArrayView*&gt;(cell);
</span><span class="cx">     
</span><del>-    if (propertyName == exec-&gt;propertyNames().length || parseIndex(propertyName))
</del><ins>+    if (parseIndex(propertyName))
</ins><span class="cx">         return false;
</span><span class="cx">     
</span><span class="cx">     return Base::deleteProperty(thisObject, exec, propertyName);
</span><span class="lines">@@ -408,18 +393,6 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename Adaptor&gt;
</span><del>-void JSGenericTypedArrayView&lt;Adaptor&gt;::getOwnNonIndexPropertyNames(
-    JSObject* object, ExecState* exec, PropertyNameArray&amp; array, EnumerationMode mode)
-{
-    JSGenericTypedArrayView* thisObject = jsCast&lt;JSGenericTypedArrayView*&gt;(object);
-    
-    if (mode.includeDontEnumProperties())
-        array.add(exec-&gt;propertyNames().length);
-    
-    Base::getOwnNonIndexPropertyNames(thisObject, exec, array, mode);
-}
-
-template&lt;typename Adaptor&gt;
</del><span class="cx"> void JSGenericTypedArrayView&lt;Adaptor&gt;::getOwnPropertyNames(
</span><span class="cx">     JSObject* object, ExecState* exec, PropertyNameArray&amp; array, EnumerationMode mode)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -2287,6 +2287,14 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JSObject::putDirectNativeIntrinsicGetter(VM&amp; vm, JSGlobalObject* globalObject, Identifier name, NativeFunction nativeFunction, Intrinsic intrinsic, unsigned attributes)
+{
+    GetterSetter* accessor = GetterSetter::create(vm, globalObject);
+    JSFunction* function = JSFunction::create(vm, globalObject, 0, name.string(), nativeFunction, intrinsic);
+    accessor-&gt;setGetter(vm, globalObject, function);
+    putDirectNonIndexAccessor(vm, name, accessor, attributes);
+}
+
</ins><span class="cx"> void JSObject::putDirectNativeFunction(VM&amp; vm, JSGlobalObject* globalObject, const PropertyName&amp; propertyName, unsigned functionLength, NativeFunction nativeFunction, Intrinsic intrinsic, unsigned attributes)
</span><span class="cx"> {
</span><span class="cx">     StringImpl* name = propertyName.publicName();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSObject.h (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSObject.h        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSObject.h        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -595,6 +595,7 @@
</span><span class="cx">     void putDirect(VM&amp; vm, PropertyOffset offset, JSValue value) { locationForOffset(offset)-&gt;set(vm, this, value); }
</span><span class="cx">     void putDirectUndefined(PropertyOffset offset) { locationForOffset(offset)-&gt;setUndefined(); }
</span><span class="cx"> 
</span><ins>+    JS_EXPORT_PRIVATE void putDirectNativeIntrinsicGetter(VM&amp;, JSGlobalObject*, Identifier, NativeFunction, Intrinsic, unsigned attributes);
</ins><span class="cx">     JS_EXPORT_PRIVATE void putDirectNativeFunction(VM&amp;, JSGlobalObject*, const PropertyName&amp;, unsigned functionLength, NativeFunction, Intrinsic, unsigned attributes);
</span><span class="cx">     JS_EXPORT_PRIVATE JSFunction* putDirectBuiltinFunction(VM&amp;, JSGlobalObject*, const PropertyName&amp;, FunctionExecutable*, unsigned attributes);
</span><span class="cx">     JSFunction* putDirectBuiltinFunctionWithoutTransition(VM&amp;, JSGlobalObject*, const PropertyName&amp;, FunctionExecutable*, unsigned attributes);
</span><span class="lines">@@ -1471,15 +1472,15 @@
</span><span class="cx">         vm, globalObject, makeIdentifier(vm, (jsName)), (generatorName)(vm), (attributes))
</span><span class="cx"> 
</span><span class="cx"> // Helper for defining native getters on properties.
</span><del>-#define JSC_NATIVE_GETTER(jsName, cppName, attributes, length) do { \
-        Identifier ident = makeIdentifier(vm, (jsName)); \
-        GetterSetter* accessor = GetterSetter::create(vm, globalObject); \
-        JSFunction* function = JSFunction::create(vm, globalObject, (length), ident.string(), (cppName)); \
-        accessor-&gt;setGetter(vm, globalObject, function); \
-        putDirectNonIndexAccessor(vm, ident, accessor, (attributes) | Accessor); \
-    } while (false)
</del><ins>+#define JSC_NATIVE_INTRINSIC_GETTER(jsName, cppName, attributes, intrinsic)  \
+    putDirectNativeIntrinsicGetter(\
+        vm, globalObject, makeIdentifier(vm, (jsName)), (cppName), \
+        (intrinsic), ((attributes) | Accessor))
</ins><span class="cx"> 
</span><ins>+#define JSC_NATIVE_GETTER(jsName, cppName, attributes) \
+    JSC_NATIVE_INTRINSIC_GETTER((jsName), (cppName), (attributes), NoIntrinsic)
</ins><span class="cx"> 
</span><ins>+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // JSObject_h
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTypedArrayViewPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp (191214 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp        2015-10-16 22:09:57 UTC (rev 191214)
+++ trunk/Source/JavaScriptCore/runtime/JSTypedArrayViewPrototype.cpp        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -213,8 +213,8 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(inherits(info()));
</span><span class="cx"> 
</span><del>-    JSC_NATIVE_GETTER(vm.propertyNames-&gt;byteLength, typedArrayViewProtoGetterFuncByteLength, DontEnum | ReadOnly | DontDelete, 0);
-    JSC_NATIVE_GETTER(vm.propertyNames-&gt;byteOffset, typedArrayViewProtoGetterFuncByteOffset, DontEnum | ReadOnly | DontDelete, 0);
</del><ins>+    JSC_NATIVE_INTRINSIC_GETTER(vm.propertyNames-&gt;byteLength, typedArrayViewProtoGetterFuncByteLength, DontEnum | ReadOnly | DontDelete, TypedArrayByteLengthIntrinsic);
+    JSC_NATIVE_INTRINSIC_GETTER(vm.propertyNames-&gt;byteOffset, typedArrayViewProtoGetterFuncByteOffset, DontEnum | ReadOnly | DontDelete, TypedArrayByteOffsetIntrinsic);
</ins><span class="cx">     JSC_NATIVE_FUNCTION(&quot;copyWithin&quot;, typedArrayViewProtoFuncCopyWithin, DontEnum, 2);
</span><span class="cx">     JSC_BUILTIN_FUNCTION(&quot;every&quot;, typedArrayPrototypeEveryCodeGenerator, DontEnum);
</span><span class="cx">     JSC_BUILTIN_FUNCTION(&quot;filter&quot;, typedArrayPrototypeFilterCodeGenerator, DontEnum);
</span><span class="lines">@@ -228,7 +228,7 @@
</span><span class="cx">     JSC_NATIVE_FUNCTION(vm.propertyNames-&gt;join, typedArrayViewProtoFuncJoin, DontEnum, 1);
</span><span class="cx">     JSC_NATIVE_FUNCTION(vm.propertyNames-&gt;keys, typedArrayViewProtoFuncKeys, DontEnum, 0);
</span><span class="cx">     JSC_NATIVE_FUNCTION(&quot;lastIndexOf&quot;, typedArrayViewProtoFuncLastIndexOf, DontEnum, 1);
</span><del>-    JSC_NATIVE_GETTER(vm.propertyNames-&gt;length, typedArrayViewProtoGetterFuncLength, DontEnum | ReadOnly | DontDelete, 0);
</del><ins>+    JSC_NATIVE_INTRINSIC_GETTER(vm.propertyNames-&gt;length, typedArrayViewProtoGetterFuncLength, DontEnum | ReadOnly | DontDelete, TypedArrayLengthIntrinsic);
</ins><span class="cx">     JSC_BUILTIN_FUNCTION(&quot;map&quot;, typedArrayPrototypeMapCodeGenerator, DontEnum);
</span><span class="cx">     JSC_BUILTIN_FUNCTION(&quot;reduce&quot;, typedArrayPrototypeReduceCodeGenerator, DontEnum);
</span><span class="cx">     JSC_BUILTIN_FUNCTION(&quot;reduceRight&quot;, typedArrayPrototypeReduceRightCodeGenerator, DontEnum);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresstypedarrayaddpropertytobaseobjectjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/typedarray-add-property-to-base-object.js (0 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/typedarray-add-property-to-base-object.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/typedarray-add-property-to-base-object.js        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+// This tests that we don't fast path intrinsics when they should not be fast pathed. Currently,
+// that means that we don't inline length and byteLength when they are &quot;connected&quot; to a TypedArray.
+
+(function body() {
+    function foo(a) {
+        return a.length + a.byteLength + a.byteOffset;
+    }
+
+    let array = new Int32Array(10);
+
+    for (let i = 0; i &lt; 100000; i++)
+        foo(array);
+
+
+    Object.defineProperty(array, &quot;length&quot;, { value: 0 });
+    Object.defineProperty(array, &quot;byteLength&quot;, { value: 0 });
+    Object.defineProperty(array, &quot;byteOffset&quot;, { value: 0 });
+
+    if (foo(array) !== 0)
+        throw &quot;wrong number!&quot;;
+})();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresstypedarraybadgetterjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/typedarray-bad-getter.js (0 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/typedarray-bad-getter.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/typedarray-bad-getter.js        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+// This tests that we don't fast path intrinsics when they should not be fast pathed. Currently,
+// that means that we don't inline length, byteLength, and byteOffset when they are called
+// from a non-TypedArray.
+
+(function body() {
+    function foo(a) {
+        return a.length + a.byteLength + a.byteOffset;
+    }
+    noInline(foo);
+
+    let proto = { }
+
+    let properties = [&quot;length&quot;, &quot;byteLength&quot;, &quot;byteOffset&quot;];
+    properties.map(function(name) {
+        let getter = Int32Array.prototype.__lookupGetter__(name);
+        Object.defineProperty(proto, name, { get : getter });
+    });
+
+    function Bar() {
+        return this;
+    }
+
+    Bar.prototype = proto;
+    let bar = new Bar();
+
+    let noThrow = false;
+    for (let i = 0; i &lt; 100000; i++) {
+        try {
+            foo(bar);
+            noThrow = true
+        } catch (e) {
+        }
+        if (noThrow)
+            throw &quot;broken&quot;;
+    }
+})();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresstypedarraygetteronselfjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/typedarray-getter-on-self.js (0 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/typedarray-getter-on-self.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/typedarray-getter-on-self.js        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+// This tests that intrinsics that are attached to self of an object correctly abort
+// when the self value is changed.
+
+(function body() {
+    function foo(a) {
+        return a.length;
+    }
+    noInline(foo);
+
+    function bar(a) {
+        return a.byteLength;
+    }
+    noInline(bar);
+
+    function baz(a) {
+        return a.byteOffset;
+    }
+    noInline(baz);
+
+    let array = new Int32Array(10);
+
+    let properties = [&quot;length&quot;, &quot;byteLength&quot;, &quot;byteOffset&quot;];
+    properties.map(function(name) {
+        let getter = Int32Array.prototype.__lookupGetter__(name);
+        Object.defineProperty(array, name, { get: getter, configurable: true });
+    });
+
+    for (let i = 0; i &lt; 100000; i++)
+        foo(array);
+
+    properties.map(function(name) {
+        Object.defineProperty(array, name, { value: null });
+    });
+
+    if (foo(array) !== null)
+        throw &quot;length should have been null&quot;;
+
+    if (bar(array) !== null)
+        throw &quot;byteLength should have been null&quot;;
+
+    if (baz(array) !== null)
+        throw &quot;byteOffset should have been null&quot;;
+})();
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresstypedarrayintrinsicgetterschangeprototypejs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/typedarray-intrinsic-getters-change-prototype.js (0 => 191215)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/typedarray-intrinsic-getters-change-prototype.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/typedarray-intrinsic-getters-change-prototype.js        2015-10-16 22:18:42 UTC (rev 191215)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+// This tests that TypedArray length and byteLength correctly dump code when the prototypes move.
+
+(function body() {
+    function foo(a) {
+        return a.length;
+    }
+    noInline(foo);
+
+    function bar(a) {
+        return a.byteLength;
+    }
+    noInline(bar);
+
+    function baz(a) {
+        return a.byteOffset;
+    }
+    noInline(baz);
+
+    let array = new Int32Array(15);
+
+    while(numberOfDFGCompiles(foo) &lt; 1) {
+        foo(array);
+        bar(array);
+        baz(array);
+    }
+
+    Object.setPrototypeOf(array, null);
+
+    let passed = false;
+
+    if (foo(array) !== undefined)
+        throw &quot;length should have become undefined when the prototype changed&quot;;
+    if (bar(array) !== undefined)
+        throw &quot;byteLength should have become undefined when the prototype changed&quot;;
+    if (baz(array) !== undefined)
+        throw &quot;byteOffset should have become undefined when the prototype changed&quot;;
+
+
+})();
</ins></span></pre>
</div>
</div>

</body>
</html>