bool run()
    {
        // FIXME: This phase shouldn't exist. We should have registered all structures by now, since
        // we may already have done optimizations that rely on structures having been registered.
        // Currently, we still have places where we don't register structures prior to this phase,
        // but structures don't end up being used for optimization prior to this phase. That's a
        // pretty fragile situation and we should fix it eventually.
        // https://bugs.webkit.org/show_bug.cgi?id=147889
        
        // We need to set this before this phase finishes. This phase doesn't do anything
        // conditioned on this field, except for assertIsRegistered() below. We intend for that
        // method to behave as if the phase was already finished. So, we set this up here.
        m_graph.m_structureRegistrationState = AllStructuresAreRegistered;
        
        // These are pretty dumb, but needed to placate subsequent assertions. We don't actually
        // have to watch these because there is no way to transition away from it, but they are
        // watchable and so we will assert if they aren't watched.
        registerStructure(m_graph.m_vm.structureStructure.get());
        registerStructure(m_graph.m_vm.stringStructure.get());
        registerStructure(m_graph.m_vm.symbolStructure.get());
        
        for (FrozenValue* value : m_graph.m_frozenValues)
            assertIsRegistered(value->structure());
        
        for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
            BasicBlock* block = m_graph.block(blockIndex);
            if (!block)
                continue;
        
            for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
                Node* node = block->at(nodeIndex);
            
                switch (node->op()) {
                case CheckStructure:
                    assertAreRegistered(node->structureSet());
                    break;
                
                case NewObject:
                case ArrayifyToStructure:
                case NewStringObject:
                    registerStructure(node->structure());
                    break;
                
                case PutStructure:
                case AllocatePropertyStorage:
                case ReallocatePropertyStorage:
                    registerStructure(node->transition()->previous);
                    registerStructure(node->transition()->next);
                    break;

                case GetGetterSetterByOffset:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->getterSetterStructure());
                    break;

                case MultiGetByOffset:
                    for (const MultiGetByOffsetCase& getCase : node->multiGetByOffsetData().cases)
                        registerStructures(getCase.set());
                    break;
                    
                case MultiPutByOffset:
                    for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
                        PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
                        registerStructures(variant.oldStructure());
                        if (variant.kind() == PutByIdVariant::Transition)
                            registerStructure(variant.newStructure());
                    }
                    break;
                    
                case NewArray:
                case NewArrayBuffer:
                case NewArrayWithSize: {
                    JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic);
                    registerStructure(globalObject->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
                    registerStructure(globalObject->originalArrayStructureForIndexingType(ArrayWithSlowPutArrayStorage));
                    break;
                }
                    
                case NewTypedArray:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructureConcurrently(node->typedArrayType()));
                    break;
                    
                case ToString:
                case CallStringConstructor:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
                    break;
                    
                case CreateActivation:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->activationStructure());
                    break;
                    
                case CreateDirectArguments:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->directArgumentsStructure());
                    break;
                    
                case CreateScopedArguments:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
                    break;

                case CreateClonedArguments:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->clonedArgumentsStructure());
                    break;

                case NewRegexp:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
                    break;
                case NewFunction:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure());
                    break;
                case NewGeneratorFunction:
                    registerStructure(m_graph.globalObjectFor(node->origin.semantic)->generatorFunctionStructure());
                    break;

                default:
                    break;
                }
            }
        }
        
        return true;
    }
 bool run()
 {
     // We need to set this before this phase finishes. This phase doesn't do anything
     // conditioned on this field, except for assertIsRegistered() below. We intend for that
     // method to behave as if the phase was already finished. So, we set this up here.
     m_graph.m_structureRegistrationState = AllStructuresAreRegistered;
     
     // These are pretty dumb, but needed to placate subsequent assertions. We don't actually
     // have to watch these because there is no way to transition away from it, but they are
     // watchable and so we will assert if they aren't watched.
     registerStructure(m_graph.m_vm.structureStructure.get());
     registerStructure(m_graph.m_vm.stringStructure.get());
     registerStructure(m_graph.m_vm.getterSetterStructure.get());
     
     for (FrozenValue* value : m_graph.m_frozenValues)
         assertIsRegistered(value->structure());
     
     for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
         BasicBlock* block = m_graph.block(blockIndex);
         if (!block)
             continue;
     
         for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
             Node* node = block->at(nodeIndex);
         
             switch (node->op()) {
             case CheckStructure:
                 assertAreRegistered(node->structureSet());
                 break;
             
             case NewObject:
             case ArrayifyToStructure:
             case NewStringObject:
                 registerStructure(node->structure());
                 break;
             
             case PutStructure:
             case AllocatePropertyStorage:
             case ReallocatePropertyStorage:
                 registerStructure(node->transition()->previous);
                 registerStructure(node->transition()->next);
                 break;
                 
             case MultiGetByOffset:
                 for (const MultiGetByOffsetCase& getCase : node->multiGetByOffsetData().cases)
                     registerStructures(getCase.set());
                 break;
                 
             case MultiPutByOffset:
                 for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
                     PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
                     registerStructures(variant.oldStructure());
                     if (variant.kind() == PutByIdVariant::Transition)
                         registerStructure(variant.newStructure());
                 }
                 break;
                 
             case NewArray:
             case NewArrayBuffer:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
                 break;
                 
             case NewTypedArray:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(node->typedArrayType()));
                 break;
                 
             case ToString:
             case CallStringConstructor:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
                 break;
                 
             case CreateActivation:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->activationStructure());
                 break;
                 
             case CreateDirectArguments:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->directArgumentsStructure());
                 break;
                 
             case CreateScopedArguments:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
                 break;
                 
             case NewRegexp:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
                 break;
             case NewArrowFunction:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->arrowFunctionStructure());
                 break;
             case NewFunction:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure());
                 break;
                 
             default:
                 break;
             }
         }
     }
     
     return true;
 }
 bool run()
 {
     // These are pretty dumb, but needed to placate subsequent assertions. We don't actually
     // have to watch these because there is no way to transition away from it, but they are
     // watchable and so we will assert if they aren't watched.
     registerStructure(m_graph.m_vm.structureStructure.get());
     registerStructure(m_graph.m_vm.stringStructure.get());
     registerStructure(m_graph.m_vm.getterSetterStructure.get());
     
     for (FrozenValue* value : m_graph.m_frozenValues)
         registerStructure(value->structure());
     
     for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
         BasicBlock* block = m_graph.block(blockIndex);
         if (!block)
             continue;
     
         for (unsigned nodeIndex = 0; nodeIndex < block->size(); ++nodeIndex) {
             Node* node = block->at(nodeIndex);
         
             switch (node->op()) {
             case CheckStructure:
                 registerStructures(node->structureSet());
                 break;
             
             case NewObject:
             case ArrayifyToStructure:
             case NewStringObject:
                 registerStructure(node->structure());
                 break;
             
             case PutStructure:
             case AllocatePropertyStorage:
             case ReallocatePropertyStorage:
                 registerStructure(node->transition()->previous);
                 registerStructure(node->transition()->next);
                 break;
                 
             case MultiGetByOffset:
                 for (unsigned i = node->multiGetByOffsetData().variants.size(); i--;) {
                     GetByIdVariant& variant = node->multiGetByOffsetData().variants[i];
                     registerStructures(variant.structureSet());
                     // Don't need to watch anything in the structure chain because that would
                     // have been decomposed into CheckStructure's. Don't need to watch the
                     // callLinkStatus because we wouldn't use MultiGetByOffset if any of the
                     // variants did that.
                     ASSERT(!variant.callLinkStatus());
                 }
                 break;
                 
             case MultiPutByOffset:
                 for (unsigned i = node->multiPutByOffsetData().variants.size(); i--;) {
                     PutByIdVariant& variant = node->multiPutByOffsetData().variants[i];
                     registerStructures(variant.oldStructure());
                     if (variant.kind() == PutByIdVariant::Transition)
                         registerStructure(variant.newStructure());
                 }
                 break;
                 
             case NewArray:
             case NewArrayBuffer:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->arrayStructureForIndexingTypeDuringAllocation(node->indexingType()));
                 break;
                 
             case NewTypedArray:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->typedArrayStructure(node->typedArrayType()));
                 break;
                 
             case ToString:
             case CallStringConstructor:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->stringObjectStructure());
                 break;
                 
             case CreateActivation:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->activationStructure());
                 break;
                 
             case CreateDirectArguments:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->directArgumentsStructure());
                 break;
                 
             case CreateScopedArguments:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->scopedArgumentsStructure());
                 break;
                 
             case NewRegexp:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->regExpStructure());
                 break;
                 
             case NewFunction:
                 registerStructure(m_graph.globalObjectFor(node->origin.semantic)->functionStructure());
                 break;
                 
             default:
                 break;
             }
         }
     }
     
     m_graph.m_structureRegistrationState = AllStructuresAreRegistered;
     
     return true;
 }