Use wgpu::StringView for wgpu::*::label

This required:
 - Adding a breaking change define for Chromium.
 - Updating a lot of const char* inside Dawn to be NullableStringView
 - Fixing up GetTraceForLabel.
 - Fixing up a couple wire test.

Bug: 42241188
Bug: 365980798
Change-Id: Iedc9941984556c94d272eedd1fca9336c78d8bd5
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/206314
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
diff --git a/generator/templates/api.h b/generator/templates/api.h
index 7cc4806..df298b0 100644
--- a/generator/templates/api.h
+++ b/generator/templates/api.h
@@ -37,6 +37,8 @@
 #ifndef {{metadata.api.upper()}}_H_
 #define {{metadata.api.upper()}}_H_
 
+#define WGPU_BREAKING_CHANGE_STRING_VIEW_LABELS
+
 {% set API = metadata.c_prefix %}
 #if defined({{API}}_SHARED_LIBRARY)
 #    if defined(_WIN32)
diff --git a/generator/templates/art/api_jni_types.kt b/generator/templates/art/api_jni_types.kt
index 0f94031..0dfb1b5 100644
--- a/generator/templates/art/api_jni_types.kt
+++ b/generator/templates/art/api_jni_types.kt
@@ -44,7 +44,7 @@
 {% endmacro %}
 
 {% macro to_jni_type(type) %}
-    {% if type.name.get() == "string view" %}
+    {% if type.name.get() == 'string view' %}
         jstring
     {% elif type.category in ['function pointer', 'object', 'structure'] %}
         jobject
diff --git a/generator/templates/art/api_kotlin_types.kt b/generator/templates/art/api_kotlin_types.kt
index d6520c0..9c34345 100644
--- a/generator/templates/art/api_kotlin_types.kt
+++ b/generator/templates/art/api_kotlin_types.kt
@@ -30,8 +30,9 @@
     {%- set optional = arg.optional %}
     {%- set default_value = arg.default_value %}
     {%- if arg.length == 'strlen' or arg.type.name.get() == 'string view' -%}
-        String{{ '?' if optional or default_value == 'nullptr' }}
-        {%- if emit_defaults and (default_value or optional) -%}
+        {%- set optional_string = optional or default_value == 'nullptr' -%}
+        String{{ '?' if optional_string }}
+        {%- if emit_defaults and optional_string -%}
             {{ ' ' }}= null
         {%- endif %}
     {% elif type.name.get() == 'void' %}
diff --git a/generator/templates/art/structures.cpp b/generator/templates/art/structures.cpp
index 9f0d1d5..11d2387 100644
--- a/generator/templates/art/structures.cpp
+++ b/generator/templates/art/structures.cpp
@@ -29,6 +29,7 @@
 #include "structures.h"
 
 #include <cassert>
+#include <string>
 
 #include <jni.h>
 #include <webgpu/webgpu.h>
@@ -90,14 +91,21 @@
 
 // Special-case [Nullable]StringView
 void ToNative(JNIContext* c, JNIEnv* env, jstring obj, WGPUStringView* s) {
+    if (obj == nullptr) {
+        *s = {nullptr, WGPU_STRLEN};
+    }
     *s = {c->GetStringUTFChars(obj), static_cast<size_t>(env->GetStringUTFLength(obj))};
 }
+
 jobject ToKotlin(JNIEnv* env, const WGPUStringView* s) {
-    if (s->data == nullptr) {
-        return nullptr;
+    if (s->length == WGPU_STRLEN) {
+        if (s->data == nullptr) {
+            return nullptr;
+        }
+        return env->NewStringUTF(s->data);
     }
-    assert(s->length == WGPU_STRLEN); // Strings returned from Dawn should always be null-terminated.
-    return env->NewStringUTF(s->data);
+    std::string nullTerminated(s->data, s->length);
+    return env->NewStringUTF(nullTerminated.c_str());
 }
 
 {% for structure in by_category['structure'] if include_structure(structure) %}
diff --git a/generator/templates/dawn/native/api_absl_format.cpp b/generator/templates/dawn/native/api_absl_format.cpp
index bdac4ad..dfb7dc9 100644
--- a/generator/templates/dawn/native/api_absl_format.cpp
+++ b/generator/templates/dawn/native/api_absl_format.cpp
@@ -34,6 +34,7 @@
 
 #include "{{native_dir}}/ChainUtils.h"
 #include "{{native_dir}}/ObjectType_autogen.h"
+#include "{{native_dir}}/webgpu_absl_format.h"
 
 namespace {{native_namespace}} {
 
@@ -53,7 +54,7 @@
                         return {true};
                     }
                     s->Append("[{{as_cppType(type.name)}}");
-                    if (value->label != nullptr) {
+                    if (value->label.data != nullptr) {
                         s->Append(absl::StrFormat(" \"%s\"", value->label));
                     }
                     s->Append("]");
diff --git a/src/dawn/common/NonCopyable.h b/src/dawn/common/NonCopyable.h
index 2a37aac..aaa80b9 100644
--- a/src/dawn/common/NonCopyable.h
+++ b/src/dawn/common/NonCopyable.h
@@ -32,10 +32,11 @@
 
 // A base class to make a class non-copyable.
 class NonCopyable {
-  protected:
+  public:
     constexpr NonCopyable() = default;
     ~NonCopyable() = default;
 
+  protected:
     NonCopyable(NonCopyable&&) = default;
     NonCopyable& operator=(NonCopyable&&) = default;
 
diff --git a/src/dawn/dawn.json b/src/dawn/dawn.json
index c6dd41f..7cf4f9a 100644
--- a/src/dawn/dawn.json
+++ b/src/dawn/dawn.json
@@ -246,7 +246,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "required feature count", "type": "size_t", "default": 0},
             {"name": "required features", "type": "feature name", "annotation": "const*", "length": "required feature count", "default": "nullptr"},
             {"name": "required limits", "type": "required limits", "annotation": "const*", "optional": true},
@@ -375,7 +375,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "layout", "type": "bind group layout"},
             {"name": "entry count", "type": "size_t"},
             {"name": "entries", "type": "bind group entry", "annotation": "const*", "length": "entry count"}
@@ -554,7 +554,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "entry count", "type": "size_t"},
             {"name": "entries", "type": "bind group layout entry", "annotation": "const*", "length": "entry count"}
         ]
@@ -714,7 +714,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "usage", "type": "buffer usage"},
             {"name": "size", "type": "uint64_t"},
             {"name": "mapped at creation", "type": "bool", "default": "false"}
@@ -874,7 +874,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true}
+            {"name": "label", "type": "string view", "optional": true}
         ]
     },
     "command encoder": {
@@ -1033,7 +1033,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true}
+            {"name": "label", "type": "string view", "optional": true}
         ]
     },
     "compare function": {
@@ -1128,7 +1128,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "timestamp writes", "type": "compute pass timestamp writes", "annotation": "const*", "optional": true}
         ]
     },
@@ -1269,7 +1269,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "layout", "type": "pipeline layout", "optional": true},
             {"name": "compute", "type": "programmable stage descriptor"}
         ]
@@ -2104,7 +2104,7 @@
         "tags": ["dawn"],
         "_comment": "TODO(crbug.com/1514732): deprecate flipY",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "plane 0", "type": "texture view"},
             {"name": "plane 1", "type": "texture view", "optional": true},
             {"name": "visible origin", "type": "origin 2D"},
@@ -2198,7 +2198,7 @@
         "extensible": "in",
         "tags": ["dawn", "native"],
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true}
+            {"name": "label", "type": "string view", "optional": true}
         ]
     },
     "shared texture memory": {
@@ -2280,7 +2280,7 @@
         "extensible": "in",
         "tags": ["dawn", "native"],
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true}
+            {"name": "label", "type": "string view", "optional": true}
         ]
     },
     "shared buffer memory begin access descriptor": {
@@ -2472,7 +2472,7 @@
         "extensible": "in",
         "tags": ["dawn", "native"],
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true}
+            {"name": "label", "type": "string view", "optional": true}
         ]
     },
     "shared fence vk semaphore opaque FD descriptor": {
@@ -2978,7 +2978,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "bind group layout count", "type": "size_t"},
             {"name": "bind group layouts", "type": "bind group layout", "annotation": "const*", "length": "bind group layout count"},
             {"name": "immediate data range byte size", "type": "uint32_t", "default": 0}
@@ -3077,7 +3077,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "type", "type": "query type"},
             {"name": "count", "type": "uint32_t"}
         ]
@@ -3186,7 +3186,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true}
+            {"name": "label", "type": "string view", "optional": true}
         ]
     },
     "queue work done callback": {
@@ -3376,7 +3376,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true}
+            {"name": "label", "type": "string view", "optional": true}
         ]
     },
 
@@ -3384,7 +3384,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "color format count", "type": "size_t"},
             {"name": "color formats", "type": "texture format", "annotation": "const*", "length": "color format count"},
             {"name": "depth stencil format", "type": "texture format", "default": "undefined"},
@@ -3434,7 +3434,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "color attachment count", "type": "size_t"},
             {"name": "color attachments", "type": "render pass color attachment", "annotation": "const*", "length": "color attachment count"},
             {"name": "depth stencil attachment", "type": "render pass depth stencil attachment", "annotation": "const*", "optional": true},
@@ -3864,7 +3864,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "layout", "type": "pipeline layout", "optional": true},
             {"name": "vertex", "type": "vertex state"},
             {"name": "primitive", "type": "primitive state"},
@@ -3897,7 +3897,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "address mode u", "type": "address mode", "default": "clamp to edge"},
             {"name": "address mode v", "type": "address mode", "default": "clamp to edge"},
             {"name": "address mode w", "type": "address mode", "default": "clamp to edge"},
@@ -3958,7 +3958,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "hint count", "type": "size_t", "default": 0, "tags": ["upstream"]},
             {"name": "hints", "type": "shader module compilation hint", "annotation": "const*", "length": "hint count", "tags": ["upstream"]}
         ]
@@ -4111,7 +4111,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true}
+            {"name": "label", "type": "string view", "optional": true}
         ]
     },
     "surface descriptor from android native window": {
@@ -4248,7 +4248,7 @@
         "tags": ["art", "dawn", "emscripten"],
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "usage", "type": "texture usage"},
             {"name": "format", "type": "texture format"},
             {"name": "width", "type": "uint32_t"},
@@ -4452,7 +4452,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "usage", "type": "texture usage"},
             {"name": "dimension", "type": "texture dimension", "default": "2D"},
             {"name": "size", "type": "extent 3D"},
@@ -4623,7 +4623,7 @@
         "category": "structure",
         "extensible": "in",
         "members": [
-            {"name": "label", "type": "char", "annotation": "const*", "length": "strlen", "optional": true},
+            {"name": "label", "type": "string view", "optional": true},
             {"name": "format", "type": "texture format", "default": "undefined"},
             {"name": "dimension", "type": "texture view dimension", "default": "undefined"},
             {"name": "base mip level", "type": "uint32_t", "default": "0"},
diff --git a/src/dawn/native/BindGroup.cpp b/src/dawn/native/BindGroup.cpp
index b397bf4..601e699 100644
--- a/src/dawn/native/BindGroup.cpp
+++ b/src/dawn/native/BindGroup.cpp
@@ -540,11 +540,11 @@
     ApiObjectBase::DeleteThis();
 }
 
-BindGroupBase::BindGroupBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label)
+BindGroupBase::BindGroupBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label)
     : ApiObjectBase(device, tag, label), mBindingData() {}
 
 // static
-Ref<BindGroupBase> BindGroupBase::MakeError(DeviceBase* device, const char* label) {
+Ref<BindGroupBase> BindGroupBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new BindGroupBase(device, ObjectBase::kError, label));
 }
 
diff --git a/src/dawn/native/BindGroup.h b/src/dawn/native/BindGroup.h
index c7b964a..7b7f331 100644
--- a/src/dawn/native/BindGroup.h
+++ b/src/dawn/native/BindGroup.h
@@ -57,7 +57,7 @@
 
 class BindGroupBase : public ApiObjectBase {
   public:
-    static Ref<BindGroupBase> MakeError(DeviceBase* device, const char* label);
+    static Ref<BindGroupBase> MakeError(DeviceBase* device, StringView label);
 
     ObjectType GetType() const override;
 
@@ -101,7 +101,7 @@
     ~BindGroupBase() override;
 
   private:
-    BindGroupBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    BindGroupBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
     void DeleteThis() override;
 
     Ref<BindGroupLayoutBase> mLayout;
diff --git a/src/dawn/native/BindGroupLayout.cpp b/src/dawn/native/BindGroupLayout.cpp
index 2ba521b..2de6eeb 100644
--- a/src/dawn/native/BindGroupLayout.cpp
+++ b/src/dawn/native/BindGroupLayout.cpp
@@ -32,7 +32,7 @@
 namespace dawn::native {
 
 BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device,
-                                         const char* label,
+                                         StringView label,
                                          Ref<BindGroupLayoutInternalBase> internal,
                                          PipelineCompatibilityToken pipelineCompatibilityToken)
     : ApiObjectBase(device, label),
@@ -43,7 +43,7 @@
 
 BindGroupLayoutBase::BindGroupLayoutBase(DeviceBase* device,
                                          ObjectBase::ErrorTag tag,
-                                         const char* label)
+                                         StringView label)
     : ApiObjectBase(device, tag, label) {}
 
 ObjectType BindGroupLayoutBase::GetType() const {
@@ -51,7 +51,7 @@
 }
 
 // static
-Ref<BindGroupLayoutBase> BindGroupLayoutBase::MakeError(DeviceBase* device, const char* label) {
+Ref<BindGroupLayoutBase> BindGroupLayoutBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new BindGroupLayoutBase(device, ObjectBase::kError, label));
 }
 
diff --git a/src/dawn/native/BindGroupLayout.h b/src/dawn/native/BindGroupLayout.h
index 73c663b..191dc36 100644
--- a/src/dawn/native/BindGroupLayout.h
+++ b/src/dawn/native/BindGroupLayout.h
@@ -41,11 +41,11 @@
 class BindGroupLayoutBase final : public ApiObjectBase {
   public:
     BindGroupLayoutBase(DeviceBase* device,
-                        const char* label,
+                        StringView label,
                         Ref<BindGroupLayoutInternalBase> internal,
                         PipelineCompatibilityToken pipelineCompatibilityToken);
 
-    static Ref<BindGroupLayoutBase> MakeError(DeviceBase* device, const char* label = nullptr);
+    static Ref<BindGroupLayoutBase> MakeError(DeviceBase* device, StringView label = {});
 
     ObjectType GetType() const override;
 
@@ -61,7 +61,7 @@
     void DestroyImpl() override;
 
   private:
-    BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    BindGroupLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     const Ref<BindGroupLayoutInternalBase> mInternalLayout;
 
diff --git a/src/dawn/native/BindGroupLayoutInternal.cpp b/src/dawn/native/BindGroupLayoutInternal.cpp
index 711c9ec..e9c03fd 100644
--- a/src/dawn/native/BindGroupLayoutInternal.cpp
+++ b/src/dawn/native/BindGroupLayoutInternal.cpp
@@ -602,7 +602,7 @@
 
 BindGroupLayoutInternalBase::BindGroupLayoutInternalBase(DeviceBase* device,
                                                          ObjectBase::ErrorTag tag,
-                                                         const char* label)
+                                                         StringView label)
     : ApiObjectBase(device, tag, label) {}
 
 BindGroupLayoutInternalBase::~BindGroupLayoutInternalBase() = default;
diff --git a/src/dawn/native/BindGroupLayoutInternal.h b/src/dawn/native/BindGroupLayoutInternal.h
index d8c0094..04e1faa 100644
--- a/src/dawn/native/BindGroupLayoutInternal.h
+++ b/src/dawn/native/BindGroupLayoutInternal.h
@@ -154,7 +154,7 @@
     }
 
   private:
-    BindGroupLayoutInternalBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    BindGroupLayoutInternalBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     BindingCounts mBindingCounts = {};
     ityp::vector<BindingIndex, BindingInfo> mBindingInfo;
diff --git a/src/dawn/native/CommandBuffer.cpp b/src/dawn/native/CommandBuffer.cpp
index df89e12..cf72188 100644
--- a/src/dawn/native/CommandBuffer.cpp
+++ b/src/dawn/native/CommandBuffer.cpp
@@ -50,13 +50,11 @@
     GetObjectTrackingList()->Track(this);
 }
 
-CommandBufferBase::CommandBufferBase(DeviceBase* device,
-                                     ObjectBase::ErrorTag tag,
-                                     const char* label)
+CommandBufferBase::CommandBufferBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label)
     : ApiObjectBase(device, tag, label) {}
 
 // static
-Ref<CommandBufferBase> CommandBufferBase::MakeError(DeviceBase* device, const char* label) {
+Ref<CommandBufferBase> CommandBufferBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new CommandBufferBase(device, ObjectBase::kError, label));
 }
 
diff --git a/src/dawn/native/CommandBuffer.h b/src/dawn/native/CommandBuffer.h
index c237fc7..578ea87 100644
--- a/src/dawn/native/CommandBuffer.h
+++ b/src/dawn/native/CommandBuffer.h
@@ -52,7 +52,7 @@
   public:
     CommandBufferBase(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor);
 
-    static Ref<CommandBufferBase> MakeError(DeviceBase* device, const char* label);
+    static Ref<CommandBufferBase> MakeError(DeviceBase* device, StringView label);
 
     ObjectType GetType() const override;
     void FormatLabel(absl::FormatSink* s) const override;
@@ -74,7 +74,7 @@
     CommandIterator mCommands;
 
   private:
-    CommandBufferBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    CommandBufferBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     CommandBufferResourceUsage mResourceUsages;
     std::vector<IndirectDrawMetadata> mIndirectDrawMetadata;
diff --git a/src/dawn/native/CommandEncoder.cpp b/src/dawn/native/CommandEncoder.cpp
index d49d4f9..380133a 100644
--- a/src/dawn/native/CommandEncoder.cpp
+++ b/src/dawn/native/CommandEncoder.cpp
@@ -1059,7 +1059,7 @@
 }
 
 // static
-Ref<CommandEncoder> CommandEncoder::MakeError(DeviceBase* device, const char* label) {
+Ref<CommandEncoder> CommandEncoder::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new CommandEncoder(device, ObjectBase::kError, label));
 }
 
@@ -1076,7 +1076,7 @@
     }
 }
 
-CommandEncoder::CommandEncoder(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label)
+CommandEncoder::CommandEncoder(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label)
     : ApiObjectBase(device, tag, label),
       mEncodingContext(device, tag),
       mUsageValidationMode(UsageValidationMode::Default) {}
@@ -1142,7 +1142,11 @@
             if (descriptor == nullptr) {
                 return {};
             }
-            cmd->label = std::string(descriptor->label ? descriptor->label : "");
+
+            std::optional<std::string_view> label = descriptor->label;
+            if (label.has_value()) {
+                cmd->label = label.value();
+            }
 
             if (descriptor->timestampWrites != nullptr) {
                 QuerySetBase* querySet = descriptor->timestampWrites->querySet;
@@ -1227,7 +1231,11 @@
             mEncodingContext.WillBeginRenderPass();
             BeginRenderPassCmd* cmd =
                 allocator->Allocate<BeginRenderPassCmd>(Command::BeginRenderPass);
-            cmd->label = std::string(descriptor->label ? descriptor->label : "");
+
+            std::optional<std::string_view> label = descriptor->label;
+            if (label.has_value()) {
+                cmd->label = label.value();
+            }
 
             cmd->attachmentState = device->GetOrCreateAttachmentState(descriptor);
             attachmentState = cmd->attachmentState;
diff --git a/src/dawn/native/CommandEncoder.h b/src/dawn/native/CommandEncoder.h
index 37d7661..12c3e2d 100644
--- a/src/dawn/native/CommandEncoder.h
+++ b/src/dawn/native/CommandEncoder.h
@@ -55,7 +55,7 @@
   public:
     static Ref<CommandEncoder> Create(DeviceBase* device,
                                       const UnpackedPtr<CommandEncoderDescriptor>& descriptor);
-    static Ref<CommandEncoder> MakeError(DeviceBase* device, const char* label);
+    static Ref<CommandEncoder> MakeError(DeviceBase* device, StringView label);
 
     ObjectType GetType() const override;
 
@@ -138,7 +138,7 @@
 
   private:
     CommandEncoder(DeviceBase* device, const UnpackedPtr<CommandEncoderDescriptor>& descriptor);
-    CommandEncoder(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    CommandEncoder(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     void DestroyImpl() override;
 
diff --git a/src/dawn/native/ComputePassEncoder.cpp b/src/dawn/native/ComputePassEncoder.cpp
index fb76d7f..0700993 100644
--- a/src/dawn/native/ComputePassEncoder.cpp
+++ b/src/dawn/native/ComputePassEncoder.cpp
@@ -147,7 +147,7 @@
                                        CommandEncoder* commandEncoder,
                                        EncodingContext* encodingContext,
                                        ErrorTag errorTag,
-                                       const char* label)
+                                       StringView label)
     : ProgrammableEncoder(device, encodingContext, errorTag, label),
       mCommandEncoder(commandEncoder) {}
 
@@ -155,7 +155,7 @@
 Ref<ComputePassEncoder> ComputePassEncoder::MakeError(DeviceBase* device,
                                                       CommandEncoder* commandEncoder,
                                                       EncodingContext* encodingContext,
-                                                      const char* label) {
+                                                      StringView label) {
     return AcquireRef(
         new ComputePassEncoder(device, commandEncoder, encodingContext, ObjectBase::kError, label));
 }
diff --git a/src/dawn/native/ComputePassEncoder.h b/src/dawn/native/ComputePassEncoder.h
index 35872e9..8acdacc 100644
--- a/src/dawn/native/ComputePassEncoder.h
+++ b/src/dawn/native/ComputePassEncoder.h
@@ -50,7 +50,7 @@
     static Ref<ComputePassEncoder> MakeError(DeviceBase* device,
                                              CommandEncoder* commandEncoder,
                                              EncodingContext* encodingContext,
-                                             const char* label);
+                                             StringView label);
 
     ~ComputePassEncoder() override;
 
@@ -85,7 +85,7 @@
                        CommandEncoder* commandEncoder,
                        EncodingContext* encodingContext,
                        ErrorTag errorTag,
-                       const char* label);
+                       StringView label);
 
   private:
     void DestroyImpl() override;
diff --git a/src/dawn/native/ComputePipeline.cpp b/src/dawn/native/ComputePipeline.cpp
index fe67bc4b..8aeefad 100644
--- a/src/dawn/native/ComputePipeline.cpp
+++ b/src/dawn/native/ComputePipeline.cpp
@@ -85,7 +85,7 @@
 
 ComputePipelineBase::ComputePipelineBase(DeviceBase* device,
                                          ObjectBase::ErrorTag tag,
-                                         const char* label)
+                                         StringView label)
     : PipelineBase(device, tag, label) {}
 
 ComputePipelineBase::~ComputePipelineBase() = default;
@@ -99,10 +99,10 @@
 }
 
 // static
-Ref<ComputePipelineBase> ComputePipelineBase::MakeError(DeviceBase* device, const char* label) {
+Ref<ComputePipelineBase> ComputePipelineBase::MakeError(DeviceBase* device, StringView label) {
     class ErrorComputePipeline final : public ComputePipelineBase {
       public:
-        explicit ErrorComputePipeline(DeviceBase* device, const char* label)
+        explicit ErrorComputePipeline(DeviceBase* device, StringView label)
             : ComputePipelineBase(device, ObjectBase::kError, label) {}
 
         MaybeError InitializeImpl() override {
diff --git a/src/dawn/native/ComputePipeline.h b/src/dawn/native/ComputePipeline.h
index 2d2e1bd..a3641d2 100644
--- a/src/dawn/native/ComputePipeline.h
+++ b/src/dawn/native/ComputePipeline.h
@@ -48,7 +48,7 @@
                         const UnpackedPtr<ComputePipelineDescriptor>& descriptor);
     ~ComputePipelineBase() override;
 
-    static Ref<ComputePipelineBase> MakeError(DeviceBase* device, const char* label);
+    static Ref<ComputePipelineBase> MakeError(DeviceBase* device, StringView label);
 
     ObjectType GetType() const override;
 
@@ -63,7 +63,7 @@
     void DestroyImpl() override;
 
   private:
-    ComputePipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    ComputePipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     bool mRequiresFullSubgroups;
 };
diff --git a/src/dawn/native/CreatePipelineAsyncEvent.cpp b/src/dawn/native/CreatePipelineAsyncEvent.cpp
index b9cf956..333a087 100644
--- a/src/dawn/native/CreatePipelineAsyncEvent.cpp
+++ b/src/dawn/native/CreatePipelineAsyncEvent.cpp
@@ -119,7 +119,7 @@
     DeviceBase* device,
     const CreatePipelineAsyncCallbackInfo& callbackInfo,
     std::unique_ptr<ErrorData> error,
-    const char* label)
+    StringView label)
     : TrackedEvent(static_cast<wgpu::CallbackMode>(callbackInfo.mode), TrackedEvent::Completed{}),
       mCallback(callbackInfo.callback),
       mUserdata1(callbackInfo.userdata1),
@@ -137,7 +137,7 @@
 void CreatePipelineAsyncEvent<PipelineType, CreatePipelineAsyncCallbackInfo>::InitializeImpl(
     bool isAsync) {
     DeviceBase* device = mPipeline->GetDevice();
-    const char* eventLabel = utils::GetLabelForTrace(mPipeline->GetLabel().c_str());
+    const char* eventLabel = utils::GetLabelForTrace(mPipeline->GetLabel());
     if (isAsync) {
         TRACE_EVENT_FLOW_END1(device->GetPlatform(), General,
                               "CreatePipelineAsyncEvent::InitializeAsync", this, "label",
@@ -170,7 +170,7 @@
 template <typename PipelineType, typename CreatePipelineAsyncCallbackInfo>
 void CreatePipelineAsyncEvent<PipelineType, CreatePipelineAsyncCallbackInfo>::InitializeAsync() {
     DeviceBase* device = mPipeline->GetDevice();
-    const char* eventLabel = utils::GetLabelForTrace(mPipeline->GetLabel().c_str());
+    const char* eventLabel = utils::GetLabelForTrace(mPipeline->GetLabel());
     TRACE_EVENT_FLOW_BEGIN1(device->GetPlatform(), General,
                             "CreatePipelineAsyncEvent::InitializeAsync", this, "label", eventLabel);
 
diff --git a/src/dawn/native/CreatePipelineAsyncEvent.h b/src/dawn/native/CreatePipelineAsyncEvent.h
index 569493b..e2ae039 100644
--- a/src/dawn/native/CreatePipelineAsyncEvent.h
+++ b/src/dawn/native/CreatePipelineAsyncEvent.h
@@ -70,7 +70,7 @@
     CreatePipelineAsyncEvent(DeviceBase* device,
                              const CreatePipelineAsyncCallbackInfo& callbackInfo,
                              std::unique_ptr<ErrorData> error,
-                             const char* label);
+                             StringView label);
 
     ~CreatePipelineAsyncEvent() override;
 
diff --git a/src/dawn/native/Device.cpp b/src/dawn/native/Device.cpp
index 259267d..180cd5f 100644
--- a/src/dawn/native/Device.cpp
+++ b/src/dawn/native/Device.cpp
@@ -434,8 +434,9 @@
 
     mFormatTable = BuildFormatTable(this);
 
-    if (descriptor->label != nullptr && strlen(descriptor->label) != 0) {
-        mLabel = descriptor->label;
+    std::optional<std::string_view> label = descriptor->label;
+    if (label.has_value()) {
+        mLabel = label.value();
     }
 
     mIsImmediateErrorHandlingEnabled = IsToggleEnabled(Toggle::EnableImmediateErrorHandling);
@@ -1349,8 +1350,9 @@
 }
 ComputePipelineBase* DeviceBase::APICreateComputePipeline(
     const ComputePipelineDescriptor* descriptor) {
+    utils::TraceLabel label = utils::GetLabelForTrace(descriptor->label);
     TRACE_EVENT1(GetPlatform(), General, "DeviceBase::APICreateComputePipeline", "label",
-                 utils::GetLabelForTrace(descriptor->label));
+                 label.label);
 
     auto resultOrError = CreateComputePipeline(descriptor);
     if (resultOrError.IsSuccess()) {
@@ -1403,8 +1405,9 @@
 Future DeviceBase::APICreateComputePipelineAsync2(
     const ComputePipelineDescriptor* descriptor,
     const WGPUCreateComputePipelineAsyncCallbackInfo2& callbackInfo) {
+    utils::TraceLabel label = utils::GetLabelForTrace(descriptor->label);
     TRACE_EVENT1(GetPlatform(), General, "DeviceBase::APICreateComputePipelineAsync", "label",
-                 utils::GetLabelForTrace(descriptor->label));
+                 label.label);
 
     EventManager* manager = GetInstance()->GetEventManager();
 
@@ -1504,8 +1507,9 @@
 Future DeviceBase::APICreateRenderPipelineAsync2(
     const RenderPipelineDescriptor* descriptor,
     const WGPUCreateRenderPipelineAsyncCallbackInfo2& callbackInfo) {
+    utils::TraceLabel label = utils::GetLabelForTrace(descriptor->label);
     TRACE_EVENT1(GetPlatform(), General, "DeviceBase::APICreateRenderPipelineAsync", "label",
-                 utils::GetLabelForTrace(descriptor->label));
+                 label.label);
 
     EventManager* manager = GetInstance()->GetEventManager();
 
@@ -1554,8 +1558,9 @@
 }
 RenderPipelineBase* DeviceBase::APICreateRenderPipeline(
     const RenderPipelineDescriptor* descriptor) {
+    utils::TraceLabel label = utils::GetLabelForTrace(descriptor->label);
     TRACE_EVENT1(GetPlatform(), General, "DeviceBase::APICreateRenderPipeline", "label",
-                 utils::GetLabelForTrace(descriptor->label));
+                 label.label);
 
     auto resultOrError = CreateRenderPipeline(descriptor);
     if (resultOrError.IsSuccess()) {
@@ -1573,8 +1578,8 @@
     return ReturnToAPI(std::move(result));
 }
 ShaderModuleBase* DeviceBase::APICreateShaderModule(const ShaderModuleDescriptor* descriptor) {
-    TRACE_EVENT1(GetPlatform(), General, "DeviceBase::APICreateShaderModule", "label",
-                 utils::GetLabelForTrace(descriptor->label));
+    utils::TraceLabel label = utils::GetLabelForTrace(descriptor->label);
+    TRACE_EVENT1(GetPlatform(), General, "DeviceBase::APICreateShaderModule", "label", label.label);
 
     std::unique_ptr<OwnedCompilationMessages> compilationMessages(
         std::make_unique<OwnedCompilationMessages>());
diff --git a/src/dawn/native/ExternalTexture.cpp b/src/dawn/native/ExternalTexture.cpp
index 7249bc5..ef76f78 100644
--- a/src/dawn/native/ExternalTexture.cpp
+++ b/src/dawn/native/ExternalTexture.cpp
@@ -152,7 +152,7 @@
 // Error external texture cannot be used in bind group.
 ExternalTextureBase::ExternalTextureBase(DeviceBase* device,
                                          ObjectBase::ErrorTag tag,
-                                         const char* label)
+                                         StringView label)
     : ApiObjectBase(device, tag, label), mState(ExternalTextureState::Destroyed) {}
 
 ExternalTextureBase::~ExternalTextureBase() = default;
@@ -425,7 +425,7 @@
 }
 
 // static
-Ref<ExternalTextureBase> ExternalTextureBase::MakeError(DeviceBase* device, const char* label) {
+Ref<ExternalTextureBase> ExternalTextureBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new ExternalTextureBase(device, ObjectBase::kError, label));
 }
 
diff --git a/src/dawn/native/ExternalTexture.h b/src/dawn/native/ExternalTexture.h
index 46c3f7b..ef0e623 100644
--- a/src/dawn/native/ExternalTexture.h
+++ b/src/dawn/native/ExternalTexture.h
@@ -77,7 +77,7 @@
     const Origin2D& GetVisibleOrigin() const;
 
     MaybeError ValidateCanUseInSubmitNow() const;
-    static Ref<ExternalTextureBase> MakeError(DeviceBase* device, const char* label = nullptr);
+    static Ref<ExternalTextureBase> MakeError(DeviceBase* device, StringView label = {});
 
     void APIExpire();
     void APIDestroy();
@@ -93,7 +93,7 @@
 
   private:
     enum class ExternalTextureState { Active, Expired, Destroyed };
-    ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    ExternalTextureBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     MaybeError ValidateRefresh();
     MaybeError ValidateExpire();
diff --git a/src/dawn/native/ObjectBase.cpp b/src/dawn/native/ObjectBase.cpp
index 94fbe77..a544c67 100644
--- a/src/dawn/native/ObjectBase.cpp
+++ b/src/dawn/native/ObjectBase.cpp
@@ -86,16 +86,18 @@
     }
 }
 
-ApiObjectBase::ApiObjectBase(DeviceBase* device, const char* label) : ObjectBase(device) {
-    if (label) {
-        mLabel = label;
+ApiObjectBase::ApiObjectBase(DeviceBase* device, StringView label) : ObjectBase(device) {
+    std::optional<std::string_view> sv = label;
+    if (sv.has_value()) {
+        mLabel = sv.value();
     }
 }
 
-ApiObjectBase::ApiObjectBase(DeviceBase* device, ErrorTag tag, const char* label)
+ApiObjectBase::ApiObjectBase(DeviceBase* device, ErrorTag tag, StringView label)
     : ObjectBase(device, tag) {
-    if (label) {
-        mLabel = label;
+    std::optional<std::string_view> sv = label;
+    if (sv.has_value()) {
+        mLabel = sv.value();
     }
 }
 
diff --git a/src/dawn/native/ObjectBase.h b/src/dawn/native/ObjectBase.h
index ed80cb7..3ae30aa 100644
--- a/src/dawn/native/ObjectBase.h
+++ b/src/dawn/native/ObjectBase.h
@@ -38,6 +38,7 @@
 #include "dawn/common/Ref.h"
 #include "dawn/common/RefCounted.h"
 #include "dawn/native/Forward.h"
+#include "dawn/native/dawn_platform.h"
 
 namespace dawn::native {
 
@@ -122,8 +123,8 @@
     static constexpr UntrackedByDeviceTag kUntrackedByDevice = {};
 
     ApiObjectBase(DeviceBase* device, LabelNotImplementedTag tag);
-    ApiObjectBase(DeviceBase* device, const char* label);
-    ApiObjectBase(DeviceBase* device, ErrorTag tag, const char* label = nullptr);
+    ApiObjectBase(DeviceBase* device, StringView label);
+    ApiObjectBase(DeviceBase* device, ErrorTag tag, StringView label = {});
     ~ApiObjectBase() override;
 
     virtual ObjectType GetType() const = 0;
diff --git a/src/dawn/native/Pipeline.cpp b/src/dawn/native/Pipeline.cpp
index b7b855b..58d5d4e 100644
--- a/src/dawn/native/Pipeline.cpp
+++ b/src/dawn/native/Pipeline.cpp
@@ -207,7 +207,7 @@
 
 PipelineBase::PipelineBase(DeviceBase* device,
                            PipelineLayoutBase* layout,
-                           const char* label,
+                           StringView label,
                            std::vector<StageAndDescriptor> stages)
     : ApiObjectBase(device, label), mLayout(layout) {
     DAWN_ASSERT(!stages.empty());
@@ -248,7 +248,7 @@
     }
 }
 
-PipelineBase::PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label)
+PipelineBase::PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label)
     : ApiObjectBase(device, tag, label) {}
 
 PipelineBase::~PipelineBase() = default;
diff --git a/src/dawn/native/Pipeline.h b/src/dawn/native/Pipeline.h
index 80c3e4e..e1d7c8c 100644
--- a/src/dawn/native/Pipeline.h
+++ b/src/dawn/native/Pipeline.h
@@ -96,9 +96,9 @@
   protected:
     PipelineBase(DeviceBase* device,
                  PipelineLayoutBase* layout,
-                 const char* label,
+                 StringView label,
                  std::vector<StageAndDescriptor> stages);
-    PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    PipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
   private:
     MaybeError ValidateGetBindGroupLayout(BindGroupIndex group);
diff --git a/src/dawn/native/PipelineLayout.cpp b/src/dawn/native/PipelineLayout.cpp
index 9405515..5cef13c 100644
--- a/src/dawn/native/PipelineLayout.cpp
+++ b/src/dawn/native/PipelineLayout.cpp
@@ -161,7 +161,7 @@
 
 PipelineLayoutBase::PipelineLayoutBase(DeviceBase* device,
                                        ObjectBase::ErrorTag tag,
-                                       const char* label)
+                                       StringView label)
     : ApiObjectBase(device, tag, label) {}
 
 PipelineLayoutBase::~PipelineLayoutBase() = default;
@@ -171,7 +171,7 @@
 }
 
 // static
-Ref<PipelineLayoutBase> PipelineLayoutBase::MakeError(DeviceBase* device, const char* label) {
+Ref<PipelineLayoutBase> PipelineLayoutBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new PipelineLayoutBase(device, ObjectBase::kError, label));
 }
 
diff --git a/src/dawn/native/PipelineLayout.h b/src/dawn/native/PipelineLayout.h
index f887694..6d2b4ef 100644
--- a/src/dawn/native/PipelineLayout.h
+++ b/src/dawn/native/PipelineLayout.h
@@ -80,7 +80,7 @@
     PipelineLayoutBase(DeviceBase* device, const UnpackedPtr<PipelineLayoutDescriptor>& descriptor);
     ~PipelineLayoutBase() override;
 
-    static Ref<PipelineLayoutBase> MakeError(DeviceBase* device, const char* label);
+    static Ref<PipelineLayoutBase> MakeError(DeviceBase* device, StringView label);
     static ResultOrError<Ref<PipelineLayoutBase>> CreateDefault(
         DeviceBase* device,
         std::vector<StageAndDescriptor> stages,
@@ -115,7 +115,7 @@
     uint32_t GetImmediateDataRangeByteSize() const;
 
   protected:
-    PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    PipelineLayoutBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
     void DestroyImpl() override;
 
     PerBindGroup<Ref<BindGroupLayoutBase>> mBindGroupLayouts;
diff --git a/src/dawn/native/ProgrammableEncoder.cpp b/src/dawn/native/ProgrammableEncoder.cpp
index 1de6916..e7ad6ee 100644
--- a/src/dawn/native/ProgrammableEncoder.cpp
+++ b/src/dawn/native/ProgrammableEncoder.cpp
@@ -43,7 +43,7 @@
 namespace dawn::native {
 
 ProgrammableEncoder::ProgrammableEncoder(DeviceBase* device,
-                                         const char* label,
+                                         StringView label,
                                          EncodingContext* encodingContext)
     : ApiObjectBase(device, label),
       mEncodingContext(encodingContext),
@@ -52,7 +52,7 @@
 ProgrammableEncoder::ProgrammableEncoder(DeviceBase* device,
                                          EncodingContext* encodingContext,
                                          ErrorTag errorTag,
-                                         const char* label)
+                                         StringView label)
     : ApiObjectBase(device, errorTag, label),
       mEncodingContext(encodingContext),
       mValidationEnabled(device->IsValidationEnabled()) {}
diff --git a/src/dawn/native/ProgrammableEncoder.h b/src/dawn/native/ProgrammableEncoder.h
index afffab0..d843e09 100644
--- a/src/dawn/native/ProgrammableEncoder.h
+++ b/src/dawn/native/ProgrammableEncoder.h
@@ -46,7 +46,7 @@
 // Base class for shared functionality between programmable encoders.
 class ProgrammableEncoder : public ApiObjectBase {
   public:
-    ProgrammableEncoder(DeviceBase* device, const char* label, EncodingContext* encodingContext);
+    ProgrammableEncoder(DeviceBase* device, StringView label, EncodingContext* encodingContext);
 
     // TODO(crbug.com/42241188): Remove const char* version of the methods.
     void APIInsertDebugMarker(const char* groupLabel) { APIInsertDebugMarker2(groupLabel); }
@@ -75,7 +75,7 @@
     ProgrammableEncoder(DeviceBase* device,
                         EncodingContext* encodingContext,
                         ErrorTag errorTag,
-                        const char* label);
+                        StringView label);
 
     raw_ptr<EncodingContext> mEncodingContext = nullptr;
 
diff --git a/src/dawn/native/Queue.cpp b/src/dawn/native/Queue.cpp
index a8197d2..cc8ef36 100644
--- a/src/dawn/native/Queue.cpp
+++ b/src/dawn/native/Queue.cpp
@@ -184,7 +184,7 @@
 
 class ErrorQueue : public QueueBase {
   public:
-    explicit ErrorQueue(DeviceBase* device, const char* label)
+    explicit ErrorQueue(DeviceBase* device, StringView label)
         : QueueBase(device, ObjectBase::kError, label) {}
 
   private:
@@ -216,7 +216,7 @@
     GetObjectTrackingList()->Track(this);
 }
 
-QueueBase::QueueBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label)
+QueueBase::QueueBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label)
     : ApiObjectBase(device, tag, label) {}
 
 QueueBase::~QueueBase() {
@@ -226,7 +226,7 @@
 void QueueBase::DestroyImpl() {}
 
 // static
-Ref<QueueBase> QueueBase::MakeError(DeviceBase* device, const char* label) {
+Ref<QueueBase> QueueBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new ErrorQueue(device, label));
 }
 
diff --git a/src/dawn/native/Queue.h b/src/dawn/native/Queue.h
index d0a53bf..36ec006 100644
--- a/src/dawn/native/Queue.h
+++ b/src/dawn/native/Queue.h
@@ -66,7 +66,7 @@
   public:
     ~QueueBase() override;
 
-    static Ref<QueueBase> MakeError(DeviceBase* device, const char* label);
+    static Ref<QueueBase> MakeError(DeviceBase* device, StringView label);
 
     ObjectType GetType() const override;
     void FormatLabel(absl::FormatSink* s) const override;
@@ -112,7 +112,7 @@
 
   protected:
     QueueBase(DeviceBase* device, const QueueDescriptor* descriptor);
-    QueueBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    QueueBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     void DestroyImpl() override;
 
diff --git a/src/dawn/native/RenderBundle.cpp b/src/dawn/native/RenderBundle.cpp
index 5e59e97..5271ec7 100644
--- a/src/dawn/native/RenderBundle.cpp
+++ b/src/dawn/native/RenderBundle.cpp
@@ -67,11 +67,11 @@
 }
 
 // static
-Ref<RenderBundleBase> RenderBundleBase::MakeError(DeviceBase* device, const char* label) {
+Ref<RenderBundleBase> RenderBundleBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new RenderBundleBase(device, ObjectBase::kError, label));
 }
 
-RenderBundleBase::RenderBundleBase(DeviceBase* device, ErrorTag errorTag, const char* label)
+RenderBundleBase::RenderBundleBase(DeviceBase* device, ErrorTag errorTag, StringView label)
     : ApiObjectBase(device, errorTag, label), mIndirectDrawMetadata(device->GetLimits()) {}
 
 ObjectType RenderBundleBase::GetType() const {
diff --git a/src/dawn/native/RenderBundle.h b/src/dawn/native/RenderBundle.h
index 91b96f2..66d79c8 100644
--- a/src/dawn/native/RenderBundle.h
+++ b/src/dawn/native/RenderBundle.h
@@ -57,7 +57,7 @@
                      RenderPassResourceUsage resourceUsage,
                      IndirectDrawMetadata indirectDrawMetadata);
 
-    static Ref<RenderBundleBase> MakeError(DeviceBase* device, const char* label);
+    static Ref<RenderBundleBase> MakeError(DeviceBase* device, StringView label);
 
     ObjectType GetType() const override;
     void FormatLabel(absl::FormatSink* s) const override;
@@ -75,7 +75,7 @@
     const IndirectDrawMetadata& GetIndirectDrawMetadata();
 
   private:
-    RenderBundleBase(DeviceBase* device, ErrorTag errorTag, const char* label);
+    RenderBundleBase(DeviceBase* device, ErrorTag errorTag, StringView label);
 
     void DestroyImpl() override;
 
diff --git a/src/dawn/native/RenderBundleEncoder.cpp b/src/dawn/native/RenderBundleEncoder.cpp
index e57d804..439db80 100644
--- a/src/dawn/native/RenderBundleEncoder.cpp
+++ b/src/dawn/native/RenderBundleEncoder.cpp
@@ -113,7 +113,7 @@
     GetObjectTrackingList()->Track(this);
 }
 
-RenderBundleEncoder::RenderBundleEncoder(DeviceBase* device, ErrorTag errorTag, const char* label)
+RenderBundleEncoder::RenderBundleEncoder(DeviceBase* device, ErrorTag errorTag, StringView label)
     : RenderEncoderBase(device, &mBundleEncodingContext, errorTag, label),
       mBundleEncodingContext(device, errorTag) {}
 
@@ -136,7 +136,7 @@
 }
 
 // static
-Ref<RenderBundleEncoder> RenderBundleEncoder::MakeError(DeviceBase* device, const char* label) {
+Ref<RenderBundleEncoder> RenderBundleEncoder::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new RenderBundleEncoder(device, ObjectBase::kError, label));
 }
 
diff --git a/src/dawn/native/RenderBundleEncoder.h b/src/dawn/native/RenderBundleEncoder.h
index 730fb52..de74229 100644
--- a/src/dawn/native/RenderBundleEncoder.h
+++ b/src/dawn/native/RenderBundleEncoder.h
@@ -43,7 +43,7 @@
   public:
     static Ref<RenderBundleEncoder> Create(DeviceBase* device,
                                            const RenderBundleEncoderDescriptor* descriptor);
-    static Ref<RenderBundleEncoder> MakeError(DeviceBase* device, const char* label);
+    static Ref<RenderBundleEncoder> MakeError(DeviceBase* device, StringView label);
 
     ~RenderBundleEncoder() override;
 
@@ -55,7 +55,7 @@
 
   private:
     RenderBundleEncoder(DeviceBase* device, const RenderBundleEncoderDescriptor* descriptor);
-    RenderBundleEncoder(DeviceBase* device, ErrorTag errorTag, const char* label);
+    RenderBundleEncoder(DeviceBase* device, ErrorTag errorTag, StringView label);
 
     void DestroyImpl() override;
 
diff --git a/src/dawn/native/RenderEncoderBase.cpp b/src/dawn/native/RenderEncoderBase.cpp
index de0359f..05695fb 100644
--- a/src/dawn/native/RenderEncoderBase.cpp
+++ b/src/dawn/native/RenderEncoderBase.cpp
@@ -44,7 +44,7 @@
 namespace dawn::native {
 
 RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
-                                     const char* label,
+                                     StringView label,
                                      EncodingContext* encodingContext,
                                      Ref<AttachmentState> attachmentState,
                                      bool depthReadOnly,
@@ -61,7 +61,7 @@
 RenderEncoderBase::RenderEncoderBase(DeviceBase* device,
                                      EncodingContext* encodingContext,
                                      ErrorTag errorTag,
-                                     const char* label)
+                                     StringView label)
     : ProgrammableEncoder(device, encodingContext, errorTag, label),
       mIndirectDrawMetadata(device->GetLimits()),
       mDisableBaseVertex(device->IsToggleEnabled(Toggle::DisableBaseVertex)),
diff --git a/src/dawn/native/RenderEncoderBase.h b/src/dawn/native/RenderEncoderBase.h
index f2a4f0e..94685ee 100644
--- a/src/dawn/native/RenderEncoderBase.h
+++ b/src/dawn/native/RenderEncoderBase.h
@@ -40,7 +40,7 @@
 class RenderEncoderBase : public ProgrammableEncoder {
   public:
     RenderEncoderBase(DeviceBase* device,
-                      const char* label,
+                      StringView label,
                       EncodingContext* encodingContext,
                       Ref<AttachmentState> attachmentState,
                       bool depthReadOnly,
@@ -95,7 +95,7 @@
     RenderEncoderBase(DeviceBase* device,
                       EncodingContext* encodingContext,
                       ErrorTag errorTag,
-                      const char* label);
+                      StringView label);
 
     void DestroyImpl() override;
 
diff --git a/src/dawn/native/RenderPassEncoder.cpp b/src/dawn/native/RenderPassEncoder.cpp
index d05d142..2162914 100644
--- a/src/dawn/native/RenderPassEncoder.cpp
+++ b/src/dawn/native/RenderPassEncoder.cpp
@@ -115,7 +115,7 @@
                                      CommandEncoder* commandEncoder,
                                      EncodingContext* encodingContext,
                                      ErrorTag errorTag,
-                                     const char* label)
+                                     StringView label)
     : RenderEncoderBase(device, encodingContext, errorTag, label),
       mCommandEncoder(commandEncoder) {}
 
@@ -123,7 +123,7 @@
 Ref<RenderPassEncoder> RenderPassEncoder::MakeError(DeviceBase* device,
                                                     CommandEncoder* commandEncoder,
                                                     EncodingContext* encodingContext,
-                                                    const char* label) {
+                                                    StringView label) {
     return AcquireRef(
         new RenderPassEncoder(device, commandEncoder, encodingContext, ObjectBase::kError, label));
 }
diff --git a/src/dawn/native/RenderPassEncoder.h b/src/dawn/native/RenderPassEncoder.h
index 242c8be..dca4501 100644
--- a/src/dawn/native/RenderPassEncoder.h
+++ b/src/dawn/native/RenderPassEncoder.h
@@ -55,7 +55,7 @@
     static Ref<RenderPassEncoder> MakeError(DeviceBase* device,
                                             CommandEncoder* commandEncoder,
                                             EncodingContext* encodingContext,
-                                            const char* label);
+                                            StringView label);
 
     ~RenderPassEncoder() override;
 
@@ -103,7 +103,7 @@
                       CommandEncoder* commandEncoder,
                       EncodingContext* encodingContext,
                       ErrorTag errorTag,
-                      const char* label);
+                      StringView label);
 
   private:
     void DestroyImpl() override;
diff --git a/src/dawn/native/RenderPipeline.cpp b/src/dawn/native/RenderPipeline.cpp
index 138d39a..df7f01e 100644
--- a/src/dawn/native/RenderPipeline.cpp
+++ b/src/dawn/native/RenderPipeline.cpp
@@ -1074,7 +1074,7 @@
 
 RenderPipelineBase::RenderPipelineBase(DeviceBase* device,
                                        ObjectBase::ErrorTag tag,
-                                       const char* label)
+                                       StringView label)
     : PipelineBase(device, tag, label) {}
 
 RenderPipelineBase::~RenderPipelineBase() = default;
@@ -1088,10 +1088,10 @@
 }
 
 // static
-Ref<RenderPipelineBase> RenderPipelineBase::MakeError(DeviceBase* device, const char* label) {
+Ref<RenderPipelineBase> RenderPipelineBase::MakeError(DeviceBase* device, StringView label) {
     class ErrorRenderPipeline final : public RenderPipelineBase {
       public:
-        explicit ErrorRenderPipeline(DeviceBase* device, const char* label)
+        explicit ErrorRenderPipeline(DeviceBase* device, StringView label)
             : RenderPipelineBase(device, ObjectBase::kError, label) {}
 
         MaybeError InitializeImpl() override {
diff --git a/src/dawn/native/RenderPipeline.h b/src/dawn/native/RenderPipeline.h
index 98d6cdc..bf20ace 100644
--- a/src/dawn/native/RenderPipeline.h
+++ b/src/dawn/native/RenderPipeline.h
@@ -91,7 +91,7 @@
     RenderPipelineBase(DeviceBase* device, const UnpackedPtr<RenderPipelineDescriptor>& descriptor);
     ~RenderPipelineBase() override;
 
-    static Ref<RenderPipelineBase> MakeError(DeviceBase* device, const char* label);
+    static Ref<RenderPipelineBase> MakeError(DeviceBase* device, StringView label);
 
     ObjectType GetType() const override;
 
@@ -153,7 +153,7 @@
     void DestroyImpl() override;
 
   private:
-    RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     // Vertex state
     uint32_t mVertexBufferCount;
diff --git a/src/dawn/native/Sampler.cpp b/src/dawn/native/Sampler.cpp
index 437b9c8..c7c80b1 100644
--- a/src/dawn/native/Sampler.cpp
+++ b/src/dawn/native/Sampler.cpp
@@ -107,7 +107,7 @@
     GetObjectTrackingList()->Track(this);
 }
 
-SamplerBase::SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label)
+SamplerBase::SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label)
     : ApiObjectBase(device, tag, label) {}
 
 SamplerBase::~SamplerBase() = default;
@@ -117,7 +117,7 @@
 }
 
 // static
-Ref<SamplerBase> SamplerBase::MakeError(DeviceBase* device, const char* label) {
+Ref<SamplerBase> SamplerBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new SamplerBase(device, ObjectBase::kError, label));
 }
 
diff --git a/src/dawn/native/Sampler.h b/src/dawn/native/Sampler.h
index 437b8c9..e7179f2 100644
--- a/src/dawn/native/Sampler.h
+++ b/src/dawn/native/Sampler.h
@@ -52,7 +52,7 @@
     SamplerBase(DeviceBase* device, const SamplerDescriptor* descriptor);
     ~SamplerBase() override;
 
-    static Ref<SamplerBase> MakeError(DeviceBase* device, const char* label);
+    static Ref<SamplerBase> MakeError(DeviceBase* device, StringView label);
 
     ObjectType GetType() const override;
 
@@ -79,7 +79,7 @@
     }
 
   private:
-    SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    SamplerBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     // TODO(cwallez@chromium.org): Store a crypto hash of the items instead?
     wgpu::AddressMode mAddressModeU;
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 2d4d5a5..507f4a3 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -1377,7 +1377,7 @@
     GetObjectTrackingList()->Track(this);
 }
 
-ShaderModuleBase::ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label)
+ShaderModuleBase::ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label)
     : Base(device, tag, label), mType(Type::Undefined) {}
 
 ShaderModuleBase::~ShaderModuleBase() = default;
@@ -1387,7 +1387,7 @@
 }
 
 // static
-Ref<ShaderModuleBase> ShaderModuleBase::MakeError(DeviceBase* device, const char* label) {
+Ref<ShaderModuleBase> ShaderModuleBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new ShaderModuleBase(device, ObjectBase::kError, label));
 }
 
diff --git a/src/dawn/native/ShaderModule.h b/src/dawn/native/ShaderModule.h
index f0cbea0..406a10e 100644
--- a/src/dawn/native/ShaderModule.h
+++ b/src/dawn/native/ShaderModule.h
@@ -299,7 +299,7 @@
                      std::vector<tint::wgsl::Extension> internalExtensions);
     ~ShaderModuleBase() override;
 
-    static Ref<ShaderModuleBase> MakeError(DeviceBase* device, const char* label);
+    static Ref<ShaderModuleBase> MakeError(DeviceBase* device, StringView label);
 
     ObjectType GetType() const override;
 
@@ -347,7 +347,7 @@
                               OwnedCompilationMessages* compilationMessages);
 
   private:
-    ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    ShaderModuleBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     void WillDropLastExternalRef() override;
 
diff --git a/src/dawn/native/SharedBufferMemory.cpp b/src/dawn/native/SharedBufferMemory.cpp
index d112b9d..d06da94 100644
--- a/src/dawn/native/SharedBufferMemory.cpp
+++ b/src/dawn/native/SharedBufferMemory.cpp
@@ -76,7 +76,7 @@
       mProperties{nullptr, wgpu::BufferUsage::None, 0} {}
 
 SharedBufferMemoryBase::SharedBufferMemoryBase(DeviceBase* device,
-                                               const char* label,
+                                               StringView label,
                                                const SharedBufferMemoryProperties& properties)
     : SharedResourceMemory(device, label), mProperties(properties) {
     GetObjectTrackingList()->Track(this);
diff --git a/src/dawn/native/SharedBufferMemory.h b/src/dawn/native/SharedBufferMemory.h
index b4e76ca..deacb4d 100644
--- a/src/dawn/native/SharedBufferMemory.h
+++ b/src/dawn/native/SharedBufferMemory.h
@@ -59,7 +59,7 @@
 
   protected:
     SharedBufferMemoryBase(DeviceBase* device,
-                           const char* label,
+                           StringView label,
                            const SharedBufferMemoryProperties& properties);
     SharedBufferMemoryBase(DeviceBase* device,
                            const SharedBufferMemoryDescriptor* descriptor,
diff --git a/src/dawn/native/SharedFence.cpp b/src/dawn/native/SharedFence.cpp
index de53d1a..3aad8c1 100644
--- a/src/dawn/native/SharedFence.cpp
+++ b/src/dawn/native/SharedFence.cpp
@@ -58,7 +58,7 @@
                                  ObjectBase::ErrorTag tag)
     : ApiObjectBase(device, tag, descriptor->label) {}
 
-SharedFenceBase::SharedFenceBase(DeviceBase* device, const char* label)
+SharedFenceBase::SharedFenceBase(DeviceBase* device, StringView label)
     : ApiObjectBase(device, label) {}
 
 ObjectType SharedFenceBase::GetType() const {
diff --git a/src/dawn/native/SharedFence.h b/src/dawn/native/SharedFence.h
index e75dd55..c515bae 100644
--- a/src/dawn/native/SharedFence.h
+++ b/src/dawn/native/SharedFence.h
@@ -48,7 +48,7 @@
     MaybeError ExportInfo(SharedFenceExportInfo* info) const;
 
   protected:
-    SharedFenceBase(DeviceBase* device, const char* label);
+    SharedFenceBase(DeviceBase* device, StringView label);
     SharedFenceBase(DeviceBase* device,
                     const SharedFenceDescriptor* descriptor,
                     ObjectBase::ErrorTag tag);
diff --git a/src/dawn/native/SharedResourceMemory.cpp b/src/dawn/native/SharedResourceMemory.cpp
index 73c08d7..91ef7be 100644
--- a/src/dawn/native/SharedResourceMemory.cpp
+++ b/src/dawn/native/SharedResourceMemory.cpp
@@ -46,7 +46,7 @@
 
 SharedResourceMemory::SharedResourceMemory(DeviceBase* device,
                                            ObjectBase::ErrorTag tag,
-                                           const char* label)
+                                           StringView label)
     : ApiObjectBase(device, tag, label),
       mContents(new SharedResourceMemoryContents(GetWeakRef(this))) {}
 
diff --git a/src/dawn/native/SharedResourceMemory.h b/src/dawn/native/SharedResourceMemory.h
index c7b908a..587cbae 100644
--- a/src/dawn/native/SharedResourceMemory.h
+++ b/src/dawn/native/SharedResourceMemory.h
@@ -101,7 +101,7 @@
     MaybeError ValidateResourceCreatedFromSelf(SharedResource* resource);
 
   protected:
-    SharedResourceMemory(DeviceBase* device, ObjectBase::ErrorTag, const char* label);
+    SharedResourceMemory(DeviceBase* device, ObjectBase::ErrorTag, StringView label);
     using ApiObjectBase::ApiObjectBase;
 
   private:
diff --git a/src/dawn/native/SharedTextureMemory.cpp b/src/dawn/native/SharedTextureMemory.cpp
index b34eed2..0f5d8ca 100644
--- a/src/dawn/native/SharedTextureMemory.cpp
+++ b/src/dawn/native/SharedTextureMemory.cpp
@@ -83,7 +83,7 @@
       } {}
 
 SharedTextureMemoryBase::SharedTextureMemoryBase(DeviceBase* device,
-                                                 const char* label,
+                                                 StringView label,
                                                  const SharedTextureMemoryProperties& properties)
     : SharedResourceMemory(device, label), mProperties(properties) {
     // Reify properties to ensure we don't expose capabilities not supported by the device.
diff --git a/src/dawn/native/SharedTextureMemory.h b/src/dawn/native/SharedTextureMemory.h
index 8a61cdf..1623e0c 100644
--- a/src/dawn/native/SharedTextureMemory.h
+++ b/src/dawn/native/SharedTextureMemory.h
@@ -65,7 +65,7 @@
 
   protected:
     SharedTextureMemoryBase(DeviceBase* device,
-                            const char* label,
+                            StringView label,
                             const SharedTextureMemoryProperties& properties);
     SharedTextureMemoryBase(DeviceBase* device,
                             const SharedTextureMemoryDescriptor* descriptor,
diff --git a/src/dawn/native/Surface.cpp b/src/dawn/native/Surface.cpp
index 6bc7645..cbfb686 100644
--- a/src/dawn/native/Surface.cpp
+++ b/src/dawn/native/Surface.cpp
@@ -274,8 +274,9 @@
     : ErrorMonad(),
       mInstance(instance),
       mCapabilityCache(std::make_unique<AdapterSurfaceCapCache>()) {
-    if (descriptor->label != nullptr && strlen(descriptor->label) != 0) {
-        mLabel = descriptor->label;
+    std::optional<std::string_view> label = descriptor->label;
+    if (label.has_value()) {
+        mLabel = label.value();
     }
 
     // Type is validated in validation, otherwise this may crash with an assert failure.
diff --git a/src/dawn/native/Texture.cpp b/src/dawn/native/Texture.cpp
index 8d929f5..8f6bec8 100644
--- a/src/dawn/native/Texture.cpp
+++ b/src/dawn/native/Texture.cpp
@@ -1308,7 +1308,7 @@
     GetObjectTrackingList()->Track(this);
 }
 
-TextureViewBase::TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label)
+TextureViewBase::TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label)
     : ApiObjectBase(device, tag, label), mFormat(kUnusedFormat) {}
 
 TextureViewBase::~TextureViewBase() = default;
@@ -1316,7 +1316,7 @@
 void TextureViewBase::DestroyImpl() {}
 
 // static
-Ref<TextureViewBase> TextureViewBase::MakeError(DeviceBase* device, const char* label) {
+Ref<TextureViewBase> TextureViewBase::MakeError(DeviceBase* device, StringView label) {
     return AcquireRef(new TextureViewBase(device, ObjectBase::kError, label));
 }
 
diff --git a/src/dawn/native/Texture.h b/src/dawn/native/Texture.h
index caad0e2..115d65c 100644
--- a/src/dawn/native/Texture.h
+++ b/src/dawn/native/Texture.h
@@ -223,7 +223,7 @@
     TextureViewBase(TextureBase* texture, const UnpackedPtr<TextureViewDescriptor>& descriptor);
     ~TextureViewBase() override;
 
-    static Ref<TextureViewBase> MakeError(DeviceBase* device, const char* label = nullptr);
+    static Ref<TextureViewBase> MakeError(DeviceBase* device, StringView label = nullptr);
 
     ObjectType GetType() const override;
     void FormatLabel(absl::FormatSink* s) const override;
@@ -247,7 +247,7 @@
     void DestroyImpl() override;
 
   private:
-    TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag, const char* label);
+    TextureViewBase(DeviceBase* device, ObjectBase::ErrorTag tag, StringView label);
 
     ApiObjectList* GetObjectTrackingList() override;
 
diff --git a/src/dawn/native/d3d/SharedFenceD3D.cpp b/src/dawn/native/d3d/SharedFenceD3D.cpp
index 9c65447..7ffa1b1 100644
--- a/src/dawn/native/d3d/SharedFenceD3D.cpp
+++ b/src/dawn/native/d3d/SharedFenceD3D.cpp
@@ -34,7 +34,7 @@
 
 namespace dawn::native::d3d {
 
-SharedFence::SharedFence(Device* device, const char* label, SystemHandle ownedHandle)
+SharedFence::SharedFence(Device* device, StringView label, SystemHandle ownedHandle)
     : SharedFenceBase(device, label), mHandle(std::move(ownedHandle)) {}
 
 HANDLE SharedFence::GetFenceHandle() const {
diff --git a/src/dawn/native/d3d/SharedFenceD3D.h b/src/dawn/native/d3d/SharedFenceD3D.h
index 8cf70bd..822598e 100644
--- a/src/dawn/native/d3d/SharedFenceD3D.h
+++ b/src/dawn/native/d3d/SharedFenceD3D.h
@@ -42,7 +42,7 @@
     HANDLE GetFenceHandle() const;
 
   protected:
-    SharedFence(Device* device, const char* label, SystemHandle ownedHandle);
+    SharedFence(Device* device, StringView label, SystemHandle ownedHandle);
 
   private:
     MaybeError ExportInfoImpl(UnpackedPtr<SharedFenceExportInfo>& info) const override;
diff --git a/src/dawn/native/d3d/SharedTextureMemoryD3D.cpp b/src/dawn/native/d3d/SharedTextureMemoryD3D.cpp
index 0211719..27ca2bf 100644
--- a/src/dawn/native/d3d/SharedTextureMemoryD3D.cpp
+++ b/src/dawn/native/d3d/SharedTextureMemoryD3D.cpp
@@ -39,7 +39,7 @@
 namespace dawn::native::d3d {
 
 SharedTextureMemory::SharedTextureMemory(d3d::Device* device,
-                                         const char* label,
+                                         StringView label,
                                          SharedTextureMemoryProperties properties)
     : SharedTextureMemoryBase(device, label, properties) {}
 
diff --git a/src/dawn/native/d3d/SharedTextureMemoryD3D.h b/src/dawn/native/d3d/SharedTextureMemoryD3D.h
index ebfd138..b66dd28 100644
--- a/src/dawn/native/d3d/SharedTextureMemoryD3D.h
+++ b/src/dawn/native/d3d/SharedTextureMemoryD3D.h
@@ -37,9 +37,7 @@
 
 class SharedTextureMemory : public SharedTextureMemoryBase {
   protected:
-    SharedTextureMemory(Device* device,
-                        const char* label,
-                        SharedTextureMemoryProperties properties);
+    SharedTextureMemory(Device* device, StringView label, SharedTextureMemoryProperties properties);
 
     MaybeError BeginAccessImpl(TextureBase* texture,
                                const UnpackedPtr<BeginAccessDescriptor>& descriptor) override;
diff --git a/src/dawn/native/d3d11/SharedFenceD3D11.cpp b/src/dawn/native/d3d11/SharedFenceD3D11.cpp
index 215c99c..127e9b0 100644
--- a/src/dawn/native/d3d11/SharedFenceD3D11.cpp
+++ b/src/dawn/native/d3d11/SharedFenceD3D11.cpp
@@ -37,7 +37,7 @@
 // static
 ResultOrError<Ref<SharedFence>> SharedFence::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedFenceDXGISharedHandleDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->handle == nullptr, "shared HANDLE is missing.");
 
@@ -54,7 +54,7 @@
 
 // static
 ResultOrError<Ref<SharedFence>> SharedFence::Create(Device* device,
-                                                    const char* label,
+                                                    StringView label,
                                                     ComPtr<ID3D11Fence> d3d11Fence) {
     SystemHandle ownedHandle;
     DAWN_TRY(CheckHRESULT(
diff --git a/src/dawn/native/d3d11/SharedFenceD3D11.h b/src/dawn/native/d3d11/SharedFenceD3D11.h
index ce60249..3e2572f 100644
--- a/src/dawn/native/d3d11/SharedFenceD3D11.h
+++ b/src/dawn/native/d3d11/SharedFenceD3D11.h
@@ -39,11 +39,11 @@
   public:
     static ResultOrError<Ref<SharedFence>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedFenceDXGISharedHandleDescriptor* descriptor);
 
     static ResultOrError<Ref<SharedFence>> Create(Device* device,
-                                                  const char* label,
+                                                  StringView label,
                                                   ComPtr<ID3D11Fence> d3d11Fence);
 
     ID3D11Fence* GetD3DFence() const;
diff --git a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp
index c841200..8550ddb 100644
--- a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp
+++ b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.cpp
@@ -91,7 +91,7 @@
 // static
 ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedTextureMemoryDXGISharedHandleDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->handle == nullptr, "shared HANDLE is missing.");
 
@@ -122,7 +122,7 @@
 // static
 ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedTextureMemoryD3D11Texture2DDescriptor* descriptor) {
     DAWN_INVALID_IF(!descriptor->texture, "D3D11 texture is missing.");
 
@@ -147,7 +147,7 @@
 }
 
 SharedTextureMemory::SharedTextureMemory(Device* device,
-                                         const char* label,
+                                         StringView label,
                                          SharedTextureMemoryProperties properties,
                                          ComPtr<ID3D11Resource> resource)
     : d3d::SharedTextureMemory(device, label, properties), mResource(std::move(resource)) {
diff --git a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.h b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.h
index 116343d..d612ddb 100644
--- a/src/dawn/native/d3d11/SharedTextureMemoryD3D11.h
+++ b/src/dawn/native/d3d11/SharedTextureMemoryD3D11.h
@@ -45,12 +45,12 @@
   public:
     static ResultOrError<Ref<SharedTextureMemory>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedTextureMemoryDXGISharedHandleDescriptor* descriptor);
 
     static ResultOrError<Ref<SharedTextureMemory>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedTextureMemoryD3D11Texture2DDescriptor* descriptor);
 
     ID3D11Resource* GetD3DResource() const;
@@ -59,7 +59,7 @@
 
   private:
     SharedTextureMemory(Device* device,
-                        const char* label,
+                        StringView label,
                         SharedTextureMemoryProperties properties,
                         ComPtr<ID3D11Resource> resource);
 
diff --git a/src/dawn/native/d3d12/SharedBufferMemoryD3D12.cpp b/src/dawn/native/d3d12/SharedBufferMemoryD3D12.cpp
index 2c4266b..4dca66d 100644
--- a/src/dawn/native/d3d12/SharedBufferMemoryD3D12.cpp
+++ b/src/dawn/native/d3d12/SharedBufferMemoryD3D12.cpp
@@ -41,7 +41,7 @@
 namespace dawn::native::d3d12 {
 
 SharedBufferMemory::SharedBufferMemory(Device* device,
-                                       const char* label,
+                                       StringView label,
                                        SharedBufferMemoryProperties properties,
                                        ComPtr<ID3D12Resource> resource)
     : SharedBufferMemoryBase(device, label, properties), mResource(std::move(resource)) {}
@@ -53,7 +53,7 @@
 // static
 ResultOrError<Ref<SharedBufferMemory>> SharedBufferMemory::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedBufferMemoryD3D12ResourceDescriptor* descriptor) {
     DAWN_INVALID_IF(!descriptor->resource, "D3D12 resource is missing.");
 
diff --git a/src/dawn/native/d3d12/SharedBufferMemoryD3D12.h b/src/dawn/native/d3d12/SharedBufferMemoryD3D12.h
index 894cf19..4ef2ba4 100644
--- a/src/dawn/native/d3d12/SharedBufferMemoryD3D12.h
+++ b/src/dawn/native/d3d12/SharedBufferMemoryD3D12.h
@@ -40,14 +40,14 @@
   public:
     static ResultOrError<Ref<SharedBufferMemory>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedBufferMemoryD3D12ResourceDescriptor* descriptor);
 
     ID3D12Resource* GetD3DResource() const;
 
   private:
     SharedBufferMemory(Device* device,
-                       const char* label,
+                       StringView label,
                        SharedBufferMemoryProperties properties,
                        ComPtr<ID3D12Resource> resource);
 
diff --git a/src/dawn/native/d3d12/SharedFenceD3D12.cpp b/src/dawn/native/d3d12/SharedFenceD3D12.cpp
index 18598f9..d5929d6 100644
--- a/src/dawn/native/d3d12/SharedFenceD3D12.cpp
+++ b/src/dawn/native/d3d12/SharedFenceD3D12.cpp
@@ -37,7 +37,7 @@
 // static
 ResultOrError<Ref<SharedFence>> SharedFence::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedFenceDXGISharedHandleDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->handle == nullptr, "shared HANDLE is missing.");
 
@@ -54,7 +54,7 @@
 
 // static
 ResultOrError<Ref<SharedFence>> SharedFence::Create(Device* device,
-                                                    const char* label,
+                                                    StringView label,
                                                     ComPtr<ID3D12Fence> d3d12Fence) {
     SystemHandle ownedHandle;
     DAWN_TRY(
diff --git a/src/dawn/native/d3d12/SharedFenceD3D12.h b/src/dawn/native/d3d12/SharedFenceD3D12.h
index f3d1558..313da06 100644
--- a/src/dawn/native/d3d12/SharedFenceD3D12.h
+++ b/src/dawn/native/d3d12/SharedFenceD3D12.h
@@ -39,11 +39,11 @@
   public:
     static ResultOrError<Ref<SharedFence>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedFenceDXGISharedHandleDescriptor* descriptor);
 
     static ResultOrError<Ref<SharedFence>> Create(Device* device,
-                                                  const char* label,
+                                                  StringView label,
                                                   ComPtr<ID3D12Fence> d3d12Fence);
 
     ID3D12Fence* GetD3DFence() const;
diff --git a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
index 248e083..8a5ec77 100644
--- a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
+++ b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.cpp
@@ -41,7 +41,7 @@
 // static
 ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedTextureMemoryDXGISharedHandleDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->handle == nullptr, "shared HANDLE is missing.");
 
@@ -99,7 +99,7 @@
 }
 
 SharedTextureMemory::SharedTextureMemory(Device* device,
-                                         const char* label,
+                                         StringView label,
                                          SharedTextureMemoryProperties properties,
                                          ComPtr<ID3D12Resource> resource,
                                          Ref<d3d::KeyedMutex> keyedMutex)
diff --git a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.h b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.h
index b139df7..2ab48ea 100644
--- a/src/dawn/native/d3d12/SharedTextureMemoryD3D12.h
+++ b/src/dawn/native/d3d12/SharedTextureMemoryD3D12.h
@@ -44,7 +44,7 @@
   public:
     static ResultOrError<Ref<SharedTextureMemory>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedTextureMemoryDXGISharedHandleDescriptor* descriptor);
 
     ID3D12Resource* GetD3DResource() const;
@@ -53,7 +53,7 @@
 
   private:
     SharedTextureMemory(Device* device,
-                        const char* label,
+                        StringView label,
                         SharedTextureMemoryProperties properties,
                         ComPtr<ID3D12Resource> resource,
                         Ref<d3d::KeyedMutex> keyedMutex);
diff --git a/src/dawn/native/metal/ShaderModuleMTL.mm b/src/dawn/native/metal/ShaderModuleMTL.mm
index 0151a18..609befd 100644
--- a/src/dawn/native/metal/ShaderModuleMTL.mm
+++ b/src/dawn/native/metal/ShaderModuleMTL.mm
@@ -422,7 +422,7 @@
                                         const RenderPipeline* renderPipeline,
                                         std::optional<uint32_t> maxSubgroupSizeForFullSubgroups) {
     TRACE_EVENT1(GetDevice()->GetPlatform(), General, "metal::ShaderModule::CreateFunction",
-                 "label", utils::GetLabelForTrace(GetLabel().c_str()));
+                 "label", utils::GetLabelForTrace(GetLabel()));
 
     DAWN_ASSERT(!IsError());
     DAWN_ASSERT(out);
diff --git a/src/dawn/native/metal/SharedFenceMTL.h b/src/dawn/native/metal/SharedFenceMTL.h
index ec36996..e790d24 100644
--- a/src/dawn/native/metal/SharedFenceMTL.h
+++ b/src/dawn/native/metal/SharedFenceMTL.h
@@ -43,15 +43,13 @@
 
 class SharedFence final : public SharedFenceBase {
   public:
-    static ResultOrError<Ref<SharedFence>> Create(
-        Device* device,
-        const char* label,
-        const SharedFenceMTLSharedEventDescriptor* descriptor);
+    static ResultOrError<Ref<SharedFence>>
+    Create(Device* device, StringView label, const SharedFenceMTLSharedEventDescriptor* descriptor);
 
     id<MTLSharedEvent> GetMTLSharedEvent() const API_AVAILABLE(macos(10.14), ios(12.0));
 
   private:
-    SharedFence(Device* device, const char* label, id<MTLSharedEvent> sharedEvent)
+    SharedFence(Device* device, StringView label, id<MTLSharedEvent> sharedEvent)
         API_AVAILABLE(macos(10.14), ios(12.0));
 
     MaybeError ExportInfoImpl(UnpackedPtr<SharedFenceExportInfo>& info) const override;
diff --git a/src/dawn/native/metal/SharedFenceMTL.mm b/src/dawn/native/metal/SharedFenceMTL.mm
index bde8bfe..76c84be 100644
--- a/src/dawn/native/metal/SharedFenceMTL.mm
+++ b/src/dawn/native/metal/SharedFenceMTL.mm
@@ -35,7 +35,7 @@
 // static
 ResultOrError<Ref<SharedFence>> SharedFence::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedFenceMTLSharedEventDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->sharedEvent == nullptr, "MTLSharedEvent is missing.");
     if (@available(macOS 10.14, iOS 12.0, *)) {
@@ -46,7 +46,7 @@
     }
 }
 
-SharedFence::SharedFence(Device* device, const char* label, id<MTLSharedEvent> sharedEvent)
+SharedFence::SharedFence(Device* device, StringView label, id<MTLSharedEvent> sharedEvent)
     : SharedFenceBase(device, label), mSharedEvent(sharedEvent) {}
 
 id<MTLSharedEvent> SharedFence::GetMTLSharedEvent() const {
diff --git a/src/dawn/native/metal/SharedTextureMemoryMTL.h b/src/dawn/native/metal/SharedTextureMemoryMTL.h
index b77f887..20d92a6 100644
--- a/src/dawn/native/metal/SharedTextureMemoryMTL.h
+++ b/src/dawn/native/metal/SharedTextureMemoryMTL.h
@@ -48,7 +48,7 @@
   public:
     static ResultOrError<Ref<SharedTextureMemory>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedTextureMemoryIOSurfaceDescriptor* descriptor);
 
     IOSurfaceRef GetIOSurface() const;
@@ -59,7 +59,7 @@
 
   private:
     SharedTextureMemory(Device* device,
-                        const char* label,
+                        StringView label,
                         const SharedTextureMemoryProperties& properties,
                         IOSurfaceRef ioSurface);
     // Performs initialization of the base class followed by Metal-specific
diff --git a/src/dawn/native/metal/SharedTextureMemoryMTL.mm b/src/dawn/native/metal/SharedTextureMemoryMTL.mm
index 848889d..fd791e7 100644
--- a/src/dawn/native/metal/SharedTextureMemoryMTL.mm
+++ b/src/dawn/native/metal/SharedTextureMemoryMTL.mm
@@ -94,7 +94,7 @@
 // static
 ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedTextureMemoryIOSurfaceDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->ioSurface == nullptr, "IOSurface is missing.");
 
@@ -134,7 +134,7 @@
 }
 
 SharedTextureMemory::SharedTextureMemory(Device* device,
-                                         const char* label,
+                                         StringView label,
                                          const SharedTextureMemoryProperties& properties,
                                          IOSurfaceRef ioSurface)
     : SharedTextureMemoryBase(device, label, properties), mIOSurface(ioSurface) {}
diff --git a/src/dawn/native/utils/WGPUHelpers.cpp b/src/dawn/native/utils/WGPUHelpers.cpp
index 667b150..325b92e 100644
--- a/src/dawn/native/utils/WGPUHelpers.cpp
+++ b/src/dawn/native/utils/WGPUHelpers.cpp
@@ -207,8 +207,25 @@
     return device->CreateBindGroup(&descriptor, mode);
 }
 
-const char* GetLabelForTrace(const char* label) {
-    return (label == nullptr || strlen(label) == 0) ? "None" : label;
+const char* GetLabelForTrace(const std::string& label) {
+    if (label.length() == 0) {
+        return "None";
+    }
+    return label.c_str();
+}
+
+TraceLabel GetLabelForTrace(StringView label) {
+    if (label.data == nullptr) {
+        return {{}, {}, "None"};
+    }
+    if (label.length == WGPU_STRLEN) {
+        return {{}, {}, label.data};
+    }
+
+    TraceLabel result;
+    result.storage = {label.data, label.length};
+    result.label = result.storage.c_str();
+    return result;
 }
 
 std::string_view NormalizeMessageString(std::optional<std::string_view> in) {
diff --git a/src/dawn/native/utils/WGPUHelpers.h b/src/dawn/native/utils/WGPUHelpers.h
index 68bab2d..b550d03 100644
--- a/src/dawn/native/utils/WGPUHelpers.h
+++ b/src/dawn/native/utils/WGPUHelpers.h
@@ -30,8 +30,10 @@
 
 #include <array>
 #include <initializer_list>
+#include <string>
 #include <vector>
 
+#include "dawn/common/NonCopyable.h"
 #include "dawn/common/Ref.h"
 #include "dawn/native/Error.h"
 #include "dawn/native/UsageValidationMode.h"
@@ -141,7 +143,14 @@
     std::initializer_list<BindingInitializationHelper> entriesInitializer,
     UsageValidationMode mode);
 
-const char* GetLabelForTrace(const char* label);
+// Converts a label to be nice for TraceEvent calls. Might perform a copy if the string isn't
+// null-terminated as TraceEvent only supports const char*
+struct TraceLabel : public NonCopyable {
+    std::string storage;
+    const char* label;
+};
+TraceLabel GetLabelForTrace(StringView label);
+const char* GetLabelForTrace(const std::string& label);
 
 // Given a std vector, allocate an equivalent array that can be returned in an API's foos/fooCount
 // pair of fields. The apiData must eventually be freed using FreeApiSeq.
diff --git a/src/dawn/native/vulkan/SharedFenceVk.cpp b/src/dawn/native/vulkan/SharedFenceVk.cpp
index 881c5eb..0c7c5ae 100644
--- a/src/dawn/native/vulkan/SharedFenceVk.cpp
+++ b/src/dawn/native/vulkan/SharedFenceVk.cpp
@@ -37,7 +37,7 @@
 // static
 ResultOrError<Ref<SharedFence>> SharedFence::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedFenceVkSemaphoreZirconHandleDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->handle == 0, "Zircon handle (%d) was invalid.", descriptor->handle);
 
@@ -51,7 +51,7 @@
 // static
 ResultOrError<Ref<SharedFence>> SharedFence::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedFenceVkSemaphoreSyncFDDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->handle < 0, "File descriptor (%d) was invalid.",
                     descriptor->handle);
@@ -65,7 +65,7 @@
 // static
 ResultOrError<Ref<SharedFence>> SharedFence::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedFenceVkSemaphoreOpaqueFDDescriptor* descriptor) {
     DAWN_INVALID_IF(descriptor->handle < 0, "File descriptor (%d) was invalid.",
                     descriptor->handle);
@@ -76,7 +76,7 @@
     return fence;
 }
 
-SharedFence::SharedFence(Device* device, const char* label, SystemHandle handle)
+SharedFence::SharedFence(Device* device, StringView label, SystemHandle handle)
     : SharedFenceBase(device, label), mHandle(std::move(handle)) {}
 
 void SharedFence::DestroyImpl() {
diff --git a/src/dawn/native/vulkan/SharedFenceVk.h b/src/dawn/native/vulkan/SharedFenceVk.h
index c9c955c..dc76f87 100644
--- a/src/dawn/native/vulkan/SharedFenceVk.h
+++ b/src/dawn/native/vulkan/SharedFenceVk.h
@@ -41,23 +41,23 @@
   public:
     static ResultOrError<Ref<SharedFence>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedFenceVkSemaphoreOpaqueFDDescriptor* descriptor);
 
     static ResultOrError<Ref<SharedFence>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedFenceVkSemaphoreSyncFDDescriptor* descriptor);
 
     static ResultOrError<Ref<SharedFence>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedFenceVkSemaphoreZirconHandleDescriptor* descriptor);
 
     const SystemHandle& GetHandle() const;
 
   private:
-    SharedFence(Device* device, const char* label, SystemHandle handle);
+    SharedFence(Device* device, StringView label, SystemHandle handle);
     void DestroyImpl() override;
 
     MaybeError ExportInfoImpl(UnpackedPtr<SharedFenceExportInfo>& info) const override;
diff --git a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
index 02d5b99..1122d45 100644
--- a/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
+++ b/src/dawn/native/vulkan/SharedTextureMemoryVk.cpp
@@ -42,6 +42,7 @@
 #include "dawn/native/vulkan/TextureVk.h"
 #include "dawn/native/vulkan/UtilsVulkan.h"
 #include "dawn/native/vulkan/VulkanError.h"
+#include "dawn/native/wgpu_structs_autogen.h"
 
 #if DAWN_PLATFORM_IS(ANDROID)
 #include <android/hardware_buffer.h>
@@ -214,7 +215,7 @@
 // static
 ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedTextureMemoryDmaBufDescriptor* descriptor) {
 #if DAWN_PLATFORM_IS(LINUX)
     VkDevice vkDevice = device->GetVkDevice();
@@ -477,7 +478,7 @@
 // static
 ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedTextureMemoryAHardwareBufferDescriptor* descriptor) {
 #if DAWN_PLATFORM_IS(ANDROID)
     const auto* ahbFunctions =
@@ -743,7 +744,7 @@
 // static
 ResultOrError<Ref<SharedTextureMemory>> SharedTextureMemory::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedTextureMemoryOpaqueFDDescriptor* descriptor) {
 #if DAWN_PLATFORM_IS(POSIX)
     VkDevice vkDevice = device->GetVkDevice();
@@ -961,7 +962,7 @@
 // static
 Ref<SharedTextureMemory> SharedTextureMemory::Create(
     Device* device,
-    const char* label,
+    StringView label,
     const SharedTextureMemoryProperties& properties,
     uint32_t queueFamilyIndex) {
     Ref<SharedTextureMemory> sharedTextureMemory =
@@ -971,7 +972,7 @@
 }
 
 SharedTextureMemory::SharedTextureMemory(Device* device,
-                                         const char* label,
+                                         StringView label,
                                          const SharedTextureMemoryProperties& properties,
                                          uint32_t queueFamilyIndex)
     : SharedTextureMemoryBase(device, label, properties), mQueueFamilyIndex(queueFamilyIndex) {}
diff --git a/src/dawn/native/vulkan/SharedTextureMemoryVk.h b/src/dawn/native/vulkan/SharedTextureMemoryVk.h
index c9e35cf..309f5f6 100644
--- a/src/dawn/native/vulkan/SharedTextureMemoryVk.h
+++ b/src/dawn/native/vulkan/SharedTextureMemoryVk.h
@@ -39,19 +39,17 @@
 
 class SharedTextureMemory final : public SharedTextureMemoryBase {
   public:
-    static ResultOrError<Ref<SharedTextureMemory>> Create(
-        Device* device,
-        const char* label,
-        const SharedTextureMemoryDmaBufDescriptor* descriptor);
+    static ResultOrError<Ref<SharedTextureMemory>>
+    Create(Device* device, StringView label, const SharedTextureMemoryDmaBufDescriptor* descriptor);
 
     static ResultOrError<Ref<SharedTextureMemory>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedTextureMemoryAHardwareBufferDescriptor* descriptor);
 
     static ResultOrError<Ref<SharedTextureMemory>> Create(
         Device* device,
-        const char* label,
+        StringView label,
         const SharedTextureMemoryOpaqueFDDescriptor* descriptor);
 
     RefCountedVkHandle<VkDeviceMemory>* GetVkDeviceMemory() const;
@@ -60,12 +58,12 @@
 
   private:
     static Ref<SharedTextureMemory> Create(Device* device,
-                                           const char* label,
+                                           StringView label,
                                            const SharedTextureMemoryProperties& properties,
                                            uint32_t queueFamilyIndex);
 
     SharedTextureMemory(Device* device,
-                        const char* label,
+                        StringView label,
                         const SharedTextureMemoryProperties& properties,
                         uint32_t queueFamilyIndex);
     void DestroyImpl() override;
diff --git a/src/dawn/node/binding/Converter.cpp b/src/dawn/node/binding/Converter.cpp
index 4b13d7d..7244956 100644
--- a/src/dawn/node/binding/Converter.cpp
+++ b/src/dawn/node/binding/Converter.cpp
@@ -1766,4 +1766,12 @@
     return false;
 }
 
+std::string CopyLabel(StringView label) {
+    if (label.data == nullptr) {
+        return {};
+    }
+    size_t length = label.length == WGPU_STRLEN ? std::strlen(label.data) : label.length;
+    return {label.data, length};
+}
+
 }  // namespace wgpu::binding
diff --git a/src/dawn/node/binding/Converter.h b/src/dawn/node/binding/Converter.h
index e9bea42..c33a68b 100644
--- a/src/dawn/node/binding/Converter.h
+++ b/src/dawn/node/binding/Converter.h
@@ -473,6 +473,8 @@
     std::vector<std::function<void()>> free_;
 };
 
+std::string CopyLabel(StringView label);
+
 }  // namespace wgpu::binding
 
 #endif  // SRC_DAWN_NODE_BINDING_CONVERTER_H_
diff --git a/src/dawn/node/binding/GPUBindGroup.cpp b/src/dawn/node/binding/GPUBindGroup.cpp
index 24e6b45..7f47df1 100644
--- a/src/dawn/node/binding/GPUBindGroup.cpp
+++ b/src/dawn/node/binding/GPUBindGroup.cpp
@@ -29,7 +29,7 @@
 
 #include <utility>
 
-#include "src/dawn/node/utils/Debug.h"
+#include "src/dawn/node/binding/Converter.h"
 
 namespace wgpu::binding {
 
@@ -37,14 +37,14 @@
 // wgpu::bindings::GPUBindGroup
 ////////////////////////////////////////////////////////////////////////////////
 GPUBindGroup::GPUBindGroup(const wgpu::BindGroupDescriptor& desc, wgpu::BindGroup group)
-    : group_(std::move(group)), label_(desc.label ? desc.label : "") {}
+    : group_(std::move(group)), label_(CopyLabel(desc.label)) {}
 
 std::string GPUBindGroup::getLabel(Napi::Env) {
     return label_;
 }
 
 void GPUBindGroup::setLabel(Napi::Env, std::string value) {
-    group_.SetLabel(value.c_str());
+    group_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUBindGroupLayout.cpp b/src/dawn/node/binding/GPUBindGroupLayout.cpp
index e1c5e23..0d0b6f5 100644
--- a/src/dawn/node/binding/GPUBindGroupLayout.cpp
+++ b/src/dawn/node/binding/GPUBindGroupLayout.cpp
@@ -29,7 +29,7 @@
 
 #include <utility>
 
-#include "src/dawn/node/utils/Debug.h"
+#include "src/dawn/node/binding/Converter.h"
 
 namespace wgpu::binding {
 
@@ -38,14 +38,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 GPUBindGroupLayout::GPUBindGroupLayout(const wgpu::BindGroupLayoutDescriptor& desc,
                                        wgpu::BindGroupLayout layout)
-    : layout_(std::move(layout)), label_(desc.label ? desc.label : "") {}
+    : layout_(std::move(layout)), label_(CopyLabel(desc.label)) {}
 
 std::string GPUBindGroupLayout::getLabel(Napi::Env) {
     return label_;
 }
 
 void GPUBindGroupLayout::setLabel(Napi::Env, std::string value) {
-    layout_.SetLabel(value.c_str());
+    layout_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUBuffer.cpp b/src/dawn/node/binding/GPUBuffer.cpp
index ec598b8..818f91f 100644
--- a/src/dawn/node/binding/GPUBuffer.cpp
+++ b/src/dawn/node/binding/GPUBuffer.cpp
@@ -33,7 +33,6 @@
 
 #include "src/dawn/node/binding/Converter.h"
 #include "src/dawn/node/binding/Errors.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -49,7 +48,7 @@
       device_(std::move(device)),
       async_(std::move(async)),
       mapped_(desc.mappedAtCreation),
-      label_(desc.label ? desc.label : "") {}
+      label_(CopyLabel(desc.label)) {}
 
 interop::Promise<void> GPUBuffer::mapAsync(Napi::Env env,
                                            interop::GPUMapModeFlags modeIn,
@@ -195,7 +194,7 @@
 }
 
 void GPUBuffer::setLabel(Napi::Env, std::string value) {
-    buffer_.SetLabel(value.c_str());
+    buffer_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUCommandBuffer.cpp b/src/dawn/node/binding/GPUCommandBuffer.cpp
index 7199249..6673b5d6 100644
--- a/src/dawn/node/binding/GPUCommandBuffer.cpp
+++ b/src/dawn/node/binding/GPUCommandBuffer.cpp
@@ -29,7 +29,7 @@
 
 #include <utility>
 
-#include "src/dawn/node/utils/Debug.h"
+#include "src/dawn/node/binding/Converter.h"
 
 namespace wgpu::binding {
 
@@ -39,14 +39,14 @@
 
 GPUCommandBuffer::GPUCommandBuffer(const wgpu::CommandBufferDescriptor& desc,
                                    wgpu::CommandBuffer cmd_buf)
-    : cmd_buf_(std::move(cmd_buf)), label_(desc.label ? desc.label : "") {}
+    : cmd_buf_(std::move(cmd_buf)), label_(CopyLabel(desc.label)) {}
 
 std::string GPUCommandBuffer::getLabel(Napi::Env) {
     return label_;
 }
 
 void GPUCommandBuffer::setLabel(Napi::Env, std::string value) {
-    cmd_buf_.SetLabel(value.c_str());
+    cmd_buf_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUCommandEncoder.cpp b/src/dawn/node/binding/GPUCommandEncoder.cpp
index 90dd4cd..06b82c5 100644
--- a/src/dawn/node/binding/GPUCommandEncoder.cpp
+++ b/src/dawn/node/binding/GPUCommandEncoder.cpp
@@ -37,7 +37,6 @@
 #include "src/dawn/node/binding/GPUQuerySet.h"
 #include "src/dawn/node/binding/GPURenderPassEncoder.h"
 #include "src/dawn/node/binding/GPUTexture.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -47,7 +46,7 @@
 GPUCommandEncoder::GPUCommandEncoder(wgpu::Device device,
                                      const wgpu::CommandEncoderDescriptor& desc,
                                      wgpu::CommandEncoder enc)
-    : device_(std::move(device)), enc_(std::move(enc)), label_(desc.label ? desc.label : "") {}
+    : device_(std::move(device)), enc_(std::move(enc)), label_(CopyLabel(desc.label)) {}
 
 interop::Interface<interop::GPURenderPassEncoder> GPUCommandEncoder::beginRenderPass(
     Napi::Env env,
@@ -235,7 +234,7 @@
 }
 
 void GPUCommandEncoder::setLabel(Napi::Env, std::string value) {
-    enc_.SetLabel(value.c_str());
+    enc_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUComputePassEncoder.cpp b/src/dawn/node/binding/GPUComputePassEncoder.cpp
index 3b8eb7c..fc3526c 100644
--- a/src/dawn/node/binding/GPUComputePassEncoder.cpp
+++ b/src/dawn/node/binding/GPUComputePassEncoder.cpp
@@ -34,7 +34,6 @@
 #include "src/dawn/node/binding/GPUBuffer.h"
 #include "src/dawn/node/binding/GPUComputePipeline.h"
 #include "src/dawn/node/binding/GPUQuerySet.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -43,7 +42,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 GPUComputePassEncoder::GPUComputePassEncoder(const wgpu::ComputePassDescriptor& desc,
                                              wgpu::ComputePassEncoder enc)
-    : enc_(std::move(enc)), label_(desc.label ? desc.label : "") {}
+    : enc_(std::move(enc)), label_(CopyLabel(desc.label)) {}
 
 void GPUComputePassEncoder::setPipeline(Napi::Env,
                                         interop::Interface<interop::GPUComputePipeline> pipeline) {
@@ -134,7 +133,7 @@
 }
 
 void GPUComputePassEncoder::setLabel(Napi::Env, std::string value) {
-    enc_.SetLabel(value.c_str());
+    enc_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUComputePipeline.cpp b/src/dawn/node/binding/GPUComputePipeline.cpp
index 5118d40..f96bead 100644
--- a/src/dawn/node/binding/GPUComputePipeline.cpp
+++ b/src/dawn/node/binding/GPUComputePipeline.cpp
@@ -29,9 +29,9 @@
 
 #include <utility>
 
+#include "src/dawn/node/binding/Converter.h"
 #include "src/dawn/node/binding/GPUBindGroupLayout.h"
 #include "src/dawn/node/binding/GPUBuffer.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -40,7 +40,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 GPUComputePipeline::GPUComputePipeline(const wgpu::ComputePipelineDescriptor& desc,
                                        wgpu::ComputePipeline pipeline)
-    : pipeline_(std::move(pipeline)), label_(desc.label ? desc.label : "") {}
+    : pipeline_(std::move(pipeline)), label_(CopyLabel(desc.label)) {}
 
 GPUComputePipeline::GPUComputePipeline(wgpu::ComputePipeline pipeline, std::string label)
     : pipeline_(std::move(pipeline)), label_(label) {}
@@ -58,7 +58,7 @@
 }
 
 void GPUComputePipeline::setLabel(Napi::Env, std::string value) {
-    pipeline_.SetLabel(value.c_str());
+    pipeline_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUDevice.cpp b/src/dawn/node/binding/GPUDevice.cpp
index 55591b2..98ce43e 100644
--- a/src/dawn/node/binding/GPUDevice.cpp
+++ b/src/dawn/node/binding/GPUDevice.cpp
@@ -143,7 +143,7 @@
       device_(device),
       async_(async),
       lost_promise_(lost_promise),
-      label_(desc.label ? desc.label : "") {
+      label_(CopyLabel(desc.label)) {
     device_.SetLoggingCallback(
         [](WGPULoggingType type, char const* message, void* userdata) {
             printf("%s:\n", str(type));
@@ -411,7 +411,7 @@
 
     device_.CreateComputePipelineAsync(
         &desc, wgpu::CallbackMode::AllowProcessEvents,
-        [ctx = std::move(ctx), label = std::string(desc.label ? desc.label : "")](
+        [ctx = std::move(ctx), label = CopyLabel(desc.label)](
             wgpu::CreatePipelineAsyncStatus status, wgpu::ComputePipeline pipeline, char const*) {
             switch (status) {
                 case wgpu::CreatePipelineAsyncStatus::Success:
@@ -443,7 +443,7 @@
 
     device_.CreateRenderPipelineAsync(
         &desc, wgpu::CallbackMode::AllowProcessEvents,
-        [ctx = std::move(ctx), label = std::string(desc.label ? desc.label : "")](
+        [ctx = std::move(ctx), label = CopyLabel(desc.label)](
             wgpu::CreatePipelineAsyncStatus status, wgpu::RenderPipeline pipeline, char const*) {
             switch (status) {
                 case wgpu::CreatePipelineAsyncStatus::Success:
@@ -582,7 +582,7 @@
 }
 
 void GPUDevice::setLabel(Napi::Env, std::string value) {
-    device_.SetLabel(value.c_str());
+    device_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUPipelineLayout.cpp b/src/dawn/node/binding/GPUPipelineLayout.cpp
index b22e6c8..4a41de0 100644
--- a/src/dawn/node/binding/GPUPipelineLayout.cpp
+++ b/src/dawn/node/binding/GPUPipelineLayout.cpp
@@ -29,7 +29,7 @@
 
 #include <utility>
 
-#include "src/dawn/node/utils/Debug.h"
+#include "src/dawn/node/binding/Converter.h"
 
 namespace wgpu::binding {
 
@@ -38,14 +38,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 GPUPipelineLayout::GPUPipelineLayout(const wgpu::PipelineLayoutDescriptor& desc,
                                      wgpu::PipelineLayout layout)
-    : layout_(std::move(layout)), label_(desc.label ? desc.label : "") {}
+    : layout_(std::move(layout)), label_(CopyLabel(desc.label)) {}
 
 std::string GPUPipelineLayout::getLabel(Napi::Env) {
     return label_;
 }
 
 void GPUPipelineLayout::setLabel(Napi::Env, std::string value) {
-    layout_.SetLabel(value.c_str());
+    layout_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUQuerySet.cpp b/src/dawn/node/binding/GPUQuerySet.cpp
index b819d97..d0c5153 100644
--- a/src/dawn/node/binding/GPUQuerySet.cpp
+++ b/src/dawn/node/binding/GPUQuerySet.cpp
@@ -30,7 +30,6 @@
 #include <utility>
 
 #include "src/dawn/node/binding/Converter.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -38,7 +37,7 @@
 // wgpu::bindings::GPUQuerySet
 ////////////////////////////////////////////////////////////////////////////////
 GPUQuerySet::GPUQuerySet(const wgpu::QuerySetDescriptor& desc, wgpu::QuerySet query_set)
-    : query_set_(std::move(query_set)), label_(desc.label ? desc.label : "") {}
+    : query_set_(std::move(query_set)), label_(CopyLabel(desc.label)) {}
 
 void GPUQuerySet::destroy(Napi::Env) {
     query_set_.Destroy();
@@ -66,7 +65,7 @@
 }
 
 void GPUQuerySet::setLabel(Napi::Env, std::string value) {
-    query_set_.SetLabel(value.c_str());
+    query_set_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPURenderBundle.cpp b/src/dawn/node/binding/GPURenderBundle.cpp
index e2e93aa..b44f8d6 100644
--- a/src/dawn/node/binding/GPURenderBundle.cpp
+++ b/src/dawn/node/binding/GPURenderBundle.cpp
@@ -32,7 +32,6 @@
 #include "src/dawn/node/binding/Converter.h"
 #include "src/dawn/node/binding/GPUBuffer.h"
 #include "src/dawn/node/binding/GPURenderPipeline.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -41,14 +40,14 @@
 ////////////////////////////////////////////////////////////////////////////////
 GPURenderBundle::GPURenderBundle(const wgpu::RenderBundleDescriptor& desc,
                                  wgpu::RenderBundle bundle)
-    : bundle_(std::move(bundle)), label_(desc.label ? desc.label : "") {}
+    : bundle_(std::move(bundle)), label_(CopyLabel(desc.label)) {}
 
 std::string GPURenderBundle::getLabel(Napi::Env) {
     return label_;
 }
 
 void GPURenderBundle::setLabel(Napi::Env, std::string value) {
-    bundle_.SetLabel(value.c_str());
+    bundle_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPURenderBundleEncoder.cpp b/src/dawn/node/binding/GPURenderBundleEncoder.cpp
index c42bcb7..50e0a96 100644
--- a/src/dawn/node/binding/GPURenderBundleEncoder.cpp
+++ b/src/dawn/node/binding/GPURenderBundleEncoder.cpp
@@ -34,7 +34,6 @@
 #include "src/dawn/node/binding/GPUBuffer.h"
 #include "src/dawn/node/binding/GPURenderBundle.h"
 #include "src/dawn/node/binding/GPURenderPipeline.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -43,7 +42,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 GPURenderBundleEncoder::GPURenderBundleEncoder(const RenderBundleEncoderDescriptor& desc,
                                                wgpu::RenderBundleEncoder enc)
-    : enc_(std::move(enc)), label_(desc.label ? desc.label : "") {}
+    : enc_(std::move(enc)), label_(CopyLabel(desc.label)) {}
 
 interop::Interface<interop::GPURenderBundle> GPURenderBundleEncoder::finish(
     Napi::Env env,
@@ -206,7 +205,7 @@
 }
 
 void GPURenderBundleEncoder::setLabel(Napi::Env, std::string value) {
-    enc_.SetLabel(value.c_str());
+    enc_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPURenderPassEncoder.cpp b/src/dawn/node/binding/GPURenderPassEncoder.cpp
index a3f0f18..4d24862 100644
--- a/src/dawn/node/binding/GPURenderPassEncoder.cpp
+++ b/src/dawn/node/binding/GPURenderPassEncoder.cpp
@@ -35,7 +35,6 @@
 #include "src/dawn/node/binding/GPUQuerySet.h"
 #include "src/dawn/node/binding/GPURenderBundle.h"
 #include "src/dawn/node/binding/GPURenderPipeline.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -44,7 +43,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 GPURenderPassEncoder::GPURenderPassEncoder(const wgpu::RenderPassDescriptor& desc,
                                            wgpu::RenderPassEncoder enc)
-    : enc_(std::move(enc)), label_(desc.label ? desc.label : "") {}
+    : enc_(std::move(enc)), label_(CopyLabel(desc.label)) {}
 
 void GPURenderPassEncoder::setViewport(Napi::Env,
                                        float x,
@@ -311,7 +310,7 @@
 }
 
 void GPURenderPassEncoder::setLabel(Napi::Env, std::string value) {
-    enc_.SetLabel(value.c_str());
+    enc_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPURenderPipeline.cpp b/src/dawn/node/binding/GPURenderPipeline.cpp
index 3f7f408..6f4713e 100644
--- a/src/dawn/node/binding/GPURenderPipeline.cpp
+++ b/src/dawn/node/binding/GPURenderPipeline.cpp
@@ -29,9 +29,9 @@
 
 #include <utility>
 
+#include "src/dawn/node/binding/Converter.h"
 #include "src/dawn/node/binding/GPUBindGroupLayout.h"
 #include "src/dawn/node/binding/GPUBuffer.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -40,7 +40,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 GPURenderPipeline::GPURenderPipeline(const wgpu::RenderPipelineDescriptor& desc,
                                      wgpu::RenderPipeline pipeline)
-    : pipeline_(std::move(pipeline)), label_(desc.label ? desc.label : "") {}
+    : pipeline_(std::move(pipeline)), label_(CopyLabel(desc.label)) {}
 
 GPURenderPipeline::GPURenderPipeline(wgpu::RenderPipeline pipeline, std::string label)
     : pipeline_(std::move(pipeline)), label_(label) {}
@@ -58,7 +58,7 @@
 }
 
 void GPURenderPipeline::setLabel(Napi::Env, std::string value) {
-    pipeline_.SetLabel(value.c_str());
+    pipeline_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUSampler.cpp b/src/dawn/node/binding/GPUSampler.cpp
index 487eab3..1a1b2f3 100644
--- a/src/dawn/node/binding/GPUSampler.cpp
+++ b/src/dawn/node/binding/GPUSampler.cpp
@@ -30,7 +30,6 @@
 #include <utility>
 
 #include "src/dawn/node/binding/Converter.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -38,14 +37,14 @@
 // wgpu::bindings::GPUSampler
 ////////////////////////////////////////////////////////////////////////////////
 GPUSampler::GPUSampler(const wgpu::SamplerDescriptor& desc, wgpu::Sampler sampler)
-    : sampler_(std::move(sampler)), label_(desc.label ? desc.label : "") {}
+    : sampler_(std::move(sampler)), label_(CopyLabel(desc.label)) {}
 
 std::string GPUSampler::getLabel(Napi::Env) {
     return label_;
 }
 
 void GPUSampler::setLabel(Napi::Env, std::string value) {
-    sampler_.SetLabel(value.c_str());
+    sampler_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUShaderModule.cpp b/src/dawn/node/binding/GPUShaderModule.cpp
index 94a3bb9..44cf937 100644
--- a/src/dawn/node/binding/GPUShaderModule.cpp
+++ b/src/dawn/node/binding/GPUShaderModule.cpp
@@ -31,7 +31,7 @@
 #include <utility>
 #include <vector>
 
-#include "src/dawn/node/utils/Debug.h"
+#include "src/dawn/node/binding/Converter.h"
 
 namespace wgpu::binding {
 
@@ -41,7 +41,7 @@
 GPUShaderModule::GPUShaderModule(const wgpu::ShaderModuleDescriptor& desc,
                                  wgpu::ShaderModule shader,
                                  std::shared_ptr<AsyncRunner> async)
-    : shader_(std::move(shader)), async_(std::move(async)), label_(desc.label ? desc.label : "") {}
+    : shader_(std::move(shader)), async_(std::move(async)), label_(CopyLabel(desc.label)) {}
 
 interop::Promise<interop::Interface<interop::GPUCompilationInfo>>
 GPUShaderModule::getCompilationInfo(Napi::Env env) {
@@ -116,7 +116,7 @@
 }
 
 void GPUShaderModule::setLabel(Napi::Env, std::string value) {
-    shader_.SetLabel(value.c_str());
+    shader_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUTexture.cpp b/src/dawn/node/binding/GPUTexture.cpp
index d2668f8..e40ac93 100644
--- a/src/dawn/node/binding/GPUTexture.cpp
+++ b/src/dawn/node/binding/GPUTexture.cpp
@@ -32,7 +32,6 @@
 #include "src/dawn/node/binding/Converter.h"
 #include "src/dawn/node/binding/Errors.h"
 #include "src/dawn/node/binding/GPUTextureView.h"
-#include "src/dawn/node/utils/Debug.h"
 
 namespace wgpu::binding {
 
@@ -42,9 +41,7 @@
 GPUTexture::GPUTexture(wgpu::Device device,
                        const wgpu::TextureDescriptor& desc,
                        wgpu::Texture texture)
-    : device_(std::move(device)),
-      texture_(std::move(texture)),
-      label_(desc.label ? desc.label : "") {}
+    : device_(std::move(device)), texture_(std::move(texture)), label_(CopyLabel(desc.label)) {}
 
 interop::Interface<interop::GPUTextureView> GPUTexture::createView(
     Napi::Env env,
@@ -136,7 +133,7 @@
 }
 
 void GPUTexture::setLabel(Napi::Env, std::string value) {
-    texture_.SetLabel(value.c_str());
+    texture_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/node/binding/GPUTextureView.cpp b/src/dawn/node/binding/GPUTextureView.cpp
index d767a66..bb47ba6 100644
--- a/src/dawn/node/binding/GPUTextureView.cpp
+++ b/src/dawn/node/binding/GPUTextureView.cpp
@@ -29,7 +29,7 @@
 
 #include <utility>
 
-#include "src/dawn/node/utils/Debug.h"
+#include "src/dawn/node/binding/Converter.h"
 
 namespace wgpu::binding {
 
@@ -37,14 +37,14 @@
 // wgpu::bindings::GPUTextureView
 ////////////////////////////////////////////////////////////////////////////////
 GPUTextureView::GPUTextureView(const wgpu::TextureViewDescriptor& desc, wgpu::TextureView view)
-    : view_(std::move(view)), label_(desc.label ? desc.label : "") {}
+    : view_(std::move(view)), label_(CopyLabel(desc.label)) {}
 
 std::string GPUTextureView::getLabel(Napi::Env) {
     return label_;
 }
 
 void GPUTextureView::setLabel(Napi::Env, std::string value) {
-    view_.SetLabel(value.c_str());
+    view_.SetLabel(std::string_view(value));
     label_ = value;
 }
 
diff --git a/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp b/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp
index 23ba064..55244d5 100644
--- a/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp
+++ b/src/dawn/tests/unittests/validation/CommandBufferValidationTests.cpp
@@ -349,7 +349,7 @@
     ASSERT_DEVICE_ERROR(encoder.Finish(), HasSubstr(sv));
 }
 
-// Test that calling inject validation error with various wgpu::NullableStringView produces
+// Test that calling inject validation error with various wgpu::StringView produces
 // an error which preserves the string.
 TEST_F(CommandBufferValidationTest, InjectedValidateErrorVariousStringTypes) {
     // Use strlen
diff --git a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
index c201d00..6a182ac 100644
--- a/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireAdapterTests.cpp
@@ -74,7 +74,7 @@
 
     EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
         .WillOnce(WithArg<1>(Invoke([&](const WGPUDeviceDescriptor* apiDesc) {
-            EXPECT_EQ(apiDesc->label, nullptr);
+            EXPECT_EQ(apiDesc->label.data, nullptr);
             EXPECT_EQ(apiDesc->requiredFeatureCount, 0u);
             EXPECT_EQ(apiDesc->requiredLimits, nullptr);
 
@@ -97,7 +97,7 @@
 
     EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
         .WillOnce(WithArg<1>(Invoke([&](const WGPUDeviceDescriptor* apiDesc) {
-            EXPECT_EQ(apiDesc->label, nullptr);
+            EXPECT_EQ(apiDesc->label.data, nullptr);
             EXPECT_EQ(apiDesc->requiredFeatureCount, 0u);
             EXPECT_EQ(apiDesc->requiredLimits, nullptr);
 
@@ -128,7 +128,7 @@
 
     EXPECT_CALL(api, OnAdapterRequestDevice(apiAdapter, NotNull(), _))
         .WillOnce(WithArg<1>(Invoke([&](const WGPUDeviceDescriptor* apiDesc) {
-            EXPECT_STREQ(apiDesc->label, desc.label);
+            EXPECT_STREQ(apiDesc->label.data, desc.label.data);
 
             // The callback should not be passed through to the server, and it should be overridden.
             WGPUDeviceDescriptor& inputDesc = *reinterpret_cast<WGPUDeviceDescriptor*>(&desc);
diff --git a/src/dawn/tests/unittests/wire/WireExtensionTests.cpp b/src/dawn/tests/unittests/wire/WireExtensionTests.cpp
index 4755f15..f5f2717 100644
--- a/src/dawn/tests/unittests/wire/WireExtensionTests.cpp
+++ b/src/dawn/tests/unittests/wire/WireExtensionTests.cpp
@@ -57,7 +57,9 @@
                 const auto* ext =
                     reinterpret_cast<const WGPUShaderSourceWGSL*>(serverDesc->nextInChain);
                 EXPECT_EQ(ext->chain.sType, WGPUSType_ShaderSourceWGSL);
-                EXPECT_STREQ(ext->code.data, clientExt.code.data);
+                EXPECT_NE(ext->code.length, WGPU_STRLEN) << "The wire should decay WGPU_STRLEN";
+                EXPECT_EQ(0, memcmp(ext->code.data, clientExt.code.data, ext->code.length));
+                EXPECT_EQ(ext->code.length, strlen(clientExt.code.data));
                 EXPECT_EQ(ext->chain.next, nullptr);
 
                 return apiShaderModule;
@@ -85,11 +87,15 @@
                 const auto* ext1 =
                     reinterpret_cast<const WGPUShaderSourceWGSL*>(serverDesc->nextInChain);
                 EXPECT_EQ(ext1->chain.sType, WGPUSType_ShaderSourceWGSL);
-                EXPECT_STREQ(ext1->code.data, clientExt1.code.data);
+                EXPECT_NE(ext1->code.length, WGPU_STRLEN) << "The wire should decay WGPU_STRLEN";
+                EXPECT_EQ(0, memcmp(ext1->code.data, clientExt1.code.data, ext1->code.length));
+                EXPECT_EQ(ext1->code.length, strlen(clientExt1.code.data));
 
                 const auto* ext2 = reinterpret_cast<const WGPUShaderSourceWGSL*>(ext1->chain.next);
                 EXPECT_EQ(ext2->chain.sType, WGPUSType_ShaderSourceWGSL);
-                EXPECT_STREQ(ext2->code.data, clientExt2.code.data);
+                EXPECT_NE(ext2->code.length, WGPU_STRLEN) << "The wire should decay WGPU_STRLEN";
+                EXPECT_EQ(0, memcmp(ext2->code.data, clientExt2.code.data, ext2->code.length));
+                EXPECT_EQ(ext2->code.length, strlen(clientExt2.code.data));
                 EXPECT_EQ(ext2->chain.next, nullptr);
 
                 return apiShaderModule;
@@ -108,11 +114,15 @@
                 const auto* ext2 =
                     reinterpret_cast<const WGPUShaderSourceWGSL*>(serverDesc->nextInChain);
                 EXPECT_EQ(ext2->chain.sType, WGPUSType_ShaderSourceWGSL);
-                EXPECT_STREQ(ext2->code.data, clientExt2.code.data);
+                EXPECT_NE(ext2->code.length, WGPU_STRLEN) << "The wire should decay WGPU_STRLEN";
+                EXPECT_EQ(0, memcmp(ext2->code.data, clientExt2.code.data, ext2->code.length));
+                EXPECT_EQ(ext2->code.length, strlen(clientExt2.code.data));
 
                 const auto* ext1 = reinterpret_cast<const WGPUShaderSourceWGSL*>(ext2->chain.next);
                 EXPECT_EQ(ext1->chain.sType, WGPUSType_ShaderSourceWGSL);
-                EXPECT_STREQ(ext1->code.data, clientExt1.code.data);
+                EXPECT_NE(ext1->code.length, WGPU_STRLEN) << "The wire should decay WGPU_STRLEN";
+                EXPECT_EQ(0, memcmp(ext1->code.data, clientExt1.code.data, ext1->code.length));
+                EXPECT_EQ(ext1->code.length, strlen(clientExt1.code.data));
                 EXPECT_EQ(ext1->chain.next, nullptr);
 
                 return apiShaderModule;
@@ -183,7 +193,9 @@
                 const auto* ext =
                     reinterpret_cast<const WGPUShaderSourceWGSL*>(serverDesc->nextInChain);
                 EXPECT_EQ(ext->chain.sType, clientExt1.chain.sType);
-                EXPECT_STREQ(ext->code.data, clientExt1.code.data);
+                EXPECT_NE(ext->code.length, WGPU_STRLEN) << "The wire should decay WGPU_STRLEN";
+                EXPECT_EQ(0, memcmp(ext->code.data, clientExt1.code.data, ext->code.length));
+                EXPECT_EQ(ext->code.length, strlen(clientExt1.code.data));
 
                 EXPECT_EQ(ext->chain.next->sType, WGPUSType(0));
                 EXPECT_EQ(ext->chain.next->next, nullptr);
@@ -206,7 +218,9 @@
                 const auto* ext =
                     reinterpret_cast<const WGPUShaderSourceWGSL*>(serverDesc->nextInChain->next);
                 EXPECT_EQ(ext->chain.sType, clientExt1.chain.sType);
-                EXPECT_STREQ(ext->code.data, clientExt1.code.data);
+                EXPECT_NE(ext->code.length, WGPU_STRLEN) << "The wire should decay WGPU_STRLEN";
+                EXPECT_EQ(0, memcmp(ext->code.data, clientExt1.code.data, ext->code.length));
+                EXPECT_EQ(ext->code.length, strlen(clientExt1.code.data));
                 EXPECT_EQ(ext->chain.next, nullptr);
 
                 return apiShaderModule;