⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 243617 in webkit


Ignore:
Timestamp:
Mar 28, 2019, 12:37:58 PM (7 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] Drop VM and Context cache map in JavaScriptCore.framework
https://bugs.webkit.org/show_bug.cgi?id=196341

Reviewed by Saam Barati.

Previously, we created Objective-C weak map to maintain JSVirtualMachine and JSContext wrappers corresponding to VM and JSGlobalObject.
But Objective-C weak map is really memory costly. Even if the entry is only one, it consumes 2.5KB per weak map. Since we can modify
JSC intrusively for JavaScriptCore.framework (and we already did it, like, holding JSWrapperMap in JSGlobalObject), we can just hold
a pointer to a wrapper in VM and JSGlobalObject.

This patch adds void* members to VM and JSGlobalObject, which holds a non-strong reference to a wrapper. When a wrapper is gone, we
clear this pointer too. This removes unnecessary two Objective-C weak maps, and save 5KB.

  • API/JSContext.mm:

(-[JSContext initWithVirtualMachine:]):
(-[JSContext dealloc]):
(-[JSContext initWithGlobalContextRef:]):
(-[JSContext wrapperMap]):
(+[JSContext contextWithJSGlobalContextRef:]):

  • API/JSVirtualMachine.mm:

(-[JSVirtualMachine initWithContextGroupRef:]):
(-[JSVirtualMachine dealloc]):
(+[JSVirtualMachine virtualMachineWithContextGroupRef:]):
(scanExternalObjectGraph):
(scanExternalRememberedSet):
(initWrapperCache): Deleted.
(wrapperCache): Deleted.
(+[JSVMWrapperCache addWrapper:forJSContextGroupRef:]): Deleted.
(+[JSVMWrapperCache wrapperForJSContextGroupRef:]): Deleted.
(-[JSVirtualMachine contextForGlobalContextRef:]): Deleted.
(-[JSVirtualMachine addContext:forGlobalContextRef:]): Deleted.

  • API/JSVirtualMachineInternal.h:
  • runtime/JSGlobalObject.h:

(JSC::JSGlobalObject::setAPIWrapper):
(JSC::JSGlobalObject::apiWrapper const):

  • runtime/VM.h:
Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/API/JSContext.mm

    r242980 r243617  
    8686
    8787    [self ensureWrapperMap];
    88     [m_virtualMachine addContext:self forGlobalContextRef:m_context];
     88
     89    toJSGlobalObject(m_context)->setAPIWrapper((__bridge void*)self);
    8990
    9091    return self;
     
    9394- (void)dealloc
    9495{
     96    toJSGlobalObject(m_context)->setAPIWrapper((__bridge void*)nil);
    9597    m_exception.clear();
    9698    JSGlobalContextRelease(m_context);
     
    309311    };
    310312
    311     [m_virtualMachine addContext:self forGlobalContextRef:m_context];
     313    toJSGlobalObject(m_context)->setAPIWrapper((__bridge void*)self);
    312314
    313315    return self;
     
    359361- (JSWrapperMap *)wrapperMap
    360362{
    361     return toJS(m_context)->lexicalGlobalObject()->wrapperMap();
     363    return toJSGlobalObject(m_context)->wrapperMap();
    362364}
    363365
     
    370372+ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)globalContext
    371373{
    372     JSVirtualMachine *virtualMachine = [JSVirtualMachine virtualMachineWithContextGroupRef:toRef(&toJS(globalContext)->vm())];
    373     JSContext *context = [virtualMachine contextForGlobalContextRef:globalContext];
     374    JSContext *context = (__bridge JSContext *)toJSGlobalObject(globalContext)->apiWrapper();
    374375    if (!context)
    375376        context = [[[JSContext alloc] initWithGlobalContextRef:globalContext] autorelease];
  • trunk/Source/JavaScriptCore/API/JSVirtualMachine.mm

    r242301 r243617  
    4242#import <wtf/Lock.h>
    4343
    44 static NSMapTable *globalWrapperCache = 0;
    45 
    46 static Lock wrapperCacheMutex;
    47 
    48 static void initWrapperCache()
    49 {
    50     ASSERT(!globalWrapperCache);
    51     NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
    52     NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
    53     globalWrapperCache = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
    54 }
    55 
    56 static NSMapTable *wrapperCache()
    57 {
    58     if (!globalWrapperCache)
    59         initWrapperCache();
    60     return globalWrapperCache;
    61 }
    62 
    63 @interface JSVMWrapperCache : NSObject
    64 + (void)addWrapper:(JSVirtualMachine *)wrapper forJSContextGroupRef:(JSContextGroupRef)group;
    65 + (JSVirtualMachine *)wrapperForJSContextGroupRef:(JSContextGroupRef)group;
    66 @end
    67 
    68 @implementation JSVMWrapperCache
    69 
    70 + (void)addWrapper:(JSVirtualMachine *)wrapper forJSContextGroupRef:(JSContextGroupRef)group
    71 {
    72     std::lock_guard<Lock> lock(wrapperCacheMutex);
    73     NSMapInsert(wrapperCache(), group, (__bridge void*)wrapper);
    74 }
    75 
    76 + (JSVirtualMachine *)wrapperForJSContextGroupRef:(JSContextGroupRef)group
    77 {
    78     std::lock_guard<Lock> lock(wrapperCacheMutex);
    79     return (__bridge JSVirtualMachine *)NSMapGet(wrapperCache(), group);
    80 }
    81 
    82 @end
    83 
    8444@implementation JSVirtualMachine {
    8545    JSContextGroupRef m_group;
    8646    Lock m_externalDataMutex;
    87     NSMapTable *m_contextCache;
    8847    NSMapTable *m_externalObjectGraph;
    8948    NSMapTable *m_externalRememberedSet;
     
    10766    m_group = JSContextGroupRetain(group);
    10867   
    109     NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
    110     NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
    111     m_contextCache = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
    112    
    11368    NSPointerFunctionsOptions weakIDOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
    11469    NSPointerFunctionsOptions strongIDOptions = NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality;
     
    11772    NSPointerFunctionsOptions integerOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsIntegerPersonality;
    11873    m_externalRememberedSet = [[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:integerOptions capacity:0];
    119    
    120     [JSVMWrapperCache addWrapper:self forJSContextGroupRef:group];
     74
     75    toJS(group)->m_apiWrapper = (__bridge void*)self;
    12176 
    12277    return self;
     
    12580- (void)dealloc
    12681{
     82    toJS(m_group)->m_apiWrapper = (__bridge void*)nil;
    12783    JSContextGroupRelease(m_group);
    128     [m_contextCache release];
    12984    [m_externalObjectGraph release];
    13085    [m_externalRememberedSet release];
     
    238193+ (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group
    239194{
    240     JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:group];
     195    auto* vm = toJS(group);
     196    JSVirtualMachine *virtualMachine = (__bridge JSVirtualMachine *)vm->m_apiWrapper;
    241197    if (!virtualMachine)
    242198        virtualMachine = [[[JSVirtualMachine alloc] initWithContextGroupRef:group] autorelease];
    243199    return virtualMachine;
    244 }
    245 
    246 - (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext
    247 {
    248     return (__bridge JSContext *)NSMapGet(m_contextCache, globalContext);
    249 }
    250 
    251 - (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext
    252 {
    253     NSMapInsert(m_contextCache, globalContext, (__bridge void*)wrapper);
    254200}
    255201
     
    313259{
    314260    @autoreleasepool {
    315         JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:toRef(&vm)];
     261        JSVirtualMachine *virtualMachine = (__bridge JSVirtualMachine *)vm.m_apiWrapper;
    316262        if (!virtualMachine)
    317263            return;
     
    351297{
    352298    @autoreleasepool {
    353         JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:toRef(&vm)];
     299        JSVirtualMachine *virtualMachine = (__bridge JSVirtualMachine *)vm.m_apiWrapper;
    354300        if (!virtualMachine)
    355301            return;
  • trunk/Source/JavaScriptCore/API/JSVirtualMachineInternal.h

    r240511 r243617  
    4545+ (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group;
    4646
    47 - (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext;
    48 - (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext;
    4947- (JSC::VM&)vm;
    5048
  • trunk/Source/JavaScriptCore/ChangeLog

    r243609 r243617  
     12019-03-27  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] Drop VM and Context cache map in JavaScriptCore.framework
     4        https://bugs.webkit.org/show_bug.cgi?id=196341
     5
     6        Reviewed by Saam Barati.
     7
     8        Previously, we created Objective-C weak map to maintain JSVirtualMachine and JSContext wrappers corresponding to VM and JSGlobalObject.
     9        But Objective-C weak map is really memory costly. Even if the entry is only one, it consumes 2.5KB per weak map. Since we can modify
     10        JSC intrusively for JavaScriptCore.framework (and we already did it, like, holding JSWrapperMap in JSGlobalObject), we can just hold
     11        a pointer to a wrapper in VM and JSGlobalObject.
     12
     13        This patch adds void* members to VM and JSGlobalObject, which holds a non-strong reference to a wrapper. When a wrapper is gone, we
     14        clear this pointer too. This removes unnecessary two Objective-C weak maps, and save 5KB.
     15
     16        * API/JSContext.mm:
     17        (-[JSContext initWithVirtualMachine:]):
     18        (-[JSContext dealloc]):
     19        (-[JSContext initWithGlobalContextRef:]):
     20        (-[JSContext wrapperMap]):
     21        (+[JSContext contextWithJSGlobalContextRef:]):
     22        * API/JSVirtualMachine.mm:
     23        (-[JSVirtualMachine initWithContextGroupRef:]):
     24        (-[JSVirtualMachine dealloc]):
     25        (+[JSVirtualMachine virtualMachineWithContextGroupRef:]):
     26        (scanExternalObjectGraph):
     27        (scanExternalRememberedSet):
     28        (initWrapperCache): Deleted.
     29        (wrapperCache): Deleted.
     30        (+[JSVMWrapperCache addWrapper:forJSContextGroupRef:]): Deleted.
     31        (+[JSVMWrapperCache wrapperForJSContextGroupRef:]): Deleted.
     32        (-[JSVirtualMachine contextForGlobalContextRef:]): Deleted.
     33        (-[JSVirtualMachine addContext:forGlobalContextRef:]): Deleted.
     34        * API/JSVirtualMachineInternal.h:
     35        * runtime/JSGlobalObject.h:
     36        (JSC::JSGlobalObject::setAPIWrapper):
     37        (JSC::JSGlobalObject::apiWrapper const):
     38        * runtime/VM.h:
     39
    1402019-03-28  Tadeu Zagallo  <tzagallo@apple.com>
    241
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r243051 r243617  
    10061006    JSWrapperMap* wrapperMap() const { return m_wrapperMap.get(); }
    10071007    void setWrapperMap(JSWrapperMap* map) { m_wrapperMap = map; }
     1008    void setAPIWrapper(void* apiWrapper) { m_apiWrapper = apiWrapper; }
     1009    void* apiWrapper() const { return m_apiWrapper; }
    10081010#endif
    10091011#ifdef JSC_GLIB_API_ENABLED
     
    10481050#if JSC_OBJC_API_ENABLED
    10491051    RetainPtr<JSWrapperMap> m_wrapperMap;
     1052    void* m_apiWrapper { nullptr };
    10501053#endif
    10511054#ifdef JSC_GLIB_API_ENABLED
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r243312 r243617  
    805805#endif
    806806
     807#if JSC_OBJC_API_ENABLED
     808    void* m_apiWrapper { nullptr };
     809#endif
     810
    807811    JS_EXPORT_PRIVATE void resetDateCache();
    808812
Note: See TracChangeset for help on using the changeset viewer.