OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 30 matching lines...) Expand all Loading... |
41 : elements_(original->element_count()), | 41 : elements_(original->element_count()), |
42 stack_pointer_(original->stack_pointer_) { | 42 stack_pointer_(original->stack_pointer_) { |
43 elements_.AddAll(original->elements_); | 43 elements_.AddAll(original->elements_); |
44 // Copy register locations from original. | 44 // Copy register locations from original. |
45 memcpy(®ister_locations_, | 45 memcpy(®ister_locations_, |
46 original->register_locations_, | 46 original->register_locations_, |
47 sizeof(register_locations_)); | 47 sizeof(register_locations_)); |
48 } | 48 } |
49 | 49 |
50 | 50 |
51 FrameElement VirtualFrame::CopyElementAt(int index) { | 51 // Create a duplicate of an existing valid frame element. |
| 52 // We can pass an optional number type information that will override the |
| 53 // existing information about the backing element. The new information must |
| 54 // not conflict with the existing type information and must be equally or |
| 55 // more precise. The default parameter value kUninitialized means that there |
| 56 // is no additional information. |
| 57 FrameElement VirtualFrame::CopyElementAt(int index, NumberInfo::Type info) { |
52 ASSERT(index >= 0); | 58 ASSERT(index >= 0); |
53 ASSERT(index < element_count()); | 59 ASSERT(index < element_count()); |
54 | 60 |
55 FrameElement target = elements_[index]; | 61 FrameElement target = elements_[index]; |
56 FrameElement result; | 62 FrameElement result; |
57 | 63 |
58 switch (target.type()) { | 64 switch (target.type()) { |
59 case FrameElement::CONSTANT: | 65 case FrameElement::CONSTANT: |
60 // We do not copy constants and instead return a fresh unsynced | 66 // We do not copy constants and instead return a fresh unsynced |
61 // constant. | 67 // constant. |
62 result = FrameElement::ConstantElement(target.handle(), | 68 result = FrameElement::ConstantElement(target.handle(), |
63 FrameElement::NOT_SYNCED); | 69 FrameElement::NOT_SYNCED); |
64 break; | 70 break; |
65 | 71 |
66 case FrameElement::COPY: | 72 case FrameElement::COPY: |
67 // We do not allow copies of copies, so we follow one link to | 73 // We do not allow copies of copies, so we follow one link to |
68 // the actual backing store of a copy before making a copy. | 74 // the actual backing store of a copy before making a copy. |
69 index = target.index(); | 75 index = target.index(); |
70 ASSERT(elements_[index].is_memory() || elements_[index].is_register()); | 76 ASSERT(elements_[index].is_memory() || elements_[index].is_register()); |
71 // Fall through. | 77 // Fall through. |
72 | 78 |
73 case FrameElement::MEMORY: // Fall through. | 79 case FrameElement::MEMORY: // Fall through. |
74 case FrameElement::REGISTER: | 80 case FrameElement::REGISTER: { |
75 // All copies are backed by memory or register locations. | 81 // All copies are backed by memory or register locations. |
76 result.set_type(FrameElement::COPY); | 82 result.set_type(FrameElement::COPY); |
77 result.clear_copied(); | 83 result.clear_copied(); |
78 result.clear_sync(); | 84 result.clear_sync(); |
79 result.set_index(index); | 85 result.set_index(index); |
80 elements_[index].set_copied(); | 86 elements_[index].set_copied(); |
| 87 // Update backing element's number information. |
| 88 NumberInfo::Type existing = elements_[index].number_info(); |
| 89 ASSERT(existing != NumberInfo::kUninitialized); |
| 90 // Assert that the new type information (a) does not conflict with the |
| 91 // existing one and (b) is equally or more precise. |
| 92 ASSERT((info == NumberInfo::kUninitialized) || |
| 93 (existing | info) != NumberInfo::kUninitialized); |
| 94 ASSERT(existing <= info); |
| 95 elements_[index].set_number_info(info != NumberInfo::kUninitialized |
| 96 ? info |
| 97 : existing); |
81 break; | 98 break; |
82 | 99 } |
83 case FrameElement::INVALID: | 100 case FrameElement::INVALID: |
84 // We should not try to copy invalid elements. | 101 // We should not try to copy invalid elements. |
85 UNREACHABLE(); | 102 UNREACHABLE(); |
86 break; | 103 break; |
87 } | 104 } |
88 return result; | 105 return result; |
89 } | 106 } |
90 | 107 |
91 | 108 |
92 // Modify the state of the virtual frame to match the actual frame by adding | 109 // Modify the state of the virtual frame to match the actual frame by adding |
93 // extra in-memory elements to the top of the virtual frame. The extra | 110 // extra in-memory elements to the top of the virtual frame. The extra |
94 // elements will be externally materialized on the actual frame (eg, by | 111 // elements will be externally materialized on the actual frame (eg, by |
95 // pushing an exception handler). No code is emitted. | 112 // pushing an exception handler). No code is emitted. |
96 void VirtualFrame::Adjust(int count) { | 113 void VirtualFrame::Adjust(int count) { |
97 ASSERT(count >= 0); | 114 ASSERT(count >= 0); |
98 ASSERT(stack_pointer_ == element_count() - 1); | 115 ASSERT(stack_pointer_ == element_count() - 1); |
99 | 116 |
100 for (int i = 0; i < count; i++) { | 117 for (int i = 0; i < count; i++) { |
101 elements_.Add(FrameElement::MemoryElement()); | 118 elements_.Add(FrameElement::MemoryElement(NumberInfo::kUnknown)); |
102 } | 119 } |
103 stack_pointer_ += count; | 120 stack_pointer_ += count; |
104 } | 121 } |
105 | 122 |
106 | 123 |
107 void VirtualFrame::ForgetElements(int count) { | 124 void VirtualFrame::ForgetElements(int count) { |
108 ASSERT(count >= 0); | 125 ASSERT(count >= 0); |
109 ASSERT(element_count() >= count); | 126 ASSERT(element_count() >= count); |
110 | 127 |
111 for (int i = 0; i < count; i++) { | 128 for (int i = 0; i < count; i++) { |
(...skipping 25 matching lines...) Expand all Loading... |
137 } | 154 } |
138 return no_reg; | 155 return no_reg; |
139 } | 156 } |
140 | 157 |
141 | 158 |
142 // Make the type of the element at a given index be MEMORY. | 159 // Make the type of the element at a given index be MEMORY. |
143 void VirtualFrame::SpillElementAt(int index) { | 160 void VirtualFrame::SpillElementAt(int index) { |
144 if (!elements_[index].is_valid()) return; | 161 if (!elements_[index].is_valid()) return; |
145 | 162 |
146 SyncElementAt(index); | 163 SyncElementAt(index); |
| 164 // Number type information is preserved. |
| 165 // Copies get their number information from their backing element. |
| 166 NumberInfo::Type info; |
| 167 if (!elements_[index].is_copy()) { |
| 168 info = elements_[index].number_info(); |
| 169 } else { |
| 170 info = elements_[elements_[index].index()].number_info(); |
| 171 } |
147 // The element is now in memory. Its copied flag is preserved. | 172 // The element is now in memory. Its copied flag is preserved. |
148 FrameElement new_element = FrameElement::MemoryElement(); | 173 FrameElement new_element = FrameElement::MemoryElement(info); |
149 if (elements_[index].is_copied()) { | 174 if (elements_[index].is_copied()) { |
150 new_element.set_copied(); | 175 new_element.set_copied(); |
151 } | 176 } |
152 if (elements_[index].is_register()) { | 177 if (elements_[index].is_register()) { |
153 Unuse(elements_[index].reg()); | 178 Unuse(elements_[index].reg()); |
154 } | 179 } |
155 elements_[index] = new_element; | 180 elements_[index] = new_element; |
156 } | 181 } |
157 | 182 |
158 | 183 |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 bool same_constant = original.is_constant() | 286 bool same_constant = original.is_constant() |
262 && value->is_constant() | 287 && value->is_constant() |
263 && original.handle().is_identical_to(value->handle()); | 288 && original.handle().is_identical_to(value->handle()); |
264 if (same_register || same_constant) { | 289 if (same_register || same_constant) { |
265 value->Unuse(); | 290 value->Unuse(); |
266 return; | 291 return; |
267 } | 292 } |
268 | 293 |
269 InvalidateFrameSlotAt(frame_index); | 294 InvalidateFrameSlotAt(frame_index); |
270 | 295 |
271 FrameElement new_element; | |
272 if (value->is_register()) { | 296 if (value->is_register()) { |
273 if (is_used(value->reg())) { | 297 if (is_used(value->reg())) { |
274 // The register already appears on the frame. Either the existing | 298 // The register already appears on the frame. Either the existing |
275 // register element, or the new element at frame_index, must be made | 299 // register element, or the new element at frame_index, must be made |
276 // a copy. | 300 // a copy. |
277 int i = register_location(value->reg()); | 301 int i = register_location(value->reg()); |
278 | 302 |
279 if (i < frame_index) { | 303 if (i < frame_index) { |
280 // The register FrameElement is lower in the frame than the new copy. | 304 // The register FrameElement is lower in the frame than the new copy. |
281 elements_[frame_index] = CopyElementAt(i); | 305 elements_[frame_index] = CopyElementAt(i); |
(...skipping 12 matching lines...) Expand all Loading... |
294 if (elements_[j].is_copy() && elements_[j].index() == i) { | 318 if (elements_[j].is_copy() && elements_[j].index() == i) { |
295 elements_[j].set_index(frame_index); | 319 elements_[j].set_index(frame_index); |
296 } | 320 } |
297 } | 321 } |
298 } | 322 } |
299 } else { | 323 } else { |
300 // The register value->reg() was not already used on the frame. | 324 // The register value->reg() was not already used on the frame. |
301 Use(value->reg(), frame_index); | 325 Use(value->reg(), frame_index); |
302 elements_[frame_index] = | 326 elements_[frame_index] = |
303 FrameElement::RegisterElement(value->reg(), | 327 FrameElement::RegisterElement(value->reg(), |
304 FrameElement::NOT_SYNCED); | 328 FrameElement::NOT_SYNCED, |
| 329 value->number_info()); |
305 } | 330 } |
306 } else { | 331 } else { |
307 ASSERT(value->is_constant()); | 332 ASSERT(value->is_constant()); |
308 elements_[frame_index] = | 333 elements_[frame_index] = |
309 FrameElement::ConstantElement(value->handle(), | 334 FrameElement::ConstantElement(value->handle(), |
310 FrameElement::NOT_SYNCED); | 335 FrameElement::NOT_SYNCED); |
311 } | 336 } |
312 value->Unuse(); | 337 value->Unuse(); |
313 } | 338 } |
314 | 339 |
315 | 340 |
316 void VirtualFrame::PushFrameSlotAt(int index) { | 341 void VirtualFrame::PushFrameSlotAt(int index) { |
317 elements_.Add(CopyElementAt(index)); | 342 elements_.Add(CopyElementAt(index)); |
318 } | 343 } |
319 | 344 |
320 | 345 |
321 void VirtualFrame::Push(Register reg) { | 346 void VirtualFrame::Push(Register reg, NumberInfo::Type info) { |
322 if (is_used(reg)) { | 347 if (is_used(reg)) { |
323 int index = register_location(reg); | 348 int index = register_location(reg); |
324 FrameElement element = CopyElementAt(index); | 349 FrameElement element = CopyElementAt(index, info); |
325 elements_.Add(element); | 350 elements_.Add(element); |
326 } else { | 351 } else { |
327 Use(reg, element_count()); | 352 Use(reg, element_count()); |
328 FrameElement element = | 353 FrameElement element = |
329 FrameElement::RegisterElement(reg, | 354 FrameElement::RegisterElement(reg, FrameElement::NOT_SYNCED, info); |
330 FrameElement::NOT_SYNCED); | |
331 elements_.Add(element); | 355 elements_.Add(element); |
332 } | 356 } |
333 } | 357 } |
334 | 358 |
335 | 359 |
336 void VirtualFrame::Push(Handle<Object> value) { | 360 void VirtualFrame::Push(Handle<Object> value) { |
337 FrameElement element = | 361 FrameElement element = |
338 FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED); | 362 FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED); |
339 elements_.Add(element); | 363 elements_.Add(element); |
340 } | 364 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 // Specialization of List::ResizeAdd to non-inlined version for FrameElements. | 396 // Specialization of List::ResizeAdd to non-inlined version for FrameElements. |
373 // The function ResizeAdd becomes a real function, whose implementation is the | 397 // The function ResizeAdd becomes a real function, whose implementation is the |
374 // inlined ResizeAddInternal. | 398 // inlined ResizeAddInternal. |
375 template <> | 399 template <> |
376 void List<FrameElement, | 400 void List<FrameElement, |
377 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) { | 401 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) { |
378 ResizeAddInternal(element); | 402 ResizeAddInternal(element); |
379 } | 403 } |
380 | 404 |
381 } } // namespace v8::internal | 405 } } // namespace v8::internal |
OLD | NEW |