diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,12 @@
 
 ## Unreleased
 
+## 1.0.2.0
+
+- Adds `Textual.toShortTextUnsafe` and related `internUnsafe` and `internUnsafe#`; these skip UTF-8 validity checks. Very useful when working with trusted serialized data.
+  - rename `intern##` to `internUnsafe##` (the old name is marked as deprecated.)
+- Cleans up `mkWeakSymbol` to be slightly less sketchy in the presence of `accursedUnutterablePerformIO`; thanks @fatho!
+
 ## 1.0.1.0
 
 - Add `Data.Data` instance
diff --git a/src/Symbolize.hs b/src/Symbolize.hs
--- a/src/Symbolize.hs
+++ b/src/Symbolize.hs
@@ -123,6 +123,7 @@
   ( -- * Symbol
     Symbol (..),
     intern,
+    internUnsafe,
     unintern,
     lookup,
 
@@ -134,6 +135,7 @@
     -- * manipulate unlifted Symbols directly
     Symbol#,
     intern#,
+    internUnsafe#,
     intern##,
     unintern#,
     unintern##,
@@ -166,7 +168,6 @@
 import Prelude hiding (lookup)
 import Data.Data qualified
 import Data.Binary qualified
-import Data.Text.Short (ShortText)
 
 -- | A string-like type with O(1) equality and comparison.
 --
@@ -293,10 +294,28 @@
 {-# INLINE intern# #-}
 intern# !str = intern## (textualToBA# str)
 
--- | Version of `intern` that directly works on an unlifted `ByteArray#` and returns an unlifted `Symbol#`
+
+-- | Like `intern`, but skips any potential UTF-8 validation
+internUnsafe :: (Textual str) => str -> Symbol
+{-# INLINE internUnsafe #-}
+internUnsafe !str = Symbol (internUnsafe# str)
+
+-- | Like `intern#`, but skips any potential UTF-8 validation
+internUnsafe# :: (Textual str) => str -> Symbol#
+{-# INLINE internUnsafe# #-}
+internUnsafe# !str = intern## (textualToBAUnsafe# str)
+
+{-# DEPRECATED intern## "Renamed to `internUnsafe##`" #-}
 intern## :: ByteArray# -> Symbol#
 {-# INLINE intern## #-}
-intern## ba# =
+intern## = internUnsafe##
+
+-- | Version of `intern`/`internUnsafe` that directly works on an unlifted `ByteArray#` and returns an unlifted `Symbol#`
+--
+-- Does not do any checking for UTF-8 validity on the `ByteArray#` beforehand.
+internUnsafe## :: ByteArray# -> Symbol#
+{-# INLINE internUnsafe## #-}
+internUnsafe## ba# =
   -- SAFETY: We're actually happy with let-floating/combining
   -- since the result is 'outwardly pure' and doing less work is better!
   let !(ByteArray ba2#) = Accursed.accursedUnutterablePerformIO (SymbolTable.insertGlobal ba#)
@@ -390,6 +409,12 @@
 {-# INLINE textualToBA# #-}
 textualToBA# !str =
   let !(SBS ba#) = Text.Short.toShortByteString (Textual.toShortText str)
+   in ba#
+
+textualToBAUnsafe# :: (Textual str) => str -> ByteArray#
+{-# INLINE textualToBAUnsafe# #-}
+textualToBAUnsafe# !str =
+  let !(SBS ba#) = Text.Short.toShortByteString (Textual.toShortTextUnsafe str)
    in ba#
 
 textualFromBA# :: (Textual str) => ByteArray# -> str
diff --git a/src/Symbolize/SymbolTable.hs b/src/Symbolize/SymbolTable.hs
--- a/src/Symbolize/SymbolTable.hs
+++ b/src/Symbolize/SymbolTable.hs
@@ -78,7 +78,13 @@
 insertGlobal ba# = do
   GlobalSymbolTable gsymtab sipkey <- globalSymbolTable
   let !key = calculateHash sipkey ba#
-  let !weak = mkWeakSymbol ba# (removeGlobal key)
+  -- SAFETY: If the table IORef contested, 
+  -- this might trigger `weak` creation for the same bytestring from multiple threads
+  -- at the same time.
+  -- But finalization is idempotent, and only when a thread finally wins the Compare-and-Swap
+  -- will its `weak` pointer be inserted (or alternatively another previously-inserted `ba` returned).
+  -- So once this function returns, we can be sure we've returned a deduplicated ByteArray
+  !weak <- mkWeakSymbol ba# (removeGlobal key)
   IORef.atomicModifyIORef' gsymtab $ \table ->
     case lookup ba# sipkey table of
       Just ba -> (table, ba)
@@ -134,7 +140,7 @@
   let (SipHash.SipHash word) = SipHash.hash sipkey (ByteArray ba#)
    in Hash (fromIntegral word)
 
-mkWeakSymbol :: ByteArray# -> IO () -> WeakSymbol
+mkWeakSymbol :: ByteArray# -> IO () -> IO WeakSymbol
 {-# INLINE mkWeakSymbol #-}
 mkWeakSymbol ba# (IO finalizer#) = 
     -- SAFETY: This should even be safe
@@ -142,7 +148,6 @@
     --
     -- because the result is outwardly pure
     -- and the finalizer we use is idempotent
-    Symbolize.Accursed.accursedUnutterablePerformIO $
   IO $ \s1 -> case mkWeak# ba# ba# finalizer# s1 of
     (# s2, weak# #) ->
       case makeStableName# ba# s2 of
diff --git a/src/Symbolize/Textual.hs b/src/Symbolize/Textual.hs
--- a/src/Symbolize/Textual.hs
+++ b/src/Symbolize/Textual.hs
@@ -1,4 +1,6 @@
 {-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE InstanceSigs #-}
 
 -- NOTE: FlexibleInstances is needed to support `String` instance :-(
 
@@ -13,10 +15,10 @@
 import qualified Data.Text.Encoding as Text.Encoding
 import qualified Data.Text.Encoding.Error as Text.Encoding.Error
 import qualified Data.Text.Lazy as LText
-import Data.Text.Lazy.Builder (Builder)
-import qualified Data.Text.Lazy.Builder as Builder
+import qualified Data.Text.Lazy.Builder as Text.Builder
 import Data.Text.Short (ShortText)
 import qualified Data.Text.Short as ShortText
+import qualified Data.Text.Short.Unsafe as ShortText.Unsafe
 
 -- | Implemented by any String-like types.
 -- The symbol table uses `ShortText` for its internal storage, so any type which can be converted to it
@@ -25,82 +27,127 @@
 -- Instance should handle potential invalid UTF-8 by using the Unicode replacement character,
 -- c.f. `Data.Text.Encoding.Error.lenientDecode`.
 class Textual a where
+  -- | Turns this text value into a `ShortText`, performing UTF-8 checking if necessary
   toShortText :: a -> ShortText
+
+  -- | Turns this text value into a `ShortText`, potentially skipping UTF-8 checks
+  toShortTextUnsafe :: a -> ShortText
+  toShortTextUnsafe = toShortText
+
+  -- | Turns a `ShortText` value into a different textual value
   fromShortText :: ShortText -> a
 
 -- |
 -- - O(0) conversion (a no-op)
 instance Textual ShortText where
-  toShortText = id
+  toShortText :: ShortText -> ShortText
   {-# INLINE toShortText #-}
-  fromShortText = id
+  toShortText = id
+
+  toShortTextUnsafe :: ShortText -> ShortText
+  {-# INLINE toShortTextUnsafe #-}
+  toShortTextUnsafe = id
+
+  fromShortText :: ShortText -> ShortText
   {-# INLINE fromShortText #-}
+  fromShortText = id
 
 -- |
 -- - O(1) conversion
 instance Textual Text where
-  toShortText = ShortText.fromText
+  toShortText :: Text -> ShortText
   {-# INLINE toShortText #-}
-  fromShortText = ShortText.toText
+  toShortText = ShortText.fromText
+
+  fromShortText :: ShortText -> Text
   {-# INLINE fromShortText #-}
+  fromShortText = ShortText.toText
 
 -- |
 -- - O(n) conversion
 instance Textual String where
-  toShortText = ShortText.fromString
+  toShortText :: String -> ShortText
   {-# INLINE toShortText #-}
-  fromShortText = ShortText.toString
+  toShortText = ShortText.fromString
+
+  fromShortText :: ShortText -> String
   {-# INLINE fromShortText #-}
+  fromShortText = ShortText.toString
 
 -- |
 -- - O(1) conversion
 instance Textual LText.Text where
-  toShortText = ShortText.fromText . LText.toStrict
+  toShortText :: LText.Text -> ShortText
   {-# INLINE toShortText #-}
-  fromShortText = LText.fromStrict . ShortText.toText
+  toShortText = ShortText.fromText . LText.toStrict
+
+  fromShortText :: ShortText -> LText.Text
   {-# INLINE fromShortText #-}
+  fromShortText = LText.fromStrict . ShortText.toText
 
 -- |
 -- - toShortText: O(n). Evaluates the entire builder.
 -- - fromShortText: O(1)
-instance Textual Builder where
-  toShortText = ShortText.fromText . LText.toStrict . Builder.toLazyText
+instance Textual Text.Builder.Builder where
+  toShortText :: Text.Builder.Builder -> ShortText
   {-# INLINE toShortText #-}
-  fromShortText = Builder.fromText . ShortText.toText
+  toShortText = ShortText.fromText . LText.toStrict . Text.Builder.toLazyText
+
+  fromShortText :: ShortText -> Text.Builder.Builder
   {-# INLINE fromShortText #-}
+  fromShortText = Text.Builder.fromText . ShortText.toText
 
 -- |
 -- - toShortText: O(n). Turns invalid UTF-8 into the Unicode replacement character.
 -- - fromShortText: O(0) no-op
 instance Textual ShortByteString where
+  toShortText :: ShortByteString -> ShortText
+  {-# INLINE toShortText #-}
   toShortText byteString =
     byteString
       & ShortByteString.fromShort
       & Text.Encoding.decodeUtf8With Text.Encoding.Error.lenientDecode
       & ShortText.fromText
-  {-# INLINE toShortText #-}
 
-  fromShortText = ShortText.toShortByteString
+  toShortTextUnsafe :: ShortByteString -> ShortText
+  {-# INLINE toShortTextUnsafe #-}
+  toShortTextUnsafe = ShortText.Unsafe.fromShortByteStringUnsafe
+
+  fromShortText :: ShortText -> ShortByteString
   {-# INLINE fromShortText #-}
+  fromShortText = ShortText.toShortByteString
 
 -- |
 -- - toShortText: O(n). Turns invalid UTF-8 into the Unicode replacement character.
 -- - fromShortText: O(n).
 instance Textual ByteString where
+  toShortText :: ByteString -> ShortText
+  {-# INLINE toShortText #-}
   toShortText byteString =
     byteString
       & Text.Encoding.decodeUtf8With Text.Encoding.Error.lenientDecode
       & ShortText.fromText
-  {-# INLINE toShortText #-}
 
-  fromShortText = ShortText.toByteString
+  toShortTextUnsafe :: ByteString -> ShortText
+  {-# INLINE toShortTextUnsafe #-}
+  toShortTextUnsafe = toShortTextUnsafe . ShortByteString.toShort
+
+  fromShortText :: ShortText -> ByteString
   {-# INLINE fromShortText #-}
+  fromShortText = ShortText.toByteString
 
 -- |
 -- - toShortText: O(n). Turns invalid UTF-8 into the Unicode replacement character.
 -- - fromShortText: O(0) no-op
 instance Textual ByteArray where
+  toShortText :: ByteArray -> ShortText
+  {-# INLINE toShortText #-}
   toShortText (ByteArray ba) = toShortText (ShortByteString.SBS ba)
-  fromShortText short =
-    let !(ShortByteString.SBS ba) = fromShortText short
-     in ByteArray ba
+
+  toShortTextUnsafe :: ByteArray -> ShortText
+  {-# INLINE toShortTextUnsafe #-}
+  toShortTextUnsafe (ByteArray ba) = toShortTextUnsafe (ShortByteString.SBS ba)
+
+  fromShortText :: ShortText -> ByteArray
+  {-# INLINE fromShortText #-}
+  fromShortText (fromShortText -> ShortByteString.SBS ba) = ByteArray ba
diff --git a/symbolize.cabal b/symbolize.cabal
--- a/symbolize.cabal
+++ b/symbolize.cabal
@@ -5,7 +5,7 @@
 -- see: https://github.com/sol/hpack
 
 name:           symbolize
-version:        1.0.1.0
+version:        1.0.2.0
 synopsis:       Efficient global Symbol table, with Garbage Collection.
 description:    Symbols, also known as Atoms or Interned Strings, are a common technique
                 to reduce memory usage and improve performance when using many small strings:
