Bug 1842773 - Part 32: Allow constructing growable SharedArrayBuffers. r=sfink
[gecko.git] / js / src / vm / GetterSetter.h
blobd1e2fe4fc77a0341aa0be67218b4e5fc5ce25c7a
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
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/. */
7 #ifndef vm_GetterSetter_h
8 #define vm_GetterSetter_h
10 #include "gc/Barrier.h" // js::GCPtr<JSObject*>
11 #include "gc/Cell.h" // js::gc::TenuredCellWithGCPointer
13 #include "js/TypeDecls.h" // JS::HandleObject
14 #include "js/UbiNode.h" // JS::ubi::TracerConcrete
16 namespace js {
18 // [SMDOC] Getter/Setter Properties
20 // Getter/setter properties are implemented similar to plain data properties:
21 // the shape contains the property's key, attributes, and slot number, but the
22 // getter/setter objects are stored separately as part of the object.
24 // To simplify the NativeObject and Shape code, a single slot is allocated for
25 // each getter/setter property (again similar to data properties). This slot
26 // contains a PrivateGCThingValue pointing to a js::GetterSetter instance.
28 // js::GetterSetter
29 // ================
30 // js::GetterSetter is an immutable type that stores the getter/setter objects.
31 // Because accessor properties can be defined with only a getter or only a
32 // setter, a GetterSetter's objects can be nullptr.
34 // JIT/IC Guards
35 // =============
36 // An object's shape implies a certain property is an accessor, but it does not
37 // imply the identity of the getter/setter objects. This means IC code needs to
38 // guard on the slot value (the GetterSetter*) when optimizing a call to a
39 // particular getter/setter function.
41 // See EmitGuardGetterSetterSlot in jit/CacheIR.cpp.
43 // HadGetterSetterChange Optimization
44 // ==================================
45 // Some getters and setters defined on the prototype chain are very hot, for
46 // example the 'length' getter for typed arrays. To avoid the GetterSetter guard
47 // in the common case, when attaching a stub for a known 'holder' object, we
48 // use the HadGetterSetterChange object flag.
50 // When this flag is not set, the object is guaranteed to get a different shape
51 // when an accessor property is either deleted or mutated, because when that
52 // happens the HadGetterSetterChange will be set which triggers a shape change.
54 // This means CacheIR does not have to guard on the GetterSetter slot for
55 // accessors on the prototype chain until the first time an accessor property is
56 // mutated or deleted.
57 class GetterSetter : public gc::TenuredCellWithGCPointer<JSObject> {
58 friend class gc::CellAllocator;
60 public:
61 // Getter object, stored in the cell header.
62 JSObject* getter() const { return headerPtr(); }
64 GCPtr<JSObject*> setter_;
66 #ifndef JS_64BIT
67 // Ensure size >= MinCellSize on 32-bit platforms.
68 uint64_t padding_ = 0;
69 #endif
71 private:
72 GetterSetter(HandleObject getter, HandleObject setter);
74 public:
75 static GetterSetter* create(JSContext* cx, HandleObject getter,
76 HandleObject setter);
78 JSObject* setter() const { return setter_; }
80 static const JS::TraceKind TraceKind = JS::TraceKind::GetterSetter;
82 void traceChildren(JSTracer* trc);
84 void finalize(JS::GCContext* gcx) {
85 // Nothing to do.
89 } // namespace js
91 // JS::ubi::Nodes can point to GetterSetters; they're js::gc::Cell instances
92 // with no associated compartment.
93 namespace JS {
94 namespace ubi {
96 template <>
97 class Concrete<js::GetterSetter> : TracerConcrete<js::GetterSetter> {
98 protected:
99 explicit Concrete(js::GetterSetter* ptr)
100 : TracerConcrete<js::GetterSetter>(ptr) {}
102 public:
103 static void construct(void* storage, js::GetterSetter* ptr) {
104 new (storage) Concrete(ptr);
107 Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
109 const char16_t* typeName() const override { return concreteTypeName; }
110 static const char16_t concreteTypeName[];
113 } // namespace ubi
114 } // namespace JS
116 #endif // vm_GetterSetter_h