Merge V8 5.8.283.32

Test: Build V8 for arm, arm64, x86, x86_64, mips, mips64 and
set a PAC script from the UI on bullhead

Change-Id: I7cc773b5daca34d869e768a1deebae3876f2dfac
diff --git a/src/inspector/v8-debugger-agent-impl.cc b/src/inspector/v8-debugger-agent-impl.cc
index 224ae28..7de46a1 100644
--- a/src/inspector/v8-debugger-agent-impl.cc
+++ b/src/inspector/v8-debugger-agent-impl.cc
@@ -54,14 +54,33 @@
 
 }  // namespace DebuggerAgentState
 
-static const int kMaxSkipStepFrameCount = 128;
 static const char kBacktraceObjectGroup[] = "backtrace";
 static const char kDebuggerNotEnabled[] = "Debugger agent is not enabled";
 static const char kDebuggerNotPaused[] =
     "Can only perform operation while paused.";
 
-static String16 breakpointIdSuffix(
-    V8DebuggerAgentImpl::BreakpointSource source) {
+namespace {
+
+void TranslateWasmStackTraceLocations(Array<CallFrame>* stackTrace,
+                                      WasmTranslation* wasmTranslation) {
+  for (size_t i = 0, e = stackTrace->length(); i != e; ++i) {
+    protocol::Debugger::Location* location = stackTrace->get(i)->getLocation();
+    String16 scriptId = location->getScriptId();
+    int lineNumber = location->getLineNumber();
+    int columnNumber = location->getColumnNumber(-1);
+
+    if (!wasmTranslation->TranslateWasmScriptLocationToProtocolLocation(
+            &scriptId, &lineNumber, &columnNumber)) {
+      continue;
+    }
+
+    location->setScriptId(std::move(scriptId));
+    location->setLineNumber(lineNumber);
+    location->setColumnNumber(columnNumber);
+  }
+}
+
+String16 breakpointIdSuffix(V8DebuggerAgentImpl::BreakpointSource source) {
   switch (source) {
     case V8DebuggerAgentImpl::UserBreakpointSource:
       break;
@@ -73,26 +92,25 @@
   return String16();
 }
 
-static String16 generateBreakpointId(
-    const String16& scriptId, int lineNumber, int columnNumber,
-    V8DebuggerAgentImpl::BreakpointSource source) {
+String16 generateBreakpointId(const ScriptBreakpoint& breakpoint,
+                              V8DebuggerAgentImpl::BreakpointSource source) {
   String16Builder builder;
-  builder.append(scriptId);
+  builder.append(breakpoint.script_id);
   builder.append(':');
-  builder.appendNumber(lineNumber);
+  builder.appendNumber(breakpoint.line_number);
   builder.append(':');
-  builder.appendNumber(columnNumber);
+  builder.appendNumber(breakpoint.column_number);
   builder.append(breakpointIdSuffix(source));
   return builder.toString();
 }
 
-static bool positionComparator(const std::pair<int, int>& a,
-                               const std::pair<int, int>& b) {
+bool positionComparator(const std::pair<int, int>& a,
+                        const std::pair<int, int>& b) {
   if (a.first != b.first) return a.first < b.first;
   return a.second < b.second;
 }
 
-static std::unique_ptr<protocol::Debugger::Location> buildProtocolLocation(
+std::unique_ptr<protocol::Debugger::Location> buildProtocolLocation(
     const String16& scriptId, int lineNumber, int columnNumber) {
   return protocol::Debugger::Location::create()
       .setScriptId(scriptId)
@@ -101,6 +119,8 @@
       .build();
 }
 
+}  // namespace
+
 V8DebuggerAgentImpl::V8DebuggerAgentImpl(
     V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel,
     protocol::DictionaryValue* state)
@@ -111,24 +131,14 @@
       m_state(state),
       m_frontend(frontendChannel),
       m_isolate(m_inspector->isolate()),
-      m_breakReason(protocol::Debugger::Paused::ReasonEnum::Other),
       m_scheduledDebuggerStep(NoStep),
-      m_skipNextDebuggerStepOut(false),
       m_javaScriptPauseScheduled(false),
-      m_steppingFromFramework(false),
-      m_pausingOnNativeEvent(false),
-      m_skippedStepFrameCount(0),
-      m_recursionLevelForStepOut(0),
-      m_recursionLevelForStepFrame(0),
-      m_skipAllPauses(false) {
-  clearBreakDetails();
+      m_recursionLevelForStepOut(0) {
 }
 
 V8DebuggerAgentImpl::~V8DebuggerAgentImpl() {}
 
 void V8DebuggerAgentImpl::enableImpl() {
-  // m_inspector->addListener may result in reporting all parsed scripts to
-  // the agent so it should already be in enabled state by then.
   m_enabled = true;
   m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true);
   m_debugger->enable();
@@ -161,29 +171,25 @@
   m_state->setObject(DebuggerAgentState::javaScriptBreakpoints,
                      protocol::DictionaryValue::create());
   m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState,
-                      v8::DebugInterface::NoBreakOnException);
+                      v8::debug::NoBreakOnException);
   m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0);
 
-  if (!m_pausedContext.IsEmpty()) m_debugger->continueProgram();
+  if (isPaused()) m_debugger->continueProgram();
   m_debugger->disable();
-  m_pausedContext.Reset();
   JavaScriptCallFrames emptyCallFrames;
   m_pausedCallFrames.swap(emptyCallFrames);
-  m_scripts.clear();
   m_blackboxedPositions.clear();
+  m_blackboxPattern.reset();
+  resetBlackboxedStateCache();
+  m_scripts.clear();
   m_breakpointIdToDebuggerBreakpointIds.clear();
   m_debugger->setAsyncCallStackDepth(this, 0);
   m_continueToLocationBreakpointId = String16();
   clearBreakDetails();
   m_scheduledDebuggerStep = NoStep;
-  m_skipNextDebuggerStepOut = false;
   m_javaScriptPauseScheduled = false;
-  m_steppingFromFramework = false;
-  m_pausingOnNativeEvent = false;
-  m_skippedStepFrameCount = 0;
-  m_recursionLevelForStepFrame = 0;
   m_skipAllPauses = false;
-  m_blackboxPattern = nullptr;
+  m_state->setBoolean(DebuggerAgentState::skipAllPauses, false);
   m_state->remove(DebuggerAgentState::blackboxPattern);
   m_enabled = false;
   m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
@@ -199,7 +205,7 @@
 
   enableImpl();
 
-  int pauseState = v8::DebugInterface::NoBreakOnException;
+  int pauseState = v8::debug::NoBreakOnException;
   m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState);
   setPauseOnExceptionsImpl(pauseState);
 
@@ -225,8 +231,8 @@
 }
 
 Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) {
+  m_state->setBoolean(DebuggerAgentState::skipAllPauses, skip);
   m_skipAllPauses = skip;
-  m_state->setBoolean(DebuggerAgentState::skipAllPauses, m_skipAllPauses);
   return Response::OK();
 }
 
@@ -291,12 +297,13 @@
       breakpointId, buildObjectForBreakpointCookie(
                         url, lineNumber, columnNumber, condition, isRegex));
 
-  ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
+  ScriptBreakpoint breakpoint(String16(), lineNumber, columnNumber, condition);
   for (const auto& script : m_scripts) {
     if (!matches(m_inspector, script.second->sourceURL(), url, isRegex))
       continue;
-    std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint(
-        breakpointId, script.first, breakpoint, UserBreakpointSource);
+    breakpoint.script_id = script.first;
+    std::unique_ptr<protocol::Debugger::Location> location =
+        resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource);
     if (location) (*locations)->addItem(std::move(location));
   }
 
@@ -308,21 +315,18 @@
     std::unique_ptr<protocol::Debugger::Location> location,
     Maybe<String16> optionalCondition, String16* outBreakpointId,
     std::unique_ptr<protocol::Debugger::Location>* actualLocation) {
-  String16 scriptId = location->getScriptId();
-  int lineNumber = location->getLineNumber();
-  int columnNumber = location->getColumnNumber(0);
+  ScriptBreakpoint breakpoint(
+      location->getScriptId(), location->getLineNumber(),
+      location->getColumnNumber(0), optionalCondition.fromMaybe(String16()));
 
-  String16 condition = optionalCondition.fromMaybe("");
-
-  String16 breakpointId = generateBreakpointId(
-      scriptId, lineNumber, columnNumber, UserBreakpointSource);
+  String16 breakpointId =
+      generateBreakpointId(breakpoint, UserBreakpointSource);
   if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) !=
       m_breakpointIdToDebuggerBreakpointIds.end()) {
     return Response::Error("Breakpoint at specified location already exists.");
   }
-  ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
-  *actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint,
-                                      UserBreakpointSource);
+  *actualLocation =
+      resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource);
   if (!*actualLocation) return Response::Error("Could not resolve breakpoint");
   *outBreakpointId = breakpointId;
   return Response::OK();
@@ -365,9 +369,9 @@
     return Response::Error(
         "start.lineNumber and start.columnNumber should be >= 0");
 
-  v8::DebugInterface::Location v8Start(start->getLineNumber(),
-                                       start->getColumnNumber(0));
-  v8::DebugInterface::Location v8End;
+  v8::debug::Location v8Start(start->getLineNumber(),
+                              start->getColumnNumber(0));
+  v8::debug::Location v8End;
   if (end.isJust()) {
     if (end.fromJust()->getScriptId() != scriptId)
       return Response::Error("Locations should contain the same scriptId");
@@ -376,12 +380,12 @@
     if (line < 0 || column < 0)
       return Response::Error(
           "end.lineNumber and end.columnNumber should be >= 0");
-    v8End = v8::DebugInterface::Location(line, column);
+    v8End = v8::debug::Location(line, column);
   }
   auto it = m_scripts.find(scriptId);
   if (it == m_scripts.end()) return Response::Error("Script not found");
 
-  std::vector<v8::DebugInterface::Location> v8Locations;
+  std::vector<v8::debug::Location> v8Locations;
   if (!it->second->getPossibleBreakpoints(v8Start, v8End, &v8Locations))
     return Response::InternalError();
 
@@ -405,38 +409,20 @@
     m_continueToLocationBreakpointId = "";
   }
 
-  String16 scriptId = location->getScriptId();
-  int lineNumber = location->getLineNumber();
-  int columnNumber = location->getColumnNumber(0);
+  ScriptBreakpoint breakpoint(location->getScriptId(),
+                              location->getLineNumber(),
+                              location->getColumnNumber(0), String16());
 
-  ScriptBreakpoint breakpoint(lineNumber, columnNumber, "");
   m_continueToLocationBreakpointId = m_debugger->setBreakpoint(
-      scriptId, breakpoint, &lineNumber, &columnNumber);
+      breakpoint, &breakpoint.line_number, &breakpoint.column_number);
+  // TODO(kozyatinskiy): Return actual line and column number.
   return resume();
 }
 
-bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() {
-  DCHECK(enabled());
-  JavaScriptCallFrames callFrames = m_debugger->currentCallFrames();
-  for (size_t index = 0; index < callFrames.size(); ++index) {
-    if (!isCallFrameWithUnknownScriptOrBlackboxed(callFrames[index].get()))
-      return false;
-  }
-  return true;
-}
-
-bool V8DebuggerAgentImpl::isTopPausedCallFrameBlackboxed() {
-  DCHECK(enabled());
-  JavaScriptCallFrame* frame =
-      m_pausedCallFrames.size() ? m_pausedCallFrames[0].get() : nullptr;
-  return isCallFrameWithUnknownScriptOrBlackboxed(frame);
-}
-
-bool V8DebuggerAgentImpl::isCallFrameWithUnknownScriptOrBlackboxed(
-    JavaScriptCallFrame* frame) {
-  if (!frame) return true;
-  ScriptsMap::iterator it =
-      m_scripts.find(String16::fromInteger(frame->sourceID()));
+bool V8DebuggerAgentImpl::isFunctionBlackboxed(const String16& scriptId,
+                                               const v8::debug::Location& start,
+                                               const v8::debug::Location& end) {
+  ScriptsMap::iterator it = m_scripts.find(scriptId);
   if (it == m_scripts.end()) {
     // Unknown scripts are blackboxed.
     return true;
@@ -447,78 +433,65 @@
         m_blackboxPattern->match(scriptSourceURL) != -1)
       return true;
   }
-  auto itBlackboxedPositions =
-      m_blackboxedPositions.find(String16::fromInteger(frame->sourceID()));
+  auto itBlackboxedPositions = m_blackboxedPositions.find(scriptId);
   if (itBlackboxedPositions == m_blackboxedPositions.end()) return false;
 
   const std::vector<std::pair<int, int>>& ranges =
       itBlackboxedPositions->second;
-  auto itRange = std::lower_bound(
+  auto itStartRange = std::lower_bound(
       ranges.begin(), ranges.end(),
-      std::make_pair(frame->line(), frame->column()), positionComparator);
+      std::make_pair(start.GetLineNumber(), start.GetColumnNumber()),
+      positionComparator);
+  auto itEndRange = std::lower_bound(
+      itStartRange, ranges.end(),
+      std::make_pair(end.GetLineNumber(), end.GetColumnNumber()),
+      positionComparator);
   // Ranges array contains positions in script where blackbox state is changed.
   // [(0,0) ... ranges[0]) isn't blackboxed, [ranges[0] ... ranges[1]) is
   // blackboxed...
-  return std::distance(ranges.begin(), itRange) % 2;
-}
-
-V8DebuggerAgentImpl::SkipPauseRequest
-V8DebuggerAgentImpl::shouldSkipExceptionPause(
-    JavaScriptCallFrame* topCallFrame) {
-  if (m_steppingFromFramework) return RequestNoSkip;
-  if (isCallFrameWithUnknownScriptOrBlackboxed(topCallFrame))
-    return RequestContinue;
-  return RequestNoSkip;
-}
-
-V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::shouldSkipStepPause(
-    JavaScriptCallFrame* topCallFrame) {
-  if (m_steppingFromFramework) return RequestNoSkip;
-
-  if (m_skipNextDebuggerStepOut) {
-    m_skipNextDebuggerStepOut = false;
-    if (m_scheduledDebuggerStep == StepOut) return RequestStepOut;
-  }
-
-  if (!isCallFrameWithUnknownScriptOrBlackboxed(topCallFrame))
-    return RequestNoSkip;
-
-  if (m_skippedStepFrameCount >= kMaxSkipStepFrameCount) return RequestStepOut;
-
-  if (!m_skippedStepFrameCount) m_recursionLevelForStepFrame = 1;
-
-  ++m_skippedStepFrameCount;
-  return RequestStepFrame;
+  return itStartRange == itEndRange &&
+         std::distance(ranges.begin(), itStartRange) % 2;
 }
 
 std::unique_ptr<protocol::Debugger::Location>
 V8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId,
-                                       const String16& scriptId,
                                        const ScriptBreakpoint& breakpoint,
                                        BreakpointSource source) {
+  v8::HandleScope handles(m_isolate);
   DCHECK(enabled());
   // FIXME: remove these checks once crbug.com/520702 is resolved.
   CHECK(!breakpointId.isEmpty());
-  CHECK(!scriptId.isEmpty());
-  ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
+  CHECK(!breakpoint.script_id.isEmpty());
+  ScriptsMap::iterator scriptIterator = m_scripts.find(breakpoint.script_id);
   if (scriptIterator == m_scripts.end()) return nullptr;
-  if (breakpoint.lineNumber < scriptIterator->second->startLine() ||
-      scriptIterator->second->endLine() < breakpoint.lineNumber)
+  if (breakpoint.line_number < scriptIterator->second->startLine() ||
+      scriptIterator->second->endLine() < breakpoint.line_number)
     return nullptr;
 
+  // Translate from protocol location to v8 location for the debugger.
+  ScriptBreakpoint translatedBreakpoint = breakpoint;
+  m_debugger->wasmTranslation()->TranslateProtocolLocationToWasmScriptLocation(
+      &translatedBreakpoint.script_id, &translatedBreakpoint.line_number,
+      &translatedBreakpoint.column_number);
+
   int actualLineNumber;
   int actualColumnNumber;
   String16 debuggerBreakpointId = m_debugger->setBreakpoint(
-      scriptId, breakpoint, &actualLineNumber, &actualColumnNumber);
+      translatedBreakpoint, &actualLineNumber, &actualColumnNumber);
   if (debuggerBreakpointId.isEmpty()) return nullptr;
 
+  // Translate back from v8 location to protocol location for the return value.
+  m_debugger->wasmTranslation()->TranslateWasmScriptLocationToProtocolLocation(
+      &translatedBreakpoint.script_id, &actualLineNumber, &actualColumnNumber);
+
   m_serverBreakpoints[debuggerBreakpointId] =
       std::make_pair(breakpointId, source);
   CHECK(!breakpointId.isEmpty());
 
   m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back(
       debuggerBreakpointId);
-  return buildProtocolLocation(scriptId, actualLineNumber, actualColumnNumber);
+  return buildProtocolLocation(translatedBreakpoint.script_id, actualLineNumber,
+                               actualColumnNumber);
 }
 
 Response V8DebuggerAgentImpl::searchInContent(
@@ -531,9 +504,8 @@
     return Response::Error("No script for id: " + scriptId);
 
   std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches =
-      searchInTextByLinesImpl(m_session,
-                              toProtocolString(it->second->source(m_isolate)),
-                              query, optionalCaseSensitive.fromMaybe(false),
+      searchInTextByLinesImpl(m_session, it->second->source(m_isolate), query,
+                              optionalCaseSensitive.fromMaybe(false),
                               optionalIsRegex.fromMaybe(false));
   *results = protocol::Array<protocol::Debugger::SearchMatch>::create();
   for (size_t i = 0; i < matches.size(); ++i)
@@ -548,6 +520,15 @@
     Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) {
   if (!enabled()) return Response::Error(kDebuggerNotEnabled);
 
+  ScriptsMap::iterator it = m_scripts.find(scriptId);
+  if (it == m_scripts.end()) {
+    return Response::Error("No script with given id found");
+  }
+  if (it->second->isModule()) {
+    // TODO(kozyatinskiy): LiveEdit should support ES6 module
+    return Response::Error("Editing module's script is not supported.");
+  }
+
   v8::HandleScope handles(m_isolate);
   v8::Local<v8::String> newSource = toV8String(m_isolate, newContent);
   bool compileError = false;
@@ -556,9 +537,7 @@
       &m_pausedCallFrames, stackChanged, &compileError);
   if (!response.isSuccess() || compileError) return response;
 
-  ScriptsMap::iterator it = m_scripts.find(scriptId);
-  if (it != m_scripts.end()) it->second->setSource(newSource);
-
+  it->second->setSource(newSource);
   std::unique_ptr<Array<CallFrame>> callFrames;
   response = currentCallFrames(&callFrames);
   if (!response.isSuccess()) return response;
@@ -571,7 +550,7 @@
     const String16& callFrameId,
     std::unique_ptr<Array<CallFrame>>* newCallFrames,
     Maybe<StackTrace>* asyncStackTrace) {
-  if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+  if (!isPaused()) return Response::Error(kDebuggerNotPaused);
   InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
                                        callFrameId);
   Response response = scope.initialize();
@@ -604,93 +583,93 @@
   if (it == m_scripts.end())
     return Response::Error("No script for id: " + scriptId);
   v8::HandleScope handles(m_isolate);
-  *scriptSource = toProtocolString(it->second->source(m_isolate));
+  *scriptSource = it->second->source(m_isolate);
   return Response::OK();
 }
 
+void V8DebuggerAgentImpl::pushBreakDetails(
+    const String16& breakReason,
+    std::unique_ptr<protocol::DictionaryValue> breakAuxData) {
+  m_breakReason.push_back(std::make_pair(breakReason, std::move(breakAuxData)));
+}
+
+void V8DebuggerAgentImpl::popBreakDetails() {
+  if (m_breakReason.empty()) return;
+  m_breakReason.pop_back();
+}
+
+void V8DebuggerAgentImpl::clearBreakDetails() {
+  std::vector<BreakReason> emptyBreakReason;
+  m_breakReason.swap(emptyBreakReason);
+}
+
 void V8DebuggerAgentImpl::schedulePauseOnNextStatement(
     const String16& breakReason,
     std::unique_ptr<protocol::DictionaryValue> data) {
   if (!enabled() || m_scheduledDebuggerStep == StepInto ||
-      m_javaScriptPauseScheduled || m_debugger->isPaused() ||
+      m_javaScriptPauseScheduled || isPaused() ||
       !m_debugger->breakpointsActivated())
     return;
-  m_breakReason = breakReason;
-  m_breakAuxData = std::move(data);
-  m_pausingOnNativeEvent = true;
-  m_skipNextDebuggerStepOut = false;
-  m_debugger->setPauseOnNextStatement(true);
+  if (m_breakReason.empty()) m_debugger->setPauseOnNextStatement(true);
+  pushBreakDetails(breakReason, std::move(data));
 }
 
 void V8DebuggerAgentImpl::schedulePauseOnNextStatementIfSteppingInto() {
   DCHECK(enabled());
   if (m_scheduledDebuggerStep != StepInto || m_javaScriptPauseScheduled ||
-      m_debugger->isPaused())
+      isPaused())
     return;
-  clearBreakDetails();
-  m_pausingOnNativeEvent = false;
-  m_skippedStepFrameCount = 0;
-  m_recursionLevelForStepFrame = 0;
   m_debugger->setPauseOnNextStatement(true);
 }
 
 void V8DebuggerAgentImpl::cancelPauseOnNextStatement() {
-  if (m_javaScriptPauseScheduled || m_debugger->isPaused()) return;
-  clearBreakDetails();
-  m_pausingOnNativeEvent = false;
-  m_debugger->setPauseOnNextStatement(false);
+  if (m_javaScriptPauseScheduled || isPaused()) return;
+  popBreakDetails();
+  if (m_breakReason.empty()) m_debugger->setPauseOnNextStatement(false);
 }
 
 Response V8DebuggerAgentImpl::pause() {
   if (!enabled()) return Response::Error(kDebuggerNotEnabled);
-  if (m_javaScriptPauseScheduled || m_debugger->isPaused())
-    return Response::OK();
+  if (m_javaScriptPauseScheduled || isPaused()) return Response::OK();
   clearBreakDetails();
   m_javaScriptPauseScheduled = true;
   m_scheduledDebuggerStep = NoStep;
-  m_skippedStepFrameCount = 0;
-  m_steppingFromFramework = false;
   m_debugger->setPauseOnNextStatement(true);
   return Response::OK();
 }
 
 Response V8DebuggerAgentImpl::resume() {
-  if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+  if (!isPaused()) return Response::Error(kDebuggerNotPaused);
   m_scheduledDebuggerStep = NoStep;
-  m_steppingFromFramework = false;
   m_session->releaseObjectGroup(kBacktraceObjectGroup);
   m_debugger->continueProgram();
   return Response::OK();
 }
 
 Response V8DebuggerAgentImpl::stepOver() {
-  if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+  if (!isPaused()) return Response::Error(kDebuggerNotPaused);
   // StepOver at function return point should fallback to StepInto.
   JavaScriptCallFrame* frame =
       !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr;
   if (frame && frame->isAtReturn()) return stepInto();
   m_scheduledDebuggerStep = StepOver;
-  m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
   m_session->releaseObjectGroup(kBacktraceObjectGroup);
   m_debugger->stepOverStatement();
   return Response::OK();
 }
 
 Response V8DebuggerAgentImpl::stepInto() {
-  if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+  if (!isPaused()) return Response::Error(kDebuggerNotPaused);
   m_scheduledDebuggerStep = StepInto;
-  m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
   m_session->releaseObjectGroup(kBacktraceObjectGroup);
   m_debugger->stepIntoStatement();
   return Response::OK();
 }
 
 Response V8DebuggerAgentImpl::stepOut() {
-  if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+  if (!isPaused()) return Response::Error(kDebuggerNotPaused);
   m_scheduledDebuggerStep = StepOut;
-  m_skipNextDebuggerStepOut = false;
   m_recursionLevelForStepOut = 1;
-  m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
   m_session->releaseObjectGroup(kBacktraceObjectGroup);
   m_debugger->stepOutOfFunction();
   return Response::OK();
@@ -699,13 +678,13 @@
 Response V8DebuggerAgentImpl::setPauseOnExceptions(
     const String16& stringPauseState) {
   if (!enabled()) return Response::Error(kDebuggerNotEnabled);
-  v8::DebugInterface::ExceptionBreakState pauseState;
+  v8::debug::ExceptionBreakState pauseState;
   if (stringPauseState == "none") {
-    pauseState = v8::DebugInterface::NoBreakOnException;
+    pauseState = v8::debug::NoBreakOnException;
   } else if (stringPauseState == "all") {
-    pauseState = v8::DebugInterface::BreakOnAnyException;
+    pauseState = v8::debug::BreakOnAnyException;
   } else if (stringPauseState == "uncaught") {
-    pauseState = v8::DebugInterface::BreakOnUncaughtException;
+    pauseState = v8::debug::BreakOnUncaughtException;
   } else {
     return Response::Error("Unknown pause on exceptions mode: " +
                            stringPauseState);
@@ -716,7 +695,7 @@
 
 void V8DebuggerAgentImpl::setPauseOnExceptionsImpl(int pauseState) {
   m_debugger->setPauseOnExceptionsState(
-      static_cast<v8::DebugInterface::ExceptionBreakState>(pauseState));
+      static_cast<v8::debug::ExceptionBreakState>(pauseState));
   m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState);
 }
 
@@ -724,9 +703,9 @@
     const String16& callFrameId, const String16& expression,
     Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI,
     Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview,
-    std::unique_ptr<RemoteObject>* result,
+    Maybe<bool> throwOnSideEffect, std::unique_ptr<RemoteObject>* result,
     Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
-  if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+  if (!isPaused()) return Response::Error(kDebuggerNotPaused);
   InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
                                        callFrameId);
   Response response = scope.initialize();
@@ -739,7 +718,8 @@
 
   v8::MaybeLocal<v8::Value> maybeResultValue =
       m_pausedCallFrames[scope.frameOrdinal()]->evaluate(
-          toV8String(m_isolate, expression));
+          toV8String(m_isolate, expression),
+          throwOnSideEffect.fromMaybe(false));
 
   // Re-initialize after running client's code, as it could have destroyed
   // context or session.
@@ -756,7 +736,7 @@
     std::unique_ptr<protocol::Runtime::CallArgument> newValueArgument,
     const String16& callFrameId) {
   if (!enabled()) return Response::Error(kDebuggerNotEnabled);
-  if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+  if (!isPaused()) return Response::Error(kDebuggerNotPaused);
   InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
                                        callFrameId);
   Response response = scope.initialize();
@@ -787,6 +767,7 @@
     std::unique_ptr<protocol::Array<String16>> patterns) {
   if (!patterns->length()) {
     m_blackboxPattern = nullptr;
+    resetBlackboxedStateCache();
     m_state->remove(DebuggerAgentState::blackboxPattern);
     return Response::OK();
   }
@@ -802,6 +783,7 @@
   String16 pattern = patternBuilder.toString();
   Response response = setBlackboxPattern(pattern);
   if (!response.isSuccess()) return response;
+  resetBlackboxedStateCache();
   m_state->setString(DebuggerAgentState::blackboxPattern, pattern);
   return Response::OK();
 }
@@ -815,15 +797,23 @@
   return Response::OK();
 }
 
+void V8DebuggerAgentImpl::resetBlackboxedStateCache() {
+  for (const auto& it : m_scripts) {
+    it.second->resetBlackboxedStateCache();
+  }
+}
+
 Response V8DebuggerAgentImpl::setBlackboxedRanges(
     const String16& scriptId,
     std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
         inPositions) {
-  if (m_scripts.find(scriptId) == m_scripts.end())
+  auto it = m_scripts.find(scriptId);
+  if (it == m_scripts.end())
     return Response::Error("No script with passed id.");
 
   if (!inPositions->length()) {
     m_blackboxedPositions.erase(scriptId);
+    it->second->resetBlackboxedStateCache();
     return Response::OK();
   }
 
@@ -849,12 +839,12 @@
   }
 
   m_blackboxedPositions[scriptId] = positions;
+  it->second->resetBlackboxedStateCache();
   return Response::OK();
 }
 
 void V8DebuggerAgentImpl::willExecuteScript(int scriptId) {
   changeJavaScriptRecursionLevel(+1);
-  // Fast return.
   if (m_scheduledDebuggerStep != StepInto) return;
   schedulePauseOnNextStatementIfSteppingInto();
 }
@@ -864,8 +854,7 @@
 }
 
 void V8DebuggerAgentImpl::changeJavaScriptRecursionLevel(int step) {
-  if (m_javaScriptPauseScheduled && !m_skipAllPauses &&
-      !m_debugger->isPaused()) {
+  if (m_javaScriptPauseScheduled && !m_skipAllPauses && !isPaused()) {
     // Do not ever loose user's pause request until we have actually paused.
     m_debugger->setPauseOnNextStatement(true);
   }
@@ -877,40 +866,19 @@
       // switch stepping to step into a next JS task, as if we exited to a
       // blackboxed framework.
       m_scheduledDebuggerStep = StepInto;
-      m_skipNextDebuggerStepOut = false;
-    }
-  }
-  if (m_recursionLevelForStepFrame) {
-    m_recursionLevelForStepFrame += step;
-    if (!m_recursionLevelForStepFrame) {
-      // We have walked through a blackboxed framework and got back to where we
-      // started.
-      // If there was no stepping scheduled, we should cancel the stepping
-      // explicitly,
-      // since there may be a scheduled StepFrame left.
-      // Otherwise, if we were stepping in/over, the StepFrame will stop at the
-      // right location,
-      // whereas if we were stepping out, we should continue doing so after
-      // debugger pauses
-      // from the old StepFrame.
-      m_skippedStepFrameCount = 0;
-      if (m_scheduledDebuggerStep == NoStep)
-        m_debugger->clearStepping();
-      else if (m_scheduledDebuggerStep == StepOut)
-        m_skipNextDebuggerStepOut = true;
     }
   }
 }
 
 Response V8DebuggerAgentImpl::currentCallFrames(
     std::unique_ptr<Array<CallFrame>>* result) {
-  if (m_pausedContext.IsEmpty() || !m_pausedCallFrames.size()) {
+  if (!isPaused()) {
     *result = Array<CallFrame>::create();
     return Response::OK();
   }
   v8::HandleScope handles(m_isolate);
   v8::Local<v8::Context> debuggerContext =
-      v8::DebugInterface::GetDebugContext(m_isolate);
+      v8::debug::GetDebugContext(m_isolate);
   v8::Context::Scope contextScope(debuggerContext);
 
   v8::Local<v8::Array> objects = v8::Array::New(m_isolate);
@@ -920,8 +888,9 @@
     const std::unique_ptr<JavaScriptCallFrame>& currentCallFrame =
         m_pausedCallFrames[frameOrdinal];
 
-    v8::Local<v8::Object> details = currentCallFrame->details();
-    if (details.IsEmpty()) return Response::InternalError();
+    v8::Local<v8::Object> details;
+    if (!currentCallFrame->details().ToLocal(&details))
+      return Response::InternalError();
 
     int contextId = currentCallFrame->contextId();
 
@@ -1004,54 +973,77 @@
   Response response = toProtocolValue(debuggerContext, objects, &protocolValue);
   if (!response.isSuccess()) return response;
   protocol::ErrorSupport errorSupport;
-  *result = Array<CallFrame>::parse(protocolValue.get(), &errorSupport);
+  *result = Array<CallFrame>::fromValue(protocolValue.get(), &errorSupport);
   if (!*result) return Response::Error(errorSupport.errors());
+  TranslateWasmStackTraceLocations(result->get(),
+                                   m_debugger->wasmTranslation());
   return Response::OK();
 }
 
 std::unique_ptr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace() {
-  if (m_pausedContext.IsEmpty()) return nullptr;
+  if (!isPaused()) return nullptr;
   V8StackTraceImpl* stackTrace = m_debugger->currentAsyncCallChain();
   return stackTrace ? stackTrace->buildInspectorObjectForTail(m_debugger)
                     : nullptr;
 }
 
+bool V8DebuggerAgentImpl::isPaused() const { return m_debugger->isPaused(); }
+
 void V8DebuggerAgentImpl::didParseSource(
     std::unique_ptr<V8DebuggerScript> script, bool success) {
   v8::HandleScope handles(m_isolate);
-  String16 scriptSource = toProtocolString(script->source(m_isolate));
+  String16 scriptSource = script->source(m_isolate);
   if (!success) script->setSourceURL(findSourceURL(scriptSource, false));
   if (!success)
     script->setSourceMappingURL(findSourceMapURL(scriptSource, false));
 
+  int contextId = script->executionContextId();
+  int contextGroupId = m_inspector->contextGroupId(contextId);
+  InspectedContext* inspected =
+      m_inspector->getContext(contextGroupId, contextId);
   std::unique_ptr<protocol::DictionaryValue> executionContextAuxData;
-  if (!script->executionContextAuxData().isEmpty())
+  if (inspected) {
+    // Script reused between different groups/sessions can have a stale
+    // execution context id.
     executionContextAuxData = protocol::DictionaryValue::cast(
-        protocol::parseJSON(script->executionContextAuxData()));
+        protocol::StringUtil::parseJSON(inspected->auxData()));
+  }
   bool isLiveEdit = script->isLiveEdit();
   bool hasSourceURL = script->hasSourceURL();
+  bool isModule = script->isModule();
   String16 scriptId = script->scriptId();
   String16 scriptURL = script->sourceURL();
 
-  Maybe<String16> sourceMapURLParam = script->sourceMappingURL();
+  m_scripts[scriptId] = std::move(script);
+
+  ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
+  DCHECK(scriptIterator != m_scripts.end());
+  V8DebuggerScript* scriptRef = scriptIterator->second.get();
+  // V8 could create functions for parsed scripts before reporting and asks
+  // inspector about blackboxed state, we should reset state each time when we
+  // make any change that change isFunctionBlackboxed output - adding parsed
+  // script is changing.
+  scriptRef->resetBlackboxedStateCache();
+
+  Maybe<String16> sourceMapURLParam = scriptRef->sourceMappingURL();
   Maybe<protocol::DictionaryValue> executionContextAuxDataParam(
       std::move(executionContextAuxData));
   const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr;
   const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr;
+  const bool* isModuleParam = isModule ? &isModule : nullptr;
   if (success)
     m_frontend.scriptParsed(
-        scriptId, scriptURL, script->startLine(), script->startColumn(),
-        script->endLine(), script->endColumn(), script->executionContextId(),
-        script->hash(), std::move(executionContextAuxDataParam),
-        isLiveEditParam, std::move(sourceMapURLParam), hasSourceURLParam);
+        scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(),
+        scriptRef->endLine(), scriptRef->endColumn(), contextId,
+        scriptRef->hash(m_isolate), std::move(executionContextAuxDataParam),
+        isLiveEditParam, std::move(sourceMapURLParam), hasSourceURLParam,
+        isModuleParam);
   else
     m_frontend.scriptFailedToParse(
-        scriptId, scriptURL, script->startLine(), script->startColumn(),
-        script->endLine(), script->endColumn(), script->executionContextId(),
-        script->hash(), std::move(executionContextAuxDataParam),
-        std::move(sourceMapURLParam), hasSourceURLParam);
-
-  m_scripts[scriptId] = std::move(script);
+        scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(),
+        scriptRef->endLine(), scriptRef->endColumn(), contextId,
+        scriptRef->hash(m_isolate), std::move(executionContextAuxDataParam),
+        std::move(sourceMapURLParam), hasSourceURLParam, isModuleParam);
 
   if (scriptURL.isEmpty() || !success) return;
 
@@ -1069,76 +1061,60 @@
     breakpointObject->getString(DebuggerAgentState::url, &url);
     if (!matches(m_inspector, scriptURL, url, isRegex)) continue;
     ScriptBreakpoint breakpoint;
+    breakpoint.script_id = scriptId;
     breakpointObject->getInteger(DebuggerAgentState::lineNumber,
-                                 &breakpoint.lineNumber);
+                                 &breakpoint.line_number);
     breakpointObject->getInteger(DebuggerAgentState::columnNumber,
-                                 &breakpoint.columnNumber);
+                                 &breakpoint.column_number);
     breakpointObject->getString(DebuggerAgentState::condition,
                                 &breakpoint.condition);
-    std::unique_ptr<protocol::Debugger::Location> location = resolveBreakpoint(
-        cookie.first, scriptId, breakpoint, UserBreakpointSource);
+    std::unique_ptr<protocol::Debugger::Location> location =
+        resolveBreakpoint(cookie.first, breakpoint, UserBreakpointSource);
     if (location)
       m_frontend.breakpointResolved(cookie.first, std::move(location));
   }
 }
 
-V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(
-    v8::Local<v8::Context> context, v8::Local<v8::Value> exception,
-    const std::vector<String16>& hitBreakpoints, bool isPromiseRejection,
-    bool isUncaught) {
-  JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1);
-  JavaScriptCallFrame* topCallFrame =
-      !callFrames.empty() ? callFrames.begin()->get() : nullptr;
-
-  V8DebuggerAgentImpl::SkipPauseRequest result;
-  if (m_skipAllPauses)
-    result = RequestContinue;
-  else if (!hitBreakpoints.empty())
-    result = RequestNoSkip;  // Don't skip explicit breakpoints even if set in
-                             // frameworks.
-  else if (!exception.IsEmpty())
-    result = shouldSkipExceptionPause(topCallFrame);
-  else if (m_scheduledDebuggerStep != NoStep || m_javaScriptPauseScheduled ||
-           m_pausingOnNativeEvent)
-    result = shouldSkipStepPause(topCallFrame);
-  else
-    result = RequestNoSkip;
-
-  m_skipNextDebuggerStepOut = false;
-  if (result != RequestNoSkip) return result;
-  // Skip pauses inside V8 internal scripts and on syntax errors.
-  if (!topCallFrame) return RequestContinue;
-
-  DCHECK(m_pausedContext.IsEmpty());
+void V8DebuggerAgentImpl::didPause(int contextId,
+                                   v8::Local<v8::Value> exception,
+                                   const std::vector<String16>& hitBreakpoints,
+                                   bool isPromiseRejection, bool isUncaught,
+                                   bool isOOMBreak) {
   JavaScriptCallFrames frames = m_debugger->currentCallFrames();
   m_pausedCallFrames.swap(frames);
-  m_pausedContext.Reset(m_isolate, context);
   v8::HandleScope handles(m_isolate);
 
-  if (!exception.IsEmpty()) {
+  std::vector<BreakReason> hitReasons;
+
+  if (isOOMBreak) {
+    hitReasons.push_back(
+        std::make_pair(protocol::Debugger::Paused::ReasonEnum::OOM, nullptr));
+  } else if (!exception.IsEmpty()) {
     InjectedScript* injectedScript = nullptr;
-    m_session->findInjectedScript(V8Debugger::contextId(context),
-                                  injectedScript);
+    m_session->findInjectedScript(contextId, injectedScript);
     if (injectedScript) {
-      m_breakReason =
+      String16 breakReason =
           isPromiseRejection
               ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection
               : protocol::Debugger::Paused::ReasonEnum::Exception;
       std::unique_ptr<protocol::Runtime::RemoteObject> obj;
       injectedScript->wrapObject(exception, kBacktraceObjectGroup, false, false,
                                  &obj);
+      std::unique_ptr<protocol::DictionaryValue> breakAuxData;
       if (obj) {
-        m_breakAuxData = obj->serialize();
-        m_breakAuxData->setBoolean("uncaught", isUncaught);
+        breakAuxData = obj->toValue();
+        breakAuxData->setBoolean("uncaught", isUncaught);
       } else {
-        m_breakAuxData = nullptr;
+        breakAuxData = nullptr;
       }
-      // m_breakAuxData might be null after this.
+      hitReasons.push_back(
+          std::make_pair(breakReason, std::move(breakAuxData)));
     }
   }
 
   std::unique_ptr<Array<String16>> hitBreakpointIds = Array<String16>::create();
 
+  bool hasDebugCommandBreakpointReason = false;
   for (const auto& point : hitBreakpoints) {
     DebugServerBreakpointToBreakpointIdAndSourceMap::iterator
         breakpointIterator = m_serverBreakpoints.find(point);
@@ -1147,34 +1123,57 @@
       hitBreakpointIds->addItem(localId);
 
       BreakpointSource source = breakpointIterator->second.second;
-      if (m_breakReason == protocol::Debugger::Paused::ReasonEnum::Other &&
-          source == DebugCommandBreakpointSource)
-        m_breakReason = protocol::Debugger::Paused::ReasonEnum::DebugCommand;
+      if (!hasDebugCommandBreakpointReason &&
+          source == DebugCommandBreakpointSource) {
+        hasDebugCommandBreakpointReason = true;
+        hitReasons.push_back(std::make_pair(
+            protocol::Debugger::Paused::ReasonEnum::DebugCommand, nullptr));
+      }
     }
   }
 
+  for (size_t i = 0; i < m_breakReason.size(); ++i) {
+    hitReasons.push_back(std::move(m_breakReason[i]));
+  }
+  clearBreakDetails();
+
+  String16 breakReason = protocol::Debugger::Paused::ReasonEnum::Other;
+  std::unique_ptr<protocol::DictionaryValue> breakAuxData;
+  if (hitReasons.size() == 1) {
+    breakReason = hitReasons[0].first;
+    breakAuxData = std::move(hitReasons[0].second);
+  } else if (hitReasons.size() > 1) {
+    breakReason = protocol::Debugger::Paused::ReasonEnum::Ambiguous;
+    std::unique_ptr<protocol::ListValue> reasons =
+        protocol::ListValue::create();
+    for (size_t i = 0; i < hitReasons.size(); ++i) {
+      std::unique_ptr<protocol::DictionaryValue> reason =
+          protocol::DictionaryValue::create();
+      reason->setString("reason", hitReasons[i].first);
+      if (hitReasons[i].second)
+        reason->setObject("auxData", std::move(hitReasons[i].second));
+      reasons->pushValue(std::move(reason));
+    }
+    breakAuxData = protocol::DictionaryValue::create();
+    breakAuxData->setArray("reasons", std::move(reasons));
+  }
+
   std::unique_ptr<Array<CallFrame>> protocolCallFrames;
   Response response = currentCallFrames(&protocolCallFrames);
   if (!response.isSuccess()) protocolCallFrames = Array<CallFrame>::create();
-  m_frontend.paused(std::move(protocolCallFrames), m_breakReason,
-                    std::move(m_breakAuxData), std::move(hitBreakpointIds),
+  m_frontend.paused(std::move(protocolCallFrames), breakReason,
+                    std::move(breakAuxData), std::move(hitBreakpointIds),
                     currentAsyncStackTrace());
   m_scheduledDebuggerStep = NoStep;
   m_javaScriptPauseScheduled = false;
-  m_steppingFromFramework = false;
-  m_pausingOnNativeEvent = false;
-  m_skippedStepFrameCount = 0;
-  m_recursionLevelForStepFrame = 0;
 
   if (!m_continueToLocationBreakpointId.isEmpty()) {
     m_debugger->removeBreakpoint(m_continueToLocationBreakpointId);
     m_continueToLocationBreakpointId = "";
   }
-  return result;
 }
 
 void V8DebuggerAgentImpl::didContinue() {
-  m_pausedContext.Reset();
   JavaScriptCallFrames emptyCallFrames;
   m_pausedCallFrames.swap(emptyCallFrames);
   clearBreakDetails();
@@ -1184,55 +1183,48 @@
 void V8DebuggerAgentImpl::breakProgram(
     const String16& breakReason,
     std::unique_ptr<protocol::DictionaryValue> data) {
-  if (!enabled() || m_skipAllPauses || !m_pausedContext.IsEmpty() ||
-      isCurrentCallStackEmptyOrBlackboxed() ||
-      !m_debugger->breakpointsActivated())
-    return;
-  m_breakReason = breakReason;
-  m_breakAuxData = std::move(data);
+  if (!enabled() || !m_debugger->canBreakProgram() || m_skipAllPauses) return;
+  std::vector<BreakReason> currentScheduledReason;
+  currentScheduledReason.swap(m_breakReason);
+  pushBreakDetails(breakReason, std::move(data));
   m_scheduledDebuggerStep = NoStep;
-  m_steppingFromFramework = false;
-  m_pausingOnNativeEvent = false;
   m_debugger->breakProgram();
+  popBreakDetails();
+  m_breakReason.swap(currentScheduledReason);
 }
 
 void V8DebuggerAgentImpl::breakProgramOnException(
     const String16& breakReason,
     std::unique_ptr<protocol::DictionaryValue> data) {
   if (!enabled() ||
-      m_debugger->getPauseOnExceptionsState() ==
-          v8::DebugInterface::NoBreakOnException)
+      m_debugger->getPauseOnExceptionsState() == v8::debug::NoBreakOnException)
     return;
   breakProgram(breakReason, std::move(data));
 }
 
-void V8DebuggerAgentImpl::clearBreakDetails() {
-  m_breakReason = protocol::Debugger::Paused::ReasonEnum::Other;
-  m_breakAuxData = nullptr;
-}
-
 void V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId,
                                           int lineNumber, int columnNumber,
                                           BreakpointSource source,
                                           const String16& condition) {
-  String16 breakpointId =
-      generateBreakpointId(scriptId, lineNumber, columnNumber, source);
-  ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
-  resolveBreakpoint(breakpointId, scriptId, breakpoint, source);
+  ScriptBreakpoint breakpoint(scriptId, lineNumber, columnNumber, condition);
+  String16 breakpointId = generateBreakpointId(breakpoint, source);
+  resolveBreakpoint(breakpointId, breakpoint, source);
 }
 
 void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId,
                                              int lineNumber, int columnNumber,
                                              BreakpointSource source) {
-  removeBreakpointImpl(
-      generateBreakpointId(scriptId, lineNumber, columnNumber, source));
+  removeBreakpointImpl(generateBreakpointId(
+      ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()),
+      source));
 }
 
 void V8DebuggerAgentImpl::reset() {
   if (!enabled()) return;
   m_scheduledDebuggerStep = NoStep;
-  m_scripts.clear();
   m_blackboxedPositions.clear();
+  resetBlackboxedStateCache();
+  m_scripts.clear();
   m_breakpointIdToDebuggerBreakpointIds.clear();
 }