From 78e3cee2044d7b4ede93a934e669535eb3228ffb Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Wed, 18 Nov 2020 21:47:04 +0900 Subject: [PATCH] [WASM] Fix least valid pointer value WebAssembly doesn't reserve low addresses But without "extra inhabitants" of the pointer representation, runtime performance and memory footprint are worse. So assume that compiler driver uses wasm-ld and --global-base=1024 to reserve low 1KB. --- lib/Driver/ToolChains.h | 3 +++ lib/Driver/WebAssemblyToolChains.cpp | 28 +++++++++++++++++++++++++++ lib/IRGen/SwiftTargetInfo.cpp | 11 ++++++++++- stdlib/public/SwiftShims/HeapObject.h | 16 +++++++++++++++ stdlib/public/SwiftShims/System.h | 8 ++++++++ 5 files changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 8297d3ab7edda..f265342c033ef 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -121,6 +121,9 @@ class LLVM_LIBRARY_VISIBILITY WebAssembly : public ToolChain { const JobContext &context) const override; InvocationInfo constructInvocation(const StaticLinkJobAction &job, const JobContext &context) const override; + void validateArguments(DiagnosticEngine &diags, + const llvm::opt::ArgList &args, + StringRef defaultTarget) const override; public: WebAssembly(const Driver &D, const llvm::Triple &Triple) : ToolChain(D, Triple) {} diff --git a/lib/Driver/WebAssemblyToolChains.cpp b/lib/Driver/WebAssemblyToolChains.cpp index 7aa8d8b1e2524..656e7165d231a 100644 --- a/lib/Driver/WebAssemblyToolChains.cpp +++ b/lib/Driver/WebAssemblyToolChains.cpp @@ -12,6 +12,8 @@ #include "ToolChains.h" +#include "swift/ABI/System.h" +#include "swift/AST/DiagnosticsDriver.h" #include "swift/Basic/Dwarf.h" #include "swift/Basic/LLVM.h" #include "swift/Basic/Platform.h" @@ -193,6 +195,15 @@ toolchains::WebAssembly::constructInvocation(const DynamicLinkJobAction &job, Arguments.push_back("-v"); } + // WebAssembly doesn't reserve low addresses But without "extra inhabitants" + // of the pointer representation, runtime performance and memory footprint are + // worse. So assume that compiler driver uses wasm-ld and --global-base=1024 + // to reserve low 1KB. + Arguments.push_back("-Xlinker"); + Arguments.push_back(context.Args.MakeArgString( + Twine("--global-base=") + + std::to_string(SWIFT_ABI_WASM32_LEAST_VALID_POINTER))); + // These custom arguments should be right before the object file at the end. context.Args.AddAllArgs(Arguments, options::OPT_linker_option_Group); context.Args.AddAllArgs(Arguments, options::OPT_Xlinker); @@ -209,6 +220,23 @@ toolchains::WebAssembly::constructInvocation(const DynamicLinkJobAction &job, return II; } +void validateLinkerArguments(DiagnosticEngine &diags, + ArgStringList linkerArgs) { + for (auto arg : linkerArgs) { + if (StringRef(arg).startswith("--global-base=")) { + diags.diagnose(SourceLoc(), diag::error_option_not_supported, arg, + "wasm32"); + } + } +} +void toolchains::WebAssembly::validateArguments(DiagnosticEngine &diags, + const llvm::opt::ArgList &args, + StringRef defaultTarget) const { + ArgStringList linkerArgs; + args.AddAllArgValues(linkerArgs, options::OPT_Xlinker); + validateLinkerArguments(diags, linkerArgs); +} + ToolChain::InvocationInfo toolchains::WebAssembly::constructInvocation(const StaticLinkJobAction &job, const JobContext &context) const { diff --git a/lib/IRGen/SwiftTargetInfo.cpp b/lib/IRGen/SwiftTargetInfo.cpp index a5e435d433973..32d36feecff36 100644 --- a/lib/IRGen/SwiftTargetInfo.cpp +++ b/lib/IRGen/SwiftTargetInfo.cpp @@ -140,6 +140,13 @@ static void configureSystemZ(IRGenModule &IGM, const llvm::Triple &triple, target.SwiftRetainIgnoresNegativeValues = true; } +/// Configures target-specific information for wasm32 platforms. +static void configureWasm32(IRGenModule &IGM, const llvm::Triple &triple, + SwiftTargetInfo &target) { + target.LeastValidPointerValue = + SWIFT_ABI_WASM32_LEAST_VALID_POINTER; +} + /// Configure a default target. SwiftTargetInfo::SwiftTargetInfo( llvm::Triple::ObjectFormatType outputObjectFormat, @@ -196,7 +203,9 @@ SwiftTargetInfo SwiftTargetInfo::get(IRGenModule &IGM) { case llvm::Triple::systemz: configureSystemZ(IGM, triple, target); break; - + case llvm::Triple::wasm32: + configureWasm32(IGM, triple, target); + break; default: // FIXME: Complain here? Default target info is unlikely to be correct. break; diff --git a/stdlib/public/SwiftShims/HeapObject.h b/stdlib/public/SwiftShims/HeapObject.h index 0e58eaf71d9a9..b647b4c096353 100644 --- a/stdlib/public/SwiftShims/HeapObject.h +++ b/stdlib/public/SwiftShims/HeapObject.h @@ -190,6 +190,22 @@ static_assert(alignof(HeapObject) == alignof(void*), #define _swift_BridgeObject_TaggedPointerBits \ (__swift_uintptr_t) SWIFT_ABI_DEFAULT_BRIDGEOBJECT_TAG_64 +#elif defined(__wasm32__) +extern unsigned char __global_base; +#define _swift_abi_LeastValidPointerValue \ + (__swift_uintptr_t) SWIFT_ABI_WASM32_LEAST_VALID_POINTER + +#define _swift_abi_SwiftSpareBitsMask \ + (__swift_uintptr_t) SWIFT_ABI_DEFAULT_SWIFT_SPARE_BITS_MASK + +#define _swift_abi_ObjCReservedBitsMask \ + (__swift_uintptr_t) SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK +#define _swift_abi_ObjCReservedLowBits \ + (unsigned) SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS + +#define _swift_BridgeObject_TaggedPointerBits \ + (__swift_uintptr_t) SWIFT_ABI_DEFAULT_BRIDGEOBJECT_TAG_32 + #else #define _swift_abi_LeastValidPointerValue \ diff --git a/stdlib/public/SwiftShims/System.h b/stdlib/public/SwiftShims/System.h index 715ce8031f372..e6733aa21e61b 100644 --- a/stdlib/public/SwiftShims/System.h +++ b/stdlib/public/SwiftShims/System.h @@ -192,4 +192,12 @@ #define SWIFT_ABI_S390X_OBJC_WEAK_REFERENCE_MARKER_VALUE \ (1<