Ignore:
Timestamp:
Jul 24, 2013, 8:59:04 PM (12 years ago)
Author:
[email protected]
Message:

fourthTier: SymbolTable should be thread-safe
https://bugs.webkit.org/show_bug.cgi?id=115301

Reviewed by Geoffrey Garen.

Makes SymbolTable thread-safe. Relies on SymbolTableEntry already being immutable,
other than the WatchpointSet; but the WatchpointSet already has a righteous
concurrency protocol. So, this patch just protects the SymbolTable's HashMap.

  • bytecode/CodeBlock.cpp:

(JSC::CodeBlock::nameForRegister):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::addVar):

  • runtime/Executable.cpp:

(JSC::ProgramExecutable::addGlobalVar):

  • runtime/JSActivation.cpp:

(JSC::JSActivation::getOwnNonIndexPropertyNames):
(JSC::JSActivation::symbolTablePutWithAttributes):

  • runtime/JSSymbolTableObject.cpp:

(JSC::JSSymbolTableObject::getOwnNonIndexPropertyNames):

  • runtime/JSSymbolTableObject.h:

(JSC::symbolTableGet):
(JSC::symbolTablePut):
(JSC::symbolTablePutWithAttributes):

  • runtime/SymbolTable.cpp:

(JSC::SymbolTable::SymbolTable):
(JSC::SymbolTable::~SymbolTable):

  • runtime/SymbolTable.h:

(JSC::SymbolTable::find):
(JSC::SymbolTable::get):
(JSC::SymbolTable::inlineGet):
(JSC::SymbolTable::begin):
(JSC::SymbolTable::end):
(JSC::SymbolTable::size):
(JSC::SymbolTable::add):
(JSC::SymbolTable::set):
(JSC::SymbolTable::contains):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h

    r148696 r153132  
    7474{
    7575    SymbolTable& symbolTable = *object->symbolTable();
    76     SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
    77     if (iter == symbolTable.end())
     76    SymbolTable::Locker locker(symbolTable.m_lock);
     77    SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
     78    if (iter == symbolTable.end(locker))
    7879        return false;
    7980    SymbolTableEntry::Fast entry = iter->value;
     
    8889{
    8990    SymbolTable& symbolTable = *object->symbolTable();
    90     SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
    91     if (iter == symbolTable.end())
     91    SymbolTable::Locker locker(symbolTable.m_lock);
     92    SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
     93    if (iter == symbolTable.end(locker))
    9294        return false;
    9395    SymbolTableEntry::Fast entry = iter->value;
     
    104106{
    105107    SymbolTable& symbolTable = *object->symbolTable();
    106     SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
    107     if (iter == symbolTable.end())
     108    SymbolTable::Locker locker(symbolTable.m_lock);
     109    SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
     110    if (iter == symbolTable.end(locker))
    108111        return false;
    109112    SymbolTableEntry::Fast entry = iter->value;
     
    122125    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
    123126   
    124     SymbolTable& symbolTable = *object->symbolTable();
    125     SymbolTable::iterator iter = symbolTable.find(propertyName.publicName());
    126     if (iter == symbolTable.end())
    127         return false;
    128     bool wasFat;
    129     SymbolTableEntry::Fast fastEntry = iter->value.getFast(wasFat);
    130     ASSERT(!fastEntry.isNull());
    131     if (fastEntry.isReadOnly()) {
    132         if (shouldThrow)
    133             throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
    134         return true;
     127    WriteBarrierBase<Unknown>* reg;
     128    {
     129        SymbolTable& symbolTable = *object->symbolTable();
     130        SymbolTable::Locker locker(symbolTable.m_lock);
     131        SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
     132        if (iter == symbolTable.end(locker))
     133            return false;
     134        bool wasFat;
     135        SymbolTableEntry::Fast fastEntry = iter->value.getFast(wasFat);
     136        ASSERT(!fastEntry.isNull());
     137        if (fastEntry.isReadOnly()) {
     138            if (shouldThrow)
     139                throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
     140            return true;
     141        }
     142        if (UNLIKELY(wasFat))
     143            iter->value.notifyWrite();
     144        reg = &object->registerAt(fastEntry.getIndex());
    135145    }
    136     if (UNLIKELY(wasFat))
    137         iter->value.notifyWrite();
    138     object->registerAt(fastEntry.getIndex()).set(vm, object, value);
     146    // I'd prefer we not hold lock while executing barriers, since I prefer to reserve
     147    // the right for barriers to be able to trigger GC. And I don't want to hold VM
     148    // locks while GC'ing.
     149    reg->set(vm, object, value);
    139150    return true;
    140151}
     
    146157{
    147158    ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object));
    148    
    149     SymbolTable::iterator iter = object->symbolTable()->find(propertyName.publicName());
    150     if (iter == object->symbolTable()->end())
    151         return false;
    152     SymbolTableEntry& entry = iter->value;
    153     ASSERT(!entry.isNull());
    154     entry.notifyWrite();
    155     entry.setAttributes(attributes);
    156     object->registerAt(entry.getIndex()).set(vm, object, value);
     159
     160    WriteBarrierBase<Unknown>* reg;
     161    {
     162        SymbolTable& symbolTable = *object->symbolTable();
     163        SymbolTable::Locker locker(symbolTable.m_lock);
     164        SymbolTable::Map::iterator iter = symbolTable.find(locker, propertyName.publicName());
     165        if (iter == symbolTable.end(locker))
     166            return false;
     167        SymbolTableEntry& entry = iter->value;
     168        ASSERT(!entry.isNull());
     169        entry.notifyWrite();
     170        entry.setAttributes(attributes);
     171        reg = &object->registerAt(entry.getIndex());
     172    }
     173    reg->set(vm, object, value);
    157174    return true;
    158175}
Note: See TracChangeset for help on using the changeset viewer.