Source/JavaScriptCore/ChangeLog

 12019-09-24 Yury Semikhatsky <yurys@chromium.org>
 2
 3 Web Inspector: tests under LayoutTests/inspector/debugger are flaky
 4 https://bugs.webkit.org/show_bug.cgi?id=137131
 5 <rdar://problem/18461335>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Changed breakpoint resolution logic to make it cosistent across platforms and
 10 better handle the case when there are several DebuggerPausePositions at the same
 11 offset (but with different types).
 12
 13 * debugger/Debugger.cpp:
 14 (JSC::Debugger::resolveBreakpoint): clarified that in the map columns are 0-based.
 15 * debugger/DebuggerParseData.cpp:
 16 (JSC::DebuggerPausePositions::breakpointLocationForLineColumn): replaced custom
 17 binary search with std::lower_bound. If there are several pause positions at the
 18 same offset they will be sorted by the type and the algorithm is guaranteed to see
 19 legtmost one first.
 20
 21 (JSC::DebuggerPausePositions::sort): use type as secondary ordering component.
 22 * debugger/DebuggerParseData.h: Rearranged type constants so that Enter < Pause < Leave
 23 this change along with sorting by type should guarantee that in case of several pause
 24 positions at the same line Enter goes before Pause before Leave and the breakpoint
 25 resolution will yield result similar to that when each pause locations has different
 26 position.
 27
 28 * inspector/protocol/Debugger.json: clarified that positions are 0-based.
 29 * parser/ParserTokens.h:
 30 (JSC::JSTextPosition::column const): added helper method for computing column.
 31
1322019-09-19 Mark Lam <mark.lam@apple.com>
233
334 Refactoring: fix broken indentation in JSNonDestructibleProxy.h.

Source/WebCore/ChangeLog

 12019-09-20 Yury Semikhatsky <yurys@chromium.org>
 2
 3 Web Inspector: tests under LayoutTests/inspector/debugger are flaky
 4 https://bugs.webkit.org/show_bug.cgi?id=137131
 5 <rdar://problem/18461335>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Fix debugger tests on GTK. All tests that pause on breakpoint didn't work because
 10 in layout tests InspectorFrontendClientLocal was using Timer to dispatch commands
 11 sent from the local front-end page to the inspected one. When paused inside a script
 12 triggered by the front-end nested timer event would be scheduled but never fired
 13 because in glib implementation of RunLoop::TimerBase uses event source which doesn't
 14 allow recursion (g_source_set_can_recurse is not called on the source), so dispatching
 15 Debugger.resume command didn't work when paused inside another inspector command (e.g.
 16 eval). RunLoop itself uses event source which does allow recursion. So instead of using
 17 a timer for asynchronous command dispatching with delay=0 we now schedule a task in
 18 RunLoop's queue.
 19
 20 * inspector/InspectorFrontendClientLocal.cpp:
 21 (WebCore::InspectorBackendDispatchTask::dispatch):
 22 (WebCore::InspectorBackendDispatchTask::reset):
 23 (WebCore::InspectorBackendDispatchTask::InspectorBackendDispatchTask):
 24 (WebCore::InspectorBackendDispatchTask::scheduleOneShot): ensures that there is one inspector
 25 dispatch task in the queue.
 26 (WebCore::InspectorBackendDispatchTask::dispatchOneMessage): this is mostly the same behavior
 27 as was with timerFired, we should be able to dispatch all accumulated messages from the queue
 28 in one batched but for now I'd like to keep it one per iteration.
 29
1302019-09-19 Peng Liu <peng.liu6@apple.com>
231
332 HTMLVideoElement with a broken poster image will take square dimension

Source/JavaScriptCore/debugger/Debugger.cpp

@@void Debugger::resolveBreakpoint(Breakpoint& breakpoint, SourceProvider* sourceP
359359
360360 // FIXME: <https://webkit.org/b/162771> Web Inspector: Adopt TextPosition in Inspector to avoid oneBasedInt/zeroBasedInt ambiguity
361361 // Inspector breakpoint line and column values are zero-based but the executable
362  // and CodeBlock line and column values are one-based.
 362 // and CodeBlock line values are one-based while column is zero-based.
363363 unsigned line = breakpoint.line + 1;
364  unsigned column = breakpoint.column ? breakpoint.column : Breakpoint::unspecifiedColumn;
 364 unsigned column = breakpoint.column;
365365
366366 // Account for a <script>'s start position on the first line only.
367367 unsigned providerStartLine = sourceProvider->startPosition().m_line.oneBasedInt(); // One based to match the already adjusted line.
368368 unsigned providerStartColumn = sourceProvider->startPosition().m_column.zeroBasedInt(); // Zero based so column zero is zero.
369  if (line == providerStartLine && column != Breakpoint::unspecifiedColumn) {
 369 if (line == providerStartLine && breakpoint.column) {
370370 ASSERT(providerStartColumn <= column);
371371 if (providerStartColumn)
372372 column -= providerStartColumn;

@@void Debugger::resolveBreakpoint(Breakpoint& breakpoint, SourceProvider* sourceP
378378 return;
379379
380380 unsigned resolvedLine = resolvedPosition->line;
381  unsigned resolvedColumn = resolvedPosition->offset - resolvedPosition->lineStartOffset + 1;
 381 unsigned resolvedColumn = resolvedPosition->offset - resolvedPosition->lineStartOffset;
382382
383383 // Re-account for a <script>'s start position on the first line only.
384  if (resolvedLine == providerStartLine && column != Breakpoint::unspecifiedColumn) {
 384 if (resolvedLine == providerStartLine && breakpoint.column) {
385385 if (providerStartColumn)
386386 resolvedColumn += providerStartColumn;
387387 }
388388
389389 breakpoint.line = resolvedLine - 1;
390  breakpoint.column = resolvedColumn - 1;
 390 breakpoint.column = resolvedColumn;
391391 breakpoint.resolved = true;
392392}
393393

Source/JavaScriptCore/debugger/DebuggerParseData.cpp

@@namespace JSC {
3333
3434Optional<JSTextPosition> DebuggerPausePositions::breakpointLocationForLineColumn(int line, int column)
3535{
36  unsigned start = 0;
37  unsigned end = m_positions.size();
38  while (start != end) {
39  unsigned middle = start + ((end - start) / 2);
40  DebuggerPausePosition& pausePosition = m_positions[middle];
41  int pauseLine = pausePosition.position.line;
42  int pauseColumn = pausePosition.position.offset - pausePosition.position.lineStartOffset;
43 
44  if (line < pauseLine) {
45  end = middle;
46  continue;
47  }
48  if (line > pauseLine) {
49  start = middle + 1;
50  continue;
51  }
 36 DebuggerPausePosition position;
 37 position.position.line = line;
 38 position.position.offset = column;
 39 position.position.lineStartOffset = 0;
 40 auto it = std::lower_bound(m_positions.begin(), m_positions.end(), position, [] (const DebuggerPausePosition& a, const DebuggerPausePosition& b) {
 41 if (a.position.line == b.position.line)
 42 return a.position.column() < b.position.column();
 43 return a.position.line < b.position.line;
 44 });
5245
53  if (column == pauseColumn) {
54  // Found an exact position match. Roll forward if this was a function Entry.
55  // We are guarenteed to have a Leave for an Entry so we don't need to bounds check.
56  while (true) {
57  if (pausePosition.type != DebuggerPausePositionType::Enter)
58  return Optional<JSTextPosition>(pausePosition.position);
59  pausePosition = m_positions[middle++];
60  }
61  }
 46 if (it == m_positions.end())
 47 return WTF::nullopt;
6248
63  if (column < pauseColumn)
64  end = middle;
65  else
66  start = middle + 1;
 49 if (line == it->position.line && column == it->position.column()) {
 50 // Found an exact position match. Roll forward if this was a function Entry.
 51 // We are guarenteed to have a Leave for an Entry so we don't need to bounds check.
 52 while (true) {
 53 if (it->type != DebuggerPausePositionType::Enter)
 54 return Optional<JSTextPosition>(it->position);
 55 ++it;
 56 }
6757 }
6858
69  // Past the end, no possible pause locations.
70  if (start >= m_positions.size())
71  return WTF::nullopt;
72 
7359 // If the next location is a function Entry we will need to decide if we should go into
7460 // the function or go past the function. We decide to go into the function if the
7561 // input is on the same line as the function entry. For example:

@@Optional<JSTextPosition> DebuggerPausePositions::breakpointLocationForLineColumn
8672 // If the input was line 3, go into the function to pause on line 4.
8773
8874 // Valid pause location. Use it.
89  DebuggerPausePosition& firstSlidePosition = m_positions[start];
 75 DebuggerPausePosition& firstSlidePosition = *it;
9076 if (firstSlidePosition.type != DebuggerPausePositionType::Enter)
9177 return Optional<JSTextPosition>(firstSlidePosition.position);
9278

@@Optional<JSTextPosition> DebuggerPausePositions::breakpointLocationForLineColumn
9480 // If entryStackSize is > 0 we are skipping functions.
9581 bool shouldEnterFunction = firstSlidePosition.position.line == line;
9682 int entryStackSize = shouldEnterFunction ? 0 : 1;
97  for (unsigned i = start + 1; i < m_positions.size(); ++i) {
98  DebuggerPausePosition& slidePosition = m_positions[i];
 83 for (++it; it != m_positions.end(); ++it) {
 84 DebuggerPausePosition& slidePosition = *it;
9985 ASSERT(entryStackSize >= 0);
10086
10187 // Already skipping functions.

@@Optional<JSTextPosition> DebuggerPausePositions::breakpointLocationForLineColumn
124110void DebuggerPausePositions::sort()
125111{
126112 std::sort(m_positions.begin(), m_positions.end(), [] (const DebuggerPausePosition& a, const DebuggerPausePosition& b) {
 113 if (a.position.offset == b.position.offset)
 114 return a.type < b.type;
127115 return a.position.offset < b.position.offset;
128116 });
129117}

Source/JavaScriptCore/debugger/DebuggerParseData.h

@@namespace JSC {
3333class SourceProvider;
3434class VM;
3535
36 enum class DebuggerPausePositionType { Enter, Leave, Pause };
 36enum class DebuggerPausePositionType { Enter, Pause, Leave };
3737struct DebuggerPausePosition {
3838 DebuggerPausePositionType type;
3939 JSTextPosition position;

Source/JavaScriptCore/inspector/protocol/Debugger.json

2828 "description": "Location in the source code.",
2929 "properties": [
3030 { "name": "scriptId", "$ref": "ScriptId", "description": "Script identifier as reported in the <code>Debugger.scriptParsed</code>." },
31  { "name": "lineNumber", "type": "integer", "description": "Line number in the script." },
32  { "name": "columnNumber", "type": "integer", "optional": true, "description": "Column number in the script." }
 31 { "name": "lineNumber", "type": "integer", "description": "Line number in the script (0-based)." },
 32 { "name": "columnNumber", "type": "integer", "optional": true, "description": "Column number in the script (0-based)." }
3333 ]
3434 },
3535 {

Source/JavaScriptCore/parser/ParserTokens.h

@@struct JSTextPosition {
217217 return !(*this == other);
218218 }
219219
 220 int column() const { return offset - lineStartOffset; }
 221
220222 int line { 0 };
221223 int offset { 0 };
222224 int lineStartOffset { 0 };

Source/WebCore/inspector/InspectorFrontendClientLocal.cpp

@@public:
8181 ASSERT_ARG(message, !message.isEmpty());
8282
8383 m_messages.append(message);
84  if (!m_timer.isActive())
85  m_timer.startOneShot(0_s);
 84 scheduleOneShot();
8685 }
8786
8887 void reset()
8988 {
9089 m_messages.clear();
91  m_timer.stop();
9290 m_inspectedPageController = nullptr;
9391 }
9492
95  void timerFired()
 93private:
 94 InspectorBackendDispatchTask(InspectorController* inspectedPageController)
 95 : m_inspectedPageController(inspectedPageController)
 96 {
 97 ASSERT_ARG(inspectedPageController, inspectedPageController);
 98 }
 99
 100 void scheduleOneShot()
 101 {
 102 if (m_hasTaskInQueue)
 103 return;
 104 m_hasTaskInQueue = true;
 105 RunLoop::current().dispatch([this, protectedThis = makeRef(*this)] {
 106 m_hasTaskInQueue = false;
 107 dispatchOneMessage();
 108 });
 109 }
 110
 111 void dispatchOneMessage()
96112 {
97113 ASSERT(m_inspectedPageController);
98114

@@public:
104120 m_inspectedPageController->dispatchMessageFromFrontend(m_messages.takeFirst());
105121
106122 if (!m_messages.isEmpty() && m_inspectedPageController)
107  m_timer.startOneShot(0_s);
108  }
109 
110 private:
111  InspectorBackendDispatchTask(InspectorController* inspectedPageController)
112  : m_inspectedPageController(inspectedPageController)
113  , m_timer(*this, &InspectorBackendDispatchTask::timerFired)
114  {
115  ASSERT_ARG(inspectedPageController, inspectedPageController);
 123 scheduleOneShot();
116124 }
117125
118126 InspectorController* m_inspectedPageController { nullptr };
119  Timer m_timer;
120127 Deque<String> m_messages;
 128 bool m_hasTaskInQueue { false };
121129};
122130
123131String InspectorFrontendClientLocal::Settings::getProperty(const String&)

LayoutTests/ChangeLog

 12019-09-20 Yury Semikhatsky <yurys@chromium.org>
 2
 3 Web Inspector: tests under LayoutTests/inspector/debugger are flaky
 4 https://bugs.webkit.org/show_bug.cgi?id=137131
 5 <rdar://problem/18461335>
 6
 7 Reviewed by NOBODY (OOPS!).
 8
 9 Enable inspector/debugger tests on GTK.
 10
 11 * inspector/debugger/breakpoints/resolved-dump-all-pause-locations-expected.txt: Rebaselined the test
 12 after changes in the breakpoint resolution code. Now the output on GTK is the same as on Mac.
 13 * platform/gtk/TestExpectations:
 14
1152019-09-19 Peng Liu <peng.liu6@apple.com>
216
317 HTMLVideoElement with a broken poster image will take square dimension

LayoutTests/inspector/debugger/breakpoints/resolved-dump-all-pause-locations-expected.txt

@@PAUSES AT: 89:7
21662166 92 x
21672167
21682168INSERTING AT: 89:8
2169 PAUSES AT: 94:0
 2169PAUSES AT: 98:0
21702170 86
21712171 87 x => x;
21722172 88 () => 1;

@@PAUSES AT: 94:0
21752175 91 (x) => {
21762176 92 x
21772177 93 };
2178  => 94 |() => {
 2178 94 () => {
21792179 95 var x;
21802180 96 };
21812181 97
 2182 => 98 |var fObj = {
 2183 99 f1: function() {
 2184 100 var x;
 2185 101 },
21822186
21832187INSERTING AT: 90:0
21842188PAUSES AT: 90:0

@@PAUSES AT: 93:0
22422246 95 var x;
22432247 96 };
22442248
 2249INSERTING AT: 94:0
 2250PAUSES AT: 94:0
 2251 91 (x) => {
 2252 92 x
 2253 93 };
 2254-=> 94 |() => {
 2255 95 var x;
 2256 96 };
 2257 97
 2258
22452259INSERTING AT: 94:1
22462260PAUSES AT: 95:4
22472261 91 (x) => {

@@PAUSES AT: 96:0
22642278 98 var fObj = {
22652279 99 f1: function() {
22662280
2267 INSERTING AT: 96:1
2268 PAUSES AT: 98:0
2269  93 };
2270  94 () => {
2271  95 var x;
2272  -> 96 }#;
2273  97
2274  => 98 |var fObj = {
2275  99 f1: function() {
2276  100 var x;
2277  101 },
2278 
22792281INSERTING AT: 99:0
22802282PAUSES AT: 100:8
22812283 96 };

LayoutTests/platform/gtk/TestExpectations

@@webkit.org/b/116957 media/track/track-automatic-subtitles.html [ Timeout ]
23112311
23122312webkit.org/b/120682 inspector/page/archive.html [ Timeout ]
23132313
 2314webkit.org/b/147518 inspector/debugger/nested-inspectors.html [ Timeout ]
23142315webkit.org/b/122571 http/tests/inspector/dom/cross-domain-inspected-node-access.html [ Timeout Pass ]
2315 webkit.org/b/122571 inspector/debugger/setBreakpoint.html [ Timeout Pass ]
2316 webkit.org/b/122571 inspector/debugger/call-frame-function-name.html [ Timeout Pass ]
2317 webkit.org/b/122571 inspector/debugger/setBreakpoint-options-exception.html [ Timeout Pass ]
2318 webkit.org/b/122571 inspector/debugger/setPauseOnExceptions-all.html [ Timeout Pass ]
2319 webkit.org/b/122571 inspector/debugger/setPauseOnExceptions-none.html [ Timeout Pass ]
2320 webkit.org/b/122571 inspector/debugger/call-frame-this-host.html [ Timeout Pass Crash ]
2321 webkit.org/b/122571 inspector/debugger/setBreakpoint-autoContinue.html [ Timeout Pass ]
2322 webkit.org/b/122571 inspector/debugger/setPauseOnExceptions-uncaught.html [ Timeout Pass ]
2323 webkit.org/b/122571 inspector/debugger/setBreakpoint-actions.html [ Failure Timeout Pass ]
2324 webkit.org/b/122571 inspector/debugger/call-frame-this-nonstrict.html [ Timeout Pass ]
2325 webkit.org/b/122571 inspector/debugger/setBreakpoint-column.html [ Timeout Pass ]
2326 webkit.org/b/122571 inspector/debugger/setBreakpoint-condition.html [ Timeout Pass ]
2327 webkit.org/b/122571 inspector/debugger/removeBreakpoint.html [ Timeout Pass ]
2328 webkit.org/b/122571 inspector/debugger/call-frame-this-strict.html [ Timeout Pass ]
23292316webkit.org/b/122571 inspector/dom/request-child-nodes-depth.html [ Timeout Pass ]
23302317webkit.org/b/122571 inspector/dom/focus.html [ Failure Timeout Pass ]
23312318webkit.org/b/122571 inspector/runtime/getProperties.html [ Timeout Pass Crash ]

@@webkit.org/b/136674 media/track/track-cue-rendering-with-padding.html [ Timeout
23702357
23712358webkit.org/b/137698 media/video-controls-drag.html [ Timeout ]
23722359
2373 webkit.org/b/137131 inspector/debugger [ Skip ]
23742360webkit.org/b/147518 inspector/dom [ Skip ]
23752361webkit.org/b/147518 inspector/model [ Skip ]
23762362webkit.org/b/147518 inspector/timeline [ Skip ]