Debugger: ensure that break points are set in code that contain debug break slots.
authoryangguo <yangguo@chromium.org>
Wed, 1 Jul 2015 08:01:14 +0000 (01:01 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 1 Jul 2015 08:01:24 +0000 (08:01 +0000)
We now consistently ignore native and extension scripts for debugging. Only native scripts and extension scripts can disallow lazy compilation. So we can make sure that break points are only set to code that are compiled with debug break slots.

R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/1216193002

Cr-Commit-Position: refs/heads/master@{#29400}

src/debug.cc
src/isolate.cc
src/objects-inl.h
src/objects.h
src/runtime/runtime-debug.cc

index d62586a..77711ec 100644 (file)
@@ -253,6 +253,7 @@ BreakLocation BreakLocation::FromPosition(Handle<DebugInfo> debug_info,
 void BreakLocation::SetBreakPoint(Handle<Object> break_point_object) {
   // If there is not already a real break point here patch code with debug
   // break.
+  DCHECK(code()->has_debug_break_slots());
   if (!HasBreakPoint()) SetDebugBreak();
   DCHECK(IsDebugBreak() || IsDebuggerStatement());
   // Set the break point information.
@@ -1083,8 +1084,8 @@ void Debug::ClearAllBreakPoints() {
 
 void Debug::FloodWithOneShot(Handle<JSFunction> function,
                              BreakLocatorType type) {
-  // Do not ever break in native functions.
-  if (function->IsFromNativeScript()) return;
+  // Do not ever break in native and extension functions.
+  if (!function->IsSubjectToDebugging()) return;
 
   PrepareForBreakPoints();
 
@@ -1109,7 +1110,7 @@ void Debug::FloodBoundFunctionWithOneShot(Handle<JSFunction> function) {
                         isolate_);
 
   if (!bindee.is_null() && bindee->IsJSFunction() &&
-      !JSFunction::cast(*bindee)->IsFromNativeScript()) {
+      JSFunction::cast(*bindee)->IsSubjectToDebugging()) {
     Handle<JSFunction> bindee_function(JSFunction::cast(*bindee));
     FloodWithOneShotGeneric(bindee_function);
   }
@@ -1307,9 +1308,9 @@ void Debug::PrepareStep(StepAction step_action,
       DCHECK(location.IsExit());
       frames_it.Advance();
     }
-    // Skip builtin functions on the stack.
+    // Skip native and extension functions on the stack.
     while (!frames_it.done() &&
-           frames_it.frame()->function()->IsFromNativeScript()) {
+           !frames_it.frame()->function()->IsSubjectToDebugging()) {
       frames_it.Advance();
     }
     // Step out: If there is a JavaScript caller frame, we need to
@@ -1965,9 +1966,12 @@ void Debug::PrepareForBreakPoints() {
     for (int i = 0; i < active_functions.length(); i++) {
       Handle<JSFunction> function = active_functions[i];
       Handle<SharedFunctionInfo> shared(function->shared());
-
-      // If recompilation is not possible just skip it.
-      if (!shared->allows_lazy_compilation()) continue;
+      if (!shared->allows_lazy_compilation()) {
+        // Ignore functions that cannot be recompiled. Fortunately, those are
+        // only ones that are not subject to debugging in the first place.
+        DCHECK(!function->IsSubjectToDebugging());
+        continue;
+      }
       if (shared->code()->kind() == Code::BUILTIN) continue;
 
       EnsureFunctionHasDebugBreakSlots(function);
index f3d047f..e9d526a 100644 (file)
@@ -320,7 +320,7 @@ static bool IsVisibleInStackTrace(JSFunction* fun,
     if (receiver->IsJSBuiltinsObject()) return false;
     if (fun->IsBuiltin()) {
       return fun->shared()->native();
-    } else if (fun->IsFromNativeScript() || fun->IsFromExtensionScript()) {
+    } else if (!fun->IsSubjectToDebugging()) {
       return false;
     }
   }
@@ -1324,7 +1324,7 @@ bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
   for (int i = 1; i < elements_limit; i += 4) {
     Handle<JSFunction> fun =
         handle(JSFunction::cast(elements->get(i + 1)), this);
-    if (fun->IsFromNativeScript()) continue;
+    if (!fun->IsSubjectToDebugging()) continue;
 
     Object* script = fun->shared()->script();
     if (script->IsScript() &&
index 7952d45..9f535ca 100644 (file)
@@ -5607,6 +5607,11 @@ bool JSFunction::IsFromExtensionScript() {
 }
 
 
+bool JSFunction::IsSubjectToDebugging() {
+  return !IsFromNativeScript() && !IsFromExtensionScript();
+}
+
+
 bool JSFunction::NeedsArgumentsAdaption() {
   return shared()->internal_formal_parameter_count() !=
          SharedFunctionInfo::kDontAdaptArgumentsSentinel;
index ac101e5..0b25aa4 100644 (file)
@@ -7290,6 +7290,9 @@ class JSFunction: public JSObject {
   // Tells whether this function is defined in an extension script.
   inline bool IsFromExtensionScript();
 
+  // Tells whether this function should be subject to debugging.
+  inline bool IsSubjectToDebugging();
+
   // Tells whether or not the function needs arguments adaption.
   inline bool NeedsArgumentsAdaption();
 
index da0934e..e8919b5 100644 (file)
@@ -457,8 +457,8 @@ RUNTIME_FUNCTION(Runtime_GetFrameCount) {
     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
     it.frame()->Summarize(&frames);
     for (int i = frames.length() - 1; i >= 0; i--) {
-      // Omit functions from native scripts.
-      if (!frames[i].function()->IsFromNativeScript()) n++;
+      // Omit functions from native and extension scripts.
+      if (frames[i].function()->IsSubjectToDebugging()) n++;
     }
   }
   return Smi::FromInt(n);
@@ -583,8 +583,8 @@ int Runtime::FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) {
     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
     it->frame()->Summarize(&frames);
     for (int i = frames.length() - 1; i >= 0; i--) {
-      // Omit functions from native scripts.
-      if (frames[i].function()->IsFromNativeScript()) continue;
+      // Omit functions from native and extension scripts.
+      if (!frames[i].function()->IsSubjectToDebugging()) continue;
       if (++count == index) return i;
     }
   }