Changeset 64938 in webkit
- Timestamp:
- Aug 7, 2010 11:04:59 PM (14 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 1 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/Android.mk
r64849 r64938 53 53 jit/JITCall.cpp \ 54 54 jit/JITCall32_64.cpp \ 55 jit/JITMarkObjects.cpp \ 55 56 jit/JITOpcodes.cpp \ 56 57 jit/JITPropertyAccess.cpp \ -
trunk/JavaScriptCore/CMakeLists.txt
r64866 r64938 56 56 jit/JITCall.cpp 57 57 jit/JIT.cpp 58 jit/JITMarkObjects.cpp 58 59 jit/JITOpcodes32_64.cpp 59 60 jit/JITOpcodes.cpp -
trunk/JavaScriptCore/ChangeLog
r64937 r64938 1 2010-08-07 Nathan Lawrence <nlawrence@apple.com> 2 3 Reviewed by Geoffrey Garen. 4 5 The JIT code contains a number of direct references to GC'd objects. 6 When we have movable objects, these references will need to be 7 updated. 8 9 * Android.mk: 10 * CMakeLists.txt: 11 * GNUmakefile.am: 12 * JavaScriptCore.gypi: 13 * JavaScriptCore.pro: 14 * JavaScriptCore.xcodeproj/project.pbxproj: 15 * assembler/AbstractMacroAssembler.h: 16 (JSC::AbstractMacroAssembler::int32AtLocation): 17 (JSC::AbstractMacroAssembler::pointerAtLocation): 18 (JSC::AbstractMacroAssembler::jumpTarget): 19 * assembler/MacroAssembler.h: 20 (JSC::MacroAssembler::loadPtrWithPatch): 21 Normally, loadPtr will optimize when the register is eax. Since 22 the slightly smaller instruction changes the offsets, it messes up 23 our ability to repatch the code. We added this new instruction 24 that garuntees a constant size. 25 * assembler/MacroAssemblerX86.h: 26 (JSC::MacroAssemblerX86::load32WithPatch): 27 Changed load32 in the same way described above. 28 (JSC::MacroAssemblerX86::load32): 29 Moved the logic to optimize laod32 from movl_mr to load32 30 (JSC::MacroAssemblerX86::store32): 31 Moved the logic to optimize store32 from movl_rm to store32 32 * assembler/X86Assembler.h: 33 (JSC::X86Assembler::movl_rm): 34 (JSC::X86Assembler::movl_mr): 35 (JSC::X86Assembler::int32AtLocation): 36 (JSC::X86Assembler::pointerAtLocation): 37 (JSC::X86Assembler::jumpTarget): 38 * bytecode/CodeBlock.cpp: 39 (JSC::CodeBlock::markAggregate): 40 * bytecode/Instruction.h: 41 As described in StructureStubInfo.h, we needed to add additional 42 fields to both StructureStubInfo and 43 PolymorphicAccessStructureList so that we can determine the 44 structure of the JITed code at patch time. 45 (JSC::PolymorphicAccessStructureList::PolymorphicStubInfo::set): 46 (JSC::PolymorphicAccessStructureList::PolymorphicAccessStructureList): 47 * bytecode/StructureStubInfo.cpp: 48 (JSC::StructureStubInfo::markAggregate): 49 Added this function to mark the JITed code that correosponds to 50 this structure stub info. 51 * bytecode/StructureStubInfo.h: 52 (JSC::StructureStubInfo::initGetByIdProto): 53 (JSC::StructureStubInfo::initGetByIdChain): 54 (JSC::StructureStubInfo::): 55 * jit/JIT.h: 56 * jit/JITMarkObjects.cpp: Added. 57 (JSC::JIT::patchPrototypeStructureAddress): 58 (JSC::JIT::patchGetDirectOffset): 59 (JSC::JIT::markGetByIdProto): 60 (JSC::JIT::markGetByIdChain): 61 (JSC::JIT::markGetByIdProtoList): 62 (JSC::JIT::markPutByIdTransition): 63 (JSC::JIT::markGlobalObjectReference): 64 * jit/JITPropertyAccess.cpp: 65 Added asserts for the patch offsets. 66 (JSC::JIT::compileGetDirectOffset): 67 (JSC::JIT::testPrototype): 68 (JSC::JIT::privateCompilePutByIdTransition): 69 (JSC::JIT::privateCompileGetByIdProto): 70 (JSC::JIT::privateCompileGetByIdProtoList): 71 (JSC::JIT::privateCompileGetByIdChainList): 72 (JSC::JIT::privateCompileGetByIdChain): 73 * jit/JITPropertyAccess32_64.cpp: 74 (JSC::JIT::compileGetDirectOffset): 75 (JSC::JIT::testPrototype): 76 (JSC::JIT::privateCompilePutByIdTransition): 77 (JSC::JIT::privateCompileGetByIdProto): 78 (JSC::JIT::privateCompileGetByIdProtoList): 79 (JSC::JIT::privateCompileGetByIdChainList): 80 (JSC::JIT::privateCompileGetByIdChain): 81 * jit/JITStubs.cpp: 82 (JSC::setupPolymorphicProtoList): 83 * wtf/Platform.h: 84 Added ENABLE_MOVABLE_GC_OBJECTS flag 85 1 86 2010-08-07 Michael Saboff <msaboff@apple.com> 2 87 -
trunk/JavaScriptCore/GNUmakefile.am
r64849 r64938 166 166 JavaScriptCore/jit/JIT.h \ 167 167 JavaScriptCore/jit/JITInlineMethods.h \ 168 JavaScriptCore/jit/JITMarkObjects.cpp \ 168 169 JavaScriptCore/jit/JITOpcodes32_64.cpp \ 169 170 JavaScriptCore/jit/JITOpcodes.cpp \ -
trunk/JavaScriptCore/JavaScriptCore.gypi
r64849 r64938 119 119 'jit/JITCode.h', 120 120 'jit/JITInlineMethods.h', 121 'jit/JITMarkObjects.cpp', 121 122 'jit/JITOpcodes.cpp', 122 123 'jit/JITOpcodes32_64.cpp', -
trunk/JavaScriptCore/JavaScriptCore.pro
r64849 r64938 101 101 jit/JITCall32_64.cpp \ 102 102 jit/JIT.cpp \ 103 jit/JITMarkObjects.cpp \ 103 104 jit/JITOpcodes.cpp \ 104 105 jit/JITOpcodes32_64.cpp \ -
trunk/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.vcproj
r64854 r64938 1690 1690 </File> 1691 1691 <File 1692 RelativePath="..\..\jit\JITMarkObjects.cpp" 1693 > 1694 <File 1692 1695 RelativePath="..\..\jit\JITOpcodes.cpp" 1693 1696 > -
trunk/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r64861 r64938 510 510 BCFD8C930EEB2EE700283848 /* JumpTable.h in Headers */ = {isa = PBXBuildFile; fileRef = BCFD8C910EEB2EE700283848 /* JumpTable.h */; }; 511 511 C0A272630E50A06300E96E15 /* NotFound.h in Headers */ = {isa = PBXBuildFile; fileRef = C0A2723F0E509F1E00E96E15 /* NotFound.h */; settings = {ATTRIBUTES = (Private, ); }; }; 512 DD23669811DBB22D00AF47C8 /* JITMarkObjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD23669711DBB22D00AF47C8 /* JITMarkObjects.cpp */; }; 512 513 DD2724681208D1FF00F9ABE7 /* AlignedMemoryAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = DD2724671208D1FF00F9ABE7 /* AlignedMemoryAllocator.h */; }; 513 514 DD2724691208D1FF00F9ABE7 /* AlignedMemoryAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = DD2724671208D1FF00F9ABE7 /* AlignedMemoryAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1063 1064 D21202280AD4310C00ED79B6 /* DateConversion.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DateConversion.cpp; sourceTree = "<group>"; }; 1064 1065 D21202290AD4310C00ED79B6 /* DateConversion.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DateConversion.h; sourceTree = "<group>"; }; 1066 DD23669711DBB22D00AF47C8 /* JITMarkObjects.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITMarkObjects.cpp; sourceTree = "<group>"; }; 1065 1067 DD2724671208D1FF00F9ABE7 /* AlignedMemoryAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AlignedMemoryAllocator.h; sourceTree = "<group>"; }; 1066 1068 DD377CBB12072C18006A2517 /* Bitmap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bitmap.h; sourceTree = "<group>"; }; … … 1273 1275 isa = PBXGroup; 1274 1276 children = ( 1277 DD23669711DBB22D00AF47C8 /* JITMarkObjects.cpp */, 1275 1278 A7B48DB60EE74CFC00DCBDB6 /* ExecutableAllocator.cpp */, 1276 1279 A7B48DB50EE74CFC00DCBDB6 /* ExecutableAllocator.h */, … … 2676 2679 DDF7ABD511F60ED200108E36 /* GCActivityCallbackCF.cpp in Sources */, 2677 2680 8627E5EB11F1281900A313B5 /* PageAllocation.cpp in Sources */, 2681 DD23669811DBB22D00AF47C8 /* JITMarkObjects.cpp in Sources */, 2678 2682 DDE82AD71209D955005C1756 /* GCHandle.cpp in Sources */, 2679 2683 ); -
trunk/JavaScriptCore/assembler/AbstractMacroAssembler.h
r62306 r64938 522 522 } 523 523 524 static int32_t int32AtLocation(CodeLocationDataLabel32 dataLabel32) 525 { 526 return AssemblerType::int32AtLocation(dataLabel32.dataLocation()); 527 } 528 529 static void* pointerAtLocation(CodeLocationDataLabelPtr dataLabelPtr) 530 { 531 return AssemblerType::pointerAtLocation(dataLabelPtr.dataLocation()); 532 } 533 534 static void* jumpTarget(CodeLocationJump jump) 535 { 536 return AssemblerType::jumpTarget(jump.dataLocation()); 537 } 538 524 539 static void repatchInt32(CodeLocationDataLabel32 dataLabel32, int32_t value) 525 540 { -
trunk/JavaScriptCore/assembler/MacroAssembler.h
r57925 r64938 210 210 } 211 211 212 void loadPtrWithPatch(void* address, RegisterID dest) 213 { 214 load32WithPatch(address, dest); 215 } 212 216 213 217 void loadPtr(ImplicitAddress address, RegisterID dest) -
trunk/JavaScriptCore/assembler/MacroAssemblerX86.h
r58469 r64938 83 83 } 84 84 85 void load32WithPatch(void* address, RegisterID dest) 86 { 87 m_assembler.movl_mr(address, dest); 88 } 89 85 90 void load32(void* address, RegisterID dest) 86 91 { 87 m_assembler.movl_mr(address, dest); 92 if (dest == X86Registers::eax) 93 m_assembler.movl_mEAX(address); 94 else 95 m_assembler.movl_mr(address, dest); 88 96 } 89 97 … … 106 114 void store32(RegisterID src, void* address) 107 115 { 108 m_assembler.movl_rm(src, address); 116 if (src == X86Registers::eax) 117 m_assembler.movl_EAXm(address); 118 else 119 m_assembler.movl_rm(src, address); 109 120 } 110 121 -
trunk/JavaScriptCore/assembler/X86Assembler.h
r64608 r64938 1155 1155 void movl_rm(RegisterID src, void* addr) 1156 1156 { 1157 if (src == X86Registers::eax) 1158 movl_EAXm(addr); 1159 else 1160 m_formatter.oneByteOp(OP_MOV_EvGv, src, addr); 1157 m_formatter.oneByteOp(OP_MOV_EvGv, src, addr); 1161 1158 } 1162 1159 1163 1160 void movl_mr(void* addr, RegisterID dst) 1164 1161 { 1165 if (dst == X86Registers::eax) 1166 movl_mEAX(addr); 1167 else 1168 m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr); 1162 m_formatter.oneByteOp(OP_MOV_GvEv, dst, addr); 1169 1163 } 1170 1164 … … 1558 1552 1559 1553 setPointer(reinterpret_cast<char*>(code) + where.m_offset, value); 1554 } 1555 1556 static int32_t int32AtLocation(void* where) 1557 { 1558 return static_cast<int32_t*>(where)[-1]; 1559 } 1560 1561 static void* pointerAtLocation(void* where) 1562 { 1563 return static_cast<void**>(where)[-1]; 1564 } 1565 1566 static void* jumpTarget(void* jump) 1567 { 1568 intptr_t src = reinterpret_cast<intptr_t>(jump); 1569 int32_t offset = static_cast<int32_t*>(jump)[-1]; 1570 return reinterpret_cast<void*>(src + offset); 1560 1571 } 1561 1572 -
trunk/JavaScriptCore/bytecode/CodeBlock.cpp
r64790 r64938 1521 1521 m_functionDecls[i]->markAggregate(markStack); 1522 1522 markStack.append(m_globalObject); 1523 #if ENABLE(MOVABLE_GC_OBJECTS) 1524 // This is the code that is responsible for marking the actual pointers 1525 // to JSCell*s in the JIT'ed code. Normally, these pointers are marked 1526 // elsewhere, however when we have movable objects, we will need to update 1527 // all of the references. 1528 for (size_t i = 0; i < m_structureStubInfos.size(); ++i) 1529 m_structureStubInfos[i].markAggregate(markStack, this); 1530 #endif 1523 1531 } 1524 1532 -
trunk/JavaScriptCore/bytecode/Instruction.h
r63056 r64938 64 64 StructureChain* chain; 65 65 } u; 66 #if ENABLE(MOVABLE_GC_OBJECTS) 67 int count; 68 PropertySlot::CachedPropertyType propertyType; 69 #endif 66 70 67 71 void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base) … … 73 77 } 74 78 79 #if ENABLE(MOVABLE_GC_OBJECTS) 80 void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto, PropertySlot::CachedPropertyType _propertyType) 81 #else 75 82 void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, Structure* _proto) 83 #endif 76 84 { 77 85 stubRoutine = _stubRoutine; … … 79 87 u.proto = _proto; 80 88 isChain = false; 89 #if ENABLE(MOVABLE_GC_OBJECTS) 90 propertyType = _propertyType; 91 #endif 81 92 } 82 93 94 #if ENABLE(MOVABLE_GC_OBJECTS) 95 void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain, int _count, PropertySlot::CachedPropertyType _propertyType) 96 #else 83 97 void set(PolymorphicAccessStructureListStubRoutineType _stubRoutine, Structure* _base, StructureChain* _chain) 98 #endif 84 99 { 85 100 stubRoutine = _stubRoutine; … … 87 102 u.chain = _chain; 88 103 isChain = true; 104 #if ENABLE(MOVABLE_GC_OBJECTS) 105 count = _count; 106 propertyType = _propertyType; 107 #endif 89 108 } 90 109 } list[POLYMORPHIC_LIST_CACHE_SIZE]; … … 95 114 } 96 115 116 #if ENABLE(MOVABLE_GC_OBJECTS) 117 PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto, PropertySlot::CachedPropertyType propertyType) 118 { 119 list[0].set(stubRoutine, firstBase, firstProto, propertyType); 120 } 121 #else 97 122 PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, Structure* firstProto) 98 123 { 99 124 list[0].set(stubRoutine, firstBase, firstProto); 100 125 } 101 126 #endif 127 128 #if ENABLE(MOVABLE_GC_OBJECTS) 129 PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain, int count, PropertySlot::CachedPropertyType propertyType) 130 { 131 list[0].set(stubRoutine, firstBase, firstChain, count, propertyType); 132 } 133 #else 102 134 PolymorphicAccessStructureList(PolymorphicAccessStructureListStubRoutineType stubRoutine, Structure* firstBase, StructureChain* firstChain) 103 135 { 104 136 list[0].set(stubRoutine, firstBase, firstChain); 105 137 } 138 #endif 106 139 107 140 void derefStructures(int count) -
trunk/JavaScriptCore/bytecode/StructureStubInfo.cpp
r46879 r64938 26 26 #include "config.h" 27 27 #include "StructureStubInfo.h" 28 29 #include "JIT.h" 28 30 29 31 namespace JSC { … … 76 78 } 77 79 } 80 81 #if ENABLE(MOVABLE_GC_OBJECTS) 82 void StructureStubInfo::markAggregate(MarkStack& markStack, CodeBlock* codeBlock) 83 { 84 switch (accessType) { 85 case access_get_by_id_proto: 86 JIT::markGetByIdProto(markStack, codeBlock, this); 87 return; 88 case access_get_by_id_chain: 89 JIT::markGetByIdChain(markStack, codeBlock, this); 90 return; 91 case access_get_by_id_proto_list: 92 JIT::markGetByIdProtoList(markStack, codeBlock, this); 93 return; 94 case access_put_by_id_transition: 95 JIT::markPutByIdTransition(markStack, codeBlock, this); 96 return; 97 case access_get_by_id_self: 98 case access_get_by_id_self_list: 99 case access_put_by_id_replace: 100 case access_get_by_id: 101 case access_put_by_id: 102 case access_get_by_id_generic: 103 case access_put_by_id_generic: 104 case access_get_array_length: 105 case access_get_string_length: 106 return; 107 default: 108 ASSERT_NOT_REACHED(); 109 } 110 } 111 #endif 112 78 113 #endif 79 114 -
trunk/JavaScriptCore/bytecode/StructureStubInfo.h
r64608 r64938 31 31 #include "Instruction.h" 32 32 #include "MacroAssembler.h" 33 #include "PropertySlot.h" 33 34 #include "Opcode.h" 34 35 #include "Structure.h" … … 67 68 } 68 69 70 #if ENABLE(MOVABLE_GC_OBJECTS) 71 void initGetByIdProto(Structure* baseObjectStructure, Structure* prototypeStructure, CodeLocationLabel routine, PropertySlot::CachedPropertyType propertyType) 72 #else 69 73 void initGetByIdProto(Structure* baseObjectStructure, Structure* prototypeStructure, CodeLocationLabel routine) 74 #endif 70 75 { 71 76 accessType = access_get_by_id_proto; … … 78 83 79 84 stubRoutine = routine; 80 } 81 85 86 #if ENABLE(MOVABLE_GC_OBJECTS) 87 u.getByIdProto.propertyType = propertyType; 88 #endif 89 } 90 91 #if ENABLE(MOVABLE_GC_OBJECTS) 92 void initGetByIdChain(Structure* baseObjectStructure, StructureChain* chain, CodeLocationLabel routine, int count, PropertySlot::CachedPropertyType propertyType) 93 #else 82 94 void initGetByIdChain(Structure* baseObjectStructure, StructureChain* chain, CodeLocationLabel routine) 95 #endif 83 96 { 84 97 accessType = access_get_by_id_chain; … … 91 104 92 105 stubRoutine = routine; 106 107 #if ENABLE(MOVABLE_GC_OBJECTS) 108 u.getByIdChain.count = count; 109 u.getByIdChain.propertyType = propertyType; 110 #endif 93 111 } 94 112 … … 140 158 141 159 void deref(); 160 #if ENABLE(MOVABLE_GC_OBJECTS) 161 void markAggregate(MarkStack&, CodeBlock*); 162 #endif 142 163 143 164 bool seenOnce() … … 161 182 Structure* baseObjectStructure; 162 183 Structure* prototypeStructure; 184 #if ENABLE(MOVABLE_GC_OBJECTS) 185 // The propertyType is required to properly determine the 186 // structure of the underlying code so that we may patch it 187 // correctly. Different code is generated for different 188 // property types, and therefore, the offsets that we need to 189 // patch at will change. 190 PropertySlot::CachedPropertyType propertyType; 191 #endif 163 192 } getByIdProto; 164 193 struct { 165 194 Structure* baseObjectStructure; 166 195 StructureChain* chain; 196 #if ENABLE(MOVABLE_GC_OBJECTS) 197 // We need the count so that we can iterate over the prototype 198 // chain, marking all of the references to objects. 199 int count; 200 PropertySlot::CachedPropertyType propertyType; 201 #endif 167 202 } getByIdChain; 168 203 struct { -
trunk/JavaScriptCore/jit/JIT.h
r64649 r64938 238 238 static void patchMethodCallProto(CodeBlock* codeblock, MethodCallLinkInfo&, JSFunction*, Structure*, JSObject*, ReturnAddressPtr); 239 239 240 #if ENABLE(MOVABLE_GC_OBJECTS) 241 static void patchPrototypeStructureAddress(CodeLocationDataLabelPtr, MarkStack&, RepatchBuffer&); 242 static void patchGetDirectOffset(CodeLocationLabel, MarkStack&, RepatchBuffer&, PropertySlot::CachedPropertyType); 243 static void markGetByIdChainInternal(CodeLocationLabel, MarkStack&, RepatchBuffer&, PropertySlot::CachedPropertyType); 244 245 static void markGetByIdProto(MarkStack&, CodeBlock*, StructureStubInfo*); 246 static void markGetByIdChain(MarkStack&, CodeBlock*, StructureStubInfo*); 247 static void markGetByIdProtoList(MarkStack&, CodeBlock*, StructureStubInfo*); 248 static void markPutByIdTransition(MarkStack&, CodeBlock*, StructureStubInfo*); 249 static void markGlobalObjectReference(MarkStack&, CodeBlock*, CodeLocationDataLabelPtr); 250 #endif 251 240 252 static bool compilePatchGetArrayLength(JSGlobalData* globalData, CodeBlock* codeBlock, StructureStubInfo* stubInfo, ReturnAddressPtr returnAddress) 241 253 { … … 296 308 void emitLoadInt32ToDouble(unsigned index, FPRegisterID value); 297 309 298 void testPrototype(JSValue, JumpList& failureCases);310 unsigned testPrototype(JSValue, JumpList& failureCases); 299 311 300 312 #if USE(JSVALUE32_64) … … 367 379 static const int patchOffsetMethodCheckProtoStruct = 18; 368 380 static const int patchOffsetMethodCheckPutFunction = 29; 381 382 static const int patchOffsetGetByIdProtoStruct = 19; 383 static const int patchOffsetPutByIdProtoStruct = 12; 384 static const int patchLengthTestPrototype = 16; 385 static const int patchLengthBranchPtr = 10; 386 static const int patchLengthMove = 6; 387 static const int patchLengthStore = 10; 369 388 #elif CPU(ARM_TRADITIONAL) 370 389 // These architecture specific value are used to enable patching - see comment on op_put_by_id. … … 537 556 static const int patchOffsetMethodCheckProtoStruct = 30; 538 557 static const int patchOffsetMethodCheckPutFunction = 50; 558 559 static const int patchOffsetGetByIdProtoStruct = 40; 560 static const int patchOffsetPutByIdProtoStruct = 20; 561 static const int patchLengthTestPrototype = 29; 562 static const int patchLengthBranchPtr = 9; 563 static const int patchLengthMove = 10; 564 static const int patchLengthStore = 13; 539 565 #elif CPU(X86) 540 566 // These architecture specific value are used to enable patching - see comment on op_put_by_id. -
trunk/JavaScriptCore/jit/JITPropertyAccess.cpp
r64937 r64938 574 574 } 575 575 576 void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID result, size_t cachedOffset)576 void JIT::compileGetDirectOffset(JSObject* base, RegisterID, RegisterID result, size_t cachedOffset) 577 577 { 578 578 if (base->isUsingInlineStorage()) … … 580 580 else { 581 581 PropertyStorage* protoPropertyStorage = &base->m_externalStorage; 582 loadPtr(static_cast<void*>(protoPropertyStorage), temp);583 loadPtr(Address( temp, cachedOffset * sizeof(JSValue)), result);582 loadPtr(static_cast<void*>(protoPropertyStorage), result); 583 loadPtr(Address(result, cachedOffset * sizeof(JSValue)), result); 584 584 } 585 585 } 586 586 587 void JIT::testPrototype(JSValue prototype, JumpList& failureCases)587 unsigned JIT::testPrototype(JSValue prototype, JumpList& failureCases) 588 588 { 589 589 if (prototype.isNull()) 590 return; 591 590 return 0; 591 592 Label testPrototypeBegin(this); 592 593 // We have a special case for X86_64 here because X86 instructions that take immediate values 593 594 // only take 32 bit immediate values, wheras the pointer constants we are using here are 64 bit … … 600 601 failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(prototype)->m_structure), ImmPtr(asCell(prototype)->structure()))); 601 602 #endif 603 ASSERT_JIT_OFFSET(differenceBetween(testPrototypeBegin, Label(this)), patchLengthTestPrototype); 604 605 return patchLengthTestPrototype; 602 606 } 603 607 604 608 bool JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure* oldStructure, Structure* newStructure, size_t cachedOffset, StructureChain* chain, ReturnAddressPtr returnAddress, bool direct) 605 609 { 610 Label putByIdTransitionBegin(this); 606 611 JumpList failureCases; 607 612 // Check eax is an object of the right Structure. 608 613 failureCases.append(emitJumpIfNotJSCell(regT0)); 609 614 failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure))); 610 testPrototype(oldStructure->storedPrototype(), failureCases); 615 616 unsigned offset = patchOffsetPutByIdProtoStruct + patchLengthBranchPtr; 617 ASSERT_JIT_OFFSET(differenceBetween(putByIdTransitionBegin, Label(this)), offset); 618 619 offset += testPrototype(oldStructure->storedPrototype(), failureCases); 620 ASSERT_JIT_OFFSET(differenceBetween(putByIdTransitionBegin, Label(this)), offset); 611 621 612 622 // ecx = baseObject->m_structure 613 623 if (!direct) { 614 for (RefPtr<Structure>* it = chain->head(); *it; ++it) 615 testPrototype((*it)->storedPrototype(), failureCases); 624 for (RefPtr<Structure>* it = chain->head(); *it; ++it) { 625 offset += testPrototype((*it)->storedPrototype(), failureCases); 626 ASSERT_JIT_OFFSET(differenceBetween(putByIdTransitionBegin, Label(this)), offset); 627 } 616 628 } 617 629 … … 772 784 bool JIT::privateCompileGetByIdProto(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, ReturnAddressPtr returnAddress, CallFrame* callFrame) 773 785 { 786 Label getByIdProtoBegin(this); 774 787 // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is 775 788 // referencing the prototype object - let's speculatively load it's table nice and early!) … … 788 801 #endif 789 802 803 ASSERT_JIT_OFFSET(differenceBetween(getByIdProtoBegin, Label(this)), patchOffsetGetByIdProtoStruct + patchLengthBranchPtr); 790 804 bool needsStubLink = false; 791 805 … … 838 852 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 839 853 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list)); 854 #if ENABLE(MOVABLE_GC_OBJECTS) 855 stubInfo->initGetByIdProto(structure, prototypeStructure, entryLabel, slot.cachedPropertyType()); 856 #else 840 857 stubInfo->initGetByIdProto(structure, prototypeStructure, entryLabel); 858 #endif 841 859 return true; 842 860 } … … 909 927 bool JIT::privateCompileGetByIdProtoList(StructureStubInfo* stubInfo, Structure* structure, Structure* prototypeStructure, const Identifier& ident, const PropertySlot& slot, size_t cachedOffset, CallFrame* callFrame) 910 928 { 929 Label getByIdProtoListBegin(this); 911 930 PolymorphicAccessStructureList* prototypeStructures = stubInfo->u.getByIdProtoList.structureList; 912 931 int currentIndex = stubInfo->u.getByIdProtoList.listSize; … … 927 946 Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure)); 928 947 #endif 948 949 ASSERT_JIT_OFFSET(differenceBetween(getByIdProtoListBegin, Label(this)), patchOffsetGetByIdProtoStruct + patchLengthBranchPtr); 929 950 930 951 // Checks out okay! … … 974 995 structure->ref(); 975 996 prototypeStructure->ref(); 997 #if ENABLE(MOVABLE_GC_OBJECTS) 998 prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure, slot.cachedPropertyType()); 999 #else 976 1000 prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure); 1001 #endif 977 1002 978 1003 // Finally patch the jump to slow case back in the hot path to jump here instead. … … 990 1015 991 1016 ASSERT(count); 1017 1018 Label getByIdChainListBegin(this); 992 1019 JumpList bucketsOfFail; 993 1020 … … 1003 1030 currStructure = it->get(); 1004 1031 testPrototype(protoObject, bucketsOfFail); 1032 ASSERT_JIT_OFFSET(differenceBetween(getByIdChainListBegin, Label(this)), 1033 patchOffsetGetByIdProtoStruct + patchLengthBranchPtr + i * patchLengthTestPrototype); 1005 1034 } 1006 1035 ASSERT(protoObject); … … 1051 1080 structure->ref(); 1052 1081 chain->ref(); 1082 #if ENABLE(MOVABLE_GC_OBJECTS) 1083 prototypeStructures->list[currentIndex].set(entryLabel, structure, chain, count, slot.cachedPropertyType()); 1084 #else 1053 1085 prototypeStructures->list[currentIndex].set(entryLabel, structure, chain); 1086 #endif 1054 1087 1055 1088 // Finally patch the jump to slow case back in the hot path to jump here instead. … … 1065 1098 ASSERT(count); 1066 1099 1100 Label getByIdChainBegin(this); 1067 1101 JumpList bucketsOfFail; 1068 1102 … … 1077 1111 currStructure = it->get(); 1078 1112 testPrototype(protoObject, bucketsOfFail); 1113 ASSERT_JIT_OFFSET(differenceBetween(getByIdChainBegin, Label(this)), 1114 patchOffsetGetByIdProtoStruct + patchLengthBranchPtr + i * patchLengthTestPrototype); 1079 1115 } 1080 1116 ASSERT(protoObject); … … 1128 1164 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 1129 1165 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list)); 1166 #if ENABLE(MOVABLE_GC_OBJECTS) 1167 stubInfo->initGetByIdChain(structure, chain, entryLabel, count, slot.cachedPropertyType()); 1168 #else 1130 1169 stubInfo->initGetByIdChain(structure, chain, entryLabel); 1170 #endif 1171 1131 1172 return true; 1132 1173 } -
trunk/JavaScriptCore/jit/JITPropertyAccess32_64.cpp
r64937 r64938 575 575 void JIT::compileGetDirectOffset(JSObject* base, RegisterID temp, RegisterID resultTag, RegisterID resultPayload, size_t cachedOffset) 576 576 { 577 Label directOffsetBegin(this); 577 578 if (base->isUsingInlineStorage()) { 578 load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload), resultPayload); 579 // On X86, load32 will optimize for a slightly smaller instruction in the case that resultPayoad is regT0 580 // Since we want this instruction to always be the same length, we use load32WithPatch to avoid this problem 581 load32WithPatch(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload), resultPayload); 582 ASSERT_JIT_OFFSET(differenceBetween(directOffsetBegin, Label(this)), patchLengthMove); 579 583 load32(reinterpret_cast<char*>(&base->m_inlineStorage[cachedOffset]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag), resultTag); 580 584 return; … … 584 588 585 589 PropertyStorage* protoPropertyStorage = &base->m_externalStorage; 586 loadPtr(static_cast<void*>(protoPropertyStorage), temp); 590 loadPtrWithPatch(static_cast<void*>(protoPropertyStorage), temp); 591 ASSERT_JIT_OFFSET(differenceBetween(directOffsetBegin, Label(this)), patchLengthMove); 587 592 load32(Address(temp, offset + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), resultPayload); 588 593 load32(Address(temp, offset + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), resultTag); 589 594 } 590 595 591 void JIT::testPrototype(JSValue prototype, JumpList& failureCases)596 unsigned JIT::testPrototype(JSValue prototype, JumpList& failureCases) 592 597 { 593 598 if (prototype.isNull()) 594 return; 595 599 return 0; 600 601 Label testPrototypeBegin(this); 596 602 // We have a special case for X86_64 here because X86 instructions that take immediate values 597 603 // only take 32 bit immediate values, wheras the pointer constants we are using here are 64 bit … … 604 610 failureCases.append(branchPtr(NotEqual, AbsoluteAddress(&asCell(prototype)->m_structure), ImmPtr(asCell(prototype)->structure()))); 605 611 #endif 612 ASSERT_JIT_OFFSET(differenceBetween(testPrototypeBegin, Label(this)), patchLengthTestPrototype); 613 614 return patchLengthTestPrototype; 606 615 } 607 616 … … 610 619 // It is assumed that regT0 contains the basePayload and regT1 contains the baseTag. The value can be found on the stack. 611 620 621 Label putByIdTransitionBegin(this); 612 622 JumpList failureCases; 613 623 failureCases.append(branch32(NotEqual, regT1, Imm32(JSValue::CellTag))); 614 624 failureCases.append(branchPtr(NotEqual, Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)), ImmPtr(oldStructure))); 615 testPrototype(oldStructure->storedPrototype(), failureCases); 625 626 int offset = patchOffsetPutByIdProtoStruct + patchLengthBranchPtr; 627 ASSERT_JIT_OFFSET(differenceBetween(putByIdTransitionBegin, Label(this)), offset); 628 629 offset += testPrototype(oldStructure->storedPrototype(), failureCases); 630 ASSERT_JIT_OFFSET(differenceBetween(putByIdTransitionBegin, Label(this)), offset); 616 631 617 632 if (!direct) { 618 633 // Verify that nothing in the prototype chain has a setter for this property. 619 for (RefPtr<Structure>* it = chain->head(); *it; ++it) 620 testPrototype((*it)->storedPrototype(), failureCases); 634 for (RefPtr<Structure>* it = chain->head(); *it; ++it) { 635 offset += testPrototype((*it)->storedPrototype(), failureCases); 636 ASSERT_JIT_OFFSET(differenceBetween(putByIdTransitionBegin, Label(this)), offset); 637 } 621 638 } 622 639 623 640 // Reallocate property storage if needed. 624 641 Call callTarget; … … 783 800 // regT0 holds a JSCell* 784 801 802 Label getByIdProtoBegin(this); 785 803 // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is 786 804 // referencing the prototype object - let's speculatively load it's table nice and early!) … … 797 815 Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure)); 798 816 #endif 817 ASSERT_JIT_OFFSET(differenceBetween(getByIdProtoBegin, Label(this)), patchOffsetGetByIdProtoStruct + patchLengthBranchPtr); 818 799 819 bool needsStubLink = false; 800 820 // Checks out okay! … … 849 869 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 850 870 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list)); 871 #if ENABLE(MOVABLE_GC_OBJECTS) 872 stubInfo->initGetByIdProto(structure, prototypeStructure, entryLabel, slot.cachedPropertyType()); 873 #else 851 874 stubInfo->initGetByIdProto(structure, prototypeStructure, entryLabel); 875 #endif 852 876 return true; 853 877 } … … 927 951 // regT0 holds a JSCell* 928 952 953 Label getByIdProtoListBegin(this); 929 954 // The prototype object definitely exists (if this stub exists the CodeBlock is referencing a Structure that is 930 955 // referencing the prototype object - let's speculatively load it's table nice and early!) … … 942 967 Jump failureCases2 = branchPtr(NotEqual, AbsoluteAddress(prototypeStructureAddress), ImmPtr(prototypeStructure)); 943 968 #endif 969 ASSERT_JIT_OFFSET(differenceBetween(getByIdProtoListBegin, Label(this)), patchOffsetGetByIdProtoStruct + patchLengthBranchPtr); 944 970 945 971 bool needsStubLink = false; … … 962 988 } else 963 989 compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); 964 990 965 991 Jump success = jump(); 966 992 … … 987 1013 structure->ref(); 988 1014 prototypeStructure->ref(); 1015 #if ENABLE(MOVABLE_GC_OBJECTS) 1016 prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure, slot.cachedPropertyType()); 1017 #else 989 1018 prototypeStructures->list[currentIndex].set(entryLabel, structure, prototypeStructure); 990 1019 #endif 1020 991 1021 // Finally patch the jump to slow case back in the hot path to jump here instead. 992 1022 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); … … 1005 1035 ASSERT(count); 1006 1036 1037 Label getByIdChainListBegin(this); 1007 1038 JumpList bucketsOfFail; 1008 1039 … … 1017 1048 currStructure = it->get(); 1018 1049 testPrototype(protoObject, bucketsOfFail); 1050 1051 ASSERT_JIT_OFFSET(differenceBetween(getByIdChainListBegin, Label(this)), 1052 patchOffsetGetByIdProtoStruct + patchLengthBranchPtr + static_cast<int>(i) * patchLengthTestPrototype); 1019 1053 } 1020 1054 ASSERT(protoObject); … … 1039 1073 } else 1040 1074 compileGetDirectOffset(protoObject, regT2, regT1, regT0, cachedOffset); 1041 1075 1042 1076 Jump success = jump(); 1043 1077 … … 1065 1099 structure->ref(); 1066 1100 chain->ref(); 1101 #if ENABLE(MOVABLE_GC_OBJECTS) 1102 prototypeStructures->list[currentIndex].set(entryLabel, structure, chain, count, slot.cachedPropertyType()); 1103 #else 1067 1104 prototypeStructures->list[currentIndex].set(entryLabel, structure, chain); 1068 1105 #endif 1106 1069 1107 // Finally patch the jump to slow case back in the hot path to jump here instead. 1070 1108 CodeLocationJump jumpLocation = stubInfo->hotPathBegin.jumpAtOffset(patchOffsetGetByIdBranchToSlowCase); … … 1080 1118 ASSERT(count); 1081 1119 1120 Label getByIdChainBegin(this); 1082 1121 JumpList bucketsOfFail; 1083 1122 … … 1092 1131 currStructure = it->get(); 1093 1132 testPrototype(protoObject, bucketsOfFail); 1133 1134 ASSERT_JIT_OFFSET(differenceBetween(getByIdChainBegin, Label(this)), 1135 patchOffsetGetByIdProtoStruct + patchLengthBranchPtr + static_cast<int>(i) * patchLengthTestPrototype); 1094 1136 } 1095 1137 ASSERT(protoObject); … … 1142 1184 // We don't want to patch more than once - in future go to cti_op_put_by_id_generic. 1143 1185 repatchBuffer.relinkCallerToFunction(returnAddress, FunctionPtr(cti_op_get_by_id_proto_list)); 1186 #if ENABLE(MOVABLE_GC_OBJECTS) 1187 stubInfo->initGetByIdChain(structure, chain, entryLabel, count, slot.cachedPropertyType()); 1188 #else 1144 1189 stubInfo->initGetByIdChain(structure, chain, entryLabel); 1190 #endif 1145 1191 return true; 1146 1192 } -
trunk/JavaScriptCore/jit/JITStubs.cpp
r64818 r64938 1598 1598 { 1599 1599 if (stubInfo->accessType == access_get_by_id_proto) 1600 #if ENABLE(MOVABLE_GC_OBJECTS) 1601 stubInfo->initGetByIdProtoList(new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure, stubInfo->u.getByIdProto.propertyType)); 1602 #else 1600 1603 stubInfo->initGetByIdProtoList(new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdProto.baseObjectStructure, stubInfo->u.getByIdProto.prototypeStructure)); 1604 #endif 1601 1605 else if (stubInfo->accessType == access_get_by_id_chain) 1606 #if ENABLE(MOVABLE_GC_OBJECTS) 1607 stubInfo->initGetByIdProtoList(new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain, stubInfo->u.getByIdChain.count, stubInfo->u.getByIdChain.propertyType)); 1608 #else 1602 1609 stubInfo->initGetByIdProtoList(new PolymorphicAccessStructureList(stubInfo->stubRoutine, stubInfo->u.getByIdChain.baseObjectStructure, stubInfo->u.getByIdChain.chain)); 1610 #endif 1603 1611 ASSERT(stubInfo->accessType == access_get_by_id_proto_list); 1604 1612 } -
trunk/JavaScriptCore/wtf/Platform.h
r64915 r64938 1083 1083 #define ENABLE_JSC_ZOMBIES 0 1084 1084 1085 #define ENABLE_MOVABLE_GC_OBJECTS 0 1086 1085 1087 /* FIXME: Eventually we should enable this for all platforms and get rid of the define. */ 1086 1088 #if PLATFORM(MAC) || PLATFORM(WIN)
Note: See TracChangeset
for help on using the changeset viewer.