Index: src/objects/debug-info.cc |
diff --git a/src/objects/debug-info.cc b/src/objects/debug-info.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..402758dd22929ef77776d5ec4280a44307040fe0 |
--- /dev/null |
+++ b/src/objects/debug-info.cc |
@@ -0,0 +1,147 @@ |
+// Copyright 2017 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "src/objects/debug-info.h" |
+ |
+#include "src/objects-inl.h" |
+ |
+namespace v8 { |
+namespace internal { |
+ |
+// Check if there is a break point at this source position. |
+bool DebugInfo::HasBreakPoint(int source_position) { |
+ // Get the break point info object for this code offset. |
+ Object* break_point_info = GetBreakPointInfo(source_position); |
+ |
+ // If there is no break point info object or no break points in the break |
+ // point info object there is no break point at this code offset. |
+ if (break_point_info->IsUndefined(GetIsolate())) return false; |
+ return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
+} |
+ |
+// Get the break point info object for this source position. |
+Object* DebugInfo::GetBreakPointInfo(int source_position) { |
+ Isolate* isolate = GetIsolate(); |
+ if (!break_points()->IsUndefined(isolate)) { |
+ for (int i = 0; i < break_points()->length(); i++) { |
+ if (!break_points()->get(i)->IsUndefined(isolate)) { |
+ BreakPointInfo* break_point_info = |
+ BreakPointInfo::cast(break_points()->get(i)); |
+ if (break_point_info->source_position() == source_position) { |
+ return break_point_info; |
+ } |
+ } |
+ } |
+ } |
+ return isolate->heap()->undefined_value(); |
+} |
+ |
+bool DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, |
+ Handle<Object> break_point_object) { |
+ Isolate* isolate = debug_info->GetIsolate(); |
+ if (debug_info->break_points()->IsUndefined(isolate)) return false; |
+ |
+ for (int i = 0; i < debug_info->break_points()->length(); i++) { |
+ if (debug_info->break_points()->get(i)->IsUndefined(isolate)) continue; |
+ Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>( |
+ BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate); |
+ if (BreakPointInfo::HasBreakPointObject(break_point_info, |
+ break_point_object)) { |
+ BreakPointInfo::ClearBreakPoint(break_point_info, break_point_object); |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
+ |
+void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, int source_position, |
+ Handle<Object> break_point_object) { |
+ Isolate* isolate = debug_info->GetIsolate(); |
+ Handle<Object> break_point_info( |
+ debug_info->GetBreakPointInfo(source_position), isolate); |
+ if (!break_point_info->IsUndefined(isolate)) { |
+ BreakPointInfo::SetBreakPoint( |
+ Handle<BreakPointInfo>::cast(break_point_info), break_point_object); |
+ return; |
+ } |
+ |
+ // Adding a new break point for a code offset which did not have any |
+ // break points before. Try to find a free slot. |
+ static const int kNoBreakPointInfo = -1; |
+ int index = kNoBreakPointInfo; |
+ for (int i = 0; i < debug_info->break_points()->length(); i++) { |
+ if (debug_info->break_points()->get(i)->IsUndefined(isolate)) { |
+ index = i; |
+ break; |
+ } |
+ } |
+ if (index == kNoBreakPointInfo) { |
+ // No free slot - extend break point info array. |
+ Handle<FixedArray> old_break_points = Handle<FixedArray>( |
+ FixedArray::cast(debug_info->break_points()), isolate); |
+ Handle<FixedArray> new_break_points = isolate->factory()->NewFixedArray( |
+ old_break_points->length() + |
+ DebugInfo::kEstimatedNofBreakPointsInFunction); |
+ |
+ debug_info->set_break_points(*new_break_points); |
+ for (int i = 0; i < old_break_points->length(); i++) { |
+ new_break_points->set(i, old_break_points->get(i)); |
+ } |
+ index = old_break_points->length(); |
+ } |
+ DCHECK(index != kNoBreakPointInfo); |
+ |
+ // Allocate new BreakPointInfo object and set the break point. |
+ Handle<BreakPointInfo> new_break_point_info = |
+ isolate->factory()->NewBreakPointInfo(source_position); |
+ BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); |
+ debug_info->break_points()->set(index, *new_break_point_info); |
+} |
+ |
+// Get the break point objects for a source position. |
+Handle<Object> DebugInfo::GetBreakPointObjects(int source_position) { |
+ Object* break_point_info = GetBreakPointInfo(source_position); |
+ Isolate* isolate = GetIsolate(); |
+ if (break_point_info->IsUndefined(isolate)) { |
+ return isolate->factory()->undefined_value(); |
+ } |
+ return Handle<Object>( |
+ BreakPointInfo::cast(break_point_info)->break_point_objects(), isolate); |
+} |
+ |
+// Get the total number of break points. |
+int DebugInfo::GetBreakPointCount() { |
+ Isolate* isolate = GetIsolate(); |
+ if (break_points()->IsUndefined(isolate)) return 0; |
+ int count = 0; |
+ for (int i = 0; i < break_points()->length(); i++) { |
+ if (!break_points()->get(i)->IsUndefined(isolate)) { |
+ BreakPointInfo* break_point_info = |
+ BreakPointInfo::cast(break_points()->get(i)); |
+ count += break_point_info->GetBreakPointCount(); |
+ } |
+ } |
+ return count; |
+} |
+ |
+Handle<Object> DebugInfo::FindBreakPointInfo( |
+ Handle<DebugInfo> debug_info, Handle<Object> break_point_object) { |
+ Isolate* isolate = debug_info->GetIsolate(); |
+ if (!debug_info->break_points()->IsUndefined(isolate)) { |
+ for (int i = 0; i < debug_info->break_points()->length(); i++) { |
+ if (!debug_info->break_points()->get(i)->IsUndefined(isolate)) { |
+ Handle<BreakPointInfo> break_point_info = Handle<BreakPointInfo>( |
+ BreakPointInfo::cast(debug_info->break_points()->get(i)), isolate); |
+ if (BreakPointInfo::HasBreakPointObject(break_point_info, |
+ break_point_object)) { |
+ return break_point_info; |
+ } |
+ } |
+ } |
+ } |
+ return isolate->factory()->undefined_value(); |
+} |
+ |
+} // namespace internal |
+} // namespace v8 |