Changeset 220298 in webkit
- Timestamp:
- Aug 4, 2017 3:03:54 PM (7 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r220294 r220298 1 2017-08-04 Mark Lam <mark.lam@apple.com> 2 3 Move DFG::OSRExitCompiler methods into DFG::OSRExit [step 1]. 4 https://bugs.webkit.org/show_bug.cgi?id=175208 5 <rdar://problem/33732402> 6 7 Reviewed by Saam Barati. 8 9 This will minimize the code diff and make it easier to review the patch for 10 https://bugs.webkit.org/show_bug.cgi?id=175144 later. We'll do this patch in 3 11 steps: 12 13 1. Do the code changes to move methods into OSRExit. 14 2. Copy the 64-bit and common methods into DFGOSRExit.cpp, and delete the unused DFGOSRExitCompiler files. 15 3. Merge the 32-bit OSRExitCompiler methods into the 64-bit version, and delete DFGOSRExitCompiler32_64.cpp. 16 17 Splitting this refactoring into these 3 steps also makes it easier to review this 18 patch and understand what is being changed. 19 20 * dfg/DFGOSRExit.h: 21 * dfg/DFGOSRExitCompiler.cpp: 22 (JSC::DFG::OSRExit::emitRestoreArguments): 23 (JSC::DFG::OSRExit::compileOSRExit): 24 (JSC::DFG::OSRExitCompiler::emitRestoreArguments): Deleted. 25 (): Deleted. 26 * dfg/DFGOSRExitCompiler.h: 27 (JSC::DFG::OSRExitCompiler::OSRExitCompiler): Deleted. 28 (): Deleted. 29 * dfg/DFGOSRExitCompiler32_64.cpp: 30 (JSC::DFG::OSRExit::compileExit): 31 (JSC::DFG::OSRExitCompiler::compileExit): Deleted. 32 * dfg/DFGOSRExitCompiler64.cpp: 33 (JSC::DFG::OSRExit::compileExit): 34 (JSC::DFG::OSRExitCompiler::compileExit): Deleted. 35 * dfg/DFGThunks.cpp: 36 (JSC::DFG::osrExitGenerationThunkGenerator): 37 1 38 2017-08-04 Devin Rousso <drousso@apple.com> 2 39 -
trunk/Source/JavaScriptCore/dfg/DFGOSRExit.h
r218794 r220298 1 1 /* 2 * Copyright (C) 2011 , 2013Apple Inc. All rights reserved.2 * Copyright (C) 2011-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 #include "MacroAssembler.h" 33 33 #include "MethodOfGettingAValueProfile.h" 34 #include "Operands.h" 35 #include "ValueRecovery.h" 34 36 35 namespace JSC { namespace DFG { 37 namespace JSC { 38 39 class CCallHelpers; 40 41 namespace DFG { 36 42 37 43 class SpeculativeJIT; … … 93 99 OSRExit(ExitKind, JSValueSource, MethodOfGettingAValueProfile, SpeculativeJIT*, unsigned streamIndex, unsigned recoveryIndex = UINT_MAX); 94 100 101 static void JIT_OPERATION compileOSRExit(ExecState*) WTF_INTERNAL; 102 95 103 unsigned m_patchableCodeOffset { 0 }; 96 104 … … 112 120 OSRExitBase::considerAddingAsFrequentExitSite(profiledCodeBlock, ExitFromDFG); 113 121 } 122 123 private: 124 static void compileExit(CCallHelpers&, VM&, const OSRExit&, const Operands<ValueRecovery>&, SpeculationRecovery*); 125 static void emitRestoreArguments(CCallHelpers&, const Operands<ValueRecovery>&); 114 126 }; 115 127 -
trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.cpp
r218794 r220298 1 1 /* 2 * Copyright (C) 2011-201 3, 2015-2016Apple Inc. All rights reserved.2 * Copyright (C) 2011-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 41 41 namespace JSC { namespace DFG { 42 42 43 void OSRExit Compiler::emitRestoreArguments(const Operands<ValueRecovery>& operands)43 void OSRExit::emitRestoreArguments(CCallHelpers& jit, const Operands<ValueRecovery>& operands) 44 44 { 45 45 HashMap<MinifiedID, int> alreadyAllocatedArguments; // Maps phantom arguments node ID to operand. … … 56 56 if (iter != alreadyAllocatedArguments.end()) { 57 57 JSValueRegs regs = JSValueRegs::withTwoAvailableRegs(GPRInfo::regT0, GPRInfo::regT1); 58 m_jit.loadValue(CCallHelpers::addressFor(iter->value), regs);59 m_jit.storeValue(regs, CCallHelpers::addressFor(operand));58 jit.loadValue(CCallHelpers::addressFor(iter->value), regs); 59 jit.storeValue(regs, CCallHelpers::addressFor(operand)); 60 60 continue; 61 61 } 62 62 63 63 InlineCallFrame* inlineCallFrame = 64 m_jit.codeBlock()->jitCode()->dfg()->minifiedDFG.at(id)->inlineCallFrame();64 jit.codeBlock()->jitCode()->dfg()->minifiedDFG.at(id)->inlineCallFrame(); 65 65 66 66 int stackOffset; … … 71 71 72 72 if (!inlineCallFrame || inlineCallFrame->isClosureCall) { 73 m_jit.loadPtr(73 jit.loadPtr( 74 74 AssemblyHelpers::addressFor(stackOffset + CallFrameSlot::callee), 75 75 GPRInfo::regT0); 76 76 } else { 77 m_jit.move(77 jit.move( 78 78 AssemblyHelpers::TrustedImmPtr(inlineCallFrame->calleeRecovery.constant().asCell()), 79 79 GPRInfo::regT0); … … 81 81 82 82 if (!inlineCallFrame || inlineCallFrame->isVarargs()) { 83 m_jit.load32(83 jit.load32( 84 84 AssemblyHelpers::payloadFor(stackOffset + CallFrameSlot::argumentCount), 85 85 GPRInfo::regT1); 86 86 } else { 87 m_jit.move(87 jit.move( 88 88 AssemblyHelpers::TrustedImm32(inlineCallFrame->arguments.size()), 89 89 GPRInfo::regT1); 90 90 } 91 91 92 m_jit.setupArgumentsWithExecState(92 jit.setupArgumentsWithExecState( 93 93 AssemblyHelpers::TrustedImmPtr(inlineCallFrame), GPRInfo::regT0, GPRInfo::regT1); 94 94 switch (recovery.technique()) { 95 95 case DirectArgumentsThatWereNotCreated: 96 m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateDirectArgumentsDuringExit)), GPRInfo::nonArgGPR0);96 jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateDirectArgumentsDuringExit)), GPRInfo::nonArgGPR0); 97 97 break; 98 98 case ClonedArgumentsThatWereNotCreated: 99 m_jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateClonedArgumentsDuringExit)), GPRInfo::nonArgGPR0);99 jit.move(AssemblyHelpers::TrustedImmPtr(bitwise_cast<void*>(operationCreateClonedArgumentsDuringExit)), GPRInfo::nonArgGPR0); 100 100 break; 101 101 default: … … 103 103 break; 104 104 } 105 m_jit.call(GPRInfo::nonArgGPR0);106 m_jit.storeCell(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(operand));105 jit.call(GPRInfo::nonArgGPR0); 106 jit.storeCell(GPRInfo::returnValueGPR, AssemblyHelpers::addressFor(operand)); 107 107 108 108 alreadyAllocatedArguments.add(id, operand); … … 110 110 } 111 111 112 extern "C" { 113 114 void compileOSRExit(ExecState* exec) 112 void OSRExit::compileOSRExit(ExecState* exec) 115 113 { 116 114 VM* vm = &exec->vm(); … … 149 147 { 150 148 CCallHelpers jit(codeBlock); 151 OSRExitCompiler exitCompiler(jit);152 149 153 150 if (exit.m_kind == GenericUnwind) { … … 173 170 } 174 171 175 exitCompiler.compileExit(*vm, exit, operands, recovery);176 172 compileExit(jit, *vm, exit, operands, recovery); 173 177 174 LinkBuffer patchBuffer(jit, codeBlock); 178 175 exit.m_code = FINALIZE_CODE_IF( … … 190 187 } 191 188 192 } // extern "C"193 194 189 } } // namespace JSC::DFG 195 190 -
trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler.h
r218794 r220298 1 1 /* 2 * Copyright (C) 2011 , 2015Apple Inc. All rights reserved.2 * Copyright (C) 2011-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 #include "Operands.h" 33 33 34 namespace JSC {35 36 class ExecState;37 38 namespace DFG {39 40 class OSRExitCompiler {41 public:42 OSRExitCompiler(CCallHelpers& jit)43 : m_jit(jit)44 {45 }46 47 void compileExit(VM&, const OSRExit&, const Operands<ValueRecovery>&, SpeculationRecovery*);48 49 private:50 void emitRestoreArguments(const Operands<ValueRecovery>&);51 52 CCallHelpers& m_jit;53 };54 55 extern "C" {56 void JIT_OPERATION compileOSRExit(ExecState*) WTF_INTERNAL;57 }58 59 } } // namespace JSC::DFG60 61 34 #endif // ENABLE(DFG_JIT) -
trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler32_64.cpp
r214531 r220298 1 1 /* 2 * Copyright (C) 2011 , 2013-2016Apple Inc. All rights reserved.2 * Copyright (C) 2011-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 37 37 namespace JSC { namespace DFG { 38 38 39 void OSRExit Compiler::compileExit(VM& vm, const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery)39 void OSRExit::compileExit(CCallHelpers& jit, VM& vm, const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery) 40 40 { 41 41 // Pro-forma stuff. 42 42 if (Options::printEachOSRExit()) { 43 43 SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo; 44 debugInfo->codeBlock = m_jit.codeBlock();44 debugInfo->codeBlock = jit.codeBlock(); 45 45 debugInfo->kind = exit.m_kind; 46 46 debugInfo->bytecodeOffset = exit.m_codeOrigin.bytecodeIndex; 47 47 48 m_jit.debugCall(vm, debugOperationPrintSpeculationFailure, debugInfo);48 jit.debugCall(vm, debugOperationPrintSpeculationFailure, debugInfo); 49 49 } 50 50 … … 55 55 switch (recovery->type()) { 56 56 case SpeculativeAdd: 57 m_jit.sub32(recovery->src(), recovery->dest());57 jit.sub32(recovery->src(), recovery->dest()); 58 58 break; 59 59 60 60 case SpeculativeAddImmediate: 61 m_jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest());61 jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest()); 62 62 break; 63 63 … … 88 88 89 89 CodeOrigin codeOrigin = exit.m_codeOriginForExitProfile; 90 if (ArrayProfile* arrayProfile = m_jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) {90 if (ArrayProfile* arrayProfile = jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) { 91 91 GPRReg usedRegister1; 92 92 GPRReg usedRegister2; … … 107 107 scratch2 = AssemblyHelpers::selectScratchGPR(usedRegister1, usedRegister2, scratch1); 108 108 109 m_jit.push(scratch1);110 m_jit.push(scratch2);109 jit.push(scratch1); 110 jit.push(scratch2); 111 111 112 112 GPRReg value; 113 113 if (exit.m_jsValueSource.isAddress()) { 114 114 value = scratch1; 115 m_jit.loadPtr(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), value);115 jit.loadPtr(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), value); 116 116 } else 117 117 value = exit.m_jsValueSource.payloadGPR(); 118 118 119 m_jit.loadPtr(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1);120 m_jit.storePtr(scratch1, arrayProfile->addressOfLastSeenStructureID());121 m_jit.load8(AssemblyHelpers::Address(scratch1, Structure::indexingTypeIncludingHistoryOffset()), scratch1);122 m_jit.move(AssemblyHelpers::TrustedImm32(1), scratch2);123 m_jit.lshift32(scratch1, scratch2);124 m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));125 126 m_jit.pop(scratch2);127 m_jit.pop(scratch1);119 jit.loadPtr(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1); 120 jit.storePtr(scratch1, arrayProfile->addressOfLastSeenStructureID()); 121 jit.load8(AssemblyHelpers::Address(scratch1, Structure::indexingTypeIncludingHistoryOffset()), scratch1); 122 jit.move(AssemblyHelpers::TrustedImm32(1), scratch2); 123 jit.lshift32(scratch1, scratch2); 124 jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes())); 125 126 jit.pop(scratch2); 127 jit.pop(scratch1); 128 128 } 129 129 } … … 134 134 GPRReg scratchPayload = AssemblyHelpers::selectScratchGPR(exit.m_jsValueSource.base()); 135 135 GPRReg scratchTag = AssemblyHelpers::selectScratchGPR(exit.m_jsValueSource.base(), scratchPayload); 136 m_jit.pushToSave(scratchPayload);137 m_jit.pushToSave(scratchTag);136 jit.pushToSave(scratchPayload); 137 jit.pushToSave(scratchTag); 138 138 139 139 JSValueRegs scratch(scratchTag, scratchPayload); 140 140 141 m_jit.loadValue(exit.m_jsValueSource.asAddress(), scratch);142 profile.emitReportValue( m_jit, scratch);143 144 m_jit.popToRestore(scratchTag);145 m_jit.popToRestore(scratchPayload);141 jit.loadValue(exit.m_jsValueSource.asAddress(), scratch); 142 profile.emitReportValue(jit, scratch); 143 144 jit.popToRestore(scratchTag); 145 jit.popToRestore(scratchPayload); 146 146 } else if (exit.m_jsValueSource.hasKnownTag()) { 147 147 GPRReg scratchTag = AssemblyHelpers::selectScratchGPR(exit.m_jsValueSource.payloadGPR()); 148 m_jit.pushToSave(scratchTag);149 m_jit.move(AssemblyHelpers::TrustedImm32(exit.m_jsValueSource.tag()), scratchTag);148 jit.pushToSave(scratchTag); 149 jit.move(AssemblyHelpers::TrustedImm32(exit.m_jsValueSource.tag()), scratchTag); 150 150 JSValueRegs value(scratchTag, exit.m_jsValueSource.payloadGPR()); 151 profile.emitReportValue( m_jit, value);152 m_jit.popToRestore(scratchTag);151 profile.emitReportValue(jit, value); 152 jit.popToRestore(scratchTag); 153 153 } else 154 profile.emitReportValue( m_jit, exit.m_jsValueSource.regs());154 profile.emitReportValue(jit, exit.m_jsValueSource.regs()); 155 155 } 156 156 } … … 171 171 case UnboxedBooleanInGPR: 172 172 case UnboxedCellInGPR: 173 m_jit.store32(173 jit.store32( 174 174 recovery.gpr(), 175 175 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload); … … 177 177 178 178 case InPair: 179 m_jit.store32(179 jit.store32( 180 180 recovery.tagGPR(), 181 181 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag); 182 m_jit.store32(182 jit.store32( 183 183 recovery.payloadGPR(), 184 184 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload); … … 200 200 case UnboxedDoubleInFPR: 201 201 case InFPR: 202 m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);203 m_jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0));202 jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0); 203 jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0)); 204 204 break; 205 205 … … 224 224 case CellDisplacedInJSStack: 225 225 case BooleanDisplacedInJSStack: 226 m_jit.load32(226 jit.load32( 227 227 AssemblyHelpers::tagFor(recovery.virtualRegister()), 228 228 GPRInfo::regT0); 229 m_jit.load32(229 jit.load32( 230 230 AssemblyHelpers::payloadFor(recovery.virtualRegister()), 231 231 GPRInfo::regT1); 232 m_jit.store32(232 jit.store32( 233 233 GPRInfo::regT0, 234 234 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag); 235 m_jit.store32(235 jit.store32( 236 236 GPRInfo::regT1, 237 237 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload); … … 246 246 // could toast some stack that the DFG used. We need to do it before storing to stack offsets 247 247 // used by baseline. 248 m_jit.addPtr(248 jit.addPtr( 249 249 CCallHelpers::TrustedImm32( 250 - m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),250 -jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)), 251 251 CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister); 252 252 253 253 // Restore the DFG callee saves and then save the ones the baseline JIT uses. 254 m_jit.emitRestoreCalleeSaves();255 m_jit.emitSaveCalleeSavesFor(m_jit.baselineCodeBlock());254 jit.emitRestoreCalleeSaves(); 255 jit.emitSaveCalleeSavesFor(jit.baselineCodeBlock()); 256 256 257 257 if (exit.isExceptionHandler()) 258 m_jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm);258 jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm); 259 259 260 260 // Do all data format conversions and store the results into the stack. … … 264 264 VirtualRegister reg = operands.virtualRegisterForIndex(index); 265 265 266 if (reg.isLocal() && reg.toLocal() < static_cast<int>( m_jit.baselineCodeBlock()->calleeSaveSpaceAsVirtualRegisters()))266 if (reg.isLocal() && reg.toLocal() < static_cast<int>(jit.baselineCodeBlock()->calleeSaveSpaceAsVirtualRegisters())) 267 267 continue; 268 268 … … 273 273 case DisplacedInJSStack: 274 274 case InFPR: 275 m_jit.load32(275 jit.load32( 276 276 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag, 277 277 GPRInfo::regT0); 278 m_jit.load32(278 jit.load32( 279 279 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload, 280 280 GPRInfo::regT1); 281 m_jit.store32(281 jit.store32( 282 282 GPRInfo::regT0, 283 283 AssemblyHelpers::tagFor(operand)); 284 m_jit.store32(284 jit.store32( 285 285 GPRInfo::regT1, 286 286 AssemblyHelpers::payloadFor(operand)); … … 289 289 case UnboxedDoubleInFPR: 290 290 case DoubleDisplacedInJSStack: 291 m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);292 m_jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0);293 m_jit.purifyNaN(FPRInfo::fpRegT0);294 m_jit.storeDouble(FPRInfo::fpRegT0, AssemblyHelpers::addressFor(operand));291 jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0); 292 jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0); 293 jit.purifyNaN(FPRInfo::fpRegT0); 294 jit.storeDouble(FPRInfo::fpRegT0, AssemblyHelpers::addressFor(operand)); 295 295 break; 296 296 297 297 case UnboxedInt32InGPR: 298 298 case Int32DisplacedInJSStack: 299 m_jit.load32(299 jit.load32( 300 300 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload, 301 301 GPRInfo::regT0); 302 m_jit.store32(302 jit.store32( 303 303 AssemblyHelpers::TrustedImm32(JSValue::Int32Tag), 304 304 AssemblyHelpers::tagFor(operand)); 305 m_jit.store32(305 jit.store32( 306 306 GPRInfo::regT0, 307 307 AssemblyHelpers::payloadFor(operand)); … … 310 310 case UnboxedCellInGPR: 311 311 case CellDisplacedInJSStack: 312 m_jit.load32(312 jit.load32( 313 313 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload, 314 314 GPRInfo::regT0); 315 m_jit.store32(315 jit.store32( 316 316 AssemblyHelpers::TrustedImm32(JSValue::CellTag), 317 317 AssemblyHelpers::tagFor(operand)); 318 m_jit.store32(318 jit.store32( 319 319 GPRInfo::regT0, 320 320 AssemblyHelpers::payloadFor(operand)); … … 323 323 case UnboxedBooleanInGPR: 324 324 case BooleanDisplacedInJSStack: 325 m_jit.load32(325 jit.load32( 326 326 &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload, 327 327 GPRInfo::regT0); 328 m_jit.store32(328 jit.store32( 329 329 AssemblyHelpers::TrustedImm32(JSValue::BooleanTag), 330 330 AssemblyHelpers::tagFor(operand)); 331 m_jit.store32(331 jit.store32( 332 332 GPRInfo::regT0, 333 333 AssemblyHelpers::payloadFor(operand)); … … 335 335 336 336 case Constant: 337 m_jit.store32(337 jit.store32( 338 338 AssemblyHelpers::TrustedImm32(recovery.constant().tag()), 339 339 AssemblyHelpers::tagFor(operand)); 340 m_jit.store32(340 jit.store32( 341 341 AssemblyHelpers::TrustedImm32(recovery.constant().payload()), 342 342 AssemblyHelpers::payloadFor(operand)); … … 359 359 // inline call frame scope - but for now the DFG wouldn't do that. 360 360 361 emitRestoreArguments( operands);361 emitRestoreArguments(jit, operands); 362 362 363 363 // Adjust the old JIT's execute counter. Since we are exiting OSR, we know … … 397 397 // counterValueForOptimizeAfterWarmUp(). 398 398 399 handleExitCounts( m_jit, exit);399 handleExitCounts(jit, exit); 400 400 401 401 // Reify inlined call frames. 402 402 403 reifyInlinedCallFrames( m_jit, exit);403 reifyInlinedCallFrames(jit, exit); 404 404 405 405 // And finish. 406 adjustAndJumpToTarget(vm, m_jit, exit);406 adjustAndJumpToTarget(vm, jit, exit); 407 407 } 408 408 -
trunk/Source/JavaScriptCore/dfg/DFGOSRExitCompiler64.cpp
r214531 r220298 1 1 /* 2 * Copyright (C) 2011 , 2013-2016Apple Inc. All rights reserved.2 * Copyright (C) 2011-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 39 39 namespace JSC { namespace DFG { 40 40 41 void OSRExit Compiler::compileExit(VM& vm, const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery)41 void OSRExit::compileExit(CCallHelpers& jit, VM& vm, const OSRExit& exit, const Operands<ValueRecovery>& operands, SpeculationRecovery* recovery) 42 42 { 43 m_jit.jitAssertTagsInPlace();43 jit.jitAssertTagsInPlace(); 44 44 45 45 // Pro-forma stuff. 46 46 if (Options::printEachOSRExit()) { 47 47 SpeculationFailureDebugInfo* debugInfo = new SpeculationFailureDebugInfo; 48 debugInfo->codeBlock = m_jit.codeBlock();48 debugInfo->codeBlock = jit.codeBlock(); 49 49 debugInfo->kind = exit.m_kind; 50 50 debugInfo->bytecodeOffset = exit.m_codeOrigin.bytecodeIndex; 51 51 52 m_jit.debugCall(vm, debugOperationPrintSpeculationFailure, debugInfo);52 jit.debugCall(vm, debugOperationPrintSpeculationFailure, debugInfo); 53 53 } 54 54 … … 59 59 switch (recovery->type()) { 60 60 case SpeculativeAdd: 61 m_jit.sub32(recovery->src(), recovery->dest());62 m_jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest());61 jit.sub32(recovery->src(), recovery->dest()); 62 jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest()); 63 63 break; 64 64 65 65 case SpeculativeAddImmediate: 66 m_jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest());67 m_jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest());66 jit.sub32(AssemblyHelpers::Imm32(recovery->immediate()), recovery->dest()); 67 jit.or64(GPRInfo::tagTypeNumberRegister, recovery->dest()); 68 68 break; 69 69 70 70 case BooleanSpeculationCheck: 71 m_jit.xor64(AssemblyHelpers::TrustedImm32(static_cast<int32_t>(ValueFalse)), recovery->dest());71 jit.xor64(AssemblyHelpers::TrustedImm32(static_cast<int32_t>(ValueFalse)), recovery->dest()); 72 72 break; 73 73 … … 91 91 92 92 CodeOrigin codeOrigin = exit.m_codeOriginForExitProfile; 93 if (ArrayProfile* arrayProfile = m_jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) {93 if (ArrayProfile* arrayProfile = jit.baselineCodeBlockFor(codeOrigin)->getArrayProfile(codeOrigin.bytecodeIndex)) { 94 94 GPRReg usedRegister; 95 95 if (exit.m_jsValueSource.isAddress()) … … 104 104 105 105 if (isARM64()) { 106 m_jit.pushToSave(scratch1);107 m_jit.pushToSave(scratch2);106 jit.pushToSave(scratch1); 107 jit.pushToSave(scratch2); 108 108 } else { 109 m_jit.push(scratch1);110 m_jit.push(scratch2);109 jit.push(scratch1); 110 jit.push(scratch2); 111 111 } 112 112 … … 114 114 if (exit.m_jsValueSource.isAddress()) { 115 115 value = scratch1; 116 m_jit.loadPtr(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), value);116 jit.loadPtr(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), value); 117 117 } else 118 118 value = exit.m_jsValueSource.gpr(); 119 119 120 m_jit.load32(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1);121 m_jit.store32(scratch1, arrayProfile->addressOfLastSeenStructureID());122 m_jit.load8(AssemblyHelpers::Address(value, JSCell::indexingTypeAndMiscOffset()), scratch1);123 m_jit.move(AssemblyHelpers::TrustedImm32(1), scratch2);124 m_jit.lshift32(scratch1, scratch2);125 m_jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes()));120 jit.load32(AssemblyHelpers::Address(value, JSCell::structureIDOffset()), scratch1); 121 jit.store32(scratch1, arrayProfile->addressOfLastSeenStructureID()); 122 jit.load8(AssemblyHelpers::Address(value, JSCell::indexingTypeAndMiscOffset()), scratch1); 123 jit.move(AssemblyHelpers::TrustedImm32(1), scratch2); 124 jit.lshift32(scratch1, scratch2); 125 jit.or32(scratch2, AssemblyHelpers::AbsoluteAddress(arrayProfile->addressOfArrayModes())); 126 126 127 127 if (isARM64()) { 128 m_jit.popToRestore(scratch2);129 m_jit.popToRestore(scratch1);128 jit.popToRestore(scratch2); 129 jit.popToRestore(scratch1); 130 130 } else { 131 m_jit.pop(scratch2);132 m_jit.pop(scratch1);131 jit.pop(scratch2); 132 jit.pop(scratch1); 133 133 } 134 134 } … … 139 139 // We can't be sure that we have a spare register. So use the tagTypeNumberRegister, 140 140 // since we know how to restore it. 141 m_jit.load64(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), GPRInfo::tagTypeNumberRegister);142 profile.emitReportValue( m_jit, JSValueRegs(GPRInfo::tagTypeNumberRegister));143 m_jit.move(AssemblyHelpers::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister);141 jit.load64(AssemblyHelpers::Address(exit.m_jsValueSource.asAddress()), GPRInfo::tagTypeNumberRegister); 142 profile.emitReportValue(jit, JSValueRegs(GPRInfo::tagTypeNumberRegister)); 143 jit.move(AssemblyHelpers::TrustedImm64(TagTypeNumber), GPRInfo::tagTypeNumberRegister); 144 144 } else 145 profile.emitReportValue( m_jit, JSValueRegs(exit.m_jsValueSource.gpr()));145 profile.emitReportValue(jit, JSValueRegs(exit.m_jsValueSource.gpr())); 146 146 } 147 147 } … … 197 197 case UnboxedStrictInt52InGPR: 198 198 case UnboxedCellInGPR: 199 m_jit.store64(recovery.gpr(), scratch + index);199 jit.store64(recovery.gpr(), scratch + index); 200 200 break; 201 201 … … 215 215 case UnboxedDoubleInFPR: 216 216 case InFPR: 217 m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);218 m_jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0));217 jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0); 218 jit.storeDouble(recovery.fpr(), MacroAssembler::Address(GPRInfo::regT0)); 219 219 break; 220 220 … … 241 241 case Int52DisplacedInJSStack: 242 242 case StrictInt52DisplacedInJSStack: 243 m_jit.load64(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0);244 m_jit.store64(GPRInfo::regT0, scratch + index);243 jit.load64(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0); 244 jit.store64(GPRInfo::regT0, scratch + index); 245 245 break; 246 246 … … 253 253 // could toast some stack that the DFG used. We need to do it before storing to stack offsets 254 254 // used by baseline. 255 m_jit.addPtr(255 jit.addPtr( 256 256 CCallHelpers::TrustedImm32( 257 - m_jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)),257 -jit.codeBlock()->jitCode()->dfgCommon()->requiredRegisterCountForExit * sizeof(Register)), 258 258 CCallHelpers::framePointerRegister, CCallHelpers::stackPointerRegister); 259 259 260 260 // Restore the DFG callee saves and then save the ones the baseline JIT uses. 261 m_jit.emitRestoreCalleeSaves();262 m_jit.emitSaveCalleeSavesFor(m_jit.baselineCodeBlock());261 jit.emitRestoreCalleeSaves(); 262 jit.emitSaveCalleeSavesFor(jit.baselineCodeBlock()); 263 263 264 264 // The tag registers are needed to materialize recoveries below. 265 m_jit.emitMaterializeTagCheckRegisters();265 jit.emitMaterializeTagCheckRegisters(); 266 266 267 267 if (exit.isExceptionHandler()) 268 m_jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm);268 jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm); 269 269 270 270 // Do all data format conversions and store the results into the stack. … … 274 274 VirtualRegister reg = operands.virtualRegisterForIndex(index); 275 275 276 if (reg.isLocal() && reg.toLocal() < static_cast<int>( m_jit.baselineCodeBlock()->calleeSaveSpaceAsVirtualRegisters()))276 if (reg.isLocal() && reg.toLocal() < static_cast<int>(jit.baselineCodeBlock()->calleeSaveSpaceAsVirtualRegisters())) 277 277 continue; 278 278 … … 286 286 case BooleanDisplacedInJSStack: 287 287 case InFPR: 288 m_jit.load64(scratch + index, GPRInfo::regT0);289 m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));288 jit.load64(scratch + index, GPRInfo::regT0); 289 jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand)); 290 290 break; 291 291 292 292 case UnboxedInt32InGPR: 293 293 case Int32DisplacedInJSStack: 294 m_jit.load64(scratch + index, GPRInfo::regT0);295 m_jit.zeroExtend32ToPtr(GPRInfo::regT0, GPRInfo::regT0);296 m_jit.or64(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0);297 m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));294 jit.load64(scratch + index, GPRInfo::regT0); 295 jit.zeroExtend32ToPtr(GPRInfo::regT0, GPRInfo::regT0); 296 jit.or64(GPRInfo::tagTypeNumberRegister, GPRInfo::regT0); 297 jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand)); 298 298 break; 299 299 300 300 case UnboxedInt52InGPR: 301 301 case Int52DisplacedInJSStack: 302 m_jit.load64(scratch + index, GPRInfo::regT0);303 m_jit.rshift64(302 jit.load64(scratch + index, GPRInfo::regT0); 303 jit.rshift64( 304 304 AssemblyHelpers::TrustedImm32(JSValue::int52ShiftAmount), GPRInfo::regT0); 305 m_jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);306 m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));305 jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0); 306 jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand)); 307 307 break; 308 308 309 309 case UnboxedStrictInt52InGPR: 310 310 case StrictInt52DisplacedInJSStack: 311 m_jit.load64(scratch + index, GPRInfo::regT0);312 m_jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0);313 m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));311 jit.load64(scratch + index, GPRInfo::regT0); 312 jit.boxInt52(GPRInfo::regT0, GPRInfo::regT0, GPRInfo::regT1, FPRInfo::fpRegT0); 313 jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand)); 314 314 break; 315 315 316 316 case UnboxedDoubleInFPR: 317 317 case DoubleDisplacedInJSStack: 318 m_jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0);319 m_jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0);320 m_jit.purifyNaN(FPRInfo::fpRegT0);321 m_jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0);322 m_jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand));318 jit.move(AssemblyHelpers::TrustedImmPtr(scratch + index), GPRInfo::regT0); 319 jit.loadDouble(MacroAssembler::Address(GPRInfo::regT0), FPRInfo::fpRegT0); 320 jit.purifyNaN(FPRInfo::fpRegT0); 321 jit.boxDouble(FPRInfo::fpRegT0, GPRInfo::regT0); 322 jit.store64(GPRInfo::regT0, AssemblyHelpers::addressFor(operand)); 323 323 break; 324 324 325 325 case Constant: 326 m_jit.store64(326 jit.store64( 327 327 AssemblyHelpers::TrustedImm64(JSValue::encode(recovery.constant())), 328 328 AssemblyHelpers::addressFor(operand)); … … 346 346 // inline call frame scope - but for now the DFG wouldn't do that. 347 347 348 emitRestoreArguments( operands);348 emitRestoreArguments(jit, operands); 349 349 350 350 // Adjust the old JIT's execute counter. Since we are exiting OSR, we know … … 384 384 // counterValueForOptimizeAfterWarmUp(). 385 385 386 handleExitCounts( m_jit, exit);386 handleExitCounts(jit, exit); 387 387 388 388 // Reify inlined call frames. 389 389 390 reifyInlinedCallFrames( m_jit, exit);390 reifyInlinedCallFrames(jit, exit); 391 391 392 392 // And finish. 393 adjustAndJumpToTarget(vm, m_jit, exit);393 adjustAndJumpToTarget(vm, jit, exit); 394 394 } 395 395 -
trunk/Source/JavaScriptCore/dfg/DFGThunks.cpp
r220219 r220298 96 96 LinkBuffer patchBuffer(jit, GLOBAL_THUNK_ID); 97 97 98 patchBuffer.link(functionCall, compileOSRExit);98 patchBuffer.link(functionCall, OSRExit::compileOSRExit); 99 99 100 100 return FINALIZE_CODE(patchBuffer, ("DFG OSR exit generation thunk"));
Note: See TracChangeset
for help on using the changeset viewer.