bool InferredType::canWatch(const ConcurrentJSLocker& locker, const Descriptor& expected) { if (expected.kind() == Top) return false; return descriptor(locker) == expected; }
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; }