- Revision
- 247346
- Author
- ysuz...@apple.com
- Date
- 2019-07-11 02:42:22 -0700 (Thu, 11 Jul 2019)
Log Message
Unreviewed, revert r243617.
https://bugs.webkit.org/show_bug.cgi?id=196341
Mark pointed out that JSVirtualMachine can be gone in the other thread while we are executing GC constraint-solving.
This patch does not account that _javascript_Core.framework is multi-thread safe: JSVirtualMachine wrapper can be destroyed,
and [JSVirtualMachine dealloc] can be executed in any threads while the VM is retained and used in the other thread (e.g.
destroyed from AutoReleasePool in some thread).
* API/JSContext.mm:
(-[JSContext initWithVirtualMachine:]):
(-[JSContext dealloc]):
(-[JSContext initWithGlobalContextRef:]):
(-[JSContext wrapperMap]):
(+[JSContext contextWithJSGlobalContextRef:]):
* API/JSVirtualMachine.mm:
(initWrapperCache):
(wrapperCache):
(+[JSVMWrapperCache addWrapper:forJSContextGroupRef:]):
(+[JSVMWrapperCache wrapperForJSContextGroupRef:]):
(-[JSVirtualMachine initWithContextGroupRef:]):
(-[JSVirtualMachine dealloc]):
(+[JSVirtualMachine virtualMachineWithContextGroupRef:]):
(-[JSVirtualMachine contextForGlobalContextRef:]):
(-[JSVirtualMachine addContext:forGlobalContextRef:]):
(scanExternalObjectGraph):
(scanExternalRememberedSet):
* API/JSVirtualMachineInternal.h:
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::setWrapperMap):
(JSC::JSGlobalObject::setAPIWrapper): Deleted.
(JSC::JSGlobalObject::apiWrapper const): Deleted.
* runtime/VM.h:
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/API/JSContext.mm (247345 => 247346)
--- trunk/Source/_javascript_Core/API/JSContext.mm 2019-07-11 07:34:19 UTC (rev 247345)
+++ trunk/Source/_javascript_Core/API/JSContext.mm 2019-07-11 09:42:22 UTC (rev 247346)
@@ -85,15 +85,13 @@
};
[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];
@@ -310,7 +308,7 @@
context.exception = exceptionValue;
};
- toJSGlobalObject(m_context)->setAPIWrapper((__bridge void*)self);
+ [m_virtualMachine addContext:self forGlobalContextRef:m_context];
return self;
}
@@ -360,7 +358,7 @@
- (JSWrapperMap *)wrapperMap
{
- return toJSGlobalObject(m_context)->wrapperMap();
+ return toJS(m_context)->lexicalGlobalObject()->wrapperMap();
}
- (JSValue *)wrapperForJSObject:(JSValueRef)value
@@ -371,7 +369,8 @@
+ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)globalContext
{
- JSContext *context = (__bridge JSContext *)toJSGlobalObject(globalContext)->apiWrapper();
+ JSVirtualMachine *virtualMachine = [JSVirtualMachine virtualMachineWithContextGroupRef:toRef(&toJS(globalContext)->vm())];
+ JSContext *context = [virtualMachine contextForGlobalContextRef:globalContext];
if (!context)
context = [[[JSContext alloc] initWithGlobalContextRef:globalContext] autorelease];
return context;
Modified: trunk/Source/_javascript_Core/API/JSVirtualMachine.mm (247345 => 247346)
--- trunk/Source/_javascript_Core/API/JSVirtualMachine.mm 2019-07-11 07:34:19 UTC (rev 247345)
+++ trunk/Source/_javascript_Core/API/JSVirtualMachine.mm 2019-07-11 09:42:22 UTC (rev 247346)
@@ -41,9 +41,50 @@
#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;
}
@@ -65,6 +106,10 @@
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];
@@ -71,8 +116,8 @@
NSPointerFunctionsOptions integerOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsIntegerPersonality;
m_externalRememberedSet = [[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:integerOptions capacity:0];
-
- toJS(group)->m_apiWrapper = (__bridge void*)self;
+
+ [JSVMWrapperCache addWrapper:self forJSContextGroupRef:group];
return self;
}
@@ -79,8 +124,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];
@@ -192,13 +237,22 @@
+ (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group
{
- auto* vm = toJS(group);
- JSVirtualMachine *virtualMachine = (__bridge JSVirtualMachine *)vm->m_apiWrapper;
+ JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:group];
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;
@@ -263,7 +317,7 @@
static void scanExternalObjectGraph(JSC::VM& vm, JSC::SlotVisitor& visitor, void* root, bool lockAcquired)
{
@autoreleasepool {
- JSVirtualMachine *virtualMachine = (__bridge JSVirtualMachine *)vm.m_apiWrapper;
+ JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:toRef(&vm)];
if (!virtualMachine)
return;
NSMapTable *externalObjectGraph = [virtualMachine externalObjectGraph];
@@ -301,7 +355,7 @@
void scanExternalRememberedSet(JSC::VM& vm, JSC::SlotVisitor& visitor)
{
@autoreleasepool {
- JSVirtualMachine *virtualMachine = (__bridge JSVirtualMachine *)vm.m_apiWrapper;
+ JSVirtualMachine *virtualMachine = [JSVMWrapperCache wrapperForJSContextGroupRef:toRef(&vm)];
if (!virtualMachine)
return;
Lock& externalDataMutex = [virtualMachine externalDataMutex];
Modified: trunk/Source/_javascript_Core/API/JSVirtualMachineInternal.h (247345 => 247346)
--- trunk/Source/_javascript_Core/API/JSVirtualMachineInternal.h 2019-07-11 07:34:19 UTC (rev 247345)
+++ trunk/Source/_javascript_Core/API/JSVirtualMachineInternal.h 2019-07-11 09:42:22 UTC (rev 247346)
@@ -44,6 +44,8 @@
+ (JSVirtualMachine *)virtualMachineWithContextGroupRef:(JSContextGroupRef)group;
+- (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext;
+- (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext;
- (JSC::VM&)vm;
- (BOOL)isWebThreadAware;
Modified: trunk/Source/_javascript_Core/ChangeLog (247345 => 247346)
--- trunk/Source/_javascript_Core/ChangeLog 2019-07-11 07:34:19 UTC (rev 247345)
+++ trunk/Source/_javascript_Core/ChangeLog 2019-07-11 09:42:22 UTC (rev 247346)
@@ -1,3 +1,38 @@
+2019-07-11 Yusuke Suzuki <ysuz...@apple.com>
+
+ Unreviewed, revert r243617.
+ https://bugs.webkit.org/show_bug.cgi?id=196341
+
+ Mark pointed out that JSVirtualMachine can be gone in the other thread while we are executing GC constraint-solving.
+ This patch does not account that _javascript_Core.framework is multi-thread safe: JSVirtualMachine wrapper can be destroyed,
+ and [JSVirtualMachine dealloc] can be executed in any threads while the VM is retained and used in the other thread (e.g.
+ destroyed from AutoReleasePool in some thread).
+
+ * API/JSContext.mm:
+ (-[JSContext initWithVirtualMachine:]):
+ (-[JSContext dealloc]):
+ (-[JSContext initWithGlobalContextRef:]):
+ (-[JSContext wrapperMap]):
+ (+[JSContext contextWithJSGlobalContextRef:]):
+ * API/JSVirtualMachine.mm:
+ (initWrapperCache):
+ (wrapperCache):
+ (+[JSVMWrapperCache addWrapper:forJSContextGroupRef:]):
+ (+[JSVMWrapperCache wrapperForJSContextGroupRef:]):
+ (-[JSVirtualMachine initWithContextGroupRef:]):
+ (-[JSVirtualMachine dealloc]):
+ (+[JSVirtualMachine virtualMachineWithContextGroupRef:]):
+ (-[JSVirtualMachine contextForGlobalContextRef:]):
+ (-[JSVirtualMachine addContext:forGlobalContextRef:]):
+ (scanExternalObjectGraph):
+ (scanExternalRememberedSet):
+ * API/JSVirtualMachineInternal.h:
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::setWrapperMap):
+ (JSC::JSGlobalObject::setAPIWrapper): Deleted.
+ (JSC::JSGlobalObject::apiWrapper const): Deleted.
+ * runtime/VM.h:
+
2019-07-10 Tadeu Zagallo <tzaga...@apple.com>
Optimize join of large empty arrays
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (247345 => 247346)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2019-07-11 07:34:19 UTC (rev 247345)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2019-07-11 09:42:22 UTC (rev 247346)
@@ -1010,8 +1010,6 @@
#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(); }
@@ -1054,7 +1052,6 @@
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 (247345 => 247346)
--- trunk/Source/_javascript_Core/runtime/VM.h 2019-07-11 07:34:19 UTC (rev 247345)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2019-07-11 09:42:22 UTC (rev 247346)
@@ -833,10 +833,6 @@
RTTraceList* m_rtTraceList;
#endif
-#if JSC_OBJC_API_ENABLED
- void* m_apiWrapper { nullptr };
-#endif
-
JS_EXPORT_PRIVATE void resetDateCache();
RegExpCache* regExpCache() { return m_regExpCache; }