void AbstractValue::set(Graph& graph, const FrozenValue& value, StructureClobberState clobberState) { if (!!value && value.value().isCell()) { Structure* structure = value.structure(); // FIXME: This check may not be necessary since any frozen value should have its structure // watched already. // https://bugs.webkit.org/show_bug.cgi?id=136055 if (graph.registerStructure(structure) == StructureRegisteredAndWatched) { m_structure = structure; if (clobberState == StructuresAreClobbered) { m_arrayModes = ALL_ARRAY_MODES; m_structure.clobber(); } else m_arrayModes = asArrayModes(structure->indexingType()); } else { m_structure.makeTop(); m_arrayModes = ALL_ARRAY_MODES; } } else { m_structure.clear(); m_arrayModes = 0; } m_type = speculationFromValue(value.value()); m_value = value.value(); checkConsistency(); assertIsRegistered(graph); }
void AbstractValue::set(Graph& graph, const FrozenValue& value, StructureClobberState clobberState) { if (!!value && value.value().isCell()) { Structure* structure = value.structure(); if (graph.registerStructure(structure) == StructureRegisteredAndWatched) { m_structure = structure; if (clobberState == StructuresAreClobbered) { m_arrayModes = ALL_ARRAY_MODES; m_structure.clobber(); } else m_arrayModes = asArrayModes(structure->indexingType()); } else { m_structure.makeTop(); m_arrayModes = ALL_ARRAY_MODES; } } else { m_structure.clear(); m_arrayModes = 0; } m_type = speculationFromValue(value.value()); m_value = value.value(); checkConsistency(); assertIsRegistered(graph); }
bool AbstractValue::mergeOSREntryValue(Graph& graph, JSValue value) { AbstractValue oldMe = *this; if (isClear()) { FrozenValue* frozenValue = graph.freeze(value); if (frozenValue->pointsToHeap()) { m_structure = frozenValue->structure(); m_arrayModes = asArrayModes(frozenValue->structure()->indexingType()); } else { m_structure.clear(); m_arrayModes = 0; } m_type = speculationFromValue(value); m_value = value; } else { mergeSpeculation(m_type, speculationFromValue(value)); if (!!value && value.isCell()) { Structure* structure = value.asCell()->structure(); graph.registerStructure(structure); mergeArrayModes(m_arrayModes, asArrayModes(structure->indexingType())); m_structure.merge(StructureSet(structure)); } if (m_value != value) m_value = JSValue(); } checkConsistency(); assertIsRegistered(graph); return oldMe != *this; }
void AbstractValue::set(Graph& graph, Structure* structure) { m_structure = structure; m_arrayModes = asArrayModes(structure->indexingType()); m_type = speculationFromStructure(structure); m_value = JSValue(); checkConsistency(); assertIsRegistered(graph); }
void AbstractValue::set(Graph& graph, const StructureSet& set) { m_structure = set; m_arrayModes = set.arrayModesFromStructures(); m_type = set.speculationFromStructures(); m_value = JSValue(); checkConsistency(); assertIsRegistered(graph); }
void AbstractValue::setOSREntryValue(Graph& graph, const FrozenValue& value) { if (!!value && value.value().isCell()) { Structure* structure = value.structure(); graph.registerStructure(structure); m_structure = structure; m_arrayModes = asArrayModes(structure->indexingType()); } else { m_structure.clear(); m_arrayModes = 0; } m_type = speculationFromValue(value.value()); m_value = value.value(); checkConsistency(); assertIsRegistered(graph); }
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; }
void assertAreRegistered(const StructureSet& set) { for (Structure* structure : set) assertIsRegistered(structure); }
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; }
FiltrationResult AbstractValue::normalizeClarity(Graph& graph) { FiltrationResult result = normalizeClarity(); assertIsRegistered(graph); return result; }