summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/dfg/DFGJITCompiler.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGJITCompiler.h')
-rw-r--r--Source/JavaScriptCore/dfg/DFGJITCompiler.h207
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
-