Changeset 210458 in webkit


Ignore:
Timestamp:
Jan 6, 2017 3:38:31 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

The ObjC API's JSVirtualMachine's map tables need to be guarded by a lock.
https://bugs.webkit.org/show_bug.cgi?id=166778
<rdar://problem/29761198>

Reviewed by Filip Pizlo.

Now that we have a concurrent GC, access to JSVirtualMachine's
m_externalObjectGraph and m_externalRememberedSet need to be guarded by a lock
since both the GC marker thread and the mutator thread may access them at the
same time.

  • API/JSVirtualMachine.mm:

(-[JSVirtualMachine addExternalRememberedObject:]):
(-[JSVirtualMachine addManagedReference:withOwner:]):
(-[JSVirtualMachine removeManagedReference:withOwner:]):
(-[JSVirtualMachine externalDataMutex]):
(scanExternalObjectGraph):
(scanExternalRememberedSet):

  • API/JSVirtualMachineInternal.h:
  • Deleted externalObjectGraph method. There's no need to expose this.
Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

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

    r208720 r210458  
    11/*
    2  * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    8282@implementation JSVirtualMachine {
    8383    JSContextGroupRef m_group;
     84    Lock m_externalDataMutex;
    8485    NSMapTable *m_contextCache;
    8586    NSMapTable *m_externalObjectGraph;
     
    157158- (void)addExternalRememberedObject:(id)object
    158159{
     160    auto locker = holdLock(m_externalDataMutex);
    159161    ASSERT([self isOldExternalObject:object]);
    160162    [m_externalRememberedSet setObject:@YES forKey:object];
     
    176178        [self addExternalRememberedObject:owner];
    177179 
     180    auto externalDataMutexLocker = holdLock(m_externalDataMutex);
    178181    NSMapTable *ownedObjects = [m_externalObjectGraph objectForKey:owner];
    179182    if (!ownedObjects) {
     
    203206    JSC::JSLockHolder locker(toJS(m_group));
    204207   
     208    auto externalDataMutexLocker = holdLock(m_externalDataMutex);
    205209    NSMapTable *ownedObjects = [m_externalObjectGraph objectForKey:owner];
    206210    if (!ownedObjects)
     
    249253}
    250254
     255- (Lock&)externalDataMutex
     256{
     257    return m_externalDataMutex;
     258}
     259
    251260- (NSMapTable *)externalObjectGraph
    252261{
     
    261270@end
    262271
    263 void scanExternalObjectGraph(JSC::VM& vm, JSC::SlotVisitor& visitor, void* root)
     272static void scanExternalObjectGraph(JSC::VM& vm, JSC::SlotVisitor& visitor, void* root, bool lockAcquired)
    264273{
    265274    @autoreleasepool {
     
    268277            return;
    269278        NSMapTable *externalObjectGraph = [virtualMachine externalObjectGraph];
     279        Lock& externalDataMutex = [virtualMachine externalDataMutex];
    270280        Vector<void*> stack;
    271281        stack.append(root);
     
    276286                continue;
    277287            visitor.addOpaqueRoot(nextRoot);
    278            
    279             NSMapTable *ownedObjects = [externalObjectGraph objectForKey:static_cast<id>(nextRoot)];
    280             for (id ownedObject in ownedObjects)
    281                 stack.append(static_cast<void*>(ownedObject));
     288
     289            auto appendOwnedObjects = [&] {
     290                NSMapTable *ownedObjects = [externalObjectGraph objectForKey:static_cast<id>(nextRoot)];
     291                for (id ownedObject in ownedObjects)
     292                    stack.append(static_cast<void*>(ownedObject));
     293            };
     294
     295            if (lockAcquired)
     296                appendOwnedObjects();
     297            else {
     298                auto locker = holdLock(externalDataMutex);
     299                appendOwnedObjects();
     300            }
    282301        }
    283302    }
     303}
     304
     305void scanExternalObjectGraph(JSC::VM& vm, JSC::SlotVisitor& visitor, void* root)
     306{
     307    bool lockAcquired = false;
     308    scanExternalObjectGraph(vm, visitor, root, lockAcquired);
    284309}
    285310
     
    290315        if (!virtualMachine)
    291316            return;
     317        Lock& externalDataMutex = [virtualMachine externalDataMutex];
     318        auto locker = holdLock(externalDataMutex);
    292319        NSMapTable *externalObjectGraph = [virtualMachine externalObjectGraph];
    293320        NSMapTable *externalRememberedSet = [virtualMachine externalRememberedSet];
    294321        for (id key in externalRememberedSet) {
    295322            NSMapTable *ownedObjects = [externalObjectGraph objectForKey:key];
     323            bool lockAcquired = true;
    296324            for (id ownedObject in ownedObjects)
    297                 scanExternalObjectGraph(vm, visitor, ownedObject);
     325                scanExternalObjectGraph(vm, visitor, ownedObject, lockAcquired);
    298326        }
    299327        [externalRememberedSet removeAllObjects];
  • trunk/Source/JavaScriptCore/API/JSVirtualMachineInternal.h

    r174110 r210458  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2017 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    4848- (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext;
    4949
    50 - (NSMapTable *)externalObjectGraph;
    51 
    5250@end
    5351#endif // defined(__OBJC__)
  • trunk/Source/JavaScriptCore/ChangeLog

    r210457 r210458  
     12017-01-06  Mark Lam  <mark.lam@apple.com>
     2
     3        The ObjC API's JSVirtualMachine's map tables need to be guarded by a lock.
     4        https://bugs.webkit.org/show_bug.cgi?id=166778
     5        <rdar://problem/29761198>
     6
     7        Reviewed by Filip Pizlo.
     8
     9        Now that we have a concurrent GC, access to JSVirtualMachine's
     10        m_externalObjectGraph and m_externalRememberedSet need to be guarded by a lock
     11        since both the GC marker thread and the mutator thread may access them at the
     12        same time.
     13
     14        * API/JSVirtualMachine.mm:
     15        (-[JSVirtualMachine addExternalRememberedObject:]):
     16        (-[JSVirtualMachine addManagedReference:withOwner:]):
     17        (-[JSVirtualMachine removeManagedReference:withOwner:]):
     18        (-[JSVirtualMachine externalDataMutex]):
     19        (scanExternalObjectGraph):
     20        (scanExternalRememberedSet):
     21
     22        * API/JSVirtualMachineInternal.h:
     23        - Deleted externalObjectGraph method.  There's no need to expose this.
     24
    1252017-01-06  Michael Saboff  <msaboff@apple.com>
    226
Note: See TracChangeset for help on using the changeset viewer.