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; }