Changeset 161543 in webkit
- Timestamp:
- Jan 8, 2014 8:11:59 PM (10 years ago)
- Location:
- branches/jsCStack/Source/JavaScriptCore
- Files:
-
- 9 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/jsCStack/Source/JavaScriptCore/ChangeLog
r161531 r161543 1 2014-01-08 Filip Pizlo <fpizlo@apple.com> 2 3 FTL should not use the inputs of an add or sub as the live-at-exit values in an overflow check, if the values aren't live after 4 https://bugs.webkit.org/show_bug.cgi?id=126545 5 6 Not yet reviewed. 7 8 Introduces the notion of an ExitValue that is computed by doing some math on two 9 exit arguments. This gets used by LowerDFGToLLVM by tracking the 10 AvailableRecoveries - i.e. the set of ways we know how to recover the value of a 11 node by performing math on LValue's - and then trying to pick an AvailableRecovery 12 if we try to exit with an Availability pointing to a Node that isn't a constant. 13 The compileArithAddOrSub() code adds AvailableRecoveries for the ways you could 14 recovery the left or right operand by using the result. 15 16 Doing this uncovered a bug in stackmap constant parsing where we were casting a 17 32-bit value to 16-bit, thereby losing the top bits. 18 19 * JavaScriptCore.xcodeproj/project.pbxproj: 20 * ftl/FTLAvailableRecovery.cpp: Added. 21 (JSC::FTL::AvailableRecovery::dump): 22 * ftl/FTLAvailableRecovery.h: Added. 23 (JSC::FTL::AvailableRecovery::AvailableRecovery): 24 (JSC::FTL::AvailableRecovery::node): 25 (JSC::FTL::AvailableRecovery::format): 26 (JSC::FTL::AvailableRecovery::opcode): 27 (JSC::FTL::AvailableRecovery::left): 28 (JSC::FTL::AvailableRecovery::right): 29 * ftl/FTLExitValue.cpp: 30 (JSC::FTL::ExitValue::dumpInContext): 31 * ftl/FTLExitValue.h: 32 (JSC::FTL::ExitValue::recovery): 33 (JSC::FTL::ExitValue::isRecovery): 34 (JSC::FTL::ExitValue::leftRecoveryArgument): 35 (JSC::FTL::ExitValue::rightRecoveryArgument): 36 (JSC::FTL::ExitValue::recoveryFormat): 37 (JSC::FTL::ExitValue::recoveryOpcode): 38 (JSC::FTL::ExitValue::valueFormat): 39 * ftl/FTLLowerDFGToLLVM.cpp: 40 (JSC::FTL::LowerDFGToLLVM::compileNode): 41 (JSC::FTL::LowerDFGToLLVM::compileArithAddOrSub): 42 (JSC::FTL::LowerDFGToLLVM::appendOSRExit): 43 (JSC::FTL::LowerDFGToLLVM::addExitArgumentForNode): 44 (JSC::FTL::LowerDFGToLLVM::doesKill): 45 (JSC::FTL::LowerDFGToLLVM::addAvailableRecovery): 46 * ftl/FTLOSRExitCompiler.cpp: 47 (JSC::FTL::compileStub): 48 * ftl/FTLRecoveryOpcode.cpp: Added. 49 (WTF::printInternal): 50 * ftl/FTLRecoveryOpcode.h: Added. 51 * ftl/FTLStackMaps.h: 52 * tests/stress/add-constant-overflow-recovery.js: Added. 53 (foo): 54 * tests/stress/add-int52-constant-overflow-recovery.js: Added. 55 (foo): 56 * tests/stress/add-int52-large-constant-overflow-recovery.js: Added. 57 (foo): 58 * tests/stress/add-overflow-recovery.js: Added. 59 (foo): 60 * tests/stress/add-small-constant-overflow-recovery.js: Added. 61 (foo): 62 1 63 2014-01-08 Michael Saboff <msaboff@apple.com> 2 64 -
branches/jsCStack/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r161409 r161543 237 237 0F485321187750560083B687 /* DFGArithMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F48531F187750560083B687 /* DFGArithMode.cpp */; }; 238 238 0F485322187750560083B687 /* DFGArithMode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485320187750560083B687 /* DFGArithMode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 239 0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F485323187DFDEC0083B687 /* FTLAvailableRecovery.cpp */; }; 240 0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485324187DFDEC0083B687 /* FTLAvailableRecovery.h */; settings = {ATTRIBUTES = (Private, ); }; }; 241 0F485329187DFDEC0083B687 /* FTLRecoveryOpcode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F485325187DFDEC0083B687 /* FTLRecoveryOpcode.cpp */; }; 242 0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; }; 239 243 0F493AFA16D0CAD30084508B /* SourceProvider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F493AF816D0CAD10084508B /* SourceProvider.cpp */; }; 240 244 0F4B94DC17B9F07500DD03A4 /* TypedArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1567 1571 0F48531F187750560083B687 /* DFGArithMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGArithMode.cpp; path = dfg/DFGArithMode.cpp; sourceTree = "<group>"; }; 1568 1572 0F485320187750560083B687 /* DFGArithMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGArithMode.h; path = dfg/DFGArithMode.h; sourceTree = "<group>"; }; 1573 0F485323187DFDEC0083B687 /* FTLAvailableRecovery.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLAvailableRecovery.cpp; path = ftl/FTLAvailableRecovery.cpp; sourceTree = "<group>"; }; 1574 0F485324187DFDEC0083B687 /* FTLAvailableRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLAvailableRecovery.h; path = ftl/FTLAvailableRecovery.h; sourceTree = "<group>"; }; 1575 0F485325187DFDEC0083B687 /* FTLRecoveryOpcode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLRecoveryOpcode.cpp; path = ftl/FTLRecoveryOpcode.cpp; sourceTree = "<group>"; }; 1576 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLRecoveryOpcode.h; path = ftl/FTLRecoveryOpcode.h; sourceTree = "<group>"; }; 1569 1577 0F493AF816D0CAD10084508B /* SourceProvider.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SourceProvider.cpp; sourceTree = "<group>"; }; 1570 1578 0F4B94DB17B9F07500DD03A4 /* TypedArrayInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypedArrayInlines.h; sourceTree = "<group>"; }; … … 2865 2873 0FEA0A191708B00700BB722C /* FTLAbstractHeapRepository.cpp */, 2866 2874 0FEA0A1A1708B00700BB722C /* FTLAbstractHeapRepository.h */, 2875 0F485323187DFDEC0083B687 /* FTLAvailableRecovery.cpp */, 2876 0F485324187DFDEC0083B687 /* FTLAvailableRecovery.h */, 2867 2877 0FEA09FE170513DB00BB722C /* FTLCapabilities.cpp */, 2868 2878 0FEA09FF170513DB00BB722C /* FTLCapabilities.h */, … … 2913 2923 0FEA0A291709629600BB722C /* FTLOutput.cpp */, 2914 2924 0FEA0A06170513DB00BB722C /* FTLOutput.h */, 2925 0F485325187DFDEC0083B687 /* FTLRecoveryOpcode.cpp */, 2926 0F485326187DFDEC0083B687 /* FTLRecoveryOpcode.h */, 2915 2927 0F6B1CBF1862C47800845D97 /* FTLRegisterAtOffset.cpp */, 2916 2928 0F6B1CC01862C47800845D97 /* FTLRegisterAtOffset.h */, … … 4420 4432 A1A009C01831A22D00CF8711 /* MacroAssemblerARM64.h in Headers */, 4421 4433 86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */, 4434 0F485328187DFDEC0083B687 /* FTLAvailableRecovery.h in Headers */, 4422 4435 0F256C361627B0AD007F2783 /* DFGCallArrayAllocatorSlowPathGenerator.h in Headers */, 4423 4436 0F7B294B14C3CD2F007C3DB1 /* DFGCapabilities.h in Headers */, … … 4552 4565 A59455931824744700CC3843 /* JSGlobalObjectDebuggable.h in Headers */, 4553 4566 0FEA0A0A170513DB00BB722C /* FTLCapabilities.h in Headers */, 4567 0F48532A187DFDEC0083B687 /* FTLRecoveryOpcode.h in Headers */, 4554 4568 0FEA0A231709606900BB722C /* FTLCommonValues.h in Headers */, 4555 4569 0FEA0A0C170513DB00BB722C /* FTLCompile.h in Headers */, … … 5566 5580 0FD8A32717D51F5700CA2C40 /* DFGTierUpCheckInjectionPhase.cpp in Sources */, 5567 5581 0FD8A32917D51F5700CA2C40 /* DFGToFTLDeferredCompilationCallback.cpp in Sources */, 5582 0F485327187DFDEC0083B687 /* FTLAvailableRecovery.cpp in Sources */, 5568 5583 0FD8A32B17D51F5700CA2C40 /* DFGToFTLForOSREntryDeferredCompilationCallback.cpp in Sources */, 5569 5584 0F63944015C75F1D006A597C /* DFGTypeCheckHoistingPhase.cpp in Sources */, … … 5698 5713 C25D709B16DE99F400FCA6BC /* JSManagedValue.mm in Sources */, 5699 5714 A700874117CBE8EB00C3E643 /* JSMap.cpp in Sources */, 5715 0F485329187DFDEC0083B687 /* FTLRecoveryOpcode.cpp in Sources */, 5700 5716 14874AE315EBDE4A002E3587 /* JSNameScope.cpp in Sources */, 5701 5717 A72700900DAC6BBC00E548D7 /* JSNotAnObject.cpp in Sources */, -
branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.cpp
r159394 r161543 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 60 60 out.print("InJSStackAsDouble:r", virtualRegister()); 61 61 return; 62 case ExitValueRecovery: 63 out.print("Recovery(", recoveryOpcode(), ", arg", leftRecoveryArgument(), ", arg", rightRecoveryArgument(), ", ", recoveryFormat(), ")"); 64 return; 62 65 } 63 66 -
branches/jsCStack/Source/JavaScriptCore/ftl/FTLExitValue.h
r160600 r161543 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 32 32 33 33 #include "FTLExitArgument.h" 34 #include "FTLRecoveryOpcode.h" 34 35 #include "JSCJSValue.h" 35 36 #include "VirtualRegister.h" … … 52 53 ExitValueInJSStackAsInt32, 53 54 ExitValueInJSStackAsInt52, 54 ExitValueInJSStackAsDouble 55 ExitValueInJSStackAsDouble, 56 ExitValueRecovery 55 57 }; 56 58 … … 116 118 result.m_kind = ExitValueArgument; 117 119 result.u.argument = argument.representation(); 120 return result; 121 } 122 123 static ExitValue recovery(RecoveryOpcode opcode, unsigned leftArgument, unsigned rightArgument, ValueFormat format) 124 { 125 ExitValue result; 126 result.m_kind = ExitValueRecovery; 127 result.u.recovery.opcode = opcode; 128 result.u.recovery.leftArgument = leftArgument; 129 result.u.recovery.rightArgument = rightArgument; 130 result.u.recovery.format = format; 118 131 return result; 119 132 } … … 136 149 bool isConstant() const { return kind() == ExitValueConstant; } 137 150 bool isArgument() const { return kind() == ExitValueArgument; } 151 bool isRecovery() const { return kind() == ExitValueRecovery; } 138 152 139 153 ExitArgument exitArgument() const … … 141 155 ASSERT(isArgument()); 142 156 return ExitArgument(u.argument); 157 } 158 159 unsigned leftRecoveryArgument() const 160 { 161 ASSERT(isRecovery()); 162 return u.recovery.leftArgument; 163 } 164 165 unsigned rightRecoveryArgument() const 166 { 167 ASSERT(isRecovery()); 168 return u.recovery.rightArgument; 169 } 170 171 ValueFormat recoveryFormat() const 172 { 173 ASSERT(isRecovery()); 174 return static_cast<ValueFormat>(u.recovery.format); 175 } 176 177 RecoveryOpcode recoveryOpcode() const 178 { 179 ASSERT(isRecovery()); 180 return static_cast<RecoveryOpcode>(u.recovery.opcode); 143 181 } 144 182 … … 191 229 case ExitValueInJSStackAsDouble: 192 230 return ValueFormatDouble; 231 232 case ExitValueRecovery: 233 return recoveryFormat(); 193 234 } 194 235 … … 206 247 EncodedJSValue constant; 207 248 int virtualRegister; 249 struct { 250 uint16_t leftArgument; 251 uint16_t rightArgument; 252 uint16_t opcode; 253 uint16_t format; 254 } recovery; 208 255 } u; 209 256 }; -
branches/jsCStack/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp
r161515 r161543 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 33 33 #include "DFGInPlaceAbstractState.h" 34 34 #include "FTLAbstractHeapRepository.h" 35 #include "FTLAvailableRecovery.h" 35 36 #include "FTLForOSREntryJITCode.h" 36 37 #include "FTLFormattedValue.h" … … 257 258 dataLog("Lowering ", m_node, "\n"); 258 259 260 m_availableRecoveries.resize(0); 261 259 262 bool shouldExecuteEffects = m_interpreter.startExecuting(m_node); 260 263 … … 296 299 break; 297 300 case ArithAdd: 298 compileAddSub();299 break;300 301 case ArithSub: 301 compileA ddSub();302 compileArithAddOrSub(); 302 303 break; 303 304 case ArithMul: … … 809 810 } 810 811 811 void compileA ddSub()812 void compileArithAddOrSub() 812 813 { 813 814 bool isSub = m_node->op() == ArithSub; … … 822 823 } 823 824 824 LValue result = isSub ? m_out.subWithOverflow32(left, right) : m_out.addWithOverflow32(left, right); 825 LValue result; 826 if (!isSub) { 827 result = m_out.addWithOverflow32(left, right); 828 829 if (doesKill(m_node->child2())) { 830 addAvailableRecovery( 831 m_node->child2(), SubRecovery, 832 m_out.extractValue(result, 0), left, ValueFormatInt32); 833 } else if (doesKill(m_node->child1())) { 834 addAvailableRecovery( 835 m_node->child1(), SubRecovery, 836 m_out.extractValue(result, 0), right, ValueFormatInt32); 837 } 838 } else { 839 result = m_out.subWithOverflow32(left, right); 840 841 if (doesKill(m_node->child2())) { 842 // result = left - right 843 // result - left = -right 844 // right = left - result 845 addAvailableRecovery( 846 m_node->child2(), SubRecovery, 847 left, m_out.extractValue(result, 0), ValueFormatInt32); 848 } else if (doesKill(m_node->child1())) { 849 // result = left - right 850 // result + right = left 851 addAvailableRecovery( 852 m_node->child1(), AddRecovery, 853 m_out.extractValue(result, 0), right, ValueFormatInt32); 854 } 855 } 825 856 826 857 speculate(Overflow, noValue(), 0, m_out.extractValue(result, 1)); … … 842 873 LValue right = lowInt52(m_node->child2()); 843 874 844 LValue result = isSub ? m_out.subWithOverflow64(left, right) : m_out.addWithOverflow64(left, right); 875 LValue result; 876 if (!isSub) { 877 result = m_out.addWithOverflow64(left, right); 878 879 if (doesKill(m_node->child2())) { 880 addAvailableRecovery( 881 m_node->child2(), SubRecovery, 882 m_out.extractValue(result, 0), left, ValueFormatInt52); 883 } else if (doesKill(m_node->child1())) { 884 addAvailableRecovery( 885 m_node->child1(), SubRecovery, 886 m_out.extractValue(result, 0), right, ValueFormatInt52); 887 } 888 } else { 889 result = m_out.subWithOverflow64(left, right); 890 891 if (doesKill(m_node->child2())) { 892 // result = left - right 893 // result - left = -right 894 // right = left - result 895 addAvailableRecovery( 896 m_node->child2(), SubRecovery, 897 left, m_out.extractValue(result, 0), ValueFormatInt52); 898 } else if (doesKill(m_node->child1())) { 899 // result = left - right 900 // result + right = left 901 addAvailableRecovery( 902 m_node->child1(), AddRecovery, 903 m_out.extractValue(result, 0), right, ValueFormatInt52); 904 } 905 } 906 845 907 speculate(Int52Overflow, noValue(), 0, m_out.extractValue(result, 1)); 846 908 setInt52(m_out.extractValue(result, 0)); … … 4066 4128 ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition) 4067 4129 { 4068 if (verboseCompilationEnabled()) 4130 if (verboseCompilationEnabled()) { 4069 4131 dataLog(" OSR exit #", m_ftlState.jitCode->osrExit.size(), " with availability: ", m_availability, "\n"); 4132 if (!m_availableRecoveries.isEmpty()) 4133 dataLog(" Available recoveries: ", listDump(m_availableRecoveries), "\n"); 4134 } 4070 4135 4071 4136 ASSERT(m_ftlState.jitCode->osrExit.size() == m_ftlState.finalizer->osrExit.size()); … … 4191 4256 if (tryToSetConstantExitArgument(exit, index, node)) 4192 4257 return; 4258 4259 for (unsigned i = 0; i < m_availableRecoveries.size(); ++i) { 4260 AvailableRecovery recovery = m_availableRecoveries[i]; 4261 if (recovery.node() != node) 4262 continue; 4263 4264 exit.m_values[index] = ExitValue::recovery( 4265 recovery.opcode(), arguments.size(), arguments.size() + 1, 4266 recovery.format()); 4267 arguments.append(recovery.left()); 4268 arguments.append(recovery.right()); 4269 return; 4270 } 4193 4271 4194 4272 LoweredNodeValue value = m_int32Values.get(node); … … 4261 4339 } 4262 4340 4341 bool doesKill(Edge edge) 4342 { 4343 if (edge.doesNotKill()) 4344 return false; 4345 4346 if (edge->hasConstant()) 4347 return false; 4348 4349 return true; 4350 } 4351 4352 void addAvailableRecovery( 4353 Node* node, RecoveryOpcode opcode, LValue left, LValue right, ValueFormat format) 4354 { 4355 m_availableRecoveries.append(AvailableRecovery(node, opcode, left, right, format)); 4356 } 4357 4358 void addAvailableRecovery( 4359 Edge edge, RecoveryOpcode opcode, LValue left, LValue right, ValueFormat format) 4360 { 4361 addAvailableRecovery(edge.node(), opcode, left, right, format); 4362 } 4363 4263 4364 void setInt32(Node* node, LValue value) 4264 4365 { … … 4424 4525 Operands<Availability> m_availability; 4425 4526 4527 Vector<AvailableRecovery, 3> m_availableRecoveries; 4528 4426 4529 InPlaceAbstractState m_state; 4427 4530 AbstractInterpreter<InPlaceAbstractState> m_interpreter; -
branches/jsCStack/Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
r161445 r161543 1 1 /* 2 * Copyright (C) 2013 Apple Inc. All rights reserved.2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 135 135 break; 136 136 137 case ExitValueRecovery: 138 record->locations[value.rightRecoveryArgument()].restoreInto( 139 jit, jitCode->stackmaps, registerScratch, GPRInfo::regT1); 140 record->locations[value.leftRecoveryArgument()].restoreInto( 141 jit, jitCode->stackmaps, registerScratch, GPRInfo::regT0); 142 switch (value.recoveryOpcode()) { 143 case AddRecovery: 144 switch (value.recoveryFormat()) { 145 case ValueFormatInt32: 146 jit.add32(GPRInfo::regT1, GPRInfo::regT0); 147 break; 148 case ValueFormatInt52: 149 jit.add64(GPRInfo::regT1, GPRInfo::regT0); 150 break; 151 default: 152 RELEASE_ASSERT_NOT_REACHED(); 153 break; 154 } 155 break; 156 case SubRecovery: 157 switch (value.recoveryFormat()) { 158 case ValueFormatInt32: 159 jit.sub32(GPRInfo::regT1, GPRInfo::regT0); 160 break; 161 case ValueFormatInt52: 162 jit.sub64(GPRInfo::regT1, GPRInfo::regT0); 163 break; 164 default: 165 RELEASE_ASSERT_NOT_REACHED(); 166 break; 167 } 168 break; 169 default: 170 RELEASE_ASSERT_NOT_REACHED(); 171 break; 172 } 173 break; 174 137 175 default: 138 176 RELEASE_ASSERT_NOT_REACHED(); -
branches/jsCStack/Source/JavaScriptCore/ftl/FTLStackMaps.h
r159448 r161543 62 62 int8_t size; 63 63 Kind kind; 64 int 16_t offset;64 int32_t offset; 65 65 66 66 void parse(DataView*, unsigned& offset);
Note: See TracChangeset
for help on using the changeset viewer.