diff options
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h new file mode 100644 index 000000000..c4707f44e --- /dev/null +++ b/Source/JavaScriptCore/dfg/DFGPromotedHeapLocation.h @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2014-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 + +#if ENABLE(DFG_JIT) + +#include "DFGEdge.h" +#include "DFGNodeOrigin.h" +#include "DFGOpInfo.h" +#include <wtf/HashTable.h> +#include <wtf/PrintStream.h> + +namespace JSC { namespace DFG { + +struct Node; + +// Promoted locations are like heap locations but are meant to be more precise. A heap location is +// applicable to CSE scenarios, where it makes sense to speak of a location very abstractly. A +// promoted heap location is for cases where we speak of a specific object and the compiler knows +// this object's identity - for example, the object allocation has been eliminated and we turned the +// fields into local variables. Because these two cases have subtly different needs, we use subtly +// different structures. One of the really significant differences is that promoted locations can be +// spoken of using either a descriptor which does not refer to any Node*'s or with a heap location, +// which is a descriptor with a Node* base. + +enum PromotedLocationKind { + InvalidPromotedLocationKind, + + ActivationScopePLoc, + ActivationSymbolTablePLoc, + ArgumentCountPLoc, + ArgumentPLoc, + ArgumentsCalleePLoc, + ClosureVarPLoc, + FunctionActivationPLoc, + FunctionExecutablePLoc, + IndexedPropertyPLoc, + NamedPropertyPLoc, + PublicLengthPLoc, + StructurePLoc, + VectorLengthPLoc, + SpreadPLoc, + NewArrayWithSpreadArgumentPLoc, +}; + +class PromotedLocationDescriptor { +public: + PromotedLocationDescriptor( + PromotedLocationKind kind = InvalidPromotedLocationKind, unsigned info = 0) + : m_kind(kind) + , m_info(info) + { + } + + PromotedLocationDescriptor(WTF::HashTableDeletedValueType) + : m_kind(InvalidPromotedLocationKind) + , m_info(1) + { + } + + bool operator!() const { return m_kind == InvalidPromotedLocationKind; } + + explicit operator bool() const { return !!*this; } + + PromotedLocationKind kind() const { return m_kind; } + unsigned info() const { return m_info; } + + unsigned imm1() const { return static_cast<uint32_t>(m_kind); } + unsigned imm2() const { return static_cast<uint32_t>(m_info); } + + unsigned hash() const + { + return m_kind + m_info; + } + + bool operator==(const PromotedLocationDescriptor& other) const + { + return m_kind == other.m_kind + && m_info == other.m_info; + } + + bool operator!=(const PromotedLocationDescriptor& other) const + { + return !(*this == other); + } + + bool isHashTableDeletedValue() const + { + return m_kind == InvalidPromotedLocationKind && m_info; + } + + bool neededForMaterialization() const + { + switch (kind()) { + case NamedPropertyPLoc: + case ClosureVarPLoc: + return false; + + default: + return true; + } + } + + void dump(PrintStream& out) const; + +private: + PromotedLocationKind m_kind; + unsigned m_info; +}; + +struct PromotedLocationDescriptorHash { + static unsigned hash(const PromotedLocationDescriptor& key) { return key.hash(); } + static bool equal(const PromotedLocationDescriptor& a, const PromotedLocationDescriptor& b) { return a == b; } + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +class PromotedHeapLocation { +public: + PromotedHeapLocation( + PromotedLocationKind kind = InvalidPromotedLocationKind, + Node* base = nullptr, unsigned info = 0) + : m_base(base) + , m_meta(kind, info) + { + } + + PromotedHeapLocation( + PromotedLocationKind kind, Edge base, unsigned info = 0) + : PromotedHeapLocation(kind, base.node(), info) + { + } + + PromotedHeapLocation(Node* base, PromotedLocationDescriptor meta) + : m_base(base) + , m_meta(meta) + { + } + + PromotedHeapLocation(WTF::HashTableDeletedValueType) + : m_base(nullptr) + , m_meta(InvalidPromotedLocationKind, 1) + { + } + + Node* createHint(Graph&, NodeOrigin, Node* value); + + bool operator!() const { return kind() == InvalidPromotedLocationKind; } + + PromotedLocationKind kind() const { return m_meta.kind(); } + Node* base() const { return m_base; } + unsigned info() const { return m_meta.info(); } + PromotedLocationDescriptor descriptor() const { return m_meta; } + + unsigned hash() const + { + return m_meta.hash() + WTF::PtrHash<Node*>::hash(m_base); + } + + bool operator==(const PromotedHeapLocation& other) const + { + return m_base == other.m_base + && m_meta == other.m_meta; + } + + bool isHashTableDeletedValue() const + { + return m_meta.isHashTableDeletedValue(); + } + + void dump(PrintStream& out) const; + +private: + Node* m_base; + PromotedLocationDescriptor m_meta; +}; + +struct PromotedHeapLocationHash { + static unsigned hash(const PromotedHeapLocation& key) { return key.hash(); } + static bool equal(const PromotedHeapLocation& a, const PromotedHeapLocation& b) { return a == b; } + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +} } // namespace JSC::DFG + +namespace WTF { + +void printInternal(PrintStream&, JSC::DFG::PromotedLocationKind); + +template<typename T> struct DefaultHash; +template<> struct DefaultHash<JSC::DFG::PromotedHeapLocation> { + typedef JSC::DFG::PromotedHeapLocationHash Hash; +}; + +template<typename T> struct HashTraits; +template<> struct HashTraits<JSC::DFG::PromotedHeapLocation> : SimpleClassHashTraits<JSC::DFG::PromotedHeapLocation> { + static const bool emptyValueIsZero = false; +}; + +template<typename T> struct DefaultHash; +template<> struct DefaultHash<JSC::DFG::PromotedLocationDescriptor> { + typedef JSC::DFG::PromotedLocationDescriptorHash Hash; +}; + +template<typename T> struct HashTraits; +template<> struct HashTraits<JSC::DFG::PromotedLocationDescriptor> : SimpleClassHashTraits<JSC::DFG::PromotedLocationDescriptor> { + static const bool emptyValueIsZero = false; +}; + +} // namespace WTF + +#endif // ENABLE(DFG_JIT) |