Closed Bug 763134 Opened 12 years ago Closed 12 years ago

GDIFontEntry::GetFontTable takes long time on main thread

Categories

(Core :: Graphics, defect)

x86_64
Windows 7
defect
Not set
normal

Tracking

()

RESOLVED DUPLICATE of bug 734308

People

(Reporter: vladan, Unassigned)

Details

Looking through chrome hang data from nightly-profiling, I saw two stacks where the main thread got hung on this call.

1. Hang lasted 16 seconds. Firefox nightly-profiling 15.0a1 20120510040221

KiFastSystemCallRet (in ntdll.dll)
GDIFontEntry::GetFontTable(unsigned int,FallibleTArray<unsigned char> &) (in xul.dll)
GDIFontEntry::ReadCMAP() (in xul.dll)
gfxFontFamily::ReadAllCMAPs() (in xul.dll)
gfxPlatformFontList::RunLoader() (in xul.dll)
gfxFontInfoLoader::LoaderTimerFire() (in xul.dll)
gfxFontInfoLoader::LoaderTimerCallback(nsITimer *,void *) (in xul.dll)
nsTimerImpl::Fire() (in xul.dll)
nsTimerEvent::Run() (in xul.dll)
nsThread::ProcessNextEvent(bool,bool *) (in xul.dll)
mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate *) (in xul.dll)
MessageLoop::RunHandler() (in xul.dll)
MessageLoop::Run() (in xul.dll)
nsBaseAppShell::Run() (in xul.dll)
nsAppShell::Run() (in xul.dll)
nsAppStartup::Run() (in xul.dll)
XREMain::XRE_mainRun() (in xul.dll)
XREMain::XRE_main(int,char * * const,nsXREAppData const *) (in xul.dll)
XRE_main (in xul.dll)
wmain (in firefox.exe)
__tmainCRTStartup (in firefox.exe)
BaseThreadInitThunk (in kernel32.dll)
__RtlUserThreadStart (in ntdll.dll)
_RtlUserThreadStart (in ntdll.dll)


2. Hang lasted 21 seconds. Firefox nightly-profiling 15.0a1 20120525040206

KiFastSystemCallRet (in ntdll.dll)
GDIFontEntry::GetFontTable(unsigned int,FallibleTArray<unsigned char> &) (in xul.dll)
gfxFontFamily::ReadFaceNames(gfxPlatformFontList *,bool) (in xul.dll)
gfxPlatformFontList::InitFaceNameListsProc(nsAString_internal const &,nsRefPtr<gfxFontFamily> &,void *) (in xul.dll)
nsBaseHashtable<nsStringHashKey,nsFrameJSScriptExecutorHolder *,nsFrameJSScriptExecutorHolder *>::s_EnumStub(PLDHashTable *,PLDHashEntryHdr *,unsigned int,void *) (in xul.dll)
PL_DHashTableEnumerate (in xul.dll)
nsBaseHashtable<nsCStringHashKey,nsCOMPtr<mozIStorageStatement>,mozIStorageStatement *>::Enumerate(PLDHashOperator (*)(nsACString_internal const &,nsCOMPtr<mozIStorageStatement> &,void *),void *) (in xul.dll)
gfxPlatformFontList::InitFaceNameLists() (in xul.dll)
gfxGDIFontList::LookupLocalFont(gfxProxyFontEntry const *,nsAString_internal const &) (in xul.dll)
gfxUserFontSet::LoadNext(gfxProxyFontEntry *) (in xul.dll)
gfxUserFontSet::FindFontEntry(nsAString_internal const &,gfxFontStyle const &,bool &,bool &,bool &) (in xul.dll)
gfxFontGroup::ForEachFontInternal(nsAString_internal const &,nsIAtom *,bool,bool,bool,bool (*)(nsAString_internal const &,nsACString_internal const &,bool,void *),void *) (in xul.dll)
gfxFontGroup::BuildFontList() (in xul.dll)
gfxFontGroup::gfxFontGroup(nsAString_internal const &,gfxFontStyle const *,gfxUserFontSet *) (in xul.dll)
gfxWindowsPlatform::CreateFontGroup(nsAString_internal const &,gfxFontStyle const *,gfxUserFontSet *) (in xul.dll)
nsFontMetrics::Init(nsFont const &,nsIAtom *,nsDeviceContext *,gfxUserFontSet *) (in xul.dll)
nsFontCache::GetMetricsFor(nsFont const &,nsIAtom *,gfxUserFontSet *,nsFontMetrics * &) (in xul.dll)
nsLayoutUtils::GetFontMetricsForStyleContext(nsStyleContext *,nsFontMetrics * *,float) (in xul.dll)
BuildTextRunsScanner::BuildTextRunForFrames(void *) (in xul.dll)
BuildTextRunsScanner::FlushFrames(bool,bool) (in xul.dll)
BuildTextRuns (in xul.dll)
nsTextFrame::EnsureTextRun(nsTextFrame::TextRunType,gfxContext *,nsIFrame *,nsLineList_iterator const *,unsigned int *) (in xul.dll)
nsTextFrame::ReflowText(nsLineLayout &,int,nsRenderingContext *,bool,nsHTMLReflowMetrics &,unsigned int &) (in xul.dll)
nsLineLayout::ReflowFrame(nsIFrame *,unsigned int &,nsHTMLReflowMetrics *,bool &) (in xul.dll)
nsBlockFrame::ReflowInlineFrame(nsBlockReflowState &,nsLineLayout &,nsLineList_iterator,nsIFrame *,LineReflowStatus *) (in xul.dll)
nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState &,nsLineLayout &,nsLineList_iterator,nsFlowAreaRect &,int &,nsFloatManager::SavedState *,bool *,LineReflowStatus *,bool) (in xul.dll)

          < Literally over a 100 calls to Reflow methods !!! >

nsBlockFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
nsBlockReflowContext::ReflowBlock(nsRect const &,bool,nsCollapsingMargin &,int,bool,nsLineBox *,nsHTMLReflowState &,unsigned int &,nsBlockReflowState &) (in xul.dll)
nsBlockFrame::ReflowBlockFrame(nsBlockReflowState &,nsLineList_iterator,bool *) (in xul.dll)
nsBlockFrame::ReflowLine(nsBlockReflowState &,nsLineList_iterator,bool *) (in xul.dll)
nsBlockFrame::ReflowDirtyLines(nsBlockReflowState &) (in xul.dll)
nsBlockFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
nsContainerFrame::ReflowChild(nsIFrame *,nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,int,int,unsigned int,unsigned int &,nsOverflowContinuationTracker *) (in xul.dll)
nsCanvasFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
nsContainerFrame::ReflowChild(nsIFrame *,nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,int,int,unsigned int,unsigned int &,nsOverflowContinuationTracker *) (in xul.dll)
nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState *,bool,bool,nsHTMLReflowMetrics *,bool) (in xul.dll)
nsHTMLScrollFrame::ReflowContents(ScrollReflowState *,nsHTMLReflowMetrics const &) (in xul.dll)
nsHTMLScrollFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
nsContainerFrame::ReflowChild(nsIFrame *,nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,int,int,unsigned int,unsigned int &,nsOverflowContinuationTracker *) (in xul.dll)
ViewportFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
PresShell::DoReflow(nsIFrame *,bool) (in xul.dll)
PresShell::ProcessReflowCommands(bool) (in xul.dll)
PresShell::FlushPendingNotifications(mozFlushType) (in xul.dll)
nsRefreshDriver::Notify(nsITimer *) (in xul.dll)
nsTimerImpl::Fire() (in xul.dll)
nsTimerEvent::Run() (in xul.dll)
nsThread::ProcessNextEvent(bool,bool *) (in xul.dll)
mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate *) (in xul.dll)
MessageLoop::RunHandler() (in xul.dll)
MessageLoop::Run() (in xul.dll)
nsBaseAppShell::Run() (in xul.dll)
nsAppShell::Run() (in xul.dll)
nsAppStartup::Run() (in xul.dll)
XREMain::XRE_mainRun() (in xul.dll)
XREMain::XRE_main(int,char * * const,nsXREAppData const *) (in xul.dll)
XRE_main (in xul.dll)
wmain (in firefox.exe)
__tmainCRTStartup (in firefox.exe)
BaseThreadInitThunk (in kernel32.dll)
__RtlUserThreadStart (in ntdll.dll)
_RtlUserThreadStart (in ntdll.dll)

3. This is from my own machine. Hang lasted 3 seconds. Firefox 16.0a1, nightly-profiling from 2012-06-07

NtGdiGetFontData (in GDI32.dll)
gfxDWriteFontEntry::GetFontTable(unsigned int,FallibleTArray &) (in xul.dll)
gfxFontFamily::ReadFaceNames(gfxPlatformFontList *,bool) (in xul.dll)
gfxPlatformFontList::InitFaceNameListsProc(nsAString_internal const &,nsRefPtr &,void *) (in xul.dll)
nsBaseHashtable::s_EnumStub(PLDHashTable *,PLDHashEntryHdr *,unsigned int,void *) (in xul.dll)
PL_DHashTableEnumerate (in xul.dll)
nsBaseHashtable,gfxFontFamily *>::Enumerate(PLDHashOperator (*)(nsAString_internal const &,nsRefPtr &,void *),void *) (in xul.dll)
gfxPlatformFontList::InitFaceNameLists() (in xul.dll)
gfxDWriteFontList::LookupLocalFont(gfxProxyFontEntry const *,nsAString_internal const &) (in xul.dll)
gfxUserFontSet::LoadNext(gfxProxyFontEntry *) (in xul.dll)
gfxUserFontSet::FindFontEntry(nsAString_internal const &,gfxFontStyle const &,bool &,bool &,bool &) (in xul.dll)
gfxFontGroup::ForEachFontInternal(nsAString_internal const &,nsIAtom *,bool,bool,bool,bool (*)(nsAString_internal const &,nsACString_internal const &,bool,void *),void *) (in xul.dll)
gfxFontGroup::BuildFontList() (in xul.dll)
gfxFontGroup::gfxFontGroup(nsAString_internal const &,gfxFontStyle const *,gfxUserFontSet *) (in xul.dll)
gfxWindowsPlatform::CreateFontGroup(nsAString_internal const &,gfxFontStyle const *,gfxUserFontSet *) (in xul.dll)
nsFontMetrics::Init(nsFont const &,nsIAtom *,nsDeviceContext *,gfxUserFontSet *) (in xul.dll)
nsFontCache::GetMetricsFor(nsFont const &,nsIAtom *,gfxUserFontSet *,nsFontMetrics * &) (in xul.dll)
ComputeLineHeight (in xul.dll)
nsBlockReflowState::nsBlockReflowState(nsHTMLReflowState const &,nsPresContext *,nsBlockFrame *,nsHTMLReflowMetrics const &,bool,bool,bool) (in xul.dll)
nsBlockFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
nsBlockReflowContext::ReflowBlock(nsRect const &,bool,nsCollapsingMargin &,int,bool,nsLineBox *,nsHTMLReflowState &,unsigned int &,nsBlockReflowState &) (in xul.dll)
nsBlockFrame::ReflowBlockFrame(nsBlockReflowState &,nsLineList_iterator,bool *) (in xul.dll)
nsBlockFrame::ReflowLine(nsBlockReflowState &,nsLineList_iterator,bool *) (in xul.dll)
nsBlockFrame::ReflowDirtyLines(nsBlockReflowState &) (in xul.dll)
nsBlockFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
nsContainerFrame::ReflowChild(nsIFrame *,nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,int,int,unsigned int,unsigned int &,nsOverflowContinuationTracker *) (in xul.dll)
nsCanvasFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
nsContainerFrame::ReflowChild(nsIFrame *,nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,int,int,unsigned int,unsigned int &,nsOverflowContinuationTracker *) (in xul.dll)
nsHTMLScrollFrame::ReflowScrolledFrame(ScrollReflowState *,bool,bool,nsHTMLReflowMetrics *,bool) (in xul.dll)
nsHTMLScrollFrame::ReflowContents(ScrollReflowState *,nsHTMLReflowMetrics const &) (in xul.dll)
nsHTMLScrollFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
nsContainerFrame::ReflowChild(nsIFrame *,nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,int,int,unsigned int,unsigned int &,nsOverflowContinuationTracker *) (in xul.dll)
ViewportFrame::Reflow(nsPresContext *,nsHTMLReflowMetrics &,nsHTMLReflowState const &,unsigned int &) (in xul.dll)
PresShell::DoReflow(nsIFrame *,bool) (in xul.dll)
PresShell::ProcessReflowCommands(bool) (in xul.dll)
PresShell::FlushPendingNotifications(mozFlushType) (in xul.dll)
nsDocument::FlushPendingNotifications(mozFlushType) (in xul.dll)
nsGenericElement::GetPrimaryFrame(mozFlushType) (in xul.dll)
nsGenericHTMLElement::GetOffsetWidth(int *) (in xul.dll)
nsIDOMHTMLElement_GetOffsetWidth (in xul.dll)
js::GetPropertyOperation(JSContext *,unsigned char *,JS::Value const &,JS::Value *) (in mozjs.dll)
js::Interpret(JSContext *,js::StackFrame *,js::InterpMode) (in mozjs.dll)
js::InvokeKernel(JSContext *,js::CallArgs,js::MaybeConstruct) (in mozjs.dll)
js::Invoke(JSContext *,js::InvokeArgsGuard &,js::MaybeConstruct) (in mozjs.dll)
js_fun_call(JSContext *,unsigned int,JS::Value *) (in mozjs.dll)
js::InvokeKernel(JSContext *,js::CallArgs,js::MaybeConstruct) (in mozjs.dll)
js::Interpret(JSContext *,js::StackFrame *,js::InterpMode) (in mozjs.dll)
js::InvokeKernel(JSContext *,js::CallArgs,js::MaybeConstruct) (in mozjs.dll)
js::Invoke(JSContext *,JS::Value const &,JS::Value const &,unsigned int,JS::Value *,JS::Value *) (in mozjs.dll)
JS_CallFunctionValue (in mozjs.dll)
nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS *,unsigned short,XPTMethodDescriptor const *,nsXPTCMiniVariant *) (in xul.dll)
nsXPCWrappedJS::CallMethod(unsigned short,XPTMethodDescriptor const *,nsXPTCMiniVariant *) (in xul.dll)
PrepareAndDispatch (in xul.dll)
SharedStub (in xul.dll)
nsEventListenerManager::HandleEventInternal(nsPresContext *,nsEvent *,nsIDOMEvent * *,nsIDOMEventTarget *,unsigned int,nsEventStatus *,nsCxPusher *) (in xul.dll)
nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor &,unsigned int,nsDispatchingCallback *,bool,nsCxPusher *) (in xul.dll)
nsEventDispatcher::Dispatch(nsISupports *,nsPresContext *,nsEvent *,nsIDOMEvent *,nsEventStatus *,nsDispatchingCallback *,nsCOMArray *) (in xul.dll)
nsEventDispatcher::DispatchDOMEvent(nsISupports *,nsEvent *,nsIDOMEvent *,nsPresContext *,nsEventStatus *) (in xul.dll)
nsINode::DispatchEvent(nsIDOMEvent *,bool *) (in xul.dll)
nsContentUtils::DispatchEvent(nsIDocument *,nsISupports *,nsAString_internal const &,bool,bool,bool,bool *) (in xul.dll)
nsDocument::DispatchContentLoadedEvents() (in xul.dll)
nsRunnableMethodImpl::Run() (in xul.dll)
nsThread::ProcessNextEvent(bool,bool *) (in xul.dll)
mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate *) (in xul.dll)
MessageLoop::RunHandler() (in xul.dll)
MessageLoop::Run() (in xul.dll)
nsBaseAppShell::Run() (in xul.dll)
nsAppShell::Run() (in xul.dll)
nsAppStartup::Run() (in xul.dll)
XREMain::XRE_mainRun() (in xul.dll)
XREMain::XRE_main(int,char * * const,nsXREAppData const *) (in xul.dll)
XRE_main (in xul.dll)
wmain (in firefox.exe)
__tmainCRTStartup (in firefox.exe)
BaseThreadInitThunk (in kernel32.dll)
__RtlUserThreadStart (in ntdll.dll)
_RtlUserThreadStart (in ntdll.dll)
Is this related to bug 734308?
The first profile could be helped by bug 734308, as it shows the hang occurring while we're in the process of loading all the font cmaps (to support the font-matching/fallback process).

The second and third profiles are different; here, I believe a page has used @font-face with src:local(), which requires us to look up the requested font by name among all the installed fonts, and because Windows doesn't offer APIs that have the same lookup semantics as CSS requires, we have to explicitly read all the font names and do our own lookup. If we haven't already loaded those names by the time @font-face src:local wants them, we'll block while they are being read from the font files.
Case 1 is a duplicate of bug 734308.  Part of this work is to implement some form of explicit timeout to avoid the chrome hang issue (item (3) in the description).  

Cases 2 and 3 are bug 699331.
Status: NEW → RESOLVED
Closed: 12 years ago
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.