Changeset 96527 in webkit
- Timestamp:
- Oct 3, 2011 12:25:16 PM (13 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r96526 r96527 1 2011-10-02 Filip Pizlo <fpizlo@apple.com> 2 3 DFG should speculate more aggressively on obvious cases on 4 polymorphic get_by_id 5 https://bugs.webkit.org/show_bug.cgi?id=69235 6 7 Reviewed by Oliver Hunt. 8 9 This implements trivial polymorphic get_by_id. It also fixes 10 problems in the CSE for CheckStructure in the put_by_id 11 transition case. 12 13 Doing this required knowing whether a polymorphic get_by_id stub 14 was doing a direct access rather than a call of some kind. 15 16 Slight speed-up on Kraken and SunSpider. 0.5% speed-up in the 17 scaled mean of all benchmarks. 18 19 * GNUmakefile.list.am: 20 * JavaScriptCore.xcodeproj/project.pbxproj: 21 * bytecode/Instruction.h: 22 (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set): 23 (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList): 24 * dfg/DFGByteCodeParser.cpp: 25 (JSC::DFG::ByteCodeParser::cellConstant): 26 (JSC::DFG::ByteCodeParser::parseBlock): 27 * dfg/DFGGraph.cpp: 28 (JSC::DFG::Graph::dump): 29 * dfg/DFGGraph.h: 30 (JSC::DFG::Graph::addStructureSet): 31 (JSC::DFG::Graph::addStructureTransitionData): 32 * dfg/DFGNode.h: 33 (JSC::DFG::StructureTransitionData::StructureTransitionData): 34 (JSC::DFG::Node::hasStructureTransitionData): 35 (JSC::DFG::Node::structureTransitionData): 36 (JSC::DFG::Node::hasStructureSet): 37 (JSC::DFG::Node::structureSet): 38 * dfg/DFGPropagator.cpp: 39 (JSC::DFG::Propagator::checkStructureLoadElimination): 40 (JSC::DFG::Propagator::performNodeCSE): 41 * dfg/DFGRepatch.cpp: 42 (JSC::DFG::tryBuildGetByIDList): 43 (JSC::DFG::tryBuildGetByIDProtoList): 44 * dfg/DFGSpeculativeJIT32_64.cpp: 45 (JSC::DFG::SpeculativeJIT::compile): 46 * dfg/DFGSpeculativeJIT64.cpp: 47 (JSC::DFG::SpeculativeJIT::compile): 48 * dfg/DFGStructureSet.h: Added. 49 (JSC::DFG::StructureSet::StructureSet): 50 (JSC::DFG::StructureSet::add): 51 (JSC::DFG::StructureSet::addAll): 52 (JSC::DFG::StructureSet::remove): 53 (JSC::DFG::StructureSet::contains): 54 (JSC::DFG::StructureSet::isSubsetOf): 55 (JSC::DFG::StructureSet::isSupersetOf): 56 (JSC::DFG::StructureSet::size): 57 (JSC::DFG::StructureSet::at): 58 (JSC::DFG::StructureSet::operator[]): 59 (JSC::DFG::StructureSet::last): 60 * jit/JITPropertyAccess.cpp: 61 (JSC::JIT::privateCompileGetByIdSelfList): 62 (JSC::JIT::privateCompileGetByIdProtoList): 63 (JSC::JIT::privateCompileGetByIdChainList): 64 * jit/JITPropertyAccess32_64.cpp: 65 (JSC::JIT::privateCompileGetByIdSelfList): 66 (JSC::JIT::privateCompileGetByIdProtoList): 67 (JSC::JIT::privateCompileGetByIdChainList): 68 * jit/JITStubs.cpp: 69 (JSC::DEFINE_STUB_FUNCTION): 70 (JSC::getPolymorphicAccessStructureListSlot): 71 1 72 2011-10-03 Jer Noble <jer.noble@apple.com> 2 73 -
trunk/Source/JavaScriptCore/GNUmakefile.list.am
r96505 r96527 135 135 Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp \ 136 136 Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h \ 137 Source/JavaScriptCore/dfg/DFGStructureSet.h \ 137 138 Source/JavaScriptCore/heap/AllocationSpace.cpp \ 138 139 Source/JavaScriptCore/heap/AllocationSpace.h \ -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r96465 r96527 84 84 0FE228ED1436AB2700196C48 /* Heuristics.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FE228EB1436AB2300196C48 /* Heuristics.h */; settings = {ATTRIBUTES = (Private, ); }; }; 85 85 0FE228EE1436AB2C00196C48 /* Heuristics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FE228EA1436AB2300196C48 /* Heuristics.cpp */; }; 86 0FFF4BB4143955E900655BC0 /* DFGStructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FFF4BB2143955E600655BC0 /* DFGStructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; 86 87 1400067712A6F7830064D123 /* OSAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1400067612A6F7830064D123 /* OSAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; 87 88 1400069312A6F9E10064D123 /* OSAllocatorPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1400069212A6F9E10064D123 /* OSAllocatorPosix.cpp */; }; … … 842 843 0FE228EA1436AB2300196C48 /* Heuristics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Heuristics.cpp; sourceTree = "<group>"; }; 843 844 0FE228EB1436AB2300196C48 /* Heuristics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Heuristics.h; sourceTree = "<group>"; }; 845 0FFF4BB2143955E600655BC0 /* DFGStructureSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGStructureSet.h; path = dfg/DFGStructureSet.h; sourceTree = "<group>"; }; 844 846 1400067612A6F7830064D123 /* OSAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSAllocator.h; sourceTree = "<group>"; }; 845 847 1400069212A6F9E10064D123 /* OSAllocatorPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OSAllocatorPosix.cpp; sourceTree = "<group>"; }; … … 2277 2279 isa = PBXGroup; 2278 2280 children = ( 2281 0FFF4BB2143955E600655BC0 /* DFGStructureSet.h */, 2279 2282 86EC9DB41328DF82002B2AD7 /* DFGByteCodeParser.cpp */, 2280 2283 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */, … … 2868 2871 86880F1E14328BB900B08D42 /* DFGJITCompilerInlineMethods.h in Headers */, 2869 2872 0FE228ED1436AB2700196C48 /* Heuristics.h in Headers */, 2873 0FFF4BB4143955E900655BC0 /* DFGStructureSet.h in Headers */, 2870 2874 ); 2871 2875 runOnlyForDeploymentPostprocessing = 0; -
trunk/Source/JavaScriptCore/bytecode/Instruction.h
r95901 r96527 59 59 struct PolymorphicStubInfo { 60 60 bool isChain; 61 bool isDirect; 61 62 PolymorphicAccessStructureListStubRoutineType stubRoutine; 62 63 WriteBarrier<Structure> base; … … 71 72 } 72 73 73 void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base )74 void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, bool isDirect) 74 75 { 75 76 stubRoutine = _stubRoutine; … … 77 78 u.proto.clear(); 78 79 isChain = false; 80 this->isDirect = isDirect; 79 81 } 80 82 81 void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto )83 void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto, bool isDirect) 82 84 { 83 85 stubRoutine = _stubRoutine; … … 85 87 u.proto.set(globalData, owner, _proto); 86 88 isChain = false; 89 this->isDirect = isDirect; 87 90 } 88 91 89 void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain )92 void set(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain, bool isDirect) 90 93 { 91 94 stubRoutine = _stubRoutine; … … 93 96 u.chain.set(globalData, owner, _chain); 94 97 isChain = true; 98 this->isDirect = isDirect; 95 99 } 96 100 } list[POLYMORPHIC_LIST_CACHE_SIZE]; 97 101 98 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase )102 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, bool isDirect) 99 103 { 100 list[0].set(globalData, owner, stubRoutine, firstBase );104 list[0].set(globalData, owner, stubRoutine, firstBase, isDirect); 101 105 } 102 106 103 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto )107 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto, bool isDirect) 104 108 { 105 list[0].set(globalData, owner, stubRoutine, firstBase, firstProto );109 list[0].set(globalData, owner, stubRoutine, firstBase, firstProto, isDirect); 106 110 } 107 111 108 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain )112 PolymorphicAccessStructureList(JSGlobalData& globalData, JSCell* owner, PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain, bool isDirect) 109 113 { 110 list[0].set(globalData, owner, stubRoutine, firstBase, firstChain );114 list[0].set(globalData, owner, stubRoutine, firstBase, firstChain, isDirect); 111 115 } 112 116 -
trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
r96443 r96527 415 415 m_constants.append(ConstantRecord()); 416 416 ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters()); 417 418 m_cellConstants.add(cell, m_codeBlock->numberOfConstantRegisters() - 1); 417 419 418 420 return getJSConstant(m_codeBlock->numberOfConstantRegisters() - 1); … … 1161 1163 unsigned identifierNumber = currentInstruction[3].u.operand; 1162 1164 1165 Identifier identifier = m_codeBlock->identifier(identifierNumber); 1163 1166 StructureStubInfo& stubInfo = m_profiledBlock->getStubInfo(m_currentIndex); 1164 1167 1165 NodeIndex getById = NoNode; 1166 if (stubInfo.seen && stubInfo.accessType == access_get_by_id_self) { 1167 Structure* structure = stubInfo.u.getByIdSelf.baseObjectStructure.get(); 1168 Identifier identifier = m_codeBlock->identifier(identifierNumber); 1169 size_t offset = structure->get(*m_globalData, identifier); 1170 1171 if (offset != notFound) { 1172 addToGraph(CheckStructure, OpInfo(structure), base); 1173 getById = addToGraph(GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction), addToGraph(GetPropertyStorage, base)); 1168 size_t offset = notFound; 1169 StructureSet structureSet; 1170 if (stubInfo.seen) { 1171 switch (stubInfo.accessType) { 1172 case access_get_by_id_self: { 1173 Structure* structure = stubInfo.u.getByIdSelf.baseObjectStructure.get(); 1174 offset = structure->get(*m_globalData, identifier); 1174 1175 1175 StorageAccessData storageAccessData; 1176 storageAccessData.offset = offset; 1177 storageAccessData.identifierNumber = identifierNumber; 1178 m_graph.m_storageAccessData.append(storageAccessData); 1176 if (offset != notFound) 1177 structureSet.add(structure); 1178 1179 if (offset != notFound) 1180 ASSERT(structureSet.size()); 1181 break; 1182 } 1183 1184 case access_get_by_id_self_list: { 1185 PolymorphicAccessStructureList* list = stubInfo.u.getByIdProtoList.structureList; 1186 unsigned size = stubInfo.u.getByIdProtoList.listSize; 1187 for (unsigned i = 0; i < size; ++i) { 1188 if (!list->list[i].isDirect) { 1189 offset = notFound; 1190 break; 1191 } 1192 1193 Structure* structure = list->list[i].base.get(); 1194 size_t myOffset = structure->get(*m_globalData, identifier); 1195 1196 if (myOffset == notFound) { 1197 offset = notFound; 1198 break; 1199 } 1200 1201 if (!i) 1202 offset = myOffset; 1203 else if (offset != myOffset) { 1204 offset = notFound; 1205 break; 1206 } 1207 1208 structureSet.add(structure); 1209 } 1210 1211 if (offset != notFound) 1212 ASSERT(structureSet.size()); 1213 break; 1214 } 1215 1216 default: 1217 ASSERT(offset == notFound); 1218 break; 1179 1219 } 1180 1220 } 1181 1182 if (getById == NoNode) 1183 getById = addToGraph(GetById, OpInfo(identifierNumber), OpInfo(prediction), base); 1184 1185 set(currentInstruction[1].u.operand, getById); 1221 1222 if (offset != notFound) { 1223 ASSERT(structureSet.size()); 1224 addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structureSet)), base); 1225 set(currentInstruction[1].u.operand, addToGraph(GetByOffset, OpInfo(m_graph.m_storageAccessData.size()), OpInfo(prediction), addToGraph(GetPropertyStorage, base))); 1226 1227 StorageAccessData storageAccessData; 1228 storageAccessData.offset = offset; 1229 storageAccessData.identifierNumber = identifierNumber; 1230 m_graph.m_storageAccessData.append(storageAccessData); 1231 } else 1232 set(currentInstruction[1].u.operand, addToGraph(GetById, OpInfo(identifierNumber), OpInfo(prediction), base)); 1186 1233 1187 1234 NEXT_OPCODE(op_get_by_id); … … 1208 1255 1209 1256 if (offset != notFound) { 1210 addToGraph(CheckStructure, OpInfo( structure), base);1257 addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(structure)), base); 1211 1258 addToGraph(PutByOffset, OpInfo(m_graph.m_storageAccessData.size()), base, addToGraph(GetPropertyStorage, base), value); 1212 1259 … … 1234 1281 1235 1282 if (offset != notFound) { 1236 addToGraph(CheckStructure, OpInfo( previousStructure), base);1283 addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(previousStructure)), base); 1237 1284 if (!direct) { 1238 1285 for (WriteBarrier<Structure>* it = structureChain->head(); *it; ++it) { … … 1241 1288 continue; 1242 1289 ASSERT(prototype.isCell()); 1243 addToGraph(CheckStructure, OpInfo( prototype.asCell()->structure()), cellConstant(prototype.asCell()));1290 addToGraph(CheckStructure, OpInfo(m_graph.addStructureSet(prototype.asCell()->structure())), cellConstant(prototype.asCell())); 1244 1291 } 1245 1292 } 1246 addToGraph(PutStructure, OpInfo( newStructure), base);1293 addToGraph(PutStructure, OpInfo(m_graph.addStructureTransitionData(StructureTransitionData(previousStructure, newStructure))), base); 1247 1294 1248 1295 addToGraph(PutByOffset, OpInfo(m_graph.m_storageAccessData.size()), base, addToGraph(GetPropertyStorage, base), value); -
trunk/Source/JavaScriptCore/dfg/DFGGraph.cpp
r96443 r96527 150 150 hasPrinted = true; 151 151 } 152 if (node.hasStructure()) { 153 printf("%sstruct(%p)", hasPrinted ? ", " : "", node.structure()); 152 if (node.hasStructureSet()) { 153 for (size_t i = 0; i < node.structureSet().size(); ++i) { 154 printf("%sstruct(%p)", hasPrinted ? ", " : "", node.structureSet()[i]); 155 hasPrinted = true; 156 } 157 } 158 if (node.hasStructureTransitionData()) { 159 printf("%sstruct(%p -> %p)", hasPrinted ? ", " : "", node.structureTransitionData().previousStructure, node.structureTransitionData().newStructure); 154 160 hasPrinted = true; 155 161 } -
trunk/Source/JavaScriptCore/dfg/DFGGraph.h
r96375 r96527 330 330 331 331 void predictArgumentTypes(ExecState*, CodeBlock*); 332 333 StructureSet* addStructureSet(const StructureSet& structureSet) 334 { 335 ASSERT(structureSet.size()); 336 m_structureSet.append(structureSet); 337 return &m_structureSet.last(); 338 } 339 340 StructureTransitionData* addStructureTransitionData(const StructureTransitionData& structureTransitionData) 341 { 342 m_structureTransitionData.append(structureTransitionData); 343 return &m_structureTransitionData.last(); 344 } 332 345 333 346 Vector< OwnPtr<BasicBlock> , 8> m_blocks; … … 338 351 Vector<NodeIndex, 8> m_arguments; 339 352 SegmentedVector<VariableAccessData, 16> m_variableAccessData; 353 SegmentedVector<StructureSet, 16> m_structureSet; 354 SegmentedVector<StructureTransitionData, 8> m_structureTransitionData; 340 355 unsigned m_preservedVars; 341 356 unsigned m_localVars; -
trunk/Source/JavaScriptCore/dfg/DFGNode.h
r96461 r96527 27 27 #define DFGNode_h 28 28 29 #include "DFGStructureSet.h" 29 30 #include <wtf/BoundsCheckedPointer.h> 30 31 #include <wtf/Platform.h> … … 155 156 }; 156 157 158 struct StructureTransitionData { 159 Structure* previousStructure; 160 Structure* newStructure; 161 162 StructureTransitionData() { } 163 164 StructureTransitionData(Structure* previousStructure, Structure* newStructure) 165 : previousStructure(previousStructure) 166 , newStructure(newStructure) 167 { 168 } 169 }; 170 157 171 typedef unsigned ArithNodeFlags; 158 172 #define NodeUseBottom 0x00 … … 785 799 } 786 800 787 bool hasStructure() 788 { 789 return op == CheckStructure || op == PutStructure; 790 } 791 792 Structure* structure() 793 { 794 return reinterpret_cast<Structure*>(m_opInfo); 801 bool hasStructureTransitionData() 802 { 803 return op == PutStructure; 804 } 805 806 StructureTransitionData& structureTransitionData() 807 { 808 ASSERT(hasStructureTransitionData()); 809 return *reinterpret_cast<StructureTransitionData*>(m_opInfo); 810 } 811 812 bool hasStructureSet() 813 { 814 return op == CheckStructure; 815 } 816 817 StructureSet& structureSet() 818 { 819 ASSERT(hasStructureSet()); 820 return *reinterpret_cast<StructureSet*>(m_opInfo); 795 821 } 796 822 -
trunk/Source/JavaScriptCore/dfg/DFGPropagator.cpp
r96482 r96527 1014 1014 } 1015 1015 1016 bool checkStructureLoadElimination( Structure* structure, NodeIndex child1)1016 bool checkStructureLoadElimination(const StructureSet& structureSet, NodeIndex child1) 1017 1017 { 1018 1018 NodeIndex start = startIndexForChildren(child1); … … 1022 1022 case CheckStructure: 1023 1023 if (node.child1() == child1 1024 && node.structure() == structure)1024 && structureSet.isSupersetOf(node.structureSet())) 1025 1025 return true; 1026 1026 break; … … 1028 1028 case PutStructure: 1029 1029 if (node.child1() == child1 1030 && node.structure() == structure)1030 && structureSet.contains(node.structureTransitionData().newStructure)) 1031 1031 return true; 1032 return false; 1032 if (structureSet.contains(node.structureTransitionData().previousStructure)) 1033 return false; 1034 break; 1033 1035 1034 1036 case PutByOffset: … … 1294 1296 1295 1297 case CheckStructure: 1296 if (checkStructureLoadElimination(node.structure (), node.child1()))1298 if (checkStructureLoadElimination(node.structureSet(), node.child1())) 1297 1299 eliminate(); 1298 1300 break; -
trunk/Source/JavaScriptCore/dfg/DFGRepatch.cpp
r96171 r96527 348 348 if (stubInfo.accessType == access_get_by_id_self) { 349 349 ASSERT(!stubInfo.stubRoutine); 350 polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), MacroAssemblerCodeRef::createSelfManagedCodeRef(stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase)), stubInfo.u.getByIdSelf.baseObjectStructure.get() );350 polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), MacroAssemblerCodeRef::createSelfManagedCodeRef(stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToSlowCase)), stubInfo.u.getByIdSelf.baseObjectStructure.get(), true); 351 351 stubInfo.initGetByIdSelfList(polymorphicStructureList, 1); 352 352 } else { … … 388 388 MacroAssemblerCodeRef stubRoutine = patchBuffer.finalizeCode(); 389 389 390 polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), stubRoutine, structure );390 polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), stubRoutine, structure, true); 391 391 392 392 CodeLocationJump jumpLocation = stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck); … … 435 435 if (stubInfo.accessType == access_get_by_id_chain) { 436 436 ASSERT(!!stubInfo.stubRoutine); 437 polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), stubInfo.stubRoutine, stubInfo.u.getByIdChain.baseObjectStructure.get(), stubInfo.u.getByIdChain.chain.get() );437 polymorphicStructureList = new PolymorphicAccessStructureList(*globalData, codeBlock->ownerExecutable(), stubInfo.stubRoutine, stubInfo.u.getByIdChain.baseObjectStructure.get(), stubInfo.u.getByIdChain.chain.get(), true); 438 438 stubInfo.stubRoutine = MacroAssemblerCodeRef(); 439 439 stubInfo.initGetByIdProtoList(polymorphicStructureList, 1); … … 454 454 generateProtoChainAccessStub(exec, stubInfo, prototypeChain, count, offset, structure, stubInfo.callReturnLocation.labelAtOffset(stubInfo.deltaCallToDone), lastProtoBegin, stubRoutine); 455 455 456 polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), stubRoutine, structure );456 polymorphicStructureList->list[listIndex].set(*globalData, codeBlock->ownerExecutable(), stubRoutine, structure, true); 457 457 458 458 CodeLocationJump jumpLocation = stubInfo.callReturnLocation.jumpAtOffset(stubInfo.deltaCallToStructCheck); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
r96461 r96527 1675 1675 SpeculateCellOperand base(this, node.child1()); 1676 1676 1677 GPRReg baseGPR = base.gpr(); 1678 1679 speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structure()))); 1677 ASSERT(node.structureSet().size()); 1678 1679 if (node.structureSet().size() == 1) 1680 speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structureSet()[0]))); 1681 else { 1682 GPRTemporary structure(this); 1683 1684 m_jit.loadPtr(JITCompiler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr()); 1685 1686 JITCompiler::JumpList done; 1687 1688 for (size_t i = 0; i < node.structureSet().size() - 1; ++i) 1689 done.append(m_jit.branchPtr(JITCompiler::Equal, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet()[i]))); 1690 1691 speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet().last()))); 1692 1693 done.link(&m_jit); 1694 } 1680 1695 1681 1696 noResult(m_compileIndex); -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
r96461 r96527 1735 1735 SpeculateCellOperand base(this, node.child1()); 1736 1736 1737 GPRReg baseGPR = base.gpr(); 1738 1739 speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(baseGPR, JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structure()))); 1737 ASSERT(node.structureSet().size()); 1738 1739 if (node.structureSet().size() == 1) 1740 speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, JITCompiler::Address(base.gpr(), JSCell::structureOffset()), JITCompiler::TrustedImmPtr(node.structureSet()[0]))); 1741 else { 1742 GPRTemporary structure(this); 1743 1744 m_jit.loadPtr(JITCompiler::Address(base.gpr(), JSCell::structureOffset()), structure.gpr()); 1745 1746 JITCompiler::JumpList done; 1747 1748 for (size_t i = 0; i < node.structureSet().size() - 1; ++i) 1749 done.append(m_jit.branchPtr(JITCompiler::Equal, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet()[i]))); 1750 1751 speculationCheck(m_jit.branchPtr(JITCompiler::NotEqual, structure.gpr(), JITCompiler::TrustedImmPtr(node.structureSet().last()))); 1752 1753 done.link(&m_jit); 1754 } 1740 1755 1741 1756 noResult(m_compileIndex); … … 1749 1764 #if ENABLE(GGC) || ENABLE(WRITE_BARRIER_PROFILING) 1750 1765 // Must always emit this write barrier as the structure transition itself requires it 1751 writeBarrier(baseGPR, node.structure (), WriteBarrierForGenericAccess);1766 writeBarrier(baseGPR, node.structureTransitionData().newStructure, WriteBarrierForGenericAccess); 1752 1767 #endif 1753 1768 1754 m_jit.storePtr(MacroAssembler::TrustedImmPtr(node.structure ()), MacroAssembler::Address(baseGPR, JSCell::structureOffset()));1769 m_jit.storePtr(MacroAssembler::TrustedImmPtr(node.structureTransitionData().newStructure), MacroAssembler::Address(baseGPR, JSCell::structureOffset())); 1755 1770 1756 1771 noResult(m_compileIndex); -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r96372 r96527 703 703 Jump failureCase = checkStructure(regT0, structure); 704 704 bool needsStubLink = false; 705 bool isDirect = false; 705 706 if (slot.cachedPropertyType() == PropertySlot::Getter) { 706 707 needsStubLink = true; … … 719 720 stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress())); 720 721 stubCall.call(); 721 } else 722 } else { 723 isDirect = true; 722 724 compileGetDirectOffset(regT0, regT0, cachedOffset); 725 } 723 726 Jump success = jump(); 724 727 … … 744 747 MacroAssemblerCodeRef stubCode = patchBuffer.finalizeCode(); 745 748 746 polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure );749 polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, isDirect); 747 750 748 751 // Finally patch the jump to slow case back in the hot path to jump here instead. … … 767 770 // Checks out okay! 768 771 bool needsStubLink = false; 772 bool isDirect = false; 769 773 if (slot.cachedPropertyType() == PropertySlot::Getter) { 770 774 needsStubLink = true; … … 783 787 stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress())); 784 788 stubCall.call(); 785 } else 789 } else { 790 isDirect = true; 786 791 compileGetDirectOffset(protoObject, regT0, cachedOffset); 792 } 787 793 788 794 Jump success = jump(); … … 806 812 807 813 MacroAssemblerCodeRef stubCode = patchBuffer.finalizeCode(); 808 prototypeStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, prototypeStructure );814 prototypeStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubCode, structure, prototypeStructure, isDirect); 809 815 810 816 // Finally patch the jump to slow case back in the hot path to jump here instead. … … 833 839 ASSERT(protoObject); 834 840 841 bool needsStubLink = false; 842 bool isDirect = false; 843 if (slot.cachedPropertyType() == PropertySlot::Getter) { 844 needsStubLink = true; 845 compileGetDirectOffset(protoObject, regT1, cachedOffset); 846 JITStubCall stubCall(this, cti_op_get_by_id_getter_stub); 847 stubCall.addArgument(regT1); 848 stubCall.addArgument(regT0); 849 stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress())); 850 stubCall.call(); 851 } else if (slot.cachedPropertyType() == PropertySlot::Custom) { 852 needsStubLink = true; 853 JITStubCall stubCall(this, cti_op_get_by_id_custom_stub); 854 stubCall.addArgument(TrustedImmPtr(protoObject)); 855 stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress())); 856 stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident))); 857 stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress())); 858 stubCall.call(); 859 } else { 860 isDirect = true; 861 compileGetDirectOffset(protoObject, regT0, cachedOffset); 862 } 863 Jump success = jump(); 864 865 LinkBuffer patchBuffer(*m_globalData, this); 866 867 if (needsStubLink) { 868 for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) { 869 if (iter->to) 870 patchBuffer.link(iter->from, FunctionPtr(iter->to)); 871 } 872 } 873 874 // Use the patch information to link the failure cases back to the original slow case routine. 875 CodeLocationLabel lastProtoBegin = CodeLocationLabel(prototypeStructures->list[currentIndex - 1].stubRoutine.code()); 876 877 patchBuffer.link(bucketsOfFail, lastProtoBegin); 878 879 // On success return back to the hot patch code, at a point it will perform the store to dest for us. 880 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult)); 881 882 CodeRef stubRoutine = patchBuffer.finalizeCode(); 883 884 // Track the stub we have created so that it will be deleted later. 885 prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect); 886 887 // Finally patch the jump to slow case back in the hot path to jump here instead. 888 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); 889 RepatchBuffer repatchBuffer(m_codeBlock); 890 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code())); 891 } 892 893 void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame) 894 { 895 ASSERT(count); 896 897 JumpList bucketsOfFail; 898 899 // Check eax is an object of the right Structure. 900 bucketsOfFail.append(checkStructure(regT0, structure)); 901 902 Structure* currStructure = structure; 903 WriteBarrier<Structure>* it = chain->head(); 904 JSObject* protoObject = 0; 905 for (unsigned i = 0; i < count; ++i, ++it) { 906 protoObject = asObject(currStructure->prototypeForLookup(callFrame)); 907 currStructure = it->get(); 908 testPrototype(protoObject, bucketsOfFail); 909 } 910 ASSERT(protoObject); 911 835 912 bool needsStubLink = false; 836 913 if (slot.cachedPropertyType() == PropertySlot::Getter) { … … 855 932 856 933 LinkBuffer patchBuffer(*m_globalData, this); 857 858 if (needsStubLink) {859 for (Vector<CallRecord>::iterator iter = m_calls.begin(); iter != m_calls.end(); ++iter) {860 if (iter->to)861 patchBuffer.link(iter->from, FunctionPtr(iter->to));862 }863 }864 865 // Use the patch information to link the failure cases back to the original slow case routine.866 CodeLocationLabel lastProtoBegin = CodeLocationLabel(prototypeStructures->list[currentIndex - 1].stubRoutine.code());867 868 patchBuffer.link(bucketsOfFail, lastProtoBegin);869 870 // On success return back to the hot patch code, at a point it will perform the store to dest for us.871 patchBuffer.link(success, stubInfo->hotPathBegin.labelAtOffset(patchOffsetGetByIdPutResult));872 873 CodeRef stubRoutine = patchBuffer.finalizeCode();874 875 // Track the stub we have created so that it will be deleted later.876 prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain);877 878 // Finally patch the jump to slow case back in the hot path to jump here instead.879 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase);880 RepatchBuffer repatchBuffer(m_codeBlock);881 repatchBuffer.relink(jumpLocation, CodeLocationLabel(stubRoutine.code()));882 }883 884 void JIT::privateCompileGetByIdChain(StructureStubInfo* stubInfo, Structure* structure, StructureChain* chain, size_t count, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame)885 {886 ASSERT(count);887 888 JumpList bucketsOfFail;889 890 // Check eax is an object of the right Structure.891 bucketsOfFail.append(checkStructure(regT0, structure));892 893 Structure* currStructure = structure;894 WriteBarrier<Structure>* it = chain->head();895 JSObject* protoObject = 0;896 for (unsigned i = 0; i < count; ++i, ++it) {897 protoObject = asObject(currStructure->prototypeForLookup(callFrame));898 currStructure = it->get();899 testPrototype(protoObject, bucketsOfFail);900 }901 ASSERT(protoObject);902 903 bool needsStubLink = false;904 if (slot.cachedPropertyType() == PropertySlot::Getter) {905 needsStubLink = true;906 compileGetDirectOffset(protoObject, regT1, cachedOffset);907 JITStubCall stubCall(this, cti_op_get_by_id_getter_stub);908 stubCall.addArgument(regT1);909 stubCall.addArgument(regT0);910 stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));911 stubCall.call();912 } else if (slot.cachedPropertyType() == PropertySlot::Custom) {913 needsStubLink = true;914 JITStubCall stubCall(this, cti_op_get_by_id_custom_stub);915 stubCall.addArgument(TrustedImmPtr(protoObject));916 stubCall.addArgument(TrustedImmPtr(FunctionPtr(slot.customGetter()).executableAddress()));917 stubCall.addArgument(TrustedImmPtr(const_cast<Identifier*>(&ident)));918 stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress()));919 stubCall.call();920 } else921 compileGetDirectOffset(protoObject, regT0, cachedOffset);922 Jump success = jump();923 924 LinkBuffer patchBuffer(*m_globalData, this);925 934 926 935 if (needsStubLink) { -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r96238 r96527 701 701 Jump failureCase = checkStructure(regT0, structure); 702 702 bool needsStubLink = false; 703 bool isDirect = false; 703 704 if (slot.cachedPropertyType() == PropertySlot::Getter) { 704 705 needsStubLink = true; … … 717 718 stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress())); 718 719 stubCall.call(); 719 } else 720 } else { 721 isDirect = true; 720 722 compileGetDirectOffset(regT0, regT1, regT0, cachedOffset); 723 } 721 724 722 725 Jump success = jump(); … … 741 744 CodeRef stubRoutine = patchBuffer.finalizeCode(); 742 745 743 polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubRoutine, structure );746 polymorphicStructures->list[currentIndex].set(*m_globalData, m_codeBlock->ownerExecutable(), stubRoutine, structure, isDirect); 744 747 745 748 // Finally patch the jump to slow case back in the hot path to jump here instead. … … 765 768 766 769 bool needsStubLink = false; 770 bool isDirect = false; 767 771 if (slot.cachedPropertyType() == PropertySlot::Getter) { 768 772 needsStubLink = true; … … 781 785 stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress())); 782 786 stubCall.call(); 783 } else 787 } else { 788 isDirect = true; 784 789 compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); 790 } 785 791 786 792 Jump success = jump(); … … 803 809 CodeRef stubRoutine = patchBuffer.finalizeCode(); 804 810 805 prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, prototypeStructure );811 prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, prototypeStructure, isDirect); 806 812 807 813 // Finally patch the jump to slow case back in the hot path to jump here instead. … … 832 838 833 839 bool needsStubLink = false; 840 bool isDirect = false; 834 841 if (slot.cachedPropertyType() == PropertySlot::Getter) { 835 842 needsStubLink = true; … … 848 855 stubCall.addArgument(TrustedImmPtr(stubInfo->callReturnLocation.executableAddress())); 849 856 stubCall.call(); 850 } else 857 } else { 858 isDirect = true; 851 859 compileGetDirectOffset(protoObject, regT1, regT0, cachedOffset); 860 } 852 861 853 862 Jump success = jump(); … … 871 880 872 881 // Track the stub we have created so that it will be deleted later. 873 prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain );882 prototypeStructures->list[currentIndex].set(callFrame->globalData(), m_codeBlock->ownerExecutable(), stubRoutine, structure, chain, isDirect); 874 883 875 884 // Finally patch the jump to slow case back in the hot path to jump here instead. -
trunk/Source/JavaScriptCore/jit/JITStubs.cpp
r96164 r96527 1699 1699 if (stubInfo->accessType == access_get_by_id_self) { 1700 1700 ASSERT(!stubInfo->stubRoutine); 1701 polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), MacroAssemblerCodeRef(), stubInfo->u.getByIdSelf.baseObjectStructure.get() );1701 polymorphicStructureList = new PolymorphicAccessStructureList(callFrame->globalData(), codeBlock->ownerExecutable(), MacroAssemblerCodeRef(), stubInfo->u.getByIdSelf.baseObjectStructure.get(), true); 1702 1702 stubInfo->initGetByIdSelfList(polymorphicStructureList, 1); 1703 1703 } else { … … 1724 1724 switch (stubInfo->accessType) { 1725 1725 case access_get_by_id_proto: 1726 prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get() );1726 prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure.get(), stubInfo->u.getByIdProto.prototypeStructure.get(), true); 1727 1727 stubInfo->stubRoutine = MacroAssemblerCodeRef(); 1728 1728 stubInfo->initGetByIdProtoList(prototypeStructureList, 2); 1729 1729 break; 1730 1730 case access_get_by_id_chain: 1731 prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get() );1731 prototypeStructureList = new PolymorphicAccessStructureList(globalData, owner, stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure.get(), stubInfo->u.getByIdChain.chain.get(), true); 1732 1732 stubInfo->stubRoutine = MacroAssemblerCodeRef(); 1733 1733 stubInfo->initGetByIdProtoList(prototypeStructureList, 2);
Note: See TracChangeset
for help on using the changeset viewer.