Changeset 199076 in webkit


Ignore:
Timestamp:
Apr 5, 2016, 3:17:35 PM (9 years ago)
Author:
fpizlo@apple.com
Message:

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 "delete" 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<AbstractStateType>::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):

Location:
trunk
Files:
8 added
64 edited

Legend:

Unmodified
Added
Removed
  • trunk/PerformanceTests/SunSpider/ChangeLog

    r182170 r199076  
     12016-03-21 Filip Pizlo <fpizlo@apple.com>
     2
     3        JSC should use a shadow stack version of CHICKEN so that debuggers have the option of retrieving tail-deleted frames
     4        https://bugs.webkit.org/show_bug.cgi?id=155598
     5
     6        Reviewed by Saam Barati.
     7
     8        * shadow-chicken.yaml: Added.
     9
    1102015-03-30  Michael Saboff  <msaboff@apple.com>
    211
  • trunk/Source/JavaScriptCore/API/JSContextRef.cpp

    r193649 r199076  
    11/*
    2  * Copyright (C) 2006, 2007, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2006, 2007, 2013, 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    256256    }
    257257
    258     StackVisitor::Status operator()(StackVisitor& visitor)
     258    StackVisitor::Status operator()(StackVisitor& visitor) const
    259259    {
    260260        if (m_remainingCapacityForFrameCapture) {
     
    293293private:
    294294    StringBuilder& m_builder;
    295     unsigned m_remainingCapacityForFrameCapture;
     295    mutable unsigned m_remainingCapacityForFrameCapture;
    296296};
    297297
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r198832 r199076  
    508508    interpreter/JSStack.cpp
    509509    interpreter/ProtoCallFrame.cpp
     510    interpreter/ShadowChicken.cpp
    510511    interpreter/StackVisitor.cpp
    511512
    512513    jit/AssemblyHelpers.cpp
    513514    jit/BinarySwitch.cpp
     515    jit/CCallHelpers.cpp
    514516    jit/CachedRecovery.cpp
    515517    jit/CallFrameShuffleData.cpp
  • trunk/Source/JavaScriptCore/ChangeLog

    r199075 r199076  
     12016-03-18  Filip Pizlo  <fpizlo@apple.com>
     2
     3        JSC should use a shadow stack version of CHICKEN so that debuggers have the option of retrieving tail-deleted frames
     4        https://bugs.webkit.org/show_bug.cgi?id=155598
     5
     6        Reviewed by Saam Barati.
     7       
     8        JSC is the first JSVM to have proper tail calls. This means that error.stack and the
     9        debugger will appear to "delete" strict mode stack frames, if the call that this frame made
     10        was in tail position. This is exactly what functional programmers expect - they don't want
     11        the VM to waste resources on tail-deleted frames to ensure that it's legal to loop forever
     12        using tail calls. It's also something that non-functional programmers fear. It's not clear
     13        that tail-deleted frames would actually degrade the debugging experience, but the fear is
     14        real, so it's worthwhile to do something about it.
     15
     16        It turns out that there is at least one tail call implementation that doesn't suffer from
     17        this problem. It implements proper tail calls in the sense that you won't run out of memory
     18        by tail-looping. It also has the power to show you tail-deleted frames in a backtrace, so
     19        long as you haven't yet run out of memory. It's called CHICKEN Scheme, and it's one of my
     20        favorite hacks:
     21       
     22        http://www.more-magic.net/posts/internals-gc.html
     23
     24        CHICKEN does many awesome things. The intuition from CHICKEN that we use here is a simple
     25        one: what if a tail call still kept the tail-deleted frame, and the GC actually deleted that
     26        frame only once we proved that there was insufficient memory to keep it around.
     27       
     28        CHICKEN does this by reshaping the C stack with longjmp/setjmp. We can't do that because we
     29        can have arbitrary native code, and that native code does not have relocatable stack frames.
     30       
     31        But we can do something almost like CHICKEN on a shadow stack. It's a common trick to have a
     32        VM maintain two stacks - the actual execution stack plus a shadow stack that has some extra
     33        information. The shadow stack can be reshaped, moved, etc, since the VM tightly controls its
     34        layout. The main stack can then continue to obey ABI rules.
     35
     36        This patch implements a mechanism for being able to display stack traces that include
     37        tail-deleted frames. It uses a shadow stack that behaves like a CHICKEN stack: it has all
     38        frames all the time, though we will collect the tail-deleted ones if the stack gets too big.
     39        This new mechanism is called ShadowChicken, obviously: it's CHICKEN on a shadow stack.
     40       
     41        ShadowChicken is always on, but individual CodeBlocks may make their own choices about
     42        whether to opt into it. They will do that at bytecompile time based on the debugger mode on
     43        their global object.
     44
     45        When no CodeBlock opts in, there is no overhead, since ShadowChicken ends up doing nothing
     46        in that case. Well, except when exceptions are thrown. Then it might do some work, but it's
     47        minor.
     48
     49        When all CodeBlocks opt in, there is about 6% overhead. That's too much overhead to enable
     50        this all the time, but it's low enough to justify enabling in the Inspector. It's currently
     51        enabled on all CodeBlocks only when you use an Option. Otherwise it will auto-enable if the
     52        debugger is on.
     53
     54        Note that ShadowChicken attempts to gracefully handle the presence of stack frames that have
     55        no logging. This is essential since we *can* have debugging enabled in one GlobalObject and
     56        disabled in another. Also, some frames don't do ShadowChicken because they just haven't been
     57        hacked to do it yet. Native frames fall into this category, as do the VM entry frames.
     58
     59        This doesn't yet wire ShadowChicken into DebuggerCallFrame. That will take more work. It
     60        just makes a ShadowChicken stack walk function available to jsc. It's used from the
     61        shadow-chicken tests.
     62
     63        * API/JSContextRef.cpp:
     64        (BacktraceFunctor::BacktraceFunctor):
     65        (BacktraceFunctor::operator()):
     66        (JSContextCreateBacktrace):
     67        * CMakeLists.txt:
     68        * JavaScriptCore.xcodeproj/project.pbxproj:
     69        * bytecode/BytecodeList.json:
     70        * bytecode/BytecodeUseDef.h:
     71        (JSC::computeUsesForBytecodeOffset):
     72        (JSC::computeDefsForBytecodeOffset):
     73        * bytecode/CodeBlock.cpp:
     74        (JSC::CodeBlock::dumpBytecode):
     75        (JSC::RecursionCheckFunctor::RecursionCheckFunctor):
     76        (JSC::RecursionCheckFunctor::operator()):
     77        (JSC::CodeBlock::noticeIncomingCall):
     78        * bytecompiler/BytecodeGenerator.cpp:
     79        (JSC::BytecodeGenerator::emitEnter):
     80        (JSC::BytecodeGenerator::emitCallInTailPosition):
     81        (JSC::BytecodeGenerator::emitCallVarargsInTailPosition):
     82        (JSC::BytecodeGenerator::emitCallVarargs):
     83        (JSC::BytecodeGenerator::emitLogShadowChickenPrologueIfNecessary):
     84        (JSC::BytecodeGenerator::emitLogShadowChickenTailIfNecessary):
     85        (JSC::BytecodeGenerator::emitCallDefineProperty):
     86        * bytecompiler/BytecodeGenerator.h:
     87        * debugger/DebuggerCallFrame.cpp:
     88        (JSC::LineAndColumnFunctor::operator()):
     89        (JSC::LineAndColumnFunctor::column):
     90        (JSC::FindCallerMidStackFunctor::FindCallerMidStackFunctor):
     91        (JSC::FindCallerMidStackFunctor::operator()):
     92        (JSC::DebuggerCallFrame::DebuggerCallFrame):
     93        * dfg/DFGAbstractInterpreterInlines.h:
     94        (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
     95        * dfg/DFGByteCodeParser.cpp:
     96        (JSC::DFG::ByteCodeParser::parseBlock):
     97        * dfg/DFGClobberize.h:
     98        (JSC::DFG::clobberize):
     99        * dfg/DFGDoesGC.cpp:
     100        (JSC::DFG::doesGC):
     101        * dfg/DFGFixupPhase.cpp:
     102        (JSC::DFG::FixupPhase::fixupNode):
     103        * dfg/DFGNodeType.h:
     104        * dfg/DFGPredictionPropagationPhase.cpp:
     105        (JSC::DFG::PredictionPropagationPhase::propagate):
     106        * dfg/DFGSafeToExecute.h:
     107        (JSC::DFG::safeToExecute):
     108        * dfg/DFGSpeculativeJIT32_64.cpp:
     109        (JSC::DFG::SpeculativeJIT::compile):
     110        * dfg/DFGSpeculativeJIT64.cpp:
     111        (JSC::DFG::SpeculativeJIT::compile):
     112        * ftl/FTLAbstractHeapRepository.cpp:
     113        * ftl/FTLAbstractHeapRepository.h:
     114        * ftl/FTLCapabilities.cpp:
     115        (JSC::FTL::canCompile):
     116        * ftl/FTLLowerDFGToB3.cpp:
     117        (JSC::FTL::DFG::LowerDFGToB3::compileNode):
     118        (JSC::FTL::DFG::LowerDFGToB3::compileSetRegExpObjectLastIndex):
     119        (JSC::FTL::DFG::LowerDFGToB3::compileLogShadowChickenPrologue):
     120        (JSC::FTL::DFG::LowerDFGToB3::compileLogShadowChickenTail):
     121        (JSC::FTL::DFG::LowerDFGToB3::didOverflowStack):
     122        (JSC::FTL::DFG::LowerDFGToB3::allocateJSArray):
     123        (JSC::FTL::DFG::LowerDFGToB3::setupShadowChickenPacket):
     124        (JSC::FTL::DFG::LowerDFGToB3::boolify):
     125        * heap/Heap.cpp:
     126        (JSC::Heap::markRoots):
     127        (JSC::Heap::visitSamplingProfiler):
     128        (JSC::Heap::visitShadowChicken):
     129        (JSC::Heap::traceCodeBlocksAndJITStubRoutines):
     130        (JSC::Heap::collectImpl):
     131        * heap/Heap.h:
     132        * inspector/ScriptCallStackFactory.cpp:
     133        (Inspector::CreateScriptCallStackFunctor::CreateScriptCallStackFunctor):
     134        (Inspector::CreateScriptCallStackFunctor::operator()):
     135        (Inspector::createScriptCallStack):
     136        * interpreter/CallFrame.h:
     137        (JSC::ExecState::iterate):
     138        * interpreter/Interpreter.cpp:
     139        (JSC::DumpRegisterFunctor::DumpRegisterFunctor):
     140        (JSC::DumpRegisterFunctor::operator()):
     141        (JSC::GetStackTraceFunctor::GetStackTraceFunctor):
     142        (JSC::GetStackTraceFunctor::operator()):
     143        (JSC::Interpreter::getStackTrace):
     144        (JSC::GetCatchHandlerFunctor::handler):
     145        (JSC::GetCatchHandlerFunctor::operator()):
     146        (JSC::notifyDebuggerOfUnwinding):
     147        (JSC::UnwindFunctor::UnwindFunctor):
     148        (JSC::UnwindFunctor::operator()):
     149        (JSC::UnwindFunctor::copyCalleeSavesToVMCalleeSavesBuffer):
     150        * interpreter/ShadowChicken.cpp: Added.
     151        (JSC::ShadowChicken::Packet::dump):
     152        (JSC::ShadowChicken::Frame::dump):
     153        (JSC::ShadowChicken::ShadowChicken):
     154        (JSC::ShadowChicken::~ShadowChicken):
     155        (JSC::ShadowChicken::log):
     156        (JSC::ShadowChicken::update):
     157        (JSC::ShadowChicken::visitChildren):
     158        (JSC::ShadowChicken::reset):
     159        (JSC::ShadowChicken::dump):
     160        (JSC::ShadowChicken::functionsOnStack):
     161        * interpreter/ShadowChicken.h: Added.
     162        (JSC::ShadowChicken::Packet::Packet):
     163        (JSC::ShadowChicken::Packet::tailMarker):
     164        (JSC::ShadowChicken::Packet::throwMarker):
     165        (JSC::ShadowChicken::Packet::prologue):
     166        (JSC::ShadowChicken::Packet::tail):
     167        (JSC::ShadowChicken::Packet::throwPacket):
     168        (JSC::ShadowChicken::Packet::operator bool):
     169        (JSC::ShadowChicken::Packet::isPrologue):
     170        (JSC::ShadowChicken::Packet::isTail):
     171        (JSC::ShadowChicken::Packet::isThrow):
     172        (JSC::ShadowChicken::Frame::Frame):
     173        (JSC::ShadowChicken::Frame::operator==):
     174        (JSC::ShadowChicken::Frame::operator!=):
     175        (JSC::ShadowChicken::log):
     176        (JSC::ShadowChicken::logSize):
     177        (JSC::ShadowChicken::addressOfLogCursor):
     178        (JSC::ShadowChicken::logEnd):
     179        * interpreter/ShadowChickenInlines.h: Added.
     180        (JSC::ShadowChicken::iterate):
     181        * interpreter/StackVisitor.h:
     182        (JSC::StackVisitor::Frame::callee):
     183        (JSC::StackVisitor::Frame::codeBlock):
     184        (JSC::StackVisitor::Frame::bytecodeOffset):
     185        (JSC::StackVisitor::Frame::inlineCallFrame):
     186        (JSC::StackVisitor::Frame::isJSFrame):
     187        (JSC::StackVisitor::Frame::isInlinedFrame):
     188        (JSC::StackVisitor::visit):
     189        * jit/CCallHelpers.cpp: Added.
     190        (JSC::CCallHelpers::logShadowChickenProloguePacket):
     191        (JSC::CCallHelpers::logShadowChickenTailPacket):
     192        (JSC::CCallHelpers::setupShadowChickenPacket):
     193        * jit/CCallHelpers.h:
     194        (JSC::CCallHelpers::prepareForTailCallSlow):
     195        * jit/JIT.cpp:
     196        (JSC::JIT::privateCompileMainPass):
     197        * jit/JIT.h:
     198        * jit/JITExceptions.cpp:
     199        (JSC::genericUnwind):
     200        * jit/JITOpcodes.cpp:
     201        (JSC::JIT::emit_op_resume):
     202        (JSC::JIT::emit_op_log_shadow_chicken_prologue):
     203        (JSC::JIT::emit_op_log_shadow_chicken_tail):
     204        * jit/JITOperations.cpp:
     205        * jit/JITOperations.h:
     206        * jsc.cpp:
     207        (GlobalObject::finishCreation):
     208        (FunctionJSCStackFunctor::FunctionJSCStackFunctor):
     209        (FunctionJSCStackFunctor::operator()):
     210        (functionClearSamplingFlags):
     211        (functionShadowChickenFunctionsOnStack):
     212        (functionReadline):
     213        * llint/LLIntOffsetsExtractor.cpp:
     214        * llint/LLIntSlowPaths.cpp:
     215        (JSC::LLInt::LLINT_SLOW_PATH_DECL):
     216        (JSC::LLInt::llint_throw_stack_overflow_error):
     217        * llint/LLIntSlowPaths.h:
     218        * llint/LowLevelInterpreter.asm:
     219        * profiler/ProfileGenerator.cpp:
     220        (JSC::AddParentForConsoleStartFunctor::foundParent):
     221        (JSC::AddParentForConsoleStartFunctor::operator()):
     222        * runtime/Error.cpp:
     223        (JSC::FindFirstCallerFrameWithCodeblockFunctor::FindFirstCallerFrameWithCodeblockFunctor):
     224        (JSC::FindFirstCallerFrameWithCodeblockFunctor::operator()):
     225        (JSC::addErrorInfoAndGetBytecodeOffset):
     226        * runtime/JSFunction.cpp:
     227        (JSC::RetrieveArgumentsFunctor::result):
     228        (JSC::RetrieveArgumentsFunctor::operator()):
     229        (JSC::retrieveArguments):
     230        (JSC::RetrieveCallerFunctionFunctor::result):
     231        (JSC::RetrieveCallerFunctionFunctor::operator()):
     232        (JSC::retrieveCallerFunction):
     233        * runtime/JSGlobalObjectFunctions.cpp:
     234        (JSC::GlobalFuncProtoGetterFunctor::result):
     235        (JSC::GlobalFuncProtoGetterFunctor::operator()):
     236        (JSC::globalFuncProtoGetter):
     237        (JSC::GlobalFuncProtoSetterFunctor::allowsAccess):
     238        (JSC::GlobalFuncProtoSetterFunctor::operator()):
     239        * runtime/NullSetterFunction.cpp:
     240        (JSC::GetCallerStrictnessFunctor::GetCallerStrictnessFunctor):
     241        (JSC::GetCallerStrictnessFunctor::operator()):
     242        (JSC::GetCallerStrictnessFunctor::callerIsStrict):
     243        (JSC::callerIsStrict):
     244        * runtime/ObjectConstructor.cpp:
     245        (JSC::ObjectConstructorGetPrototypeOfFunctor::result):
     246        (JSC::ObjectConstructorGetPrototypeOfFunctor::operator()):
     247        (JSC::objectConstructorGetPrototypeOf):
     248        * runtime/Options.h:
     249        * runtime/VM.cpp:
     250        (JSC::VM::VM):
     251        (JSC::SetEnabledProfilerFunctor::operator()):
     252        * runtime/VM.h:
     253        (JSC::VM::shouldBuilderPCToCodeOriginMapping):
     254        (JSC::VM::bytecodeIntrinsicRegistry):
     255        (JSC::VM::shadowChicken):
     256        * tests/stress/resources/shadow-chicken-support.js: Added.
     257        (describeFunction):
     258        (describeArray):
     259        (expectStack):
     260        (initialize):
     261        * tests/stress/shadow-chicken-disabled.js: Added.
     262        (test1.foo):
     263        (test1.bar):
     264        (test1.baz):
     265        (test1):
     266        (test2.foo):
     267        (test2.bar):
     268        (test2.baz):
     269        (test2):
     270        (test3.foo):
     271        (test3.bar):
     272        (test3.baz):
     273        (test3):
     274        * tests/stress/shadow-chicken-enabled.js: Added.
     275        (test1.foo):
     276        (test1.bar):
     277        (test1.baz):
     278        (test1):
     279        (test2.foo):
     280        (test2.bar):
     281        (test2.baz):
     282        (test2):
     283        (test3.bob):
     284        (test3.thingy):
     285        (test3.foo):
     286        (test3.bar):
     287        (test3.baz):
     288        (test3):
     289        (test4.bob):
     290        (test4.thingy):
     291        (test4.foo):
     292        (test4.bar):
     293        (test4.baz):
     294        (test4):
     295        (test5.foo):
     296        (test5):
     297        * tools/JSDollarVMPrototype.cpp:
     298        (JSC::CallerFrameJITTypeFunctor::CallerFrameJITTypeFunctor):
     299        (JSC::CallerFrameJITTypeFunctor::operator()):
     300        (JSC::CallerFrameJITTypeFunctor::jitType):
     301        (JSC::functionLLintTrue):
     302        (JSC::CellAddressCheckFunctor::CellAddressCheckFunctor):
     303        (JSC::CellAddressCheckFunctor::operator()):
     304        (JSC::JSDollarVMPrototype::isValidCell):
     305        (JSC::JSDollarVMPrototype::isValidCodeBlock):
     306        (JSC::JSDollarVMPrototype::codeBlockForFrame):
     307        (JSC::PrintFrameFunctor::PrintFrameFunctor):
     308        (JSC::PrintFrameFunctor::operator()):
     309        (JSC::printCallFrame):
     310
    13112016-03-19  Filip Pizlo  <fpizlo@apple.com>
    2312
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r199075 r199076  
    19921992                C4F4B6F61A05C984005CAB76 /* objc_generator_templates.py in Headers */ = {isa = PBXBuildFile; fileRef = C4F4B6D81A05C76F005CAB76 /* objc_generator_templates.py */; settings = {ATTRIBUTES = (Private, ); }; };
    19931993                DC00039319D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h in Headers */ = {isa = PBXBuildFile; fileRef = DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */; };
     1994                DC17E8171C9C91D6008A6AB3 /* ShadowChicken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC17E8131C9C7FD4008A6AB3 /* ShadowChicken.cpp */; };
     1995                DC17E8181C9C91D9008A6AB3 /* ShadowChicken.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17E8141C9C7FD4008A6AB3 /* ShadowChicken.h */; };
     1996                DC17E8191C9C91DB008A6AB3 /* ShadowChickenInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */; };
     1997                DC17E81A1C9C91E9008A6AB3 /* CCallHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */; };
    19941998                DE5A0A001BA3AC3E003D4424 /* IntrinsicEmitter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */; };
    19951999                DEA7E2441BBC677200D78440 /* JSTypedArrayViewPrototype.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */; };
     
    41934197                D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = "<group>"; };
    41944198                DC00039019D8BE6F00023EB0 /* DFGPreciseLocalClobberize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGPreciseLocalClobberize.h; path = dfg/DFGPreciseLocalClobberize.h; sourceTree = "<group>"; };
     4199                DC17E8131C9C7FD4008A6AB3 /* ShadowChicken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ShadowChicken.cpp; sourceTree = "<group>"; };
     4200                DC17E8141C9C7FD4008A6AB3 /* ShadowChicken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowChicken.h; sourceTree = "<group>"; };
     4201                DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShadowChickenInlines.h; sourceTree = "<group>"; };
     4202                DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCallHelpers.cpp; sourceTree = "<group>"; };
    41954203                DE5A09FF1BA3AC3E003D4424 /* IntrinsicEmitter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicEmitter.cpp; sourceTree = "<group>"; };
    41964204                E124A8F50E555775003091F1 /* OpaqueJSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueJSString.h; sourceTree = "<group>"; };
     
    49454953                                65FB5115184EE8F800C12B70 /* ProtoCallFrame.h */,
    49464954                                149B24FF0D8AF6D1009CB8C7 /* Register.h */,
     4955                                DC17E8131C9C7FD4008A6AB3 /* ShadowChicken.cpp */,
     4956                                DC17E8141C9C7FD4008A6AB3 /* ShadowChicken.h */,
     4957                                DC17E8151C9C7FD4008A6AB3 /* ShadowChickenInlines.h */,
    49474958                                A7C1EAEC17987AB600299DB2 /* StackVisitor.cpp */,
    49484959                                A7C1EAED17987AB600299DB2 /* StackVisitor.h */,
     
    49674978                                62D755D21B84FB39001801FA /* CallFrameShuffler32_64.cpp */,
    49684979                                62D755D31B84FB39001801FA /* CallFrameShuffler64.cpp */,
     4980                                DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */,
    49694981                                0F24E53D17EA9F5900ABB217 /* CCallHelpers.h */,
    49704982                                0FD82E37141AB14200179C94 /* CompactJITCodeMap.h */,
     
    76137625                                A5EA70EE19F5B5C40098F5EC /* JSContextRefInspectorSupport.h in Headers */,
    76147626                                A5D2E665195E174000A518E7 /* JSContextRefInternal.h in Headers */,
     7627                                DC17E8191C9C91DB008A6AB3 /* ShadowChickenInlines.h in Headers */,
    76157628                                A5AB49DD1BEC8086007020FB /* PerGlobalObjectWrapperWorld.h in Headers */,
    76167629                                148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
     
    80588071                                0F242DA713F3B1E8007ADD4C /* WeakReferenceHarvester.h in Headers */,
    80598072                                14E84FA114EE1ACC00D6D5D4 /* WeakSet.h in Headers */,
     8073                                DC17E8181C9C91D9008A6AB3 /* ShadowChicken.h in Headers */,
    80608074                                709FB86A1AE335C60039D069 /* WeakSetConstructor.h in Headers */,
    80618075                                14150133154BB13F005D8C98 /* WeakSetInlines.h in Headers */,
     
    90349048                                70B791941C024A28002481E2 /* GeneratorFunctionConstructor.cpp in Sources */,
    90359049                                0F5EF91E16878F7A003E5C25 /* JITThunks.cpp in Sources */,
     9050                                DC17E81A1C9C91E9008A6AB3 /* CCallHelpers.cpp in Sources */,
    90369051                                0FC712E217CD8791008CC93C /* JITToDFGDeferredCompilationCallback.cpp in Sources */,
    90379052                                140566C4107EC255005DBC8D /* JSAPIValueWrapper.cpp in Sources */,
     
    91139128                                A7C0C4AD1681067E0017011D /* JSScriptRef.cpp in Sources */,
    91149129                                0F919D10157F3329004A4E7D /* JSSegmentedVariableObject.cpp in Sources */,
     9130                                DC17E8171C9C91D6008A6AB3 /* ShadowChicken.cpp in Sources */,
    91159131                                A7299D9D17D12837005F5FF9 /* JSSet.cpp in Sources */,
    91169132                                A790DD6F182F499700588807 /* JSSetIterator.cpp in Sources */,
  • trunk/Source/JavaScriptCore/bytecode/BytecodeList.json

    r199073 r199076  
    138138            { "name" : "op_save", "length" : 4 },
    139139            { "name" : "op_resume", "length" : 3 },
    140             { "name" : "op_watchdog", "length" : 1 }
     140            { "name" : "op_watchdog", "length" : 1 },
     141            { "name" : "op_log_shadow_chicken_prologue", "length" : 1},
     142            { "name" : "op_log_shadow_chicken_tail", "length" : 1}
    141143        ]
    142144    },
  • trunk/Source/JavaScriptCore/bytecode/BytecodeUseDef.h

    r199073 r199076  
    11/*
    2  * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5656    case op_get_rest_length:
    5757    case op_watchdog:
     58    case op_log_shadow_chicken_prologue:
     59    case op_log_shadow_chicken_tail:
    5860        return;
    5961    case op_assert:
     
    327329    case op_set_function_name:
    328330    case op_watchdog:
     331    case op_log_shadow_chicken_prologue:
     332    case op_log_shadow_chicken_tail:
    329333#define LLINT_HELPER_OPCODES(opcode, length) case opcode:
    330334        FOR_EACH_LLINT_OPCODE_EXTENSION(LLINT_HELPER_OPCODES);
  • trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp

    r199073 r199076  
    11/*
    2  * Copyright (C) 2008-2010, 2012-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008-2010, 2012-2016 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
    44 *
     
    13161316            break;
    13171317        }
     1318        case op_log_shadow_chicken_prologue: {
     1319            printLocationAndOp(out, exec, location, it, "log_shadow_chicken_prologue");
     1320            break;
     1321        }
     1322        case op_log_shadow_chicken_tail: {
     1323            printLocationAndOp(out, exec, location, it, "log_shadow_chicken_tail");
     1324            break;
     1325        }
    13181326        case op_switch_imm: {
    13191327            int tableIndex = (++it)->u.operand;
     
    33953403    { }
    33963404
    3397     StackVisitor::Status operator()(StackVisitor& visitor)
     3405    StackVisitor::Status operator()(StackVisitor& visitor) const
    33983406    {
    33993407        CallFrame* currentCallFrame = visitor->callFrame();
     
    34203428    CallFrame* m_startCallFrame;
    34213429    CodeBlock* m_codeBlock;
    3422     unsigned m_depthToCheck;
    3423     bool m_foundStartCallFrame;
    3424     bool m_didRecurse;
     3430    mutable unsigned m_depthToCheck;
     3431    mutable bool m_foundStartCallFrame;
     3432    mutable bool m_didRecurse;
    34253433};
    34263434
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r199073 r199076  
    10931093{
    10941094    emitOpcode(op_enter);
     1095    emitLogShadowChickenPrologueIfNecessary();
    10951096    emitWatchdog();
    10961097}
     
    29732974    ASSERT(opcodeID == op_call || opcodeID == op_call_eval || opcodeID == op_tail_call);
    29742975    ASSERT(func->refCount());
    2975 
     2976   
    29762977    if (m_shouldEmitProfileHooks)
    29772978        emitMove(callArguments.profileHookRegister(), func);
     
    30073008    RefPtr<Label> done = newLabel();
    30083009    expectedFunction = emitExpectedFunctionSnippet(dst, func, expectedFunction, callArguments, done.get());
     3010   
     3011    if (opcodeID == op_tail_call)
     3012        emitLogShadowChickenTailIfNecessary();
    30093013   
    30103014    // Emit call.
     
    30583062    emitExpressionInfo(divot, divotStart, divotEnd);
    30593063
     3064    if (opcode == op_tail_call_varargs)
     3065        emitLogShadowChickenTailIfNecessary();
     3066   
    30603067    // Emit call.
    30613068    UnlinkedArrayProfile arrayProfile = newArrayProfile();
     
    30753082    }
    30763083    return dst;
     3084}
     3085
     3086void BytecodeGenerator::emitLogShadowChickenPrologueIfNecessary()
     3087{
     3088    if (!m_shouldEmitDebugHooks && !Options::alwaysUseShadowChicken())
     3089        return;
     3090    emitOpcode(op_log_shadow_chicken_prologue);
     3091}
     3092
     3093void BytecodeGenerator::emitLogShadowChickenTailIfNecessary()
     3094{
     3095    if (!m_shouldEmitDebugHooks && !Options::alwaysUseShadowChicken())
     3096        return;
     3097    emitOpcode(op_log_shadow_chicken_tail);
    30773098}
    30783099
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.h

    r199073 r199076  
    837837        RegisterID* emitConstructVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
    838838        RegisterID* emitCallVarargs(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* arguments, RegisterID* firstFreeRegister, int32_t firstVarArgOffset, RegisterID* profileHookRegister, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
     839       
     840        void emitLogShadowChickenPrologueIfNecessary();
     841        void emitLogShadowChickenTailIfNecessary();
    839842
    840843        void initializeParameters(FunctionParameters&);
  • trunk/Source/JavaScriptCore/debugger/DebuggerCallFrame.cpp

    r198980 r199076  
    11/*
    2  * Copyright (C) 2008, 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2013-2014, 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4343namespace JSC {
    4444
     45// FIXME: Make this use ShadowChicken so that it sees tail-deleted frames.
     46// https://bugs.webkit.org/show_bug.cgi?id=155690
     47
    4548class LineAndColumnFunctor {
    4649public:
    47     StackVisitor::Status operator()(StackVisitor& visitor)
     50    StackVisitor::Status operator()(StackVisitor& visitor) const
    4851    {
    4952        visitor->computeLineAndColumn(m_line, m_column);
     
    5558
    5659private:
    57     unsigned m_line;
    58     unsigned m_column;
     60    mutable unsigned m_line;
     61    mutable unsigned m_column;
    5962};
    6063
     
    6669    { }
    6770
    68     StackVisitor::Status operator()(StackVisitor& visitor)
     71    StackVisitor::Status operator()(StackVisitor& visitor) const
    6972    {
    7073        if (visitor->callFrame() == m_callFrame) {
     
    7982private:
    8083    CallFrame* m_callFrame;
    81     CallFrame* m_callerFrame;
     84    mutable CallFrame* m_callerFrame;
    8285};
    8386
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r199075 r199076  
    26272627
    26282628    case CheckWatchdogTimer:
     2629    case LogShadowChickenPrologue:
     2630    case LogShadowChickenTail:
    26292631        break;
    26302632
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r198981 r199076  
    47504750            NEXT_OPCODE(op_to_index_string);
    47514751        }
     4752           
     4753        case op_log_shadow_chicken_prologue: {
     4754            if (!m_inlineStackTop->m_inlineCallFrame)
     4755                addToGraph(LogShadowChickenPrologue);
     4756            NEXT_OPCODE(op_log_shadow_chicken_prologue);
     4757        }
     4758
     4759        case op_log_shadow_chicken_tail: {
     4760            if (!m_inlineStackTop->m_inlineCallFrame) {
     4761                // FIXME: The right solution for inlining is to elide these whenever the tail call
     4762                // ends up being inlined.
     4763                // https://bugs.webkit.org/show_bug.cgi?id=155686
     4764                addToGraph(LogShadowChickenTail);
     4765            }
     4766            NEXT_OPCODE(op_log_shadow_chicken_tail);
     4767        }
    47524768
    47534769        default:
  • trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp

    r198288 r199076  
    226226    case op_copy_rest:
    227227    case op_get_rest_length:
     228    case op_log_shadow_chicken_prologue:
     229    case op_log_shadow_chicken_tail:
    228230        return CanCompileAndInline;
    229231
  • trunk/Source/JavaScriptCore/dfg/DFGClobberize.h

    r199075 r199076  
    11601160        return;
    11611161       
     1162    case LogShadowChickenPrologue:
     1163    case LogShadowChickenTail:
     1164        write(SideState);
     1165        return;
     1166       
    11621167    case LastNodeType:
    11631168        RELEASE_ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp

    r199075 r199076  
    235235    case PutToArguments:
    236236    case CopyRest:
     237    case LogShadowChickenPrologue:
     238    case LogShadowChickenTail:
    237239        return false;
    238240
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r199075 r199076  
    15091509        case CheckNotEmpty:
    15101510        case CheckWatchdogTimer:
     1511        case LogShadowChickenPrologue:
     1512        case LogShadowChickenTail:
    15111513        case Unreachable:
    15121514        case ExtractOSREntryLocal:
  • trunk/Source/JavaScriptCore/dfg/DFGNodeType.h

    r199075 r199076  
    266266    macro(TailCallForwardVarargsInlinedCaller, NodeResultJS | NodeMustGenerate) \
    267267    \
     268    /* Shadow Chicken */\
     269    macro(LogShadowChickenPrologue, NodeMustGenerate) \
     270    macro(LogShadowChickenTail, NodeMustGenerate) \
     271    \
    268272    /* Allocations. */\
    269273    macro(NewObject, NodeResultJS) \
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r199075 r199076  
    789789    ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
    790790{
     791    VM& vm = exec->vm();
     792    NativeCallFrameTracer tracer(&vm, exec);
    791793    return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt8Array>(exec, structure, encodedValue, 0, Nullopt));
    792794}
     
    801803    ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
    802804{
     805    VM& vm = exec->vm();
     806    NativeCallFrameTracer tracer(&vm, exec);
    803807    return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt16Array>(exec, structure, encodedValue, 0, Nullopt));
    804808}
     
    813817    ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
    814818{
     819    VM& vm = exec->vm();
     820    NativeCallFrameTracer tracer(&vm, exec);
    815821    return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSInt32Array>(exec, structure, encodedValue, 0, Nullopt));
    816822}
     
    825831    ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
    826832{
     833    VM& vm = exec->vm();
     834    NativeCallFrameTracer tracer(&vm, exec);
    827835    return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8Array>(exec, structure, encodedValue, 0, Nullopt));
    828836}
     
    837845    ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
    838846{
     847    VM& vm = exec->vm();
     848    NativeCallFrameTracer tracer(&vm, exec);
    839849    return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint8ClampedArray>(exec, structure, encodedValue, 0, Nullopt));
    840850}
     
    849859    ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
    850860{
     861    VM& vm = exec->vm();
     862    NativeCallFrameTracer tracer(&vm, exec);
    851863    return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint16Array>(exec, structure, encodedValue, 0, Nullopt));
    852864}
     
    861873    ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
    862874{
     875    VM& vm = exec->vm();
     876    NativeCallFrameTracer tracer(&vm, exec);
    863877    return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSUint32Array>(exec, structure, encodedValue, 0, Nullopt));
    864878}
     
    873887    ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
    874888{
     889    VM& vm = exec->vm();
     890    NativeCallFrameTracer tracer(&vm, exec);
    875891    return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat32Array>(exec, structure, encodedValue, 0, Nullopt));
    876892}
     
    885901    ExecState* exec, Structure* structure, EncodedJSValue encodedValue)
    886902{
     903    VM& vm = exec->vm();
     904    NativeCallFrameTracer tracer(&vm, exec);
    887905    return reinterpret_cast<char*>(constructGenericTypedArrayViewWithArguments<JSFloat64Array>(exec, structure, encodedValue, 0, Nullopt));
    888906}
  • trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp

    r199075 r199076  
    766766        case PutGlobalVariable:
    767767        case CheckWatchdogTimer:
     768        case LogShadowChickenPrologue:
     769        case LogShadowChickenTail:
    768770        case Unreachable:
    769771        case LoopHint:
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r199075 r199076  
    290290    case ForceOSRExit:
    291291    case CheckWatchdogTimer:
     292    case LogShadowChickenPrologue:
     293    case LogShadowChickenTail:
    292294    case StringFromCharCode:
    293295    case NewTypedArray:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r199075 r199076  
    49474947    }
    49484948
     4949    case LogShadowChickenPrologue: {
     4950        flushRegisters();
     4951        prepareForExternalCall();
     4952        m_jit.emitStoreCodeOrigin(node->origin.semantic);
     4953        m_jit.logShadowChickenProloguePacket();
     4954        noResult(node);
     4955        break;
     4956    }
     4957
     4958    case LogShadowChickenTail: {
     4959        flushRegisters();
     4960        prepareForExternalCall();
     4961        m_jit.emitStoreCodeOrigin(node->origin.semantic);
     4962        m_jit.logShadowChickenTailPacket();
     4963        noResult(node);
     4964        break;
     4965    }
     4966
    49494967    case ForceOSRExit: {
    49504968        terminateSpeculativeExecution(InadequateCoverage, JSValueRegs(), 0);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r199075 r199076  
    49944994        break;
    49954995    }
     4996       
     4997    case LogShadowChickenPrologue: {
     4998        flushRegisters();
     4999        prepareForExternalCall();
     5000        m_jit.emitStoreCodeOrigin(node->origin.semantic);
     5001        m_jit.logShadowChickenProloguePacket();
     5002        noResult(node);
     5003        break;
     5004    }
     5005
     5006    case LogShadowChickenTail: {
     5007        flushRegisters();
     5008        prepareForExternalCall();
     5009        m_jit.emitStoreCodeOrigin(node->origin.semantic);
     5010        m_jit.logShadowChickenTailPacket();
     5011        noResult(node);
     5012        break;
     5013    }
    49965014
    49975015    case MaterializeNewObject:
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp

    r199075 r199076  
    4444#include "ScopedArguments.h"
    4545#include "ScopedArgumentsTable.h"
     46#include "ShadowChicken.h"
    4647
    4748namespace JSC { namespace FTL {
  • trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h

    r199075 r199076  
    8585    macro(RegExpObject_lastIndex, RegExpObject::offsetOfLastIndex()) \
    8686    macro(RegExpObject_lastIndexIsWritable, RegExpObject::offsetOfLastIndexIsWritable()) \
     87    macro(ShadowChicken_Packet_callee, OBJECT_OFFSETOF(ShadowChicken::Packet, callee)) \
     88    macro(ShadowChicken_Packet_frame, OBJECT_OFFSETOF(ShadowChicken::Packet, frame)) \
     89    macro(ShadowChicken_Packet_callerFrame, OBJECT_OFFSETOF(ShadowChicken::Packet, callerFrame)) \
    8790    macro(ScopedArguments_overrodeThings, ScopedArguments::offsetOfOverrodeThings()) \
    8891    macro(ScopedArguments_scope, ScopedArguments::offsetOfScope()) \
  • trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp

    r199075 r199076  
    231231    case RecordRegExpCachedResult:
    232232    case SetFunctionName:
     233    case LogShadowChickenPrologue:
     234    case LogShadowChickenTail:
    233235        // These are OK.
    234236        break;
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r199075 r199076  
    6969#include "ScopedArgumentsTable.h"
    7070#include "ScratchRegisterAllocator.h"
     71#include "ShadowChicken.h"
    7172#include "SetupVarargsFrame.h"
    7273#include "VirtualRegister.h"
     
    941942        case SetRegExpObjectLastIndex:
    942943            compileSetRegExpObjectLastIndex();
     944            break;
     945        case LogShadowChickenPrologue:
     946            compileLogShadowChickenPrologue();
     947            break;
     948        case LogShadowChickenTail:
     949            compileLogShadowChickenTail();
    943950            break;
    944951        case RecordRegExpCachedResult:
     
    67696776        m_out.store64(value, regExp, m_heaps.RegExpObject_lastIndex);
    67706777    }
     6778   
     6779    void compileLogShadowChickenPrologue()
     6780    {
     6781        LValue packet = setupShadowChickenPacket();
     6782       
     6783        m_out.storePtr(m_callFrame, packet, m_heaps.ShadowChicken_Packet_frame);
     6784        m_out.storePtr(m_out.loadPtr(addressFor(0)), packet, m_heaps.ShadowChicken_Packet_callerFrame);
     6785        m_out.storePtr(m_out.loadPtr(payloadFor(JSStack::Callee)), packet, m_heaps.ShadowChicken_Packet_callee);
     6786    }
     6787   
     6788    void compileLogShadowChickenTail()
     6789    {
     6790        LValue packet = setupShadowChickenPacket();
     6791       
     6792        m_out.storePtr(m_callFrame, packet, m_heaps.ShadowChicken_Packet_frame);
     6793        m_out.storePtr(m_out.constIntPtr(ShadowChicken::Packet::tailMarker()), packet, m_heaps.ShadowChicken_Packet_callee);
     6794    }
    67716795
    67726796    void compileRecordRegExpCachedResult()
     
    79918015            m_out.phi(m_out.intPtr, fastArray, slowArray),
    79928016            m_out.phi(m_out.intPtr, fastButterfly, slowButterfly));
     8017    }
     8018   
     8019    LValue setupShadowChickenPacket()
     8020    {
     8021        LBasicBlock slowCase = m_out.newBlock();
     8022        LBasicBlock continuation = m_out.newBlock();
     8023       
     8024        TypedPointer addressOfLogCursor = m_out.absolute(vm().shadowChicken().addressOfLogCursor());
     8025        LValue logCursor = m_out.loadPtr(addressOfLogCursor);
     8026       
     8027        ValueFromBlock fastResult = m_out.anchor(logCursor);
     8028       
     8029        m_out.branch(
     8030            m_out.below(logCursor, m_out.constIntPtr(vm().shadowChicken().logEnd())),
     8031            usually(continuation), rarely(slowCase));
     8032       
     8033        LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
     8034       
     8035        vmCall(Void, m_out.operation(operationProcessShadowChickenLog), m_callFrame);
     8036       
     8037        ValueFromBlock slowResult = m_out.anchor(m_out.loadPtr(addressOfLogCursor));
     8038        m_out.jump(continuation);
     8039       
     8040        m_out.appendTo(continuation, lastNext);
     8041        LValue result = m_out.phi(pointerType(), fastResult, slowResult);
     8042       
     8043        m_out.storePtr(
     8044            m_out.add(result, m_out.constIntPtr(sizeof(ShadowChicken::Packet))),
     8045            addressOfLogCursor);
     8046       
     8047        return result;
    79938048    }
    79948049   
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r198565 r199076  
    4646#include "JSVirtualMachineInternal.h"
    4747#include "SamplingProfiler.h"
     48#include "ShadowChicken.h"
    4849#include "Tracing.h"
    4950#include "TypeProfilerLog.h"
     
    598599        visitHandleStack(heapRootVisitor);
    599600        visitSamplingProfiler();
     601        visitShadowChicken();
    600602        traceCodeBlocksAndJITStubRoutines();
    601603        converge();
     
    900902}
    901903
     904void Heap::visitShadowChicken()
     905{
     906    m_vm->shadowChicken().visitChildren(m_slotVisitor);
     907}
     908
    902909void Heap::traceCodeBlocksAndJITStubRoutines()
    903910{
     
    11241131        vm()->typeProfilerLog()->processLogEntries(ASCIILiteral("GC"));
    11251132    }
    1126    
     1133
     1134    vm()->shadowChicken().update(*vm(), vm()->topCallFrame);
     1135
    11271136    RELEASE_ASSERT(!m_deferralDepth);
    11281137    ASSERT(vm()->currentThreadIsHoldingAPILock());
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r198212 r199076  
    318318    void visitHandleStack(HeapRootVisitor&);
    319319    void visitSamplingProfiler();
     320    void visitShadowChicken();
    320321    void traceCodeBlocksAndJITStubRoutines();
    321322    void converge();
  • trunk/Source/JavaScriptCore/inspector/ScriptCallStackFactory.cpp

    r197794 r199076  
    11/*
    2  * Copyright (C) 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
    33 * Copyright (c) 2010 Google Inc. All rights reserved.
    44 * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
     
    6060    }
    6161
    62     StackVisitor::Status operator()(StackVisitor& visitor)
     62    StackVisitor::Status operator()(StackVisitor& visitor) const
    6363    {
    6464        if (m_needToSkipAFrame) {
     
    8585
    8686private:
    87     bool m_needToSkipAFrame;
     87    mutable bool m_needToSkipAFrame;
    8888    Vector<ScriptCallFrame>& m_frames;
    89     size_t m_remainingCapacityForFrameCapture;
     89    mutable size_t m_remainingCapacityForFrameCapture;
    9090};
    9191
  • trunk/Source/JavaScriptCore/interpreter/CallFrame.h

    r196658 r199076  
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    33 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4  *  Copyright (C) 2003, 2007, 2008, 2011, 2013-2015 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003, 2007, 2008, 2011, 2013-2016 Apple Inc. All rights reserved.
    55 *
    66 *  This library is free software; you can redistribute it and/or
     
    246246
    247247        // CallFrame::iterate() expects a Functor that implements the following method:
    248         //     StackVisitor::Status operator()(StackVisitor&);
    249 
    250         template <typename Functor> void iterate(Functor& functor)
     248        //     StackVisitor::Status operator()(StackVisitor&) const;
     249        // FIXME: This method is improper. We rely on the fact that we can call it with a null
     250        // receiver. We should always be using StackVisitor directly.
     251        template <typename Functor> void iterate(const Functor& functor)
    251252        {
    252253            StackVisitor::visit<Functor>(this, functor);
  • trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp

    r198980 r199076  
    11/*
    2  * Copyright (C) 2008, 2009, 2010, 2012-2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2008, 2009, 2010, 2012-2016 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
    44 *
     
    354354    }
    355355
    356     StackVisitor::Status operator()(StackVisitor& visitor)
     356    StackVisitor::Status operator()(StackVisitor& visitor) const
    357357    {
    358358        if (!m_hasSkippedFirstFrame) {
     
    370370
    371371private:
    372     bool m_hasSkippedFirstFrame;
     372    mutable bool m_hasSkippedFirstFrame;
    373373    const Register*& m_it;
    374374};
     
    544544    }
    545545
    546     StackVisitor::Status operator()(StackVisitor& visitor)
     546    StackVisitor::Status operator()(StackVisitor& visitor) const
    547547    {
    548548        VM& vm = m_vm;
     
    579579    VM& m_vm;
    580580    Vector<StackFrame>& m_results;
    581     size_t m_remainingCapacityForFrameCapture;
     581    mutable size_t m_remainingCapacityForFrameCapture;
    582582};
    583583
     
    631631    HandlerInfo* handler() { return m_handler; }
    632632
    633     StackVisitor::Status operator()(StackVisitor& visitor)
     633    StackVisitor::Status operator()(StackVisitor& visitor) const
    634634    {
    635635        visitor.unwindToMachineCodeBlockFrame();
     
    647647
    648648private:
    649     HandlerInfo* m_handler;
     649    mutable HandlerInfo* m_handler;
    650650};
    651651
     
    672672    }
    673673
    674     StackVisitor::Status operator()(StackVisitor& visitor)
     674    StackVisitor::Status operator()(StackVisitor& visitor) const
    675675    {
    676676        visitor.unwindToMachineCodeBlockFrame();
     
    706706
    707707private:
    708     void copyCalleeSavesToVMCalleeSavesBuffer(StackVisitor& visitor)
     708    void copyCalleeSavesToVMCalleeSavesBuffer(StackVisitor& visitor) const
    709709    {
    710710#if ENABLE(JIT) && NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
  • trunk/Source/JavaScriptCore/interpreter/StackVisitor.h

    r189995 r199076  
    11/*
    2  * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    6464        CodeBlock* codeBlock() const { return m_codeBlock; }
    6565        unsigned bytecodeOffset() const { return m_bytecodeOffset; }
     66        InlineCallFrame* inlineCallFrame() const {
    6667#if ENABLE(DFG_JIT)
    67         InlineCallFrame* inlineCallFrame() const { return m_inlineCallFrame; }
     68            return m_inlineCallFrame;
     69#else
     70            return nullptr;
    6871#endif
     72        }
    6973
    7074        bool isJSFrame() const { return !!codeBlock(); }
    71 #if ENABLE(DFG_JIT)
    72         bool isInlinedFrame() const { return !!m_inlineCallFrame; }
    73 #endif
     75        bool isInlinedFrame() const { return !!inlineCallFrame(); }
    7476
    7577        JS_EXPORT_PRIVATE String functionName();
     
    116118
    117119    // StackVisitor::visit() expects a Functor that implements the following method:
    118     //     Status operator()(StackVisitor&);
     120    //     Status operator()(StackVisitor&) const;
    119121
    120122    template <typename Functor>
    121     static void visit(CallFrame* startFrame, Functor& functor)
     123    static void visit(CallFrame* startFrame, const Functor& functor)
    122124    {
    123125        StackVisitor visitor(startFrame);
     
    158160    CallFrame* callerFrame() const { return m_callerFrame; }
    159161
    160     StackVisitor::Status operator()(StackVisitor& visitor)
     162    StackVisitor::Status operator()(StackVisitor& visitor) const
    161163    {
    162164        if (!m_hasSkippedFirstFrame) {
     
    170172   
    171173private:
    172     bool m_hasSkippedFirstFrame;
    173     CallFrame* m_callerFrame;
     174    mutable bool m_hasSkippedFirstFrame;
     175    mutable CallFrame* m_callerFrame;
    174176};
    175177
  • trunk/Source/JavaScriptCore/jit/CCallHelpers.h

    r197653 r199076  
    11/*
    2  * Copyright (C) 2011, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2011, 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    22062206        move(newFramePointer, stackPointerRegister);
    22072207    }
     2208   
     2209    // These operations clobber all volatile registers. They assume that there is room on the top of
     2210    // stack to marshall call arguments.
     2211    void logShadowChickenProloguePacket();
     2212    void logShadowChickenTailPacket();
     2213
     2214private:
     2215    // Leaves behind a pointer to the Packet we should write to in regT1.
     2216    void setupShadowChickenPacket();
    22082217};
    22092218
  • trunk/Source/JavaScriptCore/jit/JIT.cpp

    r199073 r199076  
    327327        DEFINE_OP(op_enumerator_generic_pname)
    328328        DEFINE_OP(op_to_index_string)
     329           
     330        DEFINE_OP(op_log_shadow_chicken_prologue)
     331        DEFINE_OP(op_log_shadow_chicken_tail)
    329332        default:
    330333            RELEASE_ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r199073 r199076  
    596596        void emit_op_enumerator_generic_pname(Instruction*);
    597597        void emit_op_to_index_string(Instruction*);
     598        void emit_op_log_shadow_chicken_prologue(Instruction*);
     599        void emit_op_log_shadow_chicken_tail(Instruction*);
    598600
    599601        void emitSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&);
  • trunk/Source/JavaScriptCore/jit/JITExceptions.cpp

    r195502 r199076  
    11/*
    2  * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3030#include "CodeBlock.h"
    3131#include "Interpreter.h"
     32#include "JSCInlines.h"
    3233#include "JSCJSValue.h"
    3334#include "LLIntData.h"
     
    3536#include "LLIntThunks.h"
    3637#include "Opcode.h"
    37 #include "JSCInlines.h"
     38#include "ShadowChicken.h"
    3839#include "VM.h"
    3940
     
    5051        CRASH();
    5152    }
     53   
     54    vm->shadowChicken().log(*vm, callFrame, ShadowChicken::Packet::throwPacket());
    5255   
    5356    Exception* exception = vm->exception();
  • trunk/Source/JavaScriptCore/jit/JITInlines.h

    r199073 r199076  
    144144#endif
    145145    store32(TrustedImm32(locationBits), intTagFor(JSStack::ArgumentCount));
     146   
     147    // FIXME: It's not clear that this is needed. JITOperations tend to update the top call frame on
     148    // the C++ side.
     149    // https://bugs.webkit.org/show_bug.cgi?id=155693
    146150    storePtr(callFrameRegister, &m_vm->topCallFrame);
    147151}
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r198288 r199076  
    14511451}
    14521452
     1453void JIT::emit_op_log_shadow_chicken_prologue(Instruction*)
     1454{
     1455    updateTopCallFrame();
     1456    logShadowChickenProloguePacket();
     1457}
     1458
     1459void JIT::emit_op_log_shadow_chicken_tail(Instruction*)
     1460{
     1461    updateTopCallFrame();
     1462    logShadowChickenTailPacket();
     1463}
     1464
    14531465} // namespace JSC
    14541466
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r198288 r199076  
    5050JIT::CodeRef JIT::privateCompileCTINativeCall(VM* vm, NativeFunction func)
    5151{
     52    // FIXME: This should be able to log ShadowChicken prologue packets.
     53    // https://bugs.webkit.org/show_bug.cgi?id=155689
     54   
    5255    Call nativeCall;
    5356
  • trunk/Source/JavaScriptCore/jit/JITOperations.cpp

    r199073 r199076  
    5858#include "Repatch.h"
    5959#include "ScopedArguments.h"
     60#include "ShadowChicken.h"
    6061#include "SuperSampler.h"
    6162#include "TestRunnerUtils.h"
     
    21192120void JIT_OPERATION operationProcessTypeProfilerLog(ExecState* exec)
    21202121{
    2121     exec->vm().typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside baseline JIT"));
     2122    VM& vm = exec->vm();
     2123    NativeCallFrameTracer tracer(&vm, exec);
     2124    vm.typeProfilerLog()->processLogEntries(ASCIILiteral("Log Full, called from inside baseline JIT"));
     2125}
     2126
     2127void JIT_OPERATION operationProcessShadowChickenLog(ExecState* exec)
     2128{
     2129    VM& vm = exec->vm();
     2130    NativeCallFrameTracer tracer(&vm, exec);
     2131    vm.shadowChicken().update(vm, exec);
    21222132}
    21232133
  • trunk/Source/JavaScriptCore/jit/JITOperations.h

    r199073 r199076  
    395395
    396396void JIT_OPERATION operationProcessTypeProfilerLog(ExecState*) WTF_INTERNAL;
     397void JIT_OPERATION operationProcessShadowChickenLog(ExecState*) WTF_INTERNAL;
    397398
    398399} // extern "C"
  • trunk/Source/JavaScriptCore/jit/ThunkGenerators.cpp

    r199069 r199076  
    239239static MacroAssemblerCodeRef nativeForGenerator(VM* vm, CodeSpecializationKind kind, ThunkEntryType entryType = EnterViaCall)
    240240{
     241    // FIXME: This should be able to log ShadowChicken prologue packets.
     242    // https://bugs.webkit.org/show_bug.cgi?id=155689
     243   
    241244    int executableOffsetToFunction = NativeExecutable::offsetOfNativeFunctionFor(kind);
    242245   
  • trunk/Source/JavaScriptCore/jsc.cpp

    r199073 r199076  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2004-2008, 2012-2013, 2015 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2004-2008, 2012-2013, 2015-2016 Apple Inc. All rights reserved.
    44 *  Copyright (C) 2006 Bjoern Graf (bjoern.graf@gmail.com)
    55 *
     
    5454#include "ProfilerDatabase.h"
    5555#include "SamplingProfiler.h"
     56#include "ShadowChicken.h"
    5657#include "StackVisitor.h"
    5758#include "StructureInlines.h"
     
    630631#endif
    631632
     633static EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState*);
     634
    632635struct Script {
    633636    bool isFile;
     
    769772        addFunction(vm, "clearSamplingFlags", functionClearSamplingFlags, 1);
    770773#endif
     774        addFunction(vm, "shadowChickenFunctionsOnStack", functionShadowChickenFunctionsOnStack, 0);
    771775        addConstructableFunction(vm, "Root", functionCreateRoot, 0);
    772776        addConstructableFunction(vm, "Element", functionCreateElement, 1);
     
    11551159    }
    11561160
    1157     StackVisitor::Status operator()(StackVisitor& visitor)
     1161    StackVisitor::Status operator()(StackVisitor& visitor) const
    11581162    {
    11591163        m_trace.append(String::format("    %zu   %s\n", visitor->index(), visitor->toString().utf8().data()));
     
    14711475}
    14721476#endif
     1477
     1478EncodedJSValue JSC_HOST_CALL functionShadowChickenFunctionsOnStack(ExecState* exec)
     1479{
     1480    return JSValue::encode(exec->vm().shadowChicken().functionsOnStack(exec));
     1481}
    14731482
    14741483EncodedJSValue JSC_HOST_CALL functionReadline(ExecState* exec)
  • trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp

    r194835 r199076  
    11/*
    2  * Copyright (C) 2012, 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2012, 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    5050#include "MarkedSpace.h"
    5151#include "ProtoCallFrame.h"
     52#include "ShadowChicken.h"
    5253#include "Structure.h"
    5354#include "StructureChain.h"
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.cpp

    r199073 r199076  
    5454#include "ObjectConstructor.h"
    5555#include "ProtoCallFrame.h"
     56#include "ShadowChicken.h"
    5657#include "StructureRareDataInlines.h"
    5758#include "VMInlines.h"
     
    15151516}
    15161517
     1518LLINT_SLOW_PATH_DECL(slow_path_log_shadow_chicken_prologue)
     1519{
     1520    LLINT_BEGIN();
     1521   
     1522    vm.shadowChicken().log(
     1523        vm, exec, ShadowChicken::Packet::prologue(exec->callee(), exec, exec->callerFrame()));
     1524   
     1525    LLINT_END();
     1526}
     1527
     1528LLINT_SLOW_PATH_DECL(slow_path_log_shadow_chicken_tail)
     1529{
     1530    LLINT_BEGIN();
     1531   
     1532    vm.shadowChicken().log(vm, exec, ShadowChicken::Packet::tail(exec));
     1533   
     1534    LLINT_END();
     1535}
     1536
    15171537extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM* vm, ProtoCallFrame* protoFrame)
    15181538{
  • trunk/Source/JavaScriptCore/llint/LLIntSlowPaths.h

    r199073 r199076  
    124124LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_put_to_scope);
    125125LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_check_if_exception_is_uncatchable_and_notify_profiler);
     126LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_log_shadow_chicken_prologue);
     127LLINT_SLOW_PATH_HIDDEN_DECL(slow_path_log_shadow_chicken_tail);
    126128extern "C" SlowPathReturnType llint_throw_stack_overflow_error(VM*, ProtoCallFrame*) WTF_INTERNAL;
    127129#if !ENABLE(JIT)
  • trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm

    r199073 r199076  
    14571457
    14581458
     1459# Returns the packet pointer in t0.
     1460macro acquireShadowChickenPacket(slow)
     1461    loadp CodeBlock[cfr], t1
     1462    loadp CodeBlock::m_vm[t1], t1
     1463    loadp VM::m_shadowChicken[t1], t2
     1464    loadp ShadowChicken::m_logCursor[t2], t0
     1465    bpaeq t0, ShadowChicken::m_logEnd[t2], slow
     1466    addp sizeof ShadowChicken::Packet, t0, t1
     1467    storep t1, ShadowChicken::m_logCursor[t2]
     1468end
     1469
     1470_llint_op_log_shadow_chicken_prologue:
     1471    traceExecution()
     1472    acquireShadowChickenPacket(.opLogShadowChickenPrologueSlow)
     1473    storep cfr, ShadowChicken::Packet::frame[t0]
     1474    loadp CallerFrame[cfr], t1
     1475    storep t1, ShadowChicken::Packet::callerFrame[t0]
     1476    loadp Callee + PayloadOffset[cfr], t1
     1477    storep t1, ShadowChicken::Packet::callee[t0]
     1478    dispatch(1)
     1479.opLogShadowChickenPrologueSlow:
     1480    callSlowPath(_llint_slow_path_log_shadow_chicken_prologue)
     1481    dispatch(1)
     1482
     1483
     1484_llint_op_log_shadow_chicken_tail:
     1485    traceExecution()
     1486    acquireShadowChickenPacket(.opLogShadowChickenTailSlow)
     1487    storep cfr, ShadowChicken::Packet::frame[t0]
     1488    storep 0x7a11, ShadowChicken::Packet::callee[t0]
     1489    dispatch(1)
     1490.opLogShadowChickenTailSlow:
     1491    callSlowPath(_llint_slow_path_log_shadow_chicken_tail)
     1492    dispatch(1)
     1493
     1494
    14591495_llint_op_switch_string:
    14601496    traceExecution()
  • trunk/Source/JavaScriptCore/profiler/ProfileGenerator.cpp

    r185346 r199076  
    11/*
    2  * Copyright (C) 2008, 2014 Apple Inc. All Rights Reserved.
     2 * Copyright (C) 2008, 2014, 2016 Apple Inc. All Rights Reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7373    bool foundParent() const { return m_foundParent; }
    7474
    75     StackVisitor::Status operator()(StackVisitor& visitor)
     75    StackVisitor::Status operator()(StackVisitor& visitor) const
    7676    {
    7777        if (!m_hasSkippedFirstFrame) {
     
    9393private:
    9494    ExecState* m_exec;
    95     bool m_hasSkippedFirstFrame;
    96     bool m_foundParent;
     95    mutable bool m_hasSkippedFirstFrame;
     96    mutable bool m_foundParent;
    9797    RefPtr<ProfileNode>& m_rootNode;
    9898    RefPtr<ProfileNode>& m_currentNode;
  • trunk/Source/JavaScriptCore/runtime/Error.cpp

    r197531 r199076  
    22 *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
    33 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4  *  Copyright (C) 2003, 2004, 2005, 2006, 2008 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003, 2004, 2005, 2006, 2008, 2016 Apple Inc. All rights reserved.
    55 *  Copyright (C) 2007 Eric Seidel (eric@webkit.org)
    66 *
     
    114114    { }
    115115
    116     StackVisitor::Status operator()(StackVisitor& visitor)
     116    StackVisitor::Status operator()(StackVisitor& visitor) const
    117117    {
    118118        if (!m_foundStartCallFrame && (visitor->callFrame() == m_startCallFrame))
     
    135135private:
    136136    CallFrame* m_startCallFrame;
    137     CallFrame* m_foundCallFrame;
    138     bool m_foundStartCallFrame;
    139     unsigned m_index;
     137    mutable CallFrame* m_foundCallFrame;
     138    mutable bool m_foundStartCallFrame;
     139    mutable unsigned m_index;
    140140};
    141141
  • trunk/Source/JavaScriptCore/runtime/JSFunction.cpp

    r198288 r199076  
    251251    JSValue result() const { return m_result; }
    252252
    253     StackVisitor::Status operator()(StackVisitor& visitor)
     253    StackVisitor::Status operator()(StackVisitor& visitor) const
    254254    {
    255255        JSObject* callee = visitor->callee();
     
    263263private:
    264264    JSObject* m_targetCallee;
    265     JSValue m_result;
     265    mutable JSValue m_result;
    266266};
    267267
     
    293293    JSValue result() const { return m_result; }
    294294
    295     StackVisitor::Status operator()(StackVisitor& visitor)
     295    StackVisitor::Status operator()(StackVisitor& visitor) const
    296296    {
    297297        JSObject* callee = visitor->callee();
     
    316316private:
    317317    JSObject* m_targetCallee;
    318     bool m_hasFoundFrame;
    319     bool m_hasSkippedToCallerFrame;
    320     JSValue m_result;
     318    mutable bool m_hasFoundFrame;
     319    mutable bool m_hasSkippedToCallerFrame;
     320    mutable JSValue m_result;
    321321};
    322322
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r198980 r199076  
    22 *  Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
    33 *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
    4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012 Apple Inc. All rights reserved.
     4 *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2012, 2016 Apple Inc. All rights reserved.
    55 *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
    66 *  Copyright (C) 2007 Maks Orlovich
     
    795795    EncodedJSValue result() { return m_result; }
    796796
    797     StackVisitor::Status operator()(StackVisitor& visitor)
     797    StackVisitor::Status operator()(StackVisitor& visitor) const
    798798    {
    799799        if (!m_hasSkippedFirstFrame) {
     
    810810private:
    811811    ExecState* m_exec;
    812     bool m_hasSkippedFirstFrame;
     812    mutable bool m_hasSkippedFirstFrame;
    813813    JSObject* m_thisObject;
    814     EncodedJSValue m_result;
     814    mutable EncodedJSValue m_result;
    815815};
    816816
     
    848848    bool allowsAccess() const { return m_allowsAccess; }
    849849
    850     StackVisitor::Status operator()(StackVisitor& visitor)
     850    StackVisitor::Status operator()(StackVisitor& visitor) const
    851851    {
    852852        if (!m_hasSkippedFirstFrame) {
     
    860860
    861861private:
    862     bool m_hasSkippedFirstFrame;
    863     bool m_allowsAccess;
     862    mutable bool m_hasSkippedFirstFrame;
     863    mutable bool m_allowsAccess;
    864864    JSObject* m_thisObject;
    865865};
  • trunk/Source/JavaScriptCore/runtime/NullSetterFunction.cpp

    r197614 r199076  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4646    }
    4747
    48     StackVisitor::Status operator()(StackVisitor& visitor)
     48    StackVisitor::Status operator()(StackVisitor& visitor) const
    4949    {
    5050        ++m_iterations;
     
    6060
    6161private:
    62     int m_iterations;
    63     bool m_callerIsStrict;
     62    mutable int m_iterations;
     63    mutable bool m_callerIsStrict;
    6464};
    6565
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r198776 r199076  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2008 Apple Inc. All rights reserved.
     3 *  Copyright (C) 2008, 2016 Apple Inc. All rights reserved.
    44 *
    55 *  This library is free software; you can redistribute it and/or
     
    163163    JSValue result() const { return m_result; }
    164164
    165     StackVisitor::Status operator()(StackVisitor& visitor)
     165    StackVisitor::Status operator()(StackVisitor& visitor) const
    166166    {
    167167        if (!m_hasSkippedFirstFrame) {
     
    177177private:
    178178    ExecState* m_exec;
    179     bool m_hasSkippedFirstFrame;
     179    mutable bool m_hasSkippedFirstFrame;
    180180    JSObject* m_object;
    181     JSValue m_result;
     181    mutable JSValue m_result;
    182182};
    183183
  • trunk/Source/JavaScriptCore/runtime/Options.h

    r199069 r199076  
    135135    v(bool, useFunctionDotArguments, true, nullptr) \
    136136    v(bool, useTailCalls, true, nullptr) \
     137    v(bool, alwaysUseShadowChicken, false, nullptr) \
     138    v(unsigned, shadowChickenLogSize, 1000, nullptr) \
     139    v(unsigned, shadowChickenStackSizeLimit, 100000, nullptr) \
    137140    \
    138141    /* dumpDisassembly implies dumpDFGDisassembly. */ \
  • trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp

    r199075 r199076  
    453453}
    454454
    455 static ALWAYS_INLINE EncodedJSValue removeUsingRegExpSearch(ExecState* exec, JSString* string, const String& source, RegExp* regExp)
     455static ALWAYS_INLINE EncodedJSValue removeUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, const String& source, RegExp* regExp)
    456456{
    457457    SuperSamplerScope superSamplerScope(false);
     
    461461
    462462    Vector<StringRange, 16> sourceRanges;
    463     VM* vm = &exec->vm();
    464463    RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
    465464    unsigned sourceLen = source.length();
    466465
    467466    while (true) {
    468         MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, source, startPosition);
     467        MatchResult result = regExpConstructor->performMatch(vm, regExp, string, source, startPosition);
    469468        if (!result)
    470469            break;
     
    494493
    495494static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(
    496     ExecState* exec, JSString* string, JSValue searchValue, CallData& callData, CallType callType,
    497     String& replacementString, JSValue replaceValue)
     495    VM& vm, ExecState* exec, JSString* string, JSValue searchValue, CallData& callData,
     496    CallType callType, String& replacementString, JSValue replaceValue)
    498497{
    499498    const String& source = string->value(exec);
     
    512511
    513512        if (callType == CallType::None && !replacementString.length())
    514             return removeUsingRegExpSearch(exec, string, source, regExp);
     513            return removeUsingRegExpSearch(vm, exec, string, source, regExp);
    515514    }
    516515
     
    533532        if (exec->hadException())
    534533            return JSValue::encode(jsUndefined());
    535         VM* vm = &exec->vm();
    536534        if (source.is8Bit()) {
    537535            while (true) {
    538536                int* ovector;
    539                 MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, source, startPosition, &ovector);
     537                MatchResult result = regExpConstructor->performMatch(vm, regExp, string, source, startPosition, &ovector);
    540538                if (!result)
    541539                    break;
     
    551549                        cachedCall.setArgument(i, jsUndefined());
    552550                    else
    553                         cachedCall.setArgument(i, jsSubstring(vm, source, matchStart, matchLen));
     551                        cachedCall.setArgument(i, jsSubstring(&vm, source, matchStart, matchLen));
    554552                }
    555553
     
    576574            while (true) {
    577575                int* ovector;
    578                 MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, source, startPosition, &ovector);
     576                MatchResult result = regExpConstructor->performMatch(vm, regExp, string, source, startPosition, &ovector);
    579577                if (!result)
    580578                    break;
     
    590588                        cachedCall.setArgument(i, jsUndefined());
    591589                    else
    592                         cachedCall.setArgument(i, jsSubstring(vm, source, matchStart, matchLen));
     590                        cachedCall.setArgument(i, jsSubstring(&vm, source, matchStart, matchLen));
    593591                }
    594592
     
    614612        }
    615613    } else {
    616         VM* vm = &exec->vm();
    617614        do {
    618615            int* ovector;
    619             MatchResult result = regExpConstructor->performMatch(*vm, regExp, string, source, startPosition, &ovector);
     616            MatchResult result = regExpConstructor->performMatch(vm, regExp, string, source, startPosition, &ovector);
    620617            if (!result)
    621618                break;
     
    678675    ExecState* exec, JSString* thisValue, RegExpObject* searchValue)
    679676{
     677    VM& vm = exec->vm();
     678    NativeCallFrameTracer tracer(&vm, exec);
     679   
    680680    RegExp* regExp = searchValue->regExp();
    681681    if (regExp->global()) {
     
    684684        if (exec->hadException())
    685685            return JSValue::encode(jsUndefined());
    686         return removeUsingRegExpSearch(exec, thisValue, thisValue->value(exec), regExp);
     686        return removeUsingRegExpSearch(vm, exec, thisValue, thisValue->value(exec), regExp);
    687687    }
    688688
     
    690690    String replacementString = emptyString();
    691691    return replaceUsingRegExpSearch(
    692         exec, thisValue, searchValue, callData, CallType::None, replacementString, JSValue());
     692        vm, exec, thisValue, searchValue, callData, CallType::None, replacementString, JSValue());
    693693}
    694694
     
    696696    ExecState* exec, JSString* thisValue, RegExpObject* searchValue, JSString* replaceString)
    697697{
     698    VM& vm = exec->vm();
     699    NativeCallFrameTracer tracer(&vm, exec);
     700   
    698701    CallData callData;
    699702    String replacementString = replaceString->value(exec);
    700703    return replaceUsingRegExpSearch(
    701         exec, thisValue, searchValue, callData, CallType::None, replacementString, replaceString);
    702 }
    703 
    704 static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
     704        vm, exec, thisValue, searchValue, callData, CallType::None, replacementString, replaceString);
     705}
     706
     707static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(VM& vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
    705708{
    706709    String replacementString;
     
    714717
    715718    return replaceUsingRegExpSearch(
    716         exec, string, searchValue, callData, callType, replacementString, replaceValue);
    717 }
    718 
    719 static ALWAYS_INLINE EncodedJSValue replaceUsingStringSearch(ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
     719        vm, exec, string, searchValue, callData, callType, replacementString, replaceValue);
     720}
     721
     722static ALWAYS_INLINE EncodedJSValue replaceUsingStringSearch(VM&, ExecState* exec, JSString* jsString, JSValue searchValue, JSValue replaceValue)
    720723{
    721724    const String& string = jsString->value(exec);
     
    911914
    912915ALWAYS_INLINE EncodedJSValue replace(
    913     ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
     916    VM& vm, ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
    914917{
    915918    if (searchValue.inherits(RegExpObject::info()))
    916         return replaceUsingRegExpSearch(exec, string, searchValue, replaceValue);
    917     return replaceUsingStringSearch(exec, string, searchValue, replaceValue);
     919        return replaceUsingRegExpSearch(vm, exec, string, searchValue, replaceValue);
     920    return replaceUsingStringSearch(vm, exec, string, searchValue, replaceValue);
    918921}
    919922
    920923ALWAYS_INLINE EncodedJSValue replace(
    921     ExecState* exec, JSValue thisValue, JSValue searchValue, JSValue replaceValue)
     924    VM& vm, ExecState* exec, JSValue thisValue, JSValue searchValue, JSValue replaceValue)
    922925{
    923926    if (!checkObjectCoercible(thisValue))
     
    926929    if (exec->hadException())
    927930        return JSValue::encode(jsUndefined());
    928     return replace(exec, string, searchValue, replaceValue);
     931    return replace(vm, exec, string, searchValue, replaceValue);
    929932}
    930933
    931934EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
    932935{
    933     return replace(exec, exec->thisValue(), exec->argument(0), exec->argument(1));
     936    return replace(exec->vm(), exec, exec->thisValue(), exec->argument(0), exec->argument(1));
    934937}
    935938
     
    938941    EncodedJSValue replaceValue)
    939942{
     943    VM& vm = exec->vm();
     944    NativeCallFrameTracer tracer(&vm, exec);
     945   
    940946    return replace(
    941         exec, JSValue::decode(thisValue), JSValue::decode(searchValue),
     947        vm, exec, JSValue::decode(thisValue), JSValue::decode(searchValue),
    942948        JSValue::decode(replaceValue));
    943949}
  • trunk/Source/JavaScriptCore/runtime/VM.cpp

    r198981 r199076  
    8383#include "RuntimeType.h"
    8484#include "SamplingProfiler.h"
     85#include "ShadowChicken.h"
    8586#include "SimpleTypedArrayController.h"
    8687#include "SourceProviderCache.h"
     
    198199    , m_typeProfilerEnabledCount(0)
    199200    , m_controlFlowProfilerEnabledCount(0)
     201    , m_shadowChicken(std::make_unique<ShadowChicken>())
    200202{
    201203    interpreter = new Interpreter(*this);
     
    768770class SetEnabledProfilerFunctor {
    769771public:
    770     bool operator()(CodeBlock* codeBlock)
     772    bool operator()(CodeBlock* codeBlock) const
    771773    {
    772774        if (JITCode::isOptimizingJIT(codeBlock->jitType()))
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r199075 r199076  
    103103class SamplingProfiler;
    104104#endif
     105class ShadowChicken;
    105106class ScriptExecutable;
    106107class SourceProvider;
     
    608609
    609610    BytecodeIntrinsicRegistry& bytecodeIntrinsicRegistry() { return *m_bytecodeIntrinsicRegistry; }
     611   
     612    ShadowChicken& shadowChicken() { return *m_shadowChicken; }
    610613
    611614private:
     
    677680    RefPtr<SamplingProfiler> m_samplingProfiler;
    678681#endif
     682    std::unique_ptr<ShadowChicken> m_shadowChicken;
    679683    std::unique_ptr<BytecodeIntrinsicRegistry> m_bytecodeIntrinsicRegistry;
    680684};
  • trunk/Source/JavaScriptCore/tools/JSDollarVMPrototype.cpp

    r198855 r199076  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7878    }
    7979
    80     StackVisitor::Status operator()(StackVisitor& visitor)
     80    StackVisitor::Status operator()(StackVisitor& visitor) const
    8181    {
    8282        if (m_currentFrame++ > 1) {
     
    9090
    9191private:
    92     unsigned m_currentFrame;
    93     JITCode::JITType m_jitType;
     92    mutable unsigned m_currentFrame;
     93    mutable JITCode::JITType m_jitType;
    9494};
    9595
     
    161161    }
    162162
    163     IterationStatus operator()(JSCell* cell)
     163    IterationStatus operator()(JSCell* cell) const
    164164    {
    165165        if (cell == candidate) {
     
    171171
    172172    JSCell* candidate;
    173     bool found { false };
     173    mutable bool found { false };
    174174};
    175175
     
    193193        }
    194194       
    195         bool operator()(CodeBlock* codeBlock)
     195        bool operator()(CodeBlock* codeBlock) const
    196196        {
    197197            if (codeBlock == candidate)
     
    201201       
    202202        CodeBlock* candidate;
    203         bool found { false };
     203        mutable bool found { false };
    204204    };
    205205   
     
    225225        }
    226226       
    227         StackVisitor::Status operator()(StackVisitor& visitor)
     227        StackVisitor::Status operator()(StackVisitor& visitor) const
    228228        {
    229229            currentFrame++;
     
    236236       
    237237        unsigned targetFrame;
    238         unsigned currentFrame { 0 };
    239         CodeBlock* codeBlock { nullptr };
     238        mutable unsigned currentFrame { 0 };
     239        mutable CodeBlock* codeBlock { nullptr };
    240240    };
    241241   
     
    323323    }
    324324   
    325     StackVisitor::Status operator()(StackVisitor& visitor)
     325    StackVisitor::Status operator()(StackVisitor& visitor) const
    326326    {
    327327        m_currentFrame++;
     
    337337    Action m_action;
    338338    unsigned m_framesToSkip;
    339     unsigned m_currentFrame { 0 };
     339    mutable unsigned m_currentFrame { 0 };
    340340};
    341341
  • trunk/Source/WebCore/ChangeLog

    r199072 r199076  
     12016-03-19  Filip Pizlo  <fpizlo@apple.com>
     2
     3        JSC should use a shadow stack version of CHICKEN so that debuggers have the option of retrieving tail-deleted frames
     4        https://bugs.webkit.org/show_bug.cgi?id=155598
     5
     6        Reviewed by Saam Barati.
     7
     8        Fixed some uses of the stack walking functor to obey the new lambda-friendly API, which
     9        requires that operator() is const.
     10
     11        No new tests because no change in behavior.
     12
     13        * bindings/js/JSXMLHttpRequestCustom.cpp:
     14        (WebCore::SendFunctor::column):
     15        (WebCore::SendFunctor::url):
     16        (WebCore::SendFunctor::operator()):
     17        (WebCore::JSXMLHttpRequest::send):
     18        * testing/Internals.cpp:
     19        (WebCore::GetCallerCodeBlockFunctor::GetCallerCodeBlockFunctor):
     20        (WebCore::GetCallerCodeBlockFunctor::operator()):
     21        (WebCore::GetCallerCodeBlockFunctor::codeBlock):
     22        (WebCore::Internals::parserMetaData):
     23
    1242016-04-05  Brady Eidson  <beidson@apple.com>
    225
  • trunk/Source/WebCore/bindings/js/JSXMLHttpRequestCustom.cpp

    r191887 r199076  
    114114    String url() const { return m_url; }
    115115
    116     StackVisitor::Status operator()(StackVisitor& visitor)
     116    StackVisitor::Status operator()(StackVisitor& visitor) const
    117117    {
    118118        if (!m_hasSkippedFirstFrame) {
     
    131131
    132132private:
    133     bool m_hasSkippedFirstFrame;
    134     unsigned m_line;
    135     unsigned m_column;
    136     String m_url;
     133    mutable bool m_hasSkippedFirstFrame;
     134    mutable unsigned m_line;
     135    mutable unsigned m_column;
     136    mutable String m_url;
    137137};
    138138
     
    159159        wrapped().send(val.toString(&state)->value(&state), ec);
    160160
     161    // FIXME: This should probably use ShadowChicken so that we get the right frame even when it did
     162    // a tail call.
     163    // https://bugs.webkit.org/show_bug.cgi?id=155688
    161164    SendFunctor functor;
    162165    state.iterate(functor);
  • trunk/Source/WebCore/testing/Internals.cpp

    r198859 r199076  
    16621662    }
    16631663
    1664     StackVisitor::Status operator()(StackVisitor& visitor)
     1664    StackVisitor::Status operator()(StackVisitor& visitor) const
    16651665    {
    16661666        ++m_iterations;
     
    16751675
    16761676private:
    1677     int m_iterations;
    1678     CodeBlock* m_codeBlock;
     1677    mutable int m_iterations;
     1678    mutable CodeBlock* m_codeBlock;
    16791679};
    16801680
  • trunk/Tools/Scripts/run-javascriptcore-tests

    r198807 r199076  
    224224            "Source/JavaScriptCore/tests/exceptionFuzz.yaml",
    225225            "PerformanceTests/SunSpider/no-architecture-specific-optimizations.yaml",
     226            "PerformanceTests/SunSpider/shadow-chicken.yaml",
    226227            "PerformanceTests/SunSpider/tests/v8-v6",
    227228            "Source/JavaScriptCore/tests/mozilla/mozilla-tests.yaml",
  • trunk/Tools/Scripts/run-jsc-stress-tests

    r198670 r199076  
    879879end
    880880
     881def runShadowChicken
     882    run("shadow-chicken", "--useDFGJIT=false", "--alwaysUseShadowChicken=true")
     883end
     884
    881885def defaultRun
    882886    if $quickMode
Note: See TracChangeset for help on using the changeset viewer.