]> git.saurik.com Git - apple/javascriptcore.git/blob - bytecode/PolymorphicPutByIdList.cpp
JavaScriptCore-7600.1.4.13.1.tar.gz
[apple/javascriptcore.git] / bytecode / PolymorphicPutByIdList.cpp
1 /*
2 * Copyright (C) 2012, 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 "PolymorphicPutByIdList.h"
28
29 #if ENABLE(JIT)
30
31 #include "StructureStubInfo.h"
32
33 namespace JSC {
34
35 PutByIdAccess PutByIdAccess::fromStructureStubInfo(StructureStubInfo& stubInfo)
36 {
37 MacroAssemblerCodePtr initialSlowPath =
38 stubInfo.callReturnLocation.labelAtOffset(stubInfo.patch.deltaCallToSlowCase);
39
40 PutByIdAccess result;
41
42 switch (stubInfo.accessType) {
43 case access_put_by_id_replace:
44 result.m_type = Replace;
45 result.m_oldStructure.copyFrom(stubInfo.u.putByIdReplace.baseObjectStructure);
46 result.m_stubRoutine = JITStubRoutine::createSelfManagedRoutine(initialSlowPath);
47 break;
48
49 case access_put_by_id_transition_direct:
50 case access_put_by_id_transition_normal:
51 result.m_type = Transition;
52 result.m_oldStructure.copyFrom(stubInfo.u.putByIdTransition.previousStructure);
53 result.m_newStructure.copyFrom(stubInfo.u.putByIdTransition.structure);
54 result.m_chain.copyFrom(stubInfo.u.putByIdTransition.chain);
55 result.m_stubRoutine = stubInfo.stubRoutine;
56 break;
57
58 default:
59 RELEASE_ASSERT_NOT_REACHED();
60 }
61
62 return result;
63 }
64
65 bool PutByIdAccess::visitWeak(RepatchBuffer& repatchBuffer) const
66 {
67 switch (m_type) {
68 case Replace:
69 if (!Heap::isMarked(m_oldStructure.get()))
70 return false;
71 break;
72 case Transition:
73 if (!Heap::isMarked(m_oldStructure.get()))
74 return false;
75 if (!Heap::isMarked(m_newStructure.get()))
76 return false;
77 if (!Heap::isMarked(m_chain.get()))
78 return false;
79 break;
80 case Setter:
81 case CustomSetter:
82 if (!Heap::isMarked(m_oldStructure.get()))
83 return false;
84 if (m_chain && !Heap::isMarked(m_chain.get()))
85 return false;
86 break;
87 default:
88 RELEASE_ASSERT_NOT_REACHED();
89 return false;
90 }
91 if (!m_stubRoutine->visitWeak(repatchBuffer))
92 return false;
93 return true;
94 }
95
96 PolymorphicPutByIdList::PolymorphicPutByIdList(
97 PutKind putKind, StructureStubInfo& stubInfo)
98 : m_kind(putKind)
99 {
100 if (stubInfo.accessType != access_unset)
101 m_list.append(PutByIdAccess::fromStructureStubInfo(stubInfo));
102 }
103
104 PolymorphicPutByIdList* PolymorphicPutByIdList::from(
105 PutKind putKind, StructureStubInfo& stubInfo)
106 {
107 if (stubInfo.accessType == access_put_by_id_list)
108 return stubInfo.u.putByIdList.list;
109
110 ASSERT(stubInfo.accessType == access_put_by_id_replace
111 || stubInfo.accessType == access_put_by_id_transition_normal
112 || stubInfo.accessType == access_put_by_id_transition_direct
113 || stubInfo.accessType == access_unset);
114
115 PolymorphicPutByIdList* result =
116 new PolymorphicPutByIdList(putKind, stubInfo);
117
118 stubInfo.initPutByIdList(result);
119
120 return result;
121 }
122
123 PolymorphicPutByIdList::~PolymorphicPutByIdList() { }
124
125 bool PolymorphicPutByIdList::isFull() const
126 {
127 ASSERT(size() <= POLYMORPHIC_LIST_CACHE_SIZE);
128 return size() == POLYMORPHIC_LIST_CACHE_SIZE;
129 }
130
131 bool PolymorphicPutByIdList::isAlmostFull() const
132 {
133 ASSERT(size() <= POLYMORPHIC_LIST_CACHE_SIZE);
134 return size() >= POLYMORPHIC_LIST_CACHE_SIZE - 1;
135 }
136
137 void PolymorphicPutByIdList::addAccess(const PutByIdAccess& putByIdAccess)
138 {
139 ASSERT(!isFull());
140 // Make sure that the resizing optimizes for space, not time.
141 m_list.resize(m_list.size() + 1);
142 m_list.last() = putByIdAccess;
143 }
144
145 bool PolymorphicPutByIdList::visitWeak(RepatchBuffer& repatchBuffer) const
146 {
147 for (unsigned i = 0; i < size(); ++i) {
148 if (!at(i).visitWeak(repatchBuffer))
149 return false;
150 }
151 return true;
152 }
153
154 } // namespace JSC
155
156 #endif // ENABLE(JIT)