Changeset 209673 in webkit
- Timestamp:
- Dec 10, 2016, 1:04:05 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r209668 r209673 1 2016-12-10 Michael Saboff <msaboff@apple.com> 2 3 REGRESSION(r209653) Crash in CallFrameShuffler::snapshot() 4 https://bugs.webkit.org/show_bug.cgi?id=165728 5 6 Reviewed by Filip Pizlo. 7 8 New regression test. 9 10 * stress/regress-165728.js: Added. 11 (sum1): 12 (sum2): 13 (tailCaller): 14 (test): 15 1 16 2016-12-10 Keith Miller <keith_miller@apple.com> 2 17 -
trunk/Source/JavaScriptCore/ChangeLog
r209668 r209673 1 2016-12-10 Michael Saboff <msaboff@apple.com> 2 3 REGRESSION(r209653) Crash in CallFrameShuffler::snapshot() 4 https://bugs.webkit.org/show_bug.cgi?id=165728 5 6 Reviewed by Filip Pizlo. 7 8 It can be the case that a JSValueReg's CachedRecovery is the source for mutliple 9 GPRs. We only store the CachedRecovery in one slot of m_newRegisters to simplify 10 the recovery process. This is also done for the case where the recovery source 11 and destination are the same GPR. 12 13 In light of this change, snapshot needs to be taught that one CacheRecovery is 14 the source for multiple registers. This is done by using a two step process. 15 First find all the argument CachedRecovery's and create a vector mapping all of 16 the target GPRs and the source recovery. Then use that vector to get the 17 recovery for each register. 18 19 * jit/CallFrameShuffler.h: 20 (JSC::CallFrameShuffler::snapshot): 21 1 22 2016-12-10 Keith Miller <keith_miller@apple.com> 2 23 -
trunk/Source/JavaScriptCore/jit/CallFrameShuffler.h
r209653 r209673 114 114 } 115 115 data.args.resize(argCount()); 116 117 Vector<ValueRecovery> registerArgRecoveries; 118 #if USE(JSVALUE64) 119 // Find cached recoveries for all argument registers. 120 // We do this here, because a cached recovery may be the source for multiple 121 // argument registers, but it is only stored in one m_newRegister index. 122 if (data.argumentsInRegisters) { 123 unsigned maxArgumentRegister = std::min(static_cast<unsigned>(argCount()), NUMBER_OF_JS_FUNCTION_ARGUMENT_REGISTERS); 124 registerArgRecoveries.resize(maxArgumentRegister); 125 for (size_t i = 0; i < maxArgumentRegister; ++i) { 126 Reg reg { argumentRegisterForFunctionArgument(i) }; 127 CachedRecovery* cachedRecovery { m_newRegisters[reg] }; 128 if (cachedRecovery) { 129 for (auto jsValueReg : cachedRecovery->gprTargets()) 130 registerArgRecoveries[jsFunctionArgumentForArgumentRegister(jsValueReg.gpr())] = cachedRecovery->recovery(); 131 } 132 } 133 } 134 #endif 135 116 136 for (size_t i = 0; i < argCount(); ++i) { 117 137 if (argumentsLocation == StackArgs || i >= NUMBER_OF_JS_FUNCTION_ARGUMENT_REGISTERS) … … 119 139 else { 120 140 Reg reg { argumentRegisterForFunctionArgument(i) }; 121 CachedRecovery* cachedRecovery { m_newRegisters[reg] };122 data.args[i] = cachedRecovery->recovery();141 ASSERT(registerArgRecoveries[i]); 142 data.args[i] = registerArgRecoveries[i]; 123 143 } 124 144 } … … 441 461 #endif 442 462 443 // This stores, for each register, information about the recovery 444 // for the value that should eventually go into that register. The 445 // only registers that have a target recovery will be callee-save 446 // registers, as well as possibly one JSValueRegs for holding the 447 // callee. 463 // This stores information about the recovery for the value that 464 // should eventually go into that register. In some cases there 465 // are recoveries that have multiple targets. For those recoveries, 466 // only the first target register in the map has the recovery. 467 // We optimize the case where there are multiple targets for one 468 // recovery where one of those targets is also the source register. 469 // Restoring the first target becomes a nop and simplifies the logic 470 // of restoring the remaining targets. 448 471 // 449 472 // Once the correct value has been put into the registers, and 450 473 // contrary to what we do with m_newFrame, we keep the entry in 451 474 // m_newRegisters to simplify spilling. 475 // 476 // If a recovery has multiple target registers, we copy the value 477 // from the first target register to the remaining target registers 478 // at the end of the shuffling process. 452 479 RegisterMap<CachedRecovery*> m_newRegisters; 453 480
Note:
See TracChangeset
for help on using the changeset viewer.