Commit b9bc81d6 authored by Ben L. Titzer's avatar Ben L. Titzer Committed by Commit Bot

[typed-arrays] Introduce JSTypedArray::kMaxSizeInHeap constant

Extract the maximum on-heap typed array size to a constant in the
JSTypedArray class. Add tests for allocating typed arrays of various
sizes and validate through the API whether they are allocated on heap.
It is not possible to observe from JavaScript.

R=mstarzinger@chromium.org

Change-Id: I1298e0a49010de829edaad32b7d6c6c9c52704fb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1662572
Commit-Queue: Ben Titzer <titzer@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62257}
parent 4e17a6be
......@@ -1026,8 +1026,8 @@ const kMaxArrayIndex:
constexpr uint32 generates 'JSArray::kMaxArrayIndex';
const kArrayBufferMaxByteLength:
constexpr uintptr generates 'JSArrayBuffer::kMaxByteLength';
const V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP:
constexpr int31 generates 'V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP';
const kMaxTypedArrayInHeap:
constexpr int31 generates 'JSTypedArray::kMaxSizeInHeap';
const kMaxSafeInteger: constexpr float64 generates 'kMaxSafeInteger';
const kSmiMaxValue: constexpr uintptr generates 'kSmiMaxValue';
const kSmiMax: uintptr = kSmiMaxValue;
......
......@@ -18,12 +18,6 @@ using compiler::Node;
template <class T>
using TNode = compiler::TNode<T>;
// This is needed for gc_mole which will compile this file without the full set
// of GN defined macros.
#ifndef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP
#define V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP 64
#endif
// -----------------------------------------------------------------------------
// ES6 section 22.2 TypedArray Objects
......@@ -1007,7 +1001,5 @@ TF_BUILTIN(TypedArrayFrom, TypedArrayBuiltinsAssembler) {
"%TypedArray%.from");
}
#undef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP
} // namespace internal
} // namespace v8
......@@ -86,7 +86,7 @@ namespace typed_array_createtypedarray {
defaultConstructor, bufferConstructor, byteLengthNum));
}
if (byteLength > V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP) goto AllocateOffHeap;
if (byteLength > kMaxTypedArrayInHeap) goto AllocateOffHeap;
const buffer = AllocateEmptyOnHeapBuffer(byteLength);
......
......@@ -33,12 +33,6 @@ namespace v8 {
namespace internal {
namespace compiler {
// This is needed for gc_mole which will compile this file without the full set
// of GN defined macros.
#ifndef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP
#define V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP 64
#endif
namespace {
bool HasNumberMaps(JSHeapBroker* broker, ZoneVector<Handle<Map>> const& maps) {
......@@ -2587,7 +2581,7 @@ JSNativeContextSpecialization::BuildElementAccess(
// for Chrome. Node and Electron both set this limit to 0. Setting
// the base to Smi zero here allows the EffectControlLinearizer to
// optimize away the tricky part of the access later.
if (V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP == 0) {
if (JSTypedArray::kMaxSizeInHeap == 0) {
base_pointer = jsgraph()->ZeroConstant();
} else {
base_pointer = effect =
......@@ -3361,8 +3355,6 @@ SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
return jsgraph()->simplified();
}
#undef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -243,6 +243,12 @@ class JSTypedArray : public JSArrayBufferView {
class BodyDescriptor;
#ifdef V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP
static constexpr size_t kMaxSizeInHeap = V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP;
#else
static constexpr size_t kMaxSizeInHeap = 64;
#endif
private:
static Handle<JSArrayBuffer> MaterializeArrayBuffer(
Handle<JSTypedArray> typed_array);
......
......@@ -577,3 +577,85 @@ TEST(InternalFieldsOnDataView) {
array->GetAlignedPointerFromInternalField(i));
}
}
namespace {
void TestOnHeapHasBuffer(const char* array_name, size_t elem_size) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
i::ScopedVector<char> source(128);
// Test on-heap sizes.
for (size_t size = 0; size <= i::JSTypedArray::kMaxSizeInHeap;
size += elem_size) {
size_t length = size / elem_size;
i::SNPrintF(source, "new %sArray(%zu)", array_name, length);
auto typed_array =
v8::Local<v8::TypedArray>::Cast(CompileRun(source.begin()));
CHECK_EQ(length, typed_array->Length());
// Should not (yet) have a buffer.
CHECK(!typed_array->HasBuffer());
// Get the buffer and check its length.
i::Handle<i::JSTypedArray> i_typed_array =
v8::Utils::OpenHandle(*typed_array);
auto i_array_buffer1 = i_typed_array->GetBuffer();
CHECK_EQ(size, i_array_buffer1->byte_length());
CHECK(typed_array->HasBuffer());
// Should have the same buffer each time.
auto i_array_buffer2 = i_typed_array->GetBuffer();
CHECK(i_array_buffer1.is_identical_to(i_array_buffer2));
}
}
void TestOffHeapHasBuffer(const char* array_name, size_t elem_size) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope handle_scope(isolate);
i::ScopedVector<char> source(128);
// Test off-heap sizes.
size_t size = i::JSTypedArray::kMaxSizeInHeap;
for (int i = 0; i < 3; i++) {
size_t length = 1 + (size / elem_size);
i::SNPrintF(source, "new %sArray(%zu)", array_name, length);
auto typed_array =
v8::Local<v8::TypedArray>::Cast(CompileRun(source.begin()));
CHECK_EQ(length, typed_array->Length());
// Should already have a buffer.
CHECK(typed_array->HasBuffer());
// Get the buffer and check its length.
i::Handle<i::JSTypedArray> i_typed_array =
v8::Utils::OpenHandle(*typed_array);
auto i_array_buffer1 = i_typed_array->GetBuffer();
CHECK_EQ(length * elem_size, i_array_buffer1->byte_length());
size *= 2;
}
}
} // namespace
#define TEST_HAS_BUFFER(array_name, elem_size) \
TEST(OnHeap_##array_name##Array_HasBuffer) { \
TestOnHeapHasBuffer(#array_name, elem_size); \
} \
TEST(OffHeap_##array_name##_HasBuffer) { \
TestOffHeapHasBuffer(#array_name, elem_size); \
}
TEST_HAS_BUFFER(Uint8, 1)
TEST_HAS_BUFFER(Int8, 1)
TEST_HAS_BUFFER(Uint16, 2)
TEST_HAS_BUFFER(Int16, 2)
TEST_HAS_BUFFER(Uint32, 4)
TEST_HAS_BUFFER(Int32, 4)
TEST_HAS_BUFFER(Float32, 4)
TEST_HAS_BUFFER(Float64, 8)
#undef TEST_HAS_BUFFER
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment