From 3bea8bcae5f392b58a2abcea5dd9e8e9b4fcba8b Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Tue, 6 Nov 2018 17:59:32 +0000 Subject: [PATCH] [WebAssembly] Support creation and import of shared memories Used for WebAssembly threads proposal. Add a flag --shared-memory which sets the IS_SHARED bit in WasmLimits Differential Revision: https://reviews.llvm.org/D54130 llvm-svn: 346248 --- lld/test/wasm/data-layout.ll | 10 ++++++++++ lld/test/wasm/import-memory.test | 17 +++++++++++++++++ lld/wasm/Config.h | 1 + lld/wasm/Driver.cpp | 1 + lld/wasm/Options.td | 3 +++ lld/wasm/Writer.cpp | 9 +++++++-- 6 files changed, 39 insertions(+), 2 deletions(-) diff --git a/lld/test/wasm/data-layout.ll b/lld/test/wasm/data-layout.ll index 5fd3f2d7791c..b01c13ac9b82 100644 --- a/lld/test/wasm/data-layout.ll +++ b/lld/test/wasm/data-layout.ll @@ -68,6 +68,16 @@ target triple = "wasm32-unknown-unknown" ; CHECK-MAX-NEXT: Initial: 0x00000002 ; CHECK-MAX-NEXT: Maximum: 0x00000002 +; RUN: wasm-ld -no-gc-sections --allow-undefined --no-entry --shared-memory \ +; RUN: --initial-memory=131072 --max-memory=131072 -o %t_max.wasm %t.o \ +; RUN: %t.hello.o +; RUN: obj2yaml %t_max.wasm | FileCheck %s -check-prefix=CHECK-SHARED + +; CHECK-SHARED: - Type: MEMORY +; CHECK-SHARED-NEXT: Memories: +; CHECK-SHARED-NEXT: - Flags: [ HAS_MAX, IS_SHARED ] +; CHECK-SHARED-NEXT: Initial: 0x00000002 +; CHECK-SHARED-NEXT: Maximum: 0x00000002 ; RUN: wasm-ld --relocatable -o %t_reloc.wasm %t.o %t.hello.o ; RUN: obj2yaml %t_reloc.wasm | FileCheck %s -check-prefix=RELOC diff --git a/lld/test/wasm/import-memory.test b/lld/test/wasm/import-memory.test index 49bf06b74832..0a64afd6ce20 100644 --- a/lld/test/wasm/import-memory.test +++ b/lld/test/wasm/import-memory.test @@ -31,3 +31,20 @@ # CHECK-MAX-NEXT: Initial: 0x00000004 # CHECK-MAX-NEXT: Maximum: 0x00000005 # CHECK-MAX-NEXT: - Type: + +# RUN: wasm-ld --import-memory --shared-memory --initial-memory=262144 \ +# RUN: --max-memory=327680 -o %t.max.wasm %t.start.o +# RUN: obj2yaml %t.max.wasm | FileCheck -check-prefix=CHECK-SHARED %s + +# Verify the --shared-memory flag works with imports + +# CHECK-SHARED: - Type: IMPORT +# CHECK-SHARED-NEXT: Imports: +# CHECK-SHARED-NEXT: - Module: env +# CHECK-SHARED-NEXT: Field: memory +# CHECK-SHARED-NEXT: Kind: MEMORY +# CHECK-SHARED-NEXT: Memory: +# CHECK-SHARED-NEXT: Flags: [ HAS_MAX, IS_SHARED ] +# CHECK-SHARED-NEXT: Initial: 0x00000004 +# CHECK-SHARED-NEXT: Maximum: 0x00000005 +# CHECK-SHARED-NEXT: - Type: diff --git a/lld/wasm/Config.h b/lld/wasm/Config.h index 233ac9f4abfc..9f051a676c44 100644 --- a/lld/wasm/Config.h +++ b/lld/wasm/Config.h @@ -28,6 +28,7 @@ struct Configuration { bool ExportTable; bool GcSections; bool ImportMemory; + bool SharedMemory; bool ImportTable; bool MergeDataSegments; bool PrintGcSections; diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp index 4079b112de03..acdb5f93f154 100644 --- a/lld/wasm/Driver.cpp +++ b/lld/wasm/Driver.cpp @@ -381,6 +381,7 @@ void LinkerDriver::link(ArrayRef ArgsArr) { errorHandler().FatalWarnings = Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false); Config->ImportMemory = Args.hasArg(OPT_import_memory); + Config->SharedMemory = Args.hasArg(OPT_shared_memory); Config->ImportTable = Args.hasArg(OPT_import_table); Config->LTOO = args::getInteger(Args, OPT_lto_O, 2); Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1); diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td index 156e9b57fa67..fb686ad174fe 100644 --- a/lld/wasm/Options.td +++ b/lld/wasm/Options.td @@ -123,6 +123,9 @@ def global_base: J<"global-base=">, def import_memory: F<"import-memory">, HelpText<"Import memory from the environment">; +def shared_memory: F<"shared-memory">, + HelpText<"Use shared linear memory">; + def import_table: F<"import-table">, HelpText<"Import function table from the environment">; diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp index 64dce4c6d4a8..53b9ff5b4ba4 100644 --- a/lld/wasm/Writer.cpp +++ b/lld/wasm/Writer.cpp @@ -155,6 +155,9 @@ void Writer::createImportSection() { Import.Memory.Flags |= WASM_LIMITS_FLAG_HAS_MAX; Import.Memory.Maximum = MaxMemoryPages; } + if (Config->SharedMemory) { + Import.Memory.Flags |= WASM_LIMITS_FLAG_IS_SHARED; + } writeImport(OS, Import); } @@ -214,8 +217,10 @@ void Writer::createMemorySection() { bool HasMax = MaxMemoryPages != 0; writeUleb128(OS, 1, "memory count"); - writeUleb128(OS, HasMax ? static_cast(WASM_LIMITS_FLAG_HAS_MAX) : 0, - "memory limits flags"); + unsigned Flags = HasMax ? static_cast(WASM_LIMITS_FLAG_HAS_MAX) : 0; + if (Config->SharedMemory) + Flags |= WASM_LIMITS_FLAG_IS_SHARED; + writeUleb128(OS, Flags, "memory limits flags"); writeUleb128(OS, NumMemoryPages, "initial pages"); if (HasMax) writeUleb128(OS, MaxMemoryPages, "max pages");