OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 BreakLocatorType type) | 62 BreakLocatorType type) |
63 : debug_info_(debug_info), | 63 : debug_info_(debug_info), |
64 type_(type), | 64 type_(type), |
65 reloc_iterator_(debug_info->code(), | 65 reloc_iterator_(debug_info->code(), |
66 ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)), | 66 ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)), |
67 reloc_iterator_original_( | 67 reloc_iterator_original_( |
68 debug_info->original_code(), | 68 debug_info->original_code(), |
69 ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)), | 69 ~RelocInfo::ModeMask(RelocInfo::CODE_AGE_SEQUENCE)), |
70 break_index_(-1), | 70 break_index_(-1), |
71 position_(1), | 71 position_(1), |
72 statement_position_(1) { | 72 statement_position_(1), |
| 73 has_immediate_position_(false) { |
73 Next(); | 74 Next(); |
74 } | 75 } |
75 | 76 |
76 | 77 |
77 void BreakLocation::Iterator::Next() { | 78 void BreakLocation::Iterator::Next() { |
78 DisallowHeapAllocation no_gc; | 79 DisallowHeapAllocation no_gc; |
79 DCHECK(!RinfoDone()); | 80 DCHECK(!RinfoDone()); |
80 | 81 |
81 // Iterate through reloc info for code and original code stopping at each | 82 // Iterate through reloc info for code and original code stopping at each |
82 // breakable code target. | 83 // breakable code target. |
83 bool first = break_index_ == -1; | 84 bool first = break_index_ == -1; |
84 while (!RinfoDone()) { | 85 while (!RinfoDone()) { |
85 if (!first) RinfoNext(); | 86 if (!first) RinfoNext(); |
86 first = false; | 87 first = false; |
87 if (RinfoDone()) return; | 88 if (RinfoDone()) return; |
88 | 89 |
89 // Whenever a statement position or (plain) position is passed update the | 90 // Whenever a statement position or (plain) position is passed update the |
90 // current value of these. | 91 // current value of these. |
91 if (RelocInfo::IsPosition(rmode())) { | 92 if (RelocInfo::IsPosition(rmode())) { |
92 if (RelocInfo::IsStatementPosition(rmode())) { | 93 if (RelocInfo::IsStatementPosition(rmode())) { |
93 statement_position_ = static_cast<int>( | 94 statement_position_ = static_cast<int>( |
94 rinfo()->data() - debug_info_->shared()->start_position()); | 95 rinfo()->data() - debug_info_->shared()->start_position()); |
95 } | 96 } |
96 // Always update the position as we don't want that to be before the | 97 // Always update the position as we don't want that to be before the |
97 // statement position. | 98 // statement position. |
98 position_ = static_cast<int>(rinfo()->data() - | 99 position_ = static_cast<int>(rinfo()->data() - |
99 debug_info_->shared()->start_position()); | 100 debug_info_->shared()->start_position()); |
100 DCHECK(position_ >= 0); | 101 DCHECK(position_ >= 0); |
101 DCHECK(statement_position_ >= 0); | 102 DCHECK(statement_position_ >= 0); |
| 103 has_immediate_position_ = true; |
| 104 continue; |
102 } | 105 } |
103 | 106 |
104 // Check for break at return. | 107 // Check for break at return. |
105 if (RelocInfo::IsJSReturn(rmode())) { | 108 if (RelocInfo::IsJSReturn(rmode())) { |
106 // Set the positions to the end of the function. | 109 // Set the positions to the end of the function. |
107 if (debug_info_->shared()->HasSourceCode()) { | 110 if (debug_info_->shared()->HasSourceCode()) { |
108 position_ = debug_info_->shared()->end_position() - | 111 position_ = debug_info_->shared()->end_position() - |
109 debug_info_->shared()->start_position() - 1; | 112 debug_info_->shared()->start_position() - 1; |
110 } else { | 113 } else { |
111 position_ = 0; | 114 position_ = 0; |
112 } | 115 } |
113 statement_position_ = position_; | 116 statement_position_ = position_; |
114 break_index_++; | 117 break_index_++; |
115 return; | 118 break; |
116 } | 119 } |
117 | 120 |
118 if (RelocInfo::IsCodeTarget(rmode())) { | 121 if (RelocInfo::IsCodeTarget(rmode())) { |
119 // Check for breakable code target. Look in the original code as setting | 122 // Check for breakable code target. Look in the original code as setting |
120 // break points can cause the code targets in the running (debugged) code | 123 // break points can cause the code targets in the running (debugged) code |
121 // to be of a different kind than in the original code. | 124 // to be of a different kind than in the original code. |
122 Address target = original_rinfo()->target_address(); | 125 Address target = original_rinfo()->target_address(); |
123 Code* code = Code::GetCodeFromTargetAddress(target); | 126 Code* code = Code::GetCodeFromTargetAddress(target); |
124 | 127 |
125 if (RelocInfo::IsConstructCall(rmode()) || code->is_call_stub()) { | 128 if (RelocInfo::IsConstructCall(rmode()) || code->is_call_stub()) { |
126 break_index_++; | 129 break_index_++; |
127 return; | 130 break; |
128 } | 131 } |
129 | 132 |
130 // Skip below if we only want locations for calls and returns. | 133 // Skip below if we only want locations for calls and returns. |
131 if (type_ == CALLS_AND_RETURNS) continue; | 134 if (type_ == CALLS_AND_RETURNS) continue; |
132 | 135 |
133 if ((code->is_inline_cache_stub() && !code->is_binary_op_stub() && | 136 // Only break at an inline cache if it has an immediate position attached. |
| 137 if (has_immediate_position_ && |
| 138 (code->is_inline_cache_stub() && !code->is_binary_op_stub() && |
134 !code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) { | 139 !code->is_compare_ic_stub() && !code->is_to_boolean_ic_stub())) { |
135 break_index_++; | 140 break_index_++; |
136 return; | 141 break; |
137 } | 142 } |
138 if (code->kind() == Code::STUB) { | 143 if (code->kind() == Code::STUB) { |
139 if (RelocInfo::IsDebuggerStatement(rmode())) { | 144 if (RelocInfo::IsDebuggerStatement(rmode())) { |
140 break_index_++; | 145 break_index_++; |
141 return; | 146 break; |
142 } else if (CodeStub::GetMajorKey(code) == CodeStub::CallFunction) { | 147 } else if (CodeStub::GetMajorKey(code) == CodeStub::CallFunction) { |
143 break_index_++; | 148 break_index_++; |
144 return; | 149 break; |
145 } | 150 } |
146 } | 151 } |
147 } | 152 } |
148 | 153 |
149 if (RelocInfo::IsDebugBreakSlot(rmode()) && type_ != CALLS_AND_RETURNS) { | 154 if (RelocInfo::IsDebugBreakSlot(rmode()) && type_ != CALLS_AND_RETURNS) { |
150 // There is always a possible break point at a debug break slot. | 155 // There is always a possible break point at a debug break slot. |
151 break_index_++; | 156 break_index_++; |
152 return; | 157 break; |
153 } | 158 } |
154 } | 159 } |
| 160 has_immediate_position_ = false; |
155 } | 161 } |
156 | 162 |
157 | 163 |
158 // Find the break point at the supplied address, or the closest one before | 164 // Find the break point at the supplied address, or the closest one before |
159 // the address. | 165 // the address. |
160 BreakLocation BreakLocation::FromAddress(Handle<DebugInfo> debug_info, | 166 BreakLocation BreakLocation::FromAddress(Handle<DebugInfo> debug_info, |
161 BreakLocatorType type, Address pc) { | 167 BreakLocatorType type, Address pc) { |
162 Iterator it(debug_info, type); | 168 Iterator it(debug_info, type); |
163 it.SkipTo(BreakIndexFromAddress(debug_info, type, pc)); | 169 it.SkipTo(BreakIndexFromAddress(debug_info, type, pc)); |
164 return it.GetBreakLocation(); | 170 return it.GetBreakLocation(); |
(...skipping 3197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3362 logger_->DebugEvent("Put", message.text()); | 3368 logger_->DebugEvent("Put", message.text()); |
3363 } | 3369 } |
3364 | 3370 |
3365 | 3371 |
3366 void LockingCommandMessageQueue::Clear() { | 3372 void LockingCommandMessageQueue::Clear() { |
3367 base::LockGuard<base::Mutex> lock_guard(&mutex_); | 3373 base::LockGuard<base::Mutex> lock_guard(&mutex_); |
3368 queue_.Clear(); | 3374 queue_.Clear(); |
3369 } | 3375 } |
3370 | 3376 |
3371 } } // namespace v8::internal | 3377 } } // namespace v8::internal |
OLD | NEW |