diff options
Diffstat (limited to 'Source/JavaScriptCore/bytecode/PropertyCondition.h')
| -rw-r--r-- | Source/JavaScriptCore/bytecode/PropertyCondition.h | 338 |
1 files changed, 0 insertions, 338 deletions
diff --git a/Source/JavaScriptCore/bytecode/PropertyCondition.h b/Source/JavaScriptCore/bytecode/PropertyCondition.h deleted file mode 100644 index bd08c3b9d..000000000 --- a/Source/JavaScriptCore/bytecode/PropertyCondition.h +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 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 - * 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. - */ - -#ifndef PropertyCondition_h -#define PropertyCondition_h - -#include "JSObject.h" -#include <wtf/HashMap.h> - -namespace JSC { - -class TrackedReferences; - -class PropertyCondition { -public: - enum Kind { - Presence, - Absence, - AbsenceOfSetter, - Equivalence // An adaptive watchpoint on this will be a pair of watchpoints, and when the structure transitions, we will set the replacement watchpoint on the new structure. - }; - - PropertyCondition() - : m_uid(nullptr) - , m_kind(Presence) - { - memset(&u, 0, sizeof(u)); - } - - PropertyCondition(WTF::HashTableDeletedValueType) - : m_uid(nullptr) - , m_kind(Absence) - { - memset(&u, 0, sizeof(u)); - } - - static PropertyCondition presenceWithoutBarrier(UniquedStringImpl* uid, PropertyOffset offset, unsigned attributes) - { - PropertyCondition result; - result.m_uid = uid; - result.m_kind = Presence; - result.u.presence.offset = offset; - result.u.presence.attributes = attributes; - return result; - } - - static PropertyCondition presence( - VM&, JSCell*, UniquedStringImpl* uid, PropertyOffset offset, unsigned attributes) - { - return presenceWithoutBarrier(uid, offset, attributes); - } - - // NOTE: The prototype is the storedPrototype not the prototypeForLookup. - static PropertyCondition absenceWithoutBarrier(UniquedStringImpl* uid, JSObject* prototype) - { - PropertyCondition result; - result.m_uid = uid; - result.m_kind = Absence; - result.u.absence.prototype = prototype; - return result; - } - - static PropertyCondition absence( - VM& vm, JSCell* owner, UniquedStringImpl* uid, JSObject* prototype) - { - if (owner) - vm.heap.writeBarrier(owner); - return absenceWithoutBarrier(uid, prototype); - } - - static PropertyCondition absenceOfSetterWithoutBarrier( - UniquedStringImpl* uid, JSObject* prototype) - { - PropertyCondition result; - result.m_uid = uid; - result.m_kind = AbsenceOfSetter; - result.u.absence.prototype = prototype; - return result; - } - - static PropertyCondition absenceOfSetter( - VM& vm, JSCell* owner, UniquedStringImpl* uid, JSObject* prototype) - { - if (owner) - vm.heap.writeBarrier(owner); - return absenceOfSetterWithoutBarrier(uid, prototype); - } - - static PropertyCondition equivalenceWithoutBarrier( - UniquedStringImpl* uid, JSValue value) - { - PropertyCondition result; - result.m_uid = uid; - result.m_kind = Equivalence; - result.u.equivalence.value = JSValue::encode(value); - return result; - } - - static PropertyCondition equivalence( - VM& vm, JSCell* owner, UniquedStringImpl* uid, JSValue value) - { - if (value.isCell() && owner) - vm.heap.writeBarrier(owner); - return equivalenceWithoutBarrier(uid, value); - } - - bool operator!() const { return !m_uid && m_kind == Presence; }; - - Kind kind() const { return m_kind; } - UniquedStringImpl* uid() const { return m_uid; } - - bool hasOffset() const { return !!*this && m_kind == Presence; }; - PropertyOffset offset() const - { - ASSERT(hasOffset()); - return u.presence.offset; - } - bool hasAttributes() const { return !!*this && m_kind == Presence; }; - unsigned attributes() const - { - ASSERT(hasAttributes()); - return u.presence.attributes; - } - - bool hasPrototype() const { return !!*this && (m_kind == Absence || m_kind == AbsenceOfSetter); } - JSObject* prototype() const - { - ASSERT(hasPrototype()); - return u.absence.prototype; - } - - bool hasRequiredValue() const { return !!*this && m_kind == Equivalence; } - JSValue requiredValue() const - { - ASSERT(hasRequiredValue()); - return JSValue::decode(u.equivalence.value); - } - - void dumpInContext(PrintStream&, DumpContext*) const; - void dump(PrintStream&) const; - - unsigned hash() const - { - unsigned result = WTF::PtrHash<UniquedStringImpl*>::hash(m_uid) + static_cast<unsigned>(m_kind); - switch (m_kind) { - case Presence: - result ^= u.presence.offset; - result ^= u.presence.attributes; - break; - case Absence: - case AbsenceOfSetter: - result ^= WTF::PtrHash<JSObject*>::hash(u.absence.prototype); - break; - case Equivalence: - result ^= EncodedJSValueHash::hash(u.equivalence.value); - break; - } - return result; - } - - bool operator==(const PropertyCondition& other) const - { - if (m_uid != other.m_uid) - return false; - if (m_kind != other.m_kind) - return false; - switch (m_kind) { - case Presence: - return u.presence.offset == other.u.presence.offset - && u.presence.attributes == other.u.presence.attributes; - case Absence: - case AbsenceOfSetter: - return u.absence.prototype == other.u.absence.prototype; - case Equivalence: - return u.equivalence.value == other.u.equivalence.value; - } - RELEASE_ASSERT_NOT_REACHED(); - return false; - } - - bool isHashTableDeletedValue() const - { - return !m_uid && m_kind == Absence; - } - - // Two conditions are compatible if they are identical or if they speak of different uids. If - // false is returned, you have to decide how to resolve the conflict - for example if there is - // a Presence and an Equivalence then in some cases you'll want the more general of the two - // while in other cases you'll want the more specific of the two. This will also return false - // for contradictions, like Presence and Absence on the same uid. By convention, invalid - // conditions aren't compatible with anything. - bool isCompatibleWith(const PropertyCondition& other) const - { - if (!*this || !other) - return false; - return *this == other || uid() != other.uid(); - } - - // Checks if the object's structure claims that the property won't be intercepted. - bool isStillValidAssumingImpurePropertyWatchpoint(Structure*, JSObject* base = nullptr) const; - - // Returns true if we need an impure property watchpoint to ensure validity even if - // isStillValidAccordingToStructure() returned true. - bool validityRequiresImpurePropertyWatchpoint(Structure*) const; - - // Checks if the condition is still valid right now for the given object and structure. - // May conservatively return false, if the object and structure alone don't guarantee the - // condition. This happens for an Absence condition on an object that may have impure - // properties. If the object is not supplied, then a "true" return indicates that checking if - // an object has the given structure guarantees the condition still holds. If an object is - // supplied, then you may need to use some other watchpoints on the object to guarantee the - // condition in addition to the structure check. - bool isStillValid(Structure*, JSObject* base = nullptr) const; - - // In some cases, the condition is not watchable, but could be made watchable by enabling the - // appropriate watchpoint. For example, replacement watchpoints are enabled only when some - // access is cached on the property in some structure. This is mainly to save space for - // dictionary properties or properties that never get very hot. But, it's always safe to - // enable watching, provided that this is called from the main thread. - enum WatchabilityEffort { - // This is the default. It means that we don't change the state of any Structure or - // object, and implies that if the property happens not to be watchable then we don't make - // it watchable. This is mandatory if calling from a JIT thread. This is also somewhat - // preferable when first deciding whether to watch a condition for the first time (i.e. - // not from a watchpoint fire that causes us to see if we should adapt), since a - // watchpoint not being initialized for watching implies that maybe we don't know enough - // yet to make it profitable to watch -- as in, the thing being watched may not have - // stabilized yet. We prefer to only assume that a condition will hold if it has been - // known to hold for a while already. - MakeNoChanges, - - // Do what it takes to ensure that the property can be watched, if doing so has no - // user-observable effect. For now this just means that we will ensure that a property - // replacement watchpoint is enabled if it hadn't been enabled already. Do not use this - // from JIT threads, since the act of enabling watchpoints is not thread-safe. - EnsureWatchability - }; - - // This means that it's still valid and we could enforce validity by setting a transition - // watchpoint on the structure and possibly an impure property watchpoint. - bool isWatchableAssumingImpurePropertyWatchpoint( - Structure*, JSObject* base = nullptr, WatchabilityEffort = MakeNoChanges) const; - - // This means that it's still valid and we could enforce validity by setting a transition - // watchpoint on the structure. - bool isWatchable( - Structure*, JSObject* base = nullptr, WatchabilityEffort = MakeNoChanges) const; - - bool watchingRequiresStructureTransitionWatchpoint() const - { - // Currently, this is required for all of our conditions. - return !!*this; - } - bool watchingRequiresReplacementWatchpoint() const - { - return !!*this && m_kind == Equivalence; - } - - // This means that the objects involved in this are still live. - bool isStillLive() const; - - void validateReferences(const TrackedReferences&) const; - - static bool isValidValueForAttributes(JSValue value, unsigned attributes); - - bool isValidValueForPresence(JSValue) const; - - PropertyCondition attemptToMakeEquivalenceWithoutBarrier(JSObject* base) const; - -private: - bool isWatchableWhenValid(Structure*, WatchabilityEffort) const; - - UniquedStringImpl* m_uid; - Kind m_kind; - union { - struct { - PropertyOffset offset; - unsigned attributes; - } presence; - struct { - JSObject* prototype; - } absence; - struct { - EncodedJSValue value; - } equivalence; - } u; -}; - -struct PropertyConditionHash { - static unsigned hash(const PropertyCondition& key) { return key.hash(); } - static bool equal( - const PropertyCondition& a, const PropertyCondition& b) - { - return a == b; - } - static const bool safeToCompareToEmptyOrDeleted = true; -}; - -} // namespace JSC - -namespace WTF { - -void printInternal(PrintStream&, JSC::PropertyCondition::Kind); - -template<typename T> struct DefaultHash; -template<> struct DefaultHash<JSC::PropertyCondition> { - typedef JSC::PropertyConditionHash Hash; -}; - -template<typename T> struct HashTraits; -template<> struct HashTraits<JSC::PropertyCondition> : SimpleClassHashTraits<JSC::PropertyCondition> { }; - -} // namespace WTF - -#endif // PropertyCondition_h - |
