2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "IntendedStructureChain.h"
29 #include "CodeBlock.h"
30 #include "JSCInlines.h"
31 #include "StructureChain.h"
32 #include <wtf/CommaPrinter.h>
36 IntendedStructureChain::IntendedStructureChain(JSGlobalObject
* globalObject
, JSValue prototype
)
37 : m_globalObject(globalObject
)
38 , m_prototype(prototype
)
40 ASSERT(m_prototype
.isNull() || m_prototype
.isObject());
41 if (prototype
.isNull())
43 for (Structure
* current
= asObject(prototype
)->structure(); current
; current
= current
->storedPrototypeStructure())
44 m_vector
.append(current
);
47 IntendedStructureChain::IntendedStructureChain(JSGlobalObject
* globalObject
, Structure
* head
)
48 : m_globalObject(globalObject
)
49 , m_prototype(head
->prototypeForLookup(m_globalObject
))
51 if (m_prototype
.isNull())
53 for (Structure
* current
= asObject(m_prototype
)->structure(); current
; current
= current
->storedPrototypeStructure())
54 m_vector
.append(current
);
57 IntendedStructureChain::IntendedStructureChain(CodeBlock
* codeBlock
, Structure
* head
, Structure
* prototypeStructure
)
58 : m_globalObject(codeBlock
->globalObject())
59 , m_prototype(head
->prototypeForLookup(m_globalObject
))
61 m_vector
.append(prototypeStructure
);
64 IntendedStructureChain::IntendedStructureChain(CodeBlock
* codeBlock
, Structure
* head
, StructureChain
* chain
)
65 : m_globalObject(codeBlock
->globalObject())
66 , m_prototype(head
->prototypeForLookup(m_globalObject
))
68 for (unsigned i
= 0; chain
->head()[i
]; ++i
)
69 m_vector
.append(chain
->head()[i
].get());
72 IntendedStructureChain::IntendedStructureChain(CodeBlock
* codeBlock
, Structure
* head
, StructureChain
* chain
, unsigned count
)
73 : m_globalObject(codeBlock
->globalObject())
74 , m_prototype(head
->prototypeForLookup(m_globalObject
))
76 for (unsigned i
= 0; i
< count
; ++i
)
77 m_vector
.append(chain
->head()[i
].get());
80 IntendedStructureChain::~IntendedStructureChain()
84 bool IntendedStructureChain::isStillValid() const
86 JSValue currentPrototype
= m_prototype
;
87 for (unsigned i
= 0; i
< m_vector
.size(); ++i
) {
88 if (asObject(currentPrototype
)->structure() != m_vector
[i
])
90 currentPrototype
= m_vector
[i
]->storedPrototype();
95 bool IntendedStructureChain::matches(StructureChain
* chain
) const
97 for (unsigned i
= 0; i
< m_vector
.size(); ++i
) {
98 if (m_vector
[i
] != chain
->head()[i
].get())
101 if (chain
->head()[m_vector
.size()])
106 bool IntendedStructureChain::mayInterceptStoreTo(UniquedStringImpl
* uid
)
108 for (unsigned i
= 0; i
< m_vector
.size(); ++i
) {
110 PropertyOffset offset
= m_vector
[i
]->getConcurrently(uid
, attributes
);
111 if (!isValidOffset(offset
))
113 if (attributes
& (ReadOnly
| Accessor
))
120 bool IntendedStructureChain::isNormalized()
122 for (unsigned i
= 0; i
< m_vector
.size(); ++i
) {
123 Structure
* structure
= m_vector
[i
];
124 if (structure
->isProxy())
126 if (structure
->isDictionary())
132 bool IntendedStructureChain::takesSlowPathInDFGForImpureProperty()
134 for (size_t i
= 0; i
< size(); ++i
) {
135 if (at(i
)->takesSlowPathInDFGForImpureProperty())
141 JSObject
* IntendedStructureChain::terminalPrototype() const
143 ASSERT(!m_vector
.isEmpty());
144 if (m_vector
.size() == 1)
145 return asObject(m_prototype
);
146 return asObject(m_vector
[m_vector
.size() - 2]->storedPrototype());
149 bool IntendedStructureChain::operator==(const IntendedStructureChain
& other
) const
151 return m_globalObject
== other
.m_globalObject
152 && m_prototype
== other
.m_prototype
153 && m_vector
== other
.m_vector
;
156 void IntendedStructureChain::gatherChecks(ConstantStructureCheckVector
& vector
) const
158 JSValue currentPrototype
= m_prototype
;
159 for (unsigned i
= 0; i
< size(); ++i
) {
160 JSObject
* currentObject
= asObject(currentPrototype
);
161 Structure
* currentStructure
= at(i
);
162 vector
.append(ConstantStructureCheck(currentObject
, currentStructure
));
163 currentPrototype
= currentStructure
->prototypeForLookup(m_globalObject
);
167 void IntendedStructureChain::visitChildren(SlotVisitor
& visitor
)
169 visitor
.appendUnbarrieredPointer(&m_globalObject
);
170 visitor
.appendUnbarrieredValue(&m_prototype
);
171 for (unsigned i
= m_vector
.size(); i
--;)
172 visitor
.appendUnbarrieredPointer(&m_vector
[i
]);
175 void IntendedStructureChain::dump(PrintStream
& out
) const
177 dumpInContext(out
, 0);
180 void IntendedStructureChain::dumpInContext(PrintStream
& out
, DumpContext
* context
) const
183 "(global = ", RawPointer(m_globalObject
), ", head = ",
184 inContext(m_prototype
, context
), ", vector = [");
186 for (unsigned i
= 0; i
< m_vector
.size(); ++i
)
187 out
.print(comma
, pointerDumpInContext(m_vector
[i
], context
));