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 22 matching lines...) Expand all Loading... |
33 #include "register-allocator-inl.h" | 33 #include "register-allocator-inl.h" |
34 #include "scopes.h" | 34 #include "scopes.h" |
35 #include "virtual-frame-inl.h" | 35 #include "virtual-frame-inl.h" |
36 | 36 |
37 namespace v8 { | 37 namespace v8 { |
38 namespace internal { | 38 namespace internal { |
39 | 39 |
40 #define __ ACCESS_MASM(masm()) | 40 #define __ ACCESS_MASM(masm()) |
41 | 41 |
42 void VirtualFrame::PopToR1R0() { | 42 void VirtualFrame::PopToR1R0() { |
43 VirtualFrame where_to_go = *this; | |
44 // Shuffle things around so the top of stack is in r0 and r1. | 43 // Shuffle things around so the top of stack is in r0 and r1. |
45 where_to_go.top_of_stack_state_ = R0_R1_TOS; | 44 MergeTOSTo(R0_R1_TOS); |
46 MergeTo(&where_to_go); | |
47 // Pop the two registers off the stack so they are detached from the frame. | 45 // Pop the two registers off the stack so they are detached from the frame. |
48 element_count_ -= 2; | 46 element_count_ -= 2; |
49 top_of_stack_state_ = NO_TOS_REGISTERS; | 47 top_of_stack_state_ = NO_TOS_REGISTERS; |
50 } | 48 } |
51 | 49 |
52 | 50 |
53 void VirtualFrame::PopToR1() { | 51 void VirtualFrame::PopToR1() { |
54 VirtualFrame where_to_go = *this; | |
55 // Shuffle things around so the top of stack is only in r1. | 52 // Shuffle things around so the top of stack is only in r1. |
56 where_to_go.top_of_stack_state_ = R1_TOS; | 53 MergeTOSTo(R1_TOS); |
57 MergeTo(&where_to_go); | |
58 // Pop the register off the stack so it is detached from the frame. | 54 // Pop the register off the stack so it is detached from the frame. |
59 element_count_ -= 1; | 55 element_count_ -= 1; |
60 top_of_stack_state_ = NO_TOS_REGISTERS; | 56 top_of_stack_state_ = NO_TOS_REGISTERS; |
61 } | 57 } |
62 | 58 |
63 | 59 |
64 void VirtualFrame::PopToR0() { | 60 void VirtualFrame::PopToR0() { |
65 VirtualFrame where_to_go = *this; | |
66 // Shuffle things around so the top of stack only in r0. | 61 // Shuffle things around so the top of stack only in r0. |
67 where_to_go.top_of_stack_state_ = R0_TOS; | 62 MergeTOSTo(R0_TOS); |
68 MergeTo(&where_to_go); | |
69 // Pop the register off the stack so it is detached from the frame. | 63 // Pop the register off the stack so it is detached from the frame. |
70 element_count_ -= 1; | 64 element_count_ -= 1; |
71 top_of_stack_state_ = NO_TOS_REGISTERS; | 65 top_of_stack_state_ = NO_TOS_REGISTERS; |
72 } | 66 } |
73 | 67 |
74 | 68 |
75 void VirtualFrame::MergeTo(const VirtualFrame* expected, Condition cond) { | 69 void VirtualFrame::MergeTo(const VirtualFrame* expected, Condition cond) { |
76 if (Equals(expected)) return; | 70 if (Equals(expected)) return; |
77 MergeTOSTo(expected->top_of_stack_state_, cond); | 71 MergeTOSTo(expected->top_of_stack_state_, cond); |
78 ASSERT(register_allocation_map_ == expected->register_allocation_map_); | 72 ASSERT(register_allocation_map_ == expected->register_allocation_map_); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 void VirtualFrame::PushTryHandler(HandlerType type) { | 260 void VirtualFrame::PushTryHandler(HandlerType type) { |
267 // Grow the expression stack by handler size less one (the return | 261 // Grow the expression stack by handler size less one (the return |
268 // address in lr is already counted by a call instruction). | 262 // address in lr is already counted by a call instruction). |
269 Adjust(kHandlerSize - 1); | 263 Adjust(kHandlerSize - 1); |
270 __ PushTryHandler(IN_JAVASCRIPT, type); | 264 __ PushTryHandler(IN_JAVASCRIPT, type); |
271 } | 265 } |
272 | 266 |
273 | 267 |
274 void VirtualFrame::CallJSFunction(int arg_count) { | 268 void VirtualFrame::CallJSFunction(int arg_count) { |
275 // InvokeFunction requires function in r1. | 269 // InvokeFunction requires function in r1. |
276 EmitPop(r1); | 270 PopToR1(); |
| 271 SpillAll(); |
277 | 272 |
278 // +1 for receiver. | 273 // +1 for receiver. |
279 Forget(arg_count + 1); | 274 Forget(arg_count + 1); |
280 ASSERT(cgen()->HasValidEntryRegisters()); | 275 ASSERT(cgen()->HasValidEntryRegisters()); |
281 ParameterCount count(arg_count); | 276 ParameterCount count(arg_count); |
282 __ InvokeFunction(r1, count, CALL_FUNCTION); | 277 __ InvokeFunction(r1, count, CALL_FUNCTION); |
283 // Restore the context. | 278 // Restore the context. |
284 __ ldr(cp, Context()); | 279 __ ldr(cp, Context()); |
285 } | 280 } |
286 | 281 |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 __ push(kBottomRegister[top_of_stack_state_]); | 619 __ push(kBottomRegister[top_of_stack_state_]); |
625 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; | 620 top_of_stack_state_ = kStateAfterPush[top_of_stack_state_]; |
626 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; | 621 top_of_stack_state_ = kStateAfterPop[top_of_stack_state_]; |
627 } | 622 } |
628 ASSERT(kVirtualElements[top_of_stack_state_] != kMaxTOSRegisters); | 623 ASSERT(kVirtualElements[top_of_stack_state_] != kMaxTOSRegisters); |
629 } | 624 } |
630 | 625 |
631 | 626 |
632 void VirtualFrame::EmitPush(Register reg) { | 627 void VirtualFrame::EmitPush(Register reg) { |
633 element_count_++; | 628 element_count_++; |
634 if (SpilledScope::is_spilled()) { | 629 if (reg.is(cp)) { |
| 630 // If we are pushing cp then we are about to make a call and things have to |
| 631 // be pushed to the physical stack. There's nothing to be gained my moving |
| 632 // to a TOS register and then pushing that, we might as well push to the |
| 633 // physical stack immediately. |
| 634 MergeTOSTo(NO_TOS_REGISTERS); |
635 __ push(reg); | 635 __ push(reg); |
636 return; | 636 return; |
637 } | 637 } |
| 638 if (SpilledScope::is_spilled()) { |
| 639 ASSERT(top_of_stack_state_ == NO_TOS_REGISTERS); |
| 640 __ push(reg); |
| 641 return; |
| 642 } |
638 if (top_of_stack_state_ == NO_TOS_REGISTERS) { | 643 if (top_of_stack_state_ == NO_TOS_REGISTERS) { |
639 if (reg.is(r0)) { | 644 if (reg.is(r0)) { |
640 top_of_stack_state_ = R0_TOS; | 645 top_of_stack_state_ = R0_TOS; |
641 return; | 646 return; |
642 } | 647 } |
643 if (reg.is(r1)) { | 648 if (reg.is(r1)) { |
644 top_of_stack_state_ = R1_TOS; | 649 top_of_stack_state_ = R1_TOS; |
645 return; | 650 return; |
646 } | 651 } |
647 } | 652 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 break; | 767 break; |
763 } | 768 } |
764 ASSERT(register_allocation_map_ == 0); // Not yet implemented. | 769 ASSERT(register_allocation_map_ == 0); // Not yet implemented. |
765 } | 770 } |
766 | 771 |
767 #undef __ | 772 #undef __ |
768 | 773 |
769 } } // namespace v8::internal | 774 } } // namespace v8::internal |
770 | 775 |
771 #endif // V8_TARGET_ARCH_ARM | 776 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |