[typedarray] Change JSTypedArray::length field to uintptr_t.

This is a mostly mechanical change that updates the JSTypedArray::length
field to have uintptr_t storage. It doesn't change the allowed ranges
for this field yet, that will be done separately later on.

Bug: v8:4153, v8:7881
Change-Id: Ia4b6f5455bd97b82a4b980d77bda0b09cfa845f5
Doc: http://doc/1Z-wM2qwvAuxH46e9ivtkYvKzzwYZg8ymm0x0wJaomow
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1607647
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61485}
diff --git a/src/builtins/array-join.tq b/src/builtins/array-join.tq
index 8c53114..bc12393 100644
--- a/src/builtins/array-join.tq
+++ b/src/builtins/array-join.tq
@@ -624,7 +624,7 @@
     // the algorithm.
     const typedArray: JSTypedArray = typed_array::ValidateTypedArray(
         context, receiver, '%TypedArray%.prototype.join');
-    const length: Smi = typedArray.length;
+    const length = Convert<Number>(typedArray.length);
 
     return CycleProtectedArrayJoin<JSTypedArray>(
         false, typedArray, length, separator, Undefined, Undefined);
@@ -640,7 +640,7 @@
     // the algorithm.
     const typedArray: JSTypedArray = typed_array::ValidateTypedArray(
         context, receiver, '%TypedArray%.prototype.toLocaleString');
-    const length: Smi = typedArray.length;
+    const length = Convert<Number>(typedArray.length);
 
     return CycleProtectedArrayJoin<JSTypedArray>(
         true, typedArray, length, ',', locales, options);
diff --git a/src/builtins/base.tq b/src/builtins/base.tq
index 936eb88..b65d9a7 100644
--- a/src/builtins/base.tq
+++ b/src/builtins/base.tq
@@ -526,7 +526,7 @@
     };
   }
 
-  length: Smi;
+  length: uintptr;
 }
 
 @noVerifier
diff --git a/src/builtins/builtins-array-gen.cc b/src/builtins/builtins-array-gen.cc
index 0ad58b9..ba213ae6 100644
--- a/src/builtins/builtins-array-gen.cc
+++ b/src/builtins/builtins-array-gen.cc
@@ -42,7 +42,8 @@
         context(), method_name, original_array, length);
     // In the Spec and our current implementation, the length check is already
     // performed in TypedArraySpeciesCreate.
-    CSA_ASSERT(this, SmiLessThanOrEqual(CAST(len_), LoadJSTypedArrayLength(a)));
+    CSA_ASSERT(this, UintPtrLessThanOrEqual(SmiUntag(CAST(len_)),
+                                            LoadJSTypedArrayLength(a)));
     fast_typed_array_target_ =
         Word32Equal(LoadInstanceType(LoadElements(original_array)),
                     LoadInstanceType(LoadElements(a)));
@@ -159,7 +160,7 @@
         LoadJSArrayBufferViewBuffer(typed_array);
     ThrowIfArrayBufferIsDetached(context_, array_buffer, name_);
 
-    len_ = LoadJSTypedArrayLength(typed_array);
+    len_ = ChangeUintPtrToTagged(LoadJSTypedArrayLength(typed_array));
 
     Label throw_not_callable(this, Label::kDeferred);
     Label distinguish_types(this);
@@ -1641,6 +1642,7 @@
   BIND(&if_typedarray);
   {
     // If {array} is a JSTypedArray, the {index} must always be a Smi.
+    // TODO(v8:4153): Update this and the relevant TurboFan code.
     CSA_ASSERT(this, TaggedIsSmi(index));
 
     // Check that the {array}s buffer wasn't detached.
@@ -1650,8 +1652,9 @@
     // [[ArrayIteratorNextIndex]] anymore, since a JSTypedArray's
     // length cannot change anymore, so this {iterator} will never
     // produce values again anyways.
-    TNode<Smi> length = LoadJSTypedArrayLength(CAST(array));
-    GotoIfNot(SmiBelow(CAST(index), length), &allocate_iterator_result);
+    TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(array));
+    GotoIfNot(UintPtrLessThan(SmiUntag(CAST(index)), length),
+              &allocate_iterator_result);
     StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset,
                                    SmiInc(CAST(index)));
 
diff --git a/src/builtins/builtins-sharedarraybuffer-gen.cc b/src/builtins/builtins-sharedarraybuffer-gen.cc
index d92e988..0c7aad4 100644
--- a/src/builtins/builtins-sharedarraybuffer-gen.cc
+++ b/src/builtins/builtins-sharedarraybuffer-gen.cc
@@ -116,13 +116,14 @@
 }
 
 void SharedArrayBufferBuiltinsAssembler::ValidateAtomicIndex(Node* array,
-                                                             Node* index_word,
+                                                             Node* index,
                                                              Node* context) {
   // Check if the index is in bounds. If not, throw RangeError.
   Label check_passed(this);
-  Node* array_length_word32 =
-      TruncateTaggedToWord32(context, LoadJSTypedArrayLength(CAST(array)));
-  GotoIf(Uint32LessThan(index_word, array_length_word32), &check_passed);
+  TNode<UintPtrT> array_length = LoadJSTypedArrayLength(CAST(array));
+  // TODO(v8:4153): Use UintPtr for the {index} as well.
+  GotoIf(UintPtrLessThan(ChangeUint32ToWord(index), array_length),
+         &check_passed);
 
   ThrowRangeError(context, MessageTemplate::kInvalidAtomicAccessIndex);
 
@@ -136,10 +137,8 @@
   // ToInteger above calls out to JavaScript. A SharedArrayBuffer can't be
   // detached and the TypedArray length can't change either, so skipping this
   // check in Release mode is safe.
-  CSA_ASSERT(this,
-             Uint32LessThan(index_word,
-                            TruncateTaggedToWord32(
-                                context, LoadJSTypedArrayLength(CAST(array)))));
+  CSA_ASSERT(this, UintPtrLessThan(ChangeUint32ToWord(index_word),
+                                   LoadJSTypedArrayLength(CAST(array))));
 }
 #endif
 
diff --git a/src/builtins/builtins-typed-array-gen.cc b/src/builtins/builtins-typed-array-gen.cc
index 1206785..cb518e1 100644
--- a/src/builtins/builtins-typed-array-gen.cc
+++ b/src/builtins/builtins-typed-array-gen.cc
@@ -51,11 +51,11 @@
 //  - Set the byte_length.
 //  - Set EmbedderFields to 0.
 void TypedArrayBuiltinsAssembler::SetupTypedArray(TNode<JSTypedArray> holder,
-                                                  TNode<Smi> length,
+                                                  TNode<UintPtrT> length,
                                                   TNode<UintPtrT> byte_offset,
                                                   TNode<UintPtrT> byte_length) {
-  CSA_ASSERT(this, TaggedIsPositiveSmi(length));
-  StoreObjectField(holder, JSTypedArray::kLengthOffset, length);
+  StoreObjectFieldNoWriteBarrier(holder, JSTypedArray::kLengthOffset, length,
+                                 MachineType::PointerRepresentation());
   StoreObjectFieldNoWriteBarrier(holder, JSArrayBufferView::kByteOffsetOffset,
                                  byte_offset,
                                  MachineType::PointerRepresentation());
@@ -238,10 +238,10 @@
   // Default to zero if the {receiver}s buffer was detached.
   TNode<JSArrayBuffer> receiver_buffer =
       LoadJSArrayBufferViewBuffer(CAST(receiver));
-  TNode<Smi> length = Select<Smi>(
-      IsDetachedBuffer(receiver_buffer), [=] { return SmiConstant(0); },
+  TNode<UintPtrT> length = Select<UintPtrT>(
+      IsDetachedBuffer(receiver_buffer), [=] { return UintPtrConstant(0); },
       [=] { return LoadJSTypedArrayLength(CAST(receiver)); });
-  Return(length);
+  Return(ChangeUintPtrToTagged(length));
 }
 
 TNode<Word32T> TypedArrayBuiltinsAssembler::IsUint8ElementsKind(
@@ -328,8 +328,9 @@
     TNode<Smi> min_length) {
   // If typed_array.[[ArrayLength]] < min_length, throw a TypeError exception.
   Label if_length_is_not_short(this);
-  TNode<Smi> new_length = LoadJSTypedArrayLength(typed_array);
-  GotoIfNot(SmiLessThan(new_length, min_length), &if_length_is_not_short);
+  TNode<UintPtrT> new_length = LoadJSTypedArrayLength(typed_array);
+  GotoIfNot(UintPtrLessThan(new_length, SmiUntag(min_length)),
+            &if_length_is_not_short);
   ThrowTypeError(context, MessageTemplate::kTypedArrayTooShort);
 
   BIND(&if_length_is_not_short);
@@ -383,8 +384,8 @@
 
   // Check for possible range errors.
 
-  TNode<IntPtrT> source_length = SmiUntag(LoadJSTypedArrayLength(source));
-  TNode<IntPtrT> target_length = SmiUntag(LoadJSTypedArrayLength(target));
+  TNode<IntPtrT> source_length = Signed(LoadJSTypedArrayLength(source));
+  TNode<IntPtrT> target_length = Signed(LoadJSTypedArrayLength(target));
   TNode<IntPtrT> required_target_length = IntPtrAdd(source_length, offset);
 
   GotoIf(IntPtrGreaterThan(required_target_length, target_length),
@@ -434,7 +435,7 @@
                           IsBigInt64ElementsKind(target_el_kind)),
            &exception);
 
-    TNode<IntPtrT> source_length = SmiUntag(LoadJSTypedArrayLength(source));
+    TNode<IntPtrT> source_length = Signed(LoadJSTypedArrayLength(source));
     CallCCopyTypedArrayElementsToTypedArray(source, target, source_length,
                                             offset);
     Goto(&out);
@@ -455,7 +456,7 @@
              IntPtrLessThanOrEqual(offset, IntPtrConstant(Smi::kMaxValue)));
 
   TNode<IntPtrT> source_length = SmiUntag(LoadFastJSArrayLength(source));
-  TNode<IntPtrT> target_length = SmiUntag(LoadJSTypedArrayLength(target));
+  TNode<IntPtrT> target_length = Signed(LoadJSTypedArrayLength(target));
 
   // Maybe out of bounds?
   GotoIf(IntPtrGreaterThan(IntPtrAdd(source_length, offset), target_length),
@@ -956,7 +957,8 @@
     // Source is a TypedArray with unmodified iterator behavior. Use the
     // source object directly, taking advantage of the special-case code in
     // TypedArrayCopyElements
-    final_length = LoadJSTypedArrayLength(CAST(source));
+    // TODO(v8:4153): This needs to be handle to huge TypedArrays.
+    final_length = SmiTag(Signed(LoadJSTypedArrayLength(CAST(source))));
     final_source = source;
     Goto(&create_typed_array);
   }
diff --git a/src/builtins/builtins-typed-array-gen.h b/src/builtins/builtins-typed-array-gen.h
index ab0ee60..57fba06 100644
--- a/src/builtins/builtins-typed-array-gen.h
+++ b/src/builtins/builtins-typed-array-gen.h
@@ -29,7 +29,7 @@
                                                   const char* method_name,
                                                   IterationKind iteration_kind);
 
-  void SetupTypedArray(TNode<JSTypedArray> holder, TNode<Smi> length,
+  void SetupTypedArray(TNode<JSTypedArray> holder, TNode<UintPtrT> length,
                        TNode<UintPtrT> byte_offset,
                        TNode<UintPtrT> byte_length);
   void AttachBuffer(TNode<JSTypedArray> holder, TNode<JSArrayBuffer> buffer,
diff --git a/src/builtins/typed-array-createtypedarray.tq b/src/builtins/typed-array-createtypedarray.tq
index 7943ae0..64eb7c6 100644
--- a/src/builtins/typed-array-createtypedarray.tq
+++ b/src/builtins/typed-array-createtypedarray.tq
@@ -19,7 +19,7 @@
   extern macro TypedArrayBuiltinsAssembler::IsSharedArrayBuffer(JSArrayBuffer):
       bool;
   extern macro TypedArrayBuiltinsAssembler::SetupTypedArray(
-      JSTypedArray, Smi, uintptr, uintptr): void;
+      JSTypedArray, uintptr, uintptr, uintptr): void;
 
   extern runtime ThrowInvalidTypedArrayAlignment(implicit context: Context)(
       Map, String): never;
@@ -77,7 +77,8 @@
     }
 
     const byteOffset: uintptr = 0;
-    SetupTypedArray(typedArray, length, byteOffset, byteLength);
+    SetupTypedArray(
+        typedArray, Convert<uintptr>(length), byteOffset, byteLength);
 
     return byteLength;
   }
@@ -156,7 +157,9 @@
     let bufferConstructor: JSReceiver = GetArrayBufferFunction();
     const srcBuffer: JSArrayBuffer = srcTypedArray.buffer;
     // TODO(petermarshall): Throw on detached typedArray.
-    let length: Smi = IsDetachedBuffer(srcBuffer) ? 0 : srcTypedArray.length;
+    // TODO(v8:4156): Update this to support huge TypedArrays.
+    let length =
+        IsDetachedBuffer(srcBuffer) ? 0 : Convert<Number>(srcTypedArray.length);
 
     // The spec requires that constructing a typed array using a SAB-backed
     // typed array use the ArrayBuffer constructor, not the species constructor.
@@ -235,7 +238,8 @@
           goto IfInvalidLength;
       }
 
-      SetupTypedArray(typedArray, newLength, offset, newByteLength);
+      SetupTypedArray(
+          typedArray, Convert<uintptr>(newLength), offset, newByteLength);
       typedArray.AttachOffHeapBuffer(buffer, elementsInfo.map, offset);
     }
     label IfInvalidAlignment(problemString: String) deferred {
@@ -291,6 +295,7 @@
     // the object even though that doesn't make any sense for these fields.
     array.byte_offset = 0;
     array.byte_length = 0;
+    array.length = 0;
 
     // 5. Let elementSize be the Number value of the Element Size value in Table
     // 56 for constructorName.
@@ -372,12 +377,11 @@
   transitioning macro TypedArraySpeciesCreateByLength(implicit context:
                                                           Context)(
       methodName: constexpr string, exemplar: JSTypedArray,
-      length: Smi): JSTypedArray {
-    assert(Is<PositiveSmi>(length));
+      length: PositiveSmi): JSTypedArray {
     const numArgs: constexpr int31 = 1;
     const typedArray: JSTypedArray = TypedArraySpeciesCreate(
         methodName, numArgs, exemplar, length, Undefined, Undefined);
-    if (typedArray.length < length) deferred {
+    if (typedArray.length < Convert<uintptr>(length)) deferred {
         ThrowTypeError(kTypedArrayTooShort);
       }
 
diff --git a/src/builtins/typed-array-every.tq b/src/builtins/typed-array-every.tq
index 85b4a77..4f88048 100644
--- a/src/builtins/typed-array-every.tq
+++ b/src/builtins/typed-array-every.tq
@@ -11,7 +11,9 @@
       array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
       thisArg: Object): Boolean {
     let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
-    const length: Smi = Convert<Smi>(witness.Get().length);
+    // TODO(v8:4153): Support huge TypedArrays here.
+    const length =
+        Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
     for (let k: Smi = 0; k < length; k++) {
       // BUG(4895): We should throw on detached buffers rather than simply exit.
       witness.Recheck() otherwise break;
diff --git a/src/builtins/typed-array-filter.tq b/src/builtins/typed-array-filter.tq
index d73f21e..9407c3a 100644
--- a/src/builtins/typed-array-filter.tq
+++ b/src/builtins/typed-array-filter.tq
@@ -21,7 +21,8 @@
       const src = typed_array::EnsureAttached(array) otherwise IsDetached;
 
       // 3. Let len be O.[[ArrayLength]].
-      const len: Smi = src.length;
+      // TODO(v8:4153): Support huge TypedArrays here.
+      const len = Cast<Smi>(Convert<Number>(src.length)) otherwise unreachable;
 
       // 4. If IsCallable(callbackfn) is false, throw a TypeError exception.
       const callbackfn = Cast<Callable>(arguments[0])
@@ -58,7 +59,7 @@
       }
 
       // 10. Let A be ? TypedArraySpeciesCreate(O, captured).
-      const lengthSmi: Smi = Convert<Smi>(kept.length);
+      const lengthSmi = Convert<PositiveSmi>(kept.length);
       const typedArray: JSTypedArray =
           typed_array_createtypedarray::TypedArraySpeciesCreateByLength(
               kBuiltinName, array, lengthSmi);
diff --git a/src/builtins/typed-array-find.tq b/src/builtins/typed-array-find.tq
index 19b0602..3c331eb 100644
--- a/src/builtins/typed-array-find.tq
+++ b/src/builtins/typed-array-find.tq
@@ -11,7 +11,9 @@
       array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
       thisArg: Object): Object {
     let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
-    const length: Smi = Convert<Smi>(witness.Get().length);
+    // TODO(v8:4153): Support huge TypedArrays here.
+    const length =
+        Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
     for (let k: Smi = 0; k < length; k++) {
       // BUG(4895): We should throw on detached buffers rather than simply exit.
       witness.Recheck() otherwise break;
diff --git a/src/builtins/typed-array-findindex.tq b/src/builtins/typed-array-findindex.tq
index fd77774..05f112d 100644
--- a/src/builtins/typed-array-findindex.tq
+++ b/src/builtins/typed-array-findindex.tq
@@ -11,7 +11,9 @@
       array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
       thisArg: Object): Number {
     let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
-    const length: Smi = Convert<Smi>(witness.Get().length);
+    // TODO(v8:4153): Support huge TypedArrays here.
+    const length =
+        Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
     for (let k: Smi = 0; k < length; k++) {
       // BUG(4895): We should throw on detached buffers rather than simply exit.
       witness.Recheck() otherwise break;
diff --git a/src/builtins/typed-array-foreach.tq b/src/builtins/typed-array-foreach.tq
index 49ed0a6..dbf1a12 100644
--- a/src/builtins/typed-array-foreach.tq
+++ b/src/builtins/typed-array-foreach.tq
@@ -11,7 +11,9 @@
       array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
       thisArg: Object): Object {
     let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
-    const length: Smi = Convert<Smi>(array.length);
+    // TODO(v8:4153): Support huge TypedArrays here.
+    const length =
+        Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
     for (let k: Smi = 0; k < length; k++) {
       // BUG(4895): We should throw on detached buffers rather than simply exit.
       witness.Recheck() otherwise break;
diff --git a/src/builtins/typed-array-reduce.tq b/src/builtins/typed-array-reduce.tq
index 232f2fc..7af918a 100644
--- a/src/builtins/typed-array-reduce.tq
+++ b/src/builtins/typed-array-reduce.tq
@@ -11,7 +11,9 @@
       array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
       initialValue: Object): Object {
     let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
-    const length: Smi = Convert<Smi>(witness.Get().length);
+    // TODO(v8:4153): Support huge TypedArrays here.
+    const length =
+        Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
     let accumulator = initialValue;
     for (let k: Smi = 0; k < length; k++) {
       // BUG(4895): We should throw on detached buffers rather than simply exit.
diff --git a/src/builtins/typed-array-reduceright.tq b/src/builtins/typed-array-reduceright.tq
index 3aa9511..59ce7ff 100644
--- a/src/builtins/typed-array-reduceright.tq
+++ b/src/builtins/typed-array-reduceright.tq
@@ -11,7 +11,9 @@
       array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
       initialValue: Object): Object {
     let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
-    const length: Smi = Convert<Smi>(array.length);
+    // TODO(v8:4153): Support huge TypedArrays here.
+    const length =
+        Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
     let accumulator = initialValue;
     for (let k: Smi = length - 1; k >= 0; k--) {
       // BUG(4895): We should throw on detached buffers rather than simply exit.
diff --git a/src/builtins/typed-array-some.tq b/src/builtins/typed-array-some.tq
index f56d63c..991cad6 100644
--- a/src/builtins/typed-array-some.tq
+++ b/src/builtins/typed-array-some.tq
@@ -11,7 +11,9 @@
       array: typed_array::AttachedJSTypedArray, callbackfn: Callable,
       thisArg: Object): Boolean {
     let witness = typed_array::NewAttachedJSTypedArrayWitness(array);
-    const length: Smi = Convert<Smi>(witness.Get().length);
+    // TODO(v8:4153): Support huge TypedArrays here.
+    const length =
+        Cast<Smi>(Convert<Number>(witness.Get().length)) otherwise unreachable;
     for (let k: Smi = 0; k < length; k++) {
       // BUG(4895): We should throw on detached buffers rather than simply exit.
       witness.Recheck() otherwise break;
diff --git a/src/builtins/typed-array.tq b/src/builtins/typed-array.tq
index d86b48d..b386621 100644
--- a/src/builtins/typed-array.tq
+++ b/src/builtins/typed-array.tq
@@ -298,7 +298,8 @@
     }
 
     // 4. Let len be obj.[[ArrayLength]].
-    const len: Smi = array.length;
+    // TODO(v8:4153): Support huge TypedArrays here.
+    const len = Cast<Smi>(Convert<Number>(array.length)) otherwise unreachable;
 
     // Arrays of length 1 or less are considered sorted.
     if (len < 2) return array;
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 47323dd..06228e6 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -9658,7 +9658,7 @@
     Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
     GotoIf(IsDetachedBuffer(buffer), if_absent);
 
-    Node* length = SmiUntag(LoadJSTypedArrayLength(CAST(object)));
+    TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(object));
     Branch(UintPtrLessThan(intptr_index, length), if_found, if_absent);
   }
   BIND(&if_oob);
@@ -10553,8 +10553,7 @@
     GotoIf(IsDetachedBuffer(buffer), bailout);
 
     // Bounds check.
-    Node* length =
-        TaggedToParameter(LoadJSTypedArrayLength(CAST(object)), parameter_mode);
+    TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(object));
 
     if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
       // Skip the store if we write beyond the length or
@@ -13165,9 +13164,9 @@
                                    JSArrayBufferView::kByteOffsetOffset);
 }
 
-TNode<Smi> CodeStubAssembler::LoadJSTypedArrayLength(
+TNode<UintPtrT> CodeStubAssembler::LoadJSTypedArrayLength(
     TNode<JSTypedArray> typed_array) {
-  return LoadObjectField<Smi>(typed_array, JSTypedArray::kLengthOffset);
+  return LoadObjectField<UintPtrT>(typed_array, JSTypedArray::kLengthOffset);
 }
 
 CodeStubArguments::CodeStubArguments(
diff --git a/src/code-stub-assembler.h b/src/code-stub-assembler.h
index cd00083..7509bf2 100644
--- a/src/code-stub-assembler.h
+++ b/src/code-stub-assembler.h
@@ -3238,7 +3238,7 @@
       const char* method_name);
 
   // JSTypedArray helpers
-  TNode<Smi> LoadJSTypedArrayLength(TNode<JSTypedArray> typed_array);
+  TNode<UintPtrT> LoadJSTypedArrayLength(TNode<JSTypedArray> typed_array);
 
   TNode<IntPtrT> ElementOffsetFromIndex(Node* index, ElementsKind kind,
                                         ParameterMode mode, int base_size = 0);
diff --git a/src/compiler/access-builder.cc b/src/compiler/access-builder.cc
index a6a241b..2e7a454 100644
--- a/src/compiler/access-builder.cc
+++ b/src/compiler/access-builder.cc
@@ -422,7 +422,7 @@
                         MaybeHandle<Name>(),
                         MaybeHandle<Map>(),
                         TypeCache::Get()->kJSTypedArrayLengthType,
-                        MachineType::TypeCompressedTaggedSigned(),
+                        MachineType::UintPtr(),
                         kNoWriteBarrier};
   return access;
 }
diff --git a/src/compiler/type-cache.h b/src/compiler/type-cache.h
index 1a1555d..b93698c 100644
--- a/src/compiler/type-cache.h
+++ b/src/compiler/type-cache.h
@@ -113,9 +113,10 @@
   // JSArrayBuffer::byte_length above.
   Type const kJSArrayBufferViewByteOffsetType = kJSArrayBufferByteLengthType;
 
-  // The JSTypedArray::length property always contains a tagged number in the
-  // range [0, kMaxSmiValue].
-  Type const kJSTypedArrayLengthType = Type::UnsignedSmall();
+  // The JSTypedArray::length property always contains an untagged number in
+  // the range [0, kMaxSmiValue].
+  Type const kJSTypedArrayLengthType =
+      CreateRange(0.0, JSTypedArray::kMaxLength);
 
   // The String::length property always contains a smi in the range
   // [0, String::kMaxLength].
diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc
index 64f921c..10cf89d 100644
--- a/src/ic/accessor-assembler.cc
+++ b/src/ic/accessor-assembler.cc
@@ -1979,7 +1979,7 @@
     GotoIf(IsDetachedBuffer(buffer), miss);
 
     // Bounds check.
-    Node* length = SmiUntag(LoadJSTypedArrayLength(CAST(object)));
+    TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(object));
     GotoIfNot(UintPtrLessThan(intptr_index, length), out_of_bounds);
     if (access_mode == LoadAccessMode::kHas) {
       exit_point->Return(TrueConstant());
diff --git a/src/objects-debug.cc b/src/objects-debug.cc
index dc49173..3a57b50 100644
--- a/src/objects-debug.cc
+++ b/src/objects-debug.cc
@@ -1546,7 +1546,7 @@
 
 void JSTypedArray::JSTypedArrayVerify(Isolate* isolate) {
   ClassVerifiersFromDSL::JSTypedArrayVerify(*this, isolate);
-  VerifyPointer(isolate, elements());
+  CHECK_LE(length(), JSTypedArray::kMaxLength);
 }
 
 void JSDataView::JSDataViewVerify(Isolate* isolate) {
diff --git a/src/objects/js-array-buffer-inl.h b/src/objects/js-array-buffer-inl.h
index a733f51..354bfe8 100644
--- a/src/objects/js-array-buffer-inl.h
+++ b/src/objects/js-array-buffer-inl.h
@@ -133,16 +133,11 @@
 }
 
 size_t JSTypedArray::length() const {
-  // TODO(bmeurer, v8:4153): Change this to size_t later.
-  int length = Smi::cast(raw_length())->value();
-  DCHECK_LE(0, length);
-  return length;
+  return READ_UINTPTR_FIELD(*this, kLengthOffset);
 }
 
 void JSTypedArray::set_length(size_t value) {
-  // TODO(bmeurer, v8:4153): Change this to size_t later.
-  CHECK_LE(value, Smi::kMaxValue);
-  set_raw_length(Smi::FromInt(static_cast<int>(value)), SKIP_WRITE_BARRIER);
+  WRITE_UINTPTR_FIELD(*this, kLengthOffset, value);
 }
 
 bool JSTypedArray::is_on_heap() const {
@@ -175,8 +170,6 @@
   return array;
 }
 
-ACCESSORS(JSTypedArray, raw_length, Object, kLengthOffset)
-
 void* JSDataView::data_pointer() const {
   intptr_t ptr = READ_INTPTR_FIELD(*this, kDataPointerOffset);
   return reinterpret_cast<void*>(ptr);
diff --git a/src/objects/js-array-buffer.h b/src/objects/js-array-buffer.h
index 4454519..8a6227e 100644
--- a/src/objects/js-array-buffer.h
+++ b/src/objects/js-array-buffer.h
@@ -177,6 +177,9 @@
 
 class JSTypedArray : public JSArrayBufferView {
  public:
+  // TODO(v8:4153): This should become JSArrayBuffer::kMaxByteLength eventually.
+  static constexpr size_t kMaxLength = kSmiMaxValue;
+
   // [length]: length of typed array in elements.
   DECL_PRIMITIVE_ACCESSORS(length, size_t)
 
@@ -206,7 +209,7 @@
 // Layout description.
 #define JS_TYPED_ARRAY_FIELDS(V) \
   /* Raw data fields. */         \
-  V(kLengthOffset, kTaggedSize)  \
+  V(kLengthOffset, kUIntptrSize) \
   /* Header size. */             \
   V(kHeaderSize, 0)
 
@@ -224,8 +227,6 @@
   static Handle<JSArrayBuffer> MaterializeArrayBuffer(
       Handle<JSTypedArray> typed_array);
 
-  DECL_ACCESSORS(raw_length, Object)
-
   OBJECT_CONSTRUCTORS(JSTypedArray, JSArrayBufferView);
 };