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

Side by Side Diff: third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp

Issue 2890023003: [IndexedDB] Adding async tracing for renderer calls. (Closed)
Patch Set: test fix 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google Inc. All rights reserved. 2 * Copyright (C) 2010 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 26 matching lines...) Expand all
37 #include "core/dom/ExceptionCode.h" 37 #include "core/dom/ExceptionCode.h"
38 #include "core/dom/ExecutionContext.h" 38 #include "core/dom/ExecutionContext.h"
39 #include "core/events/EventQueue.h" 39 #include "core/events/EventQueue.h"
40 #include "modules/IndexedDBNames.h" 40 #include "modules/IndexedDBNames.h"
41 #include "modules/indexeddb/IDBCursorWithValue.h" 41 #include "modules/indexeddb/IDBCursorWithValue.h"
42 #include "modules/indexeddb/IDBDatabase.h" 42 #include "modules/indexeddb/IDBDatabase.h"
43 #include "modules/indexeddb/IDBEventDispatcher.h" 43 #include "modules/indexeddb/IDBEventDispatcher.h"
44 #include "modules/indexeddb/IDBTracing.h" 44 #include "modules/indexeddb/IDBTracing.h"
45 #include "modules/indexeddb/IDBValue.h" 45 #include "modules/indexeddb/IDBValue.h"
46 #include "modules/indexeddb/WebIDBCallbacksImpl.h" 46 #include "modules/indexeddb/WebIDBCallbacksImpl.h"
47 #include "platform/Histogram.h"
47 #include "platform/SharedBuffer.h" 48 #include "platform/SharedBuffer.h"
48 #include "public/platform/WebBlobInfo.h" 49 #include "public/platform/WebBlobInfo.h"
49 50
50 using blink::WebIDBCursor; 51 using blink::WebIDBCursor;
51 52
52 namespace blink { 53 namespace blink {
53 54
55 IDBRequest::AsyncTraceState::AsyncTraceState()
pwnall 2017/05/25 23:04:25 You seem to use tracing_name_ for all the decision
dmurph 2017/05/31 19:26:25 Done.
56 : tracing_name_(nullptr), id_(nullptr) {}
57
58 IDBRequest::AsyncTraceState::AsyncTraceState(const char* tracing_name, void* id)
59 : tracing_name_(tracing_name), id_(id) {
60 if (tracing_name_)
61 TRACE_EVENT_ASYNC_BEGIN0("IndexedDB", tracing_name_, id);
62 }
63
64 IDBRequest::AsyncTraceState::AsyncTraceState(
pwnall 2017/05/25 23:04:25 I think that the constructor and assignment operat
dmurph 2017/05/31 19:26:25 Done.
65 IDBRequest::AsyncTraceState&& other) {
66 this->tracing_name_ = other.tracing_name_;
67 other.tracing_name_ = nullptr;
68 this->id_ = other.id_;
69 other.id_ = nullptr;
70 }
71
72 IDBRequest::AsyncTraceState& IDBRequest::AsyncTraceState::operator=(
73 IDBRequest::AsyncTraceState&& rhs) {
74 this->tracing_name_ = rhs.tracing_name_;
75 rhs.tracing_name_ = nullptr;
76 this->id_ = rhs.id_;
77 rhs.id_ = nullptr;
78 return *this;
79 }
80
81 void IDBRequest::AsyncTraceState::RecordAndReset() {
82 if (tracing_name_)
83 TRACE_EVENT_ASYNC_END0("IndexedDB", tracing_name_, id_);
84 tracing_name_ = nullptr;
85 id_ = nullptr;
86 }
87
88 IDBRequest::AsyncTraceState::~AsyncTraceState() {
89 if (tracing_name_)
90 TRACE_EVENT_ASYNC_END0("IndexedDB", tracing_name_, id_);
91 }
92
54 IDBRequest* IDBRequest::Create(ScriptState* script_state, 93 IDBRequest* IDBRequest::Create(ScriptState* script_state,
55 IDBAny* source, 94 IDBAny* source,
56 IDBTransaction* transaction) { 95 IDBTransaction* transaction,
57 IDBRequest* request = new IDBRequest(script_state, source, transaction); 96 IDBRequest::AsyncTraceState metrics) {
97 IDBRequest* request =
98 new IDBRequest(script_state, source, transaction, std::move(metrics));
58 request->SuspendIfNeeded(); 99 request->SuspendIfNeeded();
59 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) 100 // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames)
60 // are not associated with transactions. 101 // are not associated with transactions.
61 if (transaction) 102 if (transaction)
62 transaction->RegisterRequest(request); 103 transaction->RegisterRequest(request);
63 return request; 104 return request;
64 } 105 }
65 106
66 IDBRequest::IDBRequest(ScriptState* script_state, 107 IDBRequest::IDBRequest(ScriptState* script_state,
67 IDBAny* source, 108 IDBAny* source,
68 IDBTransaction* transaction) 109 IDBTransaction* transaction,
110 AsyncTraceState metrics)
69 : SuspendableObject(ExecutionContext::From(script_state)), 111 : SuspendableObject(ExecutionContext::From(script_state)),
70 transaction_(transaction), 112 transaction_(transaction),
71 isolate_(script_state->GetIsolate()), 113 isolate_(script_state->GetIsolate()),
72 source_(source) {} 114 source_(source),
115 metrics_(std::move(metrics)) {}
73 116
74 IDBRequest::~IDBRequest() { 117 IDBRequest::~IDBRequest() {
75 DCHECK(ready_state_ == DONE || ready_state_ == kEarlyDeath || 118 DCHECK((ready_state_ == DONE && !metrics_.is_valid()) ||
76 !GetExecutionContext()); 119 ready_state_ == kEarlyDeath || !GetExecutionContext());
77 } 120 }
78 121
79 DEFINE_TRACE(IDBRequest) { 122 DEFINE_TRACE(IDBRequest) {
80 visitor->Trace(transaction_); 123 visitor->Trace(transaction_);
81 visitor->Trace(source_); 124 visitor->Trace(source_);
82 visitor->Trace(result_); 125 visitor->Trace(result_);
83 visitor->Trace(error_); 126 visitor->Trace(error_);
84 visitor->Trace(enqueued_events_); 127 visitor->Trace(enqueued_events_);
85 visitor->Trace(pending_cursor_); 128 visitor->Trace(pending_cursor_);
86 visitor->Trace(cursor_key_); 129 visitor->Trace(cursor_key_);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 if (request_aborted_) 278 if (request_aborted_)
236 return false; 279 return false;
237 DCHECK_EQ(ready_state_, PENDING); 280 DCHECK_EQ(ready_state_, PENDING);
238 DCHECK(!error_ && !result_); 281 DCHECK(!error_ && !result_);
239 return true; 282 return true;
240 } 283 }
241 284
242 void IDBRequest::EnqueueResponse(DOMException* error) { 285 void IDBRequest::EnqueueResponse(DOMException* error) {
243 IDB_TRACE("IDBRequest::onError()"); 286 IDB_TRACE("IDBRequest::onError()");
244 ClearPutOperationBlobs(); 287 ClearPutOperationBlobs();
245 if (!ShouldEnqueueEvent()) 288 if (!ShouldEnqueueEvent()) {
289 metrics_.RecordAndReset();
246 return; 290 return;
291 }
247 292
248 error_ = error; 293 error_ = error;
249 SetResult(IDBAny::CreateUndefined()); 294 SetResult(IDBAny::CreateUndefined());
250 pending_cursor_.Clear(); 295 pending_cursor_.Clear();
251 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); 296 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error));
297 metrics_.RecordAndReset();
252 } 298 }
253 299
254 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { 300 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) {
255 IDB_TRACE("IDBRequest::onSuccess(StringList)"); 301 IDB_TRACE("IDBRequest::onSuccess(StringList)");
256 if (!ShouldEnqueueEvent()) 302 if (!ShouldEnqueueEvent()) {
303 metrics_.RecordAndReset();
257 return; 304 return;
305 }
258 306
259 DOMStringList* dom_string_list = DOMStringList::Create(); 307 DOMStringList* dom_string_list = DOMStringList::Create();
260 for (size_t i = 0; i < string_list.size(); ++i) 308 for (size_t i = 0; i < string_list.size(); ++i)
261 dom_string_list->Append(string_list[i]); 309 dom_string_list->Append(string_list[i]);
262 EnqueueResultInternal(IDBAny::Create(dom_string_list)); 310 EnqueueResultInternal(IDBAny::Create(dom_string_list));
311 metrics_.RecordAndReset();
263 } 312 }
264 313
265 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, 314 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend,
266 IDBKey* key, 315 IDBKey* key,
267 IDBKey* primary_key, 316 IDBKey* primary_key,
268 PassRefPtr<IDBValue> value) { 317 PassRefPtr<IDBValue> value) {
269 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); 318 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)");
270 if (!ShouldEnqueueEvent()) 319 if (!ShouldEnqueueEvent()) {
320 metrics_.RecordAndReset();
271 return; 321 return;
322 }
272 323
273 DCHECK(!pending_cursor_); 324 DCHECK(!pending_cursor_);
274 IDBCursor* cursor = nullptr; 325 IDBCursor* cursor = nullptr;
275 switch (cursor_type_) { 326 switch (cursor_type_) {
276 case IndexedDB::kCursorKeyOnly: 327 case IndexedDB::kCursorKeyOnly:
277 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, 328 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this,
278 source_.Get(), transaction_.Get()); 329 source_.Get(), transaction_.Get());
279 break; 330 break;
280 case IndexedDB::kCursorKeyAndValue: 331 case IndexedDB::kCursorKeyAndValue:
281 cursor = 332 cursor =
282 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, 333 IDBCursorWithValue::Create(std::move(backend), cursor_direction_,
283 this, source_.Get(), transaction_.Get()); 334 this, source_.Get(), transaction_.Get());
284 break; 335 break;
285 default: 336 default:
286 NOTREACHED(); 337 NOTREACHED();
287 } 338 }
288 SetResultCursor(cursor, key, primary_key, std::move(value)); 339 SetResultCursor(cursor, key, primary_key, std::move(value));
340 metrics_.RecordAndReset();
289 } 341 }
290 342
291 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { 343 void IDBRequest::EnqueueResponse(IDBKey* idb_key) {
292 IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); 344 IDB_TRACE("IDBRequest::onSuccess(IDBKey)");
293 ClearPutOperationBlobs(); 345 ClearPutOperationBlobs();
294 if (!ShouldEnqueueEvent()) 346 if (!ShouldEnqueueEvent()) {
347 metrics_.RecordAndReset();
295 return; 348 return;
349 }
296 350
297 if (idb_key && idb_key->IsValid()) 351 if (idb_key && idb_key->IsValid())
298 EnqueueResultInternal(IDBAny::Create(idb_key)); 352 EnqueueResultInternal(IDBAny::Create(idb_key));
299 else 353 else
300 EnqueueResultInternal(IDBAny::CreateUndefined()); 354 EnqueueResultInternal(IDBAny::CreateUndefined());
355 metrics_.RecordAndReset();
301 } 356 }
302 357
303 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { 358 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) {
304 IDB_TRACE("IDBRequest::onSuccess([IDBValue])"); 359 IDB_TRACE("IDBRequest::onSuccess([IDBValue])");
305 if (!ShouldEnqueueEvent()) 360 if (!ShouldEnqueueEvent()) {
361 metrics_.RecordAndReset();
306 return; 362 return;
363 }
307 364
308 AckReceivedBlobs(values); 365 AckReceivedBlobs(values);
309 EnqueueResultInternal(IDBAny::Create(values)); 366 EnqueueResultInternal(IDBAny::Create(values));
367 metrics_.RecordAndReset();
310 } 368 }
311 369
312 #if DCHECK_IS_ON() 370 #if DCHECK_IS_ON()
313 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { 371 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) {
314 if (source->GetType() == IDBAny::kIDBObjectStoreType) 372 if (source->GetType() == IDBAny::kIDBObjectStoreType)
315 return source->IdbObjectStore(); 373 return source->IdbObjectStore();
316 if (source->GetType() == IDBAny::kIDBIndexType) 374 if (source->GetType() == IDBAny::kIDBIndexType)
317 return source->IdbIndex()->objectStore(); 375 return source->IdbIndex()->objectStore();
318 376
319 NOTREACHED(); 377 NOTREACHED();
320 return nullptr; 378 return nullptr;
321 } 379 }
322 #endif // DCHECK_IS_ON() 380 #endif // DCHECK_IS_ON()
323 381
324 void IDBRequest::EnqueueResponse(PassRefPtr<IDBValue> prp_value) { 382 void IDBRequest::EnqueueResponse(PassRefPtr<IDBValue> prp_value) {
325 IDB_TRACE("IDBRequest::onSuccess(IDBValue)"); 383 IDB_TRACE("IDBRequest::onSuccess(IDBValue)");
326 if (!ShouldEnqueueEvent()) 384 if (!ShouldEnqueueEvent()) {
385 metrics_.RecordAndReset();
327 return; 386 return;
387 }
328 388
329 RefPtr<IDBValue> value(std::move(prp_value)); 389 RefPtr<IDBValue> value(std::move(prp_value));
330 AckReceivedBlobs(value.Get()); 390 AckReceivedBlobs(value.Get());
331 391
332 if (pending_cursor_) { 392 if (pending_cursor_) {
333 // Value should be null, signifying the end of the cursor's range. 393 // Value should be null, signifying the end of the cursor's range.
334 DCHECK(value->IsNull()); 394 DCHECK(value->IsNull());
335 DCHECK(!value->BlobInfo()->size()); 395 DCHECK(!value->BlobInfo()->size());
336 pending_cursor_->Close(); 396 pending_cursor_->Close();
337 pending_cursor_.Clear(); 397 pending_cursor_.Clear();
338 } 398 }
339 399
340 #if DCHECK_IS_ON() 400 #if DCHECK_IS_ON()
341 DCHECK(!value->PrimaryKey() || 401 DCHECK(!value->PrimaryKey() ||
342 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); 402 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath());
343 #endif 403 #endif
344 404
345 EnqueueResultInternal(IDBAny::Create(value.Release())); 405 EnqueueResultInternal(IDBAny::Create(value.Release()));
406 metrics_.RecordAndReset();
346 } 407 }
347 408
348 void IDBRequest::EnqueueResponse(int64_t value) { 409 void IDBRequest::EnqueueResponse(int64_t value) {
349 IDB_TRACE("IDBRequest::onSuccess(int64_t)"); 410 IDB_TRACE("IDBRequest::onSuccess(int64_t)");
350 if (!ShouldEnqueueEvent()) 411 if (!ShouldEnqueueEvent()) {
412 metrics_.RecordAndReset();
351 return; 413 return;
414 }
352 EnqueueResultInternal(IDBAny::Create(value)); 415 EnqueueResultInternal(IDBAny::Create(value));
416 metrics_.RecordAndReset();
353 } 417 }
354 418
355 void IDBRequest::EnqueueResponse() { 419 void IDBRequest::EnqueueResponse() {
356 IDB_TRACE("IDBRequest::onSuccess()"); 420 IDB_TRACE("IDBRequest::onSuccess()");
357 if (!ShouldEnqueueEvent()) 421 if (!ShouldEnqueueEvent()) {
422 metrics_.RecordAndReset();
358 return; 423 return;
424 }
359 EnqueueResultInternal(IDBAny::CreateUndefined()); 425 EnqueueResultInternal(IDBAny::CreateUndefined());
426 metrics_.RecordAndReset();
360 } 427 }
361 428
362 void IDBRequest::EnqueueResultInternal(IDBAny* result) { 429 void IDBRequest::EnqueueResultInternal(IDBAny* result) {
363 DCHECK(GetExecutionContext()); 430 DCHECK(GetExecutionContext());
364 DCHECK(!pending_cursor_); 431 DCHECK(!pending_cursor_);
365 DCHECK(transit_blob_handles_.IsEmpty()); 432 DCHECK(transit_blob_handles_.IsEmpty());
366 SetResult(result); 433 SetResult(result);
367 EnqueueEvent(Event::Create(EventTypeNames::success)); 434 EnqueueEvent(Event::Create(EventTypeNames::success));
368 } 435 }
369 436
370 void IDBRequest::SetResult(IDBAny* result) { 437 void IDBRequest::SetResult(IDBAny* result) {
371 result_ = result; 438 result_ = result;
372 result_dirty_ = true; 439 result_dirty_ = true;
373 } 440 }
374 441
375 void IDBRequest::EnqueueResponse(IDBKey* key, 442 void IDBRequest::EnqueueResponse(IDBKey* key,
376 IDBKey* primary_key, 443 IDBKey* primary_key,
377 PassRefPtr<IDBValue> value) { 444 PassRefPtr<IDBValue> value) {
378 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); 445 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)");
379 if (!ShouldEnqueueEvent()) 446 if (!ShouldEnqueueEvent()) {
447 metrics_.RecordAndReset();
380 return; 448 return;
449 }
381 450
382 DCHECK(pending_cursor_); 451 DCHECK(pending_cursor_);
383 SetResultCursor(pending_cursor_.Release(), key, primary_key, 452 SetResultCursor(pending_cursor_.Release(), key, primary_key,
384 std::move(value)); 453 std::move(value));
454 metrics_.RecordAndReset();
385 } 455 }
386 456
387 bool IDBRequest::HasPendingActivity() const { 457 bool IDBRequest::HasPendingActivity() const {
388 // FIXME: In an ideal world, we should return true as long as anyone has a or 458 // FIXME: In an ideal world, we should return true as long as anyone has a or
389 // can get a handle to us and we have event listeners. This is order to 459 // can get a handle to us and we have event listeners. This is order to
390 // handle user generated events properly. 460 // handle user generated events properly.
391 return has_pending_activity_ && GetExecutionContext(); 461 return has_pending_activity_ && GetExecutionContext();
392 } 462 }
393 463
394 void IDBRequest::ContextDestroyed(ExecutionContext*) { 464 void IDBRequest::ContextDestroyed(ExecutionContext*) {
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 } 626 }
557 627
558 void IDBRequest::DequeueEvent(Event* event) { 628 void IDBRequest::DequeueEvent(Event* event) {
559 for (size_t i = 0; i < enqueued_events_.size(); ++i) { 629 for (size_t i = 0; i < enqueued_events_.size(); ++i) {
560 if (enqueued_events_[i].Get() == event) 630 if (enqueued_events_[i].Get() == event)
561 enqueued_events_.erase(i); 631 enqueued_events_.erase(i);
562 } 632 }
563 } 633 }
564 634
565 } // namespace blink 635 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698