1/*
2 * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "VM.h"
29#include "JSGlobalObject.h"
30#include "ObjectPrototype.h"
31#include "SlotVisitor.h"
32#include "WriteBarrier.h"
33
34namespace JSC {
35
36class FunctionRareData;
37
38template<typename Derived>
39class ObjectAllocationProfileBase {
40 friend class LLIntOffsetsExtractor;
41public:
42 static ptrdiff_t offsetOfAllocator() { return OBJECT_OFFSETOF(ObjectAllocationProfileBase, m_allocator); }
43 static ptrdiff_t offsetOfStructure() { return OBJECT_OFFSETOF(ObjectAllocationProfileBase, m_structure); }
44
45 ObjectAllocationProfileBase() = default;
46
47 bool isNull() { return !m_structure; }
48
49 void initializeProfile(VM&, JSGlobalObject*, JSCell* owner, JSObject* prototype, unsigned inferredInlineCapacity, JSFunction* constructor = nullptr, FunctionRareData* = nullptr);
50
51 Structure* structure()
52 {
53 Structure* structure = m_structure.get();
54 // Ensure that if we see the structure, it has been properly created
55 WTF::loadLoadFence();
56 return structure;
57 }
58
59protected:
60 void clear()
61 {
62 m_allocator = Allocator();
63 m_structure.clear();
64 ASSERT(isNull());
65 }
66
67 void visitAggregate(SlotVisitor& visitor)
68 {
69 visitor.append(m_structure);
70 }
71
72private:
73 unsigned possibleDefaultPropertyCount(VM&, JSObject* prototype);
74
75 Allocator m_allocator; // Precomputed to make things easier for generated code.
76 WriteBarrier<Structure> m_structure;
77};
78
79class ObjectAllocationProfile : public ObjectAllocationProfileBase<ObjectAllocationProfile> {
80public:
81 using Base = ObjectAllocationProfileBase<ObjectAllocationProfile>;
82
83 ObjectAllocationProfile() = default;
84
85 using Base::clear;
86 using Base::visitAggregate;
87
88 void setPrototype(VM&, JSCell*, JSObject*) { }
89};
90
91class ObjectAllocationProfileWithPrototype : public ObjectAllocationProfileBase<ObjectAllocationProfileWithPrototype> {
92public:
93 using Base = ObjectAllocationProfileBase<ObjectAllocationProfileWithPrototype>;
94
95 ObjectAllocationProfileWithPrototype() = default;
96
97 JSObject* prototype()
98 {
99 JSObject* prototype = m_prototype.get();
100 WTF::loadLoadFence();
101 return prototype;
102 }
103
104 void clear()
105 {
106 Base::clear();
107 m_prototype.clear();
108 ASSERT(isNull());
109 }
110
111 void visitAggregate(SlotVisitor& visitor)
112 {
113 Base::visitAggregate(visitor);
114 visitor.append(m_prototype);
115 }
116
117 void setPrototype(VM& vm, JSCell* owner, JSObject* object)
118 {
119 m_prototype.set(vm, owner, object);
120 }
121
122private:
123 WriteBarrier<JSObject> m_prototype;
124};
125
126
127
128} // namespace JSC
129