1// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5#include "vm/globals.h"
6#if defined(TARGET_ARCH_IA32)
7
8#include "vm/debugger.h"
9
10#include "vm/code_patcher.h"
11#include "vm/compiler/assembler/disassembler.h"
12#include "vm/cpu.h"
13#include "vm/object.h"
14#include "vm/os.h"
15#include "vm/stack_frame.h"
16#include "vm/stub_code.h"
17
18namespace dart {
19
20#ifndef PRODUCT
21
22CodePtr CodeBreakpoint::OrigStubAddress() const {
23 return saved_value_;
24}
25
26void CodeBreakpoint::PatchCode() {
27 ASSERT(!is_enabled_);
28 auto thread = Thread::Current();
29 auto zone = thread->zone();
30 const Code& code = Code::Handle(zone, code_);
31 const Instructions& instrs = Instructions::Handle(zone, code.instructions());
32 Code& stub_target = Code::Handle(zone);
33 thread->isolate_group()->RunWithStoppedMutators([&]() {
34 WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
35 switch (breakpoint_kind_) {
36 case PcDescriptorsLayout::kIcCall: {
37 stub_target = StubCode::ICCallBreakpoint().raw();
38 break;
39 }
40 case PcDescriptorsLayout::kUnoptStaticCall: {
41 stub_target = StubCode::UnoptStaticCallBreakpoint().raw();
42 break;
43 }
44 case PcDescriptorsLayout::kRuntimeCall: {
45 saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
46 stub_target = StubCode::RuntimeCallBreakpoint().raw();
47 break;
48 }
49 default:
50 UNREACHABLE();
51 }
52 saved_value_ = CodePatcher::GetStaticCallTargetAt(pc_, code);
53 CodePatcher::PatchStaticCallAt(pc_, code, stub_target);
54 });
55 is_enabled_ = true;
56}
57
58void CodeBreakpoint::RestoreCode() {
59 ASSERT(is_enabled_);
60 auto thread = Thread::Current();
61 auto zone = thread->zone();
62 const Code& code = Code::Handle(zone, code_);
63 const Instructions& instrs = Instructions::Handle(zone, code.instructions());
64 thread->isolate_group()->RunWithStoppedMutators([&]() {
65 WritableInstructionsScope writable(instrs.PayloadStart(), instrs.Size());
66 switch (breakpoint_kind_) {
67 case PcDescriptorsLayout::kIcCall:
68 case PcDescriptorsLayout::kUnoptStaticCall:
69 case PcDescriptorsLayout::kRuntimeCall: {
70 CodePatcher::PatchStaticCallAt(pc_, code, Code::Handle(saved_value_));
71 break;
72 }
73 default:
74 UNREACHABLE();
75 }
76 });
77 is_enabled_ = false;
78}
79
80#endif // !PRODUCT
81
82} // namespace dart
83
84#endif // defined TARGET_ARCH_IA32
85