<!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>[199076] 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/199076">199076</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2016-04-05 15:17:35 -0700 (Tue, 05 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>JSC should use a shadow stack version of CHICKEN so that debuggers have the option of retrieving tail-deleted frames
https://bugs.webkit.org/show_bug.cgi?id=155598

Reviewed by Saam Barati.
PerformanceTests/SunSpider:


* shadow-chicken.yaml: Added.

Source/JavaScriptCore:

        
JSC is the first JSVM to have proper tail calls. This means that error.stack and the
debugger will appear to &quot;delete&quot; strict mode stack frames, if the call that this frame made
was in tail position. This is exactly what functional programmers expect - they don't want
the VM to waste resources on tail-deleted frames to ensure that it's legal to loop forever
using tail calls. It's also something that non-functional programmers fear. It's not clear
that tail-deleted frames would actually degrade the debugging experience, but the fear is
real, so it's worthwhile to do something about it.

It turns out that there is at least one tail call implementation that doesn't suffer from
this problem. It implements proper tail calls in the sense that you won't run out of memory
by tail-looping. It also has the power to show you tail-deleted frames in a backtrace, so
long as you haven't yet run out of memory. It's called CHICKEN Scheme, and it's one of my
favorite hacks:
        
http://www.more-magic.net/posts/internals-gc.html

CHICKEN does many awesome things. The intuition from CHICKEN that we use here is a simple
one: what if a tail call still kept the tail-deleted frame, and the GC actually deleted that
frame only once we proved that there was insufficient memory to keep it around.
        
CHICKEN does this by reshaping the C stack with longjmp/setjmp. We can't do that because we
can have arbitrary native code, and that native code does not have relocatable stack frames.
        
But we can do something almost like CHICKEN on a shadow stack. It's a common trick to have a
VM maintain two stacks - the actual execution stack plus a shadow stack that has some extra
information. The shadow stack can be reshaped, moved, etc, since the VM tightly controls its
layout. The main stack can then continue to obey ABI rules.

This patch implements a mechanism for being able to display stack traces that include
tail-deleted frames. It uses a shadow stack that behaves like a CHICKEN stack: it has all
frames all the time, though we will collect the tail-deleted ones if the stack gets too big.
This new mechanism is called ShadowChicken, obviously: it's CHICKEN on a shadow stack.
        
ShadowChicken is always on, but individual CodeBlocks may make their own choices about
whether to opt into it. They will do that at bytecompile time based on the debugger mode on
their global object.

When no CodeBlock opts in, there is no overhead, since ShadowChicken ends up doing nothing
in that case. Well, except when exceptions are thrown. Then it might do some work, but it's
minor.

When all CodeBlocks opt in, there is about 6% overhead. That's too much overhead to enable
this all the time, but it's low enough to justify enabling in the Inspector. It's currently
enabled on all CodeBlocks only when you use an Option. Otherwise it will auto-enable if the
debugger is on.

Note that ShadowChicken attempts to gracefully handle the presence of stack frames that have
no logging. This is essential since we *can* have debugging enabled in one GlobalObject and
disabled in another. Also, some frames don't do ShadowChicken because they just haven't been
hacked to do it yet. Native frames fall into this category, as do the VM entry frames.

This doesn't yet wire ShadowChicken into DebuggerCallFrame. That will take more work. It
just makes a ShadowChicken stack walk function available to jsc. It's used from the
shadow-chicken tests.

* API/JSContextRef.cpp:
(BacktraceFunctor::BacktraceFunctor):
(BacktraceFunctor::operator()):
(JSContextCreateBacktrace):
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/BytecodeList.json:
* bytecode/BytecodeUseDef.h:
(JSC::computeUsesForBytecodeOffset):
(JSC::computeDefsForBytecodeOffset):
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::dumpBytecode):
(JSC::RecursionCheckFunctor::RecursionCheckFunctor):
(JSC::RecursionCheckFunctor::operator()):
(JSC::CodeBlock::noticeIncomingCall):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitEnter):
(JSC::BytecodeGenerator::emitCallInTailPosition):
(JSC::BytecodeGenerator::emitCallVarargsInTailPosition):
(JSC::BytecodeGenerator::emitCallVarargs):
(JSC::BytecodeGenerator::emitLogShadowChickenPrologueIfNecessary):
(JSC::BytecodeGenerator::emitLogShadowChickenTailIfNecessary):
(JSC::BytecodeGenerator::emitCallDefineProperty):
* bytecompiler/BytecodeGenerator.h:
* debugger/DebuggerCallFrame.cpp:
(JSC::LineAndColumnFunctor::operator()):
(JSC::LineAndColumnFunctor::column):
(JSC::FindCallerMidStackFunctor::FindCallerMidStackFunctor):
(JSC::FindCallerMidStackFunctor::operator()):
(JSC::DebuggerCallFrame::DebuggerCallFrame):
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* dfg/DFGDoesGC.cpp:
(JSC::DFG::doesGC):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGNodeType.h:
* dfg/DFGPredictionPropagationPhase.cpp:
(JSC::DFG::PredictionPropagationPhase::propagate):
* dfg/DFGSafeToExecute.h:
(JSC::DFG::safeToExecute):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* ftl/FTLAbstractHeapRepository.cpp:
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNode):
(JSC::FTL::DFG::LowerDFGToB3::compileSetRegExpObjectLastIndex):
(JSC::FTL::DFG::LowerDFGToB3::compileLogShadowChickenPrologue):
(JSC::FTL::DFG::LowerDFGToB3::compileLogShadowChickenTail):
(JSC::FTL::DFG::LowerDFGToB3::didOverflowStack):
(JSC::FTL::DFG::LowerDFGToB3::allocateJSArray):
(JSC::FTL::DFG::LowerDFGToB3::setupShadowChickenPacket):
(JSC::FTL::DFG::LowerDFGToB3::boolify):
* heap/Heap.cpp:
(JSC::Heap::markRoots):
(JSC::Heap::visitSamplingProfiler):
(JSC::Heap::visitShadowChicken):
(JSC::Heap::traceCodeBlocksAndJITStubRoutines):
(JSC::Heap::collectImpl):
* heap/Heap.h:
* inspector/ScriptCallStackFactory.cpp:
(Inspector::CreateScriptCallStackFunctor::CreateScriptCallStackFunctor):
(Inspector::CreateScriptCallStackFunctor::operator()):
(Inspector::createScriptCallStack):
* interpreter/CallFrame.h:
(JSC::ExecState::iterate):
* interpreter/Interpreter.cpp:
(JSC::DumpRegisterFunctor::DumpRegisterFunctor):
(JSC::DumpRegisterFunctor::operator()):
(JSC::GetStackTraceFunctor::GetStackTraceFunctor):
(JSC::GetStackTraceFunctor::operator()):
(JSC::Interpreter::getStackTrace):
(JSC::GetCatchHandlerFunctor::handler):
(JSC::GetCatchHandlerFunctor::operator()):
(JSC::notifyDebuggerOfUnwinding):
(JSC::UnwindFunctor::UnwindFunctor):
(JSC::UnwindFunctor::operator()):
(JSC::UnwindFunctor::copyCalleeSavesToVMCalleeSavesBuffer):
* interpreter/ShadowChicken.cpp: Added.
(JSC::ShadowChicken::Packet::dump):
(JSC::ShadowChicken::Frame::dump):
(JSC::ShadowChicken::ShadowChicken):
(JSC::ShadowChicken::~ShadowChicken):
(JSC::ShadowChicken::log):
(JSC::ShadowChicken::update):
(JSC::ShadowChicken::visitChildren):
(JSC::ShadowChicken::reset):
(JSC::ShadowChicken::dump):
(JSC::ShadowChicken::functionsOnStack):
* interpreter/ShadowChicken.h: Added.
(JSC::ShadowChicken::Packet::Packet):
(JSC::ShadowChicken::Packet::tailMarker):
(JSC::ShadowChicken::Packet::throwMarker):
(JSC::ShadowChicken::Packet::prologue):
(JSC::ShadowChicken::Packet::tail):
(JSC::ShadowChicken::Packet::throwPacket):
(JSC::ShadowChicken::Packet::operator bool):
(JSC::ShadowChicken::Packet::isPrologue):
(JSC::ShadowChicken::Packet::isTail):
(JSC::ShadowChicken::Packet::isThrow):
(JSC::ShadowChicken::Frame::Frame):
(JSC::ShadowChicken::Frame::operator==):
(JSC::ShadowChicken::Frame::operator!=):
(JSC::ShadowChicken::log):
(JSC::ShadowChicken::logSize):
(JSC::ShadowChicken::addressOfLogCursor):
(JSC::ShadowChicken::logEnd):
* interpreter/ShadowChickenInlines.h: Added.
(JSC::ShadowChicken::iterate):
* interpreter/StackVisitor.h:
(JSC::StackVisitor::Frame::callee):
(JSC::StackVisitor::Frame::codeBlock):
(JSC::StackVisitor::Frame::bytecodeOffset):
(JSC::StackVisitor::Frame::inlineCallFrame):
(JSC::StackVisitor::Frame::isJSFrame):
(JSC::StackVisitor::Frame::isInlinedFrame):
(JSC::StackVisitor::visit):
* jit/CCallHelpers.cpp: Added.
(JSC::CCallHelpers::logShadowChickenProloguePacket):
(JSC::CCallHelpers::logShadowChickenTailPacket):
(JSC::CCallHelpers::setupShadowChickenPacket):
* jit/CCallHelpers.h:
(JSC::CCallHelpers::prepareForTailCallSlow):
* jit/JIT.cpp:
(JSC::JIT::privateCompileMainPass):
* jit/JIT.h:
* jit/JITExceptions.cpp:
(JSC::genericUnwind):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_resume):
(JSC::JIT::emit_op_log_shadow_chicken_prologue):
(JSC::JIT::emit_op_log_shadow_chicken_tail):
* jit/JITOperations.cpp:
* jit/JITOperations.h:
* jsc.cpp:
(GlobalObject::finishCreation):
(FunctionJSCStackFunctor::FunctionJSCStackFunctor):
(FunctionJSCStackFunctor::operator()):
(functionClearSamplingFlags):
(functionShadowChickenFunctionsOnStack):
(functionReadline):
* llint/LLIntOffsetsExtractor.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
(JSC::LLInt::llint_throw_stack_overflow_error):
* llint/LLIntSlowPaths.h:
* llint/LowLevelInterpreter.asm:
* profiler/ProfileGenerator.cpp:
(JSC::AddParentForConsoleStartFunctor::foundParent):
(JSC::AddParentForConsoleStartFunctor::operator()):
* runtime/Error.cpp:
(JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor):
(JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()):
(JSC::addErrorInfoAndGetBytecodeOffset):
* runtime/JSFunction.cpp:
(JSC::RetrieveArgumentsFunctor::result):
(JSC::RetrieveArgumentsFunctor::operator()):
(JSC::retrieveArguments):
(JSC::RetrieveCallerFunctionFunctor::result):
(JSC::RetrieveCallerFunctionFunctor::operator()):
(JSC::retrieveCallerFunction):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::GlobalFuncProtoGetterFunctor::result):
(JSC::GlobalFuncProtoGetterFunctor::operator()):
(JSC::globalFuncProtoGetter):
(JSC::GlobalFuncProtoSetterFunctor::allowsAccess):
(JSC::GlobalFuncProtoSetterFunctor::operator()):
* runtime/NullSetterFunction.cpp:
(JSC::GetCallerStrictnessFunctor::GetCallerStrictnessFunctor):
(JSC::GetCallerStrictnessFunctor::operator()):
(JSC::GetCallerStrictnessFunctor::callerIsStrict):
(JSC::callerIsStrict):
* runtime/ObjectConstructor.cpp:
(JSC::ObjectConstructorGetPrototypeOfFunctor::result):
(JSC::ObjectConstructorGetPrototypeOfFunctor::operator()):
(JSC::objectConstructorGetPrototypeOf):
* runtime/Options.h:
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::SetEnabledProfilerFunctor::operator()):
* runtime/VM.h:
(JSC::VM::shouldBuilderPCToCodeOriginMapping):
(JSC::VM::bytecodeIntrinsicRegistry):
(JSC::VM::shadowChicken):
* tests/stress/resources/shadow-chicken-support.js: Added.
(describeFunction):
(describeArray):
(expectStack):
(initialize):
* tests/stress/shadow-chicken-disabled.js: Added.
(test1.foo):
(test1.bar):
(test1.baz):
(test1):
(test2.foo):
(test2.bar):
(test2.baz):
(test2):
(test3.foo):
(test3.bar):
(test3.baz):
(test3):
* tests/stress/shadow-chicken-enabled.js: Added.
(test1.foo):
(test1.bar):
(test1.baz):
(test1):
(test2.foo):
(test2.bar):
(test2.baz):
(test2):
(test3.bob):
(test3.thingy):
(test3.foo):
(test3.bar):
(test3.baz):
(test3):
(test4.bob):
(test4.thingy):
(test4.foo):
(test4.bar):
(test4.baz):
(test4):
(test5.foo):
(test5):
* tools/JSDollarVMPrototype.cpp:
(JSC::CallerFrameJITTypeFunctor::CallerFrameJITTypeFunctor):
(JSC::CallerFrameJITTypeFunctor::operator()):
(JSC::CallerFrameJITTypeFunctor::jitType):
(JSC::functionLLintTrue):
(JSC::CellAddressCheckFunctor::CellAddressCheckFunctor):
(JSC::CellAddressCheckFunctor::operator()):
(JSC::JSDollarVMPrototype::isValidCell):
(JSC::JSDollarVMPrototype::isValidCodeBlock):
(JSC::JSDollarVMPrototype::codeBlockForFrame):
(JSC::PrintFrameFunctor::PrintFrameFunctor):
(JSC::PrintFrameFunctor::operator()):
(JSC::printCallFrame):

Source/WebCore:


Fixed some uses of the stack walking functor to obey the new lambda-friendly API, which
requires that operator() is const.

No new tests because no change in behavior.

* bindings/js/JSXMLHttpRequestCustom.cpp:
(WebCore::SendFunctor::column):
(WebCore::SendFunctor::url):
(WebCore::SendFunctor::operator()):
(WebCore::JSXMLHttpRequest::send):
* testing/Internals.cpp:
(WebCore::GetCallerCodeBlockFunctor::GetCallerCodeBlockFunctor):
(WebCore::GetCallerCodeBlockFunctor::operator()):
(WebCore::GetCallerCodeBlockFunctor::codeBlock):
(WebCore::Internals::parserMetaData):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsSunSpiderChangeLog">trunk/PerformanceTests/SunSpider/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreAPIJSContextRefcpp">trunk/Source/JavaScriptCore/API/JSContextRef.cpp</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="#trunkSourceJavaScriptCorebytecodeBytecodeListjson">trunk/Source/JavaScriptCore/bytecode/BytecodeList.json</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeUseDefh">trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeCodeBlockcpp">trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh">trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredebuggerDebuggerCallFramecpp">trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh">trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp">trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGClobberizeh">trunk/Source/JavaScriptCore/dfg/DFGClobberize.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGDoesGCcpp">trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGFixupPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGNodeTypeh">trunk/Source/JavaScriptCore/dfg/DFGNodeType.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGOperationscpp">trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSafeToExecuteh">trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLAbstractHeapRepositorycpp">trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLAbstractHeapRepositoryh">trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLCapabilitiescpp">trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeaph">trunk/Source/JavaScriptCore/heap/Heap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorScriptCallStackFactorycpp">trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterCallFrameh">trunk/Source/JavaScriptCore/interpreter/CallFrame.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterInterpretercpp">trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterStackVisitorh">trunk/Source/JavaScriptCore/interpreter/StackVisitor.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitCCallHelpersh">trunk/Source/JavaScriptCore/jit/CCallHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITcpp">trunk/Source/JavaScriptCore/jit/JIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITh">trunk/Source/JavaScriptCore/jit/JIT.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITExceptionscpp">trunk/Source/JavaScriptCore/jit/JITExceptions.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITInlinesh">trunk/Source/JavaScriptCore/jit/JITInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodescpp">trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOpcodes32_64cpp">trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationscpp">trunk/Source/JavaScriptCore/jit/JITOperations.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitJITOperationsh">trunk/Source/JavaScriptCore/jit/JITOperations.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitThunkGeneratorscpp">trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntOffsetsExtractorcpp">trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathscpp">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLLIntSlowPathsh">trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreprofilerProfileGeneratorcpp">trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeErrorcpp">trunk/Source/JavaScriptCore/runtime/Error.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSFunctioncpp">trunk/Source/JavaScriptCore/runtime/JSFunction.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeNullSetterFunctioncpp">trunk/Source/JavaScriptCore/runtime/NullSetterFunction.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeObjectConstructorcpp">trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeOptionsh">trunk/Source/JavaScriptCore/runtime/Options.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeStringPrototypecpp">trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMcpp">trunk/Source/JavaScriptCore/runtime/VM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretoolsJSDollarVMPrototypecpp">trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorebindingsjsJSXMLHttpRequestCustomcpp">trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp</a></li>
<li><a href="#trunkSourceWebCoretestingInternalscpp">trunk/Source/WebCore/testing/Internals.cpp</a></li>
<li><a href="#trunkToolsScriptsrunjavascriptcoretests">trunk/Tools/Scripts/run-javascriptcore-tests</a></li>
<li><a href="#trunkToolsScriptsrunjscstresstests">trunk/Tools/Scripts/run-jsc-stress-tests</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkPerformanceTestsSunSpidershadowchickenyaml">trunk/PerformanceTests/SunSpider/shadow-chicken.yaml</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterShadowChickencpp">trunk/Source/JavaScriptCore/interpreter/ShadowChicken.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterShadowChickenh">trunk/Source/JavaScriptCore/interpreter/ShadowChicken.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreinterpreterShadowChickenInlinesh">trunk/Source/JavaScriptCore/interpreter/ShadowChickenInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitCCallHelperscpp">trunk/Source/JavaScriptCore/jit/CCallHelpers.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressresourcesshadowchickensupportjs">trunk/Source/JavaScriptCore/tests/stress/resources/shadow-chicken-support.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressshadowchickendisabledjs">trunk/Source/JavaScriptCore/tests/stress/shadow-chicken-disabled.js</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstressshadowchickenenabledjs">trunk/Source/JavaScriptCore/tests/stress/shadow-chicken-enabled.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkPerformanceTestsSunSpiderChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/PerformanceTests/SunSpider/ChangeLog (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/SunSpider/ChangeLog        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/PerformanceTests/SunSpider/ChangeLog        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,3 +1,12 @@
</span><ins>+2016-03-21 Filip Pizlo &lt;fpizlo@apple.com&gt;
+
+        JSC should use a shadow stack version of CHICKEN so that debuggers have the option of retrieving tail-deleted frames
+        https://bugs.webkit.org/show_bug.cgi?id=155598
+
+        Reviewed by Saam Barati.
+
+        * shadow-chicken.yaml: Added.
+
</ins><span class="cx"> 2015-03-30  Michael Saboff  &lt;msaboff@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix failing v8-deltablue.js for ARM
</span></span></pre></div>
<a id="trunkPerformanceTestsSunSpidershadowchickenyaml"></a>
<div class="addfile"><h4>Added: trunk/PerformanceTests/SunSpider/shadow-chicken.yaml (0 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/PerformanceTests/SunSpider/shadow-chicken.yaml                                (rev 0)
+++ trunk/PerformanceTests/SunSpider/shadow-chicken.yaml        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+# Copyright (C) 2013 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. 
+#
+# 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.
+
+# Tests SunSpider with architecture-specific optimizations disabled. This is
+# just here so you can't get away with murder when dealing with the generic
+# (i.e. no ASO) paths. You should still likely actually *test* all of the
+# architectures you care about.
+
+- path: tests/sunspider-1.0
+  cmd: runShadowChicken
+
+- path: tests/v8-v6
+  cmd: runShadowChicken
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreAPIJSContextRefcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/JSContextRef.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/JSContextRef.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/API/JSContextRef.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2006, 2007, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2006, 2007, 2013, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -255,7 +255,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (m_remainingCapacityForFrameCapture) {
</span><span class="cx">             // If callee is unknown, but we've not added any frame yet, we should
</span><span class="lines">@@ -292,7 +292,7 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     StringBuilder&amp; m_builder;
</span><del>-    unsigned m_remainingCapacityForFrameCapture;
</del><ins>+    mutable unsigned m_remainingCapacityForFrameCapture;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> JSStringRef JSContextCreateBacktrace(JSContextRef ctx, unsigned maxStackSize)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -507,10 +507,12 @@
</span><span class="cx">     interpreter/Interpreter.cpp
</span><span class="cx">     interpreter/JSStack.cpp
</span><span class="cx">     interpreter/ProtoCallFrame.cpp
</span><ins>+    interpreter/ShadowChicken.cpp
</ins><span class="cx">     interpreter/StackVisitor.cpp
</span><span class="cx"> 
</span><span class="cx">     jit/AssemblyHelpers.cpp
</span><span class="cx">     jit/BinarySwitch.cpp
</span><ins>+    jit/CCallHelpers.cpp
</ins><span class="cx">     jit/CachedRecovery.cpp
</span><span class="cx">     jit/CallFrameShuffleData.cpp
</span><span class="cx">     jit/CallFrameShuffler.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,3 +1,313 @@
</span><ins>+2016-03-18  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        JSC should use a shadow stack version of CHICKEN so that debuggers have the option of retrieving tail-deleted frames
+        https://bugs.webkit.org/show_bug.cgi?id=155598
+
+        Reviewed by Saam Barati.
+        
+        JSC is the first JSVM to have proper tail calls. This means that error.stack and the
+        debugger will appear to &quot;delete&quot; strict mode stack frames, if the call that this frame made
+        was in tail position. This is exactly what functional programmers expect - they don't want
+        the VM to waste resources on tail-deleted frames to ensure that it's legal to loop forever
+        using tail calls. It's also something that non-functional programmers fear. It's not clear
+        that tail-deleted frames would actually degrade the debugging experience, but the fear is
+        real, so it's worthwhile to do something about it.
+
+        It turns out that there is at least one tail call implementation that doesn't suffer from
+        this problem. It implements proper tail calls in the sense that you won't run out of memory
+        by tail-looping. It also has the power to show you tail-deleted frames in a backtrace, so
+        long as you haven't yet run out of memory. It's called CHICKEN Scheme, and it's one of my
+        favorite hacks:
+        
+        http://www.more-magic.net/posts/internals-gc.html
+
+        CHICKEN does many awesome things. The intuition from CHICKEN that we use here is a simple
+        one: what if a tail call still kept the tail-deleted frame, and the GC actually deleted that
+        frame only once we proved that there was insufficient memory to keep it around.
+        
+        CHICKEN does this by reshaping the C stack with longjmp/setjmp. We can't do that because we
+        can have arbitrary native code, and that native code does not have relocatable stack frames.
+        
+        But we can do something almost like CHICKEN on a shadow stack. It's a common trick to have a
+        VM maintain two stacks - the actual execution stack plus a shadow stack that has some extra
+        information. The shadow stack can be reshaped, moved, etc, since the VM tightly controls its
+        layout. The main stack can then continue to obey ABI rules.
+
+        This patch implements a mechanism for being able to display stack traces that include
+        tail-deleted frames. It uses a shadow stack that behaves like a CHICKEN stack: it has all
+        frames all the time, though we will collect the tail-deleted ones if the stack gets too big.
+        This new mechanism is called ShadowChicken, obviously: it's CHICKEN on a shadow stack.
+        
+        ShadowChicken is always on, but individual CodeBlocks may make their own choices about
+        whether to opt into it. They will do that at bytecompile time based on the debugger mode on
+        their global object.
+
+        When no CodeBlock opts in, there is no overhead, since ShadowChicken ends up doing nothing
+        in that case. Well, except when exceptions are thrown. Then it might do some work, but it's
+        minor.
+
+        When all CodeBlocks opt in, there is about 6% overhead. That's too much overhead to enable
+        this all the time, but it's low enough to justify enabling in the Inspector. It's currently
+        enabled on all CodeBlocks only when you use an Option. Otherwise it will auto-enable if the
+        debugger is on.
+
+        Note that ShadowChicken attempts to gracefully handle the presence of stack frames that have
+        no logging. This is essential since we *can* have debugging enabled in one GlobalObject and
+        disabled in another. Also, some frames don't do ShadowChicken because they just haven't been
+        hacked to do it yet. Native frames fall into this category, as do the VM entry frames.
+
+        This doesn't yet wire ShadowChicken into DebuggerCallFrame. That will take more work. It
+        just makes a ShadowChicken stack walk function available to jsc. It's used from the
+        shadow-chicken tests.
+
+        * API/JSContextRef.cpp:
+        (BacktraceFunctor::BacktraceFunctor):
+        (BacktraceFunctor::operator()):
+        (JSContextCreateBacktrace):
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/BytecodeList.json:
+        * bytecode/BytecodeUseDef.h:
+        (JSC::computeUsesForBytecodeOffset):
+        (JSC::computeDefsForBytecodeOffset):
+        * bytecode/CodeBlock.cpp:
+        (JSC::CodeBlock::dumpBytecode):
+        (JSC::RecursionCheckFunctor::RecursionCheckFunctor):
+        (JSC::RecursionCheckFunctor::operator()):
+        (JSC::CodeBlock::noticeIncomingCall):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitEnter):
+        (JSC::BytecodeGenerator::emitCallInTailPosition):
+        (JSC::BytecodeGenerator::emitCallVarargsInTailPosition):
+        (JSC::BytecodeGenerator::emitCallVarargs):
+        (JSC::BytecodeGenerator::emitLogShadowChickenPrologueIfNecessary):
+        (JSC::BytecodeGenerator::emitLogShadowChickenTailIfNecessary):
+        (JSC::BytecodeGenerator::emitCallDefineProperty):
+        * bytecompiler/BytecodeGenerator.h:
+        * debugger/DebuggerCallFrame.cpp:
+        (JSC::LineAndColumnFunctor::operator()):
+        (JSC::LineAndColumnFunctor::column):
+        (JSC::FindCallerMidStackFunctor::FindCallerMidStackFunctor):
+        (JSC::FindCallerMidStackFunctor::operator()):
+        (JSC::DebuggerCallFrame::DebuggerCallFrame):
+        * dfg/DFGAbstractInterpreterInlines.h:
+        (JSC::DFG::AbstractInterpreter&lt;AbstractStateType&gt;::executeEffects):
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGClobberize.h:
+        (JSC::DFG::clobberize):
+        * dfg/DFGDoesGC.cpp:
+        (JSC::DFG::doesGC):
+        * dfg/DFGFixupPhase.cpp:
+        (JSC::DFG::FixupPhase::fixupNode):
+        * dfg/DFGNodeType.h:
+        * dfg/DFGPredictionPropagationPhase.cpp:
+        (JSC::DFG::PredictionPropagationPhase::propagate):
+        * dfg/DFGSafeToExecute.h:
+        (JSC::DFG::safeToExecute):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * dfg/DFGSpeculativeJIT64.cpp:
+        (JSC::DFG::SpeculativeJIT::compile):
+        * ftl/FTLAbstractHeapRepository.cpp:
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
+        (JSC::FTL::DFG::LowerDFGToB3::compileSetRegExpObjectLastIndex):
+        (JSC::FTL::DFG::LowerDFGToB3::compileLogShadowChickenPrologue):
+        (JSC::FTL::DFG::LowerDFGToB3::compileLogShadowChickenTail):
+        (JSC::FTL::DFG::LowerDFGToB3::didOverflowStack):
+        (JSC::FTL::DFG::LowerDFGToB3::allocateJSArray):
+        (JSC::FTL::DFG::LowerDFGToB3::setupShadowChickenPacket):
+        (JSC::FTL::DFG::LowerDFGToB3::boolify):
+        * heap/Heap.cpp:
+        (JSC::Heap::markRoots):
+        (JSC::Heap::visitSamplingProfiler):
+        (JSC::Heap::visitShadowChicken):
+        (JSC::Heap::traceCodeBlocksAndJITStubRoutines):
+        (JSC::Heap::collectImpl):
+        * heap/Heap.h:
+        * inspector/ScriptCallStackFactory.cpp:
+        (Inspector::CreateScriptCallStackFunctor::CreateScriptCallStackFunctor):
+        (Inspector::CreateScriptCallStackFunctor::operator()):
+        (Inspector::createScriptCallStack):
+        * interpreter/CallFrame.h:
+        (JSC::ExecState::iterate):
+        * interpreter/Interpreter.cpp:
+        (JSC::DumpRegisterFunctor::DumpRegisterFunctor):
+        (JSC::DumpRegisterFunctor::operator()):
+        (JSC::GetStackTraceFunctor::GetStackTraceFunctor):
+        (JSC::GetStackTraceFunctor::operator()):
+        (JSC::Interpreter::getStackTrace):
+        (JSC::GetCatchHandlerFunctor::handler):
+        (JSC::GetCatchHandlerFunctor::operator()):
+        (JSC::notifyDebuggerOfUnwinding):
+        (JSC::UnwindFunctor::UnwindFunctor):
+        (JSC::UnwindFunctor::operator()):
+        (JSC::UnwindFunctor::copyCalleeSavesToVMCalleeSavesBuffer):
+        * interpreter/ShadowChicken.cpp: Added.
+        (JSC::ShadowChicken::Packet::dump):
+        (JSC::ShadowChicken::Frame::dump):
+        (JSC::ShadowChicken::ShadowChicken):
+        (JSC::ShadowChicken::~ShadowChicken):
+        (JSC::ShadowChicken::log):
+        (JSC::ShadowChicken::update):
+        (JSC::ShadowChicken::visitChildren):
+        (JSC::ShadowChicken::reset):
+        (JSC::ShadowChicken::dump):
+        (JSC::ShadowChicken::functionsOnStack):
+        * interpreter/ShadowChicken.h: Added.
+        (JSC::ShadowChicken::Packet::Packet):
+        (JSC::ShadowChicken::Packet::tailMarker):
+        (JSC::ShadowChicken::Packet::throwMarker):
+        (JSC::ShadowChicken::Packet::prologue):
+        (JSC::ShadowChicken::Packet::tail):
+        (JSC::ShadowChicken::Packet::throwPacket):
+        (JSC::ShadowChicken::Packet::operator bool):
+        (JSC::ShadowChicken::Packet::isPrologue):
+        (JSC::ShadowChicken::Packet::isTail):
+        (JSC::ShadowChicken::Packet::isThrow):
+        (JSC::ShadowChicken::Frame::Frame):
+        (JSC::ShadowChicken::Frame::operator==):
+        (JSC::ShadowChicken::Frame::operator!=):
+        (JSC::ShadowChicken::log):
+        (JSC::ShadowChicken::logSize):
+        (JSC::ShadowChicken::addressOfLogCursor):
+        (JSC::ShadowChicken::logEnd):
+        * interpreter/ShadowChickenInlines.h: Added.
+        (JSC::ShadowChicken::iterate):
+        * interpreter/StackVisitor.h:
+        (JSC::StackVisitor::Frame::callee):
+        (JSC::StackVisitor::Frame::codeBlock):
+        (JSC::StackVisitor::Frame::bytecodeOffset):
+        (JSC::StackVisitor::Frame::inlineCallFrame):
+        (JSC::StackVisitor::Frame::isJSFrame):
+        (JSC::StackVisitor::Frame::isInlinedFrame):
+        (JSC::StackVisitor::visit):
+        * jit/CCallHelpers.cpp: Added.
+        (JSC::CCallHelpers::logShadowChickenProloguePacket):
+        (JSC::CCallHelpers::logShadowChickenTailPacket):
+        (JSC::CCallHelpers::setupShadowChickenPacket):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::prepareForTailCallSlow):
+        * jit/JIT.cpp:
+        (JSC::JIT::privateCompileMainPass):
+        * jit/JIT.h:
+        * jit/JITExceptions.cpp:
+        (JSC::genericUnwind):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_resume):
+        (JSC::JIT::emit_op_log_shadow_chicken_prologue):
+        (JSC::JIT::emit_op_log_shadow_chicken_tail):
+        * jit/JITOperations.cpp:
+        * jit/JITOperations.h:
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (FunctionJSCStackFunctor::FunctionJSCStackFunctor):
+        (FunctionJSCStackFunctor::operator()):
+        (functionClearSamplingFlags):
+        (functionShadowChickenFunctionsOnStack):
+        (functionReadline):
+        * llint/LLIntOffsetsExtractor.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
+        (JSC::LLInt::llint_throw_stack_overflow_error):
+        * llint/LLIntSlowPaths.h:
+        * llint/LowLevelInterpreter.asm:
+        * profiler/ProfileGenerator.cpp:
+        (JSC::AddParentForConsoleStartFunctor::foundParent):
+        (JSC::AddParentForConsoleStartFunctor::operator()):
+        * runtime/Error.cpp:
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor):
+        (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()):
+        (JSC::addErrorInfoAndGetBytecodeOffset):
+        * runtime/JSFunction.cpp:
+        (JSC::RetrieveArgumentsFunctor::result):
+        (JSC::RetrieveArgumentsFunctor::operator()):
+        (JSC::retrieveArguments):
+        (JSC::RetrieveCallerFunctionFunctor::result):
+        (JSC::RetrieveCallerFunctionFunctor::operator()):
+        (JSC::retrieveCallerFunction):
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::GlobalFuncProtoGetterFunctor::result):
+        (JSC::GlobalFuncProtoGetterFunctor::operator()):
+        (JSC::globalFuncProtoGetter):
+        (JSC::GlobalFuncProtoSetterFunctor::allowsAccess):
+        (JSC::GlobalFuncProtoSetterFunctor::operator()):
+        * runtime/NullSetterFunction.cpp:
+        (JSC::GetCallerStrictnessFunctor::GetCallerStrictnessFunctor):
+        (JSC::GetCallerStrictnessFunctor::operator()):
+        (JSC::GetCallerStrictnessFunctor::callerIsStrict):
+        (JSC::callerIsStrict):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructorGetPrototypeOfFunctor::result):
+        (JSC::ObjectConstructorGetPrototypeOfFunctor::operator()):
+        (JSC::objectConstructorGetPrototypeOf):
+        * runtime/Options.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::SetEnabledProfilerFunctor::operator()):
+        * runtime/VM.h:
+        (JSC::VM::shouldBuilderPCToCodeOriginMapping):
+        (JSC::VM::bytecodeIntrinsicRegistry):
+        (JSC::VM::shadowChicken):
+        * tests/stress/resources/shadow-chicken-support.js: Added.
+        (describeFunction):
+        (describeArray):
+        (expectStack):
+        (initialize):
+        * tests/stress/shadow-chicken-disabled.js: Added.
+        (test1.foo):
+        (test1.bar):
+        (test1.baz):
+        (test1):
+        (test2.foo):
+        (test2.bar):
+        (test2.baz):
+        (test2):
+        (test3.foo):
+        (test3.bar):
+        (test3.baz):
+        (test3):
+        * tests/stress/shadow-chicken-enabled.js: Added.
+        (test1.foo):
+        (test1.bar):
+        (test1.baz):
+        (test1):
+        (test2.foo):
+        (test2.bar):
+        (test2.baz):
+        (test2):
+        (test3.bob):
+        (test3.thingy):
+        (test3.foo):
+        (test3.bar):
+        (test3.baz):
+        (test3):
+        (test4.bob):
+        (test4.thingy):
+        (test4.foo):
+        (test4.bar):
+        (test4.baz):
+        (test4):
+        (test5.foo):
+        (test5):
+        * tools/JSDollarVMPrototype.cpp:
+        (JSC::CallerFrameJITTypeFunctor::CallerFrameJITTypeFunctor):
+        (JSC::CallerFrameJITTypeFunctor::operator()):
+        (JSC::CallerFrameJITTypeFunctor::jitType):
+        (JSC::functionLLintTrue):
+        (JSC::CellAddressCheckFunctor::CellAddressCheckFunctor):
+        (JSC::CellAddressCheckFunctor::operator()):
+        (JSC::JSDollarVMPrototype::isValidCell):
+        (JSC::JSDollarVMPrototype::isValidCodeBlock):
+        (JSC::JSDollarVMPrototype::codeBlockForFrame):
+        (JSC::PrintFrameFunctor::PrintFrameFunctor):
+        (JSC::PrintFrameFunctor::operator()):
+        (JSC::printCallFrame):
+
</ins><span class="cx"> 2016-03-19  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         DFG and FTL should constant-fold RegExpExec, RegExpTest, and StringReplace
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1991,6 +1991,10 @@
</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>+                DC17E8171C9C91D6008A6AB3 /* ShadowChicken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC17E8131C9C7FD4008A6AB3 /* ShadowChicken.cpp */; };
+                DC17E8181C9C91D9008A6AB3 /* ShadowChicken.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17E8141C9C7FD4008A6AB3 /* ShadowChicken.h */; };
+                DC17E8191C9C91DB008A6AB3 /* ShadowChickenInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */; };
+                DC17E81A1C9C91E9008A6AB3 /* CCallHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */; };
</ins><span class="cx">                 DE5A0A001BA3AC3E003D4424 /* IntrinsicEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */; };
</span><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="lines">@@ -4192,6 +4196,10 @@
</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>+                DC17E8131C9C7FD4008A6AB3 /* ShadowChicken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowChicken.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                DC17E8141C9C7FD4008A6AB3 /* ShadowChicken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowChicken.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowChickenInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCallHelpers.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicEmitter.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><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="lines">@@ -4944,6 +4952,9 @@
</span><span class="cx">                                 65FB5116184EE9BC00C12B70 /* ProtoCallFrame.cpp */,
</span><span class="cx">                                 65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */,
</span><span class="cx">                                 149B24FF0D8AF6D1009CB8C7 /* Register.h */,
</span><ins>+                                DC17E8131C9C7FD4008A6AB3 /* ShadowChicken.cpp */,
+                                DC17E8141C9C7FD4008A6AB3 /* ShadowChicken.h */,
+                                DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */,
</ins><span class="cx">                                 A7C1EAEC17987AB600299DB2 /* StackVisitor.cpp */,
</span><span class="cx">                                 A7C1EAED17987AB600299DB2 /* StackVisitor.h */,
</span><span class="cx">                                 658D3A5519638268003C45D6 /* VMEntryRecord.h */,
</span><span class="lines">@@ -4966,6 +4977,7 @@
</span><span class="cx">                                 62D755D11B84FB39001801FA /* CallFrameShuffler.h */,
</span><span class="cx">                                 62D755D21B84FB39001801FA /* CallFrameShuffler32_64.cpp */,
</span><span class="cx">                                 62D755D31B84FB39001801FA /* CallFrameShuffler64.cpp */,
</span><ins>+                                DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */,
</ins><span class="cx">                                 0F24E53D17EA9F5900ABB217 /* CCallHelpers.h */,
</span><span class="cx">                                 0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
</span><span class="cx">                                 0FF054F71AC35B4400E5BE57 /* ExecutableAllocationFuzz.cpp */,
</span><span class="lines">@@ -7612,6 +7624,7 @@
</span><span class="cx">                                 BC18C41E0E16F5CD00B34460 /* JSContextRef.h in Headers */,
</span><span class="cx">                                 A5EA70EE19F5B5C40098F5EC /* JSContextRefInspectorSupport.h in Headers */,
</span><span class="cx">                                 A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
</span><ins>+                                DC17E8191C9C91DB008A6AB3 /* ShadowChickenInlines.h in Headers */,
</ins><span class="cx">                                 A5AB49DD1BEC8086007020FB /* PerGlobalObjectWrapperWorld.h in Headers */,
</span><span class="cx">                                 148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
</span><span class="cx">                                 A72028B81797601E0098028C /* JSCTestRunnerUtils.h in Headers */,
</span><span class="lines">@@ -8057,6 +8070,7 @@
</span><span class="cx">                                 A7CA3AE617DA41AE006538AF /* WeakMapPrototype.h in Headers */,
</span><span class="cx">                                 0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */,
</span><span class="cx">                                 14E84FA114EE1ACC00D6D5D4 /* WeakSet.h in Headers */,
</span><ins>+                                DC17E8181C9C91D9008A6AB3 /* ShadowChicken.h in Headers */,
</ins><span class="cx">                                 709FB86A1AE335C60039D069 /* WeakSetConstructor.h in Headers */,
</span><span class="cx">                                 14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */,
</span><span class="cx">                                 709FB86C1AE335C60039D069 /* WeakSetPrototype.h in Headers */,
</span><span class="lines">@@ -9033,6 +9047,7 @@
</span><span class="cx">                                 FE4238901BE18C3C00514737 /* JITSubGenerator.cpp in Sources */,
</span><span class="cx">                                 70B791941C024A28002481E2 /* GeneratorFunctionConstructor.cpp in Sources */,
</span><span class="cx">                                 0F5EF91E16878F7A003E5C25 /* JITThunks.cpp in Sources */,
</span><ins>+                                DC17E81A1C9C91E9008A6AB3 /* CCallHelpers.cpp in Sources */,
</ins><span class="cx">                                 0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */,
</span><span class="cx">                                 140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */,
</span><span class="cx">                                 C2CF39C116E15A8100DD69BE /* JSAPIWrapperObject.mm in Sources */,
</span><span class="lines">@@ -9112,6 +9127,7 @@
</span><span class="cx">                                 14874AE515EBDE4A002E3587 /* JSScope.cpp in Sources */,
</span><span class="cx">                                 A7C0C4AD1681067E0017011D /* JSScriptRef.cpp in Sources */,
</span><span class="cx">                                 0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */,
</span><ins>+                                DC17E8171C9C91D6008A6AB3 /* ShadowChicken.cpp in Sources */,
</ins><span class="cx">                                 A7299D9D17D12837005F5FF9 /* JSSet.cpp in Sources */,
</span><span class="cx">                                 A790DD6F182F499700588807 /* JSSetIterator.cpp in Sources */,
</span><span class="cx">                                 1428083A107EC0750013E7B2 /* JSStack.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.json (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.json        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -137,7 +137,9 @@
</span><span class="cx">             { &quot;name&quot; : &quot;op_get_rest_length&quot;, &quot;length&quot;: 3 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_save&quot;, &quot;length&quot; : 4 },
</span><span class="cx">             { &quot;name&quot; : &quot;op_resume&quot;, &quot;length&quot; : 3 },
</span><del>-            { &quot;name&quot; : &quot;op_watchdog&quot;, &quot;length&quot; : 1 }
</del><ins>+            { &quot;name&quot; : &quot;op_watchdog&quot;, &quot;length&quot; : 1 },
+            { &quot;name&quot; : &quot;op_log_shadow_chicken_prologue&quot;, &quot;length&quot; : 1},
+            { &quot;name&quot; : &quot;op_log_shadow_chicken_tail&quot;, &quot;length&quot; : 1}
</ins><span class="cx">         ]
</span><span class="cx">     },
</span><span class="cx">     {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeUseDefh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -55,6 +55,8 @@
</span><span class="cx">     case op_create_cloned_arguments:
</span><span class="cx">     case op_get_rest_length:
</span><span class="cx">     case op_watchdog:
</span><ins>+    case op_log_shadow_chicken_prologue:
+    case op_log_shadow_chicken_tail:
</ins><span class="cx">         return;
</span><span class="cx">     case op_assert:
</span><span class="cx">     case op_get_scope:
</span><span class="lines">@@ -326,6 +328,8 @@
</span><span class="cx">     case op_put_to_arguments:
</span><span class="cx">     case op_set_function_name:
</span><span class="cx">     case op_watchdog:
</span><ins>+    case op_log_shadow_chicken_prologue:
+    case op_log_shadow_chicken_tail:
</ins><span class="cx"> #define LLINT_HELPER_OPCODES(opcode, length) case opcode:
</span><span class="cx">         FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
</span><span class="cx"> #undef LLINT_HELPER_OPCODES
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeCodeBlockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008-2010, 2012-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008-2010, 2012-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2008 Cameron Zwarich &lt;cwzwarich@uwaterloo.ca&gt;
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -1315,6 +1315,14 @@
</span><span class="cx">             printLocationAndOp(out, exec, location, it, &quot;watchdog&quot;);
</span><span class="cx">             break;
</span><span class="cx">         }
</span><ins>+        case op_log_shadow_chicken_prologue: {
+            printLocationAndOp(out, exec, location, it, &quot;log_shadow_chicken_prologue&quot;);
+            break;
+        }
+        case op_log_shadow_chicken_tail: {
+            printLocationAndOp(out, exec, location, it, &quot;log_shadow_chicken_tail&quot;);
+            break;
+        }
</ins><span class="cx">         case op_switch_imm: {
</span><span class="cx">             int tableIndex = (++it)-&gt;u.operand;
</span><span class="cx">             int defaultTarget = (++it)-&gt;u.operand;
</span><span class="lines">@@ -3394,7 +3402,7 @@
</span><span class="cx">         , m_didRecurse(false)
</span><span class="cx">     { }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         CallFrame* currentCallFrame = visitor-&gt;callFrame();
</span><span class="cx"> 
</span><span class="lines">@@ -3419,9 +3427,9 @@
</span><span class="cx"> private:
</span><span class="cx">     CallFrame* m_startCallFrame;
</span><span class="cx">     CodeBlock* m_codeBlock;
</span><del>-    unsigned m_depthToCheck;
-    bool m_foundStartCallFrame;
-    bool m_didRecurse;
</del><ins>+    mutable unsigned m_depthToCheck;
+    mutable bool m_foundStartCallFrame;
+    mutable bool m_didRecurse;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> void CodeBlock::noticeIncomingCall(ExecState* callerFrame)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1092,6 +1092,7 @@
</span><span class="cx"> void BytecodeGenerator::emitEnter()
</span><span class="cx"> {
</span><span class="cx">     emitOpcode(op_enter);
</span><ins>+    emitLogShadowChickenPrologueIfNecessary();
</ins><span class="cx">     emitWatchdog();
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2972,7 +2973,7 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(opcodeID == op_call || opcodeID == op_call_eval || opcodeID == op_tail_call);
</span><span class="cx">     ASSERT(func-&gt;refCount());
</span><del>-
</del><ins>+    
</ins><span class="cx">     if (m_shouldEmitProfileHooks)
</span><span class="cx">         emitMove(callArguments.profileHookRegister(), func);
</span><span class="cx"> 
</span><span class="lines">@@ -3007,6 +3008,9 @@
</span><span class="cx">     RefPtr&lt;Label&gt; done = newLabel();
</span><span class="cx">     expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
</span><span class="cx">     
</span><ins>+    if (opcodeID == op_tail_call)
+        emitLogShadowChickenTailIfNecessary();
+    
</ins><span class="cx">     // Emit call.
</span><span class="cx">     UnlinkedArrayProfile arrayProfile = newArrayProfile();
</span><span class="cx">     UnlinkedValueProfile profile = emitProfiledOpcode(opcodeID);
</span><span class="lines">@@ -3057,6 +3061,9 @@
</span><span class="cx">     
</span><span class="cx">     emitExpressionInfo(divot, divotStart, divotEnd);
</span><span class="cx"> 
</span><ins>+    if (opcode == op_tail_call_varargs)
+        emitLogShadowChickenTailIfNecessary();
+    
</ins><span class="cx">     // Emit call.
</span><span class="cx">     UnlinkedArrayProfile arrayProfile = newArrayProfile();
</span><span class="cx">     UnlinkedValueProfile profile = emitProfiledOpcode(opcode);
</span><span class="lines">@@ -3076,6 +3083,20 @@
</span><span class="cx">     return dst;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void BytecodeGenerator::emitLogShadowChickenPrologueIfNecessary()
+{
+    if (!m_shouldEmitDebugHooks &amp;&amp; !Options::alwaysUseShadowChicken())
+        return;
+    emitOpcode(op_log_shadow_chicken_prologue);
+}
+
+void BytecodeGenerator::emitLogShadowChickenTailIfNecessary()
+{
+    if (!m_shouldEmitDebugHooks &amp;&amp; !Options::alwaysUseShadowChicken())
+        return;
+    emitOpcode(op_log_shadow_chicken_tail);
+}
+
</ins><span class="cx"> void BytecodeGenerator::emitCallDefineProperty(RegisterID* newObj, RegisterID* propertyNameRegister,
</span><span class="cx">     RegisterID* valueRegister, RegisterID* getterRegister, RegisterID* setterRegister, unsigned options, const JSTextPosition&amp; position)
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecompilerBytecodeGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -836,6 +836,9 @@
</span><span class="cx"> 
</span><span class="cx">         RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><span class="cx">         RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition&amp; divot, const JSTextPosition&amp; divotStart, const JSTextPosition&amp; divotEnd);
</span><ins>+        
+        void emitLogShadowChickenPrologueIfNecessary();
+        void emitLogShadowChickenTailIfNecessary();
</ins><span class="cx"> 
</span><span class="cx">         void initializeParameters(FunctionParameters&amp;);
</span><span class="cx">         void initializeVarLexicalEnvironment(int symbolTableConstantIndex);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredebuggerDebuggerCallFramecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2013-2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -42,9 +42,12 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><ins>+// FIXME: Make this use ShadowChicken so that it sees tail-deleted frames.
+// https://bugs.webkit.org/show_bug.cgi?id=155690
+
</ins><span class="cx"> class LineAndColumnFunctor {
</span><span class="cx"> public:
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         visitor-&gt;computeLineAndColumn(m_line, m_column);
</span><span class="cx">         return StackVisitor::Done;
</span><span class="lines">@@ -54,8 +57,8 @@
</span><span class="cx">     unsigned column() const { return m_column; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    unsigned m_line;
-    unsigned m_column;
</del><ins>+    mutable unsigned m_line;
+    mutable unsigned m_column;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class FindCallerMidStackFunctor {
</span><span class="lines">@@ -65,7 +68,7 @@
</span><span class="cx">         , m_callerFrame(nullptr)
</span><span class="cx">     { }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (visitor-&gt;callFrame() == m_callFrame) {
</span><span class="cx">             m_callerFrame = visitor-&gt;callerFrame();
</span><span class="lines">@@ -78,7 +81,7 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     CallFrame* m_callFrame;
</span><del>-    CallFrame* m_callerFrame;
</del><ins>+    mutable CallFrame* m_callerFrame;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> DebuggerCallFrame::DebuggerCallFrame(CallFrame* callFrame)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGAbstractInterpreterInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -2626,6 +2626,8 @@
</span><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case CheckWatchdogTimer:
</span><ins>+    case LogShadowChickenPrologue:
+    case LogShadowChickenTail:
</ins><span class="cx">         break;
</span><span class="cx"> 
</span><span class="cx">     case ProfileWillCall:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGByteCodeParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -4749,7 +4749,23 @@
</span><span class="cx">                 get(VirtualRegister(currentInstruction[2].u.operand))));
</span><span class="cx">             NEXT_OPCODE(op_to_index_string);
</span><span class="cx">         }
</span><ins>+            
+        case op_log_shadow_chicken_prologue: {
+            if (!m_inlineStackTop-&gt;m_inlineCallFrame)
+                addToGraph(LogShadowChickenPrologue);
+            NEXT_OPCODE(op_log_shadow_chicken_prologue);
+        }
</ins><span class="cx"> 
</span><ins>+        case op_log_shadow_chicken_tail: {
+            if (!m_inlineStackTop-&gt;m_inlineCallFrame) {
+                // FIXME: The right solution for inlining is to elide these whenever the tail call
+                // ends up being inlined.
+                // https://bugs.webkit.org/show_bug.cgi?id=155686
+                addToGraph(LogShadowChickenTail);
+            }
+            NEXT_OPCODE(op_log_shadow_chicken_tail);
+        }
+
</ins><span class="cx">         default:
</span><span class="cx">             // Parse failed! This should not happen because the capabilities checker
</span><span class="cx">             // should have caught it.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -225,6 +225,8 @@
</span><span class="cx">     case op_catch:
</span><span class="cx">     case op_copy_rest:
</span><span class="cx">     case op_get_rest_length:
</span><ins>+    case op_log_shadow_chicken_prologue:
+    case op_log_shadow_chicken_tail:
</ins><span class="cx">         return CanCompileAndInline;
</span><span class="cx"> 
</span><span class="cx">     case op_put_to_scope: {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGClobberizeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGClobberize.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGClobberize.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1159,6 +1159,11 @@
</span><span class="cx">         write(InternalState);
</span><span class="cx">         return;
</span><span class="cx">         
</span><ins>+    case LogShadowChickenPrologue:
+    case LogShadowChickenTail:
+        write(SideState);
+        return;
+        
</ins><span class="cx">     case LastNodeType:
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         return;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGDoesGCcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -234,6 +234,8 @@
</span><span class="cx">     case GetFromArguments:
</span><span class="cx">     case PutToArguments:
</span><span class="cx">     case CopyRest:
</span><ins>+    case LogShadowChickenPrologue:
+    case LogShadowChickenTail:
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     case CreateActivation:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGFixupPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1508,6 +1508,8 @@
</span><span class="cx">         case CheckBadCell:
</span><span class="cx">         case CheckNotEmpty:
</span><span class="cx">         case CheckWatchdogTimer:
</span><ins>+        case LogShadowChickenPrologue:
+        case LogShadowChickenTail:
</ins><span class="cx">         case Unreachable:
</span><span class="cx">         case ExtractOSREntryLocal:
</span><span class="cx">         case LoopHint:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGNodeTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGNodeType.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGNodeType.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -265,6 +265,10 @@
</span><span class="cx">     macro(TailCallVarargsInlinedCaller, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     macro(TailCallForwardVarargsInlinedCaller, NodeResultJS | NodeMustGenerate) \
</span><span class="cx">     \
</span><ins>+    /* Shadow Chicken */\
+    macro(LogShadowChickenPrologue, NodeMustGenerate) \
+    macro(LogShadowChickenTail, NodeMustGenerate) \
+    \
</ins><span class="cx">     /* Allocations. */\
</span><span class="cx">     macro(NewObject, NodeResultJS) \
</span><span class="cx">     macro(NewArray, NodeResultJS | NodeHasVarArgs) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -788,6 +788,8 @@
</span><span class="cx"> char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
</span><span class="cx">     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
</ins><span class="cx">     return reinterpret_cast&lt;char*&gt;(constructGenericTypedArrayViewWithArguments&lt;JSInt8Array&gt;(exec, structure, encodedValue, 0, Nullopt));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -800,6 +802,8 @@
</span><span class="cx"> char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
</span><span class="cx">     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
</ins><span class="cx">     return reinterpret_cast&lt;char*&gt;(constructGenericTypedArrayViewWithArguments&lt;JSInt16Array&gt;(exec, structure, encodedValue, 0, Nullopt));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -812,6 +816,8 @@
</span><span class="cx"> char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
</span><span class="cx">     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
</ins><span class="cx">     return reinterpret_cast&lt;char*&gt;(constructGenericTypedArrayViewWithArguments&lt;JSInt32Array&gt;(exec, structure, encodedValue, 0, Nullopt));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -824,6 +830,8 @@
</span><span class="cx"> char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
</span><span class="cx">     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
</ins><span class="cx">     return reinterpret_cast&lt;char*&gt;(constructGenericTypedArrayViewWithArguments&lt;JSUint8Array&gt;(exec, structure, encodedValue, 0, Nullopt));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -836,6 +844,8 @@
</span><span class="cx"> char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
</span><span class="cx">     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
</ins><span class="cx">     return reinterpret_cast&lt;char*&gt;(constructGenericTypedArrayViewWithArguments&lt;JSUint8ClampedArray&gt;(exec, structure, encodedValue, 0, Nullopt));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -848,6 +858,8 @@
</span><span class="cx"> char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
</span><span class="cx">     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
</ins><span class="cx">     return reinterpret_cast&lt;char*&gt;(constructGenericTypedArrayViewWithArguments&lt;JSUint16Array&gt;(exec, structure, encodedValue, 0, Nullopt));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -860,6 +872,8 @@
</span><span class="cx"> char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
</span><span class="cx">     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
</ins><span class="cx">     return reinterpret_cast&lt;char*&gt;(constructGenericTypedArrayViewWithArguments&lt;JSUint32Array&gt;(exec, structure, encodedValue, 0, Nullopt));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -872,6 +886,8 @@
</span><span class="cx"> char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
</span><span class="cx">     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
</ins><span class="cx">     return reinterpret_cast&lt;char*&gt;(constructGenericTypedArrayViewWithArguments&lt;JSFloat32Array&gt;(exec, structure, encodedValue, 0, Nullopt));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -884,6 +900,8 @@
</span><span class="cx"> char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
</span><span class="cx">     ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
</ins><span class="cx">     return reinterpret_cast&lt;char*&gt;(constructGenericTypedArrayViewWithArguments&lt;JSFloat64Array&gt;(exec, structure, encodedValue, 0, Nullopt));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGPredictionPropagationPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -765,6 +765,8 @@
</span><span class="cx">         case Check:
</span><span class="cx">         case PutGlobalVariable:
</span><span class="cx">         case CheckWatchdogTimer:
</span><ins>+        case LogShadowChickenPrologue:
+        case LogShadowChickenTail:
</ins><span class="cx">         case Unreachable:
</span><span class="cx">         case LoopHint:
</span><span class="cx">         case NotifyWrite:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSafeToExecuteh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -289,6 +289,8 @@
</span><span class="cx">     case CountExecution:
</span><span class="cx">     case ForceOSRExit:
</span><span class="cx">     case CheckWatchdogTimer:
</span><ins>+    case LogShadowChickenPrologue:
+    case LogShadowChickenTail:
</ins><span class="cx">     case StringFromCharCode:
</span><span class="cx">     case NewTypedArray:
</span><span class="cx">     case Unreachable:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -4946,6 +4946,24 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case LogShadowChickenPrologue: {
+        flushRegisters();
+        prepareForExternalCall();
+        m_jit.emitStoreCodeOrigin(node-&gt;origin.semantic);
+        m_jit.logShadowChickenProloguePacket();
+        noResult(node);
+        break;
+    }
+
+    case LogShadowChickenTail: {
+        flushRegisters();
+        prepareForExternalCall();
+        m_jit.emitStoreCodeOrigin(node-&gt;origin.semantic);
+        m_jit.logShadowChickenTailPacket();
+        noResult(node);
+        break;
+    }
+
</ins><span class="cx">     case ForceOSRExit: {
</span><span class="cx">         terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJIT64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -4993,7 +4993,25 @@
</span><span class="cx">         noResult(node);
</span><span class="cx">         break;
</span><span class="cx">     }
</span><ins>+        
+    case LogShadowChickenPrologue: {
+        flushRegisters();
+        prepareForExternalCall();
+        m_jit.emitStoreCodeOrigin(node-&gt;origin.semantic);
+        m_jit.logShadowChickenProloguePacket();
+        noResult(node);
+        break;
+    }
</ins><span class="cx"> 
</span><ins>+    case LogShadowChickenTail: {
+        flushRegisters();
+        prepareForExternalCall();
+        m_jit.emitStoreCodeOrigin(node-&gt;origin.semantic);
+        m_jit.logShadowChickenTailPacket();
+        noResult(node);
+        break;
+    }
+
</ins><span class="cx">     case MaterializeNewObject:
</span><span class="cx">         compileMaterializeNewObject(node);
</span><span class="cx">         break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLAbstractHeapRepositorycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx"> #include &quot;RegExpObject.h&quot;
</span><span class="cx"> #include &quot;ScopedArguments.h&quot;
</span><span class="cx"> #include &quot;ScopedArgumentsTable.h&quot;
</span><ins>+#include &quot;ShadowChicken.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLAbstractHeapRepositoryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -84,6 +84,9 @@
</span><span class="cx">     macro(RegExpConstructor_cachedResult_reified, RegExpConstructor::offsetOfCachedResult() + RegExpCachedResult::offsetOfReified()) \
</span><span class="cx">     macro(RegExpObject_lastIndex, RegExpObject::offsetOfLastIndex()) \
</span><span class="cx">     macro(RegExpObject_lastIndexIsWritable, RegExpObject::offsetOfLastIndexIsWritable()) \
</span><ins>+    macro(ShadowChicken_Packet_callee, OBJECT_OFFSETOF(ShadowChicken::Packet, callee)) \
+    macro(ShadowChicken_Packet_frame, OBJECT_OFFSETOF(ShadowChicken::Packet, frame)) \
+    macro(ShadowChicken_Packet_callerFrame, OBJECT_OFFSETOF(ShadowChicken::Packet, callerFrame)) \
</ins><span class="cx">     macro(ScopedArguments_overrodeThings, ScopedArguments::offsetOfOverrodeThings()) \
</span><span class="cx">     macro(ScopedArguments_scope, ScopedArguments::offsetOfScope()) \
</span><span class="cx">     macro(ScopedArguments_table, ScopedArguments::offsetOfTable()) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -230,6 +230,8 @@
</span><span class="cx">     case SetRegExpObjectLastIndex:
</span><span class="cx">     case RecordRegExpCachedResult:
</span><span class="cx">     case SetFunctionName:
</span><ins>+    case LogShadowChickenPrologue:
+    case LogShadowChickenTail:
</ins><span class="cx">         // These are OK.
</span><span class="cx">         break;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -68,6 +68,7 @@
</span><span class="cx"> #include &quot;ScopedArguments.h&quot;
</span><span class="cx"> #include &quot;ScopedArgumentsTable.h&quot;
</span><span class="cx"> #include &quot;ScratchRegisterAllocator.h&quot;
</span><ins>+#include &quot;ShadowChicken.h&quot;
</ins><span class="cx"> #include &quot;SetupVarargsFrame.h&quot;
</span><span class="cx"> #include &quot;VirtualRegister.h&quot;
</span><span class="cx"> #include &quot;Watchdog.h&quot;
</span><span class="lines">@@ -941,6 +942,12 @@
</span><span class="cx">         case SetRegExpObjectLastIndex:
</span><span class="cx">             compileSetRegExpObjectLastIndex();
</span><span class="cx">             break;
</span><ins>+        case LogShadowChickenPrologue:
+            compileLogShadowChickenPrologue();
+            break;
+        case LogShadowChickenTail:
+            compileLogShadowChickenTail();
+            break;
</ins><span class="cx">         case RecordRegExpCachedResult:
</span><span class="cx">             compileRecordRegExpCachedResult();
</span><span class="cx">             break;
</span><span class="lines">@@ -6768,6 +6775,23 @@
</span><span class="cx">         
</span><span class="cx">         m_out.store64(value, regExp, m_heaps.RegExpObject_lastIndex);
</span><span class="cx">     }
</span><ins>+    
+    void compileLogShadowChickenPrologue()
+    {
+        LValue packet = setupShadowChickenPacket();
+        
+        m_out.storePtr(m_callFrame, packet, m_heaps.ShadowChicken_Packet_frame);
+        m_out.storePtr(m_out.loadPtr(addressFor(0)), packet, m_heaps.ShadowChicken_Packet_callerFrame);
+        m_out.storePtr(m_out.loadPtr(payloadFor(JSStack::Callee)), packet, m_heaps.ShadowChicken_Packet_callee);
+    }
+    
+    void compileLogShadowChickenTail()
+    {
+        LValue packet = setupShadowChickenPacket();
+        
+        m_out.storePtr(m_callFrame, packet, m_heaps.ShadowChicken_Packet_frame);
+        m_out.storePtr(m_out.constIntPtr(ShadowChicken::Packet::tailMarker()), packet, m_heaps.ShadowChicken_Packet_callee);
+    }
</ins><span class="cx"> 
</span><span class="cx">     void compileRecordRegExpCachedResult()
</span><span class="cx">     {
</span><span class="lines">@@ -7992,6 +8016,37 @@
</span><span class="cx">             m_out.phi(m_out.intPtr, fastButterfly, slowButterfly));
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    LValue setupShadowChickenPacket()
+    {
+        LBasicBlock slowCase = m_out.newBlock();
+        LBasicBlock continuation = m_out.newBlock();
+        
+        TypedPointer addressOfLogCursor = m_out.absolute(vm().shadowChicken().addressOfLogCursor());
+        LValue logCursor = m_out.loadPtr(addressOfLogCursor);
+        
+        ValueFromBlock fastResult = m_out.anchor(logCursor);
+        
+        m_out.branch(
+            m_out.below(logCursor, m_out.constIntPtr(vm().shadowChicken().logEnd())),
+            usually(continuation), rarely(slowCase));
+        
+        LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
+        
+        vmCall(Void, m_out.operation(operationProcessShadowChickenLog), m_callFrame);
+        
+        ValueFromBlock slowResult = m_out.anchor(m_out.loadPtr(addressOfLogCursor));
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        LValue result = m_out.phi(pointerType(), fastResult, slowResult);
+        
+        m_out.storePtr(
+            m_out.add(result, m_out.constIntPtr(sizeof(ShadowChicken::Packet))),
+            addressOfLogCursor);
+        
+        return result;
+    }
+    
</ins><span class="cx">     LValue boolify(Edge edge)
</span><span class="cx">     {
</span><span class="cx">         switch (edge.useKind()) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -45,6 +45,7 @@
</span><span class="cx"> #include &quot;JSLock.h&quot;
</span><span class="cx"> #include &quot;JSVirtualMachineInternal.h&quot;
</span><span class="cx"> #include &quot;SamplingProfiler.h&quot;
</span><ins>+#include &quot;ShadowChicken.h&quot;
</ins><span class="cx"> #include &quot;Tracing.h&quot;
</span><span class="cx"> #include &quot;TypeProfilerLog.h&quot;
</span><span class="cx"> #include &quot;UnlinkedCodeBlock.h&quot;
</span><span class="lines">@@ -597,6 +598,7 @@
</span><span class="cx">         visitStrongHandles(heapRootVisitor);
</span><span class="cx">         visitHandleStack(heapRootVisitor);
</span><span class="cx">         visitSamplingProfiler();
</span><ins>+        visitShadowChicken();
</ins><span class="cx">         traceCodeBlocksAndJITStubRoutines();
</span><span class="cx">         converge();
</span><span class="cx">     }
</span><span class="lines">@@ -899,6 +901,11 @@
</span><span class="cx"> #endif // ENABLE(SAMPLING_PROFILER)
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Heap::visitShadowChicken()
+{
+    m_vm-&gt;shadowChicken().visitChildren(m_slotVisitor);
+}
+
</ins><span class="cx"> void Heap::traceCodeBlocksAndJITStubRoutines()
</span><span class="cx"> {
</span><span class="cx">     GCPHASE(TraceCodeBlocksAndJITStubRoutines);
</span><span class="lines">@@ -1123,7 +1130,9 @@
</span><span class="cx">         DeferGCForAWhile awhile(*this);
</span><span class="cx">         vm()-&gt;typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;GC&quot;));
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+    vm()-&gt;shadowChicken().update(*vm(), vm()-&gt;topCallFrame);
+
</ins><span class="cx">     RELEASE_ASSERT(!m_deferralDepth);
</span><span class="cx">     ASSERT(vm()-&gt;currentThreadIsHoldingAPILock());
</span><span class="cx">     RELEASE_ASSERT(vm()-&gt;atomicStringTable() == wtfThreadData().atomicStringTable());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/heap/Heap.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -317,6 +317,7 @@
</span><span class="cx">     void visitStrongHandles(HeapRootVisitor&amp;);
</span><span class="cx">     void visitHandleStack(HeapRootVisitor&amp;);
</span><span class="cx">     void visitSamplingProfiler();
</span><ins>+    void visitShadowChicken();
</ins><span class="cx">     void traceCodeBlocksAndJITStubRoutines();
</span><span class="cx">     void converge();
</span><span class="cx">     void visitWeakHandles(HeapRootVisitor&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorScriptCallStackFactorycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (c) 2010 Google Inc. All rights reserved.
</span><span class="cx">  * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
</span><span class="cx">  *
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (m_needToSkipAFrame) {
</span><span class="cx">             m_needToSkipAFrame = false;
</span><span class="lines">@@ -84,9 +84,9 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    bool m_needToSkipAFrame;
</del><ins>+    mutable bool m_needToSkipAFrame;
</ins><span class="cx">     Vector&lt;ScriptCallFrame&gt;&amp; m_frames;
</span><del>-    size_t m_remainingCapacityForFrameCapture;
</del><ins>+    mutable size_t m_remainingCapacityForFrameCapture;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> Ref&lt;ScriptCallStack&gt; createScriptCallStack(JSC::ExecState* exec, size_t maxStackSize)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterCallFrameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/CallFrame.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/CallFrame.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/interpreter/CallFrame.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2007, 2008, 2011, 2013-2015 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003, 2007, 2008, 2011, 2013-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Library General Public
</span><span class="lines">@@ -245,9 +245,10 @@
</span><span class="cx">         String friendlyFunctionName();
</span><span class="cx"> 
</span><span class="cx">         // CallFrame::iterate() expects a Functor that implements the following method:
</span><del>-        //     StackVisitor::Status operator()(StackVisitor&amp;);
-
-        template &lt;typename Functor&gt; void iterate(Functor&amp; functor)
</del><ins>+        //     StackVisitor::Status operator()(StackVisitor&amp;) const;
+        // FIXME: This method is improper. We rely on the fact that we can call it with a null
+        // receiver. We should always be using StackVisitor directly.
+        template &lt;typename Functor&gt; void iterate(const Functor&amp; functor)
</ins><span class="cx">         {
</span><span class="cx">             StackVisitor::visit&lt;Functor&gt;(this, functor);
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterInterpretercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2009, 2010, 2012-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2008, 2009, 2010, 2012-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2008 Cameron Zwarich &lt;cwzwarich@uwaterloo.ca&gt;
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -353,7 +353,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (!m_hasSkippedFirstFrame) {
</span><span class="cx">             m_hasSkippedFirstFrame = true;
</span><span class="lines">@@ -369,7 +369,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    bool m_hasSkippedFirstFrame;
</del><ins>+    mutable bool m_hasSkippedFirstFrame;
</ins><span class="cx">     const Register*&amp; m_it;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -543,7 +543,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         VM&amp; vm = m_vm;
</span><span class="cx">         if (m_remainingCapacityForFrameCapture) {
</span><span class="lines">@@ -578,7 +578,7 @@
</span><span class="cx"> private:
</span><span class="cx">     VM&amp; m_vm;
</span><span class="cx">     Vector&lt;StackFrame&gt;&amp; m_results;
</span><del>-    size_t m_remainingCapacityForFrameCapture;
</del><ins>+    mutable size_t m_remainingCapacityForFrameCapture;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> void Interpreter::getStackTrace(Vector&lt;StackFrame&gt;&amp; results, size_t maxStackSize)
</span><span class="lines">@@ -630,7 +630,7 @@
</span><span class="cx"> 
</span><span class="cx">     HandlerInfo* handler() { return m_handler; }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         visitor.unwindToMachineCodeBlockFrame();
</span><span class="cx"> 
</span><span class="lines">@@ -646,7 +646,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    HandlerInfo* m_handler;
</del><ins>+    mutable HandlerInfo* m_handler;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE static void notifyDebuggerOfUnwinding(CallFrame* callFrame)
</span><span class="lines">@@ -671,7 +671,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         visitor.unwindToMachineCodeBlockFrame();
</span><span class="cx">         VM&amp; vm = m_callFrame-&gt;vm();
</span><span class="lines">@@ -705,7 +705,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    void copyCalleeSavesToVMCalleeSavesBuffer(StackVisitor&amp; visitor)
</del><ins>+    void copyCalleeSavesToVMCalleeSavesBuffer(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx"> #if ENABLE(JIT) &amp;&amp; NUMBER_OF_CALLEE_SAVES_REGISTERS &gt; 0
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterShadowChickencpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/interpreter/ShadowChicken.cpp (0 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/ShadowChicken.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/interpreter/ShadowChicken.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -0,0 +1,396 @@
</span><ins>+/*
+ * Copyright (C) 2016 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' 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 INC. OR
+ * 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;ShadowChicken.h&quot;
+
+#include &quot;JSCInlines.h&quot;
+#include &quot;ShadowChickenInlines.h&quot;
+#include &lt;wtf/ListDump.h&gt;
+
+namespace JSC {
+
+static const bool verbose = false;
+
+void ShadowChicken::Packet::dump(PrintStream&amp; out) const
+{
+    if (!*this) {
+        out.print(&quot;empty&quot;);
+        return;
+    }
+    
+    if (isPrologue()) {
+        out.print(
+            &quot;{callee = &quot;, RawPointer(callee), &quot;, frame = &quot;, RawPointer(frame), &quot;, callerFrame = &quot;,
+            RawPointer(callerFrame), &quot;}&quot;);
+        return;
+    }
+    
+    if (isTail()) {
+        out.print(&quot;tail:{frame = &quot;, RawPointer(frame), &quot;}&quot;);
+        return;
+    }
+    
+    ASSERT(isThrow());
+    out.print(&quot;throw&quot;);
+}
+
+void ShadowChicken::Frame::dump(PrintStream&amp; out) const
+{
+    out.print(
+        &quot;{callee = &quot;, RawPointer(callee), &quot;, frame = &quot;, RawPointer(frame), &quot;, isTailDeleted = &quot;,
+        isTailDeleted, &quot;}&quot;);
+}
+
+ShadowChicken::ShadowChicken()
+    : m_logSize(Options::shadowChickenLogSize())
+{
+    m_log = static_cast&lt;Packet*&gt;(fastZeroedMalloc(sizeof(Packet) * m_logSize));
+    m_logCursor = m_log;
+    m_logEnd = m_log + m_logSize;
+}
+
+ShadowChicken::~ShadowChicken()
+{
+    fastFree(m_log);
+}
+
+void ShadowChicken::log(VM&amp; vm, ExecState* exec, const Packet&amp; packet)
+{
+    update(vm, exec);
+    *m_logCursor++ = packet;
+}
+
+void ShadowChicken::update(VM&amp;, ExecState* exec)
+{
+    if (verbose) {
+        dataLog(&quot;Running update on: &quot;, *this, &quot;\n&quot;);
+        WTFReportBacktrace();
+    }
+    
+    const unsigned logCursorIndex = m_logCursor - m_log;
+    
+    // We need to figure out how to reconcile the current machine stack with our shadow stack. We do
+    // that by figuring out how much of the shadow stack to pop. We apply three different rules. The
+    // precise rule relies on the log. The log contains caller frames, which means that we know
+    // where we bottomed out after making any call. If we bottomed out but made no calls then 'exec'
+    // will tell us. That's why &quot;highestPointSinceLastTime&quot; will go no lower than exec. The third
+    // rule, based on comparing to the current real stack, is executed in a later loop.
+    CallFrame* highestPointSinceLastTime = exec;
+    for (unsigned i = logCursorIndex; i--;) {
+        Packet packet = m_log[i];
+        if (packet.isPrologue()) {
+            CallFrame* watermark;
+            if (i &amp;&amp; m_log[i - 1].isTail())
+                watermark = packet.frame;
+            else
+                watermark = packet.callerFrame;
+            highestPointSinceLastTime = std::max(highestPointSinceLastTime, watermark);
+        }
+    }
+    
+    if (verbose)
+        dataLog(&quot;    Highest point since last time: &quot;, RawPointer(highestPointSinceLastTime), &quot;\n&quot;);
+    
+    while (!m_stack.isEmpty() &amp;&amp; m_stack.last().frame &lt; highestPointSinceLastTime)
+        m_stack.removeLast();
+    
+    if (verbose)
+        dataLog(&quot;    Revised stack: &quot;, listDump(m_stack), &quot;\n&quot;);
+    
+    // It's possible that the top of stack is now tail-deleted. The stack no longer contains any
+    // frames below the log's high watermark. That means that we just need to look for the first
+    // occurence of a tail packet for the current stack top.
+    if (!m_stack.isEmpty()) {
+        ASSERT(!m_stack.last().isTailDeleted);
+        for (unsigned i = 0; i &lt; logCursorIndex; ++i) {
+            Packet&amp; packet = m_log[i];
+            if (packet.isTail() &amp;&amp; packet.frame == m_stack.last().frame) {
+                m_stack.last().isTailDeleted = true;
+                break;
+            }
+        }
+    }
+    
+    if (verbose)
+        dataLog(&quot;    Revised stack: &quot;, listDump(m_stack), &quot;\n&quot;);
+    
+    // The log-based and exec-based rules require that ShadowChicken was enabled. The point of
+    // ShadowChicken is to give sensible-looking results even if we had not logged. This means that
+    // we need to reconcile the shadow stack and the real stack by actually looking at the real
+    // stack. This reconciliation allows the shadow stack to have extra tail-deleted frames, but it
+    // forbids it from diverging from the real stack on normal frames.
+    if (!m_stack.isEmpty()) {
+        Vector&lt;Frame&gt; stackRightNow;
+        StackVisitor::visit(
+            exec, [&amp;] (StackVisitor&amp; visitor) -&gt; StackVisitor::Status {
+                if (visitor-&gt;isInlinedFrame())
+                    return StackVisitor::Continue;
+                bool isTailDeleted = false;
+                stackRightNow.append(Frame(visitor-&gt;callee(), visitor-&gt;callFrame(), isTailDeleted));
+                return StackVisitor::Continue;
+            });
+        stackRightNow.reverse();
+        
+        if (verbose)
+            dataLog(&quot;    Stack right now: &quot;, listDump(stackRightNow), &quot;\n&quot;);
+        
+        unsigned shadowIndex = 0;
+        unsigned rightNowIndex = 0;
+        while (shadowIndex &lt; m_stack.size() &amp;&amp; rightNowIndex &lt; stackRightNow.size()) {
+            if (m_stack[shadowIndex].isTailDeleted) {
+                shadowIndex++;
+                continue;
+            }
+            if (m_stack[shadowIndex] == stackRightNow[rightNowIndex]) {
+                shadowIndex++;
+                rightNowIndex++;
+                continue;
+            }
+            break;
+        }
+        m_stack.resize(shadowIndex);
+        
+        if (verbose)
+            dataLog(&quot;    Revised stack: &quot;, listDump(m_stack), &quot;\n&quot;);
+    }
+    
+    // It's possible that the top stack frame is actually lower than highestPointSinceLastTime.
+    // Account for that here.
+    highestPointSinceLastTime = nullptr;
+    for (unsigned i = m_stack.size(); i--;) {
+        if (!m_stack[i].isTailDeleted) {
+            highestPointSinceLastTime = m_stack[i].frame;
+            break;
+        }
+    }
+    
+    if (verbose)
+        dataLog(&quot;    Highest point since last time: &quot;, RawPointer(highestPointSinceLastTime), &quot;\n&quot;);
+    
+    // Set everything up so that we know where the top frame is in the log.
+    unsigned indexInLog = logCursorIndex;
+    
+    auto advanceIndexInLogTo =
+        [&amp;] (CallFrame* frame, JSObject* callee, CallFrame* callerFrame) -&gt; bool {
+        if (verbose)
+            dataLog(&quot;    Advancing to frame = &quot;, RawPointer(frame), &quot; from indexInLog = &quot;, indexInLog, &quot;\n&quot;);
+        if (indexInLog &gt; logCursorIndex) {
+            if (verbose)
+                dataLog(&quot;    Bailing.\n&quot;);
+            return false;
+        }
+        
+        unsigned oldIndexInLog = indexInLog;
+        
+        while (indexInLog--) {
+            Packet packet = m_log[indexInLog];
+            
+            // If all callees opt into ShadowChicken, then this search will rapidly terminate when
+            // we find our frame. But if our frame's callee didn't emit a prologue packet because it
+            // didn't opt in, then we will keep looking backwards until we *might* find a different
+            // frame. If we've been given the callee and callerFrame as a filter, then it's unlikely
+            // that we will hit the wrong frame. But we don't always have that information.
+            //
+            // This means it's worth adding other filters. For example, we could track changes in
+            // stack size. Once we've seen a frame at some height, we're no longer interested in
+            // frames below that height. Also, we can break as soon as we see a frame higher than
+            // the one we're looking for.
+            // FIXME: Add more filters.
+            // https://bugs.webkit.org/show_bug.cgi?id=155685
+            
+            if (packet.isPrologue() &amp;&amp; packet.frame == frame
+                &amp;&amp; (!callee || packet.callee == callee)
+                &amp;&amp; (!callerFrame || packet.callerFrame == callerFrame)) {
+                if (verbose)
+                    dataLog(&quot;    Found at indexInLog = &quot;, indexInLog, &quot;\n&quot;);
+                return true;
+            }
+        }
+        
+        // This is an interesting eventuality. We will see this if ShadowChicken was not
+        // consistently enabled. We have a choice between:
+        //
+        // - Leaving the log index at -1, which will prevent the log from being considered. This is
+        //   the most conservative. It means that we will not be able to recover tail-deleted frames
+        //   from anything that sits above a frame that didn't log a prologue packet. This means
+        //   that everyone who creates prologues must log prologue packets.
+        //
+        // - Restoring the log index to what it was before. This prevents us from considering
+        //   whether this frame has tail-deleted frames behind it, but that's about it. The problem
+        //   with this approach is that it might recover tail-deleted frames that aren't relevant.
+        //   I haven't thought about this too deeply, though.
+        //
+        // It seems like the latter option is less harmful, so that's what we do.
+        indexInLog = oldIndexInLog;
+        
+        if (verbose)
+            dataLog(&quot;    Didn't find it.\n&quot;);
+        return false;
+    };
+    
+    Vector&lt;Frame&gt; toPush;
+    StackVisitor::visit(
+        exec, [&amp;] (StackVisitor&amp; visitor) -&gt; StackVisitor::Status {
+            if (visitor-&gt;isInlinedFrame()) {
+                // FIXME: Handle inlining.
+                // https://bugs.webkit.org/show_bug.cgi?id=155686
+                return StackVisitor::Continue;
+            }
+            CallFrame* callFrame = visitor-&gt;callFrame();
+            if (verbose)
+                dataLog(&quot;    Examining &quot;, RawPointer(callFrame), &quot;\n&quot;);
+            if (!toPush.isEmpty() &amp;&amp; indexInLog &lt; logCursorIndex
+                // This condition protects us from the case where advanceIndexInLogTo didn't find
+                // anything.
+                &amp;&amp; m_log[indexInLog].frame == toPush.last().frame) {
+                if (verbose)
+                    dataLog(&quot;    Going to loop through things with indexInLog = &quot;, indexInLog, &quot; and push-stack top = &quot;, toPush.last(), &quot;\n&quot;);
+                for (;;) {
+                    ASSERT(m_log[indexInLog].frame == toPush.last().frame);
+                    
+                    // Right now the index is pointing at a prologue packet of the last frame that
+                    // we pushed. Peek behind that packet to see if there is a tail packet. If there
+                    // is one then we know that there is a corresponding prologue packet that will
+                    // tell us about a tail-deleted frame.
+                    
+                    if (!indexInLog)
+                        break;
+                    Packet lastPacket = m_log[indexInLog - 1];
+                    if (!lastPacket.isTail()) {
+                        // Last frame that we recorded was not the outcome of a tail call. So, there
+                        // will not be any more deleted frames.
+                        // FIXME: We might want to have a filter here. Consider that this was a tail
+                        // marker for a tail call to something that didn't log anything. It should
+                        // be sufficient to give the tail marker a copy of the caller frame.
+                        // https://bugs.webkit.org/show_bug.cgi?id=155687
+                        break;
+                    }
+                    indexInLog--; // Skip over the tail packet.
+                    
+                    if (!advanceIndexInLogTo(lastPacket.frame, nullptr, nullptr)) {
+                        // We were unable to locate the prologue packet for this tail packet. That's
+                        // quite suspect, so give up.
+                        break;
+                    }
+                    Packet packet = m_log[indexInLog];
+                    bool isTailDeleted = true;
+                    toPush.append(Frame(packet.callee, packet.frame, isTailDeleted));
+                }
+            }
+            if (callFrame == highestPointSinceLastTime) {
+                if (verbose)
+                    dataLog(&quot;    Bailing at &quot;, RawPointer(callFrame), &quot; because it's the highest point since last time.\n&quot;);
+                return StackVisitor::Done;
+            }
+            advanceIndexInLogTo(callFrame, callFrame-&gt;callee(), callFrame-&gt;callerFrame());
+            bool isTailDeleted = false;
+            toPush.append(Frame(visitor-&gt;callee(), callFrame, isTailDeleted));
+            return StackVisitor::Continue;
+        });
+    
+    if (verbose)
+        dataLog(&quot;    Pushing: &quot;, listDump(toPush), &quot;\n&quot;);
+    
+    for (unsigned i = toPush.size(); i--;)
+        m_stack.append(toPush[i]);
+    
+    // We want to reset the log. There is a fun corner-case: there could be a tail marker at the end
+    // of this log. We could make that work by setting isTailDeleted on the top of stack, but that
+    // would require more corner cases in the complicated reconciliation code above. That code
+    // already knows how to handle a tail packet at the beginning, so we just leverage that here.
+    if (logCursorIndex &amp;&amp; m_log[logCursorIndex - 1].isTail()) {
+        m_log[0] = m_log[logCursorIndex - 1];
+        m_logCursor = m_log + 1;
+    } else
+        m_logCursor = m_log;
+
+    if (verbose)
+        dataLog(&quot;    After pushing: &quot;, *this, &quot;\n&quot;);
+    
+    // Remove tail frames until the stack is small enough again.
+    const unsigned stackSizeLimit = Options::shadowChickenStackSizeLimit();
+    if (m_stack.size() &gt; stackSizeLimit) {
+        unsigned dstIndex = 0;
+        unsigned srcIndex = 0;
+        unsigned size = m_stack.size();
+        while (srcIndex &lt; m_stack.size()) {
+            Frame frame = m_stack[srcIndex++];
+            if (size &gt; stackSizeLimit &amp;&amp; frame.isTailDeleted) {
+                size--;
+                continue;
+            }
+            m_stack[dstIndex++] = frame;
+        }
+        RELEASE_ASSERT(dstIndex == size);
+        m_stack.resize(size);
+    }
+
+    if (verbose)
+        dataLog(&quot;    After clean-up: &quot;, *this, &quot;\n&quot;);
+}
+
+void ShadowChicken::visitChildren(SlotVisitor&amp; visitor)
+{
+    for (unsigned i = m_logCursor - m_log; i--;)
+        visitor.appendUnbarrieredReadOnlyPointer(m_log[i].callee);
+    
+    for (Frame&amp; frame : m_stack)
+        visitor.appendUnbarrieredReadOnlyPointer(frame.callee);
+}
+
+void ShadowChicken::reset()
+{
+    m_logCursor = m_log;
+    m_stack.clear();
+}
+
+void ShadowChicken::dump(PrintStream&amp; out) const
+{
+    out.print(&quot;{stack = [&quot;, listDump(m_stack), &quot;], log = [&quot;);
+    
+    CommaPrinter comma;
+    unsigned limit = static_cast&lt;unsigned&gt;(m_logCursor - m_log);
+    for (unsigned i = 0; i &lt; limit; ++i)
+        out.print(comma, m_log[i]);
+    out.print(&quot;]}&quot;);
+}
+
+JSArray* ShadowChicken::functionsOnStack(ExecState* exec)
+{
+    JSArray* result = constructEmptyArray(exec, 0);
+
+    iterate(
+        exec-&gt;vm(), exec,
+        [&amp;] (const Frame&amp; frame) -&gt; bool {
+            result-&gt;push(exec, frame.callee);
+            return true;
+        });
+    
+    return result;
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterShadowChickenh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/interpreter/ShadowChicken.h (0 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/ShadowChicken.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/interpreter/ShadowChicken.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -0,0 +1,202 @@
</span><ins>+/*
+ * Copyright (C) 2016 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' 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 INC. OR
+ * 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. 
+ */
+
+#pragma once
+
+#include &lt;wtf/FastMalloc.h&gt;
+#include &lt;wtf/Noncopyable.h&gt;
+#include &lt;wtf/PrintStream.h&gt;
+#include &lt;wtf/StdLibExtras.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace JSC {
+
+class ExecState;
+class JSArray;
+class JSObject;
+class LLIntOffsetsExtractor;
+class SlotVisitor;
+class VM;
+
+typedef ExecState CallFrame;
+
+// ShadowChicken is a log that can be used to produce a shadow stack of CHICKEN-style stack frames.
+// This enables the debugger to almost always see the tail-deleted stack frames, so long as we have
+// memory inside ShadowChicken to remember them.
+//
+// The ShadowChicken log comprises packets that have one of two shapes:
+//
+// Prologue Packet, which has:
+//     - Callee object.
+//     - Frame pointer.
+//     - Caller frame pointer.
+//
+// Tail Call Packet, which has just:
+//     - Frame pointer.
+//
+// Prologue Packets are placed into the log in any JS function's prologue. Tail Call Packets are
+// placed into the log just before making a proper tail call. We never log returns, since that would
+// require a lot of infrastructure (unwinding, multiple ways of returning, etc). We don't need to
+// see the returns because the prologue packets have a frame pointer. The tail call packets tell us
+// when there was a tail call, and record the FP *before* the tail call.
+//
+// At any time it is possible to construct a shadow stack from the log and the actual machine stack.
+
+class ShadowChicken {
+    WTF_MAKE_NONCOPYABLE(ShadowChicken);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    struct Packet {
+        Packet()
+        {
+        }
+        
+        static const unsigned unlikelyValue = 0x7a11;
+        
+        static JSObject* tailMarker()
+        {
+            return bitwise_cast&lt;JSObject*&gt;(static_cast&lt;intptr_t&gt;(unlikelyValue));
+        }
+        
+        static JSObject* throwMarker()
+        {
+            return bitwise_cast&lt;JSObject*&gt;(static_cast&lt;intptr_t&gt;(unlikelyValue + 1));
+        }
+        
+        static Packet prologue(JSObject* callee, CallFrame* frame, CallFrame* callerFrame)
+        {
+            Packet result;
+            result.callee = callee;
+            result.frame = frame;
+            result.callerFrame = callerFrame;
+            return result;
+        }
+        
+        // FIXME: Tail packets should hold currentScope so that the inspector can look at local
+        // variables in tail-deleted frames.
+        // https://bugs.webkit.org/show_bug.cgi?id=155722
+        static Packet tail(CallFrame* frame)
+        {
+            Packet result;
+            result.callee = tailMarker();
+            result.frame = frame;
+            return result;
+        }
+        
+        static Packet throwPacket()
+        {
+            Packet result;
+            result.callee = throwMarker();
+            return result;
+        }
+        
+        explicit operator bool() const { return !!callee; }
+        
+        bool isPrologue() const { return *this &amp;&amp; callee != tailMarker() &amp;&amp; callee != throwMarker(); }
+        bool isTail() const { return *this &amp;&amp; callee == tailMarker(); }
+        bool isThrow() const { return *this &amp;&amp; callee == throwMarker(); }
+        
+        void dump(PrintStream&amp;) const;
+        
+        JSObject* callee { nullptr };
+        CallFrame* frame { nullptr };
+        CallFrame* callerFrame { nullptr };
+    };
+    
+    struct Frame {
+        Frame()
+        {
+        }
+        
+        Frame(JSObject* callee, CallFrame* frame, bool isTailDeleted)
+            : callee(callee)
+            , frame(frame)
+            , isTailDeleted(isTailDeleted)
+        {
+        }
+        
+        bool operator==(const Frame&amp; other) const
+        {
+            return callee == other.callee
+                &amp;&amp; frame == other.frame
+                &amp;&amp; isTailDeleted == other.isTailDeleted;
+        }
+        
+        bool operator!=(const Frame&amp; other) const
+        {
+            return !(*this == other);
+        }
+        
+        void dump(PrintStream&amp;) const;
+        
+        // FIXME: This should be able to hold the moral equivalent of StackVisitor::Frame, so that
+        // we can support inlining.
+        // https://bugs.webkit.org/show_bug.cgi?id=155686
+        JSObject* callee { nullptr };
+        CallFrame* frame { nullptr };
+        bool isTailDeleted { false };
+    };
+    
+    ShadowChicken();
+    ~ShadowChicken();
+    
+    void log(VM&amp; vm, ExecState* exec, const Packet&amp;);
+    
+    void update(VM&amp;, ExecState*);
+    
+    // Expects this signature: (const Frame&amp; frame) -&gt; bool.
+    // Note that this only works right with inlining disabled, but that's OK since for now we
+    // disable inlining when the inspector is attached. It would be easy to make this work with
+    // inlining, and would mostly require that we can request that StackVisitor doesn't skip tail
+    // frames.
+    template&lt;typename Functor&gt;
+    void iterate(VM&amp;, ExecState*, const Functor&amp;);
+    
+    void visitChildren(SlotVisitor&amp;);
+    void reset();
+    
+    // JIT support.
+    Packet* log() const { return m_log; }
+    unsigned logSize() const { return m_logSize; }
+    Packet** addressOfLogCursor() { return &amp;m_logCursor; }
+    Packet* logEnd() { return m_logEnd; }
+    
+    void dump(PrintStream&amp;) const;
+    
+    JS_EXPORT_PRIVATE JSArray* functionsOnStack(ExecState*);
+
+private:
+    friend class LLIntOffsetsExtractor;
+    
+    Packet* m_log { nullptr };
+    unsigned m_logSize { 0 };
+    Packet* m_logCursor { nullptr };
+    Packet* m_logEnd { nullptr };
+    
+    Vector&lt;Frame&gt; m_stack;
+};
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterShadowChickenInlinesh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/interpreter/ShadowChickenInlines.h (0 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/ShadowChickenInlines.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/interpreter/ShadowChickenInlines.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -0,0 +1,47 @@
</span><ins>+/*
+ * Copyright (C) 2016 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' 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 INC. OR
+ * 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. 
+ */
+
+#pragma once
+
+#include &quot;JSCInlines.h&quot;
+#include &quot;ShadowChicken.h&quot;
+
+namespace JSC {
+
+template&lt;typename Functor&gt;
+void ShadowChicken::iterate(VM&amp; vm, ExecState* exec, const Functor&amp; functor)
+{
+    DeferGC deferGC(exec-&gt;vm().heap);
+
+    update(vm, exec);
+    
+    for (unsigned i = m_stack.size(); i--;) {
+        if (!functor(m_stack[i]))
+            break;
+    }
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreinterpreterStackVisitorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/interpreter/StackVisitor.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/interpreter/StackVisitor.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/interpreter/StackVisitor.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -63,14 +63,16 @@
</span><span class="cx">         JSObject* callee() const { return m_callee; }
</span><span class="cx">         CodeBlock* codeBlock() const { return m_codeBlock; }
</span><span class="cx">         unsigned bytecodeOffset() const { return m_bytecodeOffset; }
</span><ins>+        InlineCallFrame* inlineCallFrame() const {
</ins><span class="cx"> #if ENABLE(DFG_JIT)
</span><del>-        InlineCallFrame* inlineCallFrame() const { return m_inlineCallFrame; }
</del><ins>+            return m_inlineCallFrame;
+#else
+            return nullptr;
</ins><span class="cx"> #endif
</span><ins>+        }
</ins><span class="cx"> 
</span><span class="cx">         bool isJSFrame() const { return !!codeBlock(); }
</span><del>-#if ENABLE(DFG_JIT)
-        bool isInlinedFrame() const { return !!m_inlineCallFrame; }
-#endif
</del><ins>+        bool isInlinedFrame() const { return !!inlineCallFrame(); }
</ins><span class="cx"> 
</span><span class="cx">         JS_EXPORT_PRIVATE String functionName();
</span><span class="cx">         JS_EXPORT_PRIVATE String sourceURL();
</span><span class="lines">@@ -115,10 +117,10 @@
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     // StackVisitor::visit() expects a Functor that implements the following method:
</span><del>-    //     Status operator()(StackVisitor&amp;);
</del><ins>+    //     Status operator()(StackVisitor&amp;) const;
</ins><span class="cx"> 
</span><span class="cx">     template &lt;typename Functor&gt;
</span><del>-    static void visit(CallFrame* startFrame, Functor&amp; functor)
</del><ins>+    static void visit(CallFrame* startFrame, const Functor&amp; functor)
</ins><span class="cx">     {
</span><span class="cx">         StackVisitor visitor(startFrame);
</span><span class="cx">         while (visitor-&gt;callFrame()) {
</span><span class="lines">@@ -157,7 +159,7 @@
</span><span class="cx"> 
</span><span class="cx">     CallFrame* callerFrame() const { return m_callerFrame; }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (!m_hasSkippedFirstFrame) {
</span><span class="cx">             m_hasSkippedFirstFrame = true;
</span><span class="lines">@@ -169,8 +171,8 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx"> private:
</span><del>-    bool m_hasSkippedFirstFrame;
-    CallFrame* m_callerFrame;
</del><ins>+    mutable bool m_hasSkippedFirstFrame;
+    mutable CallFrame* m_callerFrame;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitCCallHelperscpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/jit/CCallHelpers.cpp (0 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/CCallHelpers.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/jit/CCallHelpers.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+/*
+ * Copyright (C) 2016 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' 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 INC. OR
+ * 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;ShadowChicken.h&quot;
+
+namespace JSC {
+
+void CCallHelpers::logShadowChickenProloguePacket()
+{
+    setupShadowChickenPacket();
+    storePtr(GPRInfo::callFrameRegister, Address(GPRInfo::regT1, OBJECT_OFFSETOF(ShadowChicken::Packet, frame)));
+    loadPtr(Address(GPRInfo::callFrameRegister, OBJECT_OFFSETOF(CallerFrameAndPC, callerFrame)), GPRInfo::regT0);
+    storePtr(GPRInfo::regT0, Address(GPRInfo::regT1, OBJECT_OFFSETOF(ShadowChicken::Packet, callerFrame)));
+    loadPtr(addressFor(JSStack::Callee), GPRInfo::regT0);
+    storePtr(GPRInfo::regT0, Address(GPRInfo::regT1, OBJECT_OFFSETOF(ShadowChicken::Packet, callee)));
+}
+
+void CCallHelpers::logShadowChickenTailPacket()
+{
+    setupShadowChickenPacket();
+    storePtr(GPRInfo::callFrameRegister, Address(GPRInfo::regT1, OBJECT_OFFSETOF(ShadowChicken::Packet, frame)));
+    storePtr(TrustedImmPtr(ShadowChicken::Packet::tailMarker()), Address(GPRInfo::regT1, OBJECT_OFFSETOF(ShadowChicken::Packet, callee)));
+}
+
+void CCallHelpers::setupShadowChickenPacket()
+{
+    move(TrustedImmPtr(vm()-&gt;shadowChicken().addressOfLogCursor()), GPRInfo::regT0);
+    loadPtr(GPRInfo::regT0, GPRInfo::regT1);
+    Jump ok = branchPtr(Below, GPRInfo::regT1, TrustedImmPtr(vm()-&gt;shadowChicken().logEnd()));
+    setupArgumentsExecState();
+    move(TrustedImmPtr(bitwise_cast&lt;void*&gt;(operationProcessShadowChickenLog)), GPRInfo::nonArgGPR0);
+    call(GPRInfo::nonArgGPR0);
+    move(TrustedImmPtr(vm()-&gt;shadowChicken().addressOfLogCursor()), GPRInfo::regT0);
+    loadPtr(GPRInfo::regT0, GPRInfo::regT1);
+    ok.link(this);
+    addPtr(TrustedImm32(sizeof(ShadowChicken::Packet)), GPRInfo::regT1, GPRInfo::regT2);
+    storePtr(GPRInfo::regT2, GPRInfo::regT0);
+}
+
+} // namespace JSC
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorejitCCallHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/CCallHelpers.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/CCallHelpers.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/CCallHelpers.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -2205,6 +2205,15 @@
</span><span class="cx">         // Ready for a jump!
</span><span class="cx">         move(newFramePointer, stackPointerRegister);
</span><span class="cx">     }
</span><ins>+    
+    // These operations clobber all volatile registers. They assume that there is room on the top of
+    // stack to marshall call arguments.
+    void logShadowChickenProloguePacket();
+    void logShadowChickenTailPacket();
+
+private:
+    // Leaves behind a pointer to the Packet we should write to in regT1.
+    void setupShadowChickenPacket();
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/JIT.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -326,6 +326,9 @@
</span><span class="cx">         DEFINE_OP(op_enumerator_structure_pname)
</span><span class="cx">         DEFINE_OP(op_enumerator_generic_pname)
</span><span class="cx">         DEFINE_OP(op_to_index_string)
</span><ins>+            
+        DEFINE_OP(op_log_shadow_chicken_prologue)
+        DEFINE_OP(op_log_shadow_chicken_tail)
</ins><span class="cx">         default:
</span><span class="cx">             RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JIT.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JIT.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/JIT.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -595,6 +595,8 @@
</span><span class="cx">         void emit_op_enumerator_structure_pname(Instruction*);
</span><span class="cx">         void emit_op_enumerator_generic_pname(Instruction*);
</span><span class="cx">         void emit_op_to_index_string(Instruction*);
</span><ins>+        void emit_op_log_shadow_chicken_prologue(Instruction*);
+        void emit_op_log_shadow_chicken_tail(Instruction*);
</ins><span class="cx"> 
</span><span class="cx">         void emitSlow_op_add(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span><span class="cx">         void emitSlow_op_bitand(Instruction*, Vector&lt;SlowCaseEntry&gt;::iterator&amp;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITExceptionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITExceptions.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITExceptions.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/JITExceptions.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -29,12 +29,13 @@
</span><span class="cx"> #include &quot;CallFrame.h&quot;
</span><span class="cx"> #include &quot;CodeBlock.h&quot;
</span><span class="cx"> #include &quot;Interpreter.h&quot;
</span><ins>+#include &quot;JSCInlines.h&quot;
</ins><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> #include &quot;LLIntData.h&quot;
</span><span class="cx"> #include &quot;LLIntOpcode.h&quot;
</span><span class="cx"> #include &quot;LLIntThunks.h&quot;
</span><span class="cx"> #include &quot;Opcode.h&quot;
</span><del>-#include &quot;JSCInlines.h&quot;
</del><ins>+#include &quot;ShadowChicken.h&quot;
</ins><span class="cx"> #include &quot;VM.h&quot;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="lines">@@ -50,6 +51,8 @@
</span><span class="cx">         CRASH();
</span><span class="cx">     }
</span><span class="cx">     
</span><ins>+    vm-&gt;shadowChicken().log(*vm, callFrame, ShadowChicken::Packet::throwPacket());
+    
</ins><span class="cx">     Exception* exception = vm-&gt;exception();
</span><span class="cx">     RELEASE_ASSERT(exception);
</span><span class="cx">     HandlerInfo* handler = vm-&gt;interpreter-&gt;unwind(*vm, callFrame, exception, unwindStart); // This may update callFrame.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITInlines.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITInlines.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/JITInlines.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -143,6 +143,10 @@
</span><span class="cx">     uint32_t locationBits = CallSiteIndex(m_bytecodeOffset + 1).bits();
</span><span class="cx"> #endif
</span><span class="cx">     store32(TrustedImm32(locationBits), intTagFor(JSStack::ArgumentCount));
</span><ins>+    
+    // FIXME: It's not clear that this is needed. JITOperations tend to update the top call frame on
+    // the C++ side.
+    // https://bugs.webkit.org/show_bug.cgi?id=155693
</ins><span class="cx">     storePtr(callFrameRegister, &amp;m_vm-&gt;topCallFrame);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1450,6 +1450,18 @@
</span><span class="cx">     slowPathCall.call();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT::emit_op_log_shadow_chicken_prologue(Instruction*)
+{
+    updateTopCallFrame();
+    logShadowChickenProloguePacket();
+}
+
+void JIT::emit_op_log_shadow_chicken_tail(Instruction*)
+{
+    updateTopCallFrame();
+    logShadowChickenTailPacket();
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(JIT)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOpcodes32_64cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -49,6 +49,9 @@
</span><span class="cx"> 
</span><span class="cx"> JIT::CodeRef JIT::privateCompileCTINativeCall(VM* vm, NativeFunction func)
</span><span class="cx"> {
</span><ins>+    // FIXME: This should be able to log ShadowChicken prologue packets.
+    // https://bugs.webkit.org/show_bug.cgi?id=155689
+    
</ins><span class="cx">     Call nativeCall;
</span><span class="cx"> 
</span><span class="cx">     emitFunctionPrologue();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -57,6 +57,7 @@
</span><span class="cx"> #include &quot;PropertyName.h&quot;
</span><span class="cx"> #include &quot;Repatch.h&quot;
</span><span class="cx"> #include &quot;ScopedArguments.h&quot;
</span><ins>+#include &quot;ShadowChicken.h&quot;
</ins><span class="cx"> #include &quot;SuperSampler.h&quot;
</span><span class="cx"> #include &quot;TestRunnerUtils.h&quot;
</span><span class="cx"> #include &quot;TypeProfilerLog.h&quot;
</span><span class="lines">@@ -2118,9 +2119,18 @@
</span><span class="cx"> 
</span><span class="cx"> void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec)
</span><span class="cx"> {
</span><del>-    exec-&gt;vm().typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;Log Full, called from inside baseline JIT&quot;));
</del><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    vm.typeProfilerLog()-&gt;processLogEntries(ASCIILiteral(&quot;Log Full, called from inside baseline JIT&quot;));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JIT_OPERATION operationProcessShadowChickenLog(ExecState* exec)
+{
+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    vm.shadowChicken().update(vm, exec);
+}
+
</ins><span class="cx"> int32_t JIT_OPERATION operationCheckIfExceptionIsUncatchableAndNotifyProfiler(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitJITOperationsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/JITOperations.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/JITOperations.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -394,6 +394,7 @@
</span><span class="cx"> JSCell* JIT_OPERATION operationToIndexString(ExecState*, int32_t);
</span><span class="cx"> 
</span><span class="cx"> void JIT_OPERATION operationProcessTypeProfilerLog(ExecState*) WTF_INTERNAL;
</span><ins>+void JIT_OPERATION operationProcessShadowChickenLog(ExecState*) WTF_INTERNAL;
</ins><span class="cx"> 
</span><span class="cx"> } // extern &quot;C&quot;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitThunkGeneratorscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -238,6 +238,9 @@
</span><span class="cx"> 
</span><span class="cx"> static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind kind, ThunkEntryType entryType = EnterViaCall)
</span><span class="cx"> {
</span><ins>+    // FIXME: This should be able to log ShadowChicken prologue packets.
+    // https://bugs.webkit.org/show_bug.cgi?id=155689
+    
</ins><span class="cx">     int executableOffsetToFunction = NativeExecutable::offsetOfNativeFunctionFor(kind);
</span><span class="cx">     
</span><span class="cx">     JSInterfaceJIT jit(vm);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><del>- *  Copyright (C) 2004-2008, 2012-2013, 2015 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2004-2008, 2012-2013, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx"> #include &quot;JSWASMModule.h&quot;
</span><span class="cx"> #include &quot;ProfilerDatabase.h&quot;
</span><span class="cx"> #include &quot;SamplingProfiler.h&quot;
</span><ins>+#include &quot;ShadowChicken.h&quot;
</ins><span class="cx"> #include &quot;StackVisitor.h&quot;
</span><span class="cx"> #include &quot;StructureInlines.h&quot;
</span><span class="cx"> #include &quot;StructureRareDataInlines.h&quot;
</span><span class="lines">@@ -629,6 +630,8 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState*);
+
</ins><span class="cx"> struct Script {
</span><span class="cx">     bool isFile;
</span><span class="cx">     char* argument;
</span><span class="lines">@@ -768,6 +771,7 @@
</span><span class="cx">         addFunction(vm, &quot;setSamplingFlags&quot;, functionSetSamplingFlags, 1);
</span><span class="cx">         addFunction(vm, &quot;clearSamplingFlags&quot;, functionClearSamplingFlags, 1);
</span><span class="cx"> #endif
</span><ins>+        addFunction(vm, &quot;shadowChickenFunctionsOnStack&quot;, functionShadowChickenFunctionsOnStack, 0);
</ins><span class="cx">         addConstructableFunction(vm, &quot;Root&quot;, functionCreateRoot, 0);
</span><span class="cx">         addConstructableFunction(vm, &quot;Element&quot;, functionCreateElement, 1);
</span><span class="cx">         addFunction(vm, &quot;getElement&quot;, functionGetElement, 1);
</span><span class="lines">@@ -1154,7 +1158,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         m_trace.append(String::format(&quot;    %zu   %s\n&quot;, visitor-&gt;index(), visitor-&gt;toString().utf8().data()));
</span><span class="cx">         return StackVisitor::Continue;
</span><span class="lines">@@ -1471,6 +1475,11 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState* exec)
+{
+    return JSValue::encode(exec-&gt;vm().shadowChicken().functionsOnStack(exec));
+}
+
</ins><span class="cx"> EncodedJSValue JSC_HOST_CALL functionReadline(ExecState* exec)
</span><span class="cx"> {
</span><span class="cx">     Vector&lt;char, 256&gt; line;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntOffsetsExtractorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> #include &quot;LLIntOfflineAsmConfig.h&quot;
</span><span class="cx"> #include &quot;MarkedSpace.h&quot;
</span><span class="cx"> #include &quot;ProtoCallFrame.h&quot;
</span><ins>+#include &quot;ShadowChicken.h&quot;
</ins><span class="cx"> #include &quot;Structure.h&quot;
</span><span class="cx"> #include &quot;StructureChain.h&quot;
</span><span class="cx"> #include &quot;TypeProfiler.h&quot;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -53,6 +53,7 @@
</span><span class="cx"> #include &quot;LowLevelInterpreter.h&quot;
</span><span class="cx"> #include &quot;ObjectConstructor.h&quot;
</span><span class="cx"> #include &quot;ProtoCallFrame.h&quot;
</span><ins>+#include &quot;ShadowChicken.h&quot;
</ins><span class="cx"> #include &quot;StructureRareDataInlines.h&quot;
</span><span class="cx"> #include &quot;VMInlines.h&quot;
</span><span class="cx"> #include &lt;wtf/StringPrintStream.h&gt;
</span><span class="lines">@@ -1514,6 +1515,25 @@
</span><span class="cx">     LLINT_RETURN_TWO(pc, 0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+LLINT_SLOW_PATH_DECL(slow_path_log_shadow_chicken_prologue)
+{
+    LLINT_BEGIN();
+    
+    vm.shadowChicken().log(
+        vm, exec, ShadowChicken::Packet::prologue(exec-&gt;callee(), exec, exec-&gt;callerFrame()));
+    
+    LLINT_END();
+}
+
+LLINT_SLOW_PATH_DECL(slow_path_log_shadow_chicken_tail)
+{
+    LLINT_BEGIN();
+    
+    vm.shadowChicken().log(vm, exec, ShadowChicken::Packet::tail(exec));
+    
+    LLINT_END();
+}
+
</ins><span class="cx"> extern &quot;C&quot; SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
</span><span class="cx"> {
</span><span class="cx">     ExecState* exec = vm-&gt;topCallFrame;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLLIntSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -123,6 +123,8 @@
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_get_from_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope);
</span><span class="cx"> LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_check_if_exception_is_uncatchable_and_notify_profiler);
</span><ins>+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_log_shadow_chicken_prologue);
+LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_log_shadow_chicken_tail);
</ins><span class="cx"> extern &quot;C&quot; SlowPathReturnType llint_throw_stack_overflow_error(VM*, ProtoCallFrame*) WTF_INTERNAL;
</span><span class="cx"> #if !ENABLE(JIT)
</span><span class="cx"> extern &quot;C&quot; SlowPathReturnType llint_stack_check_at_vm_entry(VM*, Register*) WTF_INTERNAL;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1456,6 +1456,42 @@
</span><span class="cx">     jmp _llint_throw_from_slow_path_trampoline
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+# Returns the packet pointer in t0.
+macro acquireShadowChickenPacket(slow)
+    loadp CodeBlock[cfr], t1
+    loadp CodeBlock::m_vm[t1], t1
+    loadp VM::m_shadowChicken[t1], t2
+    loadp ShadowChicken::m_logCursor[t2], t0
+    bpaeq t0, ShadowChicken::m_logEnd[t2], slow
+    addp sizeof ShadowChicken::Packet, t0, t1
+    storep t1, ShadowChicken::m_logCursor[t2]
+end
+
+_llint_op_log_shadow_chicken_prologue:
+    traceExecution()
+    acquireShadowChickenPacket(.opLogShadowChickenPrologueSlow)
+    storep cfr, ShadowChicken::Packet::frame[t0]
+    loadp CallerFrame[cfr], t1
+    storep t1, ShadowChicken::Packet::callerFrame[t0]
+    loadp Callee + PayloadOffset[cfr], t1
+    storep t1, ShadowChicken::Packet::callee[t0]
+    dispatch(1)
+.opLogShadowChickenPrologueSlow:
+    callSlowPath(_llint_slow_path_log_shadow_chicken_prologue)
+    dispatch(1)
+
+
+_llint_op_log_shadow_chicken_tail:
+    traceExecution()
+    acquireShadowChickenPacket(.opLogShadowChickenTailSlow)
+    storep cfr, ShadowChicken::Packet::frame[t0]
+    storep 0x7a11, ShadowChicken::Packet::callee[t0]
+    dispatch(1)
+.opLogShadowChickenTailSlow:
+    callSlowPath(_llint_slow_path_log_shadow_chicken_tail)
+    dispatch(1)
+
+
</ins><span class="cx"> _llint_op_switch_string:
</span><span class="cx">     traceExecution()
</span><span class="cx">     callSlowPath(_llint_slow_path_switch_string)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreprofilerProfileGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2008, 2014 Apple Inc. All Rights Reserved.
</del><ins>+ * Copyright (C) 2008, 2014, 2016 Apple Inc. All Rights Reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool foundParent() const { return m_foundParent; }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (!m_hasSkippedFirstFrame) {
</span><span class="cx">             m_hasSkippedFirstFrame = true;
</span><span class="lines">@@ -92,8 +92,8 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     ExecState* m_exec;
</span><del>-    bool m_hasSkippedFirstFrame;
-    bool m_foundParent;
</del><ins>+    mutable bool m_hasSkippedFirstFrame;
+    mutable bool m_foundParent;
</ins><span class="cx">     RefPtr&lt;ProfileNode&gt;&amp; m_rootNode;
</span><span class="cx">     RefPtr&lt;ProfileNode&gt;&amp; m_currentNode;
</span><span class="cx">     double m_startTime;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeErrorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Error.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Error.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/runtime/Error.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
</span><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="lines">@@ -113,7 +113,7 @@
</span><span class="cx">         , m_index(0)
</span><span class="cx">     { }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (!m_foundStartCallFrame &amp;&amp; (visitor-&gt;callFrame() == m_startCallFrame))
</span><span class="cx">             m_foundStartCallFrame = true;
</span><span class="lines">@@ -134,9 +134,9 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     CallFrame* m_startCallFrame;
</span><del>-    CallFrame* m_foundCallFrame;
-    bool m_foundStartCallFrame;
-    unsigned m_index;
</del><ins>+    mutable CallFrame* m_foundCallFrame;
+    mutable bool m_foundStartCallFrame;
+    mutable unsigned m_index;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> bool addErrorInfoAndGetBytecodeOffset(ExecState* exec, VM&amp; vm, JSObject* obj, bool useCurrentFrame, CallFrame*&amp; callFrame, unsigned &amp;bytecodeOffset) 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSFunctioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSFunction.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSFunction.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/runtime/JSFunction.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -250,7 +250,7 @@
</span><span class="cx"> 
</span><span class="cx">     JSValue result() const { return m_result; }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         JSObject* callee = visitor-&gt;callee();
</span><span class="cx">         if (callee != m_targetCallee)
</span><span class="lines">@@ -262,7 +262,7 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     JSObject* m_targetCallee;
</span><del>-    JSValue m_result;
</del><ins>+    mutable JSValue m_result;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static JSValue retrieveArguments(ExecState* exec, JSFunction* functionObj)
</span><span class="lines">@@ -292,7 +292,7 @@
</span><span class="cx"> 
</span><span class="cx">     JSValue result() const { return m_result; }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         JSObject* callee = visitor-&gt;callee();
</span><span class="cx"> 
</span><span class="lines">@@ -315,9 +315,9 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     JSObject* m_targetCallee;
</span><del>-    bool m_hasFoundFrame;
-    bool m_hasSkippedToCallerFrame;
-    JSValue m_result;
</del><ins>+    mutable bool m_hasFoundFrame;
+    mutable bool m_hasSkippedToCallerFrame;
+    mutable JSValue m_result;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static JSValue retrieveCallerFunction(ExecState* exec, JSFunction* functionObj)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectFunctionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
</span><span class="cx">  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
</span><del>- *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
</span><span class="cx">  *  Copyright (C) 2007 Maks Orlovich
</span><span class="cx">  *
</span><span class="lines">@@ -794,7 +794,7 @@
</span><span class="cx"> 
</span><span class="cx">     EncodedJSValue result() { return m_result; }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (!m_hasSkippedFirstFrame) {
</span><span class="cx">             m_hasSkippedFirstFrame = true;
</span><span class="lines">@@ -809,9 +809,9 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     ExecState* m_exec;
</span><del>-    bool m_hasSkippedFirstFrame;
</del><ins>+    mutable bool m_hasSkippedFirstFrame;
</ins><span class="cx">     JSObject* m_thisObject;
</span><del>-    EncodedJSValue m_result;
</del><ins>+    mutable EncodedJSValue m_result;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState* exec)
</span><span class="lines">@@ -847,7 +847,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool allowsAccess() const { return m_allowsAccess; }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (!m_hasSkippedFirstFrame) {
</span><span class="cx">             m_hasSkippedFirstFrame = true;
</span><span class="lines">@@ -859,8 +859,8 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    bool m_hasSkippedFirstFrame;
-    bool m_allowsAccess;
</del><ins>+    mutable bool m_hasSkippedFirstFrame;
+    mutable bool m_allowsAccess;
</ins><span class="cx">     JSObject* m_thisObject;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeNullSetterFunctioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/NullSetterFunction.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/NullSetterFunction.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/runtime/NullSetterFunction.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         ++m_iterations;
</span><span class="cx">         if (m_iterations &lt; 2)
</span><span class="lines">@@ -59,8 +59,8 @@
</span><span class="cx">     bool callerIsStrict() const { return m_callerIsStrict; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    int m_iterations;
-    bool m_callerIsStrict;
</del><ins>+    mutable int m_iterations;
+    mutable bool m_callerIsStrict;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static bool callerIsStrict(ExecState* exec)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeObjectConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,6 +1,6 @@
</span><span class="cx"> /*
</span><span class="cx">  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
</span><del>- *  Copyright (C) 2008 Apple Inc. All rights reserved.
</del><ins>+ *  Copyright (C) 2008, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  *  This library is free software; you can redistribute it and/or
</span><span class="cx">  *  modify it under the terms of the GNU Lesser General Public
</span><span class="lines">@@ -162,7 +162,7 @@
</span><span class="cx"> 
</span><span class="cx">     JSValue result() const { return m_result; }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (!m_hasSkippedFirstFrame) {
</span><span class="cx">             m_hasSkippedFirstFrame = true;
</span><span class="lines">@@ -176,9 +176,9 @@
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     ExecState* m_exec;
</span><del>-    bool m_hasSkippedFirstFrame;
</del><ins>+    mutable bool m_hasSkippedFirstFrame;
</ins><span class="cx">     JSObject* m_object;
</span><del>-    JSValue m_result;
</del><ins>+    mutable JSValue m_result;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> JSValue objectConstructorGetPrototypeOf(ExecState* exec, JSObject* object)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeOptionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Options.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Options.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/runtime/Options.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -134,6 +134,9 @@
</span><span class="cx">     \
</span><span class="cx">     v(bool, useFunctionDotArguments, true, nullptr) \
</span><span class="cx">     v(bool, useTailCalls, true, nullptr) \
</span><ins>+    v(bool, alwaysUseShadowChicken, false, nullptr) \
+    v(unsigned, shadowChickenLogSize, 1000, nullptr) \
+    v(unsigned, shadowChickenStackSizeLimit, 100000, nullptr) \
</ins><span class="cx">     \
</span><span class="cx">     /* dumpDisassembly implies dumpDFGDisassembly. */ \
</span><span class="cx">     v(bool, dumpDisassembly, false, &quot;dumps disassembly of all JIT compiled code upon compilation&quot;) \
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeStringPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -452,7 +452,7 @@
</span><span class="cx">     return jsString(exec, impl.release());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static ALWAYS_INLINE EncodedJSValue removeUsingRegExpSearch(ExecState* exec, JSString* string, const String&amp; source, RegExp* regExp)
</del><ins>+static ALWAYS_INLINE EncodedJSValue removeUsingRegExpSearch(VM&amp; vm, ExecState* exec, JSString* string, const String&amp; source, RegExp* regExp)
</ins><span class="cx"> {
</span><span class="cx">     SuperSamplerScope superSamplerScope(false);
</span><span class="cx">     
</span><span class="lines">@@ -460,12 +460,11 @@
</span><span class="cx">     unsigned startPosition = 0;
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;StringRange, 16&gt; sourceRanges;
</span><del>-    VM* vm = &amp;exec-&gt;vm();
</del><span class="cx">     RegExpConstructor* regExpConstructor = exec-&gt;lexicalGlobalObject()-&gt;regExpConstructor();
</span><span class="cx">     unsigned sourceLen = source.length();
</span><span class="cx"> 
</span><span class="cx">     while (true) {
</span><del>-        MatchResult result = regExpConstructor-&gt;performMatch(*vm, regExp, string, source, startPosition);
</del><ins>+        MatchResult result = regExpConstructor-&gt;performMatch(vm, regExp, string, source, startPosition);
</ins><span class="cx">         if (!result)
</span><span class="cx">             break;
</span><span class="cx"> 
</span><span class="lines">@@ -493,8 +492,8 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(
</span><del>-    ExecState* exec, JSString* string, JSValue searchValue, CallData&amp; callData, CallType callType,
-    String&amp; replacementString, JSValue replaceValue)
</del><ins>+    VM&amp; vm, ExecState* exec, JSString* string, JSValue searchValue, CallData&amp; callData,
+    CallType callType, String&amp; replacementString, JSValue replaceValue)
</ins><span class="cx"> {
</span><span class="cx">     const String&amp; source = string-&gt;value(exec);
</span><span class="cx">     unsigned sourceLen = source.length();
</span><span class="lines">@@ -511,7 +510,7 @@
</span><span class="cx">             return JSValue::encode(jsUndefined());
</span><span class="cx"> 
</span><span class="cx">         if (callType == CallType::None &amp;&amp; !replacementString.length())
</span><del>-            return removeUsingRegExpSearch(exec, string, source, regExp);
</del><ins>+            return removeUsingRegExpSearch(vm, exec, string, source, regExp);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // FIXME: This is wrong because we may be called directly from the FTL.
</span><span class="lines">@@ -532,11 +531,10 @@
</span><span class="cx">         CachedCall cachedCall(exec, func, argCount);
</span><span class="cx">         if (exec-&gt;hadException())
</span><span class="cx">             return JSValue::encode(jsUndefined());
</span><del>-        VM* vm = &amp;exec-&gt;vm();
</del><span class="cx">         if (source.is8Bit()) {
</span><span class="cx">             while (true) {
</span><span class="cx">                 int* ovector;
</span><del>-                MatchResult result = regExpConstructor-&gt;performMatch(*vm, regExp, string, source, startPosition, &amp;ovector);
</del><ins>+                MatchResult result = regExpConstructor-&gt;performMatch(vm, regExp, string, source, startPosition, &amp;ovector);
</ins><span class="cx">                 if (!result)
</span><span class="cx">                     break;
</span><span class="cx"> 
</span><span class="lines">@@ -550,7 +548,7 @@
</span><span class="cx">                     if (matchStart &lt; 0)
</span><span class="cx">                         cachedCall.setArgument(i, jsUndefined());
</span><span class="cx">                     else
</span><del>-                        cachedCall.setArgument(i, jsSubstring(vm, source, matchStart, matchLen));
</del><ins>+                        cachedCall.setArgument(i, jsSubstring(&amp;vm, source, matchStart, matchLen));
</ins><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 cachedCall.setArgument(i++, jsNumber(result.start));
</span><span class="lines">@@ -575,7 +573,7 @@
</span><span class="cx">         } else {
</span><span class="cx">             while (true) {
</span><span class="cx">                 int* ovector;
</span><del>-                MatchResult result = regExpConstructor-&gt;performMatch(*vm, regExp, string, source, startPosition, &amp;ovector);
</del><ins>+                MatchResult result = regExpConstructor-&gt;performMatch(vm, regExp, string, source, startPosition, &amp;ovector);
</ins><span class="cx">                 if (!result)
</span><span class="cx">                     break;
</span><span class="cx"> 
</span><span class="lines">@@ -589,7 +587,7 @@
</span><span class="cx">                     if (matchStart &lt; 0)
</span><span class="cx">                         cachedCall.setArgument(i, jsUndefined());
</span><span class="cx">                     else
</span><del>-                        cachedCall.setArgument(i, jsSubstring(vm, source, matchStart, matchLen));
</del><ins>+                        cachedCall.setArgument(i, jsSubstring(&amp;vm, source, matchStart, matchLen));
</ins><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 cachedCall.setArgument(i++, jsNumber(result.start));
</span><span class="lines">@@ -613,10 +611,9 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     } else {
</span><del>-        VM* vm = &amp;exec-&gt;vm();
</del><span class="cx">         do {
</span><span class="cx">             int* ovector;
</span><del>-            MatchResult result = regExpConstructor-&gt;performMatch(*vm, regExp, string, source, startPosition, &amp;ovector);
</del><ins>+            MatchResult result = regExpConstructor-&gt;performMatch(vm, regExp, string, source, startPosition, &amp;ovector);
</ins><span class="cx">             if (!result)
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -677,31 +674,37 @@
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
</span><span class="cx">     ExecState* exec, JSString* thisValue, RegExpObject* searchValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    
</ins><span class="cx">     RegExp* regExp = searchValue-&gt;regExp();
</span><span class="cx">     if (regExp-&gt;global()) {
</span><span class="cx">         // ES5.1 15.5.4.10 step 8.a.
</span><span class="cx">         searchValue-&gt;setLastIndex(exec, 0);
</span><span class="cx">         if (exec-&gt;hadException())
</span><span class="cx">             return JSValue::encode(jsUndefined());
</span><del>-        return removeUsingRegExpSearch(exec, thisValue, thisValue-&gt;value(exec), regExp);
</del><ins>+        return removeUsingRegExpSearch(vm, exec, thisValue, thisValue-&gt;value(exec), regExp);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     CallData callData;
</span><span class="cx">     String replacementString = emptyString();
</span><span class="cx">     return replaceUsingRegExpSearch(
</span><del>-        exec, thisValue, searchValue, callData, CallType::None, replacementString, JSValue());
</del><ins>+        vm, exec, thisValue, searchValue, callData, CallType::None, replacementString, JSValue());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
</span><span class="cx">     ExecState* exec, JSString* thisValue, RegExpObject* searchValue, JSString* replaceString)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    
</ins><span class="cx">     CallData callData;
</span><span class="cx">     String replacementString = replaceString-&gt;value(exec);
</span><span class="cx">     return replaceUsingRegExpSearch(
</span><del>-        exec, thisValue, searchValue, callData, CallType::None, replacementString, replaceString);
</del><ins>+        vm, exec, thisValue, searchValue, callData, CallType::None, replacementString, replaceString);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
</del><ins>+static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(VM&amp; vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
</ins><span class="cx"> {
</span><span class="cx">     String replacementString;
</span><span class="cx">     CallData callData;
</span><span class="lines">@@ -713,10 +716,10 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return replaceUsingRegExpSearch(
</span><del>-        exec, string, searchValue, callData, callType, replacementString, replaceValue);
</del><ins>+        vm, exec, string, searchValue, callData, callType, replacementString, replaceValue);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static ALWAYS_INLINE EncodedJSValue replaceUsingStringSearch(ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
</del><ins>+static ALWAYS_INLINE EncodedJSValue replaceUsingStringSearch(VM&amp;, ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
</ins><span class="cx"> {
</span><span class="cx">     const String&amp; string = jsString-&gt;value(exec);
</span><span class="cx">     String searchString = searchValue.toString(exec)-&gt;value(exec);
</span><span class="lines">@@ -910,35 +913,38 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE EncodedJSValue replace(
</span><del>-    ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
</del><ins>+    VM&amp; vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
</ins><span class="cx"> {
</span><span class="cx">     if (searchValue.inherits(RegExpObject::info()))
</span><del>-        return replaceUsingRegExpSearch(exec, string, searchValue, replaceValue);
-    return replaceUsingStringSearch(exec, string, searchValue, replaceValue);
</del><ins>+        return replaceUsingRegExpSearch(vm, exec, string, searchValue, replaceValue);
+    return replaceUsingStringSearch(vm, exec, string, searchValue, replaceValue);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ALWAYS_INLINE EncodedJSValue replace(
</span><del>-    ExecState* exec, JSValue thisValue, JSValue searchValue, JSValue replaceValue)
</del><ins>+    VM&amp; vm, ExecState* exec, JSValue thisValue, JSValue searchValue, JSValue replaceValue)
</ins><span class="cx"> {
</span><span class="cx">     if (!checkObjectCoercible(thisValue))
</span><span class="cx">         return throwVMTypeError(exec);
</span><span class="cx">     JSString* string = thisValue.toString(exec);
</span><span class="cx">     if (exec-&gt;hadException())
</span><span class="cx">         return JSValue::encode(jsUndefined());
</span><del>-    return replace(exec, string, searchValue, replaceValue);
</del><ins>+    return replace(vm, exec, string, searchValue, replaceValue);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
</span><span class="cx"> {
</span><del>-    return replace(exec, exec-&gt;thisValue(), exec-&gt;argument(0), exec-&gt;argument(1));
</del><ins>+    return replace(exec-&gt;vm(), exec, exec-&gt;thisValue(), exec-&gt;argument(0), exec-&gt;argument(1));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceGeneric(
</span><span class="cx">     ExecState* exec, EncodedJSValue thisValue, EncodedJSValue searchValue,
</span><span class="cx">     EncodedJSValue replaceValue)
</span><span class="cx"> {
</span><ins>+    VM&amp; vm = exec-&gt;vm();
+    NativeCallFrameTracer tracer(&amp;vm, exec);
+    
</ins><span class="cx">     return replace(
</span><del>-        exec, JSValue::decode(thisValue), JSValue::decode(searchValue),
</del><ins>+        vm, exec, JSValue::decode(thisValue), JSValue::decode(searchValue),
</ins><span class="cx">         JSValue::decode(replaceValue));
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/runtime/VM.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -82,6 +82,7 @@
</span><span class="cx"> #include &quot;RegisterAtOffsetList.h&quot;
</span><span class="cx"> #include &quot;RuntimeType.h&quot;
</span><span class="cx"> #include &quot;SamplingProfiler.h&quot;
</span><ins>+#include &quot;ShadowChicken.h&quot;
</ins><span class="cx"> #include &quot;SimpleTypedArrayController.h&quot;
</span><span class="cx"> #include &quot;SourceProviderCache.h&quot;
</span><span class="cx"> #include &quot;StackVisitor.h&quot;
</span><span class="lines">@@ -197,6 +198,7 @@
</span><span class="cx">     , m_builtinExecutables(std::make_unique&lt;BuiltinExecutables&gt;(*this))
</span><span class="cx">     , m_typeProfilerEnabledCount(0)
</span><span class="cx">     , m_controlFlowProfilerEnabledCount(0)
</span><ins>+    , m_shadowChicken(std::make_unique&lt;ShadowChicken&gt;())
</ins><span class="cx"> {
</span><span class="cx">     interpreter = new Interpreter(*this);
</span><span class="cx">     StackBounds stack = wtfThreadData().stack();
</span><span class="lines">@@ -767,7 +769,7 @@
</span><span class="cx"> 
</span><span class="cx"> class SetEnabledProfilerFunctor {
</span><span class="cx"> public:
</span><del>-    bool operator()(CodeBlock* codeBlock)
</del><ins>+    bool operator()(CodeBlock* codeBlock) const
</ins><span class="cx">     {
</span><span class="cx">         if (JITCode::isOptimizingJIT(codeBlock-&gt;jitType()))
</span><span class="cx">             codeBlock-&gt;jettison(Profiler::JettisonDueToLegacyProfiler);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -102,6 +102,7 @@
</span><span class="cx"> #if ENABLE(SAMPLING_PROFILER)
</span><span class="cx"> class SamplingProfiler;
</span><span class="cx"> #endif
</span><ins>+class ShadowChicken;
</ins><span class="cx"> class ScriptExecutable;
</span><span class="cx"> class SourceProvider;
</span><span class="cx"> class SourceProviderCache;
</span><span class="lines">@@ -607,6 +608,8 @@
</span><span class="cx">     bool shouldBuilderPCToCodeOriginMapping() const { return m_shouldBuildPCToCodeOriginMapping; }
</span><span class="cx"> 
</span><span class="cx">     BytecodeIntrinsicRegistry&amp; bytecodeIntrinsicRegistry() { return *m_bytecodeIntrinsicRegistry; }
</span><ins>+    
+    ShadowChicken&amp; shadowChicken() { return *m_shadowChicken; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     friend class LLIntOffsetsExtractor;
</span><span class="lines">@@ -676,6 +679,7 @@
</span><span class="cx"> #if ENABLE(SAMPLING_PROFILER)
</span><span class="cx">     RefPtr&lt;SamplingProfiler&gt; m_samplingProfiler;
</span><span class="cx"> #endif
</span><ins>+    std::unique_ptr&lt;ShadowChicken&gt; m_shadowChicken;
</ins><span class="cx">     std::unique_ptr&lt;BytecodeIntrinsicRegistry&gt; m_bytecodeIntrinsicRegistry;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressresourcesshadowchickensupportjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/resources/shadow-chicken-support.js (0 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/resources/shadow-chicken-support.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/resources/shadow-chicken-support.js        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+&quot;use strict&quot;;
+
+function describeFunction(f)
+{
+    var name;
+    try {
+        name = f.name;
+    } catch (e) {}
+    if (!name)
+        name = &quot;&lt;&quot; + describe(f) + &quot;&gt;&quot;;
+    return name;
+}
+
+function describeArray(array) {
+    var result = &quot;[&quot;;
+    for (var i = 0; i &lt; array.length; ++i) {
+        if (i)
+            result += &quot;, &quot;;
+        result += describeFunction(array[i]);
+    }
+    return result + &quot;]&quot;;
+}
+
+function compareStacks(stack, array) {
+    if (stack.length != array.length)
+        throw new Error(&quot;Bad stack length: &quot; + describeArray(stack) + &quot; (expected &quot; + describeArray(array) + &quot;)&quot;);
+    for (var i = 0; i &lt; stack.length; ++i) {
+        if (stack[i] != array[i])
+            throw new Error(&quot;Bad stack at i = &quot; + i + &quot;: &quot; + describeArray(stack) + &quot; (expected &quot; + describeArray(array) + &quot;)&quot;);
+    }
+}
+
+function expectStack(array) {
+    var stack = shadowChickenFunctionsOnStack();
+    if (verbose)
+        print(&quot;stack = &quot; + describeArray(stack));
+    var myTop = stack.pop();
+    if (myTop != stackTop)
+        throw new Error(&quot;Bad stack top: &quot; + myTop);
+    var myBottom = stack.shift();
+    if (myBottom != shadowChickenFunctionsOnStack)
+        throw new Error(&quot;Bad stack bottom: &quot; + myBottom);
+    myBottom = stack.shift();
+    if (myBottom != expectStack)
+        throw new Error(&quot;Bad stack next-to-bottom: &quot; + myBottom);
+    compareStacks(stack, array);
+}
+
+var initialShadow;
+var stackTop;
+
+function initialize()
+{
+    initialShadow = shadowChickenFunctionsOnStack();
+    if (initialShadow.length != 3)
+        throw new Error(&quot;bad initial shadow length: &quot; + initialShadow.length);
+    if (initialShadow[0] != shadowChickenFunctionsOnStack)
+        throw new Error(&quot;bad top of stack: &quot; + describeFunction(initialShadow[0]));
+    if (initialShadow[1] != initialize)
+        throw new Error(&quot;bad middle of stack: &quot; + describeFunction(initialShadow[1]));
+    stackTop = initialShadow[2];
+    
+    expectStack([initialize]);
+}
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressshadowchickendisabledjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/shadow-chicken-disabled.js (0 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/shadow-chicken-disabled.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/shadow-chicken-disabled.js        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -0,0 +1,56 @@
</span><ins>+//@ runDefault; runNoLLInt; runFTLNoCJITValidate
+
+&quot;use strict&quot;;
+
+var verbose = false;
+load(&quot;resources/shadow-chicken-support.js&quot;);
+initialize();
+
+(function test1() {
+    function foo() {
+        expectStack([foo, test1]);
+    }
+    
+    function bar() {
+        return foo();
+    }
+
+    function baz() {
+        return bar();
+    }
+    
+    baz();
+})();
+
+(function test2() {
+    function foo() {
+    }
+    
+    function bar() {
+        return foo();
+    }
+
+    function baz() {
+        return bar();
+    }
+    
+    baz();
+})();
+
+(function test3() {
+    function foo() {
+        expectStack([foo, test3]);
+    }
+    
+    function bar() {
+        return foo();
+    }
+
+    function baz() {
+        return bar();
+    }
+    
+    baz();
+})();
+
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstressshadowchickenenabledjs"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/tests/stress/shadow-chicken-enabled.js (0 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/shadow-chicken-enabled.js                                (rev 0)
+++ trunk/Source/JavaScriptCore/tests/stress/shadow-chicken-enabled.js        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -0,0 +1,208 @@
</span><ins>+//@ runShadowChicken
+
+&quot;use strict&quot;;
+
+var verbose = false;
+
+load(&quot;resources/shadow-chicken-support.js&quot;);
+initialize();
+
+(function test1() {
+    function foo() {
+        expectStack([foo, bar, baz, test1]);
+    }
+    
+    function bar() {
+        return foo();
+    }
+
+    function baz() {
+        return bar();
+    }
+    
+    baz();
+})();
+
+(function test2() {
+    function foo() {
+    }
+    
+    function bar() {
+        return foo();
+    }
+
+    function baz() {
+        return bar();
+    }
+    
+    baz();
+})();
+
+(function test3() {
+    if (verbose) {
+        print(&quot;test3:&quot;);
+        print(&quot;bob = &quot; + describe(bob));
+        print(&quot;thingy = &quot; + describe(thingy));
+        print(&quot;foo = &quot; + describe(foo));
+        print(&quot;bar = &quot; + describe(bar));
+        print(&quot;baz = &quot; + describe(baz));
+    }
+    
+    function bob() {
+        if (verbose)
+            print(&quot;Doing bob...&quot;);
+        expectStack([bob, thingy, foo, bar, baz, test3]);
+    }
+    
+    function thingy() {
+        return bob();
+    }
+    
+    function foo() {
+        if (verbose)
+            print(&quot;Doing foo...&quot;);
+        expectStack([foo, bar, baz, test3]);
+        return thingy();
+    }
+    
+    function bar() {
+        return foo();
+    }
+
+    function baz() {
+        return bar();
+    }
+    
+    baz();
+})();
+
+(function test4() {
+    if (verbose) {
+        print(&quot;test4:&quot;);
+        print(&quot;bob = &quot; + describe(bob));
+        print(&quot;thingy = &quot; + describe(thingy));
+        print(&quot;foo = &quot; + describe(foo));
+        print(&quot;bar = &quot; + describe(bar));
+        print(&quot;baz = &quot; + describe(baz));
+    }
+    
+    function bob(thingyIsTail) {
+        if (verbose)
+            print(&quot;Doing bob...&quot;);
+        expectStack([bob, thingy, foo, bar, baz, test4]);
+    }
+    
+    function thingy(isTail) {
+        bob(false);
+        return bob(isTail);
+    }
+    
+    function foo() {
+        if (verbose)
+            print(&quot;Doing foo...&quot;);
+        expectStack([foo, bar, baz, test4]);
+        thingy(false);
+        return thingy(true);
+    }
+    
+    function bar() {
+        foo();
+        return foo();
+    }
+
+    function baz() {
+        bar();
+        return bar();
+    }
+    
+    baz();
+})();
+
+(function test5a() {
+    if (verbose)
+        print(&quot;In test5a:&quot;);
+    var foos = 990;
+    
+    function foo(ttl) {
+        if (ttl &lt;= 1) {
+            var array = [];
+            for (var i = 0; i &lt; foos; ++i)
+                array.push(foo);
+            array.push(test5a);
+            expectStack(array);
+            return;
+        }
+        return foo(ttl - 1);
+    }
+    
+    foo(foos);
+})();
+
+(function test5b() {
+    if (verbose)
+        print(&quot;In test5b:&quot;);
+    var foos = 9990;
+    
+    function foo(ttl) {
+        if (ttl &lt;= 1) {
+            var array = [];
+            for (var i = 0; i &lt; foos; ++i)
+                array.push(foo);
+            array.push(test5b);
+            expectStack(array);
+            return;
+        }
+        return foo(ttl - 1);
+    }
+    
+    foo(foos);
+})();
+
+(function test6() {
+    if (verbose) {
+        print(&quot;In test6&quot;);
+        print(&quot;foo = &quot; + describe(foo));
+        print(&quot;array.push = &quot; + describe([].push));
+    }
+    
+    var foos = 99990;
+    
+    function foo(ttl) {
+        if (ttl &lt;= 1) {
+            var array = [];
+            for (var i = 0; i &lt; foos; ++i)
+                array.push(foo);
+            array.push(test6);
+            expectStack(array);
+            return;
+        }
+        return foo(ttl - 1);
+    }
+    
+    foo(foos);
+    
+    if (verbose)
+        print(&quot;Done with test6.&quot;);
+})();
+
+(function test7() {
+    var foos = 200000;
+    
+    function foo(ttl) {
+        if (ttl &lt;= 1) {
+            var stack = shadowChickenFunctionsOnStack();
+            var expectedStack = [];
+            expectedStack.push(shadowChickenFunctionsOnStack);
+            while (expectedStack.length &lt; stack.length - 2)
+                expectedStack.push(foo);
+            expectedStack.push(test7);
+            expectedStack.push(stackTop);
+            compareStacks(stack, expectedStack);
+            return;
+        }
+        return foo(ttl - 1);
+    }
+    
+    foo(foos);
+})();
+
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoretoolsJSDollarVMPrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (m_currentFrame++ &gt; 1) {
</span><span class="cx">             m_jitType = visitor-&gt;codeBlock()-&gt;jitType();
</span><span class="lines">@@ -89,8 +89,8 @@
</span><span class="cx">     JITCode::JITType jitType() { return m_jitType; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    unsigned m_currentFrame;
-    JITCode::JITType m_jitType;
</del><ins>+    mutable unsigned m_currentFrame;
+    mutable JITCode::JITType m_jitType;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionLLintTrue(ExecState* exec)
</span><span class="lines">@@ -160,7 +160,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    IterationStatus operator()(JSCell* cell)
</del><ins>+    IterationStatus operator()(JSCell* cell) const
</ins><span class="cx">     {
</span><span class="cx">         if (cell == candidate) {
</span><span class="cx">             found = true;
</span><span class="lines">@@ -170,7 +170,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     JSCell* candidate;
</span><del>-    bool found { false };
</del><ins>+    mutable bool found { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> bool JSDollarVMPrototype::isValidCell(Heap* heap, JSCell* candidate)
</span><span class="lines">@@ -192,7 +192,7 @@
</span><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        bool operator()(CodeBlock* codeBlock)
</del><ins>+        bool operator()(CodeBlock* codeBlock) const
</ins><span class="cx">         {
</span><span class="cx">             if (codeBlock == candidate)
</span><span class="cx">                 found = true;
</span><span class="lines">@@ -200,7 +200,7 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         CodeBlock* candidate;
</span><del>-        bool found { false };
</del><ins>+        mutable bool found { false };
</ins><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="lines">@@ -224,7 +224,7 @@
</span><span class="cx">         {
</span><span class="cx">         }
</span><span class="cx">         
</span><del>-        StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+        StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">         {
</span><span class="cx">             currentFrame++;
</span><span class="cx">             if (currentFrame == targetFrame) {
</span><span class="lines">@@ -235,8 +235,8 @@
</span><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         unsigned targetFrame;
</span><del>-        unsigned currentFrame { 0 };
-        CodeBlock* codeBlock { nullptr };
</del><ins>+        mutable unsigned currentFrame { 0 };
+        mutable CodeBlock* codeBlock { nullptr };
</ins><span class="cx">     };
</span><span class="cx">     
</span><span class="cx">     FetchCodeBlockFunctor functor(frameNumber);
</span><span class="lines">@@ -322,7 +322,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         m_currentFrame++;
</span><span class="cx">         if (m_currentFrame &gt; m_framesToSkip)
</span><span class="lines">@@ -336,7 +336,7 @@
</span><span class="cx"> private:
</span><span class="cx">     Action m_action;
</span><span class="cx">     unsigned m_framesToSkip;
</span><del>-    unsigned m_currentFrame { 0 };
</del><ins>+    mutable unsigned m_currentFrame { 0 };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> static void printCallFrame(CallFrame* callFrame, unsigned framesToSkip)
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/WebCore/ChangeLog        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1,3 +1,26 @@
</span><ins>+2016-03-19  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        JSC should use a shadow stack version of CHICKEN so that debuggers have the option of retrieving tail-deleted frames
+        https://bugs.webkit.org/show_bug.cgi?id=155598
+
+        Reviewed by Saam Barati.
+
+        Fixed some uses of the stack walking functor to obey the new lambda-friendly API, which
+        requires that operator() is const.
+
+        No new tests because no change in behavior.
+
+        * bindings/js/JSXMLHttpRequestCustom.cpp:
+        (WebCore::SendFunctor::column):
+        (WebCore::SendFunctor::url):
+        (WebCore::SendFunctor::operator()):
+        (WebCore::JSXMLHttpRequest::send):
+        * testing/Internals.cpp:
+        (WebCore::GetCallerCodeBlockFunctor::GetCallerCodeBlockFunctor):
+        (WebCore::GetCallerCodeBlockFunctor::operator()):
+        (WebCore::GetCallerCodeBlockFunctor::codeBlock):
+        (WebCore::Internals::parserMetaData):
+
</ins><span class="cx"> 2016-04-05  Brady Eidson  &lt;beidson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Modern IDB: Replace use of SerializedScriptValue with IDBValue.
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsJSXMLHttpRequestCustomcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -113,7 +113,7 @@
</span><span class="cx">     unsigned column() const { return m_column; }
</span><span class="cx">     String url() const { return m_url; }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         if (!m_hasSkippedFirstFrame) {
</span><span class="cx">             m_hasSkippedFirstFrame = true;
</span><span class="lines">@@ -130,10 +130,10 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    bool m_hasSkippedFirstFrame;
-    unsigned m_line;
-    unsigned m_column;
-    String m_url;
</del><ins>+    mutable bool m_hasSkippedFirstFrame;
+    mutable unsigned m_line;
+    mutable unsigned m_column;
+    mutable String m_url;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> JSValue JSXMLHttpRequest::send(ExecState&amp; state)
</span><span class="lines">@@ -158,6 +158,9 @@
</span><span class="cx">     } else
</span><span class="cx">         wrapped().send(val.toString(&amp;state)-&gt;value(&amp;state), ec);
</span><span class="cx"> 
</span><ins>+    // FIXME: This should probably use ShadowChicken so that we get the right frame even when it did
+    // a tail call.
+    // https://bugs.webkit.org/show_bug.cgi?id=155688
</ins><span class="cx">     SendFunctor functor;
</span><span class="cx">     state.iterate(functor);
</span><span class="cx">     wrapped().setLastSendLineAndColumnNumber(functor.line(), functor.column());
</span></span></pre></div>
<a id="trunkSourceWebCoretestingInternalscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/testing/Internals.cpp (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/testing/Internals.cpp        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Source/WebCore/testing/Internals.cpp        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -1661,7 +1661,7 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    StackVisitor::Status operator()(StackVisitor&amp; visitor)
</del><ins>+    StackVisitor::Status operator()(StackVisitor&amp; visitor) const
</ins><span class="cx">     {
</span><span class="cx">         ++m_iterations;
</span><span class="cx">         if (m_iterations &lt; 2)
</span><span class="lines">@@ -1674,8 +1674,8 @@
</span><span class="cx">     CodeBlock* codeBlock() const { return m_codeBlock; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    int m_iterations;
-    CodeBlock* m_codeBlock;
</del><ins>+    mutable int m_iterations;
+    mutable CodeBlock* m_codeBlock;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> String Internals::parserMetaData(Deprecated::ScriptValue value)
</span></span></pre></div>
<a id="trunkToolsScriptsrunjavascriptcoretests"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-javascriptcore-tests (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-javascriptcore-tests        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Tools/Scripts/run-javascriptcore-tests        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -223,6 +223,7 @@
</span><span class="cx">             &quot;Source/JavaScriptCore/tests/executableAllocationFuzz.yaml&quot;,
</span><span class="cx">             &quot;Source/JavaScriptCore/tests/exceptionFuzz.yaml&quot;,
</span><span class="cx">             &quot;PerformanceTests/SunSpider/no-architecture-specific-optimizations.yaml&quot;,
</span><ins>+            &quot;PerformanceTests/SunSpider/shadow-chicken.yaml&quot;,
</ins><span class="cx">             &quot;PerformanceTests/SunSpider/tests/v8-v6&quot;,
</span><span class="cx">             &quot;Source/JavaScriptCore/tests/mozilla/mozilla-tests.yaml&quot;,
</span><span class="cx">             &quot;Source/JavaScriptCore/tests/stress&quot;,
</span></span></pre></div>
<a id="trunkToolsScriptsrunjscstresstests"></a>
<div class="modfile"><h4>Modified: trunk/Tools/Scripts/run-jsc-stress-tests (199075 => 199076)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/Scripts/run-jsc-stress-tests        2016-04-05 22:13:16 UTC (rev 199075)
+++ trunk/Tools/Scripts/run-jsc-stress-tests        2016-04-05 22:17:35 UTC (rev 199076)
</span><span class="lines">@@ -878,6 +878,10 @@
</span><span class="cx">     run(&quot;dfg-maximal-flush-validate-no-cjit&quot;, &quot;--validateGraph=true&quot;, &quot;--useMaximalFlushInsertionPhase=true&quot;, *NO_CJIT_OPTIONS)
</span><span class="cx"> end
</span><span class="cx"> 
</span><ins>+def runShadowChicken
+    run(&quot;shadow-chicken&quot;, &quot;--useDFGJIT=false&quot;, &quot;--alwaysUseShadowChicken=true&quot;)
+end
+
</ins><span class="cx"> def defaultRun
</span><span class="cx">     if $quickMode
</span><span class="cx">         defaultQuickRun
</span></span></pre>
</div>
</div>

</body>
</html>