Changeset 205330 in webkit
- Timestamp:
- Sep 1, 2016 6:19:42 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 1 added
- 12 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/B3CallingConventions.cpp
r205329 r205330 1 1 /* 2 * Copyright (C) 201 2, 2013Apple Inc. All rights reserved.2 * Copyright (C) 2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 24 */ 25 25 26 #i fndef LLIntThunks_h27 # define LLIntThunks_h26 #include "config.h" 27 #include "B3CallingConventions.h" 28 28 29 #include "MacroAssemblerCodeRef.h" 29 #include <wtf/NeverDestroyed.h> 30 31 #if ENABLE(B3_JIT) 30 32 31 33 namespace JSC { 32 34 33 class VM; 34 struct ProtoCallFrame; 35 namespace B3 { 35 36 36 extern "C" { 37 EncodedJSValue vmEntryToJavaScript(void*, VM*, ProtoCallFrame*); 38 EncodedJSValue vmEntryToNative(void*, VM*, ProtoCallFrame*); 37 JSCCallingConvention& jscCallingConvention() 38 { 39 static LazyNeverDestroyed<JSCCallingConvention> staticJSCCallingConvention; 40 static std::once_flag staticJSCCallingConventionFlag; 41 std::call_once(staticJSCCallingConventionFlag, [] () { 42 staticJSCCallingConvention.construct(Vector<GPRReg>(), RegisterSet::calleeSaveRegisters()); 43 }); 44 45 return staticJSCCallingConvention; 39 46 } 40 47 41 namespace LLInt { 48 } // namespace B3 42 49 43 MacroAssemblerCodeRef functionForCallEntryThunkGenerator(VM*); 44 MacroAssemblerCodeRef functionForConstructEntryThunkGenerator(VM*); 45 MacroAssemblerCodeRef functionForCallArityCheckThunkGenerator(VM*); 46 MacroAssemblerCodeRef functionForConstructArityCheckThunkGenerator(VM*); 47 MacroAssemblerCodeRef evalEntryThunkGenerator(VM*); 48 MacroAssemblerCodeRef programEntryThunkGenerator(VM*); 49 MacroAssemblerCodeRef moduleProgramEntryThunkGenerator(VM*); 50 } // namespace JSC 50 51 51 } } // namespace JSC::LLInt 52 53 #endif // LLIntThunks_h 52 #endif // ENABLE(B3_JIT) -
trunk/Source/JavaScriptCore/ChangeLog
r205328 r205330 79 79 * runtime/CommonSlowPaths.cpp: 80 80 (JSC::SLOW_PATH_DECL): 81 82 2016-09-01 Keith Miller <keith_miller@apple.com> 83 84 WASM functions should be able to use arguments 85 https://bugs.webkit.org/show_bug.cgi?id=161471 86 87 Reviewed by Benjamin Poulain. 88 89 This patch does a couple of changes: 90 91 1) Adds a new Calling Convention class for B3. This class is used to make it easy to specify the calling convention of a function. In particular it knows which arguments are in registers and which ones should be on the stack. For now, nothing uses the argument registers, in the future we will use these for WASM and/or JS. Additonally, it knows the callee save registers for any given function. The main advantage of this class is that it makes it easy to iterate over the arguments of your function without having to worry about the details of the calling convention you are using. 92 93 2) Makes the WASM calling convention the same as the JS one. Currently, the CodeBlock, CodeOrigin, and Callee are all 0. Since they have no value. Additionally, since we call into WASM from C++ through vmEntryToJavaScript, if there are no arguments to the callee we insert a null pointer as the first argument. 94 95 3) Since WASM expects the arguments to be mapped to function locals we map the argument stack slots to variables immediately after the function prologue. 96 97 * B3CallingConventions.cpp: Copied from Source/JavaScriptCore/llint/LLIntThunks.h. 98 (JSC::B3::jscCallingConvention): 99 * B3CallingConventions.h: Added. 100 (JSC::B3::CallingConvention::CallingConvention): 101 (JSC::B3::CallingConvention::iterate): 102 (JSC::B3::nextJSCOffset): 103 * JavaScriptCore.xcodeproj/project.pbxproj: 104 * interpreter/ProtoCallFrame.h: 105 * llint/LLIntThunks.cpp: 106 (JSC::vmEntryToWASM): 107 * llint/LLIntThunks.h: 108 * testWASM.cpp: 109 (invoke): 110 (box): 111 (runWASMTests): 112 * wasm/WASMB3IRGenerator.cpp: 113 (JSC::WASM::B3IRGenerator::addLocal): 114 (JSC::WASM::B3IRGenerator::addArguments): 115 (JSC::WASM::B3IRGenerator::getLocal): 116 * wasm/WASMFormat.h: 117 * wasm/WASMFunctionParser.h: 118 (JSC::WASM::FunctionParser<Context>::FunctionParser): 119 (JSC::WASM::FunctionParser<Context>::parseExpression): 120 * wasm/WASMModuleParser.cpp: 121 (JSC::WASM::ModuleParser::parseFunctionTypes): 122 (JSC::WASM::ModuleParser::parseFunctionSignatures): 123 * wasm/WASMModuleParser.h: 124 * wasm/WASMOps.h: 81 125 82 126 2016-09-01 Keith Miller <keith_miller@apple.com> -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r205198 r205330 1180 1180 531374BD1D5CE67600AF7A0B /* WASMPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 531374BC1D5CE67600AF7A0B /* WASMPlan.h */; }; 1181 1181 531374BF1D5CE95000AF7A0B /* WASMPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */; }; 1182 531B3C871D74C603005B3236 /* B3CallingConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 531B3C861D74C603005B3236 /* B3CallingConventions.h */; }; 1182 1183 53486BB71C1795C300F6F3AF /* JSTypedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 53486BB61C1795C300F6F3AF /* JSTypedArray.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1183 1184 53486BBB1C18E84500F6F3AF /* JSTypedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */; }; … … 1188 1189 5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; }; 1189 1190 5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; }; 1191 5388B4041D76640B00D3D852 /* B3CallingConventions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */; }; 1190 1192 53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; }; 1191 1193 539EB0791D55607000C82EF7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; }; … … 3372 3374 531374BC1D5CE67600AF7A0B /* WASMPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMPlan.h; sourceTree = "<group>"; }; 3373 3375 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMPlan.cpp; sourceTree = "<group>"; }; 3376 531B3C861D74C603005B3236 /* B3CallingConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = B3CallingConventions.h; sourceTree = "<group>"; }; 3374 3377 53486BB61C1795C300F6F3AF /* JSTypedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArray.h; sourceTree = "<group>"; }; 3375 3378 53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArray.cpp; sourceTree = "<group>"; }; … … 3382 3385 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdaptiveInferredPropertyValueWatchpointBase.cpp; sourceTree = "<group>"; }; 3383 3386 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdaptiveInferredPropertyValueWatchpointBase.h; sourceTree = "<group>"; }; 3387 5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = B3CallingConventions.cpp; sourceTree = "<group>"; }; 3384 3388 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = "<group>"; }; 3385 3389 53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = "<group>"; }; … … 4776 4780 0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */, 4777 4781 0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */, 4782 5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */, 4783 531B3C861D74C603005B3236 /* B3CallingConventions.h */, 4778 4784 DC9A0C1C1D2D94EF0085124E /* B3CaseCollection.cpp */, 4779 4785 DC9A0C1D1D2D94EF0085124E /* B3CaseCollection.h */, … … 4890 4896 0FEC84F01BDACDAC0080FF74 /* B3SwitchValue.h */, 4891 4897 0F45703E1BE584CA0062A629 /* B3TimingScope.cpp */, 4898 0FEC84F21BDACDAC0080FF74 /* B3Type.h */, 4892 4899 0F45703F1BE584CA0062A629 /* B3TimingScope.h */, 4893 4900 0FEC84F11BDACDAC0080FF74 /* B3Type.cpp */, 4894 0FEC84F21BDACDAC0080FF74 /* B3Type.h */,4895 4901 DCFDFBD81D1F5D9800FE3D72 /* B3TypeMap.h */, 4896 4902 0FEC84F31BDACDAC0080FF74 /* B3UpsilonValue.cpp */, … … 8266 8272 0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */, 8267 8273 0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */, 8274 531B3C871D74C603005B3236 /* B3CallingConventions.h in Headers */, 8268 8275 79EE0C001B4AFB85000385C9 /* VariableEnvironment.h in Headers */, 8269 8276 0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */, … … 8917 8924 C2FCAE1217A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp in Sources */, 8918 8925 0F338E0D1BF0276C0013C88F /* B3DataSection.cpp in Sources */, 8926 5388B4041D76640B00D3D852 /* B3CallingConventions.cpp in Sources */, 8919 8927 65B8392F1BACAD6A0044E824 /* CachedRecovery.cpp in Sources */, 8920 8928 1428082D107EC0570013E7B2 /* CallData.cpp in Sources */, -
trunk/Source/JavaScriptCore/interpreter/ProtoCallFrame.h
r183935 r205330 31 31 namespace JSC { 32 32 33 struct ProtoCallFrame {33 struct JS_EXPORT_PRIVATE ProtoCallFrame { 34 34 Register codeBlockValue; 35 35 Register calleeValue; -
trunk/Source/JavaScriptCore/llint/LLIntThunks.cpp
r204912 r205330 42 42 namespace JSC { 43 43 44 EncodedJSValue JS_EXPORT_PRIVATE vmEntryToWASM(void* code, VM* vm, ProtoCallFrame* frame) 45 { 46 return vmEntryToJavaScript(code, vm, frame); 47 } 48 44 49 #if ENABLE(JIT) 45 50 -
trunk/Source/JavaScriptCore/llint/LLIntThunks.h
r204912 r205330 39 39 } 40 40 41 EncodedJSValue JS_EXPORT_PRIVATE vmEntryToWASM(void*, VM*, ProtoCallFrame*); 42 41 43 namespace LLInt { 42 44 -
trunk/Source/JavaScriptCore/testWASM.cpp
r204484 r205330 28 28 #include "B3Compilation.h" 29 29 #include "InitializeThreading.h" 30 #include "JSCJSValueInlines.h" 30 31 #include "JSString.h" 32 #include "LLIntThunks.h" 33 #include "ProtoCallFrame.h" 31 34 #include "VM.h" 32 35 #include "WASMPlan.h" … … 191 194 using namespace B3; 192 195 193 template<typename T, typename... Arguments> 194 T invoke(MacroAssemblerCodePtr ptr, Arguments... arguments) 195 { 196 T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(ptr.executableAddress()); 197 return function(arguments...); 198 } 199 200 template<typename T, typename... Arguments> 201 T invoke(const Compilation& code, Arguments... arguments) 202 { 203 return invoke<T>(code.code(), arguments...); 196 template<typename T> 197 T invoke(MacroAssemblerCodePtr ptr, std::initializer_list<JSValue> args) 198 { 199 JSValue firstArgument; 200 // Since vmEntryToJavaScript expects a this value we claim there is one... there isn't. 201 int argCount = 1; 202 JSValue* remainingArguments = nullptr; 203 if (args.size()) { 204 remainingArguments = const_cast<JSValue*>(args.begin()); 205 firstArgument = *remainingArguments; 206 remainingArguments++; 207 argCount = args.size(); 208 } 209 210 ProtoCallFrame protoCallFrame; 211 protoCallFrame.init(nullptr, nullptr, firstArgument, argCount, remainingArguments); 212 213 // This won't work for floating point values but we don't have those yet. 214 return static_cast<T>(vmEntryToWASM(ptr.executableAddress(), vm, &protoCallFrame)); 215 } 216 217 template<typename T> 218 T invoke(const Compilation& code, std::initializer_list<JSValue> args) 219 { 220 return invoke<T>(code.code(), args); 221 } 222 223 inline JSValue box(uint64_t value) 224 { 225 return JSValue::decode(value); 204 226 } 205 227 … … 225 247 226 248 // Test this doesn't crash. 227 RELEASE_ASSERT(invoke<int>(*plan.result[0] ) == 5);249 RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 5); 228 250 } 229 251 … … 247 269 248 270 // Test this doesn't crash. 249 RELEASE_ASSERT(invoke<int>(*plan.result[0] ) == 11);271 RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 11); 250 272 } 251 273 … … 268 290 269 291 // Test this doesn't crash. 270 RELEASE_ASSERT(invoke<int>(*plan.result[0] ) == 11);292 RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 11); 271 293 } 272 294 … … 289 311 290 312 // Test this doesn't crash. 291 RELEASE_ASSERT(invoke<int>(*plan.result[0]) == 11); 313 RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 11); 314 } 315 316 { 317 // Generated from: (module (func $add (param $x i32) (param $y i32) (result i32) (return (i32.add (get_local $x) (get_local $y)))) ) 318 Vector<uint8_t> vector = { 319 0x00, 0x61, 0x73, 0x6d, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x74, 0x79, 0x70, 0x65, 0x87, 0x80, 0x80, 320 0x00, 0x01, 0x40, 0x02, 0x01, 0x01, 0x01, 0x01, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 321 0x6e, 0x82, 0x80, 0x80, 0x00, 0x01, 0x00, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x8e, 0x80, 0x80, 0x00, 322 0x01, 0x89, 0x80, 0x80, 0x00, 0x00, 0x14, 0x00, 0x14, 0x01, 0x40, 0x09, 0x01, 0x0f 323 }; 324 325 Plan plan(*vm, vector); 326 if (plan.result.size() != 1 || !plan.result[0]) { 327 dataLogLn("Module failed to compile correctly."); 328 CRASH(); 329 } 330 331 // Test this doesn't crash. 332 RELEASE_ASSERT(invoke<int>(*plan.result[0], {box(0), box(1)}) == 1); 333 RELEASE_ASSERT(invoke<int>(*plan.result[0], {box(100), box(1)}) == 101); 334 RELEASE_ASSERT(invoke<int>(*plan.result[0], {box(-1), box(1)}) == 0); 335 RELEASE_ASSERT(invoke<int>(*plan.result[0], {box(std::numeric_limits<int>::max()), box(1)}) == std::numeric_limits<int>::min()); 292 336 } 293 337 } -
trunk/Source/JavaScriptCore/wasm/WASMB3IRGenerator.cpp
r205309 r205330 30 30 31 31 #include "B3BasicBlockInlines.h" 32 #include "B3CallingConventions.h" 32 33 #include "B3ValueInlines.h" 33 34 #include "B3Variable.h" 34 35 #include "B3VariableValue.h" 36 #include "VirtualRegister.h" 35 37 #include "WASMFunctionParser.h" 36 38 #include <wtf/Optional.h> … … 68 70 B3IRGenerator(Procedure&); 69 71 72 void addArguments(const Vector<Type>&); 70 73 void addLocal(Type, uint32_t); 71 74 ExpressionType addConstant(Type, uint64_t); 75 76 bool WARN_UNUSED_RETURN getLocal(uint32_t index, ExpressionType& result); 72 77 73 78 bool WARN_UNUSED_RETURN binaryOp(BinaryOpType, ExpressionType left, ExpressionType right, ExpressionType& result); … … 89 94 // This is a pair of the continuation and the types expected on the stack for that continuation. 90 95 Vector<std::pair<BasicBlock*, Optional<Vector<Variable*>>>> m_controlStack; 96 Vector<Variable*> m_locals; 91 97 }; 92 98 … … 97 103 } 98 104 99 void B3IRGenerator::addLocal(Type, uint32_t) 105 void B3IRGenerator::addLocal(Type type, uint32_t count) 106 { 107 m_locals.reserveCapacity(m_locals.size() + count); 108 for (uint32_t i = 0; i < count; ++i) 109 m_locals.append(m_proc.addVariable(type)); 110 } 111 112 void B3IRGenerator::addArguments(const Vector<Type>& types) 100 113 { 101 114 // TODO: Add locals. 115 ASSERT(!m_locals.size()); 116 m_locals.grow(types.size()); 117 jscCallingConvention().iterate(types, m_proc, m_currentBlock, Origin(), 118 [&] (ExpressionType argument, unsigned i) { 119 Variable* argumentVariable = m_proc.addVariable(argument->type()); 120 m_locals[i] = argumentVariable; 121 m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), argumentVariable, argument); 122 }); 123 } 124 125 bool WARN_UNUSED_RETURN B3IRGenerator::getLocal(uint32_t index, ExpressionType& result) 126 { 127 ASSERT(m_locals[index]); 128 result = m_currentBlock->appendNew<VariableValue>(m_proc, B3::Get, Origin(), m_locals[index]); 129 return true; 102 130 } 103 131 -
trunk/Source/JavaScriptCore/wasm/WASMFormat.h
r205309 r205330 91 91 92 92 struct FunctionInformation { 93 Signature* signature; 93 94 size_t start; 94 95 size_t end; -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h
r205309 r205330 62 62 , m_context(context) 63 63 { 64 m_context.addArguments(info.signature->arguments); 64 65 } 65 66 … … 139 140 } 140 141 142 case OpType::GetLocal: { 143 uint32_t index; 144 if (!parseVarUInt32(index)) 145 return false; 146 ExpressionType result; 147 if (!m_context.getLocal(index, result)) 148 return false; 149 150 m_expressionStack.append(result); 151 return true; 152 } 153 141 154 case OpType::Block: { 142 155 if (!m_context.addBlock()) -
trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp
r205309 r205330 141 141 dataLogLn("count: ", count); 142 142 143 m_signatures.resize(count); 144 143 145 for (uint32_t i = 0; i < count; ++i) { 144 146 uint8_t type; … … 182 184 returnType = Type::Void; 183 185 184 // TODO: Actually do something with this data... 185 UNUSED_PARAM(returnType); 186 m_signatures[i] = { returnType, WTFMove(argumentTypes) }; 186 187 } 187 188 return true; … … 200 201 if (!parseVarUInt32(typeNumber)) 201 202 return false; 203 204 if (typeNumber >= m_signatures.size()) 205 return false; 206 207 m_functions[i].signature = &m_signatures[typeNumber]; 202 208 } 203 209 -
trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h
r205309 r205330 59 59 60 60 Vector<FunctionInformation> m_functions; 61 Vector<Signature> m_signatures; 61 62 }; 62 63 -
trunk/Source/JavaScriptCore/wasm/WASMOps.h
r205309 r205330 33 33 34 34 #define FOR_EACH_WASM_SPECIAL_OP(macro) \ 35 macro(I32Const, 0x10, NA) 35 macro(I32Const, 0x10, NA) \ 36 macro(GetLocal, 0x14, NA) 36 37 37 38 #define FOR_EACH_WASM_CONTROL_FLOW_OP(macro) \
Note: See TracChangeset
for help on using the changeset viewer.