Changeset 207427 in webkit
- Timestamp:
- Oct 17, 2016 1:43:43 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 16 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r207377 r207427 1 2016-10-17 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [DOMJIT] Use DOMJIT::Patchpoint in IC 4 https://bugs.webkit.org/show_bug.cgi?id=163223 5 6 Reviewed by Saam Barati. 7 8 * stress/domjit-exception-ic.js: Added. 9 (shouldBe): 10 (access): 11 * stress/domjit-exception.js: Added. 12 (shouldBe): 13 (access): 14 * stress/domjit-getter-complex-with-incorrect-object.js: Added. 15 (shouldThrow): 16 (access): 17 (i.shouldThrow): 18 * stress/domjit-getter-complex.js: Added. 19 (shouldBe): 20 (access): 21 * stress/domjit-getter-try-catch-getter-as-get-by-id-register-restoration.js: Added. 22 (assert): 23 (bar): 24 (foo): 25 1 26 2016-10-15 Saam Barati <sbarati@apple.com> 2 27 -
trunk/Source/JavaScriptCore/CMakeLists.txt
r207360 r207427 205 205 bytecode/DataFormat.cpp 206 206 bytecode/DFGExitProfile.cpp 207 bytecode/DOMJITAccessCasePatchpointParams.cpp 207 208 bytecode/DeferredCompilationCallback.cpp 208 209 bytecode/DeferredSourceDump.cpp -
trunk/Source/JavaScriptCore/ChangeLog
r207425 r207427 1 2016-10-17 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [DOMJIT] Use DOMJIT::Patchpoint in IC 4 https://bugs.webkit.org/show_bug.cgi?id=163223 5 6 Reviewed by Saam Barati. 7 8 This patch uses DOMJIT::Patchpoint to inline DOM accesses even in IC! 9 It is useful for Baseline JIT cases and GetById cases in DFG and FTL. 10 In AccessCase, we construct the environment that allows DOMJIT::Patchpoint 11 to emit code and make DOMJIT accessors inlined in IC. 12 13 To allow DOMJIT::Patchpoint to emit code, we create a mechanism to emit calls 14 required in DOMJIT::Patchpoint. This system is useful when we create the super- 15 polymorphic support[1] later. And inlining mechanism is useful even after 16 introducing super-polymorphic support since it can work even after we fire the 17 watchpoint for super-polymorphic handling. 18 19 This patch improves Dromaeo dom-traverse 8% (263.95 runs/s v.s. 244.07 runs/s). 20 21 [1]: https://bugs.webkit.org/show_bug.cgi?id=163226 22 23 * CMakeLists.txt: 24 * JavaScriptCore.xcodeproj/project.pbxproj: 25 * bytecode/DOMJITAccessCasePatchpointParams.cpp: Added. 26 (JSC::SlowPathCallGeneratorWithArguments::SlowPathCallGeneratorWithArguments): 27 (JSC::SlowPathCallGeneratorWithArguments::generateImpl): 28 (JSC::DOMJITAccessCasePatchpointParams::emitSlowPathCalls): 29 * bytecode/DOMJITAccessCasePatchpointParams.h: Copied from Source/JavaScriptCore/ftl/FTLDOMJITPatchpointParams.h. 30 (JSC::DOMJITAccessCasePatchpointParams::DOMJITAccessCasePatchpointParams): 31 (JSC::DOMJITAccessCasePatchpointParams::SlowPathCallGenerator::~SlowPathCallGenerator): 32 * bytecode/PolymorphicAccess.cpp: 33 (JSC::AccessGenerationState::liveRegistersForCall): 34 (JSC::AccessGenerationState::liveRegistersToPreserveAtExceptionHandlingCallSite): 35 (JSC::calleeSaveRegisters): 36 (JSC::AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling): 37 (JSC::AccessGenerationState::restoreLiveRegistersFromStackForCallWithThrownException): 38 (JSC::AccessGenerationState::restoreLiveRegistersFromStackForCall): 39 (JSC::AccessGenerationState::callSiteIndexForExceptionHandlingOrOriginal): 40 (JSC::AccessGenerationState::originalExceptionHandler): 41 (JSC::AccessCase::generateImpl): 42 (JSC::AccessCase::emitDOMJITGetter): 43 (JSC::PolymorphicAccess::regenerate): 44 (JSC::AccessGenerationState::preserveLiveRegistersToStackForCall): Deleted. 45 * bytecode/PolymorphicAccess.h: 46 (JSC::AccessGenerationState::SpillState::isEmpty): 47 (JSC::AccessGenerationState::setSpillStateForJSGetterSetter): 48 (JSC::AccessGenerationState::spillStateForJSGetterSetter): 49 (JSC::AccessGenerationState::liveRegistersForCall): Deleted. 50 (JSC::AccessGenerationState::numberOfStackBytesUsedForRegisterPreservation): Deleted. 51 (JSC::AccessGenerationState::liveRegistersToPreserveAtExceptionHandlingCallSite): Deleted. 52 * dfg/DFGDOMJITPatchpointParams.cpp: 53 * dfg/DFGDOMJITPatchpointParams.h: 54 * domjit/DOMJITPatchpoint.h: 55 * domjit/DOMJITPatchpointParams.h: 56 (JSC::DOMJIT::PatchpointParams::addSlowPathCall): 57 * ftl/FTLDOMJITPatchpointParams.cpp: 58 * ftl/FTLDOMJITPatchpointParams.h: 59 * jsc.cpp: 60 (WTF::DOMJITNode::checkDOMJITNode): 61 (WTF::DOMJITGetterComplex::DOMJITGetterComplex): 62 (WTF::DOMJITGetterComplex::createStructure): 63 (WTF::DOMJITGetterComplex::create): 64 (WTF::DOMJITGetterComplex::DOMJITNodeDOMJIT::DOMJITNodeDOMJIT): 65 (WTF::DOMJITGetterComplex::domJITNodeGetterSetter): 66 (WTF::DOMJITGetterComplex::finishCreation): 67 (WTF::DOMJITGetterComplex::functionEnableException): 68 (WTF::DOMJITGetterComplex::customGetter): 69 (GlobalObject::finishCreation): 70 (functionCreateDOMJITGetterComplexObject): 71 1 72 2016-10-17 Saam Barati <sbarati@apple.com> 2 73 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r207360 r207427 2115 2115 E39DA4A71B7E8B7C0084F33A /* JSModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2116 2116 E3A421431D6F58930007C617 /* PreciseJumpTargetsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A421421D6F588F0007C617 /* PreciseJumpTargetsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2117 E3BFD0BB1DAF80870065DEA2 /* DOMJITAccessCasePatchpointParams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3BFD0B91DAF807C0065DEA2 /* DOMJITAccessCasePatchpointParams.cpp */; }; 2118 E3BFD0BC1DAF808E0065DEA2 /* DOMJITAccessCasePatchpointParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E3BFD0BA1DAF807C0065DEA2 /* DOMJITAccessCasePatchpointParams.h */; }; 2117 2119 E3C08E3C1DA41B810039478F /* DOMJITPatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C08E3B1DA41B7B0039478F /* DOMJITPatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2118 2120 E3D239C81B829C1C00BBEF67 /* JSModuleEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3D239C61B829C1C00BBEF67 /* JSModuleEnvironment.cpp */; }; … … 4424 4426 E39DA4A51B7E8B7C0084F33A /* JSModuleRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleRecord.h; sourceTree = "<group>"; }; 4425 4427 E3A421421D6F588F0007C617 /* PreciseJumpTargetsInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreciseJumpTargetsInlines.h; sourceTree = "<group>"; }; 4428 E3BFD0B91DAF807C0065DEA2 /* DOMJITAccessCasePatchpointParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DOMJITAccessCasePatchpointParams.cpp; sourceTree = "<group>"; }; 4429 E3BFD0BA1DAF807C0065DEA2 /* DOMJITAccessCasePatchpointParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITAccessCasePatchpointParams.h; sourceTree = "<group>"; }; 4426 4430 E3C08E3B1DA41B7B0039478F /* DOMJITPatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITPatchpoint.h; sourceTree = "<group>"; }; 4427 4431 E3CB1E241DA7540A00FA1E56 /* DOMJITSlowPathCalls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITSlowPathCalls.h; sourceTree = "<group>"; }; … … 6825 6829 0F6FC74E196110A800E1D02D /* ComplexGetStatus.cpp */, 6826 6830 0F6FC74F196110A800E1D02D /* ComplexGetStatus.h */, 6831 E3BFD0B91DAF807C0065DEA2 /* DOMJITAccessCasePatchpointParams.cpp */, 6832 E3BFD0BA1DAF807C0065DEA2 /* DOMJITAccessCasePatchpointParams.h */, 6827 6833 62E3D5EF1B8D0B7300B868BB /* DataFormat.cpp */, 6828 6834 0F426A4A1460CD6B00131F8F /* DataFormat.h */, … … 7527 7533 86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */, 7528 7534 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */, 7535 E3BFD0BC1DAF808E0065DEA2 /* DOMJITAccessCasePatchpointParams.h in Headers */, 7529 7536 0FBDB9AD1AB0FBC6000B57E5 /* DFGCallCreateDirectArgumentsSlowPathGenerator.h in Headers */, 7530 7537 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */, … … 9423 9430 A532438B18568335002ED692 /* InspectorProtocolObjects.cpp in Sources */, 9424 9431 A50E4B6118809DD50068A46D /* InspectorRuntimeAgent.cpp in Sources */, 9432 E3BFD0BB1DAF80870065DEA2 /* DOMJITAccessCasePatchpointParams.cpp in Sources */, 9425 9433 A593CF821840377100BFCE27 /* InspectorValues.cpp in Sources */, 9426 9434 147F39CF107EC37600427A48 /* InternalFunction.cpp in Sources */, -
trunk/Source/JavaScriptCore/bytecode/DOMJITAccessCasePatchpointParams.h
r207426 r207427 26 26 #pragma once 27 27 28 #if ENABLE( FTL_JIT)28 #if ENABLE(JIT) 29 29 30 #include "B3StackmapGenerationParams.h"31 30 #include "DOMJITPatchpointParams.h" 32 31 33 namespace JSC { namespace FTL {32 namespace JSC { 34 33 35 classState;34 struct AccessGenerationState; 36 35 37 class DOMJIT PatchpointParams : public DOMJIT::PatchpointParams {36 class DOMJITAccessCasePatchpointParams : public DOMJIT::PatchpointParams { 38 37 public: 39 DOMJIT PatchpointParams(State& state, const B3::StackmapGenerationParams& params, DFG::Node* node, Box<CCallHelpers::JumpList> exceptions,Vector<DOMJIT::Value>&& regs, Vector<GPRReg>&& gpScratch, Vector<FPRReg>&& fpScratch)38 DOMJITAccessCasePatchpointParams(Vector<DOMJIT::Value>&& regs, Vector<GPRReg>&& gpScratch, Vector<FPRReg>&& fpScratch) 40 39 : DOMJIT::PatchpointParams(WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch)) 41 , m_state(state)42 , m_params(params)43 , m_node(node)44 , m_exceptions(exceptions)45 40 { 46 41 } 47 42 43 class SlowPathCallGenerator { 44 public: 45 virtual ~SlowPathCallGenerator() { } 46 virtual CCallHelpers::JumpList generate(VM&, AccessGenerationState&, const RegisterSet& usedRegistersByPatchpoint, CCallHelpers&) = 0; 47 }; 48 49 CCallHelpers::JumpList emitSlowPathCalls(VM&, AccessGenerationState&, const RegisterSet& usedRegistersByPatchpoint, CCallHelpers&); 50 48 51 private: 49 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) void addSlowPathCallImpl(CCallHelpers::JumpList, CCallHelpers&, OperationType, ResultType, std::tuple<__VA_ARGS__> args) constoverride;52 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) void addSlowPathCallImpl(CCallHelpers::JumpList, CCallHelpers&, OperationType, ResultType, std::tuple<__VA_ARGS__> args) override; 50 53 DOMJIT_SLOW_PATH_CALLS(JSC_DEFINE_CALL_OPERATIONS) 51 54 #undef JSC_DEFINE_CALL_OPERATIONS 52 53 State& m_state; 54 const B3::StackmapGenerationParams& m_params; 55 DFG::Node* m_node; 56 Box<CCallHelpers::JumpList> m_exceptions; 55 Vector<std::unique_ptr<SlowPathCallGenerator>> m_generators; 57 56 }; 58 57 59 } }58 } 60 59 61 60 #endif -
trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.cpp
r206779 r207427 32 32 #include "CCallHelpers.h" 33 33 #include "CodeBlock.h" 34 #include "DOMJITAccessCasePatchpointParams.h" 35 #include "DOMJITCallDOMPatchpoint.h" 34 36 #include "DirectArguments.h" 35 37 #include "GetterSetter.h" … … 73 75 } 74 76 75 void AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling(const RegisterSet& extra) 77 const RegisterSet& AccessGenerationState::liveRegistersForCall() 78 { 79 if (!m_calculatedRegistersForCallAndExceptionHandling) 80 calculateLiveRegistersForCallAndExceptionHandling(); 81 return m_liveRegistersForCall; 82 } 83 84 const RegisterSet& AccessGenerationState::liveRegistersToPreserveAtExceptionHandlingCallSite() 85 { 86 if (!m_calculatedRegistersForCallAndExceptionHandling) 87 calculateLiveRegistersForCallAndExceptionHandling(); 88 return m_liveRegistersToPreserveAtExceptionHandlingCallSite; 89 } 90 91 static RegisterSet calleeSaveRegisters() 92 { 93 RegisterSet result = RegisterSet::registersToNotSaveForJSCall(); 94 result.filter(RegisterSet::registersToNotSaveForCCall()); 95 return result; 96 } 97 98 const RegisterSet& AccessGenerationState::calculateLiveRegistersForCallAndExceptionHandling() 76 99 { 77 100 if (!m_calculatedRegistersForCallAndExceptionHandling) { … … 84 107 85 108 m_liveRegistersForCall = RegisterSet(m_liveRegistersToPreserveAtExceptionHandlingCallSite, allocator->usedRegisters()); 86 m_liveRegistersForCall. merge(extra);87 m_liveRegistersForCall.exclude(RegisterSet::registersToNotSaveForJSCall());88 m_liveRegistersForCall.merge(extra);89 90 } 91 92 void AccessGenerationState::preserveLiveRegistersToStackForCall(const RegisterSet& extra) 93 { 94 calculateLiveRegistersForCallAndExceptionHandling(extra);109 m_liveRegistersForCall.exclude(calleeSaveRegisters()); 110 } 111 return m_liveRegistersForCall; 112 } 113 114 auto AccessGenerationState::preserveLiveRegistersToStackForCall(const RegisterSet& extra) -> SpillState 115 { 116 RegisterSet liveRegisters = liveRegistersForCall(); 117 liveRegisters.merge(extra); 95 118 96 119 unsigned extraStackPadding = 0; 97 unsigned numberOfStackBytesUsedForRegisterPreservation = ScratchRegisterAllocator::preserveRegistersToStackForCall(*jit, liveRegistersForCall(), extraStackPadding); 98 if (m_numberOfStackBytesUsedForRegisterPreservation != std::numeric_limits<unsigned>::max()) 99 RELEASE_ASSERT(numberOfStackBytesUsedForRegisterPreservation == m_numberOfStackBytesUsedForRegisterPreservation); 100 m_numberOfStackBytesUsedForRegisterPreservation = numberOfStackBytesUsedForRegisterPreservation; 101 } 102 103 void AccessGenerationState::restoreLiveRegistersFromStackForCall(bool isGetter) 104 { 105 RegisterSet dontRestore; 106 if (isGetter) { 107 // This is the result value. We don't want to overwrite the result with what we stored to the stack. 108 // We sometimes have to store it to the stack just in case we throw an exception and need the original value. 109 dontRestore.set(valueRegs); 110 } 111 restoreLiveRegistersFromStackForCall(dontRestore); 112 } 113 114 void AccessGenerationState::restoreLiveRegistersFromStackForCallWithThrownException() 120 unsigned numberOfStackBytesUsedForRegisterPreservation = ScratchRegisterAllocator::preserveRegistersToStackForCall(*jit, liveRegisters, extraStackPadding); 121 return SpillState { 122 liveRegisters, 123 numberOfStackBytesUsedForRegisterPreservation 124 }; 125 } 126 127 void AccessGenerationState::restoreLiveRegistersFromStackForCallWithThrownException(const SpillState& spillState) 115 128 { 116 129 // Even if we're a getter, we don't want to ignore the result value like we normally do … … 120 133 // and the getter threw, we want OSR exit to see the original base value, not the result 121 134 // of the getter call. 122 RegisterSet dontRestore = liveRegistersForCall();135 RegisterSet dontRestore = spillState.spilledRegisters; 123 136 // As an optimization here, we only need to restore what is live for exception handling. 124 137 // We can construct the dontRestore set to accomplish this goal by having it contain only … … 127 140 // at the exception handler. 128 141 dontRestore.exclude(liveRegistersToPreserveAtExceptionHandlingCallSite()); 129 restoreLiveRegistersFromStackForCall( dontRestore);130 } 131 132 void AccessGenerationState::restoreLiveRegistersFromStackForCall(const RegisterSet& dontRestore)142 restoreLiveRegistersFromStackForCall(spillState, dontRestore); 143 } 144 145 void AccessGenerationState::restoreLiveRegistersFromStackForCall(const SpillState& spillState, const RegisterSet& dontRestore) 133 146 { 134 147 unsigned extraStackPadding = 0; 135 ScratchRegisterAllocator::restoreRegistersFromStackForCall(*jit, liveRegistersForCall(), dontRestore, m_numberOfStackBytesUsedForRegisterPreservation, extraStackPadding);148 ScratchRegisterAllocator::restoreRegistersFromStackForCall(*jit, spillState.spilledRegisters, dontRestore, spillState.numberOfStackBytesUsedForRegisterPreservation, extraStackPadding); 136 149 } 137 150 138 151 CallSiteIndex AccessGenerationState::callSiteIndexForExceptionHandlingOrOriginal() 139 152 { 140 RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling); 153 if (!m_calculatedRegistersForCallAndExceptionHandling) 154 calculateLiveRegistersForCallAndExceptionHandling(); 141 155 142 156 if (!m_calculatedCallSiteIndex) { … … 152 166 } 153 167 154 const HandlerInfo& AccessGenerationState::originalExceptionHandler() const 155 { 168 const HandlerInfo& AccessGenerationState::originalExceptionHandler() 169 { 170 if (!m_calculatedRegistersForCallAndExceptionHandling) 171 calculateLiveRegistersForCallAndExceptionHandling(); 172 156 173 RELEASE_ASSERT(m_needsToRestoreRegistersIfException); 157 174 HandlerInfo* exceptionHandler = jit->codeBlock()->handlerForIndex(stubInfo->callSiteIndex.bits()); … … 933 950 } 934 951 952 if (m_type == CustomAccessorGetter && m_rareData->domJIT) { 953 // We do not need to emit CheckDOM operation since structure check ensures 954 // that the structure of the given base value is structure()! So all we should 955 // do is performing the CheckDOM thingy in IC compiling time here. 956 if (structure()->classInfo()->isSubClassOf(m_rareData->domJIT->thisClassInfo())) { 957 emitDOMJITGetter(state, baseForGetGPR); 958 return; 959 } 960 } 961 935 962 // Stuff for custom getters/setters. 936 963 CCallHelpers::Call operationCall; … … 941 968 CCallHelpers::Call slowPathCall; 942 969 943 CCallHelpers::Jump success;944 CCallHelpers::Jump fail;945 946 970 // This also does the necessary calculations of whether or not we're an 947 971 // exception handling call site. 948 state.preserveLiveRegistersToStackForCall(); 972 AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall(); 973 974 auto restoreLiveRegistersFromStackForCall = [&](AccessGenerationState::SpillState& spillState, bool callHasReturnValue) { 975 RegisterSet dontRestore; 976 if (callHasReturnValue) { 977 // This is the result value. We don't want to overwrite the result with what we stored to the stack. 978 // We sometimes have to store it to the stack just in case we throw an exception and need the original value. 979 dontRestore.set(valueRegs); 980 } 981 state.restoreLiveRegistersFromStackForCall(spillState, dontRestore); 982 }; 949 983 950 984 jit.store32( … … 966 1000 // Therefore, we temporarily grow the stack for the purpose of the call and then 967 1001 // shrink it after. 1002 1003 state.setSpillStateForJSGetterSetter(spillState); 968 1004 969 1005 RELEASE_ASSERT(!m_rareData->callLinkInfo); … … 1066 1102 done.link(&jit); 1067 1103 1068 jit.addPtr(CCallHelpers::TrustedImm32((codeBlock->stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - s tate.numberOfStackBytesUsedForRegisterPreservation()),1104 jit.addPtr(CCallHelpers::TrustedImm32((codeBlock->stackPointerOffset() * sizeof(Register)) - state.preservedReusedRegisterState.numberOfBytesPreserved - spillState.numberOfStackBytesUsedForRegisterPreservation), 1069 1105 GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister); 1070 state.restoreLiveRegistersFromStackForCall(isGetter()); 1106 bool callHasReturnValue = isGetter(); 1107 restoreLiveRegistersFromStackForCall(spillState, callHasReturnValue); 1071 1108 1072 1109 jit.addLinkTask( … … 1128 1165 jit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck); 1129 1166 1130 state.restoreLiveRegistersFromStackForCallWithThrownException( );1167 state.restoreLiveRegistersFromStackForCallWithThrownException(spillState); 1131 1168 state.emitExplicitExceptionHandler(); 1132 1169 1133 1170 noException.link(&jit); 1134 state.restoreLiveRegistersFromStackForCall(isGetter()); 1171 bool callHasReturnValue = isGetter(); 1172 restoreLiveRegistersFromStackForCall(spillState, callHasReturnValue); 1135 1173 } 1136 1174 state.succeed(); … … 1249 1287 extraRegistersToPreserve.set(baseGPR); 1250 1288 extraRegistersToPreserve.set(valueRegs); 1251 state.preserveLiveRegistersToStackForCall(extraRegistersToPreserve);1289 AccessGenerationState::SpillState spillState = state.preserveLiveRegistersToStackForCall(extraRegistersToPreserve); 1252 1290 1253 1291 jit.store32( … … 1289 1327 jit.emitExceptionCheck(CCallHelpers::InvertedExceptionCheck); 1290 1328 1291 state.restoreLiveRegistersFromStackForCallWithThrownException( );1329 state.restoreLiveRegistersFromStackForCallWithThrownException(spillState); 1292 1330 state.emitExplicitExceptionHandler(); 1293 1331 1294 1332 noException.link(&jit); 1295 state.restoreLiveRegistersFromStackForCall( );1333 state.restoreLiveRegistersFromStackForCall(spillState); 1296 1334 } 1297 1335 } … … 1386 1424 } 1387 1425 1426 void AccessCase::emitDOMJITGetter(AccessGenerationState& state, GPRReg baseForGetGPR) 1427 { 1428 CCallHelpers& jit = *state.jit; 1429 VM& vm = *jit.vm(); 1430 StructureStubInfo& stubInfo = *state.stubInfo; 1431 JSValueRegs valueRegs = state.valueRegs; 1432 GPRReg baseGPR = state.baseGPR; 1433 GPRReg scratchGPR = state.scratchGPR; 1434 1435 // We construct the environment that can execute the DOMJIT::Patchpoint here. 1436 Ref<DOMJIT::CallDOMPatchpoint> patchpoint = m_rareData->domJIT->callDOM(); 1437 1438 Vector<GPRReg> gpScratch; 1439 Vector<FPRReg> fpScratch; 1440 Vector<DOMJIT::Value> regs; 1441 1442 ScratchRegisterAllocator allocator(stubInfo.patch.usedRegisters); 1443 allocator.lock(baseGPR); 1444 #if USE(JSVALUE32_64) 1445 allocator.lock(static_cast<GPRReg>(stubInfo.patch.baseTagGPR)); 1446 #endif 1447 allocator.lock(valueRegs); 1448 allocator.lock(scratchGPR); 1449 1450 GPRReg paramBaseGPR = InvalidGPRReg; 1451 GPRReg paramGlobalObjectGPR = InvalidGPRReg; 1452 JSValueRegs paramValueRegs = valueRegs; 1453 GPRReg remainingScratchGPR = InvalidGPRReg; 1454 1455 // valueRegs and baseForGetGPR may be the same. For example, in Baseline JIT, we pass the same regT0 for baseGPR and valueRegs. 1456 // In FTL, there is no constraint that the baseForGetGPR interferes with the result. To make implementation simple in 1457 // DOMJIT::Patchpoint, DOMJIT::Patchpoint assumes that result registers always early interfere with input registers, in this case, 1458 // baseForGetGPR. So we move baseForGetGPR to the other register if baseForGetGPR == valueRegs. 1459 if (baseForGetGPR != valueRegs.payloadGPR()) { 1460 paramBaseGPR = baseForGetGPR; 1461 if (!patchpoint->requireGlobalObject) 1462 remainingScratchGPR = scratchGPR; 1463 else 1464 paramGlobalObjectGPR = scratchGPR; 1465 } else { 1466 jit.move(valueRegs.payloadGPR(), scratchGPR); 1467 paramBaseGPR = scratchGPR; 1468 if (patchpoint->requireGlobalObject) 1469 paramGlobalObjectGPR = allocator.allocateScratchGPR(); 1470 } 1471 1472 JSGlobalObject* globalObjectForDOMJIT = structure()->globalObject(); 1473 1474 regs.append(paramValueRegs); 1475 if (patchpoint->requireGlobalObject) { 1476 ASSERT(paramGlobalObjectGPR != InvalidGPRReg); 1477 regs.append(DOMJIT::Value(paramGlobalObjectGPR, globalObjectForDOMJIT)); 1478 } 1479 regs.append(paramBaseGPR); 1480 1481 if (patchpoint->numGPScratchRegisters) { 1482 unsigned i = 0; 1483 if (remainingScratchGPR != InvalidGPRReg) { 1484 gpScratch.append(remainingScratchGPR); 1485 ++i; 1486 } 1487 for (; i < patchpoint->numGPScratchRegisters; ++i) 1488 gpScratch.append(allocator.allocateScratchGPR()); 1489 } 1490 1491 for (unsigned i = 0; i < patchpoint->numFPScratchRegisters; ++i) 1492 fpScratch.append(allocator.allocateScratchFPR()); 1493 1494 // Let's store the reused registers to the stack. After that, we can use allocated scratch registers. 1495 ScratchRegisterAllocator::PreservedState preservedState = 1496 allocator.preserveReusedRegistersByPushing(jit, ScratchRegisterAllocator::ExtraStackSpace::SpaceForCCall); 1497 1498 if (verbose) { 1499 dataLog("baseGPR = ", baseGPR, "\n"); 1500 dataLog("valueRegs = ", valueRegs, "\n"); 1501 dataLog("scratchGPR = ", scratchGPR, "\n"); 1502 dataLog("paramBaseGPR = ", paramBaseGPR, "\n"); 1503 if (paramGlobalObjectGPR != InvalidGPRReg) 1504 dataLog("paramGlobalObjectGPR = ", paramGlobalObjectGPR, "\n"); 1505 dataLog("paramValueRegs = ", paramValueRegs, "\n"); 1506 for (unsigned i = 0; i < patchpoint->numGPScratchRegisters; ++i) 1507 dataLog("gpScratch[", i, "] = ", gpScratch[i], "\n"); 1508 } 1509 1510 if (patchpoint->requireGlobalObject) 1511 jit.move(CCallHelpers::TrustedImmPtr(globalObjectForDOMJIT), paramGlobalObjectGPR); 1512 1513 // We just spill the registers used in DOMJIT::Patchpoint here. For not spilled registers here explicitly, 1514 // they must be in the used register set passed by the callers (Baseline, DFG, and FTL) if they need to be kept. 1515 // Some registers can be locked, but not in the used register set. For example, the caller could make baseGPR 1516 // same to valueRegs, and not include it in the used registers since it will be changed. 1517 RegisterSet registersToSpillForCCall; 1518 for (auto& value : regs) { 1519 DOMJIT::Reg reg = value.reg(); 1520 if (reg.isJSValueRegs()) 1521 registersToSpillForCCall.set(reg.jsValueRegs()); 1522 else if (reg.isGPR()) 1523 registersToSpillForCCall.set(reg.gpr()); 1524 else 1525 registersToSpillForCCall.set(reg.fpr()); 1526 } 1527 for (GPRReg reg : gpScratch) 1528 registersToSpillForCCall.set(reg); 1529 for (FPRReg reg : fpScratch) 1530 registersToSpillForCCall.set(reg); 1531 registersToSpillForCCall.exclude(RegisterSet::registersToNotSaveForCCall()); 1532 1533 DOMJITAccessCasePatchpointParams params(WTFMove(regs), WTFMove(gpScratch), WTFMove(fpScratch)); 1534 patchpoint->generator()->run(jit, params); 1535 allocator.restoreReusedRegistersByPopping(jit, preservedState); 1536 state.succeed(); 1537 1538 CCallHelpers::JumpList exceptions = params.emitSlowPathCalls(vm, state, registersToSpillForCCall, jit); 1539 exceptions.link(&jit); 1540 allocator.restoreReusedRegistersByPopping(jit, preservedState); 1541 state.emitExplicitExceptionHandler(); 1542 } 1543 1388 1544 PolymorphicAccess::PolymorphicAccess() { } 1389 1545 PolymorphicAccess::~PolymorphicAccess() { } … … 1685 1841 1686 1842 int stackPointerOffset = codeBlock->stackPointerOffset() * sizeof(EncodedJSValue); 1843 AccessGenerationState::SpillState spillStateForJSGetterSetter = state.spillStateForJSGetterSetter(); 1844 ASSERT(!spillStateForJSGetterSetter.isEmpty()); 1687 1845 stackPointerOffset -= state.preservedReusedRegisterState.numberOfBytesPreserved; 1688 stackPointerOffset -= s tate.numberOfStackBytesUsedForRegisterPreservation();1846 stackPointerOffset -= spillStateForJSGetterSetter.numberOfStackBytesUsedForRegisterPreservation; 1689 1847 1690 1848 jit.loadPtr(vm.addressOfCallFrameForCatch(), GPRInfo::callFrameRegister); 1691 1849 jit.addPtr(CCallHelpers::TrustedImm32(stackPointerOffset), GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister); 1692 1850 1693 state.restoreLiveRegistersFromStackForCallWithThrownException( );1851 state.restoreLiveRegistersFromStackForCallWithThrownException(spillStateForJSGetterSetter); 1694 1852 state.restoreScratch(); 1695 1853 CCallHelpers::Jump jumpToOSRExitExceptionHandler = jit.jump(); -
trunk/Source/JavaScriptCore/bytecode/PolymorphicAccess.h
r206779 r207427 278 278 void generateImpl(AccessGenerationState&); 279 279 void emitIntrinsicGetter(AccessGenerationState&); 280 void emitDOMJITGetter(AccessGenerationState&, GPRReg baseForGetGPR); 280 281 281 282 AccessType m_type { Load }; … … 473 474 void succeed(); 474 475 475 void calculateLiveRegistersForCallAndExceptionHandling(const RegisterSet& extra = RegisterSet()); 476 477 void preserveLiveRegistersToStackForCall(const RegisterSet& extra = RegisterSet()); 478 479 void restoreLiveRegistersFromStackForCall(bool isGetter = false); 480 void restoreLiveRegistersFromStackForCallWithThrownException(); 481 void restoreLiveRegistersFromStackForCall(const RegisterSet& dontRestore); 482 483 const RegisterSet& liveRegistersForCall() 484 { 485 RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling); 486 return m_liveRegistersForCall; 487 } 476 struct SpillState { 477 RegisterSet spilledRegisters { }; 478 unsigned numberOfStackBytesUsedForRegisterPreservation { std::numeric_limits<unsigned>::max() }; 479 480 bool isEmpty() const { return numberOfStackBytesUsedForRegisterPreservation == std::numeric_limits<unsigned>::max(); } 481 }; 482 483 const RegisterSet& calculateLiveRegistersForCallAndExceptionHandling(); 484 485 SpillState preserveLiveRegistersToStackForCall(const RegisterSet& extra = RegisterSet()); 486 487 void restoreLiveRegistersFromStackForCallWithThrownException(const SpillState&); 488 void restoreLiveRegistersFromStackForCall(const SpillState&, const RegisterSet& dontRestore = RegisterSet()); 489 490 const RegisterSet& liveRegistersForCall(); 488 491 489 492 CallSiteIndex callSiteIndexForExceptionHandlingOrOriginal(); … … 496 499 } 497 500 498 const HandlerInfo& originalExceptionHandler() const; 499 unsigned numberOfStackBytesUsedForRegisterPreservation() const 500 { 501 RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling); 502 return m_numberOfStackBytesUsedForRegisterPreservation; 503 } 501 const HandlerInfo& originalExceptionHandler(); 504 502 505 503 bool needsToRestoreRegistersIfException() const { return m_needsToRestoreRegistersIfException; } … … 507 505 508 506 void emitExplicitExceptionHandler(); 507 508 void setSpillStateForJSGetterSetter(SpillState& spillState) 509 { 510 if (!m_spillStateForJSGetterSetter.isEmpty()) { 511 ASSERT(m_spillStateForJSGetterSetter.numberOfStackBytesUsedForRegisterPreservation == spillState.numberOfStackBytesUsedForRegisterPreservation); 512 ASSERT(m_spillStateForJSGetterSetter.spilledRegisters == spillState.spilledRegisters); 513 } 514 m_spillStateForJSGetterSetter = spillState; 515 } 516 SpillState spillStateForJSGetterSetter() const { return m_spillStateForJSGetterSetter; } 509 517 510 518 private: 511 const RegisterSet& liveRegistersToPreserveAtExceptionHandlingCallSite() 512 { 513 RELEASE_ASSERT(m_calculatedRegistersForCallAndExceptionHandling); 514 return m_liveRegistersToPreserveAtExceptionHandlingCallSite; 515 } 519 const RegisterSet& liveRegistersToPreserveAtExceptionHandlingCallSite(); 516 520 517 521 RegisterSet m_liveRegistersToPreserveAtExceptionHandlingCallSite; 518 522 RegisterSet m_liveRegistersForCall; 519 523 CallSiteIndex m_callSiteIndex { CallSiteIndex(std::numeric_limits<unsigned>::max()) }; 520 unsigned m_numberOfStackBytesUsedForRegisterPreservation { std::numeric_limits<unsigned>::max() };524 SpillState m_spillStateForJSGetterSetter; 521 525 bool m_calculatedRegistersForCallAndExceptionHandling : 1; 522 526 bool m_needsToRestoreRegistersIfException : 1; -
trunk/Source/JavaScriptCore/dfg/DFGDOMJITPatchpointParams.cpp
r206899 r207427 41 41 42 42 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) \ 43 void DOMJITPatchpointParams::addSlowPathCallImpl(CCallHelpers::JumpList from, CCallHelpers&, OperationType operation, ResultType result, std::tuple<__VA_ARGS__> args) const\43 void DOMJITPatchpointParams::addSlowPathCallImpl(CCallHelpers::JumpList from, CCallHelpers&, OperationType operation, ResultType result, std::tuple<__VA_ARGS__> args) \ 44 44 { \ 45 45 dispatch(m_jit, from, operation, result, args, std::make_index_sequence<std::tuple_size<decltype(args)>::value>()); \ -
trunk/Source/JavaScriptCore/dfg/DFGDOMJITPatchpointParams.h
r207166 r207427 43 43 44 44 private: 45 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) void addSlowPathCallImpl(CCallHelpers::JumpList, CCallHelpers&, OperationType, ResultType, std::tuple<__VA_ARGS__> args) constoverride;45 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) void addSlowPathCallImpl(CCallHelpers::JumpList, CCallHelpers&, OperationType, ResultType, std::tuple<__VA_ARGS__> args) override; 46 46 DOMJIT_SLOW_PATH_CALLS(JSC_DEFINE_CALL_OPERATIONS) 47 47 #undef JSC_DEFINE_CALL_OPERATIONS -
trunk/Source/JavaScriptCore/domjit/DOMJITPatchpoint.h
r207239 r207427 35 35 class PatchpointParams; 36 36 37 typedef CCallHelpers::JumpList PatchpointGeneratorFunction(CCallHelpers&, constPatchpointParams&);37 typedef CCallHelpers::JumpList PatchpointGeneratorFunction(CCallHelpers&, PatchpointParams&); 38 38 typedef SharedTask<PatchpointGeneratorFunction> PatchpointGenerator; 39 39 -
trunk/Source/JavaScriptCore/domjit/DOMJITPatchpointParams.h
r207166 r207427 56 56 57 57 template<typename FunctionType, typename ResultType, typename... Arguments> 58 void addSlowPathCall(CCallHelpers::JumpList from, CCallHelpers& jit, FunctionType function, ResultType result, Arguments... arguments) const58 void addSlowPathCall(CCallHelpers::JumpList from, CCallHelpers& jit, FunctionType function, ResultType result, Arguments... arguments) 59 59 { 60 60 addSlowPathCallImpl(from, jit, function, result, std::make_tuple(arguments...)); … … 62 62 63 63 private: 64 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) JS_EXPORT_PRIVATE virtual void addSlowPathCallImpl(CCallHelpers::JumpList, CCallHelpers&, OperationType, ResultType, std::tuple<__VA_ARGS__> args) const= 0;64 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) JS_EXPORT_PRIVATE virtual void addSlowPathCallImpl(CCallHelpers::JumpList, CCallHelpers&, OperationType, ResultType, std::tuple<__VA_ARGS__> args) = 0; 65 65 DOMJIT_SLOW_PATH_CALLS(JSC_DEFINE_CALL_OPERATIONS) 66 66 #undef JSC_DEFINE_CALL_OPERATIONS -
trunk/Source/JavaScriptCore/ftl/FTLDOMJITPatchpointParams.cpp
r206899 r207427 51 51 52 52 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) \ 53 void DOMJITPatchpointParams::addSlowPathCallImpl(CCallHelpers::JumpList from, CCallHelpers& jit, OperationType operation, ResultType result, std::tuple<__VA_ARGS__> args) const\53 void DOMJITPatchpointParams::addSlowPathCallImpl(CCallHelpers::JumpList from, CCallHelpers& jit, OperationType operation, ResultType result, std::tuple<__VA_ARGS__> args) \ 54 54 { \ 55 55 dispatch(jit, &m_state, m_params, m_node, m_exceptions, from, operation, result, args, std::make_index_sequence<std::tuple_size<decltype(args)>::value>()); \ -
trunk/Source/JavaScriptCore/ftl/FTLDOMJITPatchpointParams.h
r207166 r207427 47 47 48 48 private: 49 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) void addSlowPathCallImpl(CCallHelpers::JumpList, CCallHelpers&, OperationType, ResultType, std::tuple<__VA_ARGS__> args) constoverride;49 #define JSC_DEFINE_CALL_OPERATIONS(OperationType, ResultType, ...) void addSlowPathCallImpl(CCallHelpers::JumpList, CCallHelpers&, OperationType, ResultType, std::tuple<__VA_ARGS__> args) override; 50 50 DOMJIT_SLOW_PATH_CALLS(JSC_DEFINE_CALL_OPERATIONS) 51 51 #undef JSC_DEFINE_CALL_OPERATIONS -
trunk/Source/JavaScriptCore/jsc.cpp
r207377 r207427 558 558 } 559 559 560 #if ENABLE(JIT) 561 static Ref<DOMJIT::Patchpoint> checkDOMJITNode() 562 { 563 Ref<DOMJIT::Patchpoint> patchpoint = DOMJIT::Patchpoint::create(); 564 patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) { 565 CCallHelpers::JumpList failureCases; 566 failureCases.append(jit.branch8( 567 CCallHelpers::NotEqual, 568 CCallHelpers::Address(params[0].gpr(), JSCell::typeInfoTypeOffset()), 569 CCallHelpers::TrustedImm32(JSC::JSType(LastJSCObjectType + 1)))); 570 return failureCases; 571 }); 572 return patchpoint; 573 } 574 #endif 575 560 576 static DOMJITNode* create(VM& vm, Structure* structure) 561 577 { … … 609 625 Ref<DOMJIT::Patchpoint> checkDOM() override 610 626 { 611 Ref<DOMJIT::Patchpoint> patchpoint = DOMJIT::Patchpoint::create(); 612 patchpoint->setGenerator([=](CCallHelpers& jit, const DOMJIT::PatchpointParams& params) { 613 CCallHelpers::JumpList failureCases; 614 failureCases.append(jit.branch8( 615 CCallHelpers::NotEqual, 616 CCallHelpers::Address(params[0].gpr(), JSCell::typeInfoTypeOffset()), 617 CCallHelpers::TrustedImm32(JSC::JSType(LastJSCObjectType + 1)))); 618 return failureCases; 619 }); 620 return patchpoint; 627 return DOMJITNode::checkDOMJITNode(); 621 628 } 622 629 … … 625 632 Ref<DOMJIT::CallDOMPatchpoint> patchpoint = DOMJIT::CallDOMPatchpoint::create(); 626 633 patchpoint->requireGlobalObject = false; 627 patchpoint->setGenerator([=](CCallHelpers& jit, constDOMJIT::PatchpointParams& params) {634 patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) { 628 635 JSValueRegs results = params[0].jsValueRegs(); 629 636 GPRReg dom = params[1].gpr(); … … 665 672 return JSValue::encode(jsNumber(thisObject->value())); 666 673 } 674 }; 675 676 class DOMJITGetterComplex : public DOMJITNode { 677 public: 678 DOMJITGetterComplex(VM& vm, Structure* structure) 679 : Base(vm, structure) 680 { 681 } 682 683 DECLARE_INFO; 684 typedef DOMJITNode Base; 685 static const unsigned StructureFlags = Base::StructureFlags; 686 687 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 688 { 689 return Structure::create(vm, globalObject, prototype, TypeInfo(JSC::JSType(LastJSCObjectType + 1), StructureFlags), info()); 690 } 691 692 static DOMJITGetterComplex* create(VM& vm, JSGlobalObject* globalObject, Structure* structure) 693 { 694 DOMJITGetterComplex* getter = new (NotNull, allocateCell<DOMJITGetterComplex>(vm.heap, sizeof(DOMJITGetterComplex))) DOMJITGetterComplex(vm, structure); 695 getter->finishCreation(vm, globalObject); 696 return getter; 697 } 698 699 class DOMJITNodeDOMJIT : public DOMJIT::GetterSetter { 700 public: 701 DOMJITNodeDOMJIT() 702 : DOMJIT::GetterSetter(DOMJITGetterComplex::customGetter, nullptr, DOMJITNode::info()) 703 { 704 } 705 706 #if ENABLE(JIT) 707 Ref<DOMJIT::Patchpoint> checkDOM() override 708 { 709 return DOMJITNode::checkDOMJITNode(); 710 } 711 712 Ref<DOMJIT::CallDOMPatchpoint> callDOM() override 713 { 714 RefPtr<DOMJIT::CallDOMPatchpoint> patchpoint = DOMJIT::CallDOMPatchpoint::create(); 715 static_assert(GPRInfo::numberOfRegisters >= 4, "Number of registers should be larger or equal to 4."); 716 patchpoint->numGPScratchRegisters = GPRInfo::numberOfRegisters - 4; 717 patchpoint->numFPScratchRegisters = 3; 718 patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) { 719 JSValueRegs results = params[0].jsValueRegs(); 720 GPRReg domGPR = params[2].gpr(); 721 for (unsigned i = 0; i < patchpoint->numGPScratchRegisters; ++i) 722 jit.move(CCallHelpers::TrustedImm32(42), params.gpScratch(i)); 723 724 params.addSlowPathCall(jit.jump(), jit, static_cast<EncodedJSValue(*)(ExecState*, void*)>([](ExecState* exec, void* pointer) { 725 VM& vm = exec->vm(); 726 auto scope = DECLARE_THROW_SCOPE(vm); 727 auto* object = static_cast<DOMJITNode*>(pointer); 728 auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(object); 729 if (domjitGetterComplex) { 730 if (domjitGetterComplex->m_enableException) 731 return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("DOMJITGetterComplex slow call exception")))); 732 } 733 return JSValue::encode(jsNumber(object->value())); 734 }), results, domGPR); 735 return CCallHelpers::JumpList(); 736 737 }); 738 return *patchpoint.get(); 739 } 740 #endif 741 }; 742 743 static DOMJIT::GetterSetter* domJITNodeGetterSetter() 744 { 745 static NeverDestroyed<DOMJITNodeDOMJIT> graph; 746 return &graph.get(); 747 } 748 749 private: 750 void finishCreation(VM& vm, JSGlobalObject* globalObject) 751 { 752 Base::finishCreation(vm); 753 DOMJIT::GetterSetter* domJIT = domJITNodeGetterSetter(); 754 CustomGetterSetter* customGetterSetter = CustomGetterSetter::create(vm, domJIT->getter(), domJIT->setter(), domJIT); 755 putDirectCustomAccessor(vm, Identifier::fromString(&vm, "customGetter"), customGetterSetter, ReadOnly | CustomAccessor); 756 putDirectNativeFunction(vm, globalObject, Identifier::fromString(&vm, "enableException"), 0, functionEnableException, NoIntrinsic, 0); 757 } 758 759 static EncodedJSValue JSC_HOST_CALL functionEnableException(ExecState* exec) 760 { 761 auto* object = jsDynamicCast<DOMJITGetterComplex*>(exec->thisValue()); 762 if (object) 763 object->m_enableException = true; 764 return JSValue::encode(jsUndefined()); 765 } 766 767 static EncodedJSValue customGetter(ExecState* exec, EncodedJSValue thisValue, PropertyName) 768 { 769 VM& vm = exec->vm(); 770 auto scope = DECLARE_THROW_SCOPE(vm); 771 772 auto* thisObject = jsDynamicCast<DOMJITNode*>(JSValue::decode(thisValue)); 773 if (!thisObject) 774 return throwVMTypeError(exec, scope); 775 if (auto* domjitGetterComplex = jsDynamicCast<DOMJITGetterComplex*>(JSValue::decode(thisValue))) { 776 if (domjitGetterComplex->m_enableException) 777 return JSValue::encode(throwException(exec, scope, createError(exec, ASCIILiteral("DOMJITGetterComplex slow call exception")))); 778 } 779 return JSValue::encode(jsNumber(thisObject->value())); 780 } 781 782 bool m_enableException { false }; 667 783 }; 668 784 … … 674 790 const ClassInfo DOMJITNode::s_info = { "DOMJITNode", &Base::s_info, 0, CREATE_METHOD_TABLE(DOMJITNode) }; 675 791 const ClassInfo DOMJITGetter::s_info = { "DOMJITGetter", &Base::s_info, 0, CREATE_METHOD_TABLE(DOMJITGetter) }; 792 const ClassInfo DOMJITGetterComplex::s_info = { "DOMJITGetterComplex", &Base::s_info, 0, CREATE_METHOD_TABLE(DOMJITGetterComplex) }; 676 793 const ClassInfo RuntimeArray::s_info = { "RuntimeArray", &Base::s_info, 0, CREATE_METHOD_TABLE(RuntimeArray) }; 677 794 const ClassInfo SimpleObject::s_info = { "SimpleObject", &Base::s_info, 0, CREATE_METHOD_TABLE(SimpleObject) }; … … 704 821 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITNodeObject(ExecState*); 705 822 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterObject(ExecState*); 823 static EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(ExecState*); 706 824 static EncodedJSValue JSC_HOST_CALL functionCreateBuiltin(ExecState*); 707 825 static EncodedJSValue JSC_HOST_CALL functionCreateGlobalObject(ExecState*); … … 991 1109 addFunction(vm, "createDOMJITNodeObject", functionCreateDOMJITNodeObject, 0); 992 1110 addFunction(vm, "createDOMJITGetterObject", functionCreateDOMJITGetterObject, 0); 1111 addFunction(vm, "createDOMJITGetterComplexObject", functionCreateDOMJITGetterComplexObject, 0); 993 1112 addFunction(vm, "createBuiltin", functionCreateBuiltin, 2); 994 1113 addFunction(vm, "createGlobalObject", functionCreateGlobalObject, 0); … … 1512 1631 } 1513 1632 1633 EncodedJSValue JSC_HOST_CALL functionCreateDOMJITGetterComplexObject(ExecState* exec) 1634 { 1635 JSLockHolder lock(exec); 1636 Structure* structure = DOMJITGetterComplex::createStructure(exec->vm(), exec->lexicalGlobalObject(), jsNull()); 1637 DOMJITGetterComplex* result = DOMJITGetterComplex::create(exec->vm(), exec->lexicalGlobalObject(), structure); 1638 return JSValue::encode(result); 1639 } 1640 1514 1641 EncodedJSValue JSC_HOST_CALL functionSetImpureGetterDelegate(ExecState* exec) 1515 1642 { -
trunk/Source/WebCore/ChangeLog
r207426 r207427 1 2016-10-17 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [DOMJIT] Use DOMJIT::Patchpoint in IC 4 https://bugs.webkit.org/show_bug.cgi?id=163223 5 6 Reviewed by Saam Barati. 7 8 Make DOMJITPatchpointParams non-const. 9 10 * domjit/DOMJITHelpers.h: 11 (WebCore::DOMJITHelpers::toWrapper): 12 * domjit/JSNodeDOMJIT.cpp: 13 (WebCore::createCallDOMForOffsetAccess): 14 (WebCore::checkNode): 15 (WebCore::NodeNodeTypeDOMJIT::callDOM): 16 1 17 2016-10-17 Chris Dumez <cdumez@apple.com> 2 18 -
trunk/Source/WebCore/domjit/DOMJITHelpers.h
r207166 r207427 60 60 61 61 template<typename WrappedType, typename ToJSFunction> 62 void toWrapper(CCallHelpers& jit, constJSC::DOMJIT::PatchpointParams& params, GPRReg wrapped, GPRReg globalObject, JSValueRegs result, ToJSFunction function, JSC::JSValue globalObjectConstant)62 void toWrapper(CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params, GPRReg wrapped, GPRReg globalObject, JSValueRegs result, ToJSFunction function, JSC::JSValue globalObjectConstant) 63 63 { 64 64 ASSERT(wrapped != result.payloadGPR()); -
trunk/Source/WebCore/domjit/JSNodeDOMJIT.cpp
r207239 r207427 55 55 Ref<DOMJIT::CallDOMPatchpoint> patchpoint = DOMJIT::CallDOMPatchpoint::create(); 56 56 patchpoint->numGPScratchRegisters = 1; 57 patchpoint->setGenerator([=](CCallHelpers& jit, constDOMJIT::PatchpointParams& params) {57 patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) { 58 58 JSValueRegs result = params[0].jsValueRegs(); 59 59 GPRReg globalObject = params[1].gpr(); … … 85 85 { 86 86 Ref<DOMJIT::Patchpoint> patchpoint = DOMJIT::Patchpoint::create(); 87 patchpoint->setGenerator([=](CCallHelpers& jit, constDOMJIT::PatchpointParams& params) {87 patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) { 88 88 CCallHelpers::JumpList failureCases; 89 89 failureCases.append(DOMJITHelpers::branchIfNotNode(jit, params[0].gpr())); … … 158 158 Ref<DOMJIT::CallDOMPatchpoint> patchpoint = DOMJIT::CallDOMPatchpoint::create(); 159 159 patchpoint->requireGlobalObject = false; 160 patchpoint->setGenerator([=](CCallHelpers& jit, constDOMJIT::PatchpointParams& params) {160 patchpoint->setGenerator([=](CCallHelpers& jit, DOMJIT::PatchpointParams& params) { 161 161 JSValueRegs result = params[0].jsValueRegs(); 162 162 GPRReg node = params[1].gpr();
Note: See TracChangeset
for help on using the changeset viewer.