OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/objects/debug-objects.h" |
| 6 #include "src/objects/debug-objects-inl.h" |
| 7 |
| 8 namespace v8 { |
| 9 namespace internal { |
| 10 |
| 11 // Check if there is a break point at this source position. |
| 12 bool DebugInfo::HasBreakPoint(int source_position) { |
| 13 // Get the break point info object for this code offset. |
| 14 Object* break_point_info = GetBreakPointInfo(source_position); |
| 15 |
| 16 // If there is no break point info object or no break points in the break |
| 17 // point info object there is no break point at this code offset. |
| 18 if (break_point_info->IsUndefined(GetIsolate())) return false; |
| 19 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
| 20 } |
| 21 |
| 22 // Get the break point info object for this source position. |
| 23 Object* DebugInfo::GetBreakPointInfo(int source_position) { |
| 24 Isolate* isolate = GetIsolate(); |
| 25 if (!break_points()->IsUndefined(isolate)) { |
| 26 for (int i = 0; i < break_points()->length(); i++) { |
| 27 if (!break_points()->get(i)->IsUndefined(isolate)) { |
| 28 BreakPointInfo* break_point_info = |
| 29 BreakPointInfo::cast(break_points()->get(i)); |
| 30 if (break_point_info->source_position() == source_position) { |
| 31 return break_point_info; |
| 32 } |
| 33 } |
| 34 } |
| 35 } |
| 36 return isolate->heap()->undefined_value(); |
| 37 } |
| 38 |
| 39 bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, |
| 40 Handle<Object> break_point_object) { |
| 41 Isolate* isolate = debug_info->GetIsolate(); |
| 42 if (debug_info->break_points()->IsUndefined(isolate)) return false; |
| 43 |
| 44 for (int i = 0; i < debug_info->break_points()->length(); i++) { |
| 45 if (debug_info->break_points()->get(i)->IsUndefined(isolate)) continue; |
| 46 Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>( |
| 47 BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate); |
| 48 if (BreakPointInfo::HasBreakPointObject(break_point_info, |
| 49 break_point_object)) { |
| 50 BreakPointInfo::ClearBreakPoint(break_point_info, break_point_object); |
| 51 return true; |
| 52 } |
| 53 } |
| 54 return false; |
| 55 } |
| 56 |
| 57 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position, |
| 58 Handle<Object> break_point_object) { |
| 59 Isolate* isolate = debug_info->GetIsolate(); |
| 60 Handle<Object> break_point_info( |
| 61 debug_info->GetBreakPointInfo(source_position), isolate); |
| 62 if (!break_point_info->IsUndefined(isolate)) { |
| 63 BreakPointInfo::SetBreakPoint( |
| 64 Handle<BreakPointInfo>::cast(break_point_info), break_point_object); |
| 65 return; |
| 66 } |
| 67 |
| 68 // Adding a new break point for a code offset which did not have any |
| 69 // break points before. Try to find a free slot. |
| 70 static const int kNoBreakPointInfo = -1; |
| 71 int index = kNoBreakPointInfo; |
| 72 for (int i = 0; i < debug_info->break_points()->length(); i++) { |
| 73 if (debug_info->break_points()->get(i)->IsUndefined(isolate)) { |
| 74 index = i; |
| 75 break; |
| 76 } |
| 77 } |
| 78 if (index == kNoBreakPointInfo) { |
| 79 // No free slot - extend break point info array. |
| 80 Handle<FixedArray> old_break_points = Handle<FixedArray>( |
| 81 FixedArray::cast(debug_info->break_points()), isolate); |
| 82 Handle<FixedArray> new_break_points = isolate->factory()->NewFixedArray( |
| 83 old_break_points->length() + |
| 84 DebugInfo::kEstimatedNofBreakPointsInFunction); |
| 85 |
| 86 debug_info->set_break_points(*new_break_points); |
| 87 for (int i = 0; i < old_break_points->length(); i++) { |
| 88 new_break_points->set(i, old_break_points->get(i)); |
| 89 } |
| 90 index = old_break_points->length(); |
| 91 } |
| 92 DCHECK(index != kNoBreakPointInfo); |
| 93 |
| 94 // Allocate new BreakPointInfo object and set the break point. |
| 95 Handle<BreakPointInfo> new_break_point_info = |
| 96 isolate->factory()->NewBreakPointInfo(source_position); |
| 97 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); |
| 98 debug_info->break_points()->set(index, *new_break_point_info); |
| 99 } |
| 100 |
| 101 // Get the break point objects for a source position. |
| 102 Handle<Object> DebugInfo::GetBreakPointObjects(int source_position) { |
| 103 Object* break_point_info = GetBreakPointInfo(source_position); |
| 104 Isolate* isolate = GetIsolate(); |
| 105 if (break_point_info->IsUndefined(isolate)) { |
| 106 return isolate->factory()->undefined_value(); |
| 107 } |
| 108 return Handle<Object>( |
| 109 BreakPointInfo::cast(break_point_info)->break_point_objects(), isolate); |
| 110 } |
| 111 |
| 112 // Get the total number of break points. |
| 113 int DebugInfo::GetBreakPointCount() { |
| 114 Isolate* isolate = GetIsolate(); |
| 115 if (break_points()->IsUndefined(isolate)) return 0; |
| 116 int count = 0; |
| 117 for (int i = 0; i < break_points()->length(); i++) { |
| 118 if (!break_points()->get(i)->IsUndefined(isolate)) { |
| 119 BreakPointInfo* break_point_info = |
| 120 BreakPointInfo::cast(break_points()->get(i)); |
| 121 count += break_point_info->GetBreakPointCount(); |
| 122 } |
| 123 } |
| 124 return count; |
| 125 } |
| 126 |
| 127 Handle<Object> DebugInfo::FindBreakPointInfo( |
| 128 Handle<DebugInfo> debug_info, Handle<Object> break_point_object) { |
| 129 Isolate* isolate = debug_info->GetIsolate(); |
| 130 if (!debug_info->break_points()->IsUndefined(isolate)) { |
| 131 for (int i = 0; i < debug_info->break_points()->length(); i++) { |
| 132 if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) { |
| 133 Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>( |
| 134 BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate); |
| 135 if (BreakPointInfo::HasBreakPointObject(break_point_info, |
| 136 break_point_object)) { |
| 137 return break_point_info; |
| 138 } |
| 139 } |
| 140 } |
| 141 } |
| 142 return isolate->factory()->undefined_value(); |
| 143 } |
| 144 |
| 145 // Remove the specified break point object. |
| 146 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info, |
| 147 Handle<Object> break_point_object) { |
| 148 Isolate* isolate = break_point_info->GetIsolate(); |
| 149 // If there are no break points just ignore. |
| 150 if (break_point_info->break_point_objects()->IsUndefined(isolate)) return; |
| 151 // If there is a single break point clear it if it is the same. |
| 152 if (!break_point_info->break_point_objects()->IsFixedArray()) { |
| 153 if (break_point_info->break_point_objects() == *break_point_object) { |
| 154 break_point_info->set_break_point_objects( |
| 155 isolate->heap()->undefined_value()); |
| 156 } |
| 157 return; |
| 158 } |
| 159 // If there are multiple break points shrink the array |
| 160 DCHECK(break_point_info->break_point_objects()->IsFixedArray()); |
| 161 Handle<FixedArray> old_array = Handle<FixedArray>( |
| 162 FixedArray::cast(break_point_info->break_point_objects())); |
| 163 Handle<FixedArray> new_array = |
| 164 isolate->factory()->NewFixedArray(old_array->length() - 1); |
| 165 int found_count = 0; |
| 166 for (int i = 0; i < old_array->length(); i++) { |
| 167 if (old_array->get(i) == *break_point_object) { |
| 168 DCHECK(found_count == 0); |
| 169 found_count++; |
| 170 } else { |
| 171 new_array->set(i - found_count, old_array->get(i)); |
| 172 } |
| 173 } |
| 174 // If the break point was found in the list change it. |
| 175 if (found_count > 0) break_point_info->set_break_point_objects(*new_array); |
| 176 } |
| 177 |
| 178 // Add the specified break point object. |
| 179 void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info, |
| 180 Handle<Object> break_point_object) { |
| 181 Isolate* isolate = break_point_info->GetIsolate(); |
| 182 |
| 183 // If there was no break point objects before just set it. |
| 184 if (break_point_info->break_point_objects()->IsUndefined(isolate)) { |
| 185 break_point_info->set_break_point_objects(*break_point_object); |
| 186 return; |
| 187 } |
| 188 // If the break point object is the same as before just ignore. |
| 189 if (break_point_info->break_point_objects() == *break_point_object) return; |
| 190 // If there was one break point object before replace with array. |
| 191 if (!break_point_info->break_point_objects()->IsFixedArray()) { |
| 192 Handle<FixedArray> array = isolate->factory()->NewFixedArray(2); |
| 193 array->set(0, break_point_info->break_point_objects()); |
| 194 array->set(1, *break_point_object); |
| 195 break_point_info->set_break_point_objects(*array); |
| 196 return; |
| 197 } |
| 198 // If there was more than one break point before extend array. |
| 199 Handle<FixedArray> old_array = Handle<FixedArray>( |
| 200 FixedArray::cast(break_point_info->break_point_objects())); |
| 201 Handle<FixedArray> new_array = |
| 202 isolate->factory()->NewFixedArray(old_array->length() + 1); |
| 203 for (int i = 0; i < old_array->length(); i++) { |
| 204 // If the break point was there before just ignore. |
| 205 if (old_array->get(i) == *break_point_object) return; |
| 206 new_array->set(i, old_array->get(i)); |
| 207 } |
| 208 // Add the new break point. |
| 209 new_array->set(old_array->length(), *break_point_object); |
| 210 break_point_info->set_break_point_objects(*new_array); |
| 211 } |
| 212 |
| 213 bool BreakPointInfo::HasBreakPointObject( |
| 214 Handle<BreakPointInfo> break_point_info, |
| 215 Handle<Object> break_point_object) { |
| 216 // No break point. |
| 217 Isolate* isolate = break_point_info->GetIsolate(); |
| 218 if (break_point_info->break_point_objects()->IsUndefined(isolate)) { |
| 219 return false; |
| 220 } |
| 221 // Single break point. |
| 222 if (!break_point_info->break_point_objects()->IsFixedArray()) { |
| 223 return break_point_info->break_point_objects() == *break_point_object; |
| 224 } |
| 225 // Multiple break points. |
| 226 FixedArray* array = FixedArray::cast(break_point_info->break_point_objects()); |
| 227 for (int i = 0; i < array->length(); i++) { |
| 228 if (array->get(i) == *break_point_object) { |
| 229 return true; |
| 230 } |
| 231 } |
| 232 return false; |
| 233 } |
| 234 |
| 235 // Get the number of break points. |
| 236 int BreakPointInfo::GetBreakPointCount() { |
| 237 // No break point. |
| 238 if (break_point_objects()->IsUndefined(GetIsolate())) return 0; |
| 239 // Single break point. |
| 240 if (!break_point_objects()->IsFixedArray()) return 1; |
| 241 // Multiple break points. |
| 242 return FixedArray::cast(break_point_objects())->length(); |
| 243 } |
| 244 |
| 245 } // namespace internal |
| 246 } // namespace v8 |
OLD | NEW |