Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef vm_ReceiverGuard_h
8 : #define vm_ReceiverGuard_h
9 :
10 : #include "vm/Shape.h"
11 :
12 : namespace js {
13 :
14 : // A ReceiverGuard encapsulates the information about an object that needs to
15 : // be tested to determine if it has the same 'structure' as another object.
16 : // The guard includes the shape and/or group of the object, and which of these
17 : // is tested, as well as the meaning here of 'structure', depends on the kind
18 : // of object being tested:
19 : //
20 : // NativeObject: The structure of a native object is determined by its shape.
21 : // Two objects with the same shape have the same class, prototype, flags,
22 : // and all properties except those stored in dense elements.
23 : //
24 : // ProxyObject: The structure of a proxy object is determined by its shape.
25 : // Proxies with the same shape have the same class and prototype, but no
26 : // other commonality is guaranteed.
27 : //
28 : // TypedObject: The structure of a typed object is determined by its group.
29 : // All typed objects with the same group have the same class, prototype, and
30 : // own properties.
31 : //
32 : // UnboxedPlainObject: The structure of an unboxed plain object is determined
33 : // by its group and its expando object's shape, if there is one. All unboxed
34 : // plain objects with the same group and expando shape have the same
35 : // properties except those stored in the expando's dense elements.
36 :
37 : class HeapReceiverGuard;
38 :
39 : class ReceiverGuard
40 : {
41 : public:
42 : ObjectGroup* group;
43 : Shape* shape;
44 :
45 165 : ReceiverGuard()
46 165 : : group(nullptr), shape(nullptr)
47 165 : {}
48 :
49 : inline MOZ_IMPLICIT ReceiverGuard(const HeapReceiverGuard& guard);
50 :
51 : explicit MOZ_ALWAYS_INLINE ReceiverGuard(JSObject* obj);
52 : MOZ_ALWAYS_INLINE ReceiverGuard(ObjectGroup* group, Shape* shape);
53 :
54 131 : bool operator ==(const ReceiverGuard& other) const {
55 131 : return group == other.group && shape == other.shape;
56 : }
57 :
58 64 : bool operator !=(const ReceiverGuard& other) const {
59 64 : return !(*this == other);
60 : }
61 :
62 184 : uintptr_t hash() const {
63 184 : return (uintptr_t(group) >> 3) ^ (uintptr_t(shape) >> 3);
64 : }
65 : };
66 :
67 : class HeapReceiverGuard
68 : {
69 : GCPtrObjectGroup group_;
70 : GCPtrShape shape_;
71 :
72 : public:
73 : explicit HeapReceiverGuard(const ReceiverGuard& guard)
74 : : group_(guard.group), shape_(guard.shape)
75 : {}
76 :
77 117 : void init(const ReceiverGuard& other) {
78 117 : group_.init(other.group);
79 117 : shape_.init(other.shape);
80 117 : }
81 :
82 : void trace(JSTracer* trc);
83 :
84 67 : Shape* shape() const {
85 67 : return shape_;
86 : }
87 67 : ObjectGroup* group() const {
88 67 : return group_;
89 : }
90 : };
91 :
92 : inline
93 67 : ReceiverGuard::ReceiverGuard(const HeapReceiverGuard& guard)
94 67 : : group(guard.group()), shape(guard.shape())
95 67 : {}
96 :
97 : } // namespace js
98 :
99 : #endif /* vm_ReceiverGuard_h */
|