Changeset 199342 in webkit
- Timestamp:
- Apr 12, 2016 1:25:48 AM (8 years ago)
- Location:
- trunk/Source
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r199339 r199342 1 2016-04-12 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [JSC] addStaticGlobals should emit SymbolTableEntry watchpoints to encourage constant folding in DFG 4 https://bugs.webkit.org/show_bug.cgi?id=155110 5 6 Reviewed by Saam Barati. 7 8 `addStaticGlobals` does not emit SymbolTableEntry watchpoints for the added entries. 9 So, all the global variable lookups pointing to these static globals are not converted 10 into constants in DFGBytecodeGenerator: this fact leaves these lookups as GetGlobalVar. 11 Such thing avoids constant folding chance and emits CheckCell for @privateFunction inlining. 12 This operation is pure overhead. 13 14 Static globals are not configurable, and they are typically non-writable. 15 So they are constants in almost all the cases. 16 17 This patch initializes watchpoints for these static globals. 18 These watchpoints allow DFG to convert these nodes into constants in DFG BytecodeParser. 19 These watchpoints includes many builtin operations and `undefined`. 20 21 The microbenchmark, many-foreach-calls shows 5 - 7% improvement since it removes unnecessary CheckCell. 22 23 * bytecode/VariableWriteFireDetail.h: 24 * runtime/JSGlobalObject.cpp: 25 (JSC::JSGlobalObject::addGlobalVar): 26 (JSC::JSGlobalObject::addStaticGlobals): 27 * runtime/JSSymbolTableObject.h: 28 (JSC::symbolTablePutTouchWatchpointSet): 29 (JSC::symbolTablePutInvalidateWatchpointSet): 30 (JSC::symbolTablePut): 31 (JSC::symbolTablePutWithAttributesTouchWatchpointSet): Deleted. 32 * runtime/SymbolTable.h: 33 (JSC::SymbolTableEntry::SymbolTableEntry): 34 (JSC::SymbolTableEntry::operator=): 35 (JSC::SymbolTableEntry::swap): 36 1 37 2016-04-12 Alex Christensen <achristensen@webkit.org> 2 38 -
trunk/Source/JavaScriptCore/bytecode/VariableWriteFireDetail.h
r197563 r199342 42 42 } 43 43 44 void dump(PrintStream&) const override;44 JS_EXPORT_PRIVATE void dump(PrintStream&) const override; 45 45 46 46 JS_EXPORT_PRIVATE static void touch(WatchpointSet*, JSObject*, const PropertyName&); -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r199164 r199342 680 680 SymbolTableEntry newEntry(VarOffset(offset), 0); 681 681 newEntry.prepareToWatch(); 682 symbolTable()->add(locker, ident.impl(), newEntry);682 symbolTable()->add(locker, ident.impl(), WTFMove(newEntry)); 683 683 684 684 ScopeOffset offsetForAssert = addVariables(1, jsUndefined()); … … 980 980 ASSERT(global.attributes & DontDelete); 981 981 982 ScopeOffset offset; 982 WatchpointSet* watchpointSet = nullptr; 983 WriteBarrierBase<Unknown>* variable = nullptr; 983 984 { 984 985 ConcurrentJITLocker locker(symbolTable()->m_lock); 985 offset = symbolTable()->takeNextScopeOffset(locker);986 ScopeOffset offset = symbolTable()->takeNextScopeOffset(locker); 986 987 RELEASE_ASSERT(offset = startOffset + i); 987 988 SymbolTableEntry newEntry(VarOffset(offset), global.attributes); 988 symbolTable()->add(locker, global.identifier.impl(), newEntry); 989 newEntry.prepareToWatch(); 990 watchpointSet = newEntry.watchpointSet(); 991 symbolTable()->add(locker, global.identifier.impl(), WTFMove(newEntry)); 992 variable = &variableAt(offset); 989 993 } 990 variableAt(offset).set(vm(), this, global.value);994 symbolTablePutTouchWatchpointSet(vm(), this, global.identifier, global.value, variable, watchpointSet); 991 995 } 992 996 } -
trunk/Source/JavaScriptCore/runtime/JSSymbolTableObject.h
r198023 r199342 142 142 } 143 143 144 template<typename SymbolTableObjectType> 145 ALWAYS_INLINE void symbolTablePutTouchWatchpointSet(VM& vm, SymbolTableObjectType* object, PropertyName propertyName, JSValue value, WriteBarrierBase<Unknown>* reg, WatchpointSet* set) 146 { 147 reg->set(vm, object, value); 148 if (set) 149 VariableWriteFireDetail::touch(set, object, propertyName); 150 } 151 152 template<typename SymbolTableObjectType> 153 ALWAYS_INLINE void symbolTablePutInvalidateWatchpointSet(VM& vm, SymbolTableObjectType* object, PropertyName propertyName, JSValue value, WriteBarrierBase<Unknown>* reg, WatchpointSet* set) 154 { 155 reg->set(vm, object, value); 156 if (set) 157 set->invalidate(VariableWriteFireDetail(object, propertyName)); // Don't mess around - if we had found this statically, we would have invalidated it. 158 } 159 144 160 enum class SymbolTablePutMode { 145 WithAttributes,146 WithoutAttributes161 Touch, 162 Invalidate 147 163 }; 148 164 149 165 template<SymbolTablePutMode symbolTablePutMode, typename SymbolTableObjectType> 150 inline bool symbolTablePut( 151 SymbolTableObjectType* object, ExecState* exec, PropertyName propertyName, JSValue value, unsigned attributes, 152 bool shouldThrowReadOnlyError, bool ignoreReadOnlyErrors, WatchpointSet*& set, bool& putResult) 153 { 154 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object)); 155 166 inline bool symbolTablePut(SymbolTableObjectType* object, ExecState* exec, PropertyName propertyName, JSValue value, bool shouldThrowReadOnlyError, bool ignoreReadOnlyErrors, bool& putResult) 167 { 156 168 VM& vm = exec->vm(); 157 169 170 WatchpointSet* set = nullptr; 158 171 WriteBarrierBase<Unknown>* reg; 159 172 { … … 182 195 183 196 set = iter->value.watchpointSet(); 184 if (symbolTablePutMode == SymbolTablePutMode::WithAttributes)185 iter->value.setAttributes(attributes);186 197 reg = &object->variableAt(offset); 187 198 } … … 189 200 // the right for barriers to be able to trigger GC. And I don't want to hold VM 190 201 // locks while GC'ing. 191 reg->set(vm, object, value); 202 if (symbolTablePutMode == SymbolTablePutMode::Invalidate) 203 symbolTablePutInvalidateWatchpointSet(exec->vm(), object, propertyName, value, reg, set); 204 else 205 symbolTablePutTouchWatchpointSet(exec->vm(), object, propertyName, value, reg, set); 192 206 putResult = true; 193 207 return true; … … 199 213 bool shouldThrowReadOnlyError, bool ignoreReadOnlyErrors, bool& putResult) 200 214 { 201 WatchpointSet* set = nullptr; 202 unsigned attributes = 0; 203 bool result = symbolTablePut<SymbolTablePutMode::WithoutAttributes>(object, exec, propertyName, value, attributes, shouldThrowReadOnlyError, ignoreReadOnlyErrors, set, putResult); 204 if (set) 205 VariableWriteFireDetail::touch(set, object, propertyName); 206 return result; 215 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object)); 216 return symbolTablePut<SymbolTablePutMode::Touch>(object, exec, propertyName, value, shouldThrowReadOnlyError, ignoreReadOnlyErrors, putResult); 207 217 } 208 218 … … 212 222 bool shouldThrowReadOnlyError, bool ignoreReadOnlyErrors, bool& putResult) 213 223 { 214 WatchpointSet* set = nullptr; 215 unsigned attributes = 0; 216 bool result = symbolTablePut<SymbolTablePutMode::WithoutAttributes>(object, exec, propertyName, value, attributes, shouldThrowReadOnlyError, ignoreReadOnlyErrors, set, putResult); 217 if (set) 218 set->invalidate(VariableWriteFireDetail(object, propertyName)); // Don't mess around - if we had found this statically, we would have invalidated it. 219 return result; 220 } 221 222 template<typename SymbolTableObjectType> 223 inline bool symbolTablePutWithAttributesTouchWatchpointSet( 224 SymbolTableObjectType* object, ExecState* exec, PropertyName propertyName, 225 JSValue value, unsigned attributes, bool& putResult) 226 { 227 WatchpointSet* set = nullptr; 228 bool shouldThrowReadOnlyError = false; 229 bool ignoreReadOnlyErrors = true; 230 bool result = symbolTablePut<SymbolTablePutMode::WithAttributes>(object, exec, propertyName, value, attributes, shouldThrowReadOnlyError, ignoreReadOnlyErrors, set, putResult); 231 if (set) 232 VariableWriteFireDetail::touch(set, object, propertyName); 233 return result; 224 ASSERT(!Heap::heap(value) || Heap::heap(value) == Heap::heap(object)); 225 return symbolTablePut<SymbolTablePutMode::Invalidate>(object, exec, propertyName, value, shouldThrowReadOnlyError, ignoreReadOnlyErrors, putResult); 234 226 } 235 227 -
trunk/Source/JavaScriptCore/runtime/SymbolTable.h
r196808 r199342 200 200 } 201 201 202 SymbolTableEntry(SymbolTableEntry&& other) 203 : m_bits(SlimFlag) 204 { 205 swap(other); 206 } 207 208 SymbolTableEntry& operator=(SymbolTableEntry&& other) 209 { 210 swap(other); 211 return *this; 212 } 213 214 void swap(SymbolTableEntry& other) 215 { 216 std::swap(m_bits, other.m_bits); 217 } 218 202 219 bool isNull() const 203 220 { … … 553 570 } 554 571 555 void add(const ConcurrentJITLocker&, UniquedStringImpl* key, const SymbolTableEntry& entry) 572 template<typename Entry> 573 void add(const ConcurrentJITLocker&, UniquedStringImpl* key, Entry&& entry) 556 574 { 557 575 RELEASE_ASSERT(!m_localToEntry); 558 576 didUseVarOffset(entry.varOffset()); 559 Map::AddResult result = m_map.add(key, entry);577 Map::AddResult result = m_map.add(key, std::forward<Entry>(entry)); 560 578 ASSERT_UNUSED(result, result.isNewEntry); 561 579 } 562 580 563 void add(UniquedStringImpl* key, const SymbolTableEntry& entry) 581 template<typename Entry> 582 void add(UniquedStringImpl* key, Entry&& entry) 564 583 { 565 584 ConcurrentJITLocker locker(m_lock); 566 add(locker, key, entry); 567 } 568 569 void set(const ConcurrentJITLocker&, UniquedStringImpl* key, const SymbolTableEntry& entry) 585 add(locker, key, std::forward<Entry>(entry)); 586 } 587 588 template<typename Entry> 589 void set(const ConcurrentJITLocker&, UniquedStringImpl* key, Entry&& entry) 570 590 { 571 591 RELEASE_ASSERT(!m_localToEntry); 572 592 didUseVarOffset(entry.varOffset()); 573 m_map.set(key, entry); 574 } 575 576 void set(UniquedStringImpl* key, const SymbolTableEntry& entry) 593 m_map.set(key, std::forward<Entry>(entry)); 594 } 595 596 template<typename Entry> 597 void set(UniquedStringImpl* key, Entry&& entry) 577 598 { 578 599 ConcurrentJITLocker locker(m_lock); 579 set(locker, key, entry);600 set(locker, key, std::forward<Entry>(entry)); 580 601 } 581 602 -
trunk/Source/WebCore/ChangeLog
r199341 r199342 1 2016-04-12 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [JSC] addStaticGlobals should emit SymbolTableEntry watchpoints to encourage constant folding in DFG 4 https://bugs.webkit.org/show_bug.cgi?id=155110 5 6 Reviewed by Saam Barati. 7 8 * bindings/js/JSDOMWindowBase.cpp: 9 (WebCore::JSDOMWindowBase::updateDocument): 10 1 11 2016-04-12 Sergio Villar Senin <svillar@igalia.com> 2 12 -
trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp
r198932 r199342 102 102 void JSDOMWindowBase::updateDocument() 103 103 { 104 // Since "document" property is defined as { configurable: false, writable: false, enumerable: true }, 105 // users cannot change its attributes further. 106 // Reaching here, the attributes of "document" property should be never changed. 104 107 ASSERT(m_wrapped->document()); 105 108 ExecState* exec = globalExec(); 109 bool shouldThrowReadOnlyError = false; 110 bool ignoreReadOnlyErrors = true; 106 111 bool putResult = false; 107 symbolTablePut WithAttributesTouchWatchpointSet(this, exec, exec->vm().propertyNames->document, toJS(exec, this, m_wrapped->document()), DontDelete | ReadOnly, putResult);112 symbolTablePutTouchWatchpointSet(this, exec, exec->vm().propertyNames->document, toJS(exec, this, m_wrapped->document()), shouldThrowReadOnlyError, ignoreReadOnlyErrors, putResult); 108 113 } 109 114
Note: See TracChangeset
for help on using the changeset viewer.