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 17 matching lines...) Expand all Loading... |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "codegen-inl.h" | 30 #include "codegen-inl.h" |
31 #include "register-allocator-inl.h" | 31 #include "register-allocator-inl.h" |
32 | 32 |
33 namespace v8 { namespace internal { | 33 namespace v8 { namespace internal { |
34 | 34 |
35 // ------------------------------------------------------------------------- | 35 // ------------------------------------------------------------------------- |
36 // VirtualFrame implementation. | 36 // VirtualFrame implementation. |
37 | 37 |
38 VirtualFrame::SpilledScope::SpilledScope(CodeGenerator* cgen) | |
39 : cgen_(cgen), | |
40 previous_state_(cgen->in_spilled_code()) { | |
41 ASSERT(cgen->has_valid_frame()); | |
42 cgen->frame()->SpillAll(); | |
43 cgen->set_in_spilled_code(true); | |
44 } | |
45 | |
46 | |
47 VirtualFrame::SpilledScope::~SpilledScope() { | |
48 cgen_->set_in_spilled_code(previous_state_); | |
49 } | |
50 | |
51 | |
52 // When cloned, a frame is a deep copy of the original. | 38 // When cloned, a frame is a deep copy of the original. |
53 VirtualFrame::VirtualFrame(VirtualFrame* original) | 39 VirtualFrame::VirtualFrame(VirtualFrame* original) |
54 : cgen_(original->cgen_), | 40 : cgen_(original->cgen_), |
55 masm_(original->masm_), | 41 masm_(original->masm_), |
56 elements_(original->elements_.capacity()), | 42 elements_(original->elements_.capacity()), |
57 parameter_count_(original->parameter_count_), | 43 parameter_count_(original->parameter_count_), |
58 local_count_(original->local_count_), | 44 local_count_(original->local_count_), |
59 stack_pointer_(original->stack_pointer_), | 45 stack_pointer_(original->stack_pointer_), |
60 frame_pointer_(original->frame_pointer_) { | 46 frame_pointer_(original->frame_pointer_) { |
61 // Copy all the elements from the original. | 47 // Copy all the elements from the original. |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 ASSERT(count >= 0); | 104 ASSERT(count >= 0); |
119 ASSERT(stack_pointer_ == elements_.length() - 1); | 105 ASSERT(stack_pointer_ == elements_.length() - 1); |
120 | 106 |
121 for (int i = 0; i < count; i++) { | 107 for (int i = 0; i < count; i++) { |
122 elements_.Add(FrameElement::MemoryElement()); | 108 elements_.Add(FrameElement::MemoryElement()); |
123 } | 109 } |
124 stack_pointer_ += count; | 110 stack_pointer_ += count; |
125 } | 111 } |
126 | 112 |
127 | 113 |
128 // Modify the state of the virtual frame to match the actual frame by | |
129 // removing elements from the top of the virtual frame. The elements will | |
130 // be externally popped from the actual frame (eg, by a runtime call). No | |
131 // code is emitted. | |
132 void VirtualFrame::Forget(int count) { | |
133 ASSERT(count >= 0); | |
134 ASSERT(stack_pointer_ == elements_.length() - 1); | |
135 | |
136 stack_pointer_ -= count; | |
137 ForgetElements(count); | |
138 } | |
139 | |
140 | |
141 void VirtualFrame::ForgetElements(int count) { | 114 void VirtualFrame::ForgetElements(int count) { |
142 ASSERT(count >= 0); | 115 ASSERT(count >= 0); |
143 ASSERT(elements_.length() >= count); | 116 ASSERT(elements_.length() >= count); |
144 | 117 |
145 for (int i = 0; i < count; i++) { | 118 for (int i = 0; i < count; i++) { |
146 FrameElement last = elements_.RemoveLast(); | 119 FrameElement last = elements_.RemoveLast(); |
147 if (last.is_register()) { | 120 if (last.is_register()) { |
148 // A hack to properly count register references for the code | 121 // A hack to properly count register references for the code |
149 // generator's current frame and also for other frames. The | 122 // generator's current frame and also for other frames. The |
150 // same code appears in PrepareMergeTo. | 123 // same code appears in PrepareMergeTo. |
151 if (cgen_->frame() == this) { | 124 if (cgen_->frame() == this) { |
152 Unuse(last.reg()); | 125 Unuse(last.reg()); |
153 } else { | 126 } else { |
154 register_locations_[last.reg().code()] = kIllegalIndex; | 127 register_locations_[last.reg().code()] = kIllegalIndex; |
155 } | 128 } |
156 } | 129 } |
157 } | 130 } |
158 } | 131 } |
159 | 132 |
160 | 133 |
161 void VirtualFrame::Use(Register reg, int index) { | |
162 ASSERT(register_locations_[reg.code()] == kIllegalIndex); | |
163 register_locations_[reg.code()] = index; | |
164 cgen_->allocator()->Use(reg); | |
165 } | |
166 | |
167 | |
168 void VirtualFrame::Unuse(Register reg) { | |
169 ASSERT(register_locations_[reg.code()] != kIllegalIndex); | |
170 register_locations_[reg.code()] = kIllegalIndex; | |
171 cgen_->allocator()->Unuse(reg); | |
172 } | |
173 | |
174 | |
175 void VirtualFrame::Spill(Register target) { | |
176 if (is_used(target)) { | |
177 SpillElementAt(register_index(target)); | |
178 } | |
179 } | |
180 | |
181 | |
182 // If there are any registers referenced only by the frame, spill one. | 134 // If there are any registers referenced only by the frame, spill one. |
183 Register VirtualFrame::SpillAnyRegister() { | 135 Register VirtualFrame::SpillAnyRegister() { |
184 // Find the leftmost (ordered by register code) register whose only | 136 // Find the leftmost (ordered by register code) register whose only |
185 // reference is in the frame. | 137 // reference is in the frame. |
186 for (int i = 0; i < kNumRegisters; i++) { | 138 for (int i = 0; i < kNumRegisters; i++) { |
187 if (is_used(i) && cgen_->allocator()->count(i) == 1) { | 139 if (is_used(i) && cgen_->allocator()->count(i) == 1) { |
188 Register result = { i }; | 140 Register result = { i }; |
189 Spill(result); | 141 Spill(result); |
190 ASSERT(!cgen_->allocator()->is_used(result)); | 142 ASSERT(!cgen_->allocator()->is_used(result)); |
191 return result; | 143 return result; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 ASSERT(value->is_constant()); | 330 ASSERT(value->is_constant()); |
379 elements_[frame_index] = | 331 elements_[frame_index] = |
380 FrameElement::ConstantElement(value->handle(), | 332 FrameElement::ConstantElement(value->handle(), |
381 FrameElement::NOT_SYNCED); | 333 FrameElement::NOT_SYNCED); |
382 } | 334 } |
383 value->Unuse(); | 335 value->Unuse(); |
384 } | 336 } |
385 | 337 |
386 | 338 |
387 void VirtualFrame::PushFrameSlotAt(int index) { | 339 void VirtualFrame::PushFrameSlotAt(int index) { |
388 FrameElement new_element = CopyElementAt(index); | 340 elements_.Add(CopyElementAt(index)); |
389 elements_.Add(new_element); | |
390 } | |
391 | |
392 | |
393 Result VirtualFrame::CallStub(CodeStub* stub, int arg_count) { | |
394 PrepareForCall(arg_count, arg_count); | |
395 return RawCallStub(stub); | |
396 } | 341 } |
397 | 342 |
398 | 343 |
399 void VirtualFrame::Push(Register reg, StaticType static_type) { | 344 void VirtualFrame::Push(Register reg, StaticType static_type) { |
400 if (is_used(reg)) { | 345 if (is_used(reg)) { |
401 int index = register_index(reg); | 346 int index = register_index(reg); |
402 FrameElement element = CopyElementAt(index); | 347 FrameElement element = CopyElementAt(index); |
403 ASSERT(static_type.merge(element.static_type()) == element.static_type()); | 348 ASSERT(static_type.merge(element.static_type()) == element.static_type()); |
404 elements_.Add(element); | 349 elements_.Add(element); |
405 } else { | 350 } else { |
406 Use(reg, elements_.length()); | 351 Use(reg, elements_.length()); |
407 FrameElement element = | 352 FrameElement element = |
408 FrameElement::RegisterElement(reg, | 353 FrameElement::RegisterElement(reg, |
409 FrameElement::NOT_SYNCED, | 354 FrameElement::NOT_SYNCED, |
410 static_type); | 355 static_type); |
411 elements_.Add(element); | 356 elements_.Add(element); |
412 } | 357 } |
413 } | 358 } |
414 | 359 |
415 | 360 |
416 void VirtualFrame::Push(Handle<Object> value) { | 361 void VirtualFrame::Push(Handle<Object> value) { |
417 FrameElement element = | 362 FrameElement element = |
418 FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED); | 363 FrameElement::ConstantElement(value, FrameElement::NOT_SYNCED); |
419 elements_.Add(element); | 364 elements_.Add(element); |
420 } | 365 } |
421 | 366 |
422 | 367 |
423 void VirtualFrame::Push(Result* result) { | |
424 if (result->is_register()) { | |
425 Push(result->reg(), result->static_type()); | |
426 } else { | |
427 ASSERT(result->is_constant()); | |
428 Push(result->handle()); | |
429 } | |
430 result->Unuse(); | |
431 } | |
432 | |
433 | |
434 void VirtualFrame::Nip(int num_dropped) { | 368 void VirtualFrame::Nip(int num_dropped) { |
435 ASSERT(num_dropped >= 0); | 369 ASSERT(num_dropped >= 0); |
436 if (num_dropped == 0) return; | 370 if (num_dropped == 0) return; |
437 Result tos = Pop(); | 371 Result tos = Pop(); |
438 if (num_dropped > 1) { | 372 if (num_dropped > 1) { |
439 Drop(num_dropped - 1); | 373 Drop(num_dropped - 1); |
440 } | 374 } |
441 SetElementAt(0, &tos); | 375 SetElementAt(0, &tos); |
442 } | 376 } |
443 | 377 |
(...skipping 27 matching lines...) Expand all Loading... |
471 // Specialization of List::ResizeAdd to non-inlined version for FrameElements. | 405 // Specialization of List::ResizeAdd to non-inlined version for FrameElements. |
472 // The function ResizeAdd becomes a real function, whose implementation is the | 406 // The function ResizeAdd becomes a real function, whose implementation is the |
473 // inlined ResizeAddInternal. | 407 // inlined ResizeAddInternal. |
474 template <> | 408 template <> |
475 void List<FrameElement, | 409 void List<FrameElement, |
476 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) { | 410 FreeStoreAllocationPolicy>::ResizeAdd(const FrameElement& element) { |
477 ResizeAddInternal(element); | 411 ResizeAddInternal(element); |
478 } | 412 } |
479 | 413 |
480 } } // namespace v8::internal | 414 } } // namespace v8::internal |
OLD | NEW |