OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/debug.h" | 10 #include "src/debug.h" |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 } | 124 } |
125 | 125 |
126 | 126 |
127 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, | 127 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
128 RegList object_regs, | 128 RegList object_regs, |
129 RegList non_object_regs, | 129 RegList non_object_regs, |
130 Register scratch) { | 130 Register scratch) { |
131 { | 131 { |
132 FrameScope scope(masm, StackFrame::INTERNAL); | 132 FrameScope scope(masm, StackFrame::INTERNAL); |
133 | 133 |
| 134 // Load padding words on stack. |
| 135 __ ldr(scratch, Smi::FromInt(LiveEdit::kFramePaddingValue)); |
| 136 for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { |
| 137 __ push(scratch); |
| 138 } |
| 139 __ ldr(scratch, Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); |
| 140 __ push(scratch); |
| 141 |
134 // Any live values (object_regs and non_object_regs) in caller-saved | 142 // Any live values (object_regs and non_object_regs) in caller-saved |
135 // registers (or lr) need to be stored on the stack so that their values are | 143 // registers (or lr) need to be stored on the stack so that their values are |
136 // safely preserved for a call into C code. | 144 // safely preserved for a call into C code. |
137 // | 145 // |
138 // Also: | 146 // Also: |
139 // * object_regs may be modified during the C code by the garbage | 147 // * object_regs may be modified during the C code by the garbage |
140 // collector. Every object register must be a valid tagged pointer or | 148 // collector. Every object register must be a valid tagged pointer or |
141 // SMI. | 149 // SMI. |
142 // | 150 // |
143 // * non_object_regs will be converted to SMIs so that the garbage | 151 // * non_object_regs will be converted to SMIs so that the garbage |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 // Stack: | 201 // Stack: |
194 // jssp[12]: reg[63:32] | 202 // jssp[12]: reg[63:32] |
195 // jssp[8]: 0x00000000 (SMI tag & padding) | 203 // jssp[8]: 0x00000000 (SMI tag & padding) |
196 // jssp[4]: reg[31:0] | 204 // jssp[4]: reg[31:0] |
197 // jssp[0]: 0x00000000 (SMI tag & padding) | 205 // jssp[0]: 0x00000000 (SMI tag & padding) |
198 Register reg = Register(non_object_list.PopHighestIndex()); | 206 Register reg = Register(non_object_list.PopHighestIndex()); |
199 __ Pop(scratch, reg); | 207 __ Pop(scratch, reg); |
200 __ Bfxil(reg, scratch, 32, 32); | 208 __ Bfxil(reg, scratch, 32, 32); |
201 } | 209 } |
202 | 210 |
| 211 // Don't bother removing padding bytes pushed on the stack |
| 212 // as the frame is going to be restored right away. |
| 213 |
203 // Leave the internal frame. | 214 // Leave the internal frame. |
204 } | 215 } |
205 | 216 |
206 // Now that the break point has been handled, resume normal execution by | 217 // Now that the break point has been handled, resume normal execution by |
207 // jumping to the target address intended by the caller and that was | 218 // jumping to the target address intended by the caller and that was |
208 // overwritten by the address of DebugBreakXXX. | 219 // overwritten by the address of DebugBreakXXX. |
209 ExternalReference after_break_target = | 220 ExternalReference after_break_target = |
210 ExternalReference::debug_after_break_target_address(masm->isolate()); | 221 ExternalReference::debug_after_break_target_address(masm->isolate()); |
211 __ Mov(scratch, after_break_target); | 222 __ Mov(scratch, after_break_target); |
212 __ Ldr(scratch, MemOperand(scratch)); | 223 __ Ldr(scratch, MemOperand(scratch)); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 | 345 |
335 | 346 |
336 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { | 347 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { |
337 // In the places where a debug break slot is inserted no registers can contain | 348 // In the places where a debug break slot is inserted no registers can contain |
338 // object pointers. | 349 // object pointers. |
339 Generate_DebugBreakCallHelper(masm, 0, 0, x10); | 350 Generate_DebugBreakCallHelper(masm, 0, 0, x10); |
340 } | 351 } |
341 | 352 |
342 | 353 |
343 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { | 354 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { |
344 masm->Abort(kLiveEditFrameDroppingIsNotSupportedOnARM64); | 355 __ Ret(); |
345 } | 356 } |
346 | 357 |
347 | 358 |
348 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { | 359 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { |
349 masm->Abort(kLiveEditFrameDroppingIsNotSupportedOnARM64); | 360 ExternalReference restarter_frame_function_slot = |
| 361 ExternalReference::debug_restarter_frame_function_pointer_address( |
| 362 masm->isolate()); |
| 363 __ mov(x1, xzr); |
| 364 __ Mov(ip0, restarter_frame_function_slot); |
| 365 __ str(x1, MemOperand(ip0, 0)); |
| 366 |
| 367 // We do not know our frame height, but set sp based on fp. |
| 368 __ sub(jssp, fp, Operand(kPointerSize)); |
| 369 |
| 370 __ Pop(x1, fp, lr); // Function, Frame, Return address. |
| 371 |
| 372 // Load context from the function. |
| 373 __ ldr(cp, FieldMemOperand(x1, JSFunction::kContextOffset)); |
| 374 |
| 375 // Get function code. |
| 376 __ ldr(ip0, FieldMemOperand(x1, JSFunction::kSharedFunctionInfoOffset)); |
| 377 __ ldr(ip0, FieldMemOperand(ip0, SharedFunctionInfo::kCodeOffset)); |
| 378 __ add(ip0, ip0, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 379 |
| 380 // Re-run JSFunction, x1 is function, cp is context. |
| 381 __ Jump(ip0); |
350 } | 382 } |
351 | 383 |
352 | 384 |
353 const bool LiveEdit::kFrameDropperSupported = false; | 385 const bool LiveEdit::kFrameDropperSupported = true; |
354 | 386 |
355 } } // namespace v8::internal | 387 } } // namespace v8::internal |
356 | 388 |
357 #endif // V8_TARGET_ARCH_ARM64 | 389 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |