Example #1
0
bool InferredType::canWatch(const ConcurrentJSLocker& locker, const Descriptor& expected)
{
    if (expected.kind() == Top)
        return false;
    
    return descriptor(locker) == expected;
}
Example #2
0
bool InferredType::set(const ConcurrentJSLocker& locker, VM& vm, Descriptor newDescriptor)
{
    // We will trigger write barriers while holding our lock. Currently, write barriers don't GC, but that
    // could change. If it does, we don't want to deadlock. Note that we could have used
    // GCSafeConcurrentJSLocker in the caller, but the caller is on a fast path so maybe that wouldn't be
    // a good idea.
    DeferGCForAWhile deferGC(vm.heap);
    
    // Be defensive: if we're not really changing the type, then we don't have to do anything.
    if (descriptor(locker) == newDescriptor)
        return false;

    bool shouldFireWatchpointSet = false;
    
    // The new descriptor must be more general than the previous one.
    ASSERT(newDescriptor.subsumes(descriptor(locker)));

    // If the new descriptors have different structures, then it can only be because one is null.
    if (descriptor(locker).structure() != newDescriptor.structure())
        ASSERT(!descriptor(locker).structure() || !newDescriptor.structure());

    // We are changing the type, so make sure that if anyone was watching, they find out about it now. If
    // anyone is watching, we make sure to go to Top so that we don't do this sort of thing again.
    if (m_watchpointSet.state() != ClearWatchpoint) {
        // We cannot have been invalidated, since if we were, then we'd already be at Top.
        ASSERT(m_watchpointSet.state() != IsInvalidated);

        // We're about to do expensive things because some compiler thread decided to watch this type and
        // then the type changed. Assume that this property is crazy, and don't ever do any more things for
        // it.
        newDescriptor = Top;

        shouldFireWatchpointSet = true;
    }

    // Remove the old InferredStructure object if we no longer need it.
    if (!newDescriptor.structure())
        m_structure = nullptr;

    // Add a new InferredStructure object if we need one now.
    if (newDescriptor.structure()) {
        if (m_structure) {
            // We should agree on the structures if we get here.
            ASSERT(newDescriptor.structure() == m_structure->structure());
        } else {
            m_structure = adoptRef(new InferredStructure(vm, this, newDescriptor.structure()));
            newDescriptor.structure()->addTransitionWatchpoint(&m_structure->m_watchpoint);
        }
    }

    // Finally, set the descriptor kind.
    m_kind = newDescriptor.kind();

    // Assert that we did things.
    ASSERT(descriptor(locker) == newDescriptor);

    return shouldFireWatchpointSet;
}