Title: [243617] trunk/Source/_javascript_Core
Revision
243617
Author
[email protected]
Date
2019-03-28 12:37:58 -0700 (Thu, 28 Mar 2019)

Log Message

[JSC] Drop VM and Context cache map in _javascript_Core.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 _javascript_Core.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:

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSContext.mm (243616 => 243617)


--- trunk/Source/_javascript_Core/API/JSContext.mm	2019-03-28 19:32:53 UTC (rev 243616)
+++ trunk/Source/_javascript_Core/API/JSContext.mm	2019-03-28 19:37:58 UTC (rev 243617)
@@ -85,13 +85,15 @@
     };
 
     [self ensureWrapperMap];
-    [m_virtualMachine addContext:self forGlobalContextRef:m_context];
 
+    toJSGlobalObject(m_context)->setAPIWrapper((__bridge void*)self);
+
     return self;
 }
 
 - (void)dealloc
 {
+    toJSGlobalObject(m_context)->setAPIWrapper((__bridge void*)nil);
     m_exception.clear();
     JSGlobalContextRelease(m_context);
     [m_virtualMachine release];
@@ -308,7 +310,7 @@
         context.exception = exceptionValue;
     };
 
-    [m_virtualMachine addContext:self forGlobalContextRef:m_context];
+    toJSGlobalObject(m_context)->setAPIWrapper((__bridge void*)self);
 
     return self;
 }
@@ -358,7 +360,7 @@
 
 - (JSWrapperMap *)wrapperMap
 {
-    return toJS(m_context)->lexicalGlobalObject()->wrapperMap();
+    return toJSGlobalObject(m_context)->wrapperMap();
 }
 
 - (JSValue *)wrapperForJSObject:(JSValueRef)value
@@ -369,8 +371,7 @@
 
 + (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)globalContext
 {
-    JSVirtualMachine *virtualMachine = [JSVirtualMachine virtualMachineWithContextGroupRef:toRef(&toJS(globalContext)->vm())];
-    JSContext *context = [virtualMachine contextForGlobalContextRef:globalContext];
+    JSContext *context = (__bridge JSContext *)toJSGlobalObject(globalContext)->apiWrapper();
     if (!context)
         context = [[[JSContext alloc] initWithGlobalContextRef:globalContext] autorelease];
     return context;

Modified: trunk/Source/_javascript_Core/API/JSVirtualMachine.mm (243616 => 243617)


--- trunk/Source/_javascript_Core/API/JSVirtualMachine.mm	2019-03-28 19:32:53 UTC (rev 243616)
+++ trunk/Source/_javascript_Core/API/JSVirtualMachine.mm	2019-03-28 19:37:58 UTC (rev 243617)
@@ -41,50 +41,9 @@
 #import <wtf/BlockPtr.h>
 #import <wtf/Lock.h>
 
-static NSMapTable *globalWrapperCache = 0;
-
-static Lock wrapperCacheMutex;
-
-static void initWrapperCache()
-{
-    ASSERT(!globalWrapperCache);
-    NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
-    NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
-    globalWrapperCache = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
-}
-
-static NSMapTable *wrapperCache()
-{
-    if (!globalWrapperCache)
-        initWrapperCache();
-    return globalWrapperCache;
-}
-
-@interface JSVMWrapperCache : NSObject
-+ (void)addWrapper:(JSVirtualMachine *)wrapper forJSContextGroupRef:(JSContextGroupRef)group;
-+ (JSVirtualMachine *)wrapperForJSContextGroupRef:(JSContextGroupRef)group;
-@end
-
-@implementation JSVMWrapperCache
-
-+ (void)addWrapper:(JSVirtualMachine *)wrapper forJSContextGroupRef:(JSContextGroupRef)group
-{
-    std::lock_guard<Lock> lock(wrapperCacheMutex);
-    NSMapInsert(wrapperCache(), group, (__bridge void*)wrapper);
-}
-
-+ (JSVirtualMachine *)wrapperForJSContextGroupRef:(JSContextGroupRef)group
-{
-    std::lock_guard<Lock> lock(wrapperCacheMutex);
-    return (__bridge JSVirtualMachine *)NSMapGet(wrapperCache(), group);
-}
-
-@end
-
 @implementation JSVirtualMachine {
     JSContextGroupRef m_group;
     Lock m_externalDataMutex;
-    NSMapTable *m_contextCache;
     NSMapTable *m_externalObjectGraph;
     NSMapTable *m_externalRememberedSet;
 }
@@ -106,10 +65,6 @@
     
     m_group = JSContextGroupRetain(group);
     
-    NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality;
-    NSPointerFunctionsOptions valueOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
-    m_contextCache = [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0];
-    
     NSPointerFunctionsOptions weakIDOptions = NSPointerFunctionsWeakMemory | NSPointerFunctionsObjectPersonality;
     NSPointerFunctionsOptions strongIDOptions = NSPointerFunctionsStrongMemory | NSPointerFunctionsObjectPersonality;
     m_externalObjectGraph = [[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:strongIDOptions capacity:0];
@@ -116,8 +71,8 @@
 
     NSPointerFunctionsOptions integerOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsIntegerPersonality;
     m_externalRememberedSet = [[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:integerOptions capacity:0];
-   
-    [JSVMWrapperCache addWrapper:self forJSContextGroupRef:group];
+
+    toJS(group)->m_apiWrapper = (__bridge void*)self;
  
     return self;
 }
@@ -124,8 +79,8 @@
 
 - (void)dealloc
 {
+    toJS(m_group)->m_apiWrapper = (__bridge void*)nil;
     JSContextGroupRelease(m_group);
-    [m_contextCache release];
     [m_externalObjectGraph release];
     [m_externalRememberedSet release];
     [super dealloc];
@@ -237,22 +192,13 @@
 
 + (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group
 {
-    JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:group];
+    auto* vm = toJS(group);
+    JSVirtualMachine *virtualMachine = (__bridge JSVirtualMachine *)vm->m_apiWrapper;
     if (!virtualMachine)
         virtualMachine = [[[JSVirtualMachine alloc] initWithContextGroupRef:group] autorelease];
     return virtualMachine;
 }
 
-- (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext
-{
-    return (__bridge JSContext *)NSMapGet(m_contextCache, globalContext);
-}
-
-- (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext
-{
-    NSMapInsert(m_contextCache, globalContext, (__bridge void*)wrapper);
-}
-
 - (Lock&)externalDataMutex
 {
     return m_externalDataMutex;
@@ -312,7 +258,7 @@
 static void scanExternalObjectGraph(JSC::VM& vm, JSC::SlotVisitor& visitor, void* root, bool lockAcquired)
 {
     @autoreleasepool {
-        JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:toRef(&vm)];
+        JSVirtualMachine *virtualMachine = (__bridge JSVirtualMachine *)vm.m_apiWrapper;
         if (!virtualMachine)
             return;
         NSMapTable *externalObjectGraph = [virtualMachine externalObjectGraph];
@@ -350,7 +296,7 @@
 void scanExternalRememberedSet(JSC::VM& vm, JSC::SlotVisitor& visitor)
 {
     @autoreleasepool {
-        JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:toRef(&vm)];
+        JSVirtualMachine *virtualMachine = (__bridge JSVirtualMachine *)vm.m_apiWrapper;
         if (!virtualMachine)
             return;
         Lock& externalDataMutex = [virtualMachine externalDataMutex];

Modified: trunk/Source/_javascript_Core/API/JSVirtualMachineInternal.h (243616 => 243617)


--- trunk/Source/_javascript_Core/API/JSVirtualMachineInternal.h	2019-03-28 19:32:53 UTC (rev 243616)
+++ trunk/Source/_javascript_Core/API/JSVirtualMachineInternal.h	2019-03-28 19:37:58 UTC (rev 243617)
@@ -44,8 +44,6 @@
 
 + (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group;
 
-- (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext;
-- (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext;
 - (JSC::VM&)vm;
 
 @end

Modified: trunk/Source/_javascript_Core/ChangeLog (243616 => 243617)


--- trunk/Source/_javascript_Core/ChangeLog	2019-03-28 19:32:53 UTC (rev 243616)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-03-28 19:37:58 UTC (rev 243617)
@@ -1,3 +1,42 @@
+2019-03-27  Yusuke Suzuki  <[email protected]>
+
+        [JSC] Drop VM and Context cache map in _javascript_Core.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 _javascript_Core.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:
+
 2019-03-28  Tadeu Zagallo  <[email protected]>
 
         In-memory code cache should not share bytecode across domains

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (243616 => 243617)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2019-03-28 19:32:53 UTC (rev 243616)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2019-03-28 19:37:58 UTC (rev 243617)
@@ -1005,6 +1005,8 @@
 #if JSC_OBJC_API_ENABLED
     JSWrapperMap* wrapperMap() const { return m_wrapperMap.get(); }
     void setWrapperMap(JSWrapperMap* map) { m_wrapperMap = map; }
+    void setAPIWrapper(void* apiWrapper) { m_apiWrapper = apiWrapper; }
+    void* apiWrapper() const { return m_apiWrapper; }
 #endif
 #ifdef JSC_GLIB_API_ENABLED
     WrapperMap* wrapperMap() const { return m_wrapperMap.get(); }
@@ -1047,6 +1049,7 @@
     bool m_needsSiteSpecificQuirks { false };
 #if JSC_OBJC_API_ENABLED
     RetainPtr<JSWrapperMap> m_wrapperMap;
+    void* m_apiWrapper { nullptr };
 #endif
 #ifdef JSC_GLIB_API_ENABLED
     std::unique_ptr<WrapperMap> m_wrapperMap;

Modified: trunk/Source/_javascript_Core/runtime/VM.h (243616 => 243617)


--- trunk/Source/_javascript_Core/runtime/VM.h	2019-03-28 19:32:53 UTC (rev 243616)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2019-03-28 19:37:58 UTC (rev 243617)
@@ -804,6 +804,10 @@
     RTTraceList* m_rtTraceList;
 #endif
 
+#if JSC_OBJC_API_ENABLED
+    void* m_apiWrapper { nullptr };
+#endif
+
     JS_EXPORT_PRIVATE void resetDateCache();
 
     RegExpCache* regExpCache() { return m_regExpCache; }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to