diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGJITCompiler.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGJITCompiler.h | 207 |
1 files changed, 105 insertions, 102 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGJITCompiler.h b/Source/JavaScriptCore/dfg/DFGJITCompiler.h index b582cea4f..d868012f8 100644 --- a/Source/JavaScriptCore/dfg/DFGJITCompiler.h +++ b/Source/JavaScriptCore/dfg/DFGJITCompiler.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2011, 2013-2015 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -23,13 +23,11 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef DFGJITCompiler_h -#define DFGJITCompiler_h +#pragma once #if ENABLE(DFG_JIT) #include "CCallHelpers.h" -#include "CallFrameInlines.h" #include "CodeBlock.h" #include "DFGDisassembler.h" #include "DFGGraph.h" @@ -39,10 +37,12 @@ #include "DFGRegisterBank.h" #include "FPRInfo.h" #include "GPRInfo.h" +#include "HandlerInfo.h" #include "JITCode.h" #include "JITInlineCacheGenerator.h" #include "LinkBuffer.h" #include "MacroAssembler.h" +#include "PCToCodeOriginMap.h" #include "TempRegisterSet.h" namespace JSC { @@ -112,15 +112,13 @@ public: void compile(); void compileFunction(); - void link(); - void linkFunction(); - // Accessors for properties. Graph& graph() { return m_graph; } // Methods to set labels for the disassembler. void setStartOfCode() { + m_pcToCodeOriginMapBuilder.appendItem(labelIgnoringWatchpoints(), CodeOrigin(0, nullptr)); if (LIKELY(!m_disassembler)) return; m_disassembler->setStartOfCode(labelIgnoringWatchpoints()); @@ -140,25 +138,24 @@ public: m_disassembler->setForNode(node, labelIgnoringWatchpoints()); } - void setEndOfMainPath() + void setEndOfMainPath(); + void setEndOfCode(); + + CallSiteIndex addCallSite(CodeOrigin codeOrigin) { - if (LIKELY(!m_disassembler)) - return; - m_disassembler->setEndOfMainPath(labelIgnoringWatchpoints()); + return m_jitCode->common.addCodeOrigin(codeOrigin); } - - void setEndOfCode() + + CallSiteIndex emitStoreCodeOrigin(CodeOrigin codeOrigin) { - if (LIKELY(!m_disassembler)) - return; - m_disassembler->setEndOfCode(labelIgnoringWatchpoints()); + CallSiteIndex callSite = addCallSite(codeOrigin); + emitStoreCallSiteIndex(callSite); + return callSite; } - - void emitStoreCodeOrigin(CodeOrigin codeOrigin) + + void emitStoreCallSiteIndex(CallSiteIndex callSite) { - unsigned index = m_jitCode->common.addCodeOrigin(codeOrigin); - unsigned locationBits = CallFrame::Location::encodeAsCodeOriginIndex(index); - store32(TrustedImm32(locationBits), tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount))); + store32(TrustedImm32(callSite.bits()), tagFor(static_cast<VirtualRegister>(CallFrameSlot::argumentCount))); } // Add a call out from JIT code, without an exception check. @@ -169,15 +166,7 @@ public: return functionCall; } - void exceptionCheck(Jump jumpToHandler) - { - m_exceptionChecks.append(jumpToHandler); - } - - void exceptionCheck() - { - m_exceptionChecks.append(emitExceptionCheck()); - } + void exceptionCheck(); void exceptionCheckWithCallFrameRollback() { @@ -187,6 +176,7 @@ public: // Add a call out from JIT code, with a fast exception check that tests if the return value is zero. void fastExceptionCheck() { + callExceptionFuzz(); m_exceptionChecks.append(branchTestPtr(Zero, GPRInfo::returnValueGPR)); } @@ -199,12 +189,7 @@ public: } #if USE(JSVALUE32_64) - void* addressOfDoubleConstant(Node* node) - { - ASSERT(m_graph.isNumberConstant(node)); - unsigned constantIndex = node->constantNumber(); - return &(codeBlock()->constantRegister(FirstConstantRegisterIndex + constantIndex)); - } + void* addressOfDoubleConstant(Node*); #endif void addGetById(const JITGetByIdGenerator& gen, SlowPathGenerator* slowPath) @@ -221,10 +206,20 @@ public: { m_ins.append(record); } - - void addJSCall(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, CallLinkInfo::CallType callType, GPRReg callee, CodeOrigin codeOrigin) + + void addJSCall(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, CallLinkInfo* info) + { + m_jsCalls.append(JSCallRecord(fastCall, slowCall, targetToCheck, info)); + } + + void addJSDirectCall(Call call, Label slowPath, CallLinkInfo* info) { - m_jsCalls.append(JSCallRecord(fastCall, slowCall, targetToCheck, callType, callee, codeOrigin)); + m_jsDirectCalls.append(JSDirectCallRecord(call, slowPath, info)); + } + + void addJSDirectTailCall(PatchableJump patchableJump, Call call, Label slowPath, CallLinkInfo* info) + { + m_jsDirectTailCalls.append(JSDirectTailCallRecord(patchableJump, call, slowPath, info)); } void addWeakReference(JSCell* target) @@ -245,62 +240,36 @@ public: addWeakReference(weakPtr); return result; } - - void noticeOSREntry(BasicBlock& basicBlock, JITCompiler::Label blockHead, LinkBuffer& linkBuffer) + + template<typename T> + Jump branchWeakStructure(RelationalCondition cond, T left, RegisteredStructure weakStructure) { - // OSR entry is not allowed into blocks deemed unreachable by control flow analysis. - if (!basicBlock.cfaHasVisited) - return; - - OSREntryData* entry = m_jitCode->appendOSREntryData(basicBlock.bytecodeBegin, linkBuffer.offsetOf(blockHead)); - - entry->m_expectedValues = basicBlock.valuesAtHead; - - // Fix the expected values: in our protocol, a dead variable will have an expected - // value of (None, []). But the old JIT may stash some values there. So we really - // need (Top, TOP). - for (size_t argument = 0; argument < basicBlock.variablesAtHead.numberOfArguments(); ++argument) { - Node* node = basicBlock.variablesAtHead.argument(argument); - if (!node || !node->shouldGenerate()) - entry->m_expectedValues.argument(argument).makeHeapTop(); - } - for (size_t local = 0; local < basicBlock.variablesAtHead.numberOfLocals(); ++local) { - Node* node = basicBlock.variablesAtHead.local(local); - if (!node || !node->shouldGenerate()) - entry->m_expectedValues.local(local).makeHeapTop(); - else { - VariableAccessData* variable = node->variableAccessData(); - switch (variable->flushFormat()) { - case FlushedDouble: - entry->m_localsForcedDouble.set(local); - break; - case FlushedInt52: - entry->m_localsForcedMachineInt.set(local); - break; - default: - break; - } - - if (variable->local() != variable->machineLocal()) { - entry->m_reshufflings.append( - OSREntryReshuffling( - variable->local().offset(), variable->machineLocal().offset())); - } - } - } - - entry->m_reshufflings.shrinkToFit(); + Structure* structure = weakStructure.get(); +#if USE(JSVALUE64) + Jump result = branch32(cond, left, TrustedImm32(structure->id())); + return result; +#else + return branchPtr(cond, left, TrustedImmPtr(structure)); +#endif } + + void noticeOSREntry(BasicBlock&, JITCompiler::Label blockHead, LinkBuffer&); - PassRefPtr<JITCode> jitCode() { return m_jitCode; } + RefPtr<JITCode> jitCode() { return m_jitCode; } Vector<Label>& blockHeads() { return m_blockHeads; } + CallSiteIndex recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(const CodeOrigin&, unsigned eventStreamIndex); + + PCToCodeOriginMapBuilder& pcToCodeOriginMapBuilder() { return m_pcToCodeOriginMapBuilder; } + private: friend class OSRExitJumpPlaceholder; // Internal implementation to compile. void compileEntry(); + void compileSetupRegistersForEntry(); + void compileEntryExecutionFlag(); void compileBody(); void link(LinkBuffer&); @@ -308,11 +277,13 @@ private: void compileExceptionHandlers(); void linkOSRExits(); void disassemble(LinkBuffer&); - + + void appendExceptionHandlingOSRExit(ExitKind, unsigned eventStreamIndex, CodeOrigin, HandlerInfo* exceptionHandler, CallSiteIndex, MacroAssembler::JumpList jumpsToFail = MacroAssembler::JumpList()); + // The dataflow graph currently being generated. Graph& m_graph; - OwnPtr<Disassembler> m_disassembler; + std::unique_ptr<Disassembler> m_disassembler; RefPtr<JITCode> m_jitCode; @@ -325,38 +296,70 @@ private: Vector<Label> m_blockHeads; struct JSCallRecord { - JSCallRecord(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, CallLinkInfo::CallType callType, GPRReg callee, CodeOrigin codeOrigin) - : m_fastCall(fastCall) - , m_slowCall(slowCall) - , m_targetToCheck(targetToCheck) - , m_callType(callType) - , m_callee(callee) - , m_codeOrigin(codeOrigin) + JSCallRecord(Call fastCall, Call slowCall, DataLabelPtr targetToCheck, CallLinkInfo* info) + : fastCall(fastCall) + , slowCall(slowCall) + , targetToCheck(targetToCheck) + , info(info) { } - Call m_fastCall; - Call m_slowCall; - DataLabelPtr m_targetToCheck; - CallLinkInfo::CallType m_callType; - GPRReg m_callee; - CodeOrigin m_codeOrigin; + Call fastCall; + Call slowCall; + DataLabelPtr targetToCheck; + CallLinkInfo* info; + }; + + struct JSDirectCallRecord { + JSDirectCallRecord(Call call, Label slowPath, CallLinkInfo* info) + : call(call) + , slowPath(slowPath) + , info(info) + { + } + + Call call; + Label slowPath; + CallLinkInfo* info; + }; + + struct JSDirectTailCallRecord { + JSDirectTailCallRecord(PatchableJump patchableJump, Call call, Label slowPath, CallLinkInfo* info) + : patchableJump(patchableJump) + , call(call) + , slowPath(slowPath) + , info(info) + { + } + + PatchableJump patchableJump; + Call call; + Label slowPath; + CallLinkInfo* info; }; Vector<InlineCacheWrapper<JITGetByIdGenerator>, 4> m_getByIds; Vector<InlineCacheWrapper<JITPutByIdGenerator>, 4> m_putByIds; Vector<InRecord, 4> m_ins; Vector<JSCallRecord, 4> m_jsCalls; + Vector<JSDirectCallRecord, 4> m_jsDirectCalls; + Vector<JSDirectTailCallRecord, 4> m_jsDirectTailCalls; SegmentedVector<OSRExitCompilationInfo, 4> m_exitCompilationInfo; Vector<Vector<Label>> m_exitSiteLabels; + struct ExceptionHandlingOSRExitInfo { + OSRExitCompilationInfo& exitInfo; + HandlerInfo baselineExceptionHandler; + CallSiteIndex callSiteIndex; + }; + Vector<ExceptionHandlingOSRExitInfo> m_exceptionHandlerOSRExitCallSites; + Call m_callArityFixup; Label m_arityCheck; - OwnPtr<SpeculativeJIT> m_speculative; + std::unique_ptr<SpeculativeJIT> m_speculative; + PCToCodeOriginMapBuilder m_pcToCodeOriginMapBuilder; }; } } // namespace JSC::DFG #endif -#endif - |