diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/dfg/DFGAbstractValue.cpp | |
parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGAbstractValue.cpp')
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGAbstractValue.cpp | 378 |
1 files changed, 58 insertions, 320 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp b/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp index b6fcf8993..bd1ba4844 100644 --- a/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp +++ b/Source/JavaScriptCore/dfg/DFGAbstractValue.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2015 Apple Inc. All rights reserved. + * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,235 +29,64 @@ #if ENABLE(DFG_JIT) #include "DFGGraph.h" -#include "JSCInlines.h" -#include "TrackedReferences.h" +#include "Operations.h" namespace JSC { namespace DFG { -void AbstractValue::observeTransitions(const TransitionVector& vector) +void AbstractValue::setMostSpecific(Graph& graph, JSValue value) { - if (m_type & SpecCell) { - m_structure.observeTransitions(vector); - ArrayModes newModes = 0; - for (unsigned i = vector.size(); i--;) { - if (m_arrayModes & asArrayModes(vector[i].previous->indexingType())) - newModes |= asArrayModes(vector[i].next->indexingType()); - } - m_arrayModes |= newModes; + if (!!value && value.isCell()) { + Structure* structure = value.asCell()->structure(); + m_currentKnownStructure = structure; + setFuturePossibleStructure(graph, structure); + m_arrayModes = asArrayModes(structure->indexingType()); + } else { + m_currentKnownStructure.clear(); + m_futurePossibleStructure.clear(); + m_arrayModes = 0; } + + m_type = speculationFromValue(value); + m_value = value; + checkConsistency(); } -void AbstractValue::set(Graph& graph, const FrozenValue& value, StructureClobberState clobberState) +void AbstractValue::set(Graph& graph, JSValue value) { - 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; - } + if (!!value && value.isCell()) { + m_currentKnownStructure.makeTop(); + Structure* structure = value.asCell()->structure(); + setFuturePossibleStructure(graph, structure); + m_arrayModes = asArrayModes(structure->indexingType()); + clobberArrayModes(); } else { - m_structure.clear(); + m_currentKnownStructure.clear(); + m_futurePossibleStructure.clear(); m_arrayModes = 0; } - - m_type = speculationFromValue(value.value()); - m_value = value.value(); - + + m_type = speculationFromValue(value); + if (m_type == SpecInt52AsDouble) + m_type = SpecInt52; + m_value = value; + checkConsistency(); - assertIsRegistered(graph); } void AbstractValue::set(Graph& graph, Structure* structure) { - m_structure = structure; + m_currentKnownStructure = structure; + setFuturePossibleStructure(graph, 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::setType(Graph& graph, SpeculatedType type) -{ - SpeculatedType cellType = type & SpecCell; - if (cellType) { - if (!(cellType & ~SpecString)) - m_structure = graph.m_vm.stringStructure.get(); - else if (isSymbolSpeculation(cellType)) - m_structure = graph.m_vm.symbolStructure.get(); - else - m_structure.makeTop(); - m_arrayModes = ALL_ARRAY_MODES; - } else { - m_structure.clear(); - m_arrayModes = 0; - } - m_type = type; - m_value = JSValue(); - checkConsistency(); -} - -void AbstractValue::set(Graph& graph, const InferredType::Descriptor& descriptor) -{ - switch (descriptor.kind()) { - case InferredType::Bottom: - clear(); - return; - case InferredType::Boolean: - setType(SpecBoolean); - return; - case InferredType::Other: - setType(SpecOther); - return; - case InferredType::Int32: - setType(SpecInt32); - return; - case InferredType::Number: - setType(SpecBytecodeNumber); - return; - case InferredType::String: - set(graph, graph.m_vm.stringStructure.get()); - return; - case InferredType::Symbol: - set(graph, graph.m_vm.symbolStructure.get()); - return; - case InferredType::ObjectWithStructure: - set(graph, descriptor.structure()); - return; - case InferredType::ObjectWithStructureOrOther: - set(graph, descriptor.structure()); - merge(SpecOther); - return; - case InferredType::Object: - setType(graph, SpecObject); - return; - case InferredType::ObjectOrOther: - setType(graph, SpecObject | SpecOther); - return; - case InferredType::Top: - makeHeapTop(); - return; - } - - RELEASE_ASSERT_NOT_REACHED(); -} - -void AbstractValue::set( - Graph& graph, const InferredType::Descriptor& descriptor, StructureClobberState clobberState) -{ - set(graph, descriptor); - if (clobberState == StructuresAreClobbered) - clobberStructures(); -} - -void AbstractValue::fixTypeForRepresentation(Graph& graph, NodeFlags representation, Node* node) -{ - if (representation == NodeResultDouble) { - if (m_value) { - ASSERT(m_value.isNumber()); - if (m_value.isInt32()) - m_value = jsDoubleNumber(m_value.asNumber()); - } - if (m_type & SpecMachineInt) { - m_type &= ~SpecMachineInt; - m_type |= SpecInt52AsDouble; - } - if (m_type & ~SpecFullDouble) - DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for double node has type outside SpecFullDouble.\n").data()); - } else if (representation == NodeResultInt52) { - if (m_type & SpecInt52AsDouble) { - m_type &= ~SpecInt52AsDouble; - m_type |= SpecInt52; - } - if (m_type & ~SpecMachineInt) - DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for int52 node has type outside SpecMachineInt.\n").data()); - } else { - if (m_type & SpecInt52) { - m_type &= ~SpecInt52; - m_type |= SpecInt52AsDouble; - } - if (m_type & ~SpecBytecodeTop) - DFG_CRASH(graph, node, toCString("Abstract value ", *this, " for value node has type outside SpecBytecodeTop.\n").data()); - } - - checkConsistency(); -} - -void AbstractValue::fixTypeForRepresentation(Graph& graph, Node* node) -{ - fixTypeForRepresentation(graph, node->result(), node); -} - -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; } -bool AbstractValue::isType(Graph& graph, const InferredType::Descriptor& inferredType) const +FiltrationResult AbstractValue::filter(Graph& graph, const StructureSet& other) { - AbstractValue typeValue; - typeValue.set(graph, inferredType); - - AbstractValue mergedValue = *this; - mergedValue.merge(typeValue); - - return mergedValue == typeValue; -} - -FiltrationResult AbstractValue::filter( - Graph& graph, const StructureSet& other, SpeculatedType admittedTypes) -{ - ASSERT(!(admittedTypes & SpecCell)); - if (isClear()) return FiltrationOK; @@ -265,31 +94,23 @@ FiltrationResult AbstractValue::filter( // having structures, array modes, or a specific value. // https://bugs.webkit.org/show_bug.cgi?id=109663 - m_type &= other.speculationFromStructures() | admittedTypes; + m_type &= other.speculationFromStructures(); m_arrayModes &= other.arrayModesFromStructures(); - m_structure.filter(other); + m_currentKnownStructure.filter(other); // It's possible that prior to the above two statements we had (Foo, TOP), where // Foo is a SpeculatedType that is disjoint with the passed StructureSet. In that // case, we will now have (None, [someStructure]). In general, we need to make // sure that new information gleaned from the SpeculatedType needs to be fed back // into the information gleaned from the StructureSet. - m_structure.filter(m_type); + m_currentKnownStructure.filter(m_type); + if (m_currentKnownStructure.hasSingleton()) + setFuturePossibleStructure(graph, m_currentKnownStructure.singleton()); + filterArrayModesByType(); filterValueByType(); - return normalizeClarity(graph); -} - -FiltrationResult AbstractValue::changeStructure(Graph& graph, const StructureSet& other) -{ - m_type &= other.speculationFromStructures(); - m_arrayModes = other.arrayModesFromStructures(); - m_structure = other; - - filterValueByType(); - - return normalizeClarity(graph); + return normalizeClarity(); } FiltrationResult AbstractValue::filterArrayModes(ArrayModes arrayModes) @@ -309,84 +130,34 @@ FiltrationResult AbstractValue::filter(SpeculatedType type) if ((m_type & type) == m_type) return FiltrationOK; - // Fast path for the case that we don't even have a cell. - if (!(m_type & SpecCell)) { - m_type &= type; - FiltrationResult result; - if (m_type == SpecNone) { - clear(); - result = Contradiction; - } else - result = FiltrationOK; - checkConsistency(); - return result; - } - m_type &= type; // It's possible that prior to this filter() call we had, say, (Final, TOP), and // the passed type is Array. At this point we'll have (None, TOP). The best way // to ensure that the structure filtering does the right thing is to filter on // the new type (None) rather than the one passed (Array). - m_structure.filter(type); + m_currentKnownStructure.filter(m_type); + m_futurePossibleStructure.filter(m_type); filterArrayModesByType(); filterValueByType(); return normalizeClarity(); } -FiltrationResult AbstractValue::filterByValue(const FrozenValue& value) +FiltrationResult AbstractValue::filterByValue(JSValue value) { - FiltrationResult result = filter(speculationFromValue(value.value())); + FiltrationResult result = filter(speculationFromValue(value)); if (m_type) - m_value = value.value(); + m_value = value; return result; } -bool AbstractValue::contains(Structure* structure) const +void AbstractValue::setFuturePossibleStructure(Graph& graph, Structure* structure) { - return couldBeType(speculationFromStructure(structure)) - && (m_arrayModes & arrayModeFromStructure(structure)) - && m_structure.contains(structure); -} - -FiltrationResult AbstractValue::filter(const AbstractValue& other) -{ - m_type &= other.m_type; - m_structure.filter(other.m_structure); - m_arrayModes &= other.m_arrayModes; - - m_structure.filter(m_type); - filterArrayModesByType(); - filterValueByType(); - - if (normalizeClarity() == Contradiction) - return Contradiction; - - if (m_value == other.m_value) - return FiltrationOK; - - // Neither of us are BOTTOM, so an empty value means TOP. - if (!m_value) { - // We previously didn't prove a value but now we have done so. - m_value = other.m_value; - return FiltrationOK; - } - - if (!other.m_value) { - // We had proved a value but the other guy hadn't, so keep our proof. - return FiltrationOK; - } - - // We both proved there to be a specific value but they are different. - clear(); - return Contradiction; -} - -FiltrationResult AbstractValue::filter(Graph& graph, const InferredType::Descriptor& descriptor) -{ - AbstractValue filterValue; - filterValue.set(graph, descriptor); - return filter(filterValue); + ASSERT(structure); + if (graph.watchpoints().isStillValid(structure->transitionWatchpointSet())) + m_futurePossibleStructure = structure; + else + m_futurePossibleStructure.makeTop(); } void AbstractValue::filterValueByType() @@ -434,7 +205,8 @@ bool AbstractValue::shouldBeClear() const return true; if (!(m_type & ~SpecCell) - && (!m_arrayModes || m_structure.isClear())) + && (!m_arrayModes + || m_currentKnownStructure.isClear())) return true; return false; @@ -458,18 +230,12 @@ FiltrationResult AbstractValue::normalizeClarity() return result; } -FiltrationResult AbstractValue::normalizeClarity(Graph& graph) -{ - FiltrationResult result = normalizeClarity(); - assertIsRegistered(graph); - return result; -} - #if !ASSERT_DISABLED void AbstractValue::checkConsistency() const { if (!(m_type & SpecCell)) { - ASSERT(m_structure.isClear()); + ASSERT(m_currentKnownStructure.isClear()); + ASSERT(m_futurePossibleStructure.isClear()); ASSERT(!m_arrayModes); } @@ -478,8 +244,6 @@ void AbstractValue::checkConsistency() const if (!!m_value) { SpeculatedType type = m_type; - // This relaxes the assertion below a bit, since we don't know the representation of the - // node. if (type & SpecInt52) type |= SpecInt52AsDouble; ASSERT(mergeSpeculations(type, speculationFromValue(m_value)) == type); @@ -490,29 +254,8 @@ void AbstractValue::checkConsistency() const // we don't want to get pedantic about this as it would only increase the computational // complexity of the code. } - -void AbstractValue::assertIsRegistered(Graph& graph) const -{ - m_structure.assertIsRegistered(graph); -} #endif -ResultType AbstractValue::resultType() const -{ - ASSERT(isType(SpecBytecodeTop)); - if (isType(SpecBoolean)) - return ResultType::booleanType(); - if (isType(SpecInt32)) - return ResultType::numberTypeIsInt32(); - if (isType(SpecBytecodeNumber)) - return ResultType::numberType(); - if (isType(SpecString)) - return ResultType::stringType(); - if (isType(SpecString | SpecBytecodeNumber)) - return ResultType::stringOrNumberType(); - return ResultType::unknownType(); -} - void AbstractValue::dump(PrintStream& out) const { dumpInContext(out, 0); @@ -524,19 +267,14 @@ void AbstractValue::dumpInContext(PrintStream& out, DumpContext* context) const if (m_type & SpecCell) { out.print( ", ", ArrayModesDump(m_arrayModes), ", ", - inContext(m_structure, context)); + inContext(m_currentKnownStructure, context), ", ", + inContext(m_futurePossibleStructure, context)); } if (!!m_value) out.print(", ", inContext(m_value, context)); out.print(")"); } -void AbstractValue::validateReferences(const TrackedReferences& trackedReferences) -{ - trackedReferences.check(m_value); - m_structure.validateReferences(trackedReferences); -} - } } // namespace JSC::DFG #endif // ENABLE(DFG_JIT) |