]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/IntendedStructureChain.cpp
JavaScriptCore-7600.1.4.16.1.tar.gz
[apple/javascriptcore.git] / runtime / IntendedStructureChain.cpp
1 /*
2 * Copyright (C) 2013, 2014 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 #include "config.h"
27 #include "IntendedStructureChain.h"
28
29 #include "CodeBlock.h"
30 #include "JSCInlines.h"
31 #include "StructureChain.h"
32 #include <wtf/CommaPrinter.h>
33
34 namespace JSC {
35
36 IntendedStructureChain::IntendedStructureChain(JSGlobalObject* globalObject, Structure* head)
37 : m_globalObject(globalObject)
38 , m_head(head)
39 {
40 JSValue prototype = head->prototypeForLookup(globalObject);
41 if (prototype.isNull())
42 return;
43 for (Structure* current = asObject(prototype)->structure(); current; current = current->storedPrototypeStructure())
44 m_vector.append(current);
45 }
46
47 IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure* head, Structure* prototypeStructure)
48 : m_globalObject(codeBlock->globalObject())
49 , m_head(head)
50 {
51 m_vector.append(prototypeStructure);
52 }
53
54 IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain)
55 : m_globalObject(codeBlock->globalObject())
56 , m_head(head)
57 {
58 for (unsigned i = 0; chain->head()[i]; ++i)
59 m_vector.append(chain->head()[i].get());
60 }
61
62 IntendedStructureChain::IntendedStructureChain(CodeBlock* codeBlock, Structure* head, StructureChain* chain, unsigned count)
63 : m_globalObject(codeBlock->globalObject())
64 , m_head(head)
65 {
66 for (unsigned i = 0; i < count; ++i)
67 m_vector.append(chain->head()[i].get());
68 }
69
70 IntendedStructureChain::~IntendedStructureChain()
71 {
72 }
73
74 bool IntendedStructureChain::isStillValid() const
75 {
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])
79 return false;
80 currentPrototype = m_vector[i]->storedPrototype();
81 }
82 return true;
83 }
84
85 bool IntendedStructureChain::matches(StructureChain* chain) const
86 {
87 for (unsigned i = 0; i < m_vector.size(); ++i) {
88 if (m_vector[i] != chain->head()[i].get())
89 return false;
90 }
91 if (chain->head()[m_vector.size()])
92 return false;
93 return true;
94 }
95
96 StructureChain* IntendedStructureChain::chain(VM& vm) const
97 {
98 ASSERT(isStillValid());
99 StructureChain* result = StructureChain::create(vm, m_head);
100 ASSERT(matches(result));
101 return result;
102 }
103
104 bool IntendedStructureChain::mayInterceptStoreTo(VM& vm, StringImpl* uid)
105 {
106 for (unsigned i = 0; i < m_vector.size(); ++i) {
107 unsigned attributes;
108 JSCell* specificValue;
109 PropertyOffset offset = m_vector[i]->getConcurrently(vm, uid, attributes, specificValue);
110 if (!isValidOffset(offset))
111 continue;
112 if (attributes & (ReadOnly | Accessor))
113 return true;
114 return false;
115 }
116 return false;
117 }
118
119 bool IntendedStructureChain::isNormalized()
120 {
121 if (m_head->isProxy())
122 return false;
123 for (unsigned i = 0; i < m_vector.size(); ++i) {
124 Structure* structure = m_vector[i];
125 if (structure->isProxy())
126 return false;
127 if (structure->isDictionary())
128 return false;
129 }
130 return true;
131 }
132
133 JSObject* IntendedStructureChain::terminalPrototype() const
134 {
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());
139 }
140
141 void IntendedStructureChain::visitChildren(SlotVisitor& visitor)
142 {
143 visitor.appendUnbarrieredPointer(&m_globalObject);
144 visitor.appendUnbarrieredPointer(&m_head);
145 for (unsigned i = m_vector.size(); i--;)
146 visitor.appendUnbarrieredPointer(&m_vector[i]);
147 }
148
149 void IntendedStructureChain::dump(PrintStream& out) const
150 {
151 dumpInContext(out, 0);
152 }
153
154 void IntendedStructureChain::dumpInContext(PrintStream& out, DumpContext* context) const
155 {
156 out.print(
157 "(global = ", RawPointer(m_globalObject), ", head = ",
158 pointerDumpInContext(m_head, context), ", vector = [");
159 CommaPrinter comma;
160 for (unsigned i = 0; i < m_vector.size(); ++i)
161 out.print(comma, pointerDumpInContext(m_vector[i], context));
162 out.print("])");
163 }
164
165 } // namespace JSC
166