Changeset 215531 in webkit
- Timestamp:
- Apr 19, 2017, 2:51:52 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r215525 r215531 1 2017-04-19 Mark Lam <mark.lam@apple.com> 2 3 B3StackmapSpecial should handle when stackmap values are not recoverable from a Def'ed arg. 4 https://bugs.webkit.org/show_bug.cgi?id=170973 5 <rdar://problem/30318657> 6 7 Reviewed by Filip Pizlo. 8 9 * stress/regress-170973.js: Added. 10 1 11 2017-04-19 JF Bastien <jfbastien@apple.com> 2 12 -
trunk/Source/JavaScriptCore/ChangeLog
r215526 r215531 1 2017-04-19 Mark Lam <mark.lam@apple.com> 2 3 B3StackmapSpecial should handle when stackmap values are not recoverable from a Def'ed arg. 4 https://bugs.webkit.org/show_bug.cgi?id=170973 5 <rdar://problem/30318657> 6 7 Reviewed by Filip Pizlo. 8 9 In the event of an arithmetic overflow on a binary sub instruction (where the 10 result register is same as one of the operand registers), the CheckSub FTL 11 operation will try to recover the original value in the clobbered result register. 12 13 This recover is done by adding the other operand value to the result register. 14 However, this recovery method only works if the width of the original value in 15 the result register is less or equal to the width of the expected result. If the 16 width of the original operand value (e.g. a JSInt32) is wider than the result 17 (e.g. a machine Int32), then the sub operation would have zero extended the 18 result and cleared the upper 32-bits of the result register. Recovery by adding 19 back the other operand will not restore the JSValue tag in the upper word. 20 21 This poses a problem if the stackmap value for the operand relies on that same 22 clobbered register. 23 24 The fix is to detect this potential scenario (i.e. width of the Def's arg < width 25 of a stackmap value). If this condition is detected, we'll declare the stackmap 26 value to be LateColdUse to ensure that the register allocator gives it a 27 different register if needed so that it's not dependent on the clobbered register. 28 29 * b3/B3CheckSpecial.cpp: 30 (JSC::B3::CheckSpecial::forEachArg): 31 * b3/B3PatchpointSpecial.cpp: 32 (JSC::B3::PatchpointSpecial::forEachArg): 33 * b3/B3StackmapSpecial.cpp: 34 (JSC::B3::StackmapSpecial::forEachArgImpl): 35 * b3/B3StackmapSpecial.h: 36 1 37 2017-04-19 JF Bastien <jfbastien@apple.com> 2 38 -
trunk/Source/JavaScriptCore/b3/B3CheckSpecial.cpp
r212970 r215531 109 109 void CheckSpecial::forEachArg(Inst& inst, const ScopedLambda<Inst::EachArgCallback>& callback) 110 110 { 111 std::optional<Width> optionalDefArgWidth; 111 112 Inst hidden = hiddenBranch(inst); 112 113 hidden.forEachArg( 113 114 [&] (Arg& arg, Arg::Role role, Bank bank, Width width) { 115 if (Arg::isAnyDef(role)) { 116 ASSERT(!optionalDefArgWidth); // There can only be one Def'ed arg. 117 optionalDefArgWidth = width; 118 } 114 119 unsigned index = &arg - &hidden.args[0]; 115 120 callback(inst.args[1 + index], role, bank, width); … … 119 124 if (m_checkKind.opcode == BranchAdd32 || m_checkKind.opcode == BranchAdd64) 120 125 firstRecoverableIndex = 1; 121 forEachArgImpl(numB3Args(inst), m_numCheckArgs + 1, inst, m_stackmapRole, firstRecoverableIndex, callback );126 forEachArgImpl(numB3Args(inst), m_numCheckArgs + 1, inst, m_stackmapRole, firstRecoverableIndex, callback, optionalDefArgWidth); 122 127 } 123 128 -
trunk/Source/JavaScriptCore/b3/B3PatchpointSpecial.cpp
r212970 r215531 60 60 } 61 61 62 forEachArgImpl(0, argIndex, inst, SameAsRep, std::nullopt, callback );62 forEachArgImpl(0, argIndex, inst, SameAsRep, std::nullopt, callback, std::nullopt); 63 63 argIndex += inst.origin->numChildren(); 64 64 -
trunk/Source/JavaScriptCore/b3/B3StackmapSpecial.cpp
r215407 r215531 75 75 unsigned numIgnoredB3Args, unsigned numIgnoredAirArgs, 76 76 Inst& inst, RoleMode roleMode, std::optional<unsigned> firstRecoverableIndex, 77 const ScopedLambda<Inst::EachArgCallback>& callback )77 const ScopedLambda<Inst::EachArgCallback>& callback, std::optional<Width> optionalDefArgWidth) 78 78 { 79 79 StackmapValue* value = inst.origin->as<StackmapValue>(); … … 84 84 ASSERT(value->children().size() >= numIgnoredB3Args); 85 85 ASSERT(inst.args.size() - numIgnoredAirArgs >= value->children().size() - numIgnoredB3Args); 86 86 ASSERT(inst.args[0].kind() == Arg::Kind::Special); 87 87 88 for (unsigned i = 0; i < value->children().size() - numIgnoredB3Args; ++i) { 88 89 Arg& arg = inst.args[i + numIgnoredAirArgs]; … … 120 121 RELEASE_ASSERT_NOT_REACHED(); 121 122 break; 123 } 124 125 // If the Def'ed arg has a smaller width than the a stackmap value, then we may not 126 // be able to recover the stackmap value. So, force LateColdUse to preserve the 127 // original stackmap value across the Special operation. 128 if (!Arg::isLateUse(role) && optionalDefArgWidth && *optionalDefArgWidth < child.value()->resultWidth()) { 129 if (Arg::isWarmUse(role)) 130 role = Arg::LateUse; 131 else 132 role = Arg::LateColdUse; 122 133 } 123 134 break; -
trunk/Source/JavaScriptCore/b3/B3StackmapSpecial.h
r208985 r215531 1 1 /* 2 * Copyright (C) 2015-201 6Apple Inc. All rights reserved.2 * Copyright (C) 2015-2017 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 61 61 unsigned numIgnoredB3Args, unsigned numIgnoredAirArgs, 62 62 Air::Inst&, RoleMode, std::optional<unsigned> firstRecoverableIndex, 63 const ScopedLambda<Air::Inst::EachArgCallback>& );64 63 const ScopedLambda<Air::Inst::EachArgCallback>&, std::optional<Width> optionalDefArgWidth); 64 65 65 bool isValidImpl( 66 66 unsigned numIgnoredB3Args, unsigned numIgnoredAirArgs,
Note:
See TracChangeset
for help on using the changeset viewer.