-
Notifications
You must be signed in to change notification settings - Fork 54
/
ShapedObject.h
80 lines (66 loc) · 2.56 KB
/
ShapedObject.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* 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_ShapedObject_h
#define vm_ShapedObject_h
#include "vm/JSObject.h"
namespace js {
namespace jit {
class CacheIRCompiler;
}
/*
* Shaped objects are a variant of JSObject that use a GCPtrShape for their
* |shapeOrExpando_| field. All objects that point to a js::Shape as their
* |shapeOrExpando_| field should use this as their subclass.
*
* NOTE: shape()->getObjectClass() must equal getClass().
*/
class ShapedObject : public JSObject {
protected:
// ShapedObjects treat the |shapeOrExpando_| field as a GCPtrShape to
// ensure barriers are called. Use these instead of accessing
// |shapeOrExpando_| directly.
MOZ_ALWAYS_INLINE const GCPtrShape& shapeRef() const {
return *reinterpret_cast<const GCPtrShape*>(&(this->shapeOrExpando_));
}
MOZ_ALWAYS_INLINE GCPtrShape& shapeRef() {
return *reinterpret_cast<GCPtrShape*>(&(this->shapeOrExpando_));
}
// Used for GC tracing and Shape::listp
MOZ_ALWAYS_INLINE GCPtrShape* shapePtr() {
return reinterpret_cast<GCPtrShape*>(&(this->shapeOrExpando_));
}
public:
// Set the shape of an object. This pointer is valid for native objects and
// some non-native objects. After creating an object, the objects for which
// the shape pointer is invalid need to overwrite this pointer before a GC
// can occur.
void initShape(Shape* shape) {
// Note: JSObject::zone() uses the group and we require it to be
// initialized before the shape.
MOZ_ASSERT(zone() == shape->zone());
shapeRef().init(shape);
}
void setShape(Shape* shape) {
MOZ_ASSERT(zone() == shape->zone());
shapeRef() = shape;
}
Shape* shape() const { return shapeRef(); }
void traceShape(JSTracer* trc) { TraceEdge(trc, shapePtr(), "shape"); }
static JSObject* fromShapeFieldPointer(uintptr_t p) {
return reinterpret_cast<JSObject*>(p - ShapedObject::offsetOfShape());
}
private:
// See JSObject::offsetOfGroup() comment.
friend class js::jit::MacroAssembler;
friend class js::jit::CacheIRCompiler;
static constexpr size_t offsetOfShape() {
static_assert(offsetOfShapeOrExpando() == offsetof(shadow::Object, shape),
"shadow shape must match actual shape");
return offsetOfShapeOrExpando();
}
};
} // namespace js
#endif /* vm_ShapedObject_h */