Structure* ArrayMode::originalArrayStructure(Graph& graph, const CodeOrigin& codeOrigin) const { JSGlobalObject* globalObject = graph.globalObjectFor(codeOrigin); switch (arrayClass()) { case Array::OriginalArray: { switch (type()) { case Array::Int32: return globalObject->originalArrayStructureForIndexingType(ArrayWithInt32); case Array::Double: return globalObject->originalArrayStructureForIndexingType(ArrayWithDouble); case Array::Contiguous: return globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous); case Array::ArrayStorage: return globalObject->originalArrayStructureForIndexingType(ArrayWithArrayStorage); default: CRASH(); return 0; } } case Array::OriginalNonArray: { TypedArrayType type = typedArrayType(); if (type == NotTypedArray) return 0; return globalObject->typedArrayStructure(type); } default: return 0; } }
Structure* ArrayMode::originalArrayStructure(Graph& graph, const CodeOrigin& codeOrigin) const { if (!isJSArrayWithOriginalStructure()) return 0; JSGlobalObject* globalObject = graph.globalObjectFor(codeOrigin); switch (type()) { case Array::Int32: return globalObject->originalArrayStructureForIndexingType(ArrayWithInt32); case Array::Double: return globalObject->originalArrayStructureForIndexingType(ArrayWithDouble); case Array::Contiguous: return globalObject->originalArrayStructureForIndexingType(ArrayWithContiguous); case Array::ArrayStorage: return globalObject->originalArrayStructureForIndexingType(ArrayWithArrayStorage); default: CRASH(); return 0; } }
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; }