summaryrefslogtreecommitdiff
path: root/Source/WebCore/domjit/DOMJITHelpers.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/domjit/DOMJITHelpers.h')
-rw-r--r--Source/WebCore/domjit/DOMJITHelpers.h190
1 files changed, 190 insertions, 0 deletions
diff --git a/Source/WebCore/domjit/DOMJITHelpers.h b/Source/WebCore/domjit/DOMJITHelpers.h
new file mode 100644
index 000000000..1370e5629
--- /dev/null
+++ b/Source/WebCore/domjit/DOMJITHelpers.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#pragma once
+
+#include "JSDOMWrapper.h"
+#include "Node.h"
+#include <domjit/DOMJITPatchpoint.h>
+#include <domjit/DOMJITPatchpointParams.h>
+#include <interpreter/FrameTracers.h>
+
+#if ENABLE(JIT)
+
+namespace WebCore { namespace DOMJIT {
+
+using JSC::CCallHelpers;
+using JSC::GPRReg;
+using JSC::JSValueRegs;
+using JSC::MacroAssembler;
+
+static_assert(std::is_same<GPRReg, MacroAssembler::RegisterID>::value, "GPRReg is the alias to the MacroAssembler::RegisterID");
+
+inline CCallHelpers::Jump branchIfNotWorldIsNormal(CCallHelpers& jit, GPRReg globalObject)
+{
+ return jit.branchTest8(CCallHelpers::Zero, CCallHelpers::Address(globalObject, JSDOMGlobalObject::offsetOfWorldIsNormal()));
+}
+
+inline CCallHelpers::Jump branchIfNotWeakIsLive(CCallHelpers& jit, GPRReg weakImpl)
+{
+ return jit.branchTestPtr(CCallHelpers::NonZero, CCallHelpers::Address(weakImpl, JSC::WeakImpl::offsetOfWeakHandleOwner()), CCallHelpers::TrustedImm32(JSC::WeakImpl::StateMask));
+}
+
+template<typename WrappedNode>
+JSC::EncodedJSValue JIT_OPERATION toWrapperSlow(JSC::ExecState* exec, JSC::JSGlobalObject* globalObject, void* result)
+{
+ ASSERT(exec);
+ ASSERT(result);
+ ASSERT(globalObject);
+ JSC::NativeCallFrameTracer tracer(&exec->vm(), exec);
+ return JSC::JSValue::encode(toJS(exec, static_cast<JSDOMGlobalObject*>(globalObject), *static_cast<WrappedNode*>(result)));
+}
+
+template<typename WrappedType>
+void tryLookUpWrapperCache(CCallHelpers& jit, CCallHelpers::JumpList& failureCases, GPRReg wrapped, GPRReg resultGPR)
+{
+ jit.loadPtr(CCallHelpers::Address(wrapped, ScriptWrappable::offsetOfWrapper<WrappedType>()), resultGPR);
+ failureCases.append(jit.branchTestPtr(CCallHelpers::Zero, resultGPR));
+ failureCases.append(branchIfNotWeakIsLive(jit, resultGPR));
+ jit.loadPtr(CCallHelpers::Address(resultGPR, JSC::WeakImpl::offsetOfJSValue() + JSC::JSValue::offsetOfPayload()), resultGPR);
+}
+
+template<typename WrappedType, typename ToJSFunction>
+void toWrapper(CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params, GPRReg wrapped, GPRReg globalObject, JSValueRegs result, ToJSFunction function, JSC::JSValue globalObjectConstant)
+{
+ ASSERT(wrapped != result.payloadGPR());
+ ASSERT(globalObject != result.payloadGPR());
+ GPRReg payloadGPR = result.payloadGPR();
+ CCallHelpers::JumpList slowCases;
+
+ if (globalObjectConstant) {
+ if (!JSC::jsCast<JSDOMGlobalObject*>(globalObjectConstant)->worldIsNormal()) {
+ slowCases.append(jit.jump());
+ params.addSlowPathCall(slowCases, jit, function, result, globalObject, wrapped);
+ return;
+ }
+ } else
+ slowCases.append(branchIfNotWorldIsNormal(jit, globalObject));
+
+ tryLookUpWrapperCache<WrappedType>(jit, slowCases, wrapped, payloadGPR);
+ jit.boxCell(payloadGPR, result);
+ params.addSlowPathCall(slowCases, jit, function, result, globalObject, wrapped);
+}
+
+inline CCallHelpers::Jump branchIfDOMWrapper(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branch8(
+ CCallHelpers::AboveOrEqual,
+ CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()),
+ CCallHelpers::TrustedImm32(JSC::JSType(JSDOMWrapperType)));
+}
+
+inline CCallHelpers::Jump branchIfNotDOMWrapper(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branch8(
+ CCallHelpers::Below,
+ CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()),
+ CCallHelpers::TrustedImm32(JSC::JSType(JSDOMWrapperType)));
+}
+
+inline CCallHelpers::Jump branchIfEvent(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branchIfType(target, JSC::JSType(JSEventType));
+}
+
+inline CCallHelpers::Jump branchIfNotEvent(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branchIfNotType(target, JSC::JSType(JSEventType));
+}
+
+inline CCallHelpers::Jump branchIfNode(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branch8(
+ CCallHelpers::AboveOrEqual,
+ CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()),
+ CCallHelpers::TrustedImm32(JSC::JSType(JSNodeType)));
+}
+
+inline CCallHelpers::Jump branchIfNotNode(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branch8(
+ CCallHelpers::Below,
+ CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()),
+ CCallHelpers::TrustedImm32(JSC::JSType(JSNodeType)));
+}
+
+inline CCallHelpers::Jump branchIfElement(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branch8(
+ CCallHelpers::AboveOrEqual,
+ CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()),
+ CCallHelpers::TrustedImm32(JSC::JSType(JSElementType)));
+}
+
+inline CCallHelpers::Jump branchIfNotElement(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branch8(
+ CCallHelpers::Below,
+ CCallHelpers::Address(target, JSC::JSCell::typeInfoTypeOffset()),
+ CCallHelpers::TrustedImm32(JSC::JSType(JSElementType)));
+}
+
+inline CCallHelpers::Jump branchIfDocumentFragment(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branchIfType(target, JSC::JSType(JSDocumentFragmentNodeType));
+}
+
+inline CCallHelpers::Jump branchIfNotDocumentFragment(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branchIfNotType(target, JSC::JSType(JSDocumentFragmentNodeType));
+}
+
+inline CCallHelpers::Jump branchIfDocumentWrapper(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branchIfType(target, JSC::JSType(JSDocumentWrapperType));
+}
+
+inline CCallHelpers::Jump branchIfNotDocumentWrapper(CCallHelpers& jit, GPRReg target)
+{
+ return jit.branchIfNotType(target, JSC::JSType(JSDocumentWrapperType));
+}
+
+void loadDocument(MacroAssembler&, GPRReg node, GPRReg output);
+void loadDocumentElement(MacroAssembler&, GPRReg document, GPRReg output);
+
+inline CCallHelpers::Jump branchTestIsElementFlagOnNode(MacroAssembler& jit, CCallHelpers::ResultCondition condition, GPRReg nodeAddress)
+{
+ return jit.branchTest32(condition, CCallHelpers::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsElement()));
+}
+
+inline CCallHelpers::Jump branchTestIsHTMLFlagOnNode(MacroAssembler& jit, CCallHelpers::ResultCondition condition, GPRReg nodeAddress)
+{
+ return jit.branchTest32(condition, CCallHelpers::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsHTML()));
+}
+
+} }
+
+#endif