Changeset 203895 in webkit
- Timestamp:
- Jul 29, 2016 12:15:01 AM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 33 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r203853 r203895 1 2016-07-28 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 JSC::Symbol should be hash-consed 4 https://bugs.webkit.org/show_bug.cgi?id=158908 5 6 Reviewed by Filip Pizlo. 7 8 Previously, SymbolImpls held by symbols represent identity of symbols. 9 When we check the equality between symbols, we need to load SymbolImpls of symbols and compare them. 10 11 This patch performs hash-consing onto the symbols. We cache symbols in per-VM's SymbolImpl-keyed WeakGCMap. 12 When creating a new symbol from SymbolImpl, we first query to this map and reuse the previously created symbol 13 if it is found. This ensures that one-on-one correspondence between SymbolImpl and symbol. So now, we can use 14 pointer-comparison to query the equality of symbols. 15 16 This change drops SymbolImpl loads when checking the equality. Furthermore, we can use DFG CheckCell to symbol 17 when we would like to ensure that the given value is the expected symbol. This cleans up GetByVal's symbol-keyd 18 caching. Then, we changed CheckIdent to CheckStringIdent since it only checks the string case now. The symbol 19 case is handled by CheckCell. 20 21 Additionally, this patch also cleans up Map / Set implementation since we can use the logic for JSCell to symbols. 22 23 The performance effects in the related benchmarks are the followings. 24 25 baseline patch 26 27 bigswitch-indirect-symbol-or-undefined 85.6214+-1.0063 ^ 63.0522+-0.8615 ^ definitely 1.3579x faster 28 bigswitch-indirect-symbol 84.9653+-0.6258 ^ 80.4900+-0.8008 ^ definitely 1.0556x faster 29 fold-put-by-val-with-symbol-to-multi-put-by-offset 30 9.4396+-0.3726 9.2941+-0.3311 might be 1.0157x faster 31 inlined-put-by-val-with-symbol-transition 32 49.5477+-0.2401 ? 49.7533+-0.3369 ? 33 get-by-val-with-symbol-self-or-proto 11.9740+-0.0798 ? 12.1706+-0.2723 ? might be 1.0164x slower 34 get-by-val-with-symbol-quadmorphic-check-structure-elimination-simple 35 4.1364+-0.0841 4.0872+-0.0925 might be 1.0120x faster 36 put-by-val-with-symbol 11.3709+-0.0223 11.3613+-0.0264 37 get-by-val-with-symbol-proto-or-self 11.8984+-0.0706 ? 11.9030+-0.0787 ? 38 polymorphic-put-by-val-with-symbol 31.4176+-0.0558 31.3825+-0.0447 39 implicit-bigswitch-indirect-symbol 61.3115+-0.6577 ^ 58.0098+-0.1212 ^ definitely 1.0569x faster 40 get-by-val-with-symbol-bimorphic-check-structure-elimination-simple 41 3.3139+-0.0565 ^ 2.9947+-0.0732 ^ definitely 1.1066x faster 42 get-by-val-with-symbol-chain-from-try-block 43 2.2316+-0.0179 2.2137+-0.0210 44 get-by-val-with-symbol-bimorphic-check-structure-elimination 45 10.6031+-0.2216 ^ 10.0939+-0.1977 ^ definitely 1.0504x faster 46 get-by-val-with-symbol-check-structure-elimination 47 8.5576+-0.1521 ^ 7.7107+-0.1308 ^ definitely 1.1098x faster 48 put-by-val-with-symbol-slightly-polymorphic 49 3.1957+-0.0538 ^ 2.9181+-0.0708 ^ definitely 1.0951x faster 50 put-by-val-with-symbol-replace-and-transition 51 11.8253+-0.0757 ^ 11.6590+-0.0351 ^ definitely 1.0143x faster 52 53 <geometric> 13.3911+-0.0527 ^ 12.7376+-0.0457 ^ definitely 1.0513x faster 54 55 * bytecode/ByValInfo.h: 56 * bytecode/CodeBlock.cpp: 57 (JSC::CodeBlock::stronglyVisitStrongReferences): 58 * dfg/DFGAbstractInterpreterInlines.h: 59 (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): 60 * dfg/DFGByteCodeParser.cpp: 61 (JSC::DFG::ByteCodeParser::parseBlock): 62 * dfg/DFGClobberize.h: 63 (JSC::DFG::clobberize): 64 * dfg/DFGConstantFoldingPhase.cpp: 65 (JSC::DFG::ConstantFoldingPhase::foldConstants): 66 * dfg/DFGDoesGC.cpp: 67 (JSC::DFG::doesGC): 68 * dfg/DFGFixupPhase.cpp: 69 (JSC::DFG::FixupPhase::fixupNode): 70 * dfg/DFGNode.h: 71 (JSC::DFG::Node::hasUidOperand): 72 * dfg/DFGNodeType.h: 73 * dfg/DFGPredictionPropagationPhase.cpp: 74 * dfg/DFGSafeToExecute.h: 75 (JSC::DFG::safeToExecute): 76 * dfg/DFGSpeculativeJIT.cpp: 77 (JSC::DFG::SpeculativeJIT::compileSymbolEquality): 78 (JSC::DFG::SpeculativeJIT::compilePeepHoleSymbolEquality): 79 (JSC::DFG::SpeculativeJIT::compileCheckStringIdent): 80 (JSC::DFG::SpeculativeJIT::extractStringImplFromBinarySymbols): Deleted. 81 (JSC::DFG::SpeculativeJIT::compileCheckIdent): Deleted. 82 (JSC::DFG::SpeculativeJIT::compileSymbolUntypedEquality): Deleted. 83 * dfg/DFGSpeculativeJIT.h: 84 * dfg/DFGSpeculativeJIT32_64.cpp: 85 (JSC::DFG::SpeculativeJIT::compileSymbolUntypedEquality): 86 (JSC::DFG::SpeculativeJIT::compile): 87 * dfg/DFGSpeculativeJIT64.cpp: 88 (JSC::DFG::SpeculativeJIT::compileSymbolUntypedEquality): 89 (JSC::DFG::SpeculativeJIT::compile): 90 * ftl/FTLAbstractHeapRepository.h: 91 * ftl/FTLCapabilities.cpp: 92 (JSC::FTL::canCompile): 93 * ftl/FTLLowerDFGToB3.cpp: 94 (JSC::FTL::DFG::LowerDFGToB3::compileNode): 95 (JSC::FTL::DFG::LowerDFGToB3::compileCheckStringIdent): 96 (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): 97 (JSC::FTL::DFG::LowerDFGToB3::compileCheckIdent): Deleted. 98 (JSC::FTL::DFG::LowerDFGToB3::lowSymbolUID): Deleted. 99 * jit/JIT.h: 100 * jit/JITOperations.cpp: 101 (JSC::tryGetByValOptimize): 102 * jit/JITPropertyAccess.cpp: 103 (JSC::JIT::emitGetByValWithCachedId): 104 (JSC::JIT::emitPutByValWithCachedId): 105 (JSC::JIT::emitByValIdentifierCheck): 106 (JSC::JIT::privateCompileGetByValWithCachedId): 107 (JSC::JIT::privateCompilePutByValWithCachedId): 108 (JSC::JIT::emitIdentifierCheck): Deleted. 109 * jit/JITPropertyAccess32_64.cpp: 110 (JSC::JIT::emitGetByValWithCachedId): 111 (JSC::JIT::emitPutByValWithCachedId): 112 * runtime/JSCJSValue.cpp: 113 (JSC::JSValue::dumpInContextAssumingStructure): 114 * runtime/JSCJSValueInlines.h: 115 (JSC::JSValue::equalSlowCaseInline): 116 (JSC::JSValue::strictEqualSlowCaseInline): Deleted. 117 * runtime/JSFunction.cpp: 118 (JSC::JSFunction::setFunctionName): 119 * runtime/MapData.h: 120 * runtime/MapDataInlines.h: 121 (JSC::JSIterator>::clear): Deleted. 122 (JSC::JSIterator>::find): Deleted. 123 (JSC::JSIterator>::add): Deleted. 124 (JSC::JSIterator>::remove): Deleted. 125 (JSC::JSIterator>::replaceAndPackBackingStore): Deleted. 126 * runtime/Symbol.cpp: 127 (JSC::Symbol::finishCreation): 128 (JSC::Symbol::create): 129 * runtime/Symbol.h: 130 * runtime/VM.cpp: 131 (JSC::VM::VM): 132 * runtime/VM.h: 133 * tests/stress/symbol-equality-over-gc.js: Added. 134 (shouldBe): 135 (test): 136 1 137 2016-07-28 Mark Lam <mark.lam@apple.com> 2 138 -
trunk/Source/JavaScriptCore/bytecode/ByValInfo.h
r199303 r203895 36 36 namespace JSC { 37 37 38 class Symbol; 39 38 40 #if ENABLE(JIT) 39 41 … … 233 235 RefPtr<JITStubRoutine> stubRoutine; 234 236 Identifier cachedId; 237 WriteBarrier<Symbol> cachedSymbol; 235 238 StructureStubInfo* stubInfo; 236 239 bool tookSlowPath : 1; -
trunk/Source/JavaScriptCore/bytecode/CodeBlock.cpp
r203697 r203895 3102 3102 for (unsigned i = 0; i < m_objectAllocationProfiles.size(); ++i) 3103 3103 m_objectAllocationProfiles[i].visitAggregate(visitor); 3104 3105 for (ByValInfo* byValInfo : m_byValInfos) 3106 visitor.append(&byValInfo->cachedSymbol); 3104 3107 3105 3108 #if ENABLE(DFG_JIT) -
trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
r203364 r203895 1399 1399 1400 1400 if (node->op() == CompareEq && leftConst.isSymbol() && rightConst.isSymbol()) { 1401 setConstant(node, jsBoolean(asSymbol(leftConst) ->privateName() == asSymbol(rightConst)->privateName()));1401 setConstant(node, jsBoolean(asSymbol(leftConst) == asSymbol(rightConst))); 1402 1402 break; 1403 1403 } … … 2627 2627 } 2628 2628 2629 case Check Ident: {2629 case CheckStringIdent: { 2630 2630 AbstractValue& value = forNode(node->child1()); 2631 2631 UniquedStringImpl* uid = node->uidOperand(); 2632 ASSERT( uid->isSymbol() ? !(value.m_type & ~SpecSymbol) :!(value.m_type & ~SpecStringIdent)); // Edge filtering should have already ensured this.2632 ASSERT(!(value.m_type & ~SpecStringIdent)); // Edge filtering should have already ensured this. 2633 2633 2634 2634 JSValue childConstant = value.value(); 2635 2635 if (childConstant) { 2636 if (uid->isSymbol()) { 2637 ASSERT(childConstant.isSymbol()); 2638 if (asSymbol(childConstant)->privateName().uid() == uid) { 2639 m_state.setFoundConstants(true); 2640 break; 2641 } 2642 } else { 2643 ASSERT(childConstant.isString()); 2644 if (asString(childConstant)->tryGetValueImpl() == uid) { 2645 m_state.setFoundConstants(true); 2646 break; 2647 } 2648 } 2649 } 2650 2651 filter(value, uid->isSymbol() ? SpecSymbol : SpecStringIdent); 2636 ASSERT(childConstant.isString()); 2637 if (asString(childConstant)->tryGetValueImpl() == uid) { 2638 m_state.setFoundConstants(true); 2639 break; 2640 } 2641 } 2642 2643 filter(value, SpecStringIdent); 2652 2644 break; 2653 2645 } -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r203808 r203895 4064 4064 // FIXME: When the bytecode is not compiled in the baseline JIT, byValInfo becomes null. 4065 4065 // At that time, there is no information. 4066 if (byValInfo && byValInfo->stubInfo && !byValInfo->tookSlowPath && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent) ) {4066 if (byValInfo && byValInfo->stubInfo && !byValInfo->tookSlowPath && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent) && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell)) { 4067 4067 compiledAsGetById = true; 4068 4068 identifierNumber = m_graph.identifiers().ensure(byValInfo->cachedId.impl()); 4069 4069 UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber]; 4070 4070 4071 addToGraph(CheckIdent, OpInfo(uid), property); 4071 if (Symbol* symbol = byValInfo->cachedSymbol.get()) { 4072 FrozenValue* frozen = m_graph.freezeStrong(symbol); 4073 addToGraph(CheckCell, OpInfo(frozen), property); 4074 } else { 4075 ASSERT(!uid->isSymbol()); 4076 addToGraph(CheckStringIdent, OpInfo(uid), property); 4077 } 4072 4078 4073 4079 getByIdStatus = GetByIdStatus::computeForStubInfo( … … 4111 4117 // FIXME: When the bytecode is not compiled in the baseline JIT, byValInfo becomes null. 4112 4118 // At that time, there is no information. 4113 if (byValInfo && byValInfo->stubInfo && !byValInfo->tookSlowPath && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent) ) {4119 if (byValInfo && byValInfo->stubInfo && !byValInfo->tookSlowPath && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadIdent) && !m_inlineStackTop->m_exitProfile.hasExitSite(m_currentIndex, BadCell)) { 4114 4120 compiledAsPutById = true; 4115 4121 unsigned identifierNumber = m_graph.identifiers().ensure(byValInfo->cachedId.impl()); 4116 4122 UniquedStringImpl* uid = m_graph.identifiers()[identifierNumber]; 4117 4123 4118 addToGraph(CheckIdent, OpInfo(uid), property); 4124 if (Symbol* symbol = byValInfo->cachedSymbol.get()) { 4125 FrozenValue* frozen = m_graph.freezeStrong(symbol); 4126 addToGraph(CheckCell, OpInfo(frozen), property); 4127 } else { 4128 ASSERT(!uid->isSymbol()); 4129 addToGraph(CheckStringIdent, OpInfo(uid), property); 4130 } 4119 4131 4120 4132 PutByIdStatus putByIdStatus = PutByIdStatus::computeForStubInfo( -
trunk/Source/JavaScriptCore/dfg/DFGClobberize.h
r203364 r203895 345 345 return; 346 346 347 case Check Ident:348 def(PureValue(Check Ident, AdjacencyList(AdjacencyList::Fixed, node->child1()), node->uidOperand()));347 case CheckStringIdent: 348 def(PureValue(CheckStringIdent, AdjacencyList(AdjacencyList::Fixed, node->child1()), node->uidOperand())); 349 349 return; 350 350 -
trunk/Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
r203808 r203895 253 253 } 254 254 255 case Check Ident: {255 case CheckStringIdent: { 256 256 UniquedStringImpl* uid = node->uidOperand(); 257 257 const UniquedStringImpl* constantUid = nullptr; … … 259 259 JSValue childConstant = m_state.forNode(node->child1()).value(); 260 260 if (childConstant) { 261 if (uid->isSymbol()) { 262 if (childConstant.isSymbol()) 263 constantUid = asSymbol(childConstant)->privateName().uid(); 264 } else { 265 if (childConstant.isString()) { 266 if (const auto* impl = asString(childConstant)->tryGetValueImpl()) { 267 // Edge filtering requires that a value here should be StringIdent. 268 // However, a constant value propagated in DFG is not filtered. 269 // So here, we check the propagated value is actually an atomic string. 270 // And if it's not, we just ignore. 271 if (impl->isAtomic()) 272 constantUid = static_cast<const UniquedStringImpl*>(impl); 273 } 261 if (childConstant.isString()) { 262 if (const auto* impl = asString(childConstant)->tryGetValueImpl()) { 263 // Edge filtering requires that a value here should be StringIdent. 264 // However, a constant value propagated in DFG is not filtered. 265 // So here, we check the propagated value is actually an atomic string. 266 // And if it's not, we just ignore. 267 if (impl->isAtomic()) 268 constantUid = static_cast<const UniquedStringImpl*>(impl); 274 269 } 275 270 } -
trunk/Source/JavaScriptCore/dfg/DFGDoesGC.cpp
r203364 r203895 130 130 case CheckCell: 131 131 case CheckNotEmpty: 132 case Check Ident:132 case CheckStringIdent: 133 133 case RegExpExec: 134 134 case RegExpTest: -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r203491 r203895 1215 1215 } 1216 1216 1217 case CheckIdent: { 1218 UniquedStringImpl* uid = node->uidOperand(); 1219 if (uid->isSymbol()) 1220 fixEdge<SymbolUse>(node->child1()); 1221 else 1222 fixEdge<StringIdentUse>(node->child1()); 1217 case CheckStringIdent: { 1218 fixEdge<StringIdentUse>(node->child1()); 1223 1219 break; 1224 1220 } -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r203808 r203895 1520 1520 bool hasUidOperand() 1521 1521 { 1522 return op() == Check Ident;1522 return op() == CheckStringIdent; 1523 1523 } 1524 1524 -
trunk/Source/JavaScriptCore/dfg/DFGNodeType.h
r203364 r203895 240 240 macro(CheckBadCell, NodeMustGenerate) \ 241 241 macro(CheckInBounds, NodeMustGenerate) \ 242 macro(Check Ident, NodeMustGenerate) \242 macro(CheckStringIdent, NodeMustGenerate) \ 243 243 macro(CheckTypeInfoFlags, NodeMustGenerate) /* Takes an OpInfo with the flags you want to test are set */\ 244 244 \ -
trunk/Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp
r203364 r203895 1046 1046 case CheckCell: 1047 1047 case CheckNotEmpty: 1048 case Check Ident:1048 case CheckStringIdent: 1049 1049 case CheckBadCell: 1050 1050 case PutStructure: -
trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h
r203364 r203895 226 226 case CheckBadCell: 227 227 case CheckNotEmpty: 228 case Check Ident:228 case CheckStringIdent: 229 229 case RegExpExec: 230 230 case RegExpTest: -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r203697 r203895 5311 5311 } 5312 5312 5313 template<typename Functor> 5314 void SpeculativeJIT::extractStringImplFromBinarySymbols(Edge leftSymbolEdge, Edge rightSymbolEdge, const Functor& functor) 5315 { 5316 SpeculateCellOperand left(this, leftSymbolEdge); 5317 SpeculateCellOperand right(this, rightSymbolEdge); 5318 GPRTemporary leftTemp(this); 5319 GPRTemporary rightTemp(this); 5313 void SpeculativeJIT::compileSymbolEquality(Node* node) 5314 { 5315 SpeculateCellOperand left(this, node->child1()); 5316 SpeculateCellOperand right(this, node->child2()); 5317 GPRTemporary result(this, Reuse, left, right); 5320 5318 5321 5319 GPRReg leftGPR = left.gpr(); 5322 5320 GPRReg rightGPR = right.gpr(); 5323 GPRReg leftTempGPR = leftTemp.gpr(); 5324 GPRReg rightTempGPR = rightTemp.gpr(); 5325 5326 speculateSymbol(leftSymbolEdge, leftGPR); 5327 speculateSymbol(rightSymbolEdge, rightGPR); 5328 5329 m_jit.loadPtr(JITCompiler::Address(leftGPR, Symbol::offsetOfPrivateName()), leftTempGPR); 5330 m_jit.loadPtr(JITCompiler::Address(rightGPR, Symbol::offsetOfPrivateName()), rightTempGPR); 5331 5332 functor(leftTempGPR, rightTempGPR); 5333 } 5334 5335 void SpeculativeJIT::compileSymbolEquality(Node* node) 5336 { 5337 extractStringImplFromBinarySymbols(node->child1(), node->child2(), [&] (GPRReg leftStringImpl, GPRReg rightStringImpl) { 5338 m_jit.comparePtr(JITCompiler::Equal, leftStringImpl, rightStringImpl, leftStringImpl); 5339 unblessedBooleanResult(leftStringImpl, node); 5340 }); 5321 GPRReg resultGPR = result.gpr(); 5322 5323 speculateSymbol(node->child1(), leftGPR); 5324 speculateSymbol(node->child2(), rightGPR); 5325 5326 m_jit.comparePtr(JITCompiler::Equal, leftGPR, rightGPR, resultGPR); 5327 unblessedBooleanResult(resultGPR, node); 5341 5328 } 5342 5329 5343 5330 void SpeculativeJIT::compilePeepHoleSymbolEquality(Node* node, Node* branchNode) 5344 5331 { 5332 SpeculateCellOperand left(this, node->child1()); 5333 SpeculateCellOperand right(this, node->child2()); 5334 5335 GPRReg leftGPR = left.gpr(); 5336 GPRReg rightGPR = right.gpr(); 5337 5338 speculateSymbol(node->child1(), leftGPR); 5339 speculateSymbol(node->child2(), rightGPR); 5340 5345 5341 BasicBlock* taken = branchNode->branchData()->taken.block; 5346 5342 BasicBlock* notTaken = branchNode->branchData()->notTaken.block; 5347 5343 5348 extractStringImplFromBinarySymbols(node->child1(), node->child2(), [&] (GPRReg leftStringImpl, GPRReg rightStringImpl) { 5349 if (taken == nextBlock()) { 5350 branchPtr(JITCompiler::NotEqual, leftStringImpl, rightStringImpl, notTaken); 5351 jump(taken); 5352 } else { 5353 branchPtr(JITCompiler::Equal, leftStringImpl, rightStringImpl, taken); 5354 jump(notTaken); 5355 } 5356 }); 5344 if (taken == nextBlock()) { 5345 branchPtr(JITCompiler::NotEqual, leftGPR, rightGPR, notTaken); 5346 jump(taken); 5347 } else { 5348 branchPtr(JITCompiler::Equal, leftGPR, rightGPR, taken); 5349 jump(notTaken); 5350 } 5357 5351 } 5358 5352 … … 5998 5992 } 5999 5993 6000 void SpeculativeJIT::compileCheckIdent(Node* node) 6001 { 6002 SpeculateCellOperand operand(this, node->child1()); 5994 void SpeculativeJIT::compileCheckStringIdent(Node* node) 5995 { 5996 SpeculateCellOperand string(this, node->child1()); 5997 GPRTemporary storage(this); 5998 5999 GPRReg stringGPR = string.gpr(); 6000 GPRReg storageGPR = storage.gpr(); 6001 6002 speculateString(node->child1(), stringGPR); 6003 speculateStringIdentAndLoadStorage(node->child1(), stringGPR, storageGPR); 6004 6003 6005 UniquedStringImpl* uid = node->uidOperand(); 6004 if (uid->isSymbol()) { 6005 speculateSymbol(node->child1(), operand.gpr()); 6006 speculationCheck( 6007 BadIdent, JSValueSource(), nullptr, 6008 m_jit.branchPtr( 6009 JITCompiler::NotEqual, 6010 JITCompiler::Address(operand.gpr(), Symbol::offsetOfPrivateName()), 6011 TrustedImmPtr(uid))); 6012 } else { 6013 speculateString(node->child1(), operand.gpr()); 6014 speculateStringIdent(node->child1(), operand.gpr()); 6015 speculationCheck( 6016 BadIdent, JSValueSource(), nullptr, 6017 m_jit.branchPtr( 6018 JITCompiler::NotEqual, 6019 JITCompiler::Address(operand.gpr(), JSString::offsetOfValue()), 6020 TrustedImmPtr(uid))); 6021 } 6006 speculationCheck( 6007 BadIdent, JSValueSource(), nullptr, 6008 m_jit.branchPtr(JITCompiler::NotEqual, storageGPR, TrustedImmPtr(uid))); 6022 6009 noResult(node); 6023 6010 } … … 8321 8308 } 8322 8309 8323 void SpeculativeJIT::compileSymbolUntypedEquality(Node* node, Edge symbolEdge, Edge untypedEdge)8324 {8325 SpeculateCellOperand symbol(this, symbolEdge);8326 JSValueOperand untyped(this, untypedEdge);8327 GPRTemporary leftTemp(this);8328 GPRTemporary rightTemp(this);8329 8330 GPRReg symbolGPR = symbol.gpr();8331 JSValueRegs untypedRegs = untyped.jsValueRegs();8332 GPRReg leftTempGPR = leftTemp.gpr();8333 GPRReg rightTempGPR = rightTemp.gpr();8334 8335 speculateSymbol(symbolEdge, symbolGPR);8336 8337 JITCompiler::Jump notCell = m_jit.branchIfNotCell(untypedRegs);8338 JITCompiler::Jump isSymbol = m_jit.branchIfSymbol(untypedRegs.payloadGPR());8339 8340 notCell.link(&m_jit);8341 m_jit.move(TrustedImm32(0), leftTempGPR);8342 JITCompiler::Jump done = m_jit.jump();8343 8344 isSymbol.link(&m_jit);8345 m_jit.loadPtr(JITCompiler::Address(symbolGPR, Symbol::offsetOfPrivateName()), leftTempGPR);8346 m_jit.loadPtr(JITCompiler::Address(untypedRegs.payloadGPR(), Symbol::offsetOfPrivateName()), rightTempGPR);8347 m_jit.comparePtr(JITCompiler::Equal, leftTempGPR, rightTempGPR, leftTempGPR);8348 8349 done.link(&m_jit);8350 unblessedBooleanResult(leftTempGPR, node);8351 }8352 8353 8310 } } // namespace JSC::DFG 8354 8311 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
r203699 r203895 2349 2349 void compileMiscStrictEq(Node*); 2350 2350 2351 template<typename Functor>2352 void extractStringImplFromBinarySymbols(Edge leftSymbolEdge, Edge rightSymbolEdge, const Functor&);2353 2351 void compileSymbolEquality(Node*); 2354 2352 void compilePeepHoleSymbolEquality(Node*, Node* branchNode); … … 2437 2435 2438 2436 void compileCheckTypeInfoFlags(Node*); 2439 void compileCheck Ident(Node*);2437 void compileCheckStringIdent(Node*); 2440 2438 2441 2439 void compileValueRep(Node*); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r203544 r203895 1524 1524 1525 1525 jump(notTaken); 1526 } 1527 1528 void SpeculativeJIT::compileSymbolUntypedEquality(Node* node, Edge symbolEdge, Edge untypedEdge) 1529 { 1530 SpeculateCellOperand symbol(this, symbolEdge); 1531 JSValueOperand untyped(this, untypedEdge); 1532 1533 GPRReg symbolGPR = symbol.gpr(); 1534 GPRReg untypedGPR = untyped.payloadGPR(); 1535 1536 speculateSymbol(symbolEdge, symbolGPR); 1537 1538 GPRTemporary resultPayload(this, Reuse, symbol); 1539 GPRReg resultPayloadGPR = resultPayload.gpr(); 1540 1541 MacroAssembler::Jump untypedCellJump = m_jit.branchIfCell(untyped.jsValueRegs()); 1542 1543 m_jit.move(TrustedImm32(0), resultPayloadGPR); 1544 MacroAssembler::Jump untypedNotCellJump = m_jit.jump(); 1545 1546 // At this point we know that we can perform a straight-forward equality comparison on pointer 1547 // values because we are doing strict equality. 1548 untypedCellJump.link(&m_jit); 1549 m_jit.compare32(MacroAssembler::Equal, symbolGPR, untypedGPR, resultPayloadGPR); 1550 1551 untypedNotCellJump.link(&m_jit); 1552 booleanResult(resultPayloadGPR, node); 1526 1553 } 1527 1554 … … 4333 4360 } 4334 4361 4335 case Check Ident:4336 compileCheck Ident(node);4362 case CheckStringIdent: 4363 compileCheckStringIdent(node); 4337 4364 break; 4338 4365 -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r203364 r203895 1606 1606 1607 1607 jump(notTaken); 1608 } 1609 1610 void SpeculativeJIT::compileSymbolUntypedEquality(Node* node, Edge symbolEdge, Edge untypedEdge) 1611 { 1612 SpeculateCellOperand symbol(this, symbolEdge); 1613 JSValueOperand untyped(this, untypedEdge); 1614 GPRTemporary result(this, Reuse, symbol, untyped); 1615 1616 GPRReg symbolGPR = symbol.gpr(); 1617 GPRReg untypedGPR = untyped.gpr(); 1618 GPRReg resultGPR = result.gpr(); 1619 1620 speculateSymbol(symbolEdge, symbolGPR); 1621 1622 // At this point we know that we can perform a straight-forward equality comparison on pointer 1623 // values because we are doing strict equality. 1624 m_jit.compare64(MacroAssembler::Equal, symbolGPR, untypedGPR, resultGPR); 1625 unblessedBooleanResult(resultGPR, node); 1608 1626 } 1609 1627 … … 4282 4300 } 4283 4301 4284 case Check Ident:4285 compileCheck Ident(node);4302 case CheckStringIdent: 4303 compileCheckStringIdent(node); 4286 4304 break; 4287 4305 -
trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
r200981 r203895 103 103 macro(Structure_globalObject, Structure::globalObjectOffset()) \ 104 104 macro(Structure_prototype, Structure::prototypeOffset()) \ 105 macro(Structure_structureID, Structure::structureIDOffset()) \ 106 macro(Symbol_privateName, Symbol::offsetOfPrivateName()) 105 macro(Structure_structureID, Structure::structureIDOffset()) 107 106 108 107 #define FOR_EACH_INDEXED_ABSTRACT_HEAP(macro) \ -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r203491 r203895 129 129 case CheckBadCell: 130 130 case CheckNotEmpty: 131 case Check Ident:131 case CheckStringIdent: 132 132 case CheckWatchdogTimer: 133 133 case StringCharCodeAt: -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r203812 r203895 603 603 compileCheckBadCell(); 604 604 break; 605 case Check Ident:606 compileCheck Ident();605 case CheckStringIdent: 606 compileCheckStringIdent(); 607 607 break; 608 608 case GetExecutable: … … 2478 2478 } 2479 2479 2480 void compileCheck Ident()2480 void compileCheckStringIdent() 2481 2481 { 2482 2482 UniquedStringImpl* uid = m_node->uidOperand(); 2483 if (uid->isSymbol()) { 2484 LValue stringImpl = lowSymbolUID(m_node->child1()); 2485 speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid))); 2486 } else { 2487 LValue string = lowStringIdent(m_node->child1()); 2488 LValue stringImpl = m_out.loadPtr(string, m_heaps.JSString_value); 2489 speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid))); 2490 } 2483 LValue string = lowStringIdent(m_node->child1()); 2484 LValue stringImpl = m_out.loadPtr(string, m_heaps.JSString_value); 2485 speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid))); 2491 2486 } 2492 2487 … … 5040 5035 5041 5036 if (m_node->isBinaryUseKind(SymbolUse)) { 5042 LValue leftS tringImpl = lowSymbolUID(m_node->child1());5043 LValue rightS tringImpl = lowSymbolUID(m_node->child2());5044 setBoolean(m_out.equal(leftS tringImpl, rightStringImpl));5037 LValue leftSymbol = lowSymbol(m_node->child1()); 5038 LValue rightSymbol = lowSymbol(m_node->child2()); 5039 setBoolean(m_out.equal(leftSymbol, rightSymbol)); 5045 5040 return; 5046 5041 } … … 5053 5048 std::swap(symbolEdge, untypedEdge); 5054 5049 5055 LValue leftS tringImpl = lowSymbolUID(symbolEdge);5050 LValue leftSymbol = lowSymbol(symbolEdge); 5056 5051 LValue untypedValue = lowJSValue(untypedEdge); 5057 5058 LBasicBlock isCellCase = m_out.newBlock(); 5059 LBasicBlock isSymbolCase = m_out.newBlock(); 5060 LBasicBlock continuation = m_out.newBlock(); 5061 5062 ValueFromBlock notSymbolResult = m_out.anchor(m_out.booleanFalse); 5063 m_out.branch( 5064 isCell(untypedValue, provenType(untypedEdge)), 5065 unsure(isCellCase), unsure(continuation)); 5066 5067 LBasicBlock lastNext = m_out.appendTo(isCellCase, isSymbolCase); 5068 m_out.branch( 5069 isSymbol(untypedValue, provenType(untypedEdge)), 5070 unsure(isSymbolCase), unsure(continuation)); 5071 5072 m_out.appendTo(isSymbolCase, continuation); 5073 ValueFromBlock symbolResult = 5074 m_out.anchor( 5075 m_out.equal( 5076 m_out.loadPtr(untypedValue, m_heaps.Symbol_privateName), 5077 leftStringImpl)); 5078 m_out.jump(continuation); 5079 5080 m_out.appendTo(continuation, lastNext); 5081 setBoolean(m_out.phi(Int32, notSymbolResult, symbolResult)); 5052 5053 setBoolean(m_out.equal(leftSymbol, untypedValue)); 5082 5054 return; 5083 5055 } … … 9873 9845 } 9874 9846 9875 LValue lowSymbolUID(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation)9876 {9877 if (Symbol* symbol = edge->dynamicCastConstant<Symbol*>())9878 return m_out.constIntPtr(symbol->privateName().uid());9879 LValue symbol = lowSymbol(edge, mode);9880 // FIXME: We could avoid this load if we had hash-consed Symbols.9881 // https://bugs.webkit.org/show_bug.cgi?id=1589089882 return m_out.loadPtr(symbol, m_heaps.Symbol_privateName);9883 }9884 9885 9847 LValue lowNonNullObject(Edge edge, OperandSpeculationMode mode = AutomaticOperandSpeculation) 9886 9848 { -
trunk/Source/JavaScriptCore/jit/JIT.h
r203699 r203895 396 396 397 397 // Identifier check helper for GetByVal and PutByVal. 398 void emit IdentifierCheck(RegisterID cell, RegisterID scratch, const Identifier&, JumpList& slowCases);399 400 JITGetByIdGenerator emitGetByValWithCachedId( Instruction*, const Identifier&, Jump& fastDoneCase, Jump& slowDoneCase, JumpList& slowCases);401 JITPutByIdGenerator emitPutByValWithCachedId( Instruction*, PutKind, const Identifier&, JumpList& doneCases, JumpList& slowCases);398 void emitByValIdentifierCheck(ByValInfo*, RegisterID cell, RegisterID scratch, const Identifier&, JumpList& slowCases); 399 400 JITGetByIdGenerator emitGetByValWithCachedId(ByValInfo*, Instruction*, const Identifier&, Jump& fastDoneCase, Jump& slowDoneCase, JumpList& slowCases); 401 JITPutByIdGenerator emitPutByValWithCachedId(ByValInfo*, Instruction*, PutKind, const Identifier&, JumpList& doneCases, JumpList& slowCases); 402 402 403 403 enum FinalObjectMode { MayBeFinal, KnownNotFinal }; -
trunk/Source/JavaScriptCore/jit/JITOperations.cpp
r203786 r203895 613 613 if (baseValue.isObject() && isStringOrSymbol(subscript)) { 614 614 const Identifier propertyName = subscript.toPropertyKey(exec); 615 if ( !subscript.isString() || !parseIndex(propertyName)) {615 if (subscript.isSymbol() || !parseIndex(propertyName)) { 616 616 ASSERT(exec->bytecodeOffset()); 617 617 ASSERT(!byValInfo->stubRoutine); … … 625 625 } 626 626 } else { 627 CodeBlock* codeBlock = exec->codeBlock(); 628 ConcurrentJITLocker locker(codeBlock->m_lock); 627 629 byValInfo->seen = true; 628 630 byValInfo->cachedId = propertyName; 631 if (subscript.isSymbol()) 632 byValInfo->cachedSymbol.set(vm, codeBlock, asSymbol(subscript)); 629 633 optimizationResult = OptimizationResult::SeenOnce; 630 634 } … … 691 695 } else if (isStringOrSymbol(subscript)) { 692 696 const Identifier propertyName = subscript.toPropertyKey(exec); 693 Optional<uint32_t> index = parseIndex(propertyName); 694 695 if (!subscript.isString() || !index) { 697 if (subscript.isSymbol() || !parseIndex(propertyName)) { 696 698 ASSERT(exec->bytecodeOffset()); 697 699 ASSERT(!byValInfo->stubRoutine); … … 705 707 } 706 708 } else { 709 CodeBlock* codeBlock = exec->codeBlock(); 710 ConcurrentJITLocker locker(codeBlock->m_lock); 707 711 byValInfo->seen = true; 708 712 byValInfo->cachedId = propertyName; 713 if (subscript.isSymbol()) 714 byValInfo->cachedSymbol.set(vm, codeBlock, asSymbol(subscript)); 709 715 optimizationResult = OptimizationResult::SeenOnce; 710 716 } … … 1687 1693 if (baseValue.isObject() && isStringOrSymbol(subscript)) { 1688 1694 const Identifier propertyName = subscript.toPropertyKey(exec); 1689 if ( !subscript.isString() || !parseIndex(propertyName)) {1695 if (subscript.isSymbol() || !parseIndex(propertyName)) { 1690 1696 ASSERT(exec->bytecodeOffset()); 1691 1697 ASSERT(!byValInfo->stubRoutine); … … 1699 1705 } 1700 1706 } else { 1707 CodeBlock* codeBlock = exec->codeBlock(); 1708 ConcurrentJITLocker locker(codeBlock->m_lock); 1701 1709 byValInfo->seen = true; 1702 1710 byValInfo->cachedId = propertyName; 1711 if (subscript.isSymbol()) 1712 byValInfo->cachedSymbol.set(vm, codeBlock, asSymbol(subscript)); 1703 1713 optimizationResult = OptimizationResult::SeenOnce; 1704 1714 } 1705 1706 1715 } 1707 1716 } -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r202982 r203895 210 210 } 211 211 212 JITGetByIdGenerator JIT::emitGetByValWithCachedId( Instruction* currentInstruction, const Identifier& propertyName, Jump& fastDoneCase, Jump& slowDoneCase, JumpList& slowCases)212 JITGetByIdGenerator JIT::emitGetByValWithCachedId(ByValInfo* byValInfo, Instruction* currentInstruction, const Identifier& propertyName, Jump& fastDoneCase, Jump& slowDoneCase, JumpList& slowCases) 213 213 { 214 214 // base: regT0 … … 219 219 220 220 slowCases.append(emitJumpIfNotJSCell(regT1)); 221 emit IdentifierCheck(regT1, regT3, propertyName, slowCases);221 emitByValIdentifierCheck(byValInfo, regT1, regT3, propertyName, slowCases); 222 222 223 223 JITGetByIdGenerator gen( … … 429 429 } 430 430 431 JITPutByIdGenerator JIT::emitPutByValWithCachedId( Instruction* currentInstruction, PutKind putKind, const Identifier& propertyName, JumpList& doneCases, JumpList& slowCases)431 JITPutByIdGenerator JIT::emitPutByValWithCachedId(ByValInfo* byValInfo, Instruction* currentInstruction, PutKind putKind, const Identifier& propertyName, JumpList& doneCases, JumpList& slowCases) 432 432 { 433 433 // base: regT0 … … 439 439 440 440 slowCases.append(emitJumpIfNotJSCell(regT1)); 441 emit IdentifierCheck(regT1, regT1, propertyName, slowCases);441 emitByValIdentifierCheck(byValInfo, regT1, regT1, propertyName, slowCases); 442 442 443 443 // Write barrier breaks the registers. So after issuing the write barrier, … … 1254 1254 } 1255 1255 1256 void JIT::emitIdentifierCheck(RegisterID cell, RegisterID scratch, const Identifier& propertyName, JumpList& slowCases) 1257 { 1258 if (propertyName.isSymbol()) { 1259 slowCases.append(branchStructure(NotEqual, Address(cell, JSCell::structureIDOffset()), m_vm->symbolStructure.get())); 1260 loadPtr(Address(cell, Symbol::offsetOfPrivateName()), scratch); 1261 } else { 1256 void JIT::emitByValIdentifierCheck(ByValInfo* byValInfo, RegisterID cell, RegisterID scratch, const Identifier& propertyName, JumpList& slowCases) 1257 { 1258 if (propertyName.isSymbol()) 1259 slowCases.append(branchPtr(NotEqual, cell, TrustedImmPtr(byValInfo->cachedSymbol.get()))); 1260 else { 1262 1261 slowCases.append(branchStructure(NotEqual, Address(cell, JSCell::structureIDOffset()), m_vm->stringStructure.get())); 1263 1262 loadPtr(Address(cell, JSString::offsetOfValue()), scratch); 1264 }1265 slowCases.append(branchPtr(NotEqual, scratch, TrustedImmPtr(propertyName.impl())));1263 slowCases.append(branchPtr(NotEqual, scratch, TrustedImmPtr(propertyName.impl()))); 1264 } 1266 1265 } 1267 1266 … … 1326 1325 JumpList slowCases; 1327 1326 1328 JITGetByIdGenerator gen = emitGetByValWithCachedId( currentInstruction, propertyName, fastDoneCase, slowDoneCase, slowCases);1327 JITGetByIdGenerator gen = emitGetByValWithCachedId(byValInfo, currentInstruction, propertyName, fastDoneCase, slowDoneCase, slowCases); 1329 1328 1330 1329 ConcurrentJITLocker locker(m_codeBlock->m_lock); … … 1415 1414 JumpList slowCases; 1416 1415 1417 JITPutByIdGenerator gen = emitPutByValWithCachedId( currentInstruction, putKind, propertyName, doneCases, slowCases);1416 JITPutByIdGenerator gen = emitPutByValWithCachedId(byValInfo, currentInstruction, putKind, propertyName, doneCases, slowCases); 1418 1417 1419 1418 ConcurrentJITLocker locker(m_codeBlock->m_lock); -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r202214 r203895 280 280 } 281 281 282 JITGetByIdGenerator JIT::emitGetByValWithCachedId( Instruction* currentInstruction, const Identifier& propertyName, Jump& fastDoneCase, Jump& slowDoneCase, JumpList& slowCases)282 JITGetByIdGenerator JIT::emitGetByValWithCachedId(ByValInfo* byValInfo, Instruction* currentInstruction, const Identifier& propertyName, Jump& fastDoneCase, Jump& slowDoneCase, JumpList& slowCases) 283 283 { 284 284 int dst = currentInstruction[1].u.operand; … … 289 289 290 290 slowCases.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::CellTag))); 291 emit IdentifierCheck(regT2, regT4, propertyName, slowCases);291 emitByValIdentifierCheck(byValInfo, regT2, regT4, propertyName, slowCases); 292 292 293 293 JITGetByIdGenerator gen( … … 486 486 } 487 487 488 JITPutByIdGenerator JIT::emitPutByValWithCachedId( Instruction* currentInstruction, PutKind putKind, const Identifier& propertyName, JumpList& doneCases, JumpList& slowCases)488 JITPutByIdGenerator JIT::emitPutByValWithCachedId(ByValInfo* byValInfo, Instruction* currentInstruction, PutKind putKind, const Identifier& propertyName, JumpList& doneCases, JumpList& slowCases) 489 489 { 490 490 // base: tag(regT1), payload(regT0) … … 495 495 496 496 slowCases.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::CellTag))); 497 emit IdentifierCheck(regT2, regT2, propertyName, slowCases);497 emitByValIdentifierCheck(byValInfo, regT2, regT2, propertyName, slowCases); 498 498 499 499 // Write barrier breaks the registers. So after issuing the write barrier, -
trunk/Source/JavaScriptCore/runtime/JSCJSValue.cpp
r202890 r203895 253 253 out.print(" (unresolved)"); 254 254 out.print(": ", impl); 255 } else if (structure->classInfo()->isSubClassOf(Structure::info())) 255 } else if (structure->classInfo()->isSubClassOf(Symbol::info())) 256 out.print("Symbol: ", RawPointer(asCell())); 257 else if (structure->classInfo()->isSubClassOf(Structure::info())) 256 258 out.print("Structure: ", inContext(*jsCast<Structure*>(asCell()), context)); 257 259 else { -
trunk/Source/JavaScriptCore/runtime/JSCJSValueInlines.h
r202890 r203895 942 942 if (sym1 || sym2) { 943 943 if (sym1 && sym2) 944 return asSymbol(v1) ->privateName() == asSymbol(v2)->privateName();944 return asSymbol(v1) == asSymbol(v2); 945 945 return false; 946 946 } … … 971 971 if (v1.asCell()->isString() && v2.asCell()->isString()) 972 972 return WTF::equal(*asString(v1)->value(exec).impl(), *asString(v2)->value(exec).impl()); 973 if (v1.asCell()->isSymbol() && v2.asCell()->isSymbol())974 return asSymbol(v1)->privateName() == asSymbol(v2)->privateName();975 976 973 return v1 == v2; 977 974 } -
trunk/Source/JavaScriptCore/runtime/JSFunction.cpp
r202890 r203895 576 576 name = emptyString(); 577 577 else 578 name = makeString( "[", String(asSymbol(value)->privateName().uid()), ']');578 name = makeString('[', String(uid), ']'); 579 579 } else { 580 580 VM& vm = exec->vm(); -
trunk/Source/JavaScriptCore/runtime/MapData.h
r198212 r203895 120 120 typedef HashMap<EncodedJSValue, int32_t, EncodedJSValueHash, EncodedJSValueHashTraits, IndexTraits> ValueKeyedMap; 121 121 typedef HashMap<StringImpl*, int32_t, typename WTF::DefaultHash<StringImpl*>::Hash, WTF::HashTraits<StringImpl*>, IndexTraits> StringKeyedMap; 122 typedef HashMap<SymbolImpl*, int32_t, typename WTF::PtrHash<SymbolImpl*>, WTF::HashTraits<SymbolImpl*>, IndexTraits> SymbolKeyedMap;123 122 124 123 ALWAYS_INLINE Entry* find(ExecState*, KeyType); … … 135 134 ValueKeyedMap m_valueKeyedTable; 136 135 StringKeyedMap m_stringKeyedTable; 137 SymbolKeyedMap m_symbolKeyedTable;138 136 int32_t m_capacity; 139 137 int32_t m_size; -
trunk/Source/JavaScriptCore/runtime/MapDataInlines.h
r198212 r203895 44 44 m_valueKeyedTable.clear(); 45 45 m_stringKeyedTable.clear(); 46 m_symbolKeyedTable.clear();47 46 m_capacity = 0; 48 47 m_size = 0; … … 63 62 return &m_entries.get()[iter->value]; 64 63 } 65 if (key.value.isSymbol()) {66 auto iter = m_symbolKeyedTable.find(asSymbol(key.value)->privateName().uid());67 if (iter == m_symbolKeyedTable.end())68 return 0;69 return &m_entries.get()[iter->value];70 }71 64 if (key.value.isCell()) { 72 65 auto iter = m_cellKeyedTable.find(key.value.asCell()); … … 121 114 if (key.value.isString()) 122 115 return add(exec, owner, m_stringKeyedTable, asString(key.value)->value(exec).impl(), key); 123 if (key.value.isSymbol())124 return add(exec, owner, m_symbolKeyedTable, asSymbol(key.value)->privateName().uid(), key);125 116 if (key.value.isCell()) 126 117 return add(exec, owner, m_cellKeyedTable, key.value.asCell(), key); … … 146 137 location = iter->value; 147 138 m_stringKeyedTable.remove(iter); 148 } else if (key.value.isSymbol()) {149 auto iter = m_symbolKeyedTable.find(asSymbol(key.value)->privateName().uid());150 if (iter == m_symbolKeyedTable.end())151 return false;152 location = iter->value;153 m_symbolKeyedTable.remove(iter);154 139 } else if (key.value.isCell()) { 155 140 auto iter = m_cellKeyedTable.find(key.value.asCell()); … … 201 186 for (auto ptr = m_stringKeyedTable.begin(); ptr != m_stringKeyedTable.end(); ++ptr) 202 187 ptr->value = m_entries.get()[ptr->value].key().get().asInt32(); 203 for (auto ptr = m_symbolKeyedTable.begin(); ptr != m_symbolKeyedTable.end(); ++ptr)204 ptr->value = m_entries.get()[ptr->value].key().get().asInt32();205 188 206 189 ASSERT((m_size - newEnd) == m_deletedCount); -
trunk/Source/JavaScriptCore/runtime/Symbol.cpp
r202890 r203895 1 1 /* 2 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.3 * Copyright (C) 2015-2016 Yusuke Suzuki <utatane.tea@gmail.com>. 4 4 * 5 5 * Redistribution and use in source and binary forms, with or without … … 54 54 } 55 55 56 void Symbol::finishCreation(VM& vm) 57 { 58 Base::finishCreation(vm); 59 ASSERT(inherits(info())); 60 61 vm.symbolImplToSymbolMap.set(m_privateName.uid(), this); 62 } 63 56 64 inline SymbolObject* SymbolObject::create(VM& vm, JSGlobalObject* globalObject, Symbol* symbol) 57 65 { … … 94 102 } 95 103 104 Symbol* Symbol::create(VM& vm) 105 { 106 Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm); 107 symbol->finishCreation(vm); 108 return symbol; 109 } 110 111 Symbol* Symbol::create(ExecState* exec, JSString* description) 112 { 113 VM& vm = exec->vm(); 114 String desc = description->value(exec); 115 Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm, desc); 116 symbol->finishCreation(vm); 117 return symbol; 118 } 119 120 Symbol* Symbol::create(VM& vm, SymbolImpl& uid) 121 { 122 if (Symbol* symbol = vm.symbolImplToSymbolMap.get(&uid)) 123 return symbol; 124 125 Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm, uid); 126 symbol->finishCreation(vm); 127 return symbol; 128 } 129 96 130 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/Symbol.h
r199686 r203895 2 2 * Copyright (C) 2012 Apple Inc. All rights reserved. 3 3 * Copyright (C) 2014 Apple Inc. All rights reserved. 4 * Copyright (C) 2015 Yusuke Suzuki <utatane.tea@gmail.com>.4 * Copyright (C) 2015-2016 Yusuke Suzuki <utatane.tea@gmail.com>. 5 5 * 6 6 * Redistribution and use in source and binary forms, with or without … … 29 29 #define Symbol_h 30 30 31 #include "JSCell.h"32 31 #include "JSString.h" 33 32 #include "PrivateName.h" … … 49 48 } 50 49 51 static Symbol* create(VM& vm) 52 { 53 Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm); 54 symbol->finishCreation(vm); 55 return symbol; 56 } 57 58 static Symbol* create(ExecState* exec, JSString* description) 59 { 60 VM& vm = exec->vm(); 61 String desc = description->value(exec); 62 Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm, desc); 63 symbol->finishCreation(vm); 64 return symbol; 65 } 66 67 static Symbol* create(VM& vm, SymbolImpl& uid) 68 { 69 Symbol* symbol = new (NotNull, allocateCell<Symbol>(vm.heap)) Symbol(vm, uid); 70 symbol->finishCreation(vm); 71 return symbol; 72 } 50 static Symbol* create(VM&); 51 static Symbol* create(ExecState*, JSString* description); 52 static Symbol* create(VM&, SymbolImpl& uid); 73 53 74 54 const PrivateName& privateName() const { return m_privateName; } … … 80 60 double toNumber(ExecState*) const; 81 61 82 static size_t offsetOfPrivateName() { return OBJECT_OFFSETOF(Symbol, m_privateName); }83 84 62 protected: 85 63 static void destroy(JSCell*); … … 89 67 Symbol(VM&, SymbolImpl& uid); 90 68 91 void finishCreation(VM& vm) 92 { 93 Base::finishCreation(vm); 94 ASSERT(inherits(info())); 95 } 69 void finishCreation(VM&); 96 70 97 71 PrivateName m_privateName; -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r203808 r203895 166 166 , customGetterSetterFunctionMap(*this) 167 167 , stringCache(*this) 168 , symbolImplToSymbolMap(*this) 168 169 , prototypeMap(*this) 169 170 , interpreter(0) -
trunk/Source/JavaScriptCore/runtime/VM.h
r203808 r203895 109 109 class RegExp; 110 110 #endif 111 class Symbol; 111 112 class UnlinkedCodeBlock; 112 113 class UnlinkedEvalCodeBlock; … … 337 338 WTF::SymbolRegistry& symbolRegistry() { return m_symbolRegistry; } 338 339 340 WeakGCMap<SymbolImpl*, Symbol, PtrHash<SymbolImpl*>> symbolImplToSymbolMap; 341 339 342 enum class DeletePropertyMode { 340 343 // Default behaviour of deleteProperty, matching the spec.
Note: See TracChangeset
for help on using the changeset viewer.