| 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 | 
|---|