Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Side by Side Diff: src/virtual-frame-heavy.cc

Issue 1164002: Split the virtual frame into heavy and light versions.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/virtual-frame.cc ('k') | src/virtual-frame-heavy-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include "v8.h"
29
30 #include "codegen-inl.h"
31 #include "register-allocator-inl.h"
32 #include "virtual-frame-inl.h"
33
34 namespace v8 {
35 namespace internal {
36
37 void VirtualFrame::SetElementAt(int index, Result* value) {
38 int frame_index = element_count() - index - 1;
39 ASSERT(frame_index >= 0);
40 ASSERT(frame_index < element_count());
41 ASSERT(value->is_valid());
42 FrameElement original = elements_[frame_index];
43
44 // Early exit if the element is the same as the one being set.
45 bool same_register = original.is_register()
46 && value->is_register()
47 && original.reg().is(value->reg());
48 bool same_constant = original.is_constant()
49 && value->is_constant()
50 && original.handle().is_identical_to(value->handle());
51 if (same_register || same_constant) {
52 value->Unuse();
53 return;
54 }
55
56 InvalidateFrameSlotAt(frame_index);
57
58 if (value->is_register()) {
59 if (is_used(value->reg())) {
60 // The register already appears on the frame. Either the existing
61 // register element, or the new element at frame_index, must be made
62 // a copy.
63 int i = register_location(value->reg());
64
65 if (i < frame_index) {
66 // The register FrameElement is lower in the frame than the new copy.
67 elements_[frame_index] = CopyElementAt(i);
68 } else {
69 // There was an early bailout for the case of setting a
70 // register element to itself.
71 ASSERT(i != frame_index);
72 elements_[frame_index] = elements_[i];
73 elements_[i] = CopyElementAt(frame_index);
74 if (elements_[frame_index].is_synced()) {
75 elements_[i].set_sync();
76 }
77 elements_[frame_index].clear_sync();
78 set_register_location(value->reg(), frame_index);
79 for (int j = i + 1; j < element_count(); j++) {
80 if (elements_[j].is_copy() && elements_[j].index() == i) {
81 elements_[j].set_index(frame_index);
82 }
83 }
84 }
85 } else {
86 // The register value->reg() was not already used on the frame.
87 Use(value->reg(), frame_index);
88 elements_[frame_index] =
89 FrameElement::RegisterElement(value->reg(),
90 FrameElement::NOT_SYNCED,
91 value->number_info());
92 }
93 } else {
94 ASSERT(value->is_constant());
95 elements_[frame_index] =
96 FrameElement::ConstantElement(value->handle(),
97 FrameElement::NOT_SYNCED);
98 }
99 value->Unuse();
100 }
101
102
103 // Create a duplicate of an existing valid frame element.
104 // We can pass an optional number type information that will override the
105 // existing information about the backing element. The new information must
106 // not conflict with the existing type information and must be equally or
107 // more precise. The default parameter value kUninitialized means that there
108 // is no additional information.
109 FrameElement VirtualFrame::CopyElementAt(int index, NumberInfo info) {
110 ASSERT(index >= 0);
111 ASSERT(index < element_count());
112
113 FrameElement target = elements_[index];
114 FrameElement result;
115
116 switch (target.type()) {
117 case FrameElement::CONSTANT:
118 // We do not copy constants and instead return a fresh unsynced
119 // constant.
120 result = FrameElement::ConstantElement(target.handle(),
121 FrameElement::NOT_SYNCED);
122 break;
123
124 case FrameElement::COPY:
125 // We do not allow copies of copies, so we follow one link to
126 // the actual backing store of a copy before making a copy.
127 index = target.index();
128 ASSERT(elements_[index].is_memory() || elements_[index].is_register());
129 // Fall through.
130
131 case FrameElement::MEMORY: // Fall through.
132 case FrameElement::REGISTER: {
133 // All copies are backed by memory or register locations.
134 result.set_type(FrameElement::COPY);
135 result.clear_copied();
136 result.clear_sync();
137 result.set_index(index);
138 elements_[index].set_copied();
139 // Update backing element's number information.
140 NumberInfo existing = elements_[index].number_info();
141 ASSERT(!existing.IsUninitialized());
142 // Assert that the new type information (a) does not conflict with the
143 // existing one and (b) is equally or more precise.
144 ASSERT((info.ToInt() & existing.ToInt()) == existing.ToInt());
145 ASSERT((info.ToInt() | existing.ToInt()) == info.ToInt());
146
147 elements_[index].set_number_info(!info.IsUninitialized()
148 ? info
149 : existing);
150 break;
151 }
152 case FrameElement::INVALID:
153 // We should not try to copy invalid elements.
154 UNREACHABLE();
155 break;
156 }
157 return result;
158 }
159
160
161 // Modify the state of the virtual frame to match the actual frame by adding
162 // extra in-memory elements to the top of the virtual frame. The extra
163 // elements will be externally materialized on the actual frame (eg, by
164 // pushing an exception handler). No code is emitted.
165 void VirtualFrame::Adjust(int count) {
166 ASSERT(count >= 0);
167 ASSERT(stack_pointer_ == element_count() - 1);
168
169 for (int i = 0; i < count; i++) {
170 elements_.Add(FrameElement::MemoryElement(NumberInfo::Unknown()));
171 }
172 stack_pointer_ += count;
173 }
174
175
176 void VirtualFrame::ForgetElements(int count) {
177 ASSERT(count >= 0);
178 ASSERT(element_count() >= count);
179
180 for (int i = 0; i < count; i++) {
181 FrameElement last = elements_.RemoveLast();
182 if (last.is_register()) {
183 // A hack to properly count register references for the code
184 // generator's current frame and also for other frames. The
185 // same code appears in PrepareMergeTo.
186 if (cgen()->frame() == this) {
187 Unuse(last.reg());
188 } else {
189 set_register_location(last.reg(), kIllegalIndex);
190 }
191 }
192 }
193 }
194
195
196 // Make the type of the element at a given index be MEMORY.
197 void VirtualFrame::SpillElementAt(int index) {
198 if (!elements_[index].is_valid()) return;
199
200 SyncElementAt(index);
201 // Number type information is preserved.
202 // Copies get their number information from their backing element.
203 NumberInfo info;
204 if (!elements_[index].is_copy()) {
205 info = elements_[index].number_info();
206 } else {
207 info = elements_[elements_[index].index()].number_info();
208 }
209 // The element is now in memory. Its copied flag is preserved.
210 FrameElement new_element = FrameElement::MemoryElement(info);
211 if (elements_[index].is_copied()) {
212 new_element.set_copied();
213 }
214 if (elements_[index].is_untagged_int32()) {
215 new_element.set_untagged_int32(true);
216 }
217 if (elements_[index].is_register()) {
218 Unuse(elements_[index].reg());
219 }
220 elements_[index] = new_element;
221 }
222
223
224 // Clear the dirty bit for the element at a given index.
225 void VirtualFrame::SyncElementAt(int index) {
226 if (index <= stack_pointer_) {
227 if (!elements_[index].is_synced()) SyncElementBelowStackPointer(index);
228 } else if (index == stack_pointer_ + 1) {
229 SyncElementByPushing(index);
230 } else {
231 SyncRange(stack_pointer_ + 1, index);
232 }
233 }
234
235
236 void VirtualFrame::PrepareMergeTo(VirtualFrame* expected) {
237 // Perform state changes on this frame that will make merge to the
238 // expected frame simpler or else increase the likelihood that his
239 // frame will match another.
240 for (int i = 0; i < element_count(); i++) {
241 FrameElement source = elements_[i];
242 FrameElement target = expected->elements_[i];
243
244 if (!target.is_valid() ||
245 (target.is_memory() && !source.is_memory() && source.is_synced())) {
246 // No code needs to be generated to invalidate valid elements.
247 // No code needs to be generated to move values to memory if
248 // they are already synced. We perform those moves here, before
249 // merging.
250 if (source.is_register()) {
251 // If the frame is the code generator's current frame, we have
252 // to decrement both the frame-internal and global register
253 // counts.
254 if (cgen()->frame() == this) {
255 Unuse(source.reg());
256 } else {
257 set_register_location(source.reg(), kIllegalIndex);
258 }
259 }
260 elements_[i] = target;
261 } else if (target.is_register() && !target.is_synced() &&
262 !source.is_memory()) {
263 // If an element's target is a register that doesn't need to be
264 // synced, and the element is not in memory, then the sync state
265 // of the element is irrelevant. We clear the sync bit.
266 ASSERT(source.is_valid());
267 elements_[i].clear_sync();
268 }
269 }
270 }
271
272
273 void VirtualFrame::PrepareForCall(int spilled_args, int dropped_args) {
274 ASSERT(height() >= dropped_args);
275 ASSERT(height() >= spilled_args);
276 ASSERT(dropped_args <= spilled_args);
277
278 SyncRange(0, element_count() - 1);
279 // Spill registers.
280 for (int i = 0; i < RegisterAllocator::kNumRegisters; i++) {
281 if (is_used(i)) {
282 SpillElementAt(register_location(i));
283 }
284 }
285
286 // Spill the arguments.
287 for (int i = element_count() - spilled_args; i < element_count(); i++) {
288 if (!elements_[i].is_memory()) {
289 SpillElementAt(i);
290 }
291 }
292
293 // Forget the frame elements that will be popped by the call.
294 Forget(dropped_args);
295 }
296
297
298 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/virtual-frame.cc ('k') | src/virtual-frame-heavy-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698