summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/bytecode/PropertyCondition.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/bytecode/PropertyCondition.h')
-rw-r--r--Source/JavaScriptCore/bytecode/PropertyCondition.h338
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
-