]>
git.saurik.com Git - apple/javascriptcore.git/blob - runtime/IntendedStructureChain.cpp
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
, Structure
* head
)
37 : m_globalObject(globalObject
)
40 JSValue prototype
= head
->prototypeForLookup(globalObject
);
41 if (prototype
.isNull())
43 for (Structure
* current
= asObject(prototype
)->structure(); current
; current
= current
->storedPrototypeStructure())
44 m_vector
.append(current
);
47 IntendedStructureChain::IntendedStructureChain(CodeBlock
* codeBlock
, Structure
* head
, Structure
* prototypeStructure
)
48 : m_globalObject(codeBlock
->globalObject())
51 m_vector
.append(prototypeStructure
);
54 IntendedStructureChain::IntendedStructureChain(CodeBlock
* codeBlock
, Structure
* head
, StructureChain
* chain
)
55 : m_globalObject(codeBlock
->globalObject())
58 for (unsigned i
= 0; chain
->head()[i
]; ++i
)
59 m_vector
.append(chain
->head()[i
].get());
62 IntendedStructureChain::IntendedStructureChain(CodeBlock
* codeBlock
, Structure
* head
, StructureChain
* chain
, unsigned count
)
63 : m_globalObject(codeBlock
->globalObject())
66 for (unsigned i
= 0; i
< count
; ++i
)
67 m_vector
.append(chain
->head()[i
].get());
70 IntendedStructureChain::~IntendedStructureChain()
74 bool IntendedStructureChain::isStillValid() const
76 JSValue currentPrototype
= m_head
->prototypeForLookup(m_globalObject
);
77 for (unsigned i
= 0; i
< m_vector
.size(); ++i
) {
78 if (asObject(currentPrototype
)->structure() != m_vector
[i
])
80 currentPrototype
= m_vector
[i
]->storedPrototype();
85 bool IntendedStructureChain::matches(StructureChain
* chain
) const
87 for (unsigned i
= 0; i
< m_vector
.size(); ++i
) {
88 if (m_vector
[i
] != chain
->head()[i
].get())
91 if (chain
->head()[m_vector
.size()])
96 StructureChain
* IntendedStructureChain::chain(VM
& vm
) const
98 ASSERT(isStillValid());
99 StructureChain
* result
= StructureChain::create(vm
, m_head
);
100 ASSERT(matches(result
));
104 bool IntendedStructureChain::mayInterceptStoreTo(VM
& vm
, StringImpl
* uid
)
106 for (unsigned i
= 0; i
< m_vector
.size(); ++i
) {
108 JSCell
* specificValue
;
109 PropertyOffset offset
= m_vector
[i
]->getConcurrently(vm
, uid
, attributes
, specificValue
);
110 if (!isValidOffset(offset
))
112 if (attributes
& (ReadOnly
| Accessor
))
119 bool IntendedStructureChain::isNormalized()
121 if (m_head
->isProxy())
123 for (unsigned i
= 0; i
< m_vector
.size(); ++i
) {
124 Structure
* structure
= m_vector
[i
];
125 if (structure
->isProxy())
127 if (structure
->isDictionary())
133 JSObject
* IntendedStructureChain::terminalPrototype() const
135 ASSERT(!m_vector
.isEmpty());
136 if (m_vector
.size() == 1)
137 return asObject(m_head
->prototypeForLookup(m_globalObject
));
138 return asObject(m_vector
[m_vector
.size() - 2]->storedPrototype());
141 void IntendedStructureChain::visitChildren(SlotVisitor
& visitor
)
143 visitor
.appendUnbarrieredPointer(&m_globalObject
);
144 visitor
.appendUnbarrieredPointer(&m_head
);
145 for (unsigned i
= m_vector
.size(); i
--;)
146 visitor
.appendUnbarrieredPointer(&m_vector
[i
]);
149 void IntendedStructureChain::dump(PrintStream
& out
) const
151 dumpInContext(out
, 0);
154 void IntendedStructureChain::dumpInContext(PrintStream
& out
, DumpContext
* context
) const
157 "(global = ", RawPointer(m_globalObject
), ", head = ",
158 pointerDumpInContext(m_head
, context
), ", vector = [");
160 for (unsigned i
= 0; i
< m_vector
.size(); ++i
)
161 out
.print(comma
, pointerDumpInContext(m_vector
[i
], context
));