Changeset 158681 in webkit
- Timestamp:
- Nov 5, 2013 10:56:06 AM (11 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r158680 r158681 1 2013-11-04 Filip Pizlo <fpizlo@apple.com> 2 3 FTL should support PutById 4 https://bugs.webkit.org/show_bug.cgi?id=123784 5 6 Reviewed by Geoffrey Garen. 7 8 * ftl/FTLAbbreviations.h: 9 (JSC::FTL::buildCall): 10 * ftl/FTLCapabilities.cpp: 11 (JSC::FTL::canCompile): 12 * ftl/FTLCompile.cpp: 13 (JSC::FTL::generateICFastPath): 14 (JSC::FTL::fixFunctionBasedOnStackMaps): 15 * ftl/FTLInlineCacheDescriptor.h: 16 (JSC::FTL::InlineCacheDescriptor::InlineCacheDescriptor): 17 (JSC::FTL::GetByIdDescriptor::GetByIdDescriptor): 18 (JSC::FTL::PutByIdDescriptor::PutByIdDescriptor): 19 (JSC::FTL::PutByIdDescriptor::ecmaMode): 20 (JSC::FTL::PutByIdDescriptor::putKind): 21 * ftl/FTLIntrinsicRepository.h: 22 * ftl/FTLLowerDFGToLLVM.cpp: 23 (JSC::FTL::LowerDFGToLLVM::compileNode): 24 (JSC::FTL::LowerDFGToLLVM::compilePutById): 25 * ftl/FTLOutput.h: 26 (JSC::FTL::Output::call): 27 * ftl/FTLSlowPathCall.cpp: 28 (JSC::FTL::callOperation): 29 * ftl/FTLSlowPathCall.h: 30 * ftl/FTLState.h: 31 * jit/CCallHelpers.h: 32 (JSC::CCallHelpers::setupArguments): 33 * runtime/Executable.h: 34 (JSC::ScriptExecutable::ecmaMode): 35 1 36 2013-11-04 Filip Pizlo <fpizlo@apple.com> 2 37 -
trunk/Source/JavaScriptCore/ftl/FTLAbbreviations.h
r157872 r158681 260 260 return buildCall(builder, function, args, 6); 261 261 } 262 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7) 263 { 264 LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 }; 265 return buildCall(builder, function, args, 7); 266 } 267 static inline LValue buildCall(LBuilder builder, LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7, LValue arg8) 268 { 269 LValue args[] = { arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 }; 270 return buildCall(builder, function, args, 8); 271 } 262 272 enum TailCallMode { IsNotTailCall, IsTailCall }; 263 273 static inline void setTailCall(LValue call, TailCallMode mode) { llvm->SetTailCall(call, mode == IsTailCall); } -
trunk/Source/JavaScriptCore/ftl/FTLCapabilities.cpp
r158304 r158681 100 100 break; 101 101 case GetById: 102 case PutById: 102 103 if (node->child1().useKind() == CellUse) 103 104 break; -
trunk/Source/JavaScriptCore/ftl/FTLCompile.cpp
r158535 r158681 107 107 } 108 108 109 template<typename DescriptorType> 110 void generateICFastPath( 111 State& state, CodeBlock* codeBlock, GeneratedFunction generatedFunction, 112 StackMaps::RecordMap& recordMap, DescriptorType& ic, size_t sizeOfIC) 113 { 114 VM& vm = state.graph.m_vm; 115 116 StackMaps::RecordMap::iterator iter = recordMap.find(ic.stackmapID()); 117 if (iter == recordMap.end()) { 118 // It was optimized out. 119 return; 120 } 121 122 StackMaps::Record& record = iter->value; 123 124 CCallHelpers fastPathJIT(&vm, codeBlock); 125 ic.m_generator.generateFastPath(fastPathJIT); 126 127 char* startOfIC = 128 bitwise_cast<char*>(generatedFunction) + record.instructionOffset; 129 130 LinkBuffer linkBuffer(vm, &fastPathJIT, startOfIC, sizeOfIC); 131 // Note: we could handle the !isValid() case. We just don't appear to have a 132 // reason to do so, yet. 133 RELEASE_ASSERT(linkBuffer.isValid()); 134 135 state.finalizer->sideCodeLinkBuffer->link( 136 ic.m_slowPathDone, CodeLocationLabel(startOfIC + sizeOfIC)); 137 138 linkBuffer.link( 139 ic.m_generator.slowPathJump(), 140 state.finalizer->sideCodeLinkBuffer->locationOf(ic.m_generator.slowPathBegin())); 141 142 ic.m_generator.finalize(linkBuffer, *state.finalizer->sideCodeLinkBuffer); 143 } 144 109 145 static void fixFunctionBasedOnStackMaps( 110 146 State& state, CodeBlock* codeBlock, JITCode* jitCode, GeneratedFunction generatedFunction, … … 139 175 } 140 176 141 if (!state.getByIds.isEmpty() ) {177 if (!state.getByIds.isEmpty() || !state.putByIds.isEmpty()) { 142 178 CCallHelpers slowPathJIT(&vm, codeBlock); 143 179 … … 178 214 } 179 215 180 state.finalizer->sideCodeLinkBuffer = adoptPtr( 181 new LinkBuffer(vm, &slowPathJIT, codeBlock, JITCompilationMustSucceed)); 182 183 for (unsigned i = state.getByIds.size(); i--;) { 184 GetByIdDescriptor& getById = state.getByIds[i]; 185 186 StackMaps::RecordMap::iterator iter = recordMap.find(getById.stackmapID()); 216 for (unsigned i = state.putByIds.size(); i--;) { 217 PutByIdDescriptor& putById = state.putByIds[i]; 218 219 StackMaps::RecordMap::iterator iter = recordMap.find(putById.stackmapID()); 187 220 if (iter == recordMap.end()) { 188 221 // It was optimized out. … … 191 224 192 225 StackMaps::Record& record = iter->value; 193 194 CCallHelpers fastPathJIT(&vm, codeBlock); 195 getById.m_generator.generateFastPath(fastPathJIT); 196 197 char* startOfIC = 198 bitwise_cast<char*>(generatedFunction) + record.instructionOffset; 199 size_t sizeOfIC = sizeOfGetById(); 200 201 LinkBuffer linkBuffer(vm, &fastPathJIT, startOfIC, sizeOfIC); 202 // Note: we could handle the !isValid() case. We just don't appear to have a 203 // reason to do so, yet. 204 RELEASE_ASSERT(linkBuffer.isValid()); 205 206 state.finalizer->sideCodeLinkBuffer->link( 207 getById.m_slowPathDone, CodeLocationLabel(startOfIC + sizeOfIC)); 208 209 linkBuffer.link( 210 getById.m_generator.slowPathJump(), 211 state.finalizer->sideCodeLinkBuffer->locationOf(getById.m_generator.slowPathBegin())); 212 213 getById.m_generator.finalize(linkBuffer, *state.finalizer->sideCodeLinkBuffer); 226 227 UNUSED_PARAM(record); // FIXME: use AnyRegs. 228 229 // FIXME: LLVM should tell us which registers are live. 230 RegisterSet usedRegisters = RegisterSet::allRegisters(); 231 232 GPRReg callFrameRegister = GPRInfo::argumentGPR0; 233 GPRReg base = GPRInfo::argumentGPR1; 234 GPRReg value = GPRInfo::argumentGPR2; 235 236 JITPutByIdGenerator gen( 237 codeBlock, putById.codeOrigin(), usedRegisters, JSValueRegs(base), 238 JSValueRegs(value), GPRInfo::argumentGPR3, false, putById.ecmaMode(), 239 putById.putKind()); 240 241 MacroAssembler::Label begin = slowPathJIT.label(); 242 243 MacroAssembler::Call call = callOperation( 244 state, usedRegisters, slowPathJIT, gen.slowPathFunction(), callFrameRegister, 245 gen.stubInfo(), value, base, putById.uid()); 246 247 gen.reportSlowPathCall(begin, call); 248 249 putById.m_slowPathDone = slowPathJIT.jump(); 250 putById.m_generator = gen; 251 } 252 253 state.finalizer->sideCodeLinkBuffer = adoptPtr( 254 new LinkBuffer(vm, &slowPathJIT, codeBlock, JITCompilationMustSucceed)); 255 256 for (unsigned i = state.getByIds.size(); i--;) { 257 generateICFastPath( 258 state, codeBlock, generatedFunction, recordMap, state.getByIds[i], 259 sizeOfGetById()); 260 } 261 for (unsigned i = state.putByIds.size(); i--;) { 262 generateICFastPath( 263 state, codeBlock, generatedFunction, recordMap, state.putByIds[i], 264 sizeOfPutById()); 214 265 } 215 266 } -
trunk/Source/JavaScriptCore/ftl/FTLInlineCacheDescriptor.h
r157872 r158681 40 40 InlineCacheDescriptor() { } 41 41 42 MacroAssembler::Jump m_slowPathDone; 43 }; 44 45 class GetByIdDescriptor : public InlineCacheDescriptor { 46 public: 47 GetByIdDescriptor() { } 48 49 GetByIdDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid) 42 InlineCacheDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid) 50 43 : m_stackmapID(stackmapID) 51 44 , m_codeOrigin(codeOrigin) … … 62 55 CodeOrigin m_codeOrigin; 63 56 StringImpl* m_uid; 57 58 public: 59 MacroAssembler::Jump m_slowPathDone; 60 }; 64 61 62 class GetByIdDescriptor : public InlineCacheDescriptor { 65 63 public: 64 GetByIdDescriptor() { } 65 66 GetByIdDescriptor(unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid) 67 : InlineCacheDescriptor(stackmapID, codeOrigin, uid) 68 { 69 } 70 66 71 JITGetByIdGenerator m_generator; 72 }; 73 74 class PutByIdDescriptor : public InlineCacheDescriptor { 75 public: 76 PutByIdDescriptor() { } 77 78 PutByIdDescriptor( 79 unsigned stackmapID, CodeOrigin codeOrigin, StringImpl* uid, 80 ECMAMode ecmaMode, PutKind putKind) 81 : InlineCacheDescriptor(stackmapID, codeOrigin, uid) 82 , m_ecmaMode(ecmaMode) 83 , m_putKind(putKind) 84 { 85 } 86 87 JITPutByIdGenerator m_generator; 88 89 ECMAMode ecmaMode() const { return m_ecmaMode; } 90 PutKind putKind() const { return m_putKind; } 91 92 private: 93 ECMAMode m_ecmaMode; 94 PutKind m_putKind; 67 95 }; 68 96 -
trunk/Source/JavaScriptCore/ftl/FTLIntrinsicRepository.h
r158535 r158681 46 46 macro(subWithOverflow64, "llvm.ssub.with.overflow.i64", functionType(structType(m_context, int64, boolean), int64, int64)) \ 47 47 macro(patchpointInt64, "llvm.experimental.patchpoint.i64", functionType(int64, int32, int32, ref8, int32, Variadic)) \ 48 macro(patchpointVoid, "llvm.experimental.patchpoint.void", functionType(voidType, int32, int32, ref8, int32, Variadic)) \ 48 49 macro(stackmap, "llvm.experimental.stackmap", functionType(voidType, int32, int32, Variadic)) \ 49 50 macro(trap, "llvm.trap", functionType(voidType)) \ -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r158535 r158681 344 344 compileGetById(); 345 345 break; 346 case PutById: 347 compilePutById(); 348 break; 346 349 case GetButterfly: 347 350 compileGetButterfly(); … … 1258 1261 1259 1262 m_ftlState.getByIds.append(GetByIdDescriptor(stackmapID, m_node->codeOrigin, uid)); 1263 } 1264 1265 void compilePutById() 1266 { 1267 // See above; CellUse is easier so we do only that for now. 1268 ASSERT(m_node->child1().useKind() == CellUse); 1269 1270 LValue base = lowCell(m_node->child1()); 1271 LValue value = lowJSValue(m_node->child2()); 1272 StringImpl* uid = m_graph.identifiers()[m_node->identifierNumber()]; 1273 1274 // Arguments: id, bytes, target, numArgs, args... 1275 unsigned stackmapID = m_stackmapIDs++; 1276 m_out.call( 1277 m_out.patchpointVoidIntrinsic(), 1278 m_out.constInt32(stackmapID), m_out.constInt32(sizeOfPutById()), 1279 constNull(m_out.ref8), m_out.constInt32(3), m_callFrame, base, value); 1280 1281 m_ftlState.putByIds.append(PutByIdDescriptor( 1282 stackmapID, m_node->codeOrigin, uid, 1283 m_graph.executableFor(m_node->codeOrigin)->ecmaMode(), 1284 m_node->op() == PutByIdDirect ? Direct : NotDirect)); 1260 1285 } 1261 1286 -
trunk/Source/JavaScriptCore/ftl/FTLOutput.h
r157872 r158681 351 351 LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5); } 352 352 LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5, arg6); } 353 LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5, arg6, arg7); } 354 LValue call(LValue function, LValue arg1, LValue arg2, LValue arg3, LValue arg4, LValue arg5, LValue arg6, LValue arg7, LValue arg8) { return buildCall(m_builder, function, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); } 353 355 354 356 template<typename FunctionType> -
trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.cpp
r157872 r158681 101 101 ~CallContext() 102 102 { 103 m_jit.move(GPRInfo::returnValueGPR, m_returnRegister); 103 if (m_returnRegister != InvalidGPRReg) 104 m_jit.move(GPRInfo::returnValueGPR, m_returnRegister); 104 105 105 106 for (unsigned i = std::min(NUMBER_OF_ARGUMENT_REGISTERS, m_numArgs); i--;) { … … 164 165 } 165 166 167 MacroAssembler::Call callOperation( 168 State& state, const RegisterSet& usedRegisters, CCallHelpers& jit, 169 V_JITOperation_ESsiJJI operation, GPRReg callFrameRegister, 170 StructureStubInfo* stubInfo, GPRReg value, GPRReg object, StringImpl* uid) 171 { 172 CallContext context(state, usedRegisters, jit, 5, InvalidGPRReg); 173 jit.setupArguments( 174 callFrameRegister, CCallHelpers::TrustedImmPtr(stubInfo), value, object, 175 CCallHelpers::TrustedImmPtr(uid)); 176 return context.makeCall(bitwise_cast<void*>(operation)); 177 // FIXME: FTL should support exceptions. 178 // https://bugs.webkit.org/show_bug.cgi?id=113622 179 } 180 166 181 } } // namespace JSC::FTL 167 182 -
trunk/Source/JavaScriptCore/ftl/FTLSlowPathCall.h
r157872 r158681 60 60 GPRReg result, GPRReg callFrameRegister, StructureStubInfo*, GPRReg object, 61 61 StringImpl* uid); 62 MacroAssembler::Call callOperation( 63 State&, const RegisterSet&, CCallHelpers&, V_JITOperation_ESsiJJI, 64 GPRReg callFrameRegister, StructureStubInfo*, GPRReg value, GPRReg object, 65 StringImpl* uid); 62 66 63 67 } } // namespace JSC::FTL -
trunk/Source/JavaScriptCore/ftl/FTLState.h
r157872 r158681 59 59 JITFinalizer* finalizer; 60 60 SegmentedVector<GetByIdDescriptor> getByIds; 61 SegmentedVector<PutByIdDescriptor> putByIds; 61 62 Vector<CString> codeSectionNames; 62 63 Vector<CString> dataSectionNames; -
trunk/Source/JavaScriptCore/jit/CCallHelpers.h
r157872 r158681 914 914 } 915 915 916 ALWAYS_INLINE void setupArguments(GPRReg arg1, TrustedImmPtr arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5) 917 { 918 setupThreeStubArgsGPR<GPRInfo::argumentGPR0, GPRInfo::argumentGPR2, GPRInfo::argumentGPR3>(arg1, arg3, arg4); 919 move(arg2, GPRInfo::argumentGPR1); 920 move(arg5, GPRInfo::argumentGPR4); 921 } 922 916 923 ALWAYS_INLINE void setupArguments(TrustedImmPtr arg1) 917 924 { -
trunk/Source/JavaScriptCore/runtime/Executable.h
r154986 r158681 384 384 bool needsActivation() const { return m_hasCapturedVariables || m_features & (EvalFeature | WithFeature | CatchFeature); } 385 385 bool isStrictMode() const { return m_features & StrictModeFeature; } 386 ECMAMode ecmaMode() const { return isStrictMode() ? StrictMode : NotStrictMode; } 386 387 387 388 void setNeverInline(bool value) { m_neverInline = value; }
Note: See TracChangeset
for help on using the changeset viewer.