summaryrefslogtreecommitdiffstats
path: root/js/src/vm/ReceiverGuard.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/vm/ReceiverGuard.h')
-rw-r--r--js/src/vm/ReceiverGuard.h137
1 files changed, 137 insertions, 0 deletions
diff --git a/js/src/vm/ReceiverGuard.h b/js/src/vm/ReceiverGuard.h
new file mode 100644
index 000000000..459cc0012
--- /dev/null
+++ b/js/src/vm/ReceiverGuard.h
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim: set ts=8 sts=4 et sw=4 tw=99:
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef vm_ReceiverGuard_h
+#define vm_ReceiverGuard_h
+
+#include "vm/Shape.h"
+
+namespace js {
+
+// A ReceiverGuard encapsulates the information about an object that needs to
+// be tested to determine if it has the same 'structure' as another object.
+// The guard includes the shape and/or group of the object, and which of these
+// is tested, as well as the meaning here of 'structure', depends on the kind
+// of object being tested:
+//
+// NativeObject: The structure of a native object is determined by its shape.
+// Two objects with the same shape have the same class, prototype, flags,
+// and all properties except those stored in dense elements.
+//
+// ProxyObject: The structure of a proxy object is determined by its shape.
+// Proxies with the same shape have the same class and prototype, but no
+// other commonality is guaranteed.
+//
+// TypedObject: The structure of a typed object is determined by its group.
+// All typed objects with the same group have the same class, prototype, and
+// own properties.
+//
+// UnboxedPlainObject: The structure of an unboxed plain object is determined
+// by its group and its expando object's shape, if there is one. All unboxed
+// plain objects with the same group and expando shape have the same
+// properties except those stored in the expando's dense elements.
+
+class HeapReceiverGuard;
+class RootedReceiverGuard;
+
+class ReceiverGuard
+{
+ public:
+ ObjectGroup* group;
+ Shape* shape;
+
+ ReceiverGuard()
+ : group(nullptr), shape(nullptr)
+ {}
+
+ inline MOZ_IMPLICIT ReceiverGuard(const HeapReceiverGuard& guard);
+ inline MOZ_IMPLICIT ReceiverGuard(const RootedReceiverGuard& guard);
+
+ explicit ReceiverGuard(JSObject* obj);
+ ReceiverGuard(ObjectGroup* group, Shape* shape);
+
+ bool operator ==(const ReceiverGuard& other) const {
+ return group == other.group && shape == other.shape;
+ }
+
+ bool operator !=(const ReceiverGuard& other) const {
+ return !(*this == other);
+ }
+
+ uintptr_t hash() const {
+ return (uintptr_t(group) >> 3) ^ (uintptr_t(shape) >> 3);
+ }
+};
+
+class HeapReceiverGuard
+{
+ GCPtrObjectGroup group_;
+ GCPtrShape shape_;
+
+ public:
+ explicit HeapReceiverGuard(const ReceiverGuard& guard)
+ : group_(guard.group), shape_(guard.shape)
+ {}
+
+ bool matches(const ReceiverGuard& guard) {
+ return group_ == guard.group && shape_ == guard.shape;
+ }
+
+ void update(const ReceiverGuard& other) {
+ group_ = other.group;
+ shape_ = other.shape;
+ }
+
+ void init(const ReceiverGuard& other) {
+ group_.init(other.group);
+ shape_.init(other.shape);
+ }
+
+ void trace(JSTracer* trc);
+
+ Shape* shape() const {
+ return shape_;
+ }
+ ObjectGroup* group() const {
+ return group_;
+ }
+
+ static size_t offsetOfShape() {
+ return offsetof(HeapReceiverGuard, shape_);
+ }
+ static size_t offsetOfGroup() {
+ return offsetof(HeapReceiverGuard, group_);
+ }
+
+ // Bits to munge into Baseline IC compiler keys when that IC has a
+ // HeapReceiverGuard. This uses at most two bits for data.
+ static int32_t keyBits(JSObject* obj);
+};
+
+class RootedReceiverGuard
+{
+ public:
+ RootedObjectGroup group;
+ RootedShape shape;
+
+ RootedReceiverGuard(JSContext* cx, const ReceiverGuard& guard)
+ : group(cx, guard.group), shape(cx, guard.shape)
+ {}
+};
+
+inline
+ReceiverGuard::ReceiverGuard(const HeapReceiverGuard& guard)
+ : group(guard.group()), shape(guard.shape())
+{}
+
+inline
+ReceiverGuard::ReceiverGuard(const RootedReceiverGuard& guard)
+ : group(guard.group), shape(guard.shape)
+{}
+
+} // namespace js
+
+#endif /* vm_ReceiverGuard_h */