1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8.h" 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_TARGET_ARCH_ARM 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/codegen.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/debug.h" 11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool BreakLocationIterator::IsDebugBreakAtReturn() { 16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Debug::IsDebugBreakAtReturn(rinfo()); 17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::SetDebugBreakAtReturn() { 21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Patch the code changing the return from JS function sequence from 22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // mov sp, fp 23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ldmia sp!, {fp, lr} 24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // add sp, sp, #4 25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // bx lr 26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // to a call to the debug break return code. 276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // ldr ip, [pc, #0] 286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block // blx ip 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // <debug break return code entry point address> 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // bkpt 0 317f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions); 326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); 336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block patcher.masm()->blx(v8::internal::ip); 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch patcher.Emit( 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry()); 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block patcher.masm()->bkpt(0); 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Restore the JS frame exit code. 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid BreakLocationIterator::ClearDebugBreakAtReturn() { 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block rinfo()->PatchCode(original_rinfo()->pc(), 437f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Assembler::kJSReturnSequenceInstructions); 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 477f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// A debug break in the frame exit code is identified by the JS frame exit code 487f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch// having been patched with a call instruction. 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) { 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(RelocInfo::IsJSReturn(rinfo->rmode())); 513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block return rinfo->IsPatchedReturnSequence(); 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 557f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochbool BreakLocationIterator::IsDebugBreakAtSlot() { 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsDebugBreakSlot()); 577f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Check whether the debug break slot instructions have been patched. 587f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch return rinfo()->IsPatchedDebugBreakSlotSequence(); 597f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 607f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakLocationIterator::SetDebugBreakAtSlot() { 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsDebugBreakSlot()); 647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Patch the code changing the debug break slot code from 657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // mov r2, r2 667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // mov r2, r2 677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // mov r2, r2 687f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // to a call to the debug break slot code. 697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // ldr ip, [pc, #0] 707f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // blx ip 717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // <debug break slot code entry point address> 727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions); 737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); 747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch patcher.masm()->blx(v8::internal::ip); 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch patcher.Emit( 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry()); 777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 787f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdochvoid BreakLocationIterator::ClearDebugBreakAtSlot() { 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(IsDebugBreakSlot()); 827f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch rinfo()->PatchCode(original_rinfo()->pc(), 837f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Assembler::kDebugBreakSlotInstructions); 847f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 857f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __ ACCESS_MASM(masm) 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void Generate_DebugBreakCallHelper(MacroAssembler* masm, 9180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen RegList object_regs, 9280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen RegList non_object_regs) { 933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch { 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load padding words on stack. 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue))); 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ push(ip); 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ push(ip); 1033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Store the registers containing live values on the expression stack to 1053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // make sure that these are correctly updated during GC. Non object values 1063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // are stored as a smi causing it to be untouched by GC. 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((object_regs & ~kJSCallerSaved) == 0); 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((non_object_regs & ~kJSCallerSaved) == 0); 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK((object_regs & non_object_regs) == 0); 1103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((object_regs | non_object_regs) != 0) { 1113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < kNumJSCallerSaved; i++) { 1123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int r = JSCallerSavedCode(i); 1133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = { r }; 1143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((non_object_regs & (1 << r)) != 0) { 1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_debug_code) { 1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ tst(reg, Operand(0xc0000000)); 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Assert(eq, kUnableToEncodeValueAsSmi); 1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ SmiTag(reg); 12080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 12180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 1223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ stm(db_w, sp, object_regs | non_object_regs); 12380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 1263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ RecordComment("// Calling from debug break to runtime - come in - over"); 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r0, Operand::Zero()); // no arguments 1293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(r1, Operand(ExternalReference::debug_break(masm->isolate()))); 1303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CEntryStub ceb(masm->isolate(), 1); 1323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ CallStub(&ceb); 1333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 1343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Restore the register values from the expression stack. 1353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((object_regs | non_object_regs) != 0) { 1363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ ldm(ia_w, sp, object_regs | non_object_regs); 1373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (int i = 0; i < kNumJSCallerSaved; i++) { 1383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch int r = JSCallerSavedCode(i); 1393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Register reg = { r }; 1403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if ((non_object_regs & (1 << r)) != 0) { 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ SmiUntag(reg); 1423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 1433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch if (FLAG_debug_code && 1443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch (((object_regs |non_object_regs) & (1 << r)) == 0)) { 1453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch __ mov(reg, Operand(kDebugZapValue)); 1463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 14780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 14880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen } 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Don't bother removing padding bytes pushed on the stack 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // as the frame is going to be restored right away. 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Leave the internal frame. 1543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch } 15585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Now that the break point has been handled, resume normal execution by 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // jumping to the target address intended by the caller and that was 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // overwritten by the address of DebugBreakXXX. 15944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExternalReference after_break_target = 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::debug_after_break_target_address(masm->isolate()); 16144f0eee88ff00398ff7f715fab053374d808c90dSteve Block __ mov(ip, Operand(after_break_target)); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ ldr(ip, MemOperand(ip)); 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block __ Jump(ip); 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register state for CallICStub 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------- S t a t e ------------- 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- r1 : function 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- r3 : slot in feedback array (smi) 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------------------------------- 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Generate_DebugBreakCallHelper(masm, r1.bit() | r3.bit(), 0); 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calling convention for IC load (from ic-arm.cc). 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register receiver = LoadDescriptor::ReceiverRegister(); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register name = LoadDescriptor::NameRegister(); 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0); 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Calling convention for IC store (from ic-arm.cc). 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register receiver = StoreDescriptor::ReceiverRegister(); 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register name = StoreDescriptor::NameRegister(); 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value = StoreDescriptor::ValueRegister(); 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Generate_DebugBreakCallHelper( 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm, receiver.bit() | name.bit() | value.bit(), 0); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calling convention for keyed IC load (from ic-arm.cc). 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch GenerateLoadICDebugBreak(masm); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Calling convention for IC keyed store call (from ic-arm.cc). 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register receiver = StoreDescriptor::ReceiverRegister(); 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register name = StoreDescriptor::NameRegister(); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register value = StoreDescriptor::ValueRegister(); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Generate_DebugBreakCallHelper( 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm, receiver.bit() | name.bit() | value.bit(), 0); 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) { 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register state for CompareNil IC 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------- S t a t e ------------- 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- r0 : value 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // ----------------------------------- 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Generate_DebugBreakCallHelper(masm, r0.bit(), 0); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // In places other than IC call sites it is expected that r0 is TOS which 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // is an object - this is not generally the case so this should be used with 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // care. 22480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Generate_DebugBreakCallHelper(masm, r0.bit(), 0); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) { 2293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Register state for CallFunctionStub (from code-stubs-arm.cc). 2303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ----------- S t a t e ------------- 2313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // -- r1 : function 2323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ----------------------------------- 2333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Generate_DebugBreakCallHelper(masm, r1.bit(), 0); 2343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) { 2383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Calling convention for CallConstructStub (from code-stubs-arm.cc) 2393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ----------- S t a t e ------------- 2403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // -- r0 : number of arguments (not smi) 2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // -- r1 : constructor function 2423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // ----------------------------------- 2433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Generate_DebugBreakCallHelper(masm, r1.bit(), r0.bit()); 2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch} 2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 2463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateCallConstructStubRecordDebugBreak( 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm) { 2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // Calling convention for CallConstructStub (from code-stubs-arm.cc) 2505d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // ----------- S t a t e ------------- 2513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // -- r0 : number of arguments (not smi) 2523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch // -- r1 : constructor function 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- r2 : feedback array 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // -- r3 : feedback slot (smi) 2555d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch // ----------------------------------- 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Generate_DebugBreakCallHelper(masm, r1.bit() | r2.bit() | r3.bit(), r0.bit()); 2575d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch} 2585d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 2595d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateSlot(MacroAssembler* masm) { 2617f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // Generate enough nop's to make space for a call instruction. Avoid emitting 2627f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // the constant pool in the debug break slot code. 2637f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Assembler::BlockConstPoolScope block_const_pool(masm); 2647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch Label check_codesize; 2657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch __ bind(&check_codesize); 2667f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch __ RecordDebugBreakSlot(); 2677f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) { 2688a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang __ nop(MacroAssembler::DEBUG_BREAK_NOP); 2697f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch } 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_EQ(Assembler::kDebugBreakSlotInstructions, 2717f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch masm->InstructionsGeneratedSince(&check_codesize)); 2727f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2737f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2747f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) { 2767f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // In the places where a debug break slot is inserted no registers can contain 2777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch // object pointers. 27880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen Generate_DebugBreakCallHelper(masm, 0, 0); 2797f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch} 2807f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 2817f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) { 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Ret(); 2846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block} 2856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 2867f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference restarter_frame_function_slot = 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference::debug_restarter_frame_function_pointer_address( 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch masm->isolate()); 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(ip, Operand(restarter_frame_function_slot)); 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ mov(r1, Operand::Zero()); 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ str(r1, MemOperand(ip, 0)); 2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load the function pointer off of our current stack frame. 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(r1, MemOperand(fp, 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch StandardFrameConstants::kConstantPoolOffset - kPointerSize)); 298756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Pop return address, frame and constant pool pointer (if 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // FLAG_enable_ool_constant_pool). 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ LeaveFrame(StackFrame::INTERNAL); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch { ConstantPoolUnavailableScope constant_pool_unavailable(masm); 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Load context from the function. 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Get function code. 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(ip, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ ldr(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset)); 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ add(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Re-run JSFunction, r1 is function, cp is context. 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch __ Jump(ip); 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 3166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 3176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst bool LiveEdit::kFrameDropperSupported = true; 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef __ 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 323f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke 324f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke#endif // V8_TARGET_ARCH_ARM 325