Changeset 201584 in webkit
- Timestamp:
- Jun 1, 2016, 8:18:16 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 6 edited
-
ChangeLog (modified) (1 diff)
-
bytecode/ObjectPropertyCondition.cpp (modified) (1 diff)
-
bytecode/ObjectPropertyConditionSet.cpp (modified) (5 diffs)
-
bytecode/ObjectPropertyConditionSet.h (modified) (1 diff)
-
dfg/DFGGraph.cpp (modified) (5 diffs)
-
dfg/DFGGraph.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r201573 r201584 1 2016-06-01 Keith Miller <keith_miller@apple.com> 2 3 canOptimizeStringObjectAccess should use ObjectPropertyConditions rather than structure watchpoints 4 https://bugs.webkit.org/show_bug.cgi?id=158291 5 6 Reviewed by Benjamin Poulain. 7 8 The old StringObject primitive access code used structure watchpoints. This meant that 9 if you set a watchpoint on String.prototype prior to tiering up to the DFG then added 10 a new property to String.prototype then we would never use StringObject optimizations. 11 This made property caching in the LLInt bad because it meant we would watchpoint 12 String.prototype very early in the program, which hurt date-format-xpab.js since that 13 benchmark relies on the StringObject optimizations. 14 15 This patch also extends ObjectPropertyConditionSet to be able to handle a slotBase 16 equivalence condition. Since that makes the code for generating the DFG watchpoints 17 significantly cleaner. 18 19 * bytecode/ObjectPropertyCondition.cpp: 20 (JSC::ObjectPropertyCondition::structureEnsuresValidityAssumingImpurePropertyWatchpoint): 21 * bytecode/ObjectPropertyConditionSet.cpp: 22 (JSC::ObjectPropertyConditionSet::hasOneSlotBaseCondition): 23 (JSC::ObjectPropertyConditionSet::slotBaseCondition): 24 (JSC::generateConditionsForPrototypeEquivalenceConcurrently): 25 * bytecode/ObjectPropertyConditionSet.h: 26 * dfg/DFGGraph.cpp: 27 (JSC::DFG::Graph::isStringPrototypeMethodSane): 28 (JSC::DFG::Graph::canOptimizeStringObjectAccess): 29 * dfg/DFGGraph.h: 30 1 31 2016-06-01 Geoffrey Garen <ggaren@apple.com> 2 32 -
trunk/Source/JavaScriptCore/bytecode/ObjectPropertyCondition.cpp
r187780 r201584 50 50 Structure* structure) const 51 51 { 52 return m_condition.isStillValidAssumingImpurePropertyWatchpoint(structure );52 return m_condition.isStillValidAssumingImpurePropertyWatchpoint(structure, m_object); 53 53 } 54 54 -
trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.cpp
r201573 r201584 63 63 bool ObjectPropertyConditionSet::hasOneSlotBaseCondition() const 64 64 { 65 return numberOfConditionsWithKind(PropertyCondition::Presence) == 1;65 return (numberOfConditionsWithKind(PropertyCondition::Presence) == 1) != (numberOfConditionsWithKind(PropertyCondition::Equivalence) == 1); 66 66 } 67 67 … … 71 71 unsigned numFound = 0; 72 72 for (const ObjectPropertyCondition& condition : *this) { 73 if (condition.kind() == PropertyCondition::Presence) { 73 if (condition.kind() == PropertyCondition::Presence 74 || condition.kind() == PropertyCondition::Equivalence) { 74 75 result = condition; 75 76 numFound++; … … 199 200 break; 200 201 } 202 case PropertyCondition::Equivalence: { 203 unsigned attributes; 204 PropertyOffset offset = structure->getConcurrently(uid, attributes); 205 if (offset == invalidOffset) 206 return ObjectPropertyCondition(); 207 JSValue value = object->getDirect(offset); 208 result = ObjectPropertyCondition::equivalence(vm, owner, object, uid, value); 209 break; 210 } 201 211 default: 202 212 RELEASE_ASSERT_NOT_REACHED(); … … 241 251 if (!prototype) { 242 252 if (verbose) 243 dataLog("Reached end upprototype chain as expected, done.\n");253 dataLog("Reached end of prototype chain as expected, done.\n"); 244 254 break; 245 255 } … … 356 366 } 357 367 368 ObjectPropertyConditionSet generateConditionsForPrototypeEquivalenceConcurrently( 369 VM& vm, JSGlobalObject* globalObject, Structure* headStructure, JSObject* prototype, UniquedStringImpl* uid) 370 { 371 return generateConditions(vm, globalObject, headStructure, prototype, 372 [&] (Vector<ObjectPropertyCondition>& conditions, JSObject* object) -> bool { 373 PropertyCondition::Kind kind = 374 object == prototype ? PropertyCondition::Equivalence : PropertyCondition::Absence; 375 ObjectPropertyCondition result = generateCondition(vm, nullptr, object, uid, kind); 376 if (!result) 377 return false; 378 conditions.append(result); 379 return true; 380 }, Concurrent); 381 } 382 358 383 ObjectPropertyConditionSet generateConditionsForPropertyMissConcurrently( 359 384 VM& vm, JSGlobalObject* globalObject, Structure* headStructure, UniquedStringImpl* uid) -
trunk/Source/JavaScriptCore/bytecode/ObjectPropertyConditionSet.h
r201532 r201584 167 167 UniquedStringImpl* uid); 168 168 169 169 ObjectPropertyConditionSet generateConditionsForPrototypeEquivalenceConcurrently( 170 VM&, JSGlobalObject*, Structure* headStructure, JSObject* prototype, 171 UniquedStringImpl* uid); 170 172 ObjectPropertyConditionSet generateConditionsForPropertyMissConcurrently( 171 173 VM&, JSGlobalObject*, Structure* headStructure, UniquedStringImpl* uid); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r201182 r201584 1539 1539 } 1540 1540 1541 bool Graph::isStringPrototypeMethodSane(JSObject* stringPrototype, Structure* stringPrototypeStructure, UniquedStringImpl* uid)1542 {1543 unsigned attributesUnused;1544 PropertyOffset offset = stringPrototypeStructure->getConcurrently(uid, attributesUnused);1545 if (!isValidOffset(offset))1546 return false;1547 1548 JSValue value = tryGetConstantProperty(stringPrototype, stringPrototypeStructure, offset);1549 if (!value)1550 return false;1551 1552 JSFunction* function = jsDynamicCast<JSFunction*>(value);1553 if (!function)1554 return false;1555 1556 if (function->executable()->intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic)1557 return false;1558 1559 return true;1560 }1561 1562 1541 bool Graph::getRegExpPrototypeProperty(JSObject* regExpPrototype, Structure* regExpPrototypeStructure, UniquedStringImpl* uid, JSValue& returnJSValue) 1563 1542 { … … 1588 1567 } 1589 1568 1569 bool Graph::isStringPrototypeMethodSane(JSGlobalObject* globalObject, UniquedStringImpl* uid) 1570 { 1571 ObjectPropertyConditionSet conditions = generateConditionsForPrototypeEquivalenceConcurrently(m_vm, globalObject, globalObject->stringObjectStructure(), globalObject->stringPrototype(), uid); 1572 1573 if (!conditions.isValid()) 1574 return false; 1575 1576 ObjectPropertyCondition equivalenceCondition = conditions.slotBaseCondition(); 1577 RELEASE_ASSERT(equivalenceCondition.hasRequiredValue()); 1578 JSFunction* function = jsDynamicCast<JSFunction*>(equivalenceCondition.condition().requiredValue()); 1579 if (!function) 1580 return false; 1581 1582 if (function->executable()->intrinsicFor(CodeForCall) != StringPrototypeValueOfIntrinsic) 1583 return false; 1584 1585 return watchConditions(conditions); 1586 } 1587 1588 1590 1589 bool Graph::canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin) 1591 1590 { … … 1593 1592 return false; 1594 1593 1594 JSGlobalObject* globalObject = globalObjectFor(codeOrigin); 1595 1595 Structure* stringObjectStructure = globalObjectFor(codeOrigin)->stringObjectStructure(); 1596 1596 registerStructure(stringObjectStructure); … … 1598 1598 ASSERT(stringObjectStructure->storedPrototype().asCell()->classInfo() == StringPrototype::info()); 1599 1599 1600 FrozenValue* stringPrototypeObjectValue = freeze(stringObjectStructure->storedPrototype()); 1601 StringPrototype* stringPrototypeObject = stringPrototypeObjectValue->dynamicCast<StringPrototype*>(); 1602 Structure* stringPrototypeStructure = stringPrototypeObjectValue->structure(); 1603 if (registerStructure(stringPrototypeStructure) != StructureRegisteredAndWatched) 1604 return false; 1605 1606 if (stringPrototypeStructure->isDictionary()) 1607 return false; 1608 1609 if (!watchConditions(generateConditionsForPropertyMissConcurrently(m_vm, globalObjectFor(codeOrigin), stringObjectStructure, m_vm.propertyNames->toPrimitiveSymbol.impl()))) 1600 if (!watchConditions(generateConditionsForPropertyMissConcurrently(m_vm, globalObject, stringObjectStructure, m_vm.propertyNames->toPrimitiveSymbol.impl()))) 1610 1601 return false; 1611 1602 … … 1615 1606 // between the two, just because that seems like it would get confusing. So we 1616 1607 // just require both methods to be sane. 1617 if (!isStringPrototypeMethodSane( stringPrototypeObject, stringPrototypeStructure, m_vm.propertyNames->valueOf.impl()))1608 if (!isStringPrototypeMethodSane(globalObject, m_vm.propertyNames->valueOf.impl())) 1618 1609 return false; 1619 if (!isStringPrototypeMethodSane(stringPrototypeObject, stringPrototypeStructure, m_vm.propertyNames->toString.impl())) 1620 return false; 1621 1622 return true; 1610 return isStringPrototypeMethodSane(globalObject, m_vm.propertyNames->toString.impl()); 1623 1611 } 1624 1612 -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r201182 r201584 911 911 private: 912 912 913 bool isStringPrototypeMethodSane(JS Object* stringPrototype, Structure* stringPrototypeStructure, UniquedStringImpl*);913 bool isStringPrototypeMethodSane(JSGlobalObject*, UniquedStringImpl*); 914 914 915 915 void handleSuccessor(Vector<BasicBlock*, 16>& worklist, BasicBlock*, BasicBlock* successor);
Note:
See TracChangeset
for help on using the changeset viewer.