OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_PPC | 7 #if V8_TARGET_ARCH_PPC |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/debug.h" | 10 #include "src/debug.h" |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry()))); | 64 debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry()))); |
65 patcher.masm()->mtctr(v8::internal::r0); | 65 patcher.masm()->mtctr(v8::internal::r0); |
66 patcher.masm()->bctrl(); | 66 patcher.masm()->bctrl(); |
67 } | 67 } |
68 | 68 |
69 | 69 |
70 #define __ ACCESS_MASM(masm) | 70 #define __ ACCESS_MASM(masm) |
71 | 71 |
72 | 72 |
73 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, | 73 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
74 RegList object_regs, | 74 RegList object_regs) { |
75 RegList non_object_regs) { | |
76 { | 75 { |
77 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 76 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
78 | 77 |
79 // Load padding words on stack. | 78 // Load padding words on stack. |
80 __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingValue)); | 79 __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingValue)); |
81 for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { | 80 for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { |
82 __ push(ip); | 81 __ push(ip); |
83 } | 82 } |
84 __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); | 83 __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); |
85 __ push(ip); | 84 __ push(ip); |
86 | 85 |
87 // Store the registers containing live values on the expression stack to | 86 // Store the registers containing live values on the expression stack to |
88 // make sure that these are correctly updated during GC. Non object values | 87 // make sure that these are correctly updated during GC. Non object values |
89 // are stored as a smi causing it to be untouched by GC. | 88 // are stored as a smi causing it to be untouched by GC. |
90 DCHECK((object_regs & ~kJSCallerSaved) == 0); | 89 DCHECK((object_regs & ~kJSCallerSaved) == 0); |
91 DCHECK((non_object_regs & ~kJSCallerSaved) == 0); | 90 if (object_regs != 0) { |
92 DCHECK((object_regs & non_object_regs) == 0); | 91 __ MultiPush(object_regs); |
93 if ((object_regs | non_object_regs) != 0) { | |
94 for (int i = 0; i < kNumJSCallerSaved; i++) { | |
95 int r = JSCallerSavedCode(i); | |
96 Register reg = {r}; | |
97 if ((non_object_regs & (1 << r)) != 0) { | |
98 if (FLAG_debug_code) { | |
99 __ TestUnsignedSmiCandidate(reg, r0); | |
100 __ Assert(eq, kUnableToEncodeValueAsSmi, cr0); | |
101 } | |
102 __ SmiTag(reg); | |
103 } | |
104 } | |
105 __ MultiPush(object_regs | non_object_regs); | |
106 } | 92 } |
107 | 93 |
108 #ifdef DEBUG | 94 #ifdef DEBUG |
109 __ RecordComment("// Calling from debug break to runtime - come in - over"); | 95 __ RecordComment("// Calling from debug break to runtime - come in - over"); |
110 #endif | 96 #endif |
111 __ mov(r3, Operand::Zero()); // no arguments | 97 __ mov(r3, Operand::Zero()); // no arguments |
112 __ mov(r4, Operand(ExternalReference::debug_break(masm->isolate()))); | 98 __ mov(r4, Operand(ExternalReference::debug_break(masm->isolate()))); |
113 | 99 |
114 CEntryStub ceb(masm->isolate(), 1); | 100 CEntryStub ceb(masm->isolate(), 1); |
115 __ CallStub(&ceb); | 101 __ CallStub(&ceb); |
116 | 102 |
117 // Restore the register values from the expression stack. | 103 // Restore the register values from the expression stack. |
118 if ((object_regs | non_object_regs) != 0) { | 104 if (object_regs != 0) { |
119 __ MultiPop(object_regs | non_object_regs); | 105 __ MultiPop(object_regs); |
120 for (int i = 0; i < kNumJSCallerSaved; i++) { | 106 } |
121 int r = JSCallerSavedCode(i); | 107 |
122 Register reg = {r}; | 108 for (int i = 0; i < kNumJSCallerSaved; i++) { |
123 if ((non_object_regs & (1 << r)) != 0) { | 109 int r = JSCallerSavedCode(i); |
124 __ SmiUntag(reg); | 110 Register reg = {r}; |
125 } | 111 if (FLAG_debug_code && ((object_regs & (1 << r)) == 0)) { |
126 if (FLAG_debug_code && | 112 __ mov(reg, Operand(kDebugZapValue)); |
127 (((object_regs | non_object_regs) & (1 << r)) == 0)) { | |
128 __ mov(reg, Operand(kDebugZapValue)); | |
129 } | |
130 } | 113 } |
131 } | 114 } |
132 | 115 |
133 // Don't bother removing padding bytes pushed on the stack | 116 // Don't bother removing padding bytes pushed on the stack |
134 // as the frame is going to be restored right away. | 117 // as the frame is going to be restored right away. |
135 | 118 |
136 // Leave the internal frame. | 119 // Leave the internal frame. |
137 } | 120 } |
138 | 121 |
139 // Now that the break point has been handled, resume normal execution by | 122 // Now that the break point has been handled, resume normal execution by |
140 // jumping to the target address intended by the caller and that was | 123 // jumping to the target address intended by the caller and that was |
141 // overwritten by the address of DebugBreakXXX. | 124 // overwritten by the address of DebugBreakXXX. |
142 ExternalReference after_break_target = | 125 ExternalReference after_break_target = |
143 ExternalReference::debug_after_break_target_address(masm->isolate()); | 126 ExternalReference::debug_after_break_target_address(masm->isolate()); |
144 __ mov(ip, Operand(after_break_target)); | 127 __ mov(ip, Operand(after_break_target)); |
145 __ LoadP(ip, MemOperand(ip)); | 128 __ LoadP(ip, MemOperand(ip)); |
146 __ JumpToJSEntry(ip); | 129 __ JumpToJSEntry(ip); |
147 } | 130 } |
148 | 131 |
149 | 132 |
150 void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { | |
151 // Register state for CallICStub | |
152 // ----------- S t a t e ------------- | |
153 // -- r4 : function | |
154 // -- r6 : slot in feedback array (smi) | |
155 // ----------------------------------- | |
156 Generate_DebugBreakCallHelper(masm, r4.bit() | r6.bit(), 0); | |
157 } | |
158 | |
159 | |
160 void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { | 133 void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { |
161 // In places other than IC call sites it is expected that r3 is TOS which | 134 // In places other than IC call sites it is expected that r3 is TOS which |
162 // is an object - this is not generally the case so this should be used with | 135 // is an object - this is not generally the case so this should be used with |
163 // care. | 136 // care. |
164 Generate_DebugBreakCallHelper(masm, r3.bit(), 0); | 137 Generate_DebugBreakCallHelper(masm, r3.bit()); |
165 } | 138 } |
166 | 139 |
167 | 140 |
168 void DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) { | |
169 // Register state for CallFunctionStub (from code-stubs-ppc.cc). | |
170 // ----------- S t a t e ------------- | |
171 // -- r4 : function | |
172 // ----------------------------------- | |
173 Generate_DebugBreakCallHelper(masm, r4.bit(), 0); | |
174 } | |
175 | |
176 | |
177 void DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) { | |
178 // Calling convention for CallConstructStub (from code-stubs-ppc.cc) | |
179 // ----------- S t a t e ------------- | |
180 // -- r3 : number of arguments (not smi) | |
181 // -- r4 : constructor function | |
182 // ----------------------------------- | |
183 Generate_DebugBreakCallHelper(masm, r4.bit(), r3.bit()); | |
184 } | |
185 | |
186 | |
187 void DebugCodegen::GenerateCallConstructStubRecordDebugBreak( | |
188 MacroAssembler* masm) { | |
189 // Calling convention for CallConstructStub (from code-stubs-ppc.cc) | |
190 // ----------- S t a t e ------------- | |
191 // -- r3 : number of arguments (not smi) | |
192 // -- r4 : constructor function | |
193 // -- r5 : feedback array | |
194 // -- r6 : feedback slot (smi) | |
195 // ----------------------------------- | |
196 Generate_DebugBreakCallHelper(masm, r4.bit() | r5.bit() | r6.bit(), r3.bit()); | |
197 } | |
198 | |
199 | |
200 void DebugCodegen::GenerateSlot(MacroAssembler* masm) { | 141 void DebugCodegen::GenerateSlot(MacroAssembler* masm) { |
201 // Generate enough nop's to make space for a call instruction. Avoid emitting | 142 // Generate enough nop's to make space for a call instruction. Avoid emitting |
202 // the trampoline pool in the debug break slot code. | 143 // the trampoline pool in the debug break slot code. |
203 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); | 144 Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); |
204 Label check_codesize; | 145 Label check_codesize; |
205 __ bind(&check_codesize); | 146 __ bind(&check_codesize); |
206 __ RecordDebugBreakSlot(); | |
207 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { | 147 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { |
208 __ nop(MacroAssembler::DEBUG_BREAK_NOP); | 148 __ nop(MacroAssembler::DEBUG_BREAK_NOP); |
209 } | 149 } |
210 DCHECK_EQ(Assembler::kDebugBreakSlotInstructions, | 150 DCHECK_EQ(Assembler::kDebugBreakSlotInstructions, |
211 masm->InstructionsGeneratedSince(&check_codesize)); | 151 masm->InstructionsGeneratedSince(&check_codesize)); |
212 } | 152 } |
213 | 153 |
214 | 154 |
215 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { | 155 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { |
216 // In the places where a debug break slot is inserted no registers can contain | 156 // In the places where a debug break slot is inserted no registers can contain |
217 // object pointers. | 157 // object pointers. |
218 Generate_DebugBreakCallHelper(masm, 0, 0); | 158 Generate_DebugBreakCallHelper(masm, 0); |
219 } | 159 } |
220 | 160 |
221 | 161 |
222 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { | 162 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { |
223 __ Ret(); | 163 __ Ret(); |
224 } | 164 } |
225 | 165 |
226 | 166 |
227 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { | 167 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { |
228 ExternalReference restarter_frame_function_slot = | 168 ExternalReference restarter_frame_function_slot = |
(...skipping 23 matching lines...) Expand all Loading... |
252 } | 192 } |
253 | 193 |
254 | 194 |
255 const bool LiveEdit::kFrameDropperSupported = true; | 195 const bool LiveEdit::kFrameDropperSupported = true; |
256 | 196 |
257 #undef __ | 197 #undef __ |
258 } // namespace internal | 198 } // namespace internal |
259 } // namespace v8 | 199 } // namespace v8 |
260 | 200 |
261 #endif // V8_TARGET_ARCH_PPC | 201 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |