Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Unified Diff: runtime/vm/debugger.cc

Issue 2904793002: Allow setting breakpoints in literal function initializers of fields. (Closed)
Patch Set: Add comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/debugger.cc
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 5f14a55b5d82ae539b3440296112a5859ed59bce..f61b06d27a8f6f533e66ba56d16525ef8dde7392 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -20,6 +20,7 @@
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/os.h"
+#include "vm/parser.h"
#include "vm/port.h"
#include "vm/runtime_entry.h"
#include "vm/service.h"
@@ -2708,6 +2709,52 @@ RawFunction* Debugger::FindBestFit(const Script& script,
}
+// Return true if |token_pos| is within the token range of a function
+// literal initializer of a field.
+bool Debugger::MatchesLiteralFunctionPos(const Script& script,
+ TokenPosition token_pos,
+ TokenPosition last_token_pos) {
+ Zone* zone = Thread::Current()->zone();
+ Class& cls = Class::Handle(zone);
+ Array& fields = Array::Handle(zone);
+ Field& field = Field::Handle(zone);
+ Error& error = Error::Handle(zone);
+
+ const ClassTable& class_table = *isolate_->class_table();
+ const intptr_t num_classes = class_table.NumCids();
+ for (intptr_t i = 1; i < num_classes; i++) {
+ if (class_table.HasValidClassAt(i)) {
+ cls = class_table.At(i);
+ ASSERT(!cls.IsNull());
+ if (cls.script() != script.raw()) {
+ continue;
+ }
+ error = cls.EnsureIsFinalized(Thread::Current());
+ if (!error.IsNull()) {
+ continue;
+ }
+ fields = cls.fields();
+ if (!fields.IsNull()) {
+ const intptr_t num_fields = fields.Length();
+ for (intptr_t pos = 0; pos < num_fields; pos++) {
+ TokenPosition start;
+ TokenPosition end;
+ field ^= fields.At(pos);
+ ASSERT(!field.IsNull());
+ if (Parser::FieldHasFunctionLiteralInitializer(field, &start, &end)) {
+ if ((start <= token_pos && token_pos <= end) ||
+ (token_pos <= start && start <= last_token_pos)) {
siva 2017/05/24 19:51:23 Not sure why this last_token_pos check needs to be
sivachandra 2017/05/26 07:17:58 We want the field initializer to start within the
+ return true;
+ }
+ }
+ }
+ }
+ }
siva 2017/05/24 19:51:23 Can the loop above be folded into Debugger::FindBe
sivachandra 2017/05/26 07:17:58 I have removed this new method and folded the esse
+ }
+ return false;
+}
+
+
BreakpointLocation* Debugger::SetBreakpoint(const Script& script,
TokenPosition token_pos,
TokenPosition last_token_pos,
@@ -2715,67 +2762,78 @@ BreakpointLocation* Debugger::SetBreakpoint(const Script& script,
intptr_t requested_column) {
Function& func = Function::Handle();
func = FindBestFit(script, token_pos);
- if (func.IsNull()) {
- return NULL;
- }
- // There may be more than one function object for a given function
- // in source code. There may be implicit closure functions, and
- // there may be copies of mixin functions. Collect all compiled
- // functions whose source code range matches exactly the best fit
- // function we found.
- GrowableObjectArray& functions =
- GrowableObjectArray::Handle(GrowableObjectArray::New());
- FindCompiledFunctions(script, func.token_pos(), func.end_token_pos(),
- &functions);
-
- if (functions.Length() > 0) {
- // One or more function object containing this breakpoint location
- // have already been compiled. We can resolve the breakpoint now.
- DeoptimizeWorld();
- func ^= functions.At(0);
- TokenPosition breakpoint_pos =
- ResolveBreakpointPos(func, token_pos, last_token_pos, requested_column);
- if (breakpoint_pos.IsReal()) {
- BreakpointLocation* bpt =
- GetBreakpointLocation(script, breakpoint_pos, requested_column);
- if (bpt != NULL) {
- // A source breakpoint for this location already exists.
+ if (!func.IsNull()) {
+ // There may be more than one function object for a given function
+ // in source code. There may be implicit closure functions, and
+ // there may be copies of mixin functions. Collect all compiled
+ // functions whose source code range matches exactly the best fit
+ // function we found.
+ GrowableObjectArray& functions =
+ GrowableObjectArray::Handle(GrowableObjectArray::New());
+ FindCompiledFunctions(script, func.token_pos(), func.end_token_pos(),
+ &functions);
+
+ if (functions.Length() > 0) {
+ // One or more function object containing this breakpoint location
+ // have already been compiled. We can resolve the breakpoint now.
+ DeoptimizeWorld();
+ func ^= functions.At(0);
+ TokenPosition breakpoint_pos = ResolveBreakpointPos(
+ func, token_pos, last_token_pos, requested_column);
+ if (breakpoint_pos.IsReal()) {
+ BreakpointLocation* bpt =
+ GetBreakpointLocation(script, breakpoint_pos, requested_column);
+ if (bpt != NULL) {
+ // A source breakpoint for this location already exists.
+ return bpt;
+ }
+ bpt = new BreakpointLocation(script, token_pos, last_token_pos,
+ requested_line, requested_column);
+ bpt->SetResolved(func, breakpoint_pos);
+ RegisterBreakpointLocation(bpt);
+
+ // Create code breakpoints for all compiled functions we found.
+ const intptr_t num_functions = functions.Length();
+ for (intptr_t i = 0; i < num_functions; i++) {
+ func ^= functions.At(i);
+ ASSERT(func.HasCode());
+ MakeCodeBreakpointAt(func, bpt);
+ }
+ if (FLAG_verbose_debug) {
+ intptr_t line_number;
+ intptr_t column_number;
+ script.GetTokenLocation(breakpoint_pos, &line_number, &column_number);
+ OS::Print(
+ "Resolved BP for "
+ "function '%s' at line %" Pd " col %" Pd "\n",
+ func.ToFullyQualifiedCString(), line_number, column_number);
+ }
return bpt;
}
- bpt = new BreakpointLocation(script, token_pos, last_token_pos,
- requested_line, requested_column);
- bpt->SetResolved(func, breakpoint_pos);
- RegisterBreakpointLocation(bpt);
-
- // Create code breakpoints for all compiled functions we found.
- const intptr_t num_functions = functions.Length();
- for (intptr_t i = 0; i < num_functions; i++) {
- func ^= functions.At(i);
- ASSERT(func.HasCode());
- MakeCodeBreakpointAt(func, bpt);
- }
- if (FLAG_verbose_debug) {
- intptr_t line_number;
- intptr_t column_number;
- script.GetTokenLocation(breakpoint_pos, &line_number, &column_number);
- OS::Print(
- "Resolved BP for "
- "function '%s' at line %" Pd " col %" Pd "\n",
- func.ToFullyQualifiedCString(), line_number, column_number);
- }
- return bpt;
}
+ } else if (!MatchesLiteralFunctionPos(script, token_pos, last_token_pos)) {
+ // |token_pos| is not within the range of a function literal initializer of
+ // a field.
+ return NULL;
}
- // There is no compiled function at this token position.
- // Register an unresolved breakpoint.
- if (FLAG_verbose_debug && !func.IsNull()) {
+ // There is either an uncompiled function, or an uncompiled function literal
+ // initializer of a field at |token_pos|. Hence, Register an unresolved
+ // breakpoint.
+ if (FLAG_verbose_debug) {
intptr_t line_number;
intptr_t column_number;
script.GetTokenLocation(token_pos, &line_number, &column_number);
- OS::Print(
- "Registering pending breakpoint for "
- "uncompiled function '%s' at line %" Pd " col %" Pd "\n",
- func.ToFullyQualifiedCString(), line_number, column_number);
+ if (func.IsNull()) {
+ OS::Print(
+ "Registering pending breakpoint for "
+ "an uncompiled function literal at line %" Pd " col %" Pd "\n",
+ line_number, column_number);
+ } else {
+ OS::Print(
+ "Registering pending breakpoint for "
+ "uncompiled function '%s' at line %" Pd " col %" Pd "\n",
+ func.ToFullyQualifiedCString(), line_number, column_number);
+ }
}
BreakpointLocation* bpt =
GetBreakpointLocation(script, token_pos, requested_column);
« no previous file with comments | « runtime/vm/debugger.h ('k') | runtime/vm/debugger_test.cc » ('j') | runtime/vm/debugger_test.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698