Chromium Code Reviews| Index: third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp |
| diff --git a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp |
| index 76d5cc57c1ab501165292e5c0af4c86959339347..d486bf8d537750962b01f80ebeb18c5f3d092293 100644 |
| --- a/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp |
| +++ b/third_party/WebKit/Source/modules/indexeddb/IDBRequest.cpp |
| @@ -44,6 +44,7 @@ |
| #include "modules/indexeddb/IDBTracing.h" |
| #include "modules/indexeddb/IDBValue.h" |
| #include "modules/indexeddb/WebIDBCallbacksImpl.h" |
| +#include "platform/Histogram.h" |
| #include "platform/SharedBuffer.h" |
| #include "public/platform/WebBlobInfo.h" |
| @@ -51,10 +52,50 @@ using blink::WebIDBCursor; |
| namespace blink { |
| +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.
|
| + : tracing_name_(nullptr), id_(nullptr) {} |
| + |
| +IDBRequest::AsyncTraceState::AsyncTraceState(const char* tracing_name, void* id) |
| + : tracing_name_(tracing_name), id_(id) { |
| + if (tracing_name_) |
| + TRACE_EVENT_ASYNC_BEGIN0("IndexedDB", tracing_name_, id); |
| +} |
| + |
| +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.
|
| + IDBRequest::AsyncTraceState&& other) { |
| + this->tracing_name_ = other.tracing_name_; |
| + other.tracing_name_ = nullptr; |
| + this->id_ = other.id_; |
| + other.id_ = nullptr; |
| +} |
| + |
| +IDBRequest::AsyncTraceState& IDBRequest::AsyncTraceState::operator=( |
| + IDBRequest::AsyncTraceState&& rhs) { |
| + this->tracing_name_ = rhs.tracing_name_; |
| + rhs.tracing_name_ = nullptr; |
| + this->id_ = rhs.id_; |
| + rhs.id_ = nullptr; |
| + return *this; |
| +} |
| + |
| +void IDBRequest::AsyncTraceState::RecordAndReset() { |
| + if (tracing_name_) |
| + TRACE_EVENT_ASYNC_END0("IndexedDB", tracing_name_, id_); |
| + tracing_name_ = nullptr; |
| + id_ = nullptr; |
| +} |
| + |
| +IDBRequest::AsyncTraceState::~AsyncTraceState() { |
| + if (tracing_name_) |
| + TRACE_EVENT_ASYNC_END0("IndexedDB", tracing_name_, id_); |
| +} |
| + |
| IDBRequest* IDBRequest::Create(ScriptState* script_state, |
| IDBAny* source, |
| - IDBTransaction* transaction) { |
| - IDBRequest* request = new IDBRequest(script_state, source, transaction); |
| + IDBTransaction* transaction, |
| + IDBRequest::AsyncTraceState metrics) { |
| + IDBRequest* request = |
| + new IDBRequest(script_state, source, transaction, std::move(metrics)); |
| request->SuspendIfNeeded(); |
| // Requests associated with IDBFactory (open/deleteDatabase/getDatabaseNames) |
| // are not associated with transactions. |
| @@ -65,15 +106,17 @@ IDBRequest* IDBRequest::Create(ScriptState* script_state, |
| IDBRequest::IDBRequest(ScriptState* script_state, |
| IDBAny* source, |
| - IDBTransaction* transaction) |
| + IDBTransaction* transaction, |
| + AsyncTraceState metrics) |
| : SuspendableObject(ExecutionContext::From(script_state)), |
| transaction_(transaction), |
| isolate_(script_state->GetIsolate()), |
| - source_(source) {} |
| + source_(source), |
| + metrics_(std::move(metrics)) {} |
| IDBRequest::~IDBRequest() { |
| - DCHECK(ready_state_ == DONE || ready_state_ == kEarlyDeath || |
| - !GetExecutionContext()); |
| + DCHECK((ready_state_ == DONE && !metrics_.is_valid()) || |
| + ready_state_ == kEarlyDeath || !GetExecutionContext()); |
| } |
| DEFINE_TRACE(IDBRequest) { |
| @@ -242,24 +285,30 @@ bool IDBRequest::ShouldEnqueueEvent() const { |
| void IDBRequest::EnqueueResponse(DOMException* error) { |
| IDB_TRACE("IDBRequest::onError()"); |
| ClearPutOperationBlobs(); |
| - if (!ShouldEnqueueEvent()) |
| + if (!ShouldEnqueueEvent()) { |
| + metrics_.RecordAndReset(); |
| return; |
| + } |
| error_ = error; |
| SetResult(IDBAny::CreateUndefined()); |
| pending_cursor_.Clear(); |
| EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); |
| + metrics_.RecordAndReset(); |
| } |
| void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { |
| IDB_TRACE("IDBRequest::onSuccess(StringList)"); |
| - if (!ShouldEnqueueEvent()) |
| + if (!ShouldEnqueueEvent()) { |
| + metrics_.RecordAndReset(); |
| return; |
| + } |
| DOMStringList* dom_string_list = DOMStringList::Create(); |
| for (size_t i = 0; i < string_list.size(); ++i) |
| dom_string_list->Append(string_list[i]); |
| EnqueueResultInternal(IDBAny::Create(dom_string_list)); |
| + metrics_.RecordAndReset(); |
| } |
| void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, |
| @@ -267,8 +316,10 @@ void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, |
| IDBKey* primary_key, |
| PassRefPtr<IDBValue> value) { |
| IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); |
| - if (!ShouldEnqueueEvent()) |
| + if (!ShouldEnqueueEvent()) { |
| + metrics_.RecordAndReset(); |
| return; |
| + } |
| DCHECK(!pending_cursor_); |
| IDBCursor* cursor = nullptr; |
| @@ -286,27 +337,34 @@ void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, |
| NOTREACHED(); |
| } |
| SetResultCursor(cursor, key, primary_key, std::move(value)); |
| + metrics_.RecordAndReset(); |
| } |
| void IDBRequest::EnqueueResponse(IDBKey* idb_key) { |
| IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); |
| ClearPutOperationBlobs(); |
| - if (!ShouldEnqueueEvent()) |
| + if (!ShouldEnqueueEvent()) { |
| + metrics_.RecordAndReset(); |
| return; |
| + } |
| if (idb_key && idb_key->IsValid()) |
| EnqueueResultInternal(IDBAny::Create(idb_key)); |
| else |
| EnqueueResultInternal(IDBAny::CreateUndefined()); |
| + metrics_.RecordAndReset(); |
| } |
| void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { |
| IDB_TRACE("IDBRequest::onSuccess([IDBValue])"); |
| - if (!ShouldEnqueueEvent()) |
| + if (!ShouldEnqueueEvent()) { |
| + metrics_.RecordAndReset(); |
| return; |
| + } |
| AckReceivedBlobs(values); |
| EnqueueResultInternal(IDBAny::Create(values)); |
| + metrics_.RecordAndReset(); |
| } |
| #if DCHECK_IS_ON() |
| @@ -323,8 +381,10 @@ static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { |
| void IDBRequest::EnqueueResponse(PassRefPtr<IDBValue> prp_value) { |
| IDB_TRACE("IDBRequest::onSuccess(IDBValue)"); |
| - if (!ShouldEnqueueEvent()) |
| + if (!ShouldEnqueueEvent()) { |
| + metrics_.RecordAndReset(); |
| return; |
| + } |
| RefPtr<IDBValue> value(std::move(prp_value)); |
| AckReceivedBlobs(value.Get()); |
| @@ -343,20 +403,27 @@ void IDBRequest::EnqueueResponse(PassRefPtr<IDBValue> prp_value) { |
| #endif |
| EnqueueResultInternal(IDBAny::Create(value.Release())); |
| + metrics_.RecordAndReset(); |
| } |
| void IDBRequest::EnqueueResponse(int64_t value) { |
| IDB_TRACE("IDBRequest::onSuccess(int64_t)"); |
| - if (!ShouldEnqueueEvent()) |
| + if (!ShouldEnqueueEvent()) { |
| + metrics_.RecordAndReset(); |
| return; |
| + } |
| EnqueueResultInternal(IDBAny::Create(value)); |
| + metrics_.RecordAndReset(); |
| } |
| void IDBRequest::EnqueueResponse() { |
| IDB_TRACE("IDBRequest::onSuccess()"); |
| - if (!ShouldEnqueueEvent()) |
| + if (!ShouldEnqueueEvent()) { |
| + metrics_.RecordAndReset(); |
| return; |
| + } |
| EnqueueResultInternal(IDBAny::CreateUndefined()); |
| + metrics_.RecordAndReset(); |
| } |
| void IDBRequest::EnqueueResultInternal(IDBAny* result) { |
| @@ -376,12 +443,15 @@ void IDBRequest::EnqueueResponse(IDBKey* key, |
| IDBKey* primary_key, |
| PassRefPtr<IDBValue> value) { |
| IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); |
| - if (!ShouldEnqueueEvent()) |
| + if (!ShouldEnqueueEvent()) { |
| + metrics_.RecordAndReset(); |
| return; |
| + } |
| DCHECK(pending_cursor_); |
| SetResultCursor(pending_cursor_.Release(), key, primary_key, |
| std::move(value)); |
| + metrics_.RecordAndReset(); |
| } |
| bool IDBRequest::HasPendingActivity() const { |