summaryrefslogtreecommitdiff
path: root/Source/WebCore/domjit
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/domjit')
-rw-r--r--Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml12
-rw-r--r--Source/WebCore/domjit/DOMJITCheckDOM.h96
-rw-r--r--Source/WebCore/domjit/DOMJITHelpers.cpp55
-rw-r--r--Source/WebCore/domjit/DOMJITHelpers.h190
-rw-r--r--Source/WebCore/domjit/DOMJITIDLConvert.h49
-rw-r--r--Source/WebCore/domjit/DOMJITIDLType.h47
-rw-r--r--Source/WebCore/domjit/DOMJITIDLTypeFilter.h71
-rw-r--r--Source/WebCore/domjit/JSDocumentDOMJIT.cpp151
-rw-r--r--Source/WebCore/domjit/JSNodeDOMJIT.cpp199
-rw-r--r--Source/WebCore/domjit/generate-abstract-heap.rb165
10 files changed, 1035 insertions, 0 deletions
diff --git a/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml b/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml
new file mode 100644
index 000000000..1b156ee1b
--- /dev/null
+++ b/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml
@@ -0,0 +1,12 @@
+DOM:
+ Tree:
+ Node:
+ - Node_firstChild
+ - Node_lastChild
+ - Node_parentNode
+ - Node_nextSibling
+ - Node_previousSibling
+ - Node_ownerDocument
+ Document:
+ - Document_documentElement
+ - Document_body
diff --git a/Source/WebCore/domjit/DOMJITCheckDOM.h b/Source/WebCore/domjit/DOMJITCheckDOM.h
new file mode 100644
index 000000000..1ba310631
--- /dev/null
+++ b/Source/WebCore/domjit/DOMJITCheckDOM.h
@@ -0,0 +1,96 @@
+/*
+ * 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 "DOMJITHelpers.h"
+
+#if ENABLE(JIT)
+
+#include "Document.h"
+#include "Element.h"
+#include "Event.h"
+#include "Node.h"
+
+namespace WebCore { namespace DOMJIT {
+
+template<typename DOMInterface>
+struct TypeChecker {
+};
+
+template<>
+struct TypeChecker<Node> {
+ static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom)
+ {
+ return DOMJIT::branchIfNotNode(jit, dom);
+ }
+};
+
+template<>
+struct TypeChecker<Document> {
+ static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom)
+ {
+ return DOMJIT::branchIfNotDocumentWrapper(jit, dom);
+ }
+};
+
+template<>
+struct TypeChecker<DocumentFragment> {
+ static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom)
+ {
+ return DOMJIT::branchIfNotDocumentFragment(jit, dom);
+ }
+};
+
+template<>
+struct TypeChecker<Event> {
+ static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom)
+ {
+ return DOMJIT::branchIfNotEvent(jit, dom);
+ }
+};
+
+template<>
+struct TypeChecker<Element> {
+ static CCallHelpers::Jump branchIfFail(CCallHelpers& jit, GPRReg dom)
+ {
+ return DOMJIT::branchIfNotElement(jit, dom);
+ }
+};
+
+template<typename DOMInterface>
+Ref<JSC::DOMJIT::Patchpoint> checkDOM()
+{
+ Ref<JSC::DOMJIT::Patchpoint> patchpoint = JSC::DOMJIT::Patchpoint::create();
+ patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
+ return TypeChecker<DOMInterface>::branchIfFail(jit, params[0].gpr());
+ });
+ return patchpoint;
+}
+
+} }
+
+#endif
diff --git a/Source/WebCore/domjit/DOMJITHelpers.cpp b/Source/WebCore/domjit/DOMJITHelpers.cpp
new file mode 100644
index 000000000..d48fca052
--- /dev/null
+++ b/Source/WebCore/domjit/DOMJITHelpers.cpp
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "DOMJITHelpers.h"
+
+#if ENABLE(JIT)
+
+#include "Document.h"
+#include "JSDOMBinding.h"
+#include "Node.h"
+
+namespace WebCore { namespace DOMJIT {
+
+using JSC::CCallHelpers;
+using JSC::GPRReg;
+using JSC::JSValueRegs;
+using JSC::MacroAssembler;
+
+void loadDocument(MacroAssembler& jit, GPRReg node, GPRReg output)
+{
+ jit.loadPtr(CCallHelpers::Address(node, Node::treeScopeMemoryOffset()), output);
+ jit.loadPtr(CCallHelpers::Address(output, TreeScope::documentScopeMemoryOffset()), output);
+}
+
+void loadDocumentElement(MacroAssembler& jit, GPRReg document, GPRReg output)
+{
+ jit.loadPtr(CCallHelpers::Address(document, Document::documentElementMemoryOffset()), output);
+}
+
+} }
+
+#endif
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
diff --git a/Source/WebCore/domjit/DOMJITIDLConvert.h b/Source/WebCore/domjit/DOMJITIDLConvert.h
new file mode 100644
index 000000000..5e00abfcc
--- /dev/null
+++ b/Source/WebCore/domjit/DOMJITIDLConvert.h
@@ -0,0 +1,49 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "IDLTypes.h"
+#include <bytecode/SpeculatedType.h>
+#include <domjit/DOMJITSignature.h>
+
+namespace WebCore { namespace DOMJIT {
+
+template<typename IDLType>
+struct DirectConverter;
+
+template<>
+struct DirectConverter<IDLDOMString> {
+ template<StringConversionConfiguration>
+ static String directConvert(JSC::ExecState&, JSC::JSString*);
+};
+
+template<>
+inline String DirectConverter<IDLDOMString>::directConvert<StringConversionConfiguration::Normal>(JSC::ExecState& state, JSC::JSString* string)
+{
+ return string->value(&state);
+}
+
+} }
diff --git a/Source/WebCore/domjit/DOMJITIDLType.h b/Source/WebCore/domjit/DOMJITIDLType.h
new file mode 100644
index 000000000..6891fbc50
--- /dev/null
+++ b/Source/WebCore/domjit/DOMJITIDLType.h
@@ -0,0 +1,47 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "IDLTypes.h"
+#include <bytecode/SpeculatedType.h>
+
+namespace WebCore { namespace DOMJIT {
+
+template<typename IDLType>
+struct IDLJSArgumentTypeSelect;
+
+template<> struct IDLJSArgumentTypeSelect<IDLBoolean> { typedef bool type; };
+template<> struct IDLJSArgumentTypeSelect<IDLByte> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLOctet> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLShort> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLUnsignedShort> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLLong> { typedef int32_t type; };
+template<> struct IDLJSArgumentTypeSelect<IDLDOMString> { typedef JSC::JSString* type; };
+
+template<typename IDLType>
+using IDLJSArgumentType = typename IDLJSArgumentTypeSelect<IDLType>::type;
+
+} }
diff --git a/Source/WebCore/domjit/DOMJITIDLTypeFilter.h b/Source/WebCore/domjit/DOMJITIDLTypeFilter.h
new file mode 100644
index 000000000..d52d99677
--- /dev/null
+++ b/Source/WebCore/domjit/DOMJITIDLTypeFilter.h
@@ -0,0 +1,71 @@
+/*
+ * 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. AND ITS CONTRIBUTORS ``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 ITS 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 <bytecode/SpeculatedType.h>
+
+namespace WebCore { namespace DOMJIT {
+
+template<typename IDLType>
+struct IDLArgumentTypeFilter;
+
+template<> struct IDLArgumentTypeFilter<IDLBoolean> { static const constexpr JSC::SpeculatedType value = JSC::SpecBoolean; };
+template<> struct IDLArgumentTypeFilter<IDLByte> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLOctet> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLUnsignedShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLArgumentTypeFilter<IDLDOMString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; };
+
+template<typename IDLType>
+struct IDLResultTypeFilter {
+ static const constexpr JSC::SpeculatedType value = JSC::SpecHeapTop;
+};
+
+template<> struct IDLResultTypeFilter<IDLAny> { static const constexpr JSC::SpeculatedType value = JSC::SpecHeapTop; };
+template<> struct IDLResultTypeFilter<IDLBoolean> { static const constexpr JSC::SpeculatedType value = JSC::SpecBoolean; };
+template<> struct IDLResultTypeFilter<IDLByte> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLOctet> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLUnsignedShort> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecInt32Only; };
+template<> struct IDLResultTypeFilter<IDLUnsignedLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLLongLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLUnsignedLongLong> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLFloat> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLUnrestrictedFloat> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLDouble> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLUnrestrictedDouble> { static const constexpr JSC::SpeculatedType value = JSC::SpecBytecodeNumber; };
+template<> struct IDLResultTypeFilter<IDLDOMString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; };
+template<> struct IDLResultTypeFilter<IDLByteString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; };
+template<> struct IDLResultTypeFilter<IDLUSVString> { static const constexpr JSC::SpeculatedType value = JSC::SpecString; };
+
+template<typename T>
+struct IDLResultTypeFilter<IDLNullable<T>> {
+ static const constexpr JSC::SpeculatedType value = JSC::SpecOther | IDLResultTypeFilter<T>::value;
+};
+
+} }
diff --git a/Source/WebCore/domjit/JSDocumentDOMJIT.cpp b/Source/WebCore/domjit/JSDocumentDOMJIT.cpp
new file mode 100644
index 000000000..d1a258fb9
--- /dev/null
+++ b/Source/WebCore/domjit/JSDocumentDOMJIT.cpp
@@ -0,0 +1,151 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "JSDocument.h"
+
+#if ENABLE(JIT)
+
+#include "DOMJITAbstractHeapRepository.h"
+#include "DOMJITCheckDOM.h"
+#include "DOMJITHelpers.h"
+#include "Document.h"
+#include "JSDOMWrapper.h"
+#include "JSElement.h"
+#include "JSHTMLElement.h"
+#include <domjit/DOMJITPatchpoint.h>
+#include <domjit/DOMJITPatchpointParams.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+Ref<JSC::DOMJIT::Patchpoint> DocumentDocumentElementDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Document>();
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> DocumentDocumentElementDOMJIT::callDOMGetter()
+{
+ Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create();
+ patchpoint->numGPScratchRegisters = 1;
+ patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
+ JSValueRegs result = params[0].jsValueRegs();
+ GPRReg document = params[1].gpr();
+ GPRReg globalObject = params[2].gpr();
+ JSValue globalObjectValue = params[2].value();
+ GPRReg scratch = params.gpScratch(0);
+
+ jit.loadPtr(CCallHelpers::Address(document, JSDocument::offsetOfWrapped()), scratch);
+ DOMJIT::loadDocumentElement(jit, scratch, scratch);
+ auto nullCase = jit.branchTestPtr(CCallHelpers::Zero, scratch);
+ DOMJIT::toWrapper<Element>(jit, params, scratch, globalObject, result, DOMJIT::toWrapperSlow<Element>, globalObjectValue);
+ auto done = jit.jump();
+
+ nullCase.link(&jit);
+ jit.moveValue(jsNull(), result);
+ done.link(&jit);
+
+ return CCallHelpers::JumpList();
+ });
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Document_documentElement);
+ return patchpoint;
+}
+
+Ref<JSC::DOMJIT::Patchpoint> DocumentBodyDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Document>();
+}
+
+static void loadLocalName(CCallHelpers& jit, GPRReg htmlElement, GPRReg localNameImpl)
+{
+ jit.loadPtr(CCallHelpers::Address(htmlElement, Element::tagQNameMemoryOffset() + QualifiedName::implMemoryOffset()), localNameImpl);
+ jit.loadPtr(CCallHelpers::Address(localNameImpl, QualifiedName::QualifiedNameImpl::localNameMemoryOffset()), localNameImpl);
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> DocumentBodyDOMJIT::callDOMGetter()
+{
+ Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create();
+ patchpoint->numGPScratchRegisters = 2;
+ patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
+ JSValueRegs result = params[0].jsValueRegs();
+ GPRReg document = params[1].gpr();
+ GPRReg globalObject = params[2].gpr();
+ JSValue globalObjectValue = params[2].value();
+ GPRReg scratch1 = params.gpScratch(0);
+ GPRReg scratch2 = params.gpScratch(1);
+
+ jit.loadPtr(CCallHelpers::Address(document, JSDocument::offsetOfWrapped()), scratch1);
+ DOMJIT::loadDocumentElement(jit, scratch1, scratch1);
+
+ CCallHelpers::JumpList nullCases;
+ CCallHelpers::JumpList successCases;
+ nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch1));
+ nullCases.append(DOMJIT::branchTestIsHTMLFlagOnNode(jit, CCallHelpers::Zero, scratch1));
+ // We ensured that the name of the given element is HTML qualified.
+ // It allows us to perform local name comparison!
+ loadLocalName(jit, scratch1, scratch2);
+ nullCases.append(jit.branchPtr(CCallHelpers::NotEqual, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::htmlTag.localName().impl())));
+
+ RELEASE_ASSERT(!CAST_OFFSET(Node*, ContainerNode*));
+ RELEASE_ASSERT(!CAST_OFFSET(Node*, Element*));
+ RELEASE_ASSERT(!CAST_OFFSET(Node*, HTMLElement*));
+
+ // Node* node = current.firstChild();
+ // while (node && !is<HTMLElement>(*node))
+ // node = node->nextSibling();
+ // return downcast<HTMLElement>(node);
+ jit.loadPtr(CCallHelpers::Address(scratch1, ContainerNode::firstChildMemoryOffset()), scratch1);
+
+ CCallHelpers::Label loopStart = jit.label();
+ nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch1));
+ auto notHTMLElementCase = DOMJIT::branchTestIsHTMLFlagOnNode(jit, CCallHelpers::Zero, scratch1);
+ // We ensured that the name of the given element is HTML qualified.
+ // It allows us to perform local name comparison!
+ loadLocalName(jit, scratch1, scratch2);
+ successCases.append(jit.branchPtr(CCallHelpers::Equal, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::bodyTag.localName().impl())));
+ successCases.append(jit.branchPtr(CCallHelpers::Equal, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::framesetTag.localName().impl())));
+
+ notHTMLElementCase.link(&jit);
+ jit.loadPtr(CCallHelpers::Address(scratch1, Node::nextSiblingMemoryOffset()), scratch1);
+ jit.jump().linkTo(loopStart, &jit);
+
+ successCases.link(&jit);
+ DOMJIT::toWrapper<HTMLElement>(jit, params, scratch1, globalObject, result, DOMJIT::toWrapperSlow<HTMLElement>, globalObjectValue);
+ auto done = jit.jump();
+
+ nullCases.link(&jit);
+ jit.moveValue(jsNull(), result);
+ done.link(&jit);
+
+ return CCallHelpers::JumpList();
+ });
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Document_body);
+ return patchpoint;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/domjit/JSNodeDOMJIT.cpp b/Source/WebCore/domjit/JSNodeDOMJIT.cpp
new file mode 100644
index 000000000..29f8b384e
--- /dev/null
+++ b/Source/WebCore/domjit/JSNodeDOMJIT.cpp
@@ -0,0 +1,199 @@
+/*
+ * 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.
+ */
+
+#include "config.h"
+#include "JSNode.h"
+
+#if ENABLE(JIT)
+
+#include "DOMJITAbstractHeapRepository.h"
+#include "DOMJITCheckDOM.h"
+#include "DOMJITHelpers.h"
+#include "JSDOMWrapper.h"
+#include "Node.h"
+#include <domjit/DOMJITPatchpoint.h>
+#include <domjit/DOMJITPatchpointParams.h>
+#include <interpreter/FrameTracers.h>
+
+using namespace JSC;
+
+namespace WebCore {
+
+enum class IsContainerGuardRequirement { Required, NotRequired };
+
+template<typename WrappedNode>
+static Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> createCallDOMGetterForOffsetAccess(ptrdiff_t offset, IsContainerGuardRequirement isContainerGuardRequirement)
+{
+ Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create();
+ patchpoint->numGPScratchRegisters = 1;
+ patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
+ JSValueRegs result = params[0].jsValueRegs();
+ GPRReg node = params[1].gpr();
+ GPRReg globalObject = params[2].gpr();
+ GPRReg scratch = params.gpScratch(0);
+ JSValue globalObjectValue = params[2].value();
+
+ CCallHelpers::JumpList nullCases;
+ // Load a wrapped object. "node" should be already type checked by CheckDOM.
+ jit.loadPtr(CCallHelpers::Address(node, JSNode::offsetOfWrapped()), scratch);
+
+ if (isContainerGuardRequirement == IsContainerGuardRequirement::Required)
+ nullCases.append(jit.branchTest32(CCallHelpers::Zero, CCallHelpers::Address(scratch, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsContainer())));
+
+ jit.loadPtr(CCallHelpers::Address(scratch, offset), scratch);
+ nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch));
+
+ DOMJIT::toWrapper<WrappedNode>(jit, params, scratch, globalObject, result, DOMJIT::toWrapperSlow<WrappedNode>, globalObjectValue);
+ CCallHelpers::Jump done = jit.jump();
+
+ nullCases.link(&jit);
+ jit.moveValue(jsNull(), result);
+ done.link(&jit);
+ return CCallHelpers::JumpList();
+ });
+ return patchpoint;
+}
+
+Ref<JSC::DOMJIT::Patchpoint> NodeFirstChildDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Node>();
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeFirstChildDOMJIT::callDOMGetter()
+{
+ auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(CAST_OFFSET(Node*, ContainerNode*) + ContainerNode::firstChildMemoryOffset(), IsContainerGuardRequirement::Required);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_firstChild);
+ return patchpoint;
+}
+
+Ref<JSC::DOMJIT::Patchpoint> NodeLastChildDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Node>();
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeLastChildDOMJIT::callDOMGetter()
+{
+ auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(CAST_OFFSET(Node*, ContainerNode*) + ContainerNode::lastChildMemoryOffset(), IsContainerGuardRequirement::Required);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_lastChild);
+ return patchpoint;
+}
+
+Ref<JSC::DOMJIT::Patchpoint> NodeNextSiblingDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Node>();
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeNextSiblingDOMJIT::callDOMGetter()
+{
+ auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(Node::nextSiblingMemoryOffset(), IsContainerGuardRequirement::NotRequired);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_nextSibling);
+ return patchpoint;
+}
+
+Ref<JSC::DOMJIT::Patchpoint> NodePreviousSiblingDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Node>();
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodePreviousSiblingDOMJIT::callDOMGetter()
+{
+ auto patchpoint = createCallDOMGetterForOffsetAccess<Node>(Node::previousSiblingMemoryOffset(), IsContainerGuardRequirement::NotRequired);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_previousSibling);
+ return patchpoint;
+}
+
+Ref<JSC::DOMJIT::Patchpoint> NodeParentNodeDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Node>();
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeParentNodeDOMJIT::callDOMGetter()
+{
+ auto patchpoint = createCallDOMGetterForOffsetAccess<ContainerNode>(Node::parentNodeMemoryOffset(), IsContainerGuardRequirement::NotRequired);
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_parentNode);
+ return patchpoint;
+}
+
+Ref<JSC::DOMJIT::Patchpoint> NodeNodeTypeDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Node>();
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeNodeTypeDOMJIT::callDOMGetter()
+{
+ Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create();
+ patchpoint->effect = JSC::DOMJIT::Effect::forPure();
+ patchpoint->requireGlobalObject = false;
+ patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
+ JSValueRegs result = params[0].jsValueRegs();
+ GPRReg node = params[1].gpr();
+ jit.load8(CCallHelpers::Address(node, JSC::JSCell::typeInfoTypeOffset()), result.payloadGPR());
+ jit.and32(CCallHelpers::TrustedImm32(JSNodeTypeMask), result.payloadGPR());
+ jit.boxInt32(result.payloadGPR(), result);
+ return CCallHelpers::JumpList();
+ });
+ return patchpoint;
+}
+
+Ref<JSC::DOMJIT::Patchpoint> NodeOwnerDocumentDOMJIT::checkDOM()
+{
+ return DOMJIT::checkDOM<Node>();
+}
+
+Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> NodeOwnerDocumentDOMJIT::callDOMGetter()
+{
+ Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create();
+ patchpoint->numGPScratchRegisters = 2;
+ patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) {
+ JSValueRegs result = params[0].jsValueRegs();
+ GPRReg node = params[1].gpr();
+ GPRReg globalObject = params[2].gpr();
+ JSValue globalObjectValue = params[2].value();
+ GPRReg wrapped = params.gpScratch(0);
+ GPRReg document = params.gpScratch(1);
+
+ jit.loadPtr(CCallHelpers::Address(node, JSNode::offsetOfWrapped()), wrapped);
+ DOMJIT::loadDocument(jit, wrapped, document);
+ RELEASE_ASSERT(!CAST_OFFSET(EventTarget*, Node*));
+ RELEASE_ASSERT(!CAST_OFFSET(Node*, Document*));
+
+ CCallHelpers::JumpList nullCases;
+ // If the |this| is the document itself, ownerDocument will return null.
+ nullCases.append(jit.branchPtr(CCallHelpers::Equal, wrapped, document));
+ DOMJIT::toWrapper<Document>(jit, params, document, globalObject, result, DOMJIT::toWrapperSlow<Document>, globalObjectValue);
+ auto done = jit.jump();
+
+ nullCases.link(&jit);
+ jit.moveValue(jsNull(), result);
+ done.link(&jit);
+ return CCallHelpers::JumpList();
+ });
+ patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Node_ownerDocument);
+ return patchpoint;
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/domjit/generate-abstract-heap.rb b/Source/WebCore/domjit/generate-abstract-heap.rb
new file mode 100644
index 000000000..b7412e85d
--- /dev/null
+++ b/Source/WebCore/domjit/generate-abstract-heap.rb
@@ -0,0 +1,165 @@
+#!/usr/bin/env ruby
+# -*- coding: utf-8 -*-
+# 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+
+require "yaml"
+
+class HeapRange
+ attr_reader :first, :last
+ def initialize(first, last)
+ @first = first
+ @last = last
+ end
+end
+
+class AbstractHeap
+ attr_reader :range, :name, :parent
+ def initialize(name, tree)
+ @name = name
+ @parent = nil
+ if tree.nil?
+ @children = []
+ else
+ @children = tree.map {|key, value| AbstractHeap.new(key, value) }
+ end
+ @range = nil
+ end
+
+ def setParent(parent)
+ parent.children.push(self)
+ @parent = parent
+ end
+
+ def compute(start)
+ current = start
+ if @children.empty?
+ @range = HeapRange.new(start, current + 1)
+ return
+ end
+
+ @children.each {|child|
+ child.compute(current)
+ current = child.range.last
+ }
+
+ @range = HeapRange.new(start, current)
+ end
+
+ def dump output
+ shallowDump(output)
+ if @parent
+ output.print "-> "
+ @parent.dump(output)
+ end
+ end
+
+ def shallowDump(output)
+ output.print "#{@name}<#{@range.first},#{@range.last}>"
+ end
+
+ def deepDump output, indent
+ printIndent(output, indent)
+ shallowDump(output)
+ if @children.empty?
+ output.print "\n"
+ return
+ end
+
+ output.print ":\n"
+ @children.each {|child|
+ child.deepDump(output, indent + 1)
+ }
+ end
+
+ def generate output
+ output.puts "constexpr JSC::DOMJIT::HeapRange #{@name}(JSC::DOMJIT::HeapRange::ConstExpr, #{@range.first}, #{@range.last});"
+ @children.each {|child|
+ child.generate(output)
+ }
+ end
+
+private
+ def printIndent output, indent
+ indent.times {
+ output.print " "
+ }
+ end
+end
+
+header = <<-EOS
+/*
+ * 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.
+ */
+// Auto-generated file. Do not modify.
+
+#pragma once
+
+#include <domjit/DOMJITHeapRange.h>
+
+namespace WebCore { namespace DOMJIT { namespace AbstractHeapRepository {
+EOS
+
+footer = <<-EOS
+} } }
+EOS
+
+$inputFileName = ARGV.shift
+$outputFileName = ARGV.shift
+File.open($outputFileName, "w") {|output|
+ File.open($inputFileName, "rb") {|file|
+ tree = YAML::load(file.read())
+ heap = tree.map {|key, value|
+ AbstractHeap.new(key, value)
+ }.first
+ heap.compute(0)
+
+ output.print(header)
+ output.puts("/* DOMJIT Abstract Heap Tree.")
+ heap.deepDump(output, 0)
+ output.puts("*/")
+ heap.generate(output)
+ output.print(footer)
+ }
+}