ScriptValue InjectedScriptBase::callFunctionWithEvalEnabled(ScriptFunctionCall& function, bool& hadException) const { ASSERT(!isEmpty()); ExecutionContext* executionContext = m_injectedScriptObject.scriptState()->executionContext(); ScriptState::Scope scope(m_injectedScriptObject.scriptState()); v8::Local<v8::Function> functionObj = function.function(); DevToolsFunctionInfo info(functionObj); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FunctionCall", "data", InspectorFunctionCallEvent::data(executionContext, info.scriptId(), "InjectedScriptSource.js", info.lineNumber())); InspectorInstrumentationCookie cookie = InspectorInstrumentation::willCallFunction(executionContext, info); ScriptState* scriptState = m_injectedScriptObject.scriptState(); bool evalIsDisabled = false; if (scriptState) { evalIsDisabled = !scriptState->evalEnabled(); // Temporarily enable allow evals for inspector. if (evalIsDisabled) scriptState->setEvalEnabled(true); } ScriptValue resultValue = function.call(hadException); if (evalIsDisabled) scriptState->setEvalEnabled(false); InspectorInstrumentation::didCallFunction(cookie); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data()); return resultValue; }
v8::Local<v8::Value> ScriptController::callFunctionWithInstrumentation(ScriptExecutionContext* context, v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]) { V8GCController::checkMemoryUsage(); if (V8RecursionScope::recursionLevel() >= kMaxRecursionDepth) return handleMaxRecursionDepthExceeded(); InspectorInstrumentationCookie cookie; if (InspectorInstrumentation::timelineAgentEnabled(context)) { String resourceName; int lineNumber; resourceInfo(function, resourceName, lineNumber); cookie = InspectorInstrumentation::willCallFunction(context, resourceName, lineNumber); } v8::Local<v8::Value> result; { TRACE_EVENT1("v8", "v8.callFunction", "callsite", resourceString(function).utf8()); V8RecursionScope recursionScope(context); result = function->Call(receiver, argc, args); } InspectorInstrumentation::didCallFunction(cookie); crashIfV8IsDead(); return result; }
v8::MaybeLocal<v8::Script> V8ScriptRunner::compileScript(v8::Local<v8::String> code, const String& fileName, const String& sourceMapUrl, const TextPosition& scriptStartPosition, v8::Isolate* isolate, ScriptResource* resource, ScriptStreamer* streamer, CachedMetadataHandler* cacheHandler, AccessControlStatus corsStatus, V8CacheOptions cacheOptions, bool isInternalScript) { TRACE_EVENT1("v8", "v8.compile", "fileName", fileName.utf8()); TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Compile"); ASSERT(!streamer || resource); ASSERT(!resource || resource->cacheHandler() == cacheHandler); // NOTE: For compatibility with WebCore, ScriptSourceCode's line starts at // 1, whereas v8 starts at 0. v8::ScriptOrigin origin( v8String(isolate, fileName), v8::Integer::New(isolate, scriptStartPosition.m_line.zeroBasedInt()), v8::Integer::New(isolate, scriptStartPosition.m_column.zeroBasedInt()), v8Boolean(corsStatus == SharableCrossOrigin, isolate), v8::Local<v8::Integer>(), v8Boolean(isInternalScript, isolate), v8String(isolate, sourceMapUrl)); OwnPtr<CompileFn> compileFn = streamer ? selectCompileFunction(cacheOptions, resource, streamer) : selectCompileFunction(cacheOptions, cacheHandler, code); return (*compileFn)(isolate, code, origin); }
v8::Local<v8::Value> V8Proxy::instrumentedCallFunction(Frame* frame, v8::Handle<v8::Function> function, v8::Handle<v8::Object> receiver, int argc, v8::Handle<v8::Value> args[]) { V8GCController::checkMemoryUsage(); if (V8RecursionScope::recursionLevel() >= kMaxRecursionDepth) return handleMaxRecursionDepthExceeded(); ScriptExecutionContext* context = frame ? frame->document() : 0; InspectorInstrumentationCookie cookie; if (InspectorInstrumentation::hasFrontends() && context) { String resourceName; int lineNumber; resourceInfo(function, resourceName, lineNumber); cookie = InspectorInstrumentation::willCallFunction(context, resourceName, lineNumber); } v8::Local<v8::Value> result; { #if PLATFORM(CHROMIUM) TRACE_EVENT1("v8", "v8.callFunction", "callsite", resourceString(function).utf8()); #endif V8RecursionScope recursionScope(context); result = function->Call(receiver, argc, args); } InspectorInstrumentation::didCallFunction(cookie); if (v8::V8::IsDead()) handleFatalErrorInV8(); return result; }
void ScriptedAnimationController::executeCallbacks(double monotonicTimeNow) { // dispatchEvents() runs script which can cause the document to be destroyed. if (!m_document) return; double highResNowMs = 1000.0 * m_document->loader()->timing()->monotonicTimeToZeroBasedDocumentTime(monotonicTimeNow); double legacyHighResNowMs = 1000.0 * m_document->loader()->timing()->monotonicTimeToPseudoWallTime(monotonicTimeNow); // First, generate a list of callbacks to consider. Callbacks registered from this point // on are considered only for the "next" frame, not this one. ASSERT(m_callbacksToInvoke.isEmpty()); m_callbacksToInvoke.swap(m_callbacks); for (size_t i = 0; i < m_callbacksToInvoke.size(); ++i) { RequestAnimationFrameCallback* callback = m_callbacksToInvoke[i].get(); if (!callback->m_cancelled) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FireAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_document, callback->m_id)); // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing. InspectorInstrumentationCookie cookie = InspectorInstrumentation::willFireAnimationFrame(m_document, callback->m_id); if (callback->m_useLegacyTimeBase) callback->handleEvent(legacyHighResNowMs); else callback->handleEvent(highResNowMs); InspectorInstrumentation::didFireAnimationFrame(cookie); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data()); } } m_callbacksToInvoke.clear(); }
void ScriptedIdleTaskController::runCallback( CallbackId id, double deadlineSeconds, IdleDeadline::CallbackType callbackType) { DCHECK(!m_suspended); auto callback = m_callbacks.take(id); if (!callback) return; double allottedTimeMillis = std::max((deadlineSeconds - monotonicallyIncreasingTime()) * 1000, 0.0); DEFINE_STATIC_LOCAL( CustomCountHistogram, idleCallbackDeadlineHistogram, ("WebCore.ScriptedIdleTaskController.IdleCallbackDeadline", 0, 50, 50)); idleCallbackDeadlineHistogram.count(allottedTimeMillis); TRACE_EVENT1( "devtools.timeline", "FireIdleCallback", "data", InspectorIdleCallbackFireEvent::data( getExecutionContext(), id, allottedTimeMillis, callbackType == IdleDeadline::CallbackType::CalledByTimeout)); callback->handleEvent(IdleDeadline::create(deadlineSeconds, callbackType)); double overrunMillis = std::max((monotonicallyIncreasingTime() - deadlineSeconds) * 1000, 0.0); DEFINE_STATIC_LOCAL( CustomCountHistogram, idleCallbackOverrunHistogram, ("WebCore.ScriptedIdleTaskController.IdleCallbackOverrun", 0, 10000, 50)); idleCallbackOverrunHistogram.count(overrunMillis); }
bool EventDispatcher::dispatch() { TRACE_EVENT0("webkit", "EventDispatcher::dispatch"); #ifndef NDEBUG ASSERT(!m_eventDispatched); m_eventDispatched = true; #endif ChildNodesLazySnapshot::takeChildNodesLazySnapshot(); m_event->setTarget(EventPath::eventTargetRespectingTargetRules(m_node.get())); ASSERT(!NoEventDispatchAssertion::isEventDispatchForbidden()); ASSERT(m_event->target()); WindowEventContext windowEventContext(m_event.get(), m_node.get(), topNodeEventContext()); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EventDispatch", "type", m_event->type().ascii()); // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing. InspectorInstrumentationCookie cookie = InspectorInstrumentation::willDispatchEvent(&m_node->document(), *m_event, windowEventContext.window(), m_node.get(), m_event->eventPath()); void* preDispatchEventHandlerResult; if (dispatchEventPreProcess(preDispatchEventHandlerResult) == ContinueDispatching) if (dispatchEventAtCapturing(windowEventContext) == ContinueDispatching) if (dispatchEventAtTarget() == ContinueDispatching) dispatchEventAtBubbling(windowEventContext); dispatchEventPostProcess(preDispatchEventHandlerResult); // Ensure that after event dispatch, the event's target object is the // outermost shadow DOM boundary. m_event->setTarget(windowEventContext.target()); m_event->setCurrentTarget(0); InspectorInstrumentation::didDispatchEvent(cookie); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data()); return !m_event->defaultPrevented(); }
v8::Local<v8::Value> ScriptController::executeScriptAndReturnValue(v8::Local<v8::Context> context, const ScriptSourceCode& source, AccessControlStatus accessControlStatus, double* compilationFinishTime) { TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data", InspectorEvaluateScriptEvent::data(frame(), source.url().string(), source.startPosition())); InspectorInstrumentation::willEvaluateScript(frame()->document()); v8::Local<v8::Value> result; { V8CacheOptions v8CacheOptions(V8CacheOptionsDefault); if (frame()->settings()) v8CacheOptions = frame()->settings()->v8CacheOptions(); // Isolate exceptions that occur when compiling and executing // the code. These exceptions should not interfere with // javascript code we might evaluate from C++ when returning // from here. v8::TryCatch tryCatch; tryCatch.SetVerbose(true); v8::Local<v8::Script> script; if (!v8Call(V8ScriptRunner::compileScript(source, isolate(), accessControlStatus, v8CacheOptions), script, tryCatch)) return result; if (compilationFinishTime) { *compilationFinishTime = WTF::monotonicallyIncreasingTime(); } // Keep LocalFrame (and therefore ScriptController) alive. RefPtrWillBeRawPtr<LocalFrame> protect(frame()); if (!v8Call(V8ScriptRunner::runCompiledScript(isolate(), script, frame()->document()), result, tryCatch)) return result; } TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data()); return result; }
bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor table[], int* tableCount) { TRACE_EVENT1("blink", "DecodingImageGenerator::getPixels", "frame index", static_cast<int>(m_frameIndex)); // Implementation doesn't support scaling yet, so make sure we're not given a // different size. if (info.width() != getInfo().width() || info.height() != getInfo().height()) return false; if (info.colorType() != getInfo().colorType()) { // blink::ImageFrame may have changed the owning SkBitmap to // kOpaque_SkAlphaType after fully decoding the image frame, so if we see a // request for opaque, that is ok even if our initial alpha type was not // opaque. return false; } PlatformInstrumentation::willDecodeLazyPixelRef(uniqueID()); bool decoded = m_frameGenerator->decodeAndScale( m_data.get(), m_allDataReceived, m_frameIndex, getInfo(), pixels, rowBytes); PlatformInstrumentation::didDecodeLazyPixelRef(); return decoded; }
v8::Local<v8::Value> ScriptController::executeScriptAndReturnValue(v8::Handle<v8::Context> context, const ScriptSourceCode& source, AccessControlStatus corsStatus, double* compilationFinishTime) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EvaluateScript", "data", InspectorEvaluateScriptEvent::data(frame(), source.url().string(), source.startLine())); // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing. InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(frame(), source.url().string(), source.startLine()); v8::Local<v8::Value> result; { V8CacheOptions v8CacheOptions(V8CacheOptionsDefault); if (frame()->settings()) v8CacheOptions = frame()->settings()->v8CacheOptions(); // Isolate exceptions that occur when compiling and executing // the code. These exceptions should not interfere with // javascript code we might evaluate from C++ when returning // from here. v8::TryCatch tryCatch; tryCatch.SetVerbose(true); v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, isolate(), corsStatus, v8CacheOptions); if (compilationFinishTime) { *compilationFinishTime = WTF::monotonicallyIncreasingTime(); } // Keep LocalFrame (and therefore ScriptController) alive. RefPtrWillBeRawPtr<LocalFrame> protect(frame()); result = V8ScriptRunner::runCompiledScript(isolate(), script, frame()->document()); ASSERT(!tryCatch.HasCaught() || result.IsEmpty()); } InspectorInstrumentation::didEvaluateScript(cookie); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data()); return result; }
void FrameRequestCallbackCollection::executeCallbacks( double highResNowMs, double highResNowMsLegacy) { // First, generate a list of callbacks to consider. Callbacks registered from // this point on are considered only for the "next" frame, not this one. DCHECK(m_callbacksToInvoke.isEmpty()); m_callbacksToInvoke.swap(m_callbacks); for (const auto& callback : m_callbacksToInvoke) { if (!callback->m_cancelled) { TRACE_EVENT1( "devtools.timeline", "FireAnimationFrame", "data", InspectorAnimationFrameEvent::data(m_context, callback->m_id)); InspectorInstrumentation::NativeBreakpoint nativeBreakpoint( m_context, "animationFrameFired", false); InspectorInstrumentation::AsyncTask asyncTask(m_context, callback); PerformanceMonitor::HandlerCall handlerCall( m_context, "requestAnimationFrame", true); if (callback->m_useLegacyTimeBase) callback->handleEvent(highResNowMsLegacy); else callback->handleEvent(highResNowMs); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data()); } } m_callbacksToInvoke.clear(); }
v8::Local<v8::Value> V8WorkerGlobalScopeEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event) { v8::Local<v8::Function> handlerFunction = getListenerFunction(scriptState()->executionContext()); v8::Local<v8::Object> receiver = getReceiverObject(event); if (handlerFunction.IsEmpty() || receiver.IsEmpty()) return v8::Local<v8::Value>(); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FunctionCall", "data", devToolsTraceEventData(scriptState()->executionContext(), handlerFunction, isolate())); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack()); // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing. InspectorInstrumentationCookie cookie; if (InspectorInstrumentation::timelineAgentEnabled(scriptState()->executionContext())) { int scriptId = 0; String resourceName; int lineNumber = 1; GetDevToolsFunctionInfo(handlerFunction, isolate(), scriptId, resourceName, lineNumber); cookie = InspectorInstrumentation::willCallFunction(scriptState()->executionContext(), scriptId, resourceName, lineNumber); } v8::Handle<v8::Value> parameters[1] = { jsEvent }; v8::Local<v8::Value> result = V8ScriptRunner::callFunction(handlerFunction, scriptState()->executionContext(), receiver, WTF_ARRAY_LENGTH(parameters), parameters, isolate()); InspectorInstrumentation::didCallFunction(cookie); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data()); return result; }
DispatchEventResult EventDispatcher::dispatch() { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("blink.debug"), "EventDispatcher::dispatch"); #if ENABLE(ASSERT) ASSERT(!m_eventDispatched); m_eventDispatched = true; #endif if (event().eventPath().isEmpty()) { // eventPath() can be empty if event path is shrinked by relataedTarget retargeting. return DispatchEventResult::NotCanceled; } m_event->eventPath().ensureWindowEventContext(); m_event->setTarget(EventPath::eventTargetRespectingTargetRules(*m_node)); ASSERT(!EventDispatchForbiddenScope::isEventDispatchForbidden()); ASSERT(m_event->target()); TRACE_EVENT1("devtools.timeline", "EventDispatch", "data", InspectorEventDispatchEvent::data(*m_event)); void* preDispatchEventHandlerResult; if (dispatchEventPreProcess(preDispatchEventHandlerResult) == ContinueDispatching) { if (dispatchEventAtCapturing() == ContinueDispatching) { if (dispatchEventAtTarget() == ContinueDispatching) dispatchEventAtBubbling(); } } dispatchEventPostProcess(preDispatchEventHandlerResult); // Ensure that after event dispatch, the event's target object is the // outermost shadow DOM boundary. m_event->setTarget(m_event->eventPath().windowEventContext().target()); m_event->setCurrentTarget(nullptr); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data()); return EventTarget::dispatchEventResult(*m_event); }
v8::MaybeLocal<v8::Value> V8ScriptRunner::runCompiledScript(v8::Isolate* isolate, v8::Local<v8::Script> script, ExecutionContext* context) { ASSERT(!script.IsEmpty()); TRACE_EVENT_SCOPED_SAMPLING_STATE("v8", "V8Execution"); TRACE_EVENT1("v8", "v8.run", "fileName", TRACE_STR_COPY(*v8::String::Utf8Value(script->GetUnboundScript()->GetScriptName()))); if (V8RecursionScope::recursionLevel(isolate) >= kMaxRecursionDepth) return throwStackOverflowExceptionIfNeeded(isolate); RELEASE_ASSERT(!context->isIteratingOverObservers()); // Run the script and keep track of the current recursion depth. v8::MaybeLocal<v8::Value> result; { if (ScriptForbiddenScope::isScriptForbidden()) { throwScriptForbiddenException(isolate); return v8::MaybeLocal<v8::Value>(); } V8RecursionScope recursionScope(isolate); result = script->Run(isolate->GetCurrentContext()); } crashIfV8IsDead(); return result; }
v8::Local<v8::Value> ScriptController::executeScriptAndReturnValue(v8::Handle<v8::Context> context, const ScriptSourceCode& source, AccessControlStatus corsStatus) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "EvaluateScript", "data", InspectorEvaluateScriptEvent::data(m_frame, source.url().string(), source.startLine())); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline.stack"), "CallStack", "stack", InspectorCallStackEvent::currentCallStack()); // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing. InspectorInstrumentationCookie cookie = InspectorInstrumentation::willEvaluateScript(m_frame, source.url().string(), source.startLine()); v8::Local<v8::Value> result; { // Isolate exceptions that occur when compiling and executing // the code. These exceptions should not interfere with // javascript code we might evaluate from C++ when returning // from here. v8::TryCatch tryCatch; tryCatch.SetVerbose(true); v8::Handle<v8::Script> script = V8ScriptRunner::compileScript(source, m_isolate, corsStatus); // Keep LocalFrame (and therefore ScriptController) alive. RefPtr<LocalFrame> protect(m_frame); result = V8ScriptRunner::runCompiledScript(script, m_frame->document(), m_isolate); ASSERT(!tryCatch.HasCaught() || result.IsEmpty()); } InspectorInstrumentation::didEvaluateScript(cookie); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data()); return result; }
ScriptValue InjectedScriptBase::callFunctionWithEvalEnabled(ScriptFunctionCall& function, bool& hadException) const { ASSERT(!isEmpty()); ExecutionContext* executionContext = m_injectedScriptObject.scriptState()->executionContext(); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FunctionCall", "data", InspectorFunctionCallEvent::data(executionContext, 0, name(), 1)); // FIXME(361045): remove InspectorInstrumentation calls once DevTools Timeline migrates to tracing. InspectorInstrumentationCookie cookie = InspectorInstrumentation::willCallFunction(executionContext, 0, name(), 1); ScriptState* scriptState = m_injectedScriptObject.scriptState(); bool evalIsDisabled = false; if (scriptState) { evalIsDisabled = !scriptState->evalEnabled(); // Temporarily enable allow evals for inspector. if (evalIsDisabled) scriptState->setEvalEnabled(true); } ScriptValue resultValue = function.call(hadException); if (evalIsDisabled) scriptState->setEvalEnabled(false); InspectorInstrumentation::didCallFunction(cookie); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", "data", InspectorUpdateCountersEvent::data()); return resultValue; }
void ContentLayerDelegate::paintContents( WebDisplayItemList* webDisplayItemList, const WebRect& clip, WebContentLayerClient::PaintingControlSetting paintingControl) { TRACE_EVENT1("blink,benchmark", "ContentLayerDelegate::paintContents", "clip_rect", toTracedValue(clip)); // TODO(pdr): Remove when slimming paint v2 is further along. This is only // here so the browser is usable during development and does not crash due // to committing the new display items twice. if (RuntimeEnabledFeatures::slimmingPaintSynchronizedPaintingEnabled()) { m_painter->displayItemList()->paintArtifact().appendToWebDisplayItemList(webDisplayItemList); return; } DisplayItemList* displayItemList = m_painter->displayItemList(); ASSERT(displayItemList); displayItemList->setDisplayItemConstructionIsDisabled( paintingControl == WebContentLayerClient::DisplayListConstructionDisabled); // We also disable caching when Painting or Construction are disabled. In both cases we would like // to compare assuming the full cost of recording, not the cost of re-using cached content. if (paintingControl != WebContentLayerClient::PaintDefaultBehavior) displayItemList->invalidateAll(); GraphicsContext::DisabledMode disabledMode = GraphicsContext::NothingDisabled; if (paintingControl == WebContentLayerClient::DisplayListPaintingDisabled || paintingControl == WebContentLayerClient::DisplayListConstructionDisabled) disabledMode = GraphicsContext::FullyDisabled; GraphicsContext context(displayItemList, disabledMode); m_painter->paint(context, clip); displayItemList->commitNewDisplayItems(); displayItemList->paintArtifact().appendToWebDisplayItemList(webDisplayItemList); }
bool ChannelReader::DispatchInputData(const char* input_data, int input_data_len) { const char* p; const char* end; // Possibly combine with the overflow buffer to make a larger buffer. if (input_overflow_buf_.empty()) { p = input_data; end = input_data + input_data_len; } else { if (input_overflow_buf_.size() + input_data_len > Channel::kMaximumMessageSize) { input_overflow_buf_.clear(); //assert(ERROR) << "IPC message is too big"; return false; } input_overflow_buf_.append(input_data, input_data_len); p = input_overflow_buf_.data(); end = p + input_overflow_buf_.size(); } // Dispatch all complete messages in the data buffer. while (p < end) { const char* message_tail = Message::FindNext(p, end); if (message_tail) { int len = static_cast<int>(message_tail - p); Message* m = new Message(p, len); m->AddRef(); if (!WillDispatchInputMessage(m)) return false; #ifdef IPC_MESSAGE_LOG_ENABLED Logging* logger = Logging::GetInstance(); std::string name; logger->GetMessageText(m.type(), &name, &m, NULL); TRACE_EVENT1("ipc", "ChannelReader::DispatchInputData", "name", name); #else //TRACE_EVENT2("ipc", "ChannelReader::DispatchInputData", // "class", IPC_MESSAGE_ID_CLASS(m.type()), // "line", IPC_MESSAGE_ID_LINE(m.type())); #endif //m.TraceMessageEnd(); if (IsHelloMessage(m)) HandleHelloMessage(m); else listener_->OnMessageReceived(m); p = message_tail; } else { // Last message is partial. break; } } // Save any partial data in the overflow buffer. input_overflow_buf_.assign(p, end - p); if (input_overflow_buf_.empty() && !DidEmptyInputBuffers()) return false; return true; }
bool ImageFrameGenerator::decodeAndScale(size_t index, const SkImageInfo& info, void* pixels, size_t rowBytes) { // Prevent concurrent decode or scale operations on the same image data. MutexLocker lock(m_decodeMutex); if (m_decodeFailed) return false; TRACE_EVENT1("blink", "ImageFrameGenerator::decodeAndScale", "frame index", static_cast<int>(index)); m_externalAllocator = adoptPtr(new ExternalMemoryAllocator(info, pixels, rowBytes)); // This implementation does not support scaling so check the requested size. SkISize scaledSize = SkISize::Make(info.width(), info.height()); ASSERT(m_fullSize == scaledSize); SkBitmap bitmap = tryToResumeDecode(index, scaledSize); if (bitmap.isNull()) return false; // Don't keep the allocator because it contains a pointer to memory // that we do not own. m_externalAllocator.clear(); // Check to see if the decoder has written directly to the pixel memory // provided. If not, make a copy. ASSERT(bitmap.width() == scaledSize.width()); ASSERT(bitmap.height() == scaledSize.height()); SkAutoLockPixels bitmapLock(bitmap); if (bitmap.getPixels() != pixels) return bitmap.copyPixelsTo(pixels, rowBytes * info.height(), rowBytes); return true; }
v8::MaybeLocal<v8::Value> ScriptController::callFunction(ExecutionContext* context, v8::Local<v8::Function> function, v8::Local<v8::Value> receiver, int argc, v8::Local<v8::Value> info[], v8::Isolate* isolate) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "FunctionCall", "data", devToolsTraceEventData(isolate, context, function)); InspectorInstrumentationCookie cookie = InspectorInstrumentation::willCallFunction(context, DevToolsFunctionInfo(function)); v8::MaybeLocal<v8::Value> result = V8ScriptRunner::callFunction(function, context, receiver, argc, info, isolate); InspectorInstrumentation::didCallFunction(cookie); return result; }
bool StyleFetchedImage::knownToBeOpaque( const LayoutObject& layoutObject) const { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(&layoutObject, *m_image.get())); return m_image->getImage()->currentFrameKnownToBeOpaque( Image::PreCacheMetadata); }
void ContentLayerDelegate::paintContents( SkCanvas* canvas, const WebRect& clip, WebContentLayerClient::PaintingControlSetting paintingControl) { TRACE_EVENT1("blink,benchmark", "ContentLayerDelegate::paintContents", "clip_rect", toTracedValue(clip)); // TODO(pdr): Remove this function. ASSERT_NOT_REACHED(); }
SkBitmap ImageFrameGenerator::tryToResumeDecode(size_t index, const SkISize& scaledSize) { TRACE_EVENT1("blink", "ImageFrameGenerator::tryToResumeDecode", "frame index", static_cast<int>(index)); ImageDecoder* decoder = 0; const bool resumeDecoding = ImageDecodingStore::instance().lockDecoder(this, m_fullSize, &decoder); ASSERT(!resumeDecoding || decoder); SkBitmap fullSizeImage; bool complete = decode(index, &decoder, &fullSizeImage); if (!decoder) return SkBitmap(); // If we are not resuming decoding that means the decoder is freshly // created and we have ownership. If we are resuming decoding then // the decoder is owned by ImageDecodingStore. OwnPtr<ImageDecoder> decoderContainer; if (!resumeDecoding) decoderContainer = adoptPtr(decoder); if (fullSizeImage.isNull()) { // If decoding has failed, we can save work in the future by // ignoring further requests to decode the image. m_decodeFailed = decoder->failed(); if (resumeDecoding) ImageDecodingStore::instance().unlockDecoder(this, decoder); return SkBitmap(); } bool removeDecoder = false; if (complete) { // Free as much memory as possible. For single-frame images, we can // just delete the decoder entirely. For multi-frame images, we keep // the decoder around in order to preserve decoded information such as // the required previous frame indexes, but if we've reached the last // frame we can at least delete all the cached frames. (If we were to // do this before reaching the last frame, any subsequent requested // frames which relied on the current frame would trigger extra // re-decoding of all frames in the dependency chain.) if (!m_isMultiFrame) removeDecoder = true; else if (index == m_frameCount - 1) decoder->clearCacheExceptFrame(kNotFound); } if (resumeDecoding) { if (removeDecoder) ImageDecodingStore::instance().removeDecoder(this, decoder); else ImageDecodingStore::instance().unlockDecoder(this, decoder); } else if (!removeDecoder) { ImageDecodingStore::instance().insertDecoder(this, decoderContainer.release()); } return fullSizeImage; }
ScriptValue WorkerOrWorkletScriptController::evaluate( const String& script, const String& fileName, const TextPosition& scriptStartPosition, CachedMetadataHandler* cacheHandler, V8CacheOptions v8CacheOptions) { TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data", InspectorEvaluateScriptEvent::data(nullptr, fileName, scriptStartPosition)); if (!initializeContextIfNeeded()) return ScriptValue(); ScriptState::Scope scope(m_scriptState.get()); if (!m_disableEvalPending.isEmpty()) { m_scriptState->context()->AllowCodeGenerationFromStrings(false); m_scriptState->context()->SetErrorMessageForCodeGenerationFromStrings( v8String(m_isolate, m_disableEvalPending)); m_disableEvalPending = String(); } v8::TryCatch block(m_isolate); v8::Local<v8::Script> compiledScript; v8::MaybeLocal<v8::Value> maybeResult; if (v8Call(V8ScriptRunner::compileScript( script, fileName, String(), scriptStartPosition, m_isolate, cacheHandler, SharableCrossOrigin, v8CacheOptions), compiledScript, block)) maybeResult = V8ScriptRunner::runCompiledScript(m_isolate, compiledScript, m_globalScope); if (!block.CanContinue()) { forbidExecution(); return ScriptValue(); } if (block.HasCaught()) { v8::Local<v8::Message> message = block.Message(); m_executionState->hadException = true; m_executionState->errorMessage = toCoreString(message->Get()); m_executionState->m_location = SourceLocation::fromMessage( m_isolate, message, m_scriptState->getExecutionContext()); m_executionState->exception = ScriptValue(m_scriptState.get(), block.Exception()); block.Reset(); } else { m_executionState->hadException = false; } v8::Local<v8::Value> result; if (!maybeResult.ToLocal(&result) || result->IsUndefined()) return ScriptValue(); return ScriptValue(m_scriptState.get(), result); }
// Modifies the top of the graphics layer tree to add layers needed to support // the inner/outer viewport fixed-position model for pinch zoom. When finished, // the tree will look like this (with * denoting added layers): // // *rootTransformLayer // +- *innerViewportContainerLayer (fixed pos container) // | +- *overscrollElasticityLayer // | +- *pageScaleLayer // | +- *innerViewportScrollLayer // | +-- overflowControlsHostLayer (root layer) // | +-- outerViewportContainerLayer (fixed pos container) [frame container layer in PaintLayerCompositor] // | | +-- outerViewportScrollLayer [frame scroll layer in PaintLayerCompositor] // | | +-- content layers ... // +- horizontalScrollbarLayer // +- verticalScrollbarLayer // +- scroll corner (non-overlay only) // void VisualViewport::attachToLayerTree(GraphicsLayer* currentLayerTreeRoot, GraphicsLayerFactory* graphicsLayerFactory) { TRACE_EVENT1("blink", "VisualViewport::attachToLayerTree", "currentLayerTreeRoot", (bool)currentLayerTreeRoot); if (!currentLayerTreeRoot) { if (m_innerViewportScrollLayer) m_innerViewportScrollLayer->removeAllChildren(); return; } if (currentLayerTreeRoot->parent() && currentLayerTreeRoot->parent() == m_innerViewportScrollLayer) return; if (!m_innerViewportScrollLayer) { ASSERT(!m_overlayScrollbarHorizontal && !m_overlayScrollbarVertical && !m_overscrollElasticityLayer && !m_pageScaleLayer && !m_innerViewportContainerLayer); // FIXME: The root transform layer should only be created on demand. m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory, this); m_innerViewportContainerLayer = GraphicsLayer::create(graphicsLayerFactory, this); m_overscrollElasticityLayer = GraphicsLayer::create(graphicsLayerFactory, this); m_pageScaleLayer = GraphicsLayer::create(graphicsLayerFactory, this); m_innerViewportScrollLayer = GraphicsLayer::create(graphicsLayerFactory, this); m_overlayScrollbarHorizontal = GraphicsLayer::create(graphicsLayerFactory, this); m_overlayScrollbarVertical = GraphicsLayer::create(graphicsLayerFactory, this); ScrollingCoordinator* coordinator = frameHost().page().scrollingCoordinator(); ASSERT(coordinator); coordinator->setLayerIsContainerForFixedPositionLayers(m_innerViewportScrollLayer.get(), true); // Set masks to bounds so the compositor doesn't clobber a manually // set inner viewport container layer size. m_innerViewportContainerLayer->setMasksToBounds(frameHost().settings().mainFrameClipsContent()); m_innerViewportContainerLayer->setSize(m_size); m_innerViewportScrollLayer->platformLayer()->setScrollClipLayer( m_innerViewportContainerLayer->platformLayer()); m_innerViewportScrollLayer->platformLayer()->setUserScrollable(true, true); m_rootTransformLayer->addChild(m_innerViewportContainerLayer.get()); m_innerViewportContainerLayer->addChild(m_overscrollElasticityLayer.get()); m_overscrollElasticityLayer->addChild(m_pageScaleLayer.get()); m_pageScaleLayer->addChild(m_innerViewportScrollLayer.get()); // Ensure this class is set as the scroll layer's ScrollableArea. coordinator->scrollableAreaScrollLayerDidChange(this); initializeScrollbars(); } m_innerViewportScrollLayer->removeAllChildren(); m_innerViewportScrollLayer->addChild(currentLayerTreeRoot); }
bool ImageResource::currentFrameKnownToBeOpaque(const LayoutObject* layoutObject) { blink::Image* image = imageForLayoutObject(layoutObject); if (image->isBitmapImage()) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(layoutObject, *this)); // BitmapImage::currentFrameKnownToBeOpaque() conservatively returns true for uncached // frames. To get an accurate answer, we pre-cache the current frame metadata. image->imageForCurrentFrame(); } return image->currentFrameKnownToBeOpaque(); }
bool ImageResource::currentFrameKnownToBeOpaque(const LayoutObject* layoutObject) { blink::Image* image = imageForLayoutObject(layoutObject); if (image->isBitmapImage()) { TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "PaintImage", "data", InspectorPaintImageEvent::data(layoutObject, *this)); SkBitmap dummy; if (!image->bitmapForCurrentFrame(&dummy)) { // force decode // We don't care about failures here, since we don't use "dummy" } } return image->currentFrameKnownToBeOpaque(); }
bool DecodingImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, SkPMColor ctable[], int* ctableCount) { TRACE_EVENT1("blink", "DecodingImageGenerator::getPixels", "index", static_cast<int>(m_frameIndex)); // Implementation doesn't support scaling yet so make sure we're not given a different size. if (info.width() != info.width() || info.height() != info.height() || info.colorType() != info.colorType()) { // ImageFrame may have changed the owning SkBitmap to kOpaque_SkAlphaType after sniffing the encoded data, so if we see a request // for opaque, that is ok even if our initial alphatype was not opaque. return false; } return m_frameGenerator->decodeAndScale(info, m_frameIndex, pixels, rowBytes); }
// There is one queue per element, so this could be invoked // recursively. void CustomElementReactionQueue::invokeReactions(Element* element) { TRACE_EVENT1("blink", "CustomElementReactionQueue::invokeReactions", "name", element->localName().utf8()); while (m_index < m_reactions.size()) { CustomElementReaction* reaction = m_reactions[m_index]; m_reactions[m_index++] = nullptr; reaction->invoke(element); } // Unlike V0CustomElementsCallbackQueue, reactions are always // inserted by steps which bump the global element queue. This // means we do not need queue "owner" guards. // https://html.spec.whatwg.org/multipage/scripting.html#custom-element-reactions clear(); }
const ScaledImageFragment* ImageFrameGenerator::tryToResumeDecodeAndScale(const SkISize& scaledSize, size_t index) { TRACE_EVENT1("webkit", "ImageFrameGenerator::tryToResumeDecodeAndScale", "index", static_cast<int>(index)); ImageDecoder* decoder = 0; const bool resumeDecoding = ImageDecodingStore::instance()->lockDecoder(this, m_fullSize, &decoder); ASSERT(!resumeDecoding || decoder); OwnPtr<ScaledImageFragment> fullSizeImage = decode(index, &decoder); if (!decoder) return 0; // If we are not resuming decoding that means the decoder is freshly // created and we have ownership. If we are resuming decoding then // the decoder is owned by ImageDecodingStore. OwnPtr<ImageDecoder> decoderContainer; if (!resumeDecoding) decoderContainer = adoptPtr(decoder); if (!fullSizeImage) { // If decode has failed and resulted an empty image we can save work // in the future by returning early. m_decodeFailedAndEmpty = !m_isMultiFrame && decoder->failed(); if (resumeDecoding) ImageDecodingStore::instance()->unlockDecoder(this, decoder); return 0; } const ScaledImageFragment* cachedImage = ImageDecodingStore::instance()->insertAndLockCache(this, fullSizeImage.release()); // If the image generated is complete then there is no need to keep // the decoder. The exception is multi-frame decoder which can generate // multiple complete frames. const bool removeDecoder = cachedImage->isComplete() && !m_isMultiFrame; if (resumeDecoding) { if (removeDecoder) ImageDecodingStore::instance()->removeDecoder(this, decoder); else ImageDecodingStore::instance()->unlockDecoder(this, decoder); } else if (!removeDecoder) { ImageDecodingStore::instance()->insertDecoder(this, decoderContainer.release(), DiscardablePixelRef::isDiscardable(cachedImage->bitmap().pixelRef())); } if (m_fullSize == scaledSize) return cachedImage; return tryToScale(cachedImage, scaledSize, index); }