summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/CallLinkInfo.h
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-05-30 12:48:17 +0200
commit881da28418d380042aa95a97f0cbd42560a64f7c (patch)
treea794dff3274695e99c651902dde93d934ea7a5af /Source/JavaScriptCore/bytecode/CallLinkInfo.h
parent7e104c57a70fdf551bb3d22a5d637cdcbc69dbea (diff)
parent0fcedcd17cc00d3dd44c718b3cb36c1033319671 (diff)
downloadqtwebkit-881da28418d380042aa95a97f0cbd42560a64f7c.tar.gz
Merge 'wip/next' into dev
Change-Id: Iff9ee5e23bb326c4371ec8ed81d56f2f05d680e9
Diffstat (limited to 'Source/JavaScriptCore/bytecode/CallLinkInfo.h')
-rw-r--r--Source/JavaScriptCore/bytecode/CallLinkInfo.h329
1 files changed, 288 insertions, 41 deletions
diff --git a/Source/JavaScriptCore/bytecode/CallLinkInfo.h b/Source/JavaScriptCore/bytecode/CallLinkInfo.h
index 36eb84bee..beeeaa12c 100644
--- a/Source/JavaScriptCore/bytecode/CallLinkInfo.h
+++ b/Source/JavaScriptCore/bytecode/CallLinkInfo.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014, 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
@@ -26,89 +26,336 @@
#ifndef CallLinkInfo_h
#define CallLinkInfo_h
-#include "ClosureCallStubRoutine.h"
+#include "CallMode.h"
#include "CodeLocation.h"
#include "CodeSpecializationKind.h"
#include "JITWriteBarrier.h"
#include "JSFunction.h"
#include "Opcode.h"
+#include "PolymorphicCallStubRoutine.h"
#include "WriteBarrier.h"
-#include <wtf/Platform.h>
#include <wtf/SentinelLinkedList.h>
namespace JSC {
#if ENABLE(JIT)
-class RepatchBuffer;
+struct CallFrameShuffleData;
-struct CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
- enum CallType { None, Call, CallVarargs, Construct };
+class CallLinkInfo : public BasicRawSentinelNode<CallLinkInfo> {
+public:
+ enum CallType { None, Call, CallVarargs, Construct, ConstructVarargs, TailCall, TailCallVarargs };
static CallType callTypeFor(OpcodeID opcodeID)
{
if (opcodeID == op_call || opcodeID == op_call_eval)
return Call;
+ if (opcodeID == op_call_varargs)
+ return CallVarargs;
if (opcodeID == op_construct)
return Construct;
- ASSERT(opcodeID == op_call_varargs);
- return CallVarargs;
+ if (opcodeID == op_construct_varargs)
+ return ConstructVarargs;
+ if (opcodeID == op_tail_call)
+ return TailCall;
+ ASSERT(opcodeID == op_tail_call_varargs);
+ return TailCallVarargs;
}
-
- CallLinkInfo()
- : hasSeenShouldRepatch(false)
- , isDFG(false)
- , hasSeenClosure(false)
- , callType(None)
+
+ static bool isVarargsCallType(CallType callType)
{
+ switch (callType) {
+ case CallVarargs:
+ case ConstructVarargs:
+ case TailCallVarargs:
+ return true;
+
+ default:
+ return false;
+ }
}
+
+ CallLinkInfo();
- ~CallLinkInfo()
+ ~CallLinkInfo();
+
+ static CodeSpecializationKind specializationKindFor(CallType callType)
{
- if (isOnList())
- remove();
+ return specializationFromIsConstruct(callType == Construct || callType == ConstructVarargs);
}
-
CodeSpecializationKind specializationKind() const
{
- return specializationFromIsConstruct(callType == Construct);
+ return specializationKindFor(static_cast<CallType>(m_callType));
+ }
+
+ static CallMode callModeFor(CallType callType)
+ {
+ switch (callType) {
+ case Call:
+ case CallVarargs:
+ return CallMode::Regular;
+ case TailCall:
+ case TailCallVarargs:
+ return CallMode::Tail;
+ case Construct:
+ case ConstructVarargs:
+ return CallMode::Construct;
+ case None:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+
+ CallMode callMode() const
+ {
+ return callModeFor(static_cast<CallType>(m_callType));
+ }
+
+ bool isTailCall() const
+ {
+ return callMode() == CallMode::Tail;
+ }
+
+ bool isVarargs() const
+ {
+ return isVarargsCallType(static_cast<CallType>(m_callType));
+ }
+
+ bool isLinked() { return m_stub || m_callee; }
+ void unlink(VM&);
+
+ void setUpCall(CallType callType, CodeOrigin codeOrigin, unsigned calleeGPR)
+ {
+ m_callType = callType;
+ m_codeOrigin = codeOrigin;
+ m_calleeGPR = calleeGPR;
+ }
+
+ void setCallLocations(CodeLocationNearCall callReturnLocation, CodeLocationDataLabelPtr hotPathBegin,
+ CodeLocationNearCall hotPathOther)
+ {
+ m_callReturnLocation = callReturnLocation;
+ m_hotPathBegin = hotPathBegin;
+ m_hotPathOther = hotPathOther;
+ }
+
+ bool allowStubs() const { return m_allowStubs; }
+
+ void disallowStubs()
+ {
+ m_allowStubs = false;
+ }
+
+ void setUpCallFromFTL(CallType callType, CodeOrigin codeOrigin,
+ CodeLocationNearCall callReturnLocation, CodeLocationDataLabelPtr hotPathBegin,
+ CodeLocationNearCall hotPathOther, unsigned calleeGPR)
+ {
+ m_callType = callType;
+ m_codeOrigin = codeOrigin;
+ m_callReturnLocation = callReturnLocation;
+ m_hotPathBegin = hotPathBegin;
+ m_hotPathOther = hotPathOther;
+ m_calleeGPR = calleeGPR;
+ }
+
+ CodeLocationNearCall callReturnLocation()
+ {
+ return m_callReturnLocation;
+ }
+
+ CodeLocationDataLabelPtr hotPathBegin()
+ {
+ return m_hotPathBegin;
+ }
+
+ CodeLocationNearCall hotPathOther()
+ {
+ return m_hotPathOther;
+ }
+
+ void setCallee(VM& vm, CodeLocationDataLabelPtr location, JSCell* owner, JSFunction* callee)
+ {
+ m_callee.set(vm, location, owner, callee);
+ }
+
+ void clearCallee()
+ {
+ m_callee.clear();
+ }
+
+ JSFunction* callee()
+ {
+ return m_callee.get();
+ }
+
+ void setLastSeenCallee(VM& vm, const JSCell* owner, JSFunction* callee)
+ {
+ m_lastSeenCallee.set(vm, owner, callee);
+ }
+
+ void clearLastSeenCallee()
+ {
+ m_lastSeenCallee.clear();
+ }
+
+ JSFunction* lastSeenCallee()
+ {
+ return m_lastSeenCallee.get();
+ }
+
+ bool haveLastSeenCallee()
+ {
+ return !!m_lastSeenCallee;
+ }
+
+ void setStub(PassRefPtr<PolymorphicCallStubRoutine> newStub)
+ {
+ clearStub();
+ m_stub = newStub;
}
- CodeLocationNearCall callReturnLocation;
- CodeLocationDataLabelPtr hotPathBegin;
- CodeLocationNearCall hotPathOther;
- JITWriteBarrier<JSFunction> callee;
- WriteBarrier<JSFunction> lastSeenCallee;
- RefPtr<ClosureCallStubRoutine> stub;
- bool hasSeenShouldRepatch : 1;
- bool isDFG : 1;
- bool hasSeenClosure : 1;
- CallType callType : 5;
- unsigned calleeGPR : 8;
- CodeOrigin codeOrigin;
+ void clearStub();
- bool isLinked() { return stub || callee; }
- void unlink(VM&, RepatchBuffer&);
+ PolymorphicCallStubRoutine* stub()
+ {
+ return m_stub.get();
+ }
+
+ void setSlowStub(PassRefPtr<JITStubRoutine> newSlowStub)
+ {
+ m_slowStub = newSlowStub;
+ }
+
+ void clearSlowStub()
+ {
+ m_slowStub = nullptr;
+ }
+
+ JITStubRoutine* slowStub()
+ {
+ return m_slowStub.get();
+ }
bool seenOnce()
{
- return hasSeenShouldRepatch;
+ return m_hasSeenShouldRepatch;
+ }
+
+ void clearSeen()
+ {
+ m_hasSeenShouldRepatch = false;
}
void setSeen()
{
- hasSeenShouldRepatch = true;
+ m_hasSeenShouldRepatch = true;
+ }
+
+ bool hasSeenClosure()
+ {
+ return m_hasSeenClosure;
+ }
+
+ void setHasSeenClosure()
+ {
+ m_hasSeenClosure = true;
+ }
+
+ bool clearedByGC()
+ {
+ return m_clearedByGC;
+ }
+
+ void setCallType(CallType callType)
+ {
+ m_callType = callType;
+ }
+
+ CallType callType()
+ {
+ return static_cast<CallType>(m_callType);
+ }
+
+ uint8_t* addressOfMaxNumArguments()
+ {
+ return &m_maxNumArguments;
}
+
+ uint8_t maxNumArguments()
+ {
+ return m_maxNumArguments;
+ }
+
+ static ptrdiff_t offsetOfSlowPathCount()
+ {
+ return OBJECT_OFFSETOF(CallLinkInfo, m_slowPathCount);
+ }
+
+ void setCalleeGPR(unsigned calleeGPR)
+ {
+ m_calleeGPR = calleeGPR;
+ }
+
+ unsigned calleeGPR()
+ {
+ return m_calleeGPR;
+ }
+
+ uint32_t slowPathCount()
+ {
+ return m_slowPathCount;
+ }
+
+ void setCodeOrigin(CodeOrigin codeOrigin)
+ {
+ m_codeOrigin = codeOrigin;
+ }
+
+ CodeOrigin codeOrigin()
+ {
+ return m_codeOrigin;
+ }
+
+ void visitWeak(VM&);
+
+ void setFrameShuffleData(const CallFrameShuffleData&);
+
+ const CallFrameShuffleData* frameShuffleData()
+ {
+ return m_frameShuffleData.get();
+ }
+
+private:
+ CodeLocationNearCall m_callReturnLocation;
+ CodeLocationDataLabelPtr m_hotPathBegin;
+ CodeLocationNearCall m_hotPathOther;
+ JITWriteBarrier<JSFunction> m_callee;
+ WriteBarrier<JSFunction> m_lastSeenCallee;
+ RefPtr<PolymorphicCallStubRoutine> m_stub;
+ RefPtr<JITStubRoutine> m_slowStub;
+ std::unique_ptr<CallFrameShuffleData> m_frameShuffleData;
+ bool m_hasSeenShouldRepatch : 1;
+ bool m_hasSeenClosure : 1;
+ bool m_clearedByGC : 1;
+ bool m_allowStubs : 1;
+ unsigned m_callType : 4; // CallType
+ unsigned m_calleeGPR : 8;
+ uint8_t m_maxNumArguments; // Only used for varargs calls.
+ uint32_t m_slowPathCount;
+ CodeOrigin m_codeOrigin;
};
-inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo)
+inline CodeOrigin getCallLinkInfoCodeOrigin(CallLinkInfo& callLinkInfo)
{
- return callLinkInfo->callReturnLocation.executableAddress();
+ return callLinkInfo.codeOrigin();
}
-inline unsigned getCallLinkInfoBytecodeIndex(CallLinkInfo* callLinkInfo)
-{
- return callLinkInfo->codeOrigin.bytecodeIndex;
-}
+typedef HashMap<CodeOrigin, CallLinkInfo*, CodeOriginApproximateHash> CallLinkInfoMap;
+
+#else // ENABLE(JIT)
+
+typedef HashMap<int, void*> CallLinkInfoMap;
+
#endif // ENABLE(JIT)
} // namespace JSC