diff --git a/.gitmodules b/.gitmodules
index 038237aa179a9..bf9bdd9a5b4b0 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -2,9 +2,6 @@
 	path = src/llvm
 	url = https://github.com/rust-lang/llvm.git
 	branch = master
-[submodule "src/jemalloc"]
-	path = src/jemalloc
-	url = https://github.com/rust-lang/jemalloc.git
 [submodule "src/rust-installer"]
 	path = src/tools/rust-installer
 	url = https://github.com/rust-lang/rust-installer.git
@@ -64,4 +61,4 @@
 	path = src/tools/clang
 	url = https://github.com/rust-lang-nursery/clang.git
 	branch = rust-release-80-v1
-  
\ No newline at end of file
+
diff --git a/.travis.yml b/.travis.yml
index ec8060b9f56aa..3457e8a8043d0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,7 +30,7 @@ matrix:
 
     - env: >
         RUST_CHECK_TARGET=dist
-        RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler --enable-lldb"
+        RUST_CONFIGURE_ARGS="--enable-extended --enable-profiler --enable-lldb --set rust.jemalloc"
         SRC=.
         DEPLOY_ALT=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
@@ -53,7 +53,7 @@ matrix:
     # version that we're using, 8.2, cannot compile LLVM for OSX 10.7.
     - env: >
         RUST_CHECK_TARGET=check
-        RUST_CONFIGURE_ARGS="--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler"
+        RUST_CONFIGURE_ARGS="--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc"
         SRC=.
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
         MACOSX_DEPLOYMENT_TARGET=10.8
@@ -67,7 +67,7 @@ matrix:
 
     - env: >
         RUST_CHECK_TARGET=check
-        RUST_CONFIGURE_ARGS=--build=i686-apple-darwin
+        RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --set rust.jemalloc"
         SRC=.
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
         MACOSX_DEPLOYMENT_TARGET=10.8
@@ -87,7 +87,7 @@ matrix:
     # OSX 10.7 and `xcode7` is the latest Xcode able to compile LLVM for 10.7.
     - env: >
         RUST_CHECK_TARGET=dist
-        RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-full-tools --enable-profiler --enable-lldb"
+        RUST_CONFIGURE_ARGS="--build=i686-apple-darwin --enable-full-tools --enable-profiler --enable-lldb --set rust.jemalloc"
         SRC=.
         DEPLOY=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
@@ -102,7 +102,7 @@ matrix:
 
     - env: >
         RUST_CHECK_TARGET=dist
-        RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --enable-lldb"
+        RUST_CONFIGURE_ARGS="--target=aarch64-apple-ios,armv7-apple-ios,armv7s-apple-ios,i386-apple-ios,x86_64-apple-ios --enable-full-tools --enable-sanitizers --enable-profiler --enable-lldb --set rust.jemalloc"
         SRC=.
         DEPLOY=1
         RUSTC_RETRY_LINKER_ON_SEGFAULT=1
diff --git a/config.toml.example b/config.toml.example
index e8cb0cba6b1f9..247b2d3ce80f9 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -296,12 +296,6 @@
 # Adding debuginfo makes them several times larger.
 #debuginfo-tools = false
 
-# Whether or not jemalloc is built and enabled
-#use-jemalloc = true
-
-# Whether or not jemalloc is built with its debug option set
-#debug-jemalloc = false
-
 # Whether or not `panic!`s generate backtraces (RUST_BACKTRACE)
 #backtrace = true
 
@@ -398,6 +392,10 @@
 # generally only set for releases
 #remap-debuginfo = false
 
+# Link the compiler against `jemalloc`, where on Linux and OSX it should
+# override the default allocator for rustc and LLVM.
+#jemalloc = false
+
 # =============================================================================
 # Options for specific targets
 #
@@ -437,10 +435,6 @@
 # not, you can specify an explicit file name for it.
 #llvm-filecheck = "/path/to/FileCheck"
 
-# Path to the custom jemalloc static library to link into the standard library
-# by default. This is only used if jemalloc is still enabled above
-#jemalloc = "/path/to/jemalloc/libjemalloc_pic.a"
-
 # If this target is for Android, this option will be required to specify where
 # the NDK for the target lives. This is used to find the C compiler to link and
 # build native code.
diff --git a/src/Cargo.lock b/src/Cargo.lock
index dd21108352792..3629525b429e3 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -15,17 +15,6 @@ dependencies = [
  "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
-[[package]]
-name = "alloc_jemalloc"
-version = "0.0.0"
-dependencies = [
- "build_helper 0.1.0",
- "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
- "compiler_builtins 0.0.0",
- "core 0.0.0",
- "libc 0.0.0",
-]
-
 [[package]]
 name = "alloc_system"
 version = "0.0.0"
@@ -784,6 +773,11 @@ dependencies = [
  "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "fs_extra"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "fst"
 version = "0.3.0"
@@ -995,6 +989,16 @@ name = "itoa"
 version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
+[[package]]
+name = "jemalloc-sys"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
 [[package]]
 name = "jobserver"
 version = "0.1.11"
@@ -2180,6 +2184,7 @@ dependencies = [
  "arena 0.0.0",
  "env_logger 0.5.12 (registry+https://github.com/rust-lang/crates.io-index)",
  "graphviz 0.0.0",
+ "jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc 0.0.0",
  "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2679,7 +2684,6 @@ name = "std"
 version = "0.0.0"
 dependencies = [
  "alloc 0.0.0",
- "alloc_jemalloc 0.0.0",
  "alloc_system 0.0.0",
  "build_helper 0.1.0",
  "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3236,6 +3240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
 "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
 "checksum fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213"
+"checksum fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5f2a4a2034423744d2cc7ca2068453168dcdb82c438419e639a26bd87839c674"
 "checksum fst 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d94485a00b1827b861dd9d1a2cc9764f9044d4c535514c0760a5a2012ef3399f"
 "checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
 "checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
@@ -3258,6 +3263,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum is-match 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7e5b386aef33a1c677be65237cb9d32c3f3ef56bd035949710c4bb13083eb053"
 "checksum itertools 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)" = "f58856976b776fedd95533137617a02fb25719f40e7d9b01c7043cd65474f450"
 "checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
+"checksum jemalloc-sys 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "bfc62c8e50e381768ce8ee0428ee53741929f7ebd73e4d83f669bcf7693e00ae"
 "checksum jobserver 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "60af5f849e1981434e4a31d3d782c4774ae9b434ce55b101a96ecfd09147e8be"
 "checksum json 0.11.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9ad0485404155f45cce53a40d4b2d6ac356418300daed05273d9e26f91c390be"
 "checksum jsonrpc-core 8.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ddf83704f4e79979a424d1082dd2c1e52683058056c9280efa19ac5f6bc9033c"
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index ffc5adbebb34f..02f8dcb2dce5f 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -712,11 +712,6 @@ def update_submodules(self):
                 backends = self.get_toml('codegen-backends')
                 if backends is None or not 'emscripten' in backends:
                     continue
-            if module.endswith("jemalloc"):
-                if self.get_toml('use-jemalloc') == 'false':
-                    continue
-                if self.get_toml('jemalloc'):
-                    continue
             if module.endswith("lld"):
                 config = self.get_toml('lld')
                 if config is None or config == 'false':
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 69d45acdedaf9..25f12ea34f203 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -158,16 +158,7 @@ pub fn std_cargo(builder: &Builder,
             .arg("--manifest-path")
             .arg(builder.src.join("src/rustc/compiler_builtins_shim/Cargo.toml"));
     } else {
-        let mut features = builder.std_features();
-
-        // When doing a local rebuild we tell cargo that we're stage1 rather than
-        // stage0. This works fine if the local rust and being-built rust have the
-        // same view of what the default allocator is, but fails otherwise. Since
-        // we don't have a way to express an allocator preference yet, work
-        // around the issue in the case of a local rebuild with jemalloc disabled.
-        if compiler.stage == 0 && builder.local_rebuild && !builder.config.use_jemalloc {
-            features.push_str(" force_alloc_system");
-        }
+        let features = builder.std_features();
 
         if compiler.stage != 0 && builder.config.sanitizers {
             // This variable is used by the sanitizer runtime crates, e.g.
@@ -188,11 +179,6 @@ pub fn std_cargo(builder: &Builder,
             .arg("--manifest-path")
             .arg(builder.src.join("src/libstd/Cargo.toml"));
 
-        if let Some(target) = builder.config.target_config.get(&target) {
-            if let Some(ref jemalloc) = target.jemalloc {
-                cargo.env("JEMALLOC_OVERRIDE", jemalloc);
-            }
-        }
         if target.contains("musl") {
             if let Some(p) = builder.musl_root(target) {
                 cargo.env("MUSL_ROOT", p);
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index a9d330e06a15d..2a75265e88381 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -115,6 +115,7 @@ pub struct Config {
     pub hosts: Vec<Interned<String>>,
     pub targets: Vec<Interned<String>>,
     pub local_rebuild: bool,
+    pub jemalloc: bool,
 
     // dist misc
     pub dist_sign_folder: Option<PathBuf>,
@@ -122,8 +123,6 @@ pub struct Config {
     pub dist_gpg_password_file: Option<PathBuf>,
 
     // libstd features
-    pub debug_jemalloc: bool,
-    pub use_jemalloc: bool,
     pub backtrace: bool, // support for RUST_BACKTRACE
     pub wasm_syscall: bool,
 
@@ -165,7 +164,6 @@ pub struct Target {
     pub llvm_config: Option<PathBuf>,
     /// Some(path to FileCheck) if one was specified.
     pub llvm_filecheck: Option<PathBuf>,
-    pub jemalloc: Option<PathBuf>,
     pub cc: Option<PathBuf>,
     pub cxx: Option<PathBuf>,
     pub ar: Option<PathBuf>,
@@ -262,7 +260,7 @@ struct Llvm {
     link_jobs: Option<u32>,
     link_shared: Option<bool>,
     version_suffix: Option<String>,
-    clang_cl: Option<String>
+    clang_cl: Option<String>,
 }
 
 #[derive(Deserialize, Default, Clone)]
@@ -300,8 +298,6 @@ struct Rust {
     debuginfo_only_std: Option<bool>,
     debuginfo_tools: Option<bool>,
     experimental_parallel_queries: Option<bool>,
-    debug_jemalloc: Option<bool>,
-    use_jemalloc: Option<bool>,
     backtrace: Option<bool>,
     default_linker: Option<String>,
     channel: Option<String>,
@@ -327,6 +323,7 @@ struct Rust {
     backtrace_on_ice: Option<bool>,
     verify_llvm_ir: Option<bool>,
     remap_debuginfo: Option<bool>,
+    jemalloc: Option<bool>,
 }
 
 /// TOML representation of how each build target is configured.
@@ -335,7 +332,6 @@ struct Rust {
 struct TomlTarget {
     llvm_config: Option<String>,
     llvm_filecheck: Option<String>,
-    jemalloc: Option<String>,
     cc: Option<String>,
     cxx: Option<String>,
     ar: Option<String>,
@@ -361,7 +357,6 @@ impl Config {
         config.llvm_enabled = true;
         config.llvm_optimize = true;
         config.llvm_version_check = true;
-        config.use_jemalloc = true;
         config.backtrace = true;
         config.rust_optimize = true;
         config.rust_optimize_tests = true;
@@ -497,7 +492,6 @@ impl Config {
         let mut debuginfo_only_std = None;
         let mut debuginfo_tools = None;
         let mut debug = None;
-        let mut debug_jemalloc = None;
         let mut debuginfo = None;
         let mut debug_assertions = None;
         let mut optimize = None;
@@ -539,12 +533,11 @@ impl Config {
             debuginfo_tools = rust.debuginfo_tools;
             optimize = rust.optimize;
             ignore_git = rust.ignore_git;
-            debug_jemalloc = rust.debug_jemalloc;
             set(&mut config.rust_optimize_tests, rust.optimize_tests);
             set(&mut config.rust_debuginfo_tests, rust.debuginfo_tests);
             set(&mut config.codegen_tests, rust.codegen_tests);
             set(&mut config.rust_rpath, rust.rpath);
-            set(&mut config.use_jemalloc, rust.use_jemalloc);
+            set(&mut config.jemalloc, rust.jemalloc);
             set(&mut config.backtrace, rust.backtrace);
             set(&mut config.channel, rust.channel.clone());
             set(&mut config.rust_dist_src, rust.dist_src);
@@ -592,9 +585,6 @@ impl Config {
                 if let Some(ref s) = cfg.llvm_filecheck {
                     target.llvm_filecheck = Some(config.src.join(s));
                 }
-                if let Some(ref s) = cfg.jemalloc {
-                    target.jemalloc = Some(config.src.join(s));
-                }
                 if let Some(ref s) = cfg.android_ndk {
                     target.ndk = Some(config.src.join(s));
                 }
@@ -640,7 +630,6 @@ impl Config {
         config.rust_debuginfo_tools = debuginfo_tools.unwrap_or(false);
 
         let default = debug == Some(true);
-        config.debug_jemalloc = debug_jemalloc.unwrap_or(default);
         config.rust_debuginfo = debuginfo.unwrap_or(default);
         config.rust_debug_assertions = debug_assertions.unwrap_or(default);
 
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 0cf84a62986a5..78e6ad1a5d202 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -82,7 +82,6 @@ def v(*args):
 o("debuginfo-lines", "rust.debuginfo-lines", "build with line number debugger metadata")
 o("debuginfo-only-std", "rust.debuginfo-only-std", "build only libstd with debugging information")
 o("debuginfo-tools", "rust.debuginfo-tools", "build extended tools with debugging information")
-o("debug-jemalloc", "rust.debug-jemalloc", "build jemalloc with --enable-debug --enable-fill")
 v("save-toolstates", "rust.save-toolstates", "save build and test status of external tools into this file")
 
 v("prefix", "install.prefix", "set installation prefix")
@@ -99,7 +98,6 @@ def v(*args):
 v("llvm-config", None, "set path to llvm-config")
 v("llvm-filecheck", None, "set path to LLVM's FileCheck utility")
 v("python", "build.python", "set path to python")
-v("jemalloc-root", None, "set directory where libjemalloc_pic.a is located")
 v("android-cross-path", "target.arm-linux-androideabi.android-ndk",
   "Android NDK standalone path (deprecated)")
 v("i686-linux-android-ndk", "target.i686-linux-android.android-ndk",
@@ -148,7 +146,6 @@ def v(*args):
 # Many of these are saved below during the "writing configuration" step
 # (others are conditionally saved).
 o("manage-submodules", "build.submodules", "let the build manage the git submodules")
-o("jemalloc", "rust.use-jemalloc", "build liballoc with jemalloc")
 o("full-bootstrap", "build.full-bootstrap", "build three compilers instead of two")
 o("extended", "build.extended", "build an extended rust tool set")
 
@@ -330,8 +327,6 @@ def set(key, value):
         set('target.{}.llvm-config'.format(build()), value)
     elif option.name == 'llvm-filecheck':
         set('target.{}.llvm-filecheck'.format(build()), value)
-    elif option.name == 'jemalloc-root':
-        set('target.{}.jemalloc'.format(build()), value + '/libjemalloc_pic.a')
     elif option.name == 'tools':
         set('build.tools', value.split(','))
     elif option.name == 'host':
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 4de899ee2d599..850b0494ea525 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -859,7 +859,6 @@ impl Step for Src {
             "src/build_helper",
             "src/dlmalloc",
             "src/liballoc",
-            "src/liballoc_jemalloc",
             "src/liballoc_system",
             "src/libbacktrace",
             "src/libcompiler_builtins",
@@ -878,13 +877,11 @@ impl Step for Src {
             "src/rustc/dlmalloc_shim",
             "src/libtest",
             "src/libterm",
-            "src/jemalloc",
             "src/libprofiler_builtins",
             "src/stdsimd",
         ];
         let std_src_dirs_exclude = [
             "src/libcompiler_builtins/compiler-rt/test",
-            "src/jemalloc/test/unit",
         ];
 
         copy_src_dirs(builder, &std_src_dirs[..], &std_src_dirs_exclude[..], &dst_src);
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 4e26c98a62759..c225ef3827180 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -516,12 +516,6 @@ impl Build {
     fn std_features(&self) -> String {
         let mut features = "panic-unwind".to_string();
 
-        if self.config.debug_jemalloc {
-            features.push_str(" debug-jemalloc");
-        }
-        if self.config.use_jemalloc {
-            features.push_str(" jemalloc");
-        }
         if self.config.backtrace {
             features.push_str(" backtrace");
         }
@@ -537,8 +531,8 @@ impl Build {
     /// Get the space-separated set of activated features for the compiler.
     fn rustc_features(&self) -> String {
         let mut features = String::new();
-        if self.config.use_jemalloc {
-            features.push_str(" jemalloc");
+        if self.config.jemalloc {
+            features.push_str("jemalloc");
         }
         features
     }
@@ -791,7 +785,7 @@ impl Build {
         // If we're compiling on macOS then we add a few unconditional flags
         // indicating that we want libc++ (more filled out than libstdc++) and
         // we want to compile for 10.7. This way we can ensure that
-        // LLVM/jemalloc/etc are all properly compiled.
+        // LLVM/etc are all properly compiled.
         if target.contains("apple-darwin") {
             base.push("-stdlib=libc++".into());
         }
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 724cb5841f48f..ed8956ce3e051 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -152,12 +152,6 @@ pub fn check(build: &mut Build) {
         if !build.config.dry_run {
             cmd_finder.must_have(build.cxx(*host).unwrap());
         }
-
-        // The msvc hosts don't use jemalloc, turn it off globally to
-        // avoid packaging the dummy liballoc_jemalloc on that platform.
-        if host.contains("msvc") {
-            build.config.use_jemalloc = false;
-        }
     }
 
     // Externally configured LLVM requires FileCheck to exist
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index fe04a91011ee5..a2b2cc263810c 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -1504,8 +1504,7 @@ impl Step for CrateNotDefault {
     type Output = ();
 
     fn should_run(run: ShouldRun) -> ShouldRun {
-        run.path("src/liballoc_jemalloc")
-            .path("src/librustc_asan")
+        run.path("src/librustc_asan")
             .path("src/librustc_lsan")
             .path("src/librustc_msan")
             .path("src/librustc_tsan")
@@ -1522,7 +1521,6 @@ impl Step for CrateNotDefault {
             target: run.target,
             test_kind,
             krate: match run.path {
-                _ if run.path.ends_with("src/liballoc_jemalloc") => "alloc_jemalloc",
                 _ if run.path.ends_with("src/librustc_asan") => "rustc_asan",
                 _ if run.path.ends_with("src/librustc_lsan") => "rustc_lsan",
                 _ if run.path.ends_with("src/librustc_msan") => "rustc_msan",
@@ -1561,7 +1559,6 @@ impl Step for Crate {
         run = run.krate("test");
         for krate in run.builder.in_tree_crates("std") {
             if krate.is_local(&run.builder)
-                && !krate.name.contains("jemalloc")
                 && !(krate.name.starts_with("rustc_") && krate.name.ends_with("san"))
                 && krate.name != "dlmalloc"
             {
diff --git a/src/ci/docker/dist-i686-linux/Dockerfile b/src/ci/docker/dist-i686-linux/Dockerfile
index d99e409e42671..8df49f364a372 100644
--- a/src/ci/docker/dist-i686-linux/Dockerfile
+++ b/src/ci/docker/dist-i686-linux/Dockerfile
@@ -98,7 +98,8 @@ ENV RUST_CONFIGURE_ARGS \
       --enable-sanitizers \
       --enable-profiler \
       --set target.i686-unknown-linux-gnu.linker=clang \
-      --build=i686-unknown-linux-gnu
+      --build=i686-unknown-linux-gnu \
+      --set rust.jemalloc
 ENV SCRIPT python2.7 ../x.py dist --build $HOSTS --host $HOSTS --target $HOSTS
 ENV CARGO_TARGET_I686_UNKNOWN_LINUX_GNU_LINKER=clang
 
diff --git a/src/ci/docker/dist-x86_64-linux/Dockerfile b/src/ci/docker/dist-x86_64-linux/Dockerfile
index 8696f72e0e388..0a2dae72f7382 100644
--- a/src/ci/docker/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/dist-x86_64-linux/Dockerfile
@@ -101,7 +101,8 @@ ENV RUST_CONFIGURE_ARGS \
       --set target.x86_64-unknown-linux-gnu.linker=clang \
       --set target.x86_64-unknown-linux-gnu.ar=/rustroot/bin/llvm-ar \
       --set target.x86_64-unknown-linux-gnu.ranlib=/rustroot/bin/llvm-ranlib \
-      --set llvm.thin-lto=true
+      --set llvm.thin-lto=true \
+      --set rust.jemalloc
 ENV SCRIPT python2.7 ../x.py dist --host $HOSTS --target $HOSTS
 ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang
 
diff --git a/src/jemalloc b/src/jemalloc
deleted file mode 160000
index 1f5a28755e301..0000000000000
--- a/src/jemalloc
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 1f5a28755e301ac581e2048011e4e0ff3da482ef
diff --git a/src/liballoc/tests/heap.rs b/src/liballoc/tests/heap.rs
index 6fa88ce969a0e..b6be38107da7f 100644
--- a/src/liballoc/tests/heap.rs
+++ b/src/liballoc/tests/heap.rs
@@ -12,9 +12,6 @@ use alloc_system::System;
 use std::alloc::{Global, Alloc, Layout};
 
 /// https://github.com/rust-lang/rust/issues/45955
-///
-/// Note that `#[global_allocator]` is not used,
-/// so `liballoc_jemalloc` is linked (on some platforms).
 #[test]
 fn alloc_system_overaligned_request() {
     check_overalign_requests(System)
diff --git a/src/liballoc_jemalloc/Cargo.toml b/src/liballoc_jemalloc/Cargo.toml
deleted file mode 100644
index 7986d5dd2eb54..0000000000000
--- a/src/liballoc_jemalloc/Cargo.toml
+++ /dev/null
@@ -1,24 +0,0 @@
-[package]
-authors = ["The Rust Project Developers"]
-name = "alloc_jemalloc"
-version = "0.0.0"
-build = "build.rs"
-links = "jemalloc"
-
-[lib]
-name = "alloc_jemalloc"
-path = "lib.rs"
-test = false
-doc = false
-
-[dependencies]
-core = { path = "../libcore" }
-libc = { path = "../rustc/libc_shim" }
-compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
-
-[build-dependencies]
-build_helper = { path = "../build_helper" }
-cc = "1.0.1"
-
-[features]
-debug = []
diff --git a/src/liballoc_jemalloc/build.rs b/src/liballoc_jemalloc/build.rs
deleted file mode 100644
index fbda425a70bf5..0000000000000
--- a/src/liballoc_jemalloc/build.rs
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![deny(warnings)]
-
-extern crate build_helper;
-extern crate cc;
-
-use std::env;
-use std::path::PathBuf;
-use std::process::Command;
-use build_helper::{run, native_lib_boilerplate};
-
-fn main() {
-    // FIXME: This is a hack to support building targets that don't
-    // support jemalloc alongside hosts that do. The jemalloc build is
-    // controlled by a feature of the std crate, and if that feature
-    // changes between targets, it invalidates the fingerprint of
-    // std's build script (this is a cargo bug); so we must ensure
-    // that the feature set used by std is the same across all
-    // targets, which means we have to build the alloc_jemalloc crate
-    // for targets like emscripten, even if we don't use it.
-    let target = env::var("TARGET").expect("TARGET was not set");
-    let host = env::var("HOST").expect("HOST was not set");
-    if target.contains("bitrig") || target.contains("emscripten") || target.contains("fuchsia") ||
-       target.contains("msvc") || target.contains("openbsd") || target.contains("redox") ||
-       target.contains("rumprun") || target.contains("wasm32") {
-        println!("cargo:rustc-cfg=dummy_jemalloc");
-        return;
-    }
-
-    // CloudABI ships with a copy of jemalloc that has been patched to
-    // work well with sandboxing. Don't attempt to build our own copy,
-    // as it won't build.
-    if target.contains("cloudabi") {
-        return;
-    }
-
-    if target.contains("android") {
-        println!("cargo:rustc-link-lib=gcc");
-    } else if !target.contains("windows") && !target.contains("musl") {
-        println!("cargo:rustc-link-lib=pthread");
-    }
-
-    if let Some(jemalloc) = env::var_os("JEMALLOC_OVERRIDE") {
-        let jemalloc = PathBuf::from(jemalloc);
-        println!("cargo:rustc-link-search=native={}",
-                 jemalloc.parent().unwrap().display());
-        let stem = jemalloc.file_stem().unwrap().to_str().unwrap();
-        let name = jemalloc.file_name().unwrap().to_str().unwrap();
-        let kind = if name.ends_with(".a") {
-            "static"
-        } else {
-            "dylib"
-        };
-        println!("cargo:rustc-link-lib={}={}", kind, &stem[3..]);
-        return;
-    }
-
-    let link_name = if target.contains("windows") { "jemalloc" } else { "jemalloc_pic" };
-    let native = match native_lib_boilerplate("jemalloc", "jemalloc", link_name, "lib") {
-        Ok(native) => native,
-        _ => return,
-    };
-
-    let mut cmd = Command::new("sh");
-    cmd.arg(native.src_dir.join("configure")
-                          .to_str()
-                          .unwrap()
-                          .replace("C:\\", "/c/")
-                          .replace("\\", "/"))
-       .current_dir(&native.out_dir)
-       // jemalloc generates Makefile deps using GCC's "-MM" flag. This means
-       // that GCC will run the preprocessor, and only the preprocessor, over
-       // jemalloc's source files. If we don't specify CPPFLAGS, then at least
-       // on ARM that step fails with a "Missing implementation for 32-bit
-       // atomic operations" error. This is because no "-march" flag will be
-       // passed to GCC, and then GCC won't define the
-       // "__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4" macro that jemalloc needs to
-       // select an atomic operation implementation.
-       .env("CPPFLAGS", env::var_os("CFLAGS").unwrap_or_default());
-
-    if target.contains("ios") {
-        cmd.arg("--disable-tls");
-    } else if target.contains("android") {
-        // We force android to have prefixed symbols because apparently
-        // replacement of the libc allocator doesn't quite work. When this was
-        // tested (unprefixed symbols), it was found that the `realpath`
-        // function in libc would allocate with libc malloc (not jemalloc
-        // malloc), and then the standard library would free with jemalloc free,
-        // causing a segfault.
-        //
-        // If the test suite passes, however, without symbol prefixes then we
-        // should be good to go!
-        cmd.arg("--with-jemalloc-prefix=je_");
-        cmd.arg("--disable-tls");
-    } else if target.contains("dragonfly") || target.contains("musl") {
-        cmd.arg("--with-jemalloc-prefix=je_");
-    }
-
-    if cfg!(feature = "debug") {
-        // Enable jemalloc assertions.
-        cmd.arg("--enable-debug");
-    }
-
-    cmd.arg(format!("--host={}", build_helper::gnu_target(&target)));
-    cmd.arg(format!("--build={}", build_helper::gnu_target(&host)));
-
-    // for some reason, jemalloc configure doesn't detect this value
-    // automatically for this target
-    if target == "sparc64-unknown-linux-gnu" {
-        cmd.arg("--with-lg-quantum=4");
-    }
-
-    run(&mut cmd);
-
-    let mut make = Command::new(build_helper::make(&host));
-    make.current_dir(&native.out_dir)
-        .arg("build_lib_static");
-
-    // These are intended for mingw32-make which we don't use
-    if cfg!(windows) {
-        make.env_remove("MAKEFLAGS").env_remove("MFLAGS");
-    }
-
-    // mingw make seems... buggy? unclear...
-    if !host.contains("windows") {
-        make.arg("-j")
-            .arg(env::var("NUM_JOBS").expect("NUM_JOBS was not set"));
-    }
-
-    run(&mut make);
-
-    // The pthread_atfork symbols is used by jemalloc on android but the really
-    // old android we're building on doesn't have them defined, so just make
-    // sure the symbols are available.
-    if target.contains("androideabi") {
-        println!("cargo:rerun-if-changed=pthread_atfork_dummy.c");
-        cc::Build::new()
-            .flag("-fvisibility=hidden")
-            .file("pthread_atfork_dummy.c")
-            .compile("pthread_atfork_dummy");
-    }
-}
diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs
deleted file mode 100644
index 0065e84a7ad1a..0000000000000
--- a/src/liballoc_jemalloc/lib.rs
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![no_std]
-#![allow(unused_attributes)]
-#![unstable(feature = "alloc_jemalloc",
-            reason = "implementation detail of std, does not provide any public API",
-            issue = "0")]
-#![feature(core_intrinsics)]
-#![feature(libc)]
-#![feature(linkage)]
-#![feature(nll)]
-#![feature(staged_api)]
-#![feature(rustc_attrs)]
-#![cfg_attr(dummy_jemalloc, allow(dead_code, unused_extern_crates))]
-#![cfg_attr(not(dummy_jemalloc), feature(allocator_api))]
-#![rustc_alloc_kind = "exe"]
-
-extern crate libc;
-
-#[cfg(not(dummy_jemalloc))]
-pub use contents::*;
-#[cfg(not(dummy_jemalloc))]
-mod contents {
-    use libc::{c_int, c_void, size_t};
-
-    // Note that the symbols here are prefixed by default on macOS and Windows (we
-    // don't explicitly request it), and on Android and DragonFly we explicitly
-    // request it as unprefixing cause segfaults (mismatches in allocators).
-    extern "C" {
-        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                       target_os = "dragonfly", target_os = "windows", target_env = "musl"),
-                   link_name = "je_mallocx")]
-        fn mallocx(size: size_t, flags: c_int) -> *mut c_void;
-        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                       target_os = "dragonfly", target_os = "windows", target_env = "musl"),
-                   link_name = "je_calloc")]
-        fn calloc(size: size_t, flags: c_int) -> *mut c_void;
-        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                       target_os = "dragonfly", target_os = "windows", target_env = "musl"),
-                   link_name = "je_rallocx")]
-        fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
-        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                       target_os = "dragonfly", target_os = "windows", target_env = "musl"),
-                   link_name = "je_sdallocx")]
-        fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
-    }
-
-    const MALLOCX_ZERO: c_int = 0x40;
-
-    // The minimum alignment guaranteed by the architecture. This value is used to
-    // add fast paths for low alignment values.
-    #[cfg(all(any(target_arch = "arm",
-                  target_arch = "mips",
-                  target_arch = "powerpc")))]
-    const MIN_ALIGN: usize = 8;
-    #[cfg(all(any(target_arch = "x86",
-                  target_arch = "x86_64",
-                  target_arch = "aarch64",
-                  target_arch = "powerpc64",
-                  target_arch = "mips64",
-                  target_arch = "s390x",
-                  target_arch = "sparc64")))]
-    const MIN_ALIGN: usize = 16;
-
-    // MALLOCX_ALIGN(a) macro
-    fn mallocx_align(a: usize) -> c_int {
-        a.trailing_zeros() as c_int
-    }
-
-    fn align_to_flags(align: usize, size: usize) -> c_int {
-        if align <= MIN_ALIGN && align <= size {
-            0
-        } else {
-            mallocx_align(align)
-        }
-    }
-
-    // for symbol names src/librustc/middle/allocator.rs
-    // for signatures src/librustc_allocator/lib.rs
-
-    // linkage directives are provided as part of the current compiler allocator
-    // ABI
-
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_alloc(size: usize, align: usize) -> *mut u8 {
-        let flags = align_to_flags(align, size);
-        let ptr = mallocx(size as size_t, flags) as *mut u8;
-        ptr
-    }
-
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_dealloc(ptr: *mut u8,
-                                       size: usize,
-                                       align: usize) {
-        let flags = align_to_flags(align, size);
-        sdallocx(ptr as *mut c_void, size, flags);
-    }
-
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_realloc(ptr: *mut u8,
-                                       _old_size: usize,
-                                       align: usize,
-                                       new_size: usize) -> *mut u8 {
-        let flags = align_to_flags(align, new_size);
-        let ptr = rallocx(ptr as *mut c_void, new_size, flags) as *mut u8;
-        ptr
-    }
-
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
-        let ptr = if align <= MIN_ALIGN && align <= size {
-            calloc(size as size_t, 1) as *mut u8
-        } else {
-            let flags = align_to_flags(align, size) | MALLOCX_ZERO;
-            mallocx(size as size_t, flags) as *mut u8
-        };
-        ptr
-    }
-}
diff --git a/src/liballoc_jemalloc/pthread_atfork_dummy.c b/src/liballoc_jemalloc/pthread_atfork_dummy.c
deleted file mode 100644
index 4e3df0ab26c37..0000000000000
--- a/src/liballoc_jemalloc/pthread_atfork_dummy.c
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// See comments in build.rs for why this exists
-int pthread_atfork(void* prefork,
-                   void* postfork_parent,
-                   void* postfork_child) {
-  return 0;
-}
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index 470c8b03d0bca..1e32f5ef6f0b6 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -38,3 +38,8 @@ syntax = { path = "../libsyntax" }
 smallvec = { version = "0.6.5", features = ["union"] }
 syntax_ext = { path = "../libsyntax_ext" }
 syntax_pos = { path = "../libsyntax_pos" }
+
+[dependencies.jemalloc-sys]
+version = '0.1.8'
+optional = true
+features = ['unprefixed_malloc_on_supported_platforms']
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 276b7290c2ef0..e8fdaddaeb89c 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -64,6 +64,14 @@ extern crate syntax;
 extern crate syntax_ext;
 extern crate syntax_pos;
 
+// Note that the linkage here should be all that we need, on Linux we're not
+// prefixing the symbols here so this should naturally override our default
+// allocator. On OSX it should override via the zone allocator. We shouldn't
+// enable this by default on other platforms, so other platforms aren't handled
+// here yet.
+#[cfg(feature = "jemalloc-sys")]
+extern crate jemalloc_sys;
+
 use driver::CompileController;
 use pretty::{PpMode, UserIdentifiedItem};
 
diff --git a/src/librustc_target/Cargo.toml b/src/librustc_target/Cargo.toml
index bb686e914a048..684ea4c78978c 100644
--- a/src/librustc_target/Cargo.toml
+++ b/src/librustc_target/Cargo.toml
@@ -13,6 +13,3 @@ bitflags = "1.0"
 log = "0.4"
 rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
 serialize = { path = "../libserialize" }
-
-[features]
-jemalloc = []
diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs
index 38b3f2528fe86..8774c15ff0121 100644
--- a/src/librustc_target/spec/apple_base.rs
+++ b/src/librustc_target/spec/apple_base.rs
@@ -44,7 +44,6 @@ pub fn opts() -> TargetOptions {
         dll_suffix: ".dylib".to_string(),
         archive_format: "bsd".to_string(),
         pre_link_args: LinkArgs::new(),
-        exe_allocation_crate: super::maybe_jemalloc(),
         has_elf_tls: version >= (10, 7),
         abi_return_struct_as_int: true,
         emit_debug_gdb_scripts: false,
diff --git a/src/librustc_target/spec/apple_ios_base.rs b/src/librustc_target/spec/apple_ios_base.rs
index 296eaca7c7df0..e926e4913d634 100644
--- a/src/librustc_target/spec/apple_ios_base.rs
+++ b/src/librustc_target/spec/apple_ios_base.rs
@@ -99,10 +99,6 @@ pub fn opts(arch: Arch) -> Result<TargetOptions, String> {
         pre_link_args,
         has_elf_tls: false,
         eliminate_frame_pointer: false,
-        // The following line is a workaround for jemalloc 4.5 being broken on
-        // ios. jemalloc 5.0 is supposed to fix this.
-        // see https://github.com/rust-lang/rust/issues/45262
-        exe_allocation_crate: None,
         .. super::apple_base::opts()
     })
 }
diff --git a/src/librustc_target/spec/cloudabi_base.rs b/src/librustc_target/spec/cloudabi_base.rs
index 2ffa74e737fd5..fb78cf495e22a 100644
--- a/src/librustc_target/spec/cloudabi_base.rs
+++ b/src/librustc_target/spec/cloudabi_base.rs
@@ -38,7 +38,6 @@ pub fn opts() -> TargetOptions {
         // dynamic linking.
         tls_model: "local-exec".to_string(),
         relro_level: RelroLevel::Full,
-        exe_allocation_crate: super::maybe_jemalloc(),
         .. Default::default()
     }
 }
diff --git a/src/librustc_target/spec/dragonfly_base.rs b/src/librustc_target/spec/dragonfly_base.rs
index 32eac8663afac..a9e317b7cb8a7 100644
--- a/src/librustc_target/spec/dragonfly_base.rs
+++ b/src/librustc_target/spec/dragonfly_base.rs
@@ -33,7 +33,6 @@ pub fn opts() -> TargetOptions {
         pre_link_args: args,
         position_independent_executables: true,
         relro_level: RelroLevel::Full,
-        exe_allocation_crate: super::maybe_jemalloc(),
         .. Default::default()
     }
 }
diff --git a/src/librustc_target/spec/freebsd_base.rs b/src/librustc_target/spec/freebsd_base.rs
index 04b8a6e706064..c8a2946da50a5 100644
--- a/src/librustc_target/spec/freebsd_base.rs
+++ b/src/librustc_target/spec/freebsd_base.rs
@@ -34,7 +34,6 @@ pub fn opts() -> TargetOptions {
         position_independent_executables: true,
         eliminate_frame_pointer: false, // FIXME 43575
         relro_level: RelroLevel::Full,
-        exe_allocation_crate: super::maybe_jemalloc(),
         abi_return_struct_as_int: true,
         .. Default::default()
     }
diff --git a/src/librustc_target/spec/linux_base.rs b/src/librustc_target/spec/linux_base.rs
index 4a9cd9e2f3233..01f65d5736322 100644
--- a/src/librustc_target/spec/linux_base.rs
+++ b/src/librustc_target/spec/linux_base.rs
@@ -36,7 +36,6 @@ pub fn opts() -> TargetOptions {
         pre_link_args: args,
         position_independent_executables: true,
         relro_level: RelroLevel::Full,
-        exe_allocation_crate: super::maybe_jemalloc(),
         has_elf_tls: true,
         .. Default::default()
     }
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 9ee4582fabf7b..91cb9b1a9dc1d 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -1270,14 +1270,6 @@ impl ToJson for Target {
     }
 }
 
-fn maybe_jemalloc() -> Option<String> {
-    if cfg!(feature = "jemalloc") {
-        Some("alloc_jemalloc".to_string())
-    } else {
-        None
-    }
-}
-
 /// Either a target triple string or a path to a JSON file.
 #[derive(PartialEq, Clone, Debug, Hash, RustcEncodable, RustcDecodable)]
 pub enum TargetTriple {
diff --git a/src/librustc_target/spec/solaris_base.rs b/src/librustc_target/spec/solaris_base.rs
index c14cc3f5bc3be..93b889d5d399e 100644
--- a/src/librustc_target/spec/solaris_base.rs
+++ b/src/librustc_target/spec/solaris_base.rs
@@ -18,7 +18,6 @@ pub fn opts() -> TargetOptions {
         has_rpath: true,
         target_family: Some("unix".to_string()),
         is_like_solaris: true,
-        exe_allocation_crate: super::maybe_jemalloc(),
 
         .. Default::default()
     }
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index cd1e3438fc372..0f22459b34349 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -14,7 +14,6 @@ crate-type = ["dylib", "rlib"]
 
 [dependencies]
 alloc = { path = "../liballoc" }
-alloc_jemalloc = { path = "../liballoc_jemalloc", optional = true }
 alloc_system = { path = "../liballoc_system" }
 panic_unwind = { path = "../libpanic_unwind", optional = true }
 panic_abort = { path = "../libpanic_abort" }
@@ -43,9 +42,6 @@ build_helper = { path = "../build_helper" }
 
 [features]
 backtrace = []
-debug-jemalloc = ["alloc_jemalloc/debug"]
-jemalloc = ["alloc_jemalloc"]
-force_alloc_system = []
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
 
diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs
index 31fc9ed3f772d..1ff342fa7a7be 100644
--- a/src/libstd/alloc.rs
+++ b/src/libstd/alloc.rs
@@ -13,13 +13,10 @@
 //! In a given program, the standard library has one “global” memory allocator
 //! that is used for example by `Box<T>` and `Vec<T>`.
 //!
-//! Currently the default global allocator is unspecified.
-//! The compiler may link to a version of [jemalloc] on some platforms,
-//! but this is not guaranteed.
-//! Libraries, however, like `cdylib`s and `staticlib`s are guaranteed
-//! to use the [`System`] by default.
+//! Currently the default global allocator is unspecified. Libraries, however,
+//! like `cdylib`s and `staticlib`s are guaranteed to use the [`System`] by
+//! default.
 //!
-//! [jemalloc]: https://github.com/jemalloc/jemalloc
 //! [`System`]: struct.System.html
 //!
 //! # The `#[global_allocator]` attribute
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index a4db879680566..935ddb791fb9b 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -313,14 +313,7 @@
 
 #![default_lib_allocator]
 
-// Always use alloc_system during stage0 since we don't know if the alloc_*
-// crate the stage0 compiler will pick by default is enabled (e.g.
-// if the user has disabled jemalloc in `./configure`).
-// `force_alloc_system` is *only* intended as a workaround for local rebuilds
-// with a rustc without jemalloc.
-// FIXME(#44236) shouldn't need MSVC logic
-#[cfg(all(not(target_env = "msvc"),
-          any(all(stage0, not(test)), feature = "force_alloc_system")))]
+#[cfg(stage0)]
 #[global_allocator]
 static ALLOC: alloc_system::System = alloc_system::System;
 
diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml
index 9ccd37a6a4592..ec822fddef3eb 100644
--- a/src/rustc/Cargo.toml
+++ b/src/rustc/Cargo.toml
@@ -12,4 +12,4 @@ rustc_target = { path = "../librustc_target" }
 rustc_driver = { path = "../librustc_driver" }
 
 [features]
-jemalloc = ["rustc_target/jemalloc"]
+jemalloc = ['rustc_driver/jemalloc-sys']
diff --git a/src/tools/tidy/src/cargo.rs b/src/tools/tidy/src/cargo.rs
index 69f61bc248dbb..466d2fa0d2bd6 100644
--- a/src/tools/tidy/src/cargo.rs
+++ b/src/tools/tidy/src/cargo.rs
@@ -84,8 +84,7 @@ fn verify(tomlfile: &Path, libfile: &Path, bad: &mut bool) {
 
         // This is intentional, this dependency just makes the crate available
         // for others later on. Cover cases
-        let whitelisted = krate == "alloc_jemalloc";
-        let whitelisted = whitelisted || krate.starts_with("panic");
+        let whitelisted = krate.starts_with("panic");
         if toml.contains("name = \"std\"") && whitelisted {
             continue
         }
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index c5f5896d286c3..e235de9c5e138 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -57,7 +57,6 @@ pub mod libcoretest;
 fn filter_dirs(path: &Path) -> bool {
     let skip = [
         "src/dlmalloc",
-        "src/jemalloc",
         "src/llvm",
         "src/llvm-emscripten",
         "src/libbacktrace",
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 3d5e18e37b070..e8f197ba78afe 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -28,7 +28,6 @@
 //! - core may not have platform-specific code
 //! - libcompiler_builtins may have platform-specific code
 //! - liballoc_system may have platform-specific code
-//! - liballoc_jemalloc may have platform-specific code
 //! - libpanic_abort may have platform-specific code
 //! - libpanic_unwind may have platform-specific code
 //! - libunwind may have platform-specific code
@@ -52,7 +51,6 @@ use std::iter::Iterator;
 // Paths that may contain platform-specific code
 const EXCEPTION_PATHS: &[&str] = &[
     // std crates
-    "src/liballoc_jemalloc",
     "src/liballoc_system",
     "src/libcompiler_builtins",
     "src/liblibc",