Bug 135359 - [iOS] REGRESSION(r171526): PDF documents fail to load in WebKit1 with disk image caching enabled
Summary: [iOS] REGRESSION(r171526): PDF documents fail to load in WebKit1 with disk im...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Platform (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Pratik Solanki
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2014-07-28 15:19 PDT by Pratik Solanki
Modified: 2014-07-29 14:42 PDT (History)
5 users (show)

See Also:


Attachments
Patch (3.55 KB, patch)
2014-07-28 16:23 PDT, Pratik Solanki
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Pratik Solanki 2014-07-28 15:19:19 PDT
When disk image caching is enabled, m_buffer in SharedBuffer is empty. createCFData() returns a WebCoreSharedBufferData with that empty buffer data and this causes pdf to fail to load. createCFData needs to take care of disk image cache backed resources.
Comment 1 Pratik Solanki 2014-07-28 16:04:50 PDT
<rdar://problem/17824645>
Comment 2 Pratik Solanki 2014-07-28 16:23:15 PDT
Created attachment 235637 [details]
Patch
Comment 3 Darin Adler 2014-07-29 00:53:21 PDT
Comment on attachment 235637 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=235637&action=review

Please fix the GC problem I spotted. Also probably need to find a way to test under garbage collection.

> Source/WebCore/platform/mac/SharedBufferMac.mm:42
>      RefPtr<SharedBuffer::DataBuffer> buffer;
> +#if ENABLE(DISK_IMAGE_CACHE)
> +    RefPtr<SharedBuffer> sharedBuffer;
> +#endif

I think the instance field names here are confusing. They are basically both shared buffers, and naming one buffer and the other sharedBuffer is not going to distinguish them. Please consider names that would make the code clearer.

> Source/WebCore/platform/mac/SharedBufferMac.mm:47
> +- (id)initWithDiskImageSharedBuffer:(SharedBuffer*)sharedBuffer;

I’d think we’d want to call this initWithMemoryMappedSharedBuffer: instead.

> Source/WebCore/platform/mac/SharedBufferMac.mm:86
> +- (id)initWithDiskImageSharedBuffer:(SharedBuffer*)diskImageSharedBuffer

The function assumes this pointer is non-null, so it should take a reference rather than a pointer.

> Source/WebCore/platform/mac/SharedBufferMac.mm:93
> +    ASSERT(diskImageSharedBuffer->isMemoryMapped());

Why assert this after calling [super init]? I’d think an assertion about the validity of an argument would come first.

> Source/WebCore/platform/mac/SharedBufferMac.mm:103
> +        ASSERT(sharedBuffer->isMemoryMapped());

Do we really need to keep asserting this repeatedly? We already assert it in the init method.

> Source/WebCore/platform/mac/SharedBufferMac.mm:114
> +        ASSERT(sharedBuffer->isMemoryMapped());

Do we really need to keep asserting this repeatedly? We already assert it in the init method.

> Source/WebCore/platform/mac/SharedBufferMac.mm:115
> +        return reinterpret_cast<const void*>(sharedBuffer->data());

There’s no need for a typecast here at all. A const char* can be converted into a const void* without a cast. And if we did need a case, there’d be no reason to use reinterpret_cast instead of static_cast.

> Source/WebCore/platform/mac/SharedBufferMac.mm:118
>      return reinterpret_cast<const void*>(buffer->data.data());

No need for a typecast here either.

> Source/WebCore/platform/mac/SharedBufferMac.mm:147
> +        return adoptCF(reinterpret_cast<CFDataRef>([[WebCoreSharedBufferData alloc] initWithDiskImageSharedBuffer:this]));

This does not do the right thing for garbage collection. You can’t balance an Objective-C alloc with a CFRelease, and that’s what this code tries to do. But since we only currently turn on DISK_IMAGE_CACHE on iOS and we don’t support GC on iOS we can get away with this sloppiness. Unfortunately I see the same thing a few lines down from here, in code that is not specific to iOS, so it looks like r171526 broke WebKit running under garbage collection.
Comment 4 Pratik Solanki 2014-07-29 09:16:36 PDT
Comment on attachment 235637 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=235637&action=review

>> Source/WebCore/platform/mac/SharedBufferMac.mm:147
>> +        return adoptCF(reinterpret_cast<CFDataRef>([[WebCoreSharedBufferData alloc] initWithDiskImageSharedBuffer:this]));
> 
> This does not do the right thing for garbage collection. You can’t balance an Objective-C alloc with a CFRelease, and that’s what this code tries to do. But since we only currently turn on DISK_IMAGE_CACHE on iOS and we don’t support GC on iOS we can get away with this sloppiness. Unfortunately I see the same thing a few lines down from here, in code that is not specific to iOS, so it looks like r171526 broke WebKit running under garbage collection.

Thanks for spotting this. The original code was

    return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBuffer:this]).leakRef());

Looks like both adoptNS and adoptCF are needed. Is this correct?

I also made createNSData() call createCFData()

-    return adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBuffer:this]);
+    return adoptNS((NSData *)createCFData().leakRef());

Would that do the right thing under GC?
Comment 5 Pratik Solanki 2014-07-29 14:42:03 PDT
Committed r171766: <http://trac.webkit.org/changeset/171766>