Move back primary header includes next to config.h
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGOSRExitCompiler.cpp
1 /*
2  * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
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. 
24  */
25
26 #include "config.h"
27 #include "DFGOSRExitCompiler.h"
28
29 #if ENABLE(DFG_JIT)
30
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>
40
41 namespace JSC { namespace DFG {
42
43 extern "C" {
44
45 void compileOSRExit(ExecState* exec)
46 {
47     SamplingRegion samplingRegion("DFG OSR Exit Compilation");
48     
49     CodeBlock* codeBlock = exec->codeBlock();
50     
51     ASSERT(codeBlock);
52     ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
53     
54     VM* vm = &exec->vm();
55     
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);
59
60     uint32_t exitIndex = vm->osrExitIndex;
61     OSRExit& exit = codeBlock->jitCode()->dfg()->osrExit[exitIndex];
62     
63     prepareCodeOriginForOSRExit(exec, exit.m_codeOrigin);
64     
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);
68     
69     // There may be an override, for forward speculations.
70     if (!!exit.m_valueRecoveryOverride) {
71         operands.setOperand(
72             exit.m_valueRecoveryOverride->operand, exit.m_valueRecoveryOverride->recovery);
73     }
74     
75     SpeculationRecovery* recovery = 0;
76     if (exit.m_recoveryIndex != UINT_MAX)
77         recovery = &codeBlock->jitCode()->dfg()->speculationRecovery[exit.m_recoveryIndex];
78
79     {
80         CCallHelpers jit(vm, codeBlock);
81         OSRExitCompiler exitCompiler(jit);
82
83         jit.jitAssertHasValidCallFrame();
84         
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();
88             
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()));
93         }
94         
95         exitCompiler.compileExit(exit, operands, recovery);
96         
97         LinkBuffer patchBuffer(*vm, &jit, codeBlock);
98         exit.m_code = FINALIZE_CODE_IF(
99             shouldShowDisassembly() || Options::verboseOSR(),
100             patchBuffer,
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()));
105     }
106     
107     {
108         RepatchBuffer repatchBuffer(codeBlock);
109         repatchBuffer.relink(exit.codeLocationForRepatch(codeBlock), CodeLocationLabel(exit.m_code.code()));
110     }
111     
112     vm->osrExitJumpDestination = exit.m_code.code().executableAddress();
113 }
114
115 } // extern "C"
116
117 } } // namespace JSC::DFG
118
119 #endif // ENABLE(DFG_JIT)