5 #include "src/objects/debug-objects.h" 7 #include "src/debug/debug-evaluate.h" 8 #include "src/handles-inl.h" 9 #include "src/objects/debug-objects-inl.h" 10 #include "src/ostreams.h" 15 bool DebugInfo::IsEmpty()
const {
16 return flags() == kNone && debugger_hints() == 0;
19 bool DebugInfo::HasBreakInfo()
const {
return (flags() & kHasBreakInfo) != 0; }
21 DebugInfo::ExecutionMode DebugInfo::DebugExecutionMode()
const {
22 return (flags() & kDebugExecutionMode) != 0 ? kSideEffects : kBreakpoints;
25 void DebugInfo::SetDebugExecutionMode(ExecutionMode value) {
26 set_flags(value == kSideEffects ? (flags() | kDebugExecutionMode)
27 : (flags() & ~kDebugExecutionMode));
30 void DebugInfo::ClearBreakInfo(Isolate* isolate) {
31 if (HasInstrumentedBytecodeArray()) {
34 shared()->SetDebugBytecodeArray(OriginalBytecodeArray());
35 set_original_bytecode_array(ReadOnlyRoots(isolate).undefined_value());
36 set_debug_bytecode_array(ReadOnlyRoots(isolate).undefined_value());
38 set_break_points(ReadOnlyRoots(isolate).empty_fixed_array());
40 int new_flags = flags();
41 new_flags &= ~kHasBreakInfo & ~kPreparedForDebugExecution;
42 new_flags &= ~kBreakAtEntry & ~kCanBreakAtEntry;
43 new_flags &= ~kDebugExecutionMode;
47 void DebugInfo::SetBreakAtEntry() {
48 DCHECK(CanBreakAtEntry());
49 set_flags(flags() | kBreakAtEntry);
52 void DebugInfo::ClearBreakAtEntry() {
53 DCHECK(CanBreakAtEntry());
54 set_flags(flags() & ~kBreakAtEntry);
57 bool DebugInfo::BreakAtEntry()
const {
return (flags() & kBreakAtEntry) != 0; }
59 bool DebugInfo::CanBreakAtEntry()
const {
60 return (flags() & kCanBreakAtEntry) != 0;
64 bool DebugInfo::HasBreakPoint(Isolate* isolate,
int source_position) {
65 DCHECK(HasBreakInfo());
67 Object* break_point_info = GetBreakPointInfo(isolate, source_position);
71 if (break_point_info->IsUndefined(isolate))
return false;
72 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount(isolate) >
77 Object* DebugInfo::GetBreakPointInfo(Isolate* isolate,
int source_position) {
78 DCHECK(HasBreakInfo());
79 for (
int i = 0;
i < break_points()->length();
i++) {
80 if (!break_points()->get(
i)->IsUndefined(isolate)) {
81 BreakPointInfo* break_point_info =
82 BreakPointInfo::cast(break_points()->
get(
i));
83 if (break_point_info->source_position() == source_position) {
84 return break_point_info;
88 return ReadOnlyRoots(isolate).undefined_value();
91 bool DebugInfo::ClearBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
92 Handle<BreakPoint> break_point) {
93 DCHECK(debug_info->HasBreakInfo());
94 for (
int i = 0;
i < debug_info->break_points()->length();
i++) {
95 if (debug_info->break_points()->get(
i)->IsUndefined(isolate))
continue;
96 Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
97 BreakPointInfo::cast(debug_info->break_points()->get(
i)), isolate);
98 if (BreakPointInfo::HasBreakPoint(isolate, break_point_info, break_point)) {
99 BreakPointInfo::ClearBreakPoint(isolate, break_point_info, break_point);
106 void DebugInfo::SetBreakPoint(Isolate* isolate, Handle<DebugInfo> debug_info,
108 Handle<BreakPoint> break_point) {
109 DCHECK(debug_info->HasBreakInfo());
110 Handle<Object> break_point_info(
111 debug_info->GetBreakPointInfo(isolate, source_position), isolate);
112 if (!break_point_info->IsUndefined(isolate)) {
113 BreakPointInfo::SetBreakPoint(
114 isolate, Handle<BreakPointInfo>::cast(break_point_info), break_point);
120 static const int kNoBreakPointInfo = -1;
121 int index = kNoBreakPointInfo;
122 for (
int i = 0;
i < debug_info->break_points()->length();
i++) {
123 if (debug_info->break_points()->get(
i)->IsUndefined(isolate)) {
128 if (index == kNoBreakPointInfo) {
130 Handle<FixedArray> old_break_points =
131 Handle<FixedArray>(debug_info->break_points(), isolate);
132 Handle<FixedArray> new_break_points = isolate->factory()->NewFixedArray(
133 old_break_points->length() +
134 DebugInfo::kEstimatedNofBreakPointsInFunction);
136 debug_info->set_break_points(*new_break_points);
137 for (
int i = 0;
i < old_break_points->length();
i++) {
138 new_break_points->set(
i, old_break_points->get(
i));
140 index = old_break_points->length();
142 DCHECK_NE(index, kNoBreakPointInfo);
145 Handle<BreakPointInfo> new_break_point_info =
146 isolate->factory()->NewBreakPointInfo(source_position);
147 BreakPointInfo::SetBreakPoint(isolate, new_break_point_info, break_point);
148 debug_info->break_points()->set(index, *new_break_point_info);
152 Handle<Object> DebugInfo::GetBreakPoints(Isolate* isolate,
153 int source_position) {
154 DCHECK(HasBreakInfo());
155 Object* break_point_info = GetBreakPointInfo(isolate, source_position);
156 if (break_point_info->IsUndefined(isolate)) {
157 return isolate->factory()->undefined_value();
159 return Handle<Object>(BreakPointInfo::cast(break_point_info)->break_points(),
164 int DebugInfo::GetBreakPointCount(Isolate* isolate) {
165 DCHECK(HasBreakInfo());
167 for (
int i = 0;
i < break_points()->length();
i++) {
168 if (!break_points()->get(
i)->IsUndefined(isolate)) {
169 BreakPointInfo* break_point_info =
170 BreakPointInfo::cast(break_points()->
get(
i));
171 count += break_point_info->GetBreakPointCount(isolate);
177 Handle<Object> DebugInfo::FindBreakPointInfo(Isolate* isolate,
178 Handle<DebugInfo> debug_info,
179 Handle<BreakPoint> break_point) {
180 DCHECK(debug_info->HasBreakInfo());
181 for (
int i = 0;
i < debug_info->break_points()->length();
i++) {
182 if (!debug_info->break_points()->get(
i)->IsUndefined(isolate)) {
183 Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>(
184 BreakPointInfo::cast(debug_info->break_points()->get(
i)), isolate);
185 if (BreakPointInfo::HasBreakPoint(isolate, break_point_info,
187 return break_point_info;
191 return isolate->factory()->undefined_value();
194 bool DebugInfo::HasCoverageInfo()
const {
195 return (flags() & kHasCoverageInfo) != 0;
198 void DebugInfo::ClearCoverageInfo(Isolate* isolate) {
199 if (HasCoverageInfo()) {
200 set_coverage_info(ReadOnlyRoots(isolate).undefined_value());
202 int new_flags = flags() & ~kHasCoverageInfo;
203 set_flags(new_flags);
207 DebugInfo::SideEffectState DebugInfo::GetSideEffectState(Isolate* isolate) {
208 if (side_effect_state() == kNotComputed) {
209 SideEffectState has_no_side_effect =
210 DebugEvaluate::FunctionGetSideEffectState(isolate,
211 handle(shared(), isolate));
212 set_side_effect_state(has_no_side_effect);
214 return static_cast<SideEffectState
>(side_effect_state());
218 bool IsEqual(BreakPoint* break_point1, BreakPoint* break_point2) {
219 return break_point1->id() == break_point2->id();
224 void BreakPointInfo::ClearBreakPoint(Isolate* isolate,
225 Handle<BreakPointInfo> break_point_info,
226 Handle<BreakPoint> break_point) {
228 if (break_point_info->break_points()->IsUndefined(isolate))
return;
230 if (!break_point_info->break_points()->IsFixedArray()) {
231 if (IsEqual(BreakPoint::cast(break_point_info->break_points()),
233 break_point_info->set_break_points(
234 ReadOnlyRoots(isolate).undefined_value());
239 DCHECK(break_point_info->break_points()->IsFixedArray());
240 Handle<FixedArray> old_array = Handle<FixedArray>(
241 FixedArray::cast(break_point_info->break_points()), isolate);
242 Handle<FixedArray> new_array =
243 isolate->factory()->NewFixedArray(old_array->length() - 1);
245 for (
int i = 0;
i < old_array->length();
i++) {
246 if (IsEqual(BreakPoint::cast(old_array->get(
i)), *break_point)) {
247 DCHECK_EQ(found_count, 0);
250 new_array->set(
i - found_count, old_array->get(
i));
254 if (found_count > 0) break_point_info->set_break_points(*new_array);
258 void BreakPointInfo::SetBreakPoint(Isolate* isolate,
259 Handle<BreakPointInfo> break_point_info,
260 Handle<BreakPoint> break_point) {
262 if (break_point_info->break_points()->IsUndefined(isolate)) {
263 break_point_info->set_break_points(*break_point);
267 if (break_point_info->break_points() == *break_point)
return;
269 if (!break_point_info->break_points()->IsFixedArray()) {
270 Handle<FixedArray> array = isolate->factory()->NewFixedArray(2);
271 array->set(0, break_point_info->break_points());
272 array->set(1, *break_point);
273 break_point_info->set_break_points(*array);
277 Handle<FixedArray> old_array = Handle<FixedArray>(
278 FixedArray::cast(break_point_info->break_points()), isolate);
279 Handle<FixedArray> new_array =
280 isolate->factory()->NewFixedArray(old_array->length() + 1);
281 for (
int i = 0;
i < old_array->length();
i++) {
283 if (IsEqual(BreakPoint::cast(old_array->get(
i)), *break_point))
return;
284 new_array->set(
i, old_array->get(
i));
287 new_array->set(old_array->length(), *break_point);
288 break_point_info->set_break_points(*new_array);
291 bool BreakPointInfo::HasBreakPoint(Isolate* isolate,
292 Handle<BreakPointInfo> break_point_info,
293 Handle<BreakPoint> break_point) {
295 if (break_point_info->break_points()->IsUndefined(isolate)) {
299 if (!break_point_info->break_points()->IsFixedArray()) {
300 return IsEqual(BreakPoint::cast(break_point_info->break_points()),
304 FixedArray array = FixedArray::cast(break_point_info->break_points());
305 for (
int i = 0;
i < array->length();
i++) {
306 if (IsEqual(BreakPoint::cast(array->get(
i)), *break_point)) {
314 int BreakPointInfo::GetBreakPointCount(Isolate* isolate) {
316 if (break_points()->IsUndefined(isolate))
return 0;
318 if (!break_points()->IsFixedArray())
return 1;
320 return FixedArray::cast(break_points())->length();
323 int CoverageInfo::SlotCount()
const {
324 DCHECK_EQ(kFirstSlotIndex, length() % kSlotIndexCount);
325 return (length() - kFirstSlotIndex) / kSlotIndexCount;
328 int CoverageInfo::StartSourcePosition(
int slot_index)
const {
329 DCHECK_LT(slot_index, SlotCount());
330 const int slot_start = CoverageInfo::FirstIndexForSlot(slot_index);
331 return Smi::ToInt(
get(slot_start + kSlotStartSourcePositionIndex));
334 int CoverageInfo::EndSourcePosition(
int slot_index)
const {
335 DCHECK_LT(slot_index, SlotCount());
336 const int slot_start = CoverageInfo::FirstIndexForSlot(slot_index);
337 return Smi::ToInt(
get(slot_start + kSlotEndSourcePositionIndex));
340 int CoverageInfo::BlockCount(
int slot_index)
const {
341 DCHECK_LT(slot_index, SlotCount());
342 const int slot_start = CoverageInfo::FirstIndexForSlot(slot_index);
343 return Smi::ToInt(
get(slot_start + kSlotBlockCountIndex));
346 void CoverageInfo::InitializeSlot(
int slot_index,
int from_pos,
int to_pos) {
347 DCHECK_LT(slot_index, SlotCount());
348 const int slot_start = CoverageInfo::FirstIndexForSlot(slot_index);
349 set(slot_start + kSlotStartSourcePositionIndex, Smi::FromInt(from_pos));
350 set(slot_start + kSlotEndSourcePositionIndex, Smi::FromInt(to_pos));
351 set(slot_start + kSlotBlockCountIndex, Smi::kZero);
354 void CoverageInfo::IncrementBlockCount(
int slot_index) {
355 DCHECK_LT(slot_index, SlotCount());
356 const int slot_start = CoverageInfo::FirstIndexForSlot(slot_index);
357 const int old_count = BlockCount(slot_index);
358 set(slot_start + kSlotBlockCountIndex, Smi::FromInt(old_count + 1));
361 void CoverageInfo::ResetBlockCount(
int slot_index) {
362 DCHECK_LT(slot_index, SlotCount());
363 const int slot_start = CoverageInfo::FirstIndexForSlot(slot_index);
364 set(slot_start + kSlotBlockCountIndex, Smi::kZero);
367 void CoverageInfo::Print(std::unique_ptr<
char[]> function_name) {
368 DCHECK(FLAG_trace_block_coverage);
369 DisallowHeapAllocation no_gc;
372 os <<
"Coverage info (";
373 if (strlen(function_name.get()) > 0) {
374 os << function_name.get();
378 os <<
"):" << std::endl;
380 for (
int i = 0;
i < SlotCount();
i++) {
381 os <<
"{" << StartSourcePosition(
i) <<
"," << EndSourcePosition(
i) <<
"}"