| 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 "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "codegen.h" | 9 #include "codegen.h" |
| 10 #include "debug.h" | 10 #include "debug.h" |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 | 73 |
| 74 | 74 |
| 75 bool BreakLocationIterator::IsDebugBreakAtSlot() { | 75 bool BreakLocationIterator::IsDebugBreakAtSlot() { |
| 76 ASSERT(IsDebugBreakSlot()); | 76 ASSERT(IsDebugBreakSlot()); |
| 77 // Check whether the debug break slot instructions have been patched. | 77 // Check whether the debug break slot instructions have been patched. |
| 78 return rinfo()->IsPatchedDebugBreakSlotSequence(); | 78 return rinfo()->IsPatchedDebugBreakSlotSequence(); |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| 82 void BreakLocationIterator::SetDebugBreakAtSlot() { | 82 void BreakLocationIterator::SetDebugBreakAtSlot() { |
| 83 // Patch the code emitted by Debug::GenerateSlots, changing the debug break | 83 // Patch the code emitted by DebugCodegen::GenerateSlots, changing the debug |
| 84 // slot code from | 84 // break slot code from |
| 85 // mov x0, x0 @ nop DEBUG_BREAK_NOP | 85 // mov x0, x0 @ nop DEBUG_BREAK_NOP |
| 86 // mov x0, x0 @ nop DEBUG_BREAK_NOP | 86 // mov x0, x0 @ nop DEBUG_BREAK_NOP |
| 87 // mov x0, x0 @ nop DEBUG_BREAK_NOP | 87 // mov x0, x0 @ nop DEBUG_BREAK_NOP |
| 88 // mov x0, x0 @ nop DEBUG_BREAK_NOP | 88 // mov x0, x0 @ nop DEBUG_BREAK_NOP |
| 89 // to a call to the debug slot code. | 89 // to a call to the debug slot code. |
| 90 // ldr ip0, [pc, #(2 * kInstructionSize)] | 90 // ldr ip0, [pc, #(2 * kInstructionSize)] |
| 91 // blr ip0 | 91 // blr ip0 |
| 92 // <debug break slot code ... | 92 // <debug break slot code ... |
| 93 // ... entry point address (64 bits)> | 93 // ... entry point address (64 bits)> |
| 94 | 94 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 116 patcher.dc64(reinterpret_cast<int64_t>(entry)); | 116 patcher.dc64(reinterpret_cast<int64_t>(entry)); |
| 117 } | 117 } |
| 118 | 118 |
| 119 | 119 |
| 120 void BreakLocationIterator::ClearDebugBreakAtSlot() { | 120 void BreakLocationIterator::ClearDebugBreakAtSlot() { |
| 121 ASSERT(IsDebugBreakSlot()); | 121 ASSERT(IsDebugBreakSlot()); |
| 122 rinfo()->PatchCode(original_rinfo()->pc(), | 122 rinfo()->PatchCode(original_rinfo()->pc(), |
| 123 Assembler::kDebugBreakSlotInstructions); | 123 Assembler::kDebugBreakSlotInstructions); |
| 124 } | 124 } |
| 125 | 125 |
| 126 const bool Debug::FramePaddingLayout::kIsSupported = false; | |
| 127 | 126 |
| 128 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, | 127 static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
| 129 RegList object_regs, | 128 RegList object_regs, |
| 130 RegList non_object_regs, | 129 RegList non_object_regs, |
| 131 Register scratch) { | 130 Register scratch) { |
| 132 { | 131 { |
| 133 FrameScope scope(masm, StackFrame::INTERNAL); | 132 FrameScope scope(masm, StackFrame::INTERNAL); |
| 134 | 133 |
| 135 // Any live values (object_regs and non_object_regs) in caller-saved | 134 // Any live values (object_regs and non_object_regs) in caller-saved |
| 136 // registers (or lr) need to be stored on the stack so that their values are | 135 // registers (or lr) need to be stored on the stack so that their values are |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 // jumping to the target address intended by the caller and that was | 207 // jumping to the target address intended by the caller and that was |
| 209 // overwritten by the address of DebugBreakXXX. | 208 // overwritten by the address of DebugBreakXXX. |
| 210 ExternalReference after_break_target = | 209 ExternalReference after_break_target = |
| 211 ExternalReference::debug_after_break_target_address(masm->isolate()); | 210 ExternalReference::debug_after_break_target_address(masm->isolate()); |
| 212 __ Mov(scratch, after_break_target); | 211 __ Mov(scratch, after_break_target); |
| 213 __ Ldr(scratch, MemOperand(scratch)); | 212 __ Ldr(scratch, MemOperand(scratch)); |
| 214 __ Br(scratch); | 213 __ Br(scratch); |
| 215 } | 214 } |
| 216 | 215 |
| 217 | 216 |
| 218 void Debug::GenerateCallICStubDebugBreak(MacroAssembler* masm) { | 217 void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { |
| 219 // Register state for CallICStub | 218 // Register state for CallICStub |
| 220 // ----------- S t a t e ------------- | 219 // ----------- S t a t e ------------- |
| 221 // -- x1 : function | 220 // -- x1 : function |
| 222 // -- x3 : slot in feedback array | 221 // -- x3 : slot in feedback array |
| 223 // ----------------------------------- | 222 // ----------------------------------- |
| 224 Generate_DebugBreakCallHelper(masm, x1.Bit() | x3.Bit(), 0, x10); | 223 Generate_DebugBreakCallHelper(masm, x1.Bit() | x3.Bit(), 0, x10); |
| 225 } | 224 } |
| 226 | 225 |
| 227 | 226 |
| 228 void Debug::GenerateLoadICDebugBreak(MacroAssembler* masm) { | 227 void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { |
| 229 // Calling convention for IC load (from ic-arm.cc). | 228 // Calling convention for IC load (from ic-arm.cc). |
| 230 // ----------- S t a t e ------------- | 229 // ----------- S t a t e ------------- |
| 231 // -- x2 : name | 230 // -- x2 : name |
| 232 // -- lr : return address | 231 // -- lr : return address |
| 233 // -- x0 : receiver | 232 // -- x0 : receiver |
| 234 // -- [sp] : receiver | 233 // -- [sp] : receiver |
| 235 // ----------------------------------- | 234 // ----------------------------------- |
| 236 // Registers x0 and x2 contain objects that need to be pushed on the | 235 // Registers x0 and x2 contain objects that need to be pushed on the |
| 237 // expression stack of the fake JS frame. | 236 // expression stack of the fake JS frame. |
| 238 Generate_DebugBreakCallHelper(masm, x0.Bit() | x2.Bit(), 0, x10); | 237 Generate_DebugBreakCallHelper(masm, x0.Bit() | x2.Bit(), 0, x10); |
| 239 } | 238 } |
| 240 | 239 |
| 241 | 240 |
| 242 void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) { | 241 void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { |
| 243 // Calling convention for IC store (from ic-arm.cc). | 242 // Calling convention for IC store (from ic-arm.cc). |
| 244 // ----------- S t a t e ------------- | 243 // ----------- S t a t e ------------- |
| 245 // -- x0 : value | 244 // -- x0 : value |
| 246 // -- x1 : receiver | 245 // -- x1 : receiver |
| 247 // -- x2 : name | 246 // -- x2 : name |
| 248 // -- lr : return address | 247 // -- lr : return address |
| 249 // ----------------------------------- | 248 // ----------------------------------- |
| 250 // Registers x0, x1, and x2 contain objects that need to be pushed on the | 249 // Registers x0, x1, and x2 contain objects that need to be pushed on the |
| 251 // expression stack of the fake JS frame. | 250 // expression stack of the fake JS frame. |
| 252 Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit() | x2.Bit(), 0, x10); | 251 Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit() | x2.Bit(), 0, x10); |
| 253 } | 252 } |
| 254 | 253 |
| 255 | 254 |
| 256 void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { | 255 void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { |
| 257 // ---------- S t a t e -------------- | 256 // ---------- S t a t e -------------- |
| 258 // -- lr : return address | 257 // -- lr : return address |
| 259 // -- x0 : key | 258 // -- x0 : key |
| 260 // -- x1 : receiver | 259 // -- x1 : receiver |
| 261 Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit(), 0, x10); | 260 Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit(), 0, x10); |
| 262 } | 261 } |
| 263 | 262 |
| 264 | 263 |
| 265 void Debug::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { | 264 void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { |
| 266 // ---------- S t a t e -------------- | 265 // ---------- S t a t e -------------- |
| 267 // -- x0 : value | 266 // -- x0 : value |
| 268 // -- x1 : key | 267 // -- x1 : key |
| 269 // -- x2 : receiver | 268 // -- x2 : receiver |
| 270 // -- lr : return address | 269 // -- lr : return address |
| 271 Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit() | x2.Bit(), 0, x10); | 270 Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit() | x2.Bit(), 0, x10); |
| 272 } | 271 } |
| 273 | 272 |
| 274 | 273 |
| 275 void Debug::GenerateCompareNilICDebugBreak(MacroAssembler* masm) { | 274 void DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) { |
| 276 // Register state for CompareNil IC | 275 // Register state for CompareNil IC |
| 277 // ----------- S t a t e ------------- | 276 // ----------- S t a t e ------------- |
| 278 // -- r0 : value | 277 // -- r0 : value |
| 279 // ----------------------------------- | 278 // ----------------------------------- |
| 280 Generate_DebugBreakCallHelper(masm, x0.Bit(), 0, x10); | 279 Generate_DebugBreakCallHelper(masm, x0.Bit(), 0, x10); |
| 281 } | 280 } |
| 282 | 281 |
| 283 | 282 |
| 284 void Debug::GenerateReturnDebugBreak(MacroAssembler* masm) { | 283 void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { |
| 285 // In places other than IC call sites it is expected that r0 is TOS which | 284 // In places other than IC call sites it is expected that r0 is TOS which |
| 286 // is an object - this is not generally the case so this should be used with | 285 // is an object - this is not generally the case so this should be used with |
| 287 // care. | 286 // care. |
| 288 Generate_DebugBreakCallHelper(masm, x0.Bit(), 0, x10); | 287 Generate_DebugBreakCallHelper(masm, x0.Bit(), 0, x10); |
| 289 } | 288 } |
| 290 | 289 |
| 291 | 290 |
| 292 void Debug::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) { | 291 void DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) { |
| 293 // Register state for CallFunctionStub (from code-stubs-arm64.cc). | 292 // Register state for CallFunctionStub (from code-stubs-arm64.cc). |
| 294 // ----------- S t a t e ------------- | 293 // ----------- S t a t e ------------- |
| 295 // -- x1 : function | 294 // -- x1 : function |
| 296 // ----------------------------------- | 295 // ----------------------------------- |
| 297 Generate_DebugBreakCallHelper(masm, x1.Bit(), 0, x10); | 296 Generate_DebugBreakCallHelper(masm, x1.Bit(), 0, x10); |
| 298 } | 297 } |
| 299 | 298 |
| 300 | 299 |
| 301 void Debug::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) { | 300 void DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) { |
| 302 // Calling convention for CallConstructStub (from code-stubs-arm64.cc). | 301 // Calling convention for CallConstructStub (from code-stubs-arm64.cc). |
| 303 // ----------- S t a t e ------------- | 302 // ----------- S t a t e ------------- |
| 304 // -- x0 : number of arguments (not smi) | 303 // -- x0 : number of arguments (not smi) |
| 305 // -- x1 : constructor function | 304 // -- x1 : constructor function |
| 306 // ----------------------------------- | 305 // ----------------------------------- |
| 307 Generate_DebugBreakCallHelper(masm, x1.Bit(), x0.Bit(), x10); | 306 Generate_DebugBreakCallHelper(masm, x1.Bit(), x0.Bit(), x10); |
| 308 } | 307 } |
| 309 | 308 |
| 310 | 309 |
| 311 void Debug::GenerateCallConstructStubRecordDebugBreak(MacroAssembler* masm) { | 310 void DebugCodegen::GenerateCallConstructStubRecordDebugBreak( |
| 311 MacroAssembler* masm) { |
| 312 // Calling convention for CallConstructStub (from code-stubs-arm64.cc). | 312 // Calling convention for CallConstructStub (from code-stubs-arm64.cc). |
| 313 // ----------- S t a t e ------------- | 313 // ----------- S t a t e ------------- |
| 314 // -- x0 : number of arguments (not smi) | 314 // -- x0 : number of arguments (not smi) |
| 315 // -- x1 : constructor function | 315 // -- x1 : constructor function |
| 316 // -- x2 : feedback array | 316 // -- x2 : feedback array |
| 317 // -- x3 : feedback slot (smi) | 317 // -- x3 : feedback slot (smi) |
| 318 // ----------------------------------- | 318 // ----------------------------------- |
| 319 Generate_DebugBreakCallHelper( | 319 Generate_DebugBreakCallHelper( |
| 320 masm, x1.Bit() | x2.Bit() | x3.Bit(), x0.Bit(), x10); | 320 masm, x1.Bit() | x2.Bit() | x3.Bit(), x0.Bit(), x10); |
| 321 } | 321 } |
| 322 | 322 |
| 323 | 323 |
| 324 void Debug::GenerateSlot(MacroAssembler* masm) { | 324 void DebugCodegen::GenerateSlot(MacroAssembler* masm) { |
| 325 // Generate enough nop's to make space for a call instruction. Avoid emitting | 325 // Generate enough nop's to make space for a call instruction. Avoid emitting |
| 326 // the constant pool in the debug break slot code. | 326 // the constant pool in the debug break slot code. |
| 327 InstructionAccurateScope scope(masm, Assembler::kDebugBreakSlotInstructions); | 327 InstructionAccurateScope scope(masm, Assembler::kDebugBreakSlotInstructions); |
| 328 | 328 |
| 329 __ RecordDebugBreakSlot(); | 329 __ RecordDebugBreakSlot(); |
| 330 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { | 330 for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { |
| 331 __ nop(Assembler::DEBUG_BREAK_NOP); | 331 __ nop(Assembler::DEBUG_BREAK_NOP); |
| 332 } | 332 } |
| 333 } | 333 } |
| 334 | 334 |
| 335 | 335 |
| 336 void Debug::GenerateSlotDebugBreak(MacroAssembler* masm) { | 336 void DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { |
| 337 // In the places where a debug break slot is inserted no registers can contain | 337 // In the places where a debug break slot is inserted no registers can contain |
| 338 // object pointers. | 338 // object pointers. |
| 339 Generate_DebugBreakCallHelper(masm, 0, 0, x10); | 339 Generate_DebugBreakCallHelper(masm, 0, 0, x10); |
| 340 } | 340 } |
| 341 | 341 |
| 342 | 342 |
| 343 void Debug::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { | 343 void DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { |
| 344 masm->Abort(kLiveEditFrameDroppingIsNotSupportedOnARM64); | 344 masm->Abort(kLiveEditFrameDroppingIsNotSupportedOnARM64); |
| 345 } | 345 } |
| 346 | 346 |
| 347 | 347 |
| 348 void Debug::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { | 348 void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { |
| 349 masm->Abort(kLiveEditFrameDroppingIsNotSupportedOnARM64); | 349 masm->Abort(kLiveEditFrameDroppingIsNotSupportedOnARM64); |
| 350 } | 350 } |
| 351 | 351 |
| 352 const bool Debug::kFrameDropperSupported = false; | 352 |
| 353 const bool LiveEdit::kFrameDropperSupported = false; |
| 353 | 354 |
| 354 } } // namespace v8::internal | 355 } } // namespace v8::internal |
| 355 | 356 |
| 356 #endif // V8_TARGET_ARCH_ARM64 | 357 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |