]>
git.saurik.com Git - apple/javascriptcore.git/blob - dfg/DFGOSRExitCompiler.cpp
2 * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "DFGOSRExitCompiler.h"
31 #include "CallFrame.h"
32 #include "DFGCommon.h"
33 #include "DFGJITCode.h"
34 #include "DFGOSRExitPreparation.h"
35 #include "LinkBuffer.h"
36 #include "OperandsInlines.h"
37 #include "JSCInlines.h"
38 #include "RepatchBuffer.h"
39 #include <wtf/StringPrintStream.h>
41 namespace JSC
{ namespace DFG
{
45 void compileOSRExit(ExecState
* exec
)
47 SamplingRegion
samplingRegion("DFG OSR Exit Compilation");
49 CodeBlock
* codeBlock
= exec
->codeBlock();
52 ASSERT(codeBlock
->jitType() == JITCode::DFGJIT
);
56 // It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
57 // really be profitable.
58 DeferGCForAWhile
deferGC(vm
->heap
);
60 uint32_t exitIndex
= vm
->osrExitIndex
;
61 OSRExit
& exit
= codeBlock
->jitCode()->dfg()->osrExit
[exitIndex
];
63 prepareCodeOriginForOSRExit(exec
, exit
.m_codeOrigin
);
65 // Compute the value recoveries.
66 Operands
<ValueRecovery
> operands
;
67 codeBlock
->jitCode()->dfg()->variableEventStream
.reconstruct(codeBlock
, exit
.m_codeOrigin
, codeBlock
->jitCode()->dfg()->minifiedDFG
, exit
.m_streamIndex
, operands
);
69 // There may be an override, for forward speculations.
70 if (!!exit
.m_valueRecoveryOverride
) {
72 exit
.m_valueRecoveryOverride
->operand
, exit
.m_valueRecoveryOverride
->recovery
);
75 SpeculationRecovery
* recovery
= 0;
76 if (exit
.m_recoveryIndex
!= UINT_MAX
)
77 recovery
= &codeBlock
->jitCode()->dfg()->speculationRecovery
[exit
.m_recoveryIndex
];
80 CCallHelpers
jit(vm
, codeBlock
);
81 OSRExitCompiler
exitCompiler(jit
);
83 jit
.jitAssertHasValidCallFrame();
85 if (vm
->m_perBytecodeProfiler
&& codeBlock
->jitCode()->dfgCommon()->compilation
) {
86 Profiler::Database
& database
= *vm
->m_perBytecodeProfiler
;
87 Profiler::Compilation
* compilation
= codeBlock
->jitCode()->dfgCommon()->compilation
.get();
89 Profiler::OSRExit
* profilerExit
= compilation
->addOSRExit(
90 exitIndex
, Profiler::OriginStack(database
, codeBlock
, exit
.m_codeOrigin
),
91 exit
.m_kind
, isWatchpoint(exit
.m_kind
));
92 jit
.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit
->counterAddress()));
95 exitCompiler
.compileExit(exit
, operands
, recovery
);
97 LinkBuffer
patchBuffer(*vm
, jit
, codeBlock
);
98 exit
.m_code
= FINALIZE_CODE_IF(
99 shouldShowDisassembly() || Options::verboseOSR(),
101 ("DFG OSR exit #%u (%s, %s) from %s, with operands = %s",
102 exitIndex
, toCString(exit
.m_codeOrigin
).data(),
103 exitKindToString(exit
.m_kind
), toCString(*codeBlock
).data(),
104 toCString(ignoringContext
<DumpContext
>(operands
)).data()));
108 RepatchBuffer
repatchBuffer(codeBlock
);
109 repatchBuffer
.relink(exit
.codeLocationForRepatch(codeBlock
), CodeLocationLabel(exit
.m_code
.code()));
112 vm
->osrExitJumpDestination
= exit
.m_code
.code().executableAddress();
117 } } // namespace JSC::DFG
119 #endif // ENABLE(DFG_JIT)