Changeset 244313 in webkit
- Timestamp:
- Apr 15, 2019 5:28:47 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r244295 r244313 1 2019-04-15 Robin Morisset <rmorisset@apple.com> 2 3 DFG should be able to constant fold Object.create() with a constant prototype operand 4 https://bugs.webkit.org/show_bug.cgi?id=196886 5 6 Reviewed by Yusuke Suzuki. 7 8 Note that this new benchmark does not currently see a speedup with inlining removed. 9 The reason is that we do not yet have inline caching for Object.create(), we only optimize it when the DFG can see statically the prototype being passed. 10 11 * microbenchmarks/object-create-constant-prototype.js: Added. 12 (test): 13 1 14 2019-04-15 Tadeu Zagallo <tzagallo@apple.com> 2 15 -
trunk/JSTests/stress/object-create-undefined.js
r232442 r244313 25 25 }, `TypeError: Object prototype may only be an Object or null.`); 26 26 } 27 for (var i = 0; i < 1e4; ++i) { 28 // Some folding does not happen in the non-inlined version, so this can test a different path through the compiler 29 // than the previous loop. 30 shouldThrow(() => { 31 Object.create(undefined); 32 }, `TypeError: Object prototype may only be an Object or null.`); 33 } -
trunk/Source/JavaScriptCore/ChangeLog
r244312 r244313 1 2019-04-15 Robin Morisset <rmorisset@apple.com> 2 3 DFG should be able to constant fold Object.create() with a constant prototype operand 4 https://bugs.webkit.org/show_bug.cgi?id=196886 5 6 Reviewed by Yusuke Suzuki. 7 8 9 It is a fairly simple and limited patch, as it only works when the DFG can prove the exact object used as prototype. 10 But when it applies it can be a significant win: 11 Baseline Optim 12 object-create-constant-prototype 3.6082+-0.0979 ^ 1.6947+-0.0756 ^ definitely 2.1292x faster 13 object-create-null 11.4492+-0.2510 ? 11.5030+-0.2402 ? 14 object-create-unknown-object-prototype 15.6067+-0.1851 ? 15.7500+-0.2322 ? 15 object-create-untyped-prototype 8.8873+-0.1240 ? 8.9806+-0.1202 ? might be 1.0105x slower 16 <geometric> 8.6967+-0.1208 ^ 7.2408+-0.1367 ^ definitely 1.2011x faster 17 18 The only subtlety is that we need to to access the StructureCache concurrently from the compiler thread (see https://bugs.webkit.org/show_bug.cgi?id=186199) 19 I solved this with a simple lock, taken when the compiler thread tries to read it, and when the main thread tries to modify it. 20 I expect it to be extremely low contention, but will watch the bots just in case. 21 The lock is taken neither when the main thread is only reading the cache (it has no-one to race with), nor when the GC purges it of dead entries (it does not free anything while a compiler thread is in the middle of a phase). 22 23 * dfg/DFGAbstractInterpreterInlines.h: 24 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 25 * dfg/DFGConstantFoldingPhase.cpp: 26 (JSC::DFG::ConstantFoldingPhase::foldConstants): 27 * runtime/StructureCache.cpp: 28 (JSC::StructureCache::createEmptyStructure): 29 (JSC::StructureCache::tryEmptyObjectStructureForPrototypeFromCompilerThread): 30 * runtime/StructureCache.h: 31 1 32 2019-04-15 Devin Rousso <drousso@apple.com> 2 33 -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r244193 r244313 1 1 /* 2 * Copyright (C) 2013-201 8Apple Inc. All rights reserved.2 * Copyright (C) 2013-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 44 44 #include "PutByIdStatus.h" 45 45 #include "StringObject.h" 46 #include "StructureCache.h" 46 47 #include "StructureRareDataInlines.h" 47 48 #include <wtf/BooleanLattice.h> … … 2587 2588 case ObjectCreate: { 2588 2589 if (JSValue base = forNode(node->child1()).m_value) { 2589 if (base.isNull()) { 2590 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic); 2590 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic); 2591 Structure* structure = nullptr; 2592 if (base.isNull()) 2593 structure = globalObject->nullPrototypeObjectStructure(); 2594 else if (base.isObject()) 2595 structure = globalObject->vm().structureCache.emptyObjectStructureConcurrently(globalObject, base.getObject(), JSFinalObject::defaultInlineCapacity()); 2596 2597 if (structure) { 2591 2598 m_state.setFoundConstants(true); 2592 2599 if (node->child1().useKind() == UntypedUse) 2593 2600 didFoldClobberWorld(); 2594 setForNode(node, globalObject->nullPrototypeObjectStructure()); 2595 break; 2596 } 2597 // FIXME: We should get a structure for a constant prototype. We need to allow concurrent 2598 // access to StructureCache from compiler threads. 2599 // https://bugs.webkit.org/show_bug.cgi?id=186199 2601 setForNode(node, structure); 2602 break; 2603 } 2600 2604 } 2601 2605 if (node->child1().useKind() == UntypedUse) -
trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
r244067 r244313 1 1 /* 2 * Copyright (C) 2012-201 8Apple Inc. All rights reserved.2 * Copyright (C) 2012-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 40 40 #include "JSCInlines.h" 41 41 #include "PutByIdStatus.h" 42 #include "StructureCache.h" 42 43 43 44 namespace JSC { namespace DFG { … … 751 752 case ObjectCreate: { 752 753 if (JSValue base = m_state.forNode(node->child1()).m_value) { 753 if (base.isNull()) { 754 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic); 755 node->convertToNewObject(m_graph.registerStructure(globalObject->nullPrototypeObjectStructure())); 754 JSGlobalObject* globalObject = m_graph.globalObjectFor(node->origin.semantic); 755 Structure* structure = nullptr; 756 if (base.isNull()) 757 structure = globalObject->nullPrototypeObjectStructure(); 758 else if (base.isObject()) 759 structure = globalObject->vm().structureCache.emptyObjectStructureConcurrently(globalObject, base.getObject(), JSFinalObject::defaultInlineCapacity()); 760 761 if (structure) { 762 node->convertToNewObject(m_graph.registerStructure(structure)); 756 763 changed = true; 757 764 break; 758 765 } 759 // FIXME: We should get a structure for a constant prototype. We need to allow concurrent760 // access to StructureCache from compiler threads.761 // https://bugs.webkit.org/show_bug.cgi?id=186199762 766 } 763 767 break; -
trunk/Source/JavaScriptCore/runtime/StructureCache.cpp
r232337 r244313 1 1 /* 2 * Copyright (C) 2013-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2013-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 #include "StructureCache.h" 28 28 29 #include "IndexingType.h"30 29 #include "JSGlobalObject.h" 31 30 #include "JSCInlines.h" 31 #include <wtf/Locker.h> 32 32 33 33 namespace JSC { … … 37 37 RELEASE_ASSERT(!!prototype); // We use nullptr inside the HashMap for prototype to mean poly proto, so user's of this API must provide non-null prototypes. 38 38 39 // We don't need to lock here because only the main thread can get here, and only the main thread can mutate the cache 39 40 PrototypeKey key { makePolyProtoStructure ? nullptr : prototype, executable, inlineCapacity, classInfo, globalObject }; 40 41 if (Structure* structure = m_structures.get(key)) { … … 59 60 vm, globalObject, prototype, typeInfo, classInfo, indexingType, inlineCapacity); 60 61 } 62 auto locker = holdLock(m_lock); 61 63 m_structures.set(key, structure); 64 return structure; 65 } 62 66 63 return structure; 67 Structure* StructureCache::emptyObjectStructureConcurrently(JSGlobalObject* globalObject, JSObject* prototype, unsigned inlineCapacity) 68 { 69 RELEASE_ASSERT(!!prototype); // We use nullptr inside the HashMap for prototype to mean poly proto, so user's of this API must provide non-null prototypes. 70 71 PrototypeKey key { prototype, nullptr, inlineCapacity, JSFinalObject::info(), globalObject }; 72 auto locker = holdLock(m_lock); 73 if (Structure* structure = m_structures.get(key)) { 74 ASSERT(prototype->mayBePrototype()); 75 return structure; 76 } 77 return nullptr; 64 78 } 65 79 -
trunk/Source/JavaScriptCore/runtime/StructureCache.h
r229161 r244313 1 1 /* 2 * Copyright (C) 2013-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2013-2019 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 30 30 #include "PrototypeKey.h" 31 31 #include "WeakGCMap.h" 32 #include <wtf/Lock.h> 32 33 #include <wtf/TriState.h> 33 34 … … 52 53 JS_EXPORT_PRIVATE Structure* emptyObjectStructureForPrototype(JSGlobalObject*, JSObject*, unsigned inlineCapacity, bool makePolyProtoStructure = false, FunctionExecutable* = nullptr); 53 54 JS_EXPORT_PRIVATE Structure* emptyStructureForPrototypeFromBaseStructure(JSGlobalObject*, JSObject*, Structure*); 55 JS_EXPORT_PRIVATE Structure* emptyObjectStructureConcurrently(JSGlobalObject*, JSObject* prototype, unsigned inlineCapacity); 54 56 55 57 private: … … 58 60 using StructureMap = WeakGCMap<PrototypeKey, Structure>; 59 61 StructureMap m_structures; 62 Lock m_lock; 60 63 }; 61 64
Note: See TracChangeset
for help on using the changeset viewer.