Skip to content

Commit c1e67ac

Browse files
rmacnak-googleCommit Bot
authored and
Commit Bot
committed
[vm] Recognize unmodifiable typed data views.
These types now work with Dart_TypedDataAcquireData. The presence of these types no longer degrades the performance of typed data indexed loads. The presence of these types degrades the performance of typed data indexed stores much less. The performance of indexed stores is somewhat regressed if these types were not used. TEST=ci Bug: #32028 Bug: #40924 Bug: #42785 Change-Id: Iffad865708501acf96db418985cd5a69bd9afa55 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/254501 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent f592a11 commit c1e67ac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+6116
-3007
lines changed

runtime/lib/typed_data.cc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ static bool IsClamped(intptr_t cid) {
9494
case kTypedDataUint8ClampedArrayCid:
9595
case kExternalTypedDataUint8ClampedArrayCid:
9696
case kTypedDataUint8ClampedArrayViewCid:
97+
case kUnmodifiableTypedDataUint8ClampedArrayViewCid:
9798
return true;
9899
default:
99100
return false;
@@ -105,9 +106,11 @@ static bool IsUint8(intptr_t cid) {
105106
case kTypedDataUint8ClampedArrayCid:
106107
case kExternalTypedDataUint8ClampedArrayCid:
107108
case kTypedDataUint8ClampedArrayViewCid:
109+
case kUnmodifiableTypedDataUint8ClampedArrayViewCid:
108110
case kTypedDataUint8ArrayCid:
109111
case kExternalTypedDataUint8ArrayCid:
110112
case kTypedDataUint8ArrayViewCid:
113+
case kUnmodifiableTypedDataUint8ArrayViewCid:
111114
return true;
112115
default:
113116
return false;
@@ -186,10 +189,15 @@ static InstancePtr NewTypedDataView(intptr_t cid,
186189
}
187190

188191
#define TYPED_DATA_NEW_NATIVE(name) \
189-
TYPED_DATA_VIEW_NEW(TypedDataView_##name##View_new, kTypedData##name##ViewCid)
192+
TYPED_DATA_VIEW_NEW(TypedDataView_##name##View_new, \
193+
kTypedData##name##ViewCid) \
194+
TYPED_DATA_VIEW_NEW(TypedDataView_Unmodifiable##name##View_new, \
195+
kUnmodifiableTypedData##name##ViewCid)
190196

191197
CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE)
192198
TYPED_DATA_VIEW_NEW(TypedDataView_ByteDataView_new, kByteDataViewCid)
199+
TYPED_DATA_VIEW_NEW(TypedDataView_UnmodifiableByteDataView_new,
200+
kUnmodifiableByteDataViewCid)
193201
#undef TYPED_DATA_NEW_NATIVE
194202
#undef TYPED_DATA_VIEW_NEW
195203

runtime/tests/vm/dart/typed_data_aot_not_inlining_il_test.dart

Lines changed: 0 additions & 47 deletions
This file was deleted.

runtime/tests/vm/dart_2/typed_data_aot_not_inlining_il_test.dart

Lines changed: 0 additions & 47 deletions
This file was deleted.

runtime/vm/bootstrap_natives.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,21 @@ namespace dart {
217217
V(TypedDataView_Float64x2ArrayView_new, 4) \
218218
V(TypedDataView_offsetInBytes, 1) \
219219
V(TypedDataView_typedData, 1) \
220+
V(TypedDataView_UnmodifiableByteDataView_new, 4) \
221+
V(TypedDataView_UnmodifiableInt8ArrayView_new, 4) \
222+
V(TypedDataView_UnmodifiableUint8ArrayView_new, 4) \
223+
V(TypedDataView_UnmodifiableUint8ClampedArrayView_new, 4) \
224+
V(TypedDataView_UnmodifiableInt16ArrayView_new, 4) \
225+
V(TypedDataView_UnmodifiableUint16ArrayView_new, 4) \
226+
V(TypedDataView_UnmodifiableInt32ArrayView_new, 4) \
227+
V(TypedDataView_UnmodifiableUint32ArrayView_new, 4) \
228+
V(TypedDataView_UnmodifiableInt64ArrayView_new, 4) \
229+
V(TypedDataView_UnmodifiableUint64ArrayView_new, 4) \
230+
V(TypedDataView_UnmodifiableFloat32ArrayView_new, 4) \
231+
V(TypedDataView_UnmodifiableFloat64ArrayView_new, 4) \
232+
V(TypedDataView_UnmodifiableFloat32x4ArrayView_new, 4) \
233+
V(TypedDataView_UnmodifiableInt32x4ArrayView_new, 4) \
234+
V(TypedDataView_UnmodifiableFloat64x2ArrayView_new, 4) \
220235
V(Float32x4_fromDoubles, 4) \
221236
V(Float32x4_splat, 1) \
222237
V(Float32x4_fromInt32x4Bits, 2) \

runtime/vm/class_id.h

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -233,10 +233,12 @@ enum ClassId : intptr_t {
233233
#define DEFINE_OBJECT_KIND(clazz) \
234234
kTypedData##clazz##Cid, \
235235
kTypedData##clazz##ViewCid, \
236-
kExternalTypedData##clazz##Cid,
236+
kExternalTypedData##clazz##Cid, \
237+
kUnmodifiableTypedData##clazz##ViewCid,
237238
CLASS_LIST_TYPED_DATA(DEFINE_OBJECT_KIND)
238239
#undef DEFINE_OBJECT_KIND
239240
kByteDataViewCid,
241+
kUnmodifiableByteDataViewCid,
240242

241243
kByteBufferCid,
242244
// clang-format on
@@ -255,6 +257,7 @@ enum ClassId : intptr_t {
255257
const int kTypedDataCidRemainderInternal = 0;
256258
const int kTypedDataCidRemainderView = 1;
257259
const int kTypedDataCidRemainderExternal = 2;
260+
const int kTypedDataCidRemainderUnmodifiable = 3;
258261

259262
// Class Id predicates.
260263

@@ -361,34 +364,45 @@ inline bool IsTypeClassId(intptr_t index) {
361364

362365
inline bool IsTypedDataBaseClassId(intptr_t index) {
363366
// Make sure this is updated when new TypedData types are added.
364-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 == kTypedDataUint8ArrayCid);
367+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 4 == kTypedDataUint8ArrayCid);
365368
return index >= kTypedDataInt8ArrayCid && index < kByteDataViewCid;
366369
}
367370

368371
inline bool IsTypedDataClassId(intptr_t index) {
369372
// Make sure this is updated when new TypedData types are added.
370-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 == kTypedDataUint8ArrayCid);
373+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 4 == kTypedDataUint8ArrayCid);
371374
return IsTypedDataBaseClassId(index) && ((index - kTypedDataInt8ArrayCid) %
372-
3) == kTypedDataCidRemainderInternal;
375+
4) == kTypedDataCidRemainderInternal;
373376
}
374377

375378
inline bool IsTypedDataViewClassId(intptr_t index) {
376379
// Make sure this is updated when new TypedData types are added.
377-
COMPILE_ASSERT(kTypedDataInt8ArrayViewCid + 3 == kTypedDataUint8ArrayViewCid);
380+
COMPILE_ASSERT(kTypedDataInt8ArrayViewCid + 4 == kTypedDataUint8ArrayViewCid);
378381

379382
const bool is_byte_data_view = index == kByteDataViewCid;
380383
return is_byte_data_view ||
381384
(IsTypedDataBaseClassId(index) &&
382-
((index - kTypedDataInt8ArrayCid) % 3) == kTypedDataCidRemainderView);
385+
((index - kTypedDataInt8ArrayCid) % 4) == kTypedDataCidRemainderView);
383386
}
384387

385388
inline bool IsExternalTypedDataClassId(intptr_t index) {
386389
// Make sure this is updated when new TypedData types are added.
387-
COMPILE_ASSERT(kExternalTypedDataInt8ArrayCid + 3 ==
390+
COMPILE_ASSERT(kExternalTypedDataInt8ArrayCid + 4 ==
388391
kExternalTypedDataUint8ArrayCid);
389392

390393
return IsTypedDataBaseClassId(index) && ((index - kTypedDataInt8ArrayCid) %
391-
3) == kTypedDataCidRemainderExternal;
394+
4) == kTypedDataCidRemainderExternal;
395+
}
396+
397+
inline bool IsUnmodifiableTypedDataViewClassId(intptr_t index) {
398+
// Make sure this is updated when new TypedData types are added.
399+
COMPILE_ASSERT(kExternalTypedDataInt8ArrayCid + 4 ==
400+
kExternalTypedDataUint8ArrayCid);
401+
402+
const bool is_byte_data_view = index == kUnmodifiableByteDataViewCid;
403+
return is_byte_data_view || (IsTypedDataBaseClassId(index) &&
404+
((index - kTypedDataInt8ArrayCid) % 4) ==
405+
kTypedDataCidRemainderUnmodifiable);
392406
}
393407

394408
inline bool IsFfiTypeClassId(intptr_t index) {
@@ -446,21 +460,21 @@ COMPILE_ASSERT(kTypedDataInt8ArrayCid + 1 == kTypedDataInt8ArrayViewCid);
446460
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 2 == kExternalTypedDataInt8ArrayCid);
447461

448462
// Ensure the order of the typed data members in 3-step.
449-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 1 * 3 == kTypedDataUint8ArrayCid);
450-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 2 * 3 ==
463+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 1 * 4 == kTypedDataUint8ArrayCid);
464+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 2 * 4 ==
451465
kTypedDataUint8ClampedArrayCid);
452-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 * 3 == kTypedDataInt16ArrayCid);
453-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 4 * 3 == kTypedDataUint16ArrayCid);
454-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 5 * 3 == kTypedDataInt32ArrayCid);
455-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 6 * 3 == kTypedDataUint32ArrayCid);
456-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 7 * 3 == kTypedDataInt64ArrayCid);
457-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 8 * 3 == kTypedDataUint64ArrayCid);
458-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 9 * 3 == kTypedDataFloat32ArrayCid);
459-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 10 * 3 == kTypedDataFloat64ArrayCid);
460-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 11 * 3 == kTypedDataFloat32x4ArrayCid);
461-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 12 * 3 == kTypedDataInt32x4ArrayCid);
462-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 13 * 3 == kTypedDataFloat64x2ArrayCid);
463-
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 14 * 3 == kByteDataViewCid);
466+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 3 * 4 == kTypedDataInt16ArrayCid);
467+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 4 * 4 == kTypedDataUint16ArrayCid);
468+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 5 * 4 == kTypedDataInt32ArrayCid);
469+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 6 * 4 == kTypedDataUint32ArrayCid);
470+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 7 * 4 == kTypedDataInt64ArrayCid);
471+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 8 * 4 == kTypedDataUint64ArrayCid);
472+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 9 * 4 == kTypedDataFloat32ArrayCid);
473+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 10 * 4 == kTypedDataFloat64ArrayCid);
474+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 11 * 4 == kTypedDataFloat32x4ArrayCid);
475+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 12 * 4 == kTypedDataInt32x4ArrayCid);
476+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 13 * 4 == kTypedDataFloat64x2ArrayCid);
477+
COMPILE_ASSERT(kTypedDataInt8ArrayCid + 14 * 4 == kByteDataViewCid);
464478
COMPILE_ASSERT(kByteBufferCid + 1 == kNullCid);
465479

466480
} // namespace dart

runtime/vm/compiler/backend/constant_propagator.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,13 @@ void ConstantPropagator::VisitGenericCheckBound(GenericCheckBoundInstr* instr) {
409409
SetValue(instr, non_constant_);
410410
}
411411

412+
void ConstantPropagator::VisitCheckWritable(CheckWritableInstr* instr) {
413+
// Don't propagate constants through check, since it would eliminate
414+
// the data dependence between the writable check and its use.
415+
// Graph finalization will expose the constant eventually.
416+
SetValue(instr, non_constant_);
417+
}
418+
412419
void ConstantPropagator::VisitCheckNull(CheckNullInstr* instr) {
413420
// Don't propagate constants through check, since it would eliminate
414421
// the data dependence between the null check and its use.

runtime/vm/compiler/backend/flow_graph_compiler.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3405,6 +3405,36 @@ void RangeErrorSlowPath::PushArgumentsForRuntimeCall(
34053405
locs->in(CheckBoundBase::kLengthPos).reg());
34063406
}
34073407

3408+
void RangeErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
3409+
bool save_fpu_registers) {
3410+
#if defined(TARGET_ARCH_IA32)
3411+
UNREACHABLE();
3412+
#else
3413+
auto object_store = compiler->isolate_group()->object_store();
3414+
const auto& stub = Code::ZoneHandle(
3415+
compiler->zone(),
3416+
save_fpu_registers
3417+
? object_store->range_error_stub_with_fpu_regs_stub()
3418+
: object_store->range_error_stub_without_fpu_regs_stub());
3419+
compiler->EmitCallToStub(stub);
3420+
#endif
3421+
}
3422+
3423+
void WriteErrorSlowPath::EmitSharedStubCall(FlowGraphCompiler* compiler,
3424+
bool save_fpu_registers) {
3425+
#if defined(TARGET_ARCH_IA32)
3426+
UNREACHABLE();
3427+
#else
3428+
auto object_store = compiler->isolate_group()->object_store();
3429+
const auto& stub = Code::ZoneHandle(
3430+
compiler->zone(),
3431+
save_fpu_registers
3432+
? object_store->write_error_stub_with_fpu_regs_stub()
3433+
: object_store->write_error_stub_without_fpu_regs_stub());
3434+
compiler->EmitCallToStub(stub);
3435+
#endif
3436+
}
3437+
34083438
void LateInitializationErrorSlowPath::PushArgumentsForRuntimeCall(
34093439
FlowGraphCompiler* compiler) {
34103440
__ PushObject(Field::ZoneHandle(OriginalField()));

runtime/vm/compiler/backend/flow_graph_compiler.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,16 @@ class RangeErrorSlowPath : public ThrowErrorSlowPathCode {
386386
bool save_fpu_registers);
387387
};
388388

389+
class WriteErrorSlowPath : public ThrowErrorSlowPathCode {
390+
public:
391+
explicit WriteErrorSlowPath(CheckWritableInstr* instruction)
392+
: ThrowErrorSlowPathCode(instruction, kWriteErrorRuntimeEntry) {}
393+
virtual const char* name() { return "check writable"; }
394+
395+
virtual void EmitSharedStubCall(FlowGraphCompiler* compiler,
396+
bool save_fpu_registers);
397+
};
398+
389399
class LateInitializationErrorSlowPath : public ThrowErrorSlowPathCode {
390400
public:
391401
explicit LateInitializationErrorSlowPath(Instruction* instruction)

0 commit comments

Comments
 (0)