Skip to content

Commit 94362f1

Browse files
committed
[vm] Unify internal/external/view typed data into new RawTypedDataBase class
This moves the length field as well as an inner pointer to the start of the data into the RawTypedDataBase class. The inner pointer is updated on allocation, scavenges and old space compactions. To avoid writing more assembly the typed data view factory constructors will be generated using IL, which will update the inner pointer. This required adding new IR instructions and changing the existing UnboxedIntConverter instruction. This is the foundation work to de-virtualize calls on the public typed data types, e.g. Uint8List. Issue #35154 Cq-Include-Trybots: luci.dart.try:vm-canary-linux-debug-try, vm-dartkb-linux-debug-x64-try, vm-dartkb-linux-release-x64-try, vm-kernel-asan-linux-release-x64-try, vm-kernel-checked-linux-release-x64-try, vm-kernel-linux-debug-ia32-try, vm-kernel-linux-debug-simdbc64-try, vm-kernel-linux-debug-x64-try, vm-kernel-linux-product-x64-try, vm-kernel-linux-release-ia32-try, vm-kernel-linux-release-simarm-try, vm-kernel-linux-release-simarm64-try, vm-kernel-linux-release-simdbc64-try, vm-kernel-linux-release-x64-try, vm-kernel-optcounter-threshold-linux-release-ia32-try, vm-kernel-optcounter-threshold-linux-release-x64-try, vm-kernel-precomp-android-release-arm-try, vm-kernel-precomp-bare-linux-release-simarm-try, vm-kernel-precomp-bare-linux-release-simarm64-try, vm-kernel-precomp-bare-linux-release-x64-try, vm-kernel-precomp-linux-debug-x64-try, vm-kernel-precomp-linux-product-x64-try, vm-kernel-precomp-linux-release-simarm-try, vm-kernel-precomp-linux-release-simarm64-try, vm-kernel-precomp-linux-release-x64-try, vm-kernel-precomp-obfuscate-linux-release-x64-try, vm-kernel-precomp-win-release-simarm64-try, vm-kernel-precomp-win-release-x64-try, vm-kernel-reload-linux-debug-x64-try, vm-kernel-reload-linux-release-x64-try, vm-kernel-reload-rollback-linux-debug-x64-try, vm-kernel-reload-rollback-linux-release-x64-try, vm-kernel-win-debug-ia32-try, vm-kernel-win-debug-x64-try, vm-kernel-win-product-x64-try, vm-kernel-win-release-ia32-try, vm-kernel-win-release-x64-try Change-Id: I1aab0dd93fa0f06a05299ab4cb019cf898b9e1ef Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97960 Reviewed-by: Ryan Macnak <[email protected]> Reviewed-by: Vyacheslav Egorov <[email protected]>
1 parent c7dd9c1 commit 94362f1

Some content is hidden

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

60 files changed

+1106
-369
lines changed

runtime/lib/typed_data.cc

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -203,20 +203,16 @@ CLASS_LIST_TYPED_DATA(TYPED_DATA_NEW_NATIVE)
203203
#undef TYPED_DATA_NEW_NATIVE
204204
#undef TYPED_DATA_NEW
205205

206-
#define TYPED_DATA_VIEW_NEW(native_name, cid_name) \
206+
#define TYPED_DATA_VIEW_NEW(native_name, cid) \
207207
DEFINE_NATIVE_ENTRY(native_name, 0, 4) { \
208-
GET_NON_NULL_NATIVE_ARGUMENT(Instance, typed_data, \
208+
GET_NON_NULL_NATIVE_ARGUMENT(TypedDataBase, typed_data, \
209209
arguments->NativeArgAt(1)); \
210210
GET_NON_NULL_NATIVE_ARGUMENT(Smi, offset, arguments->NativeArgAt(2)); \
211211
GET_NON_NULL_NATIVE_ARGUMENT(Smi, len, arguments->NativeArgAt(3)); \
212-
const intptr_t backing_length = \
213-
typed_data.IsTypedData() \
214-
? TypedData::Cast(typed_data).LengthInBytes() \
215-
: ExternalTypedData::Cast(typed_data).LengthInBytes(); \
216-
const intptr_t cid = cid_name; \
212+
const intptr_t backing_length = typed_data.LengthInBytes(); \
217213
const intptr_t offset_in_bytes = offset.Value(); \
218214
const intptr_t length = len.Value(); \
219-
const intptr_t element_size = TypedDataView::ElementSizeInBytes(cid); \
215+
const intptr_t element_size = TypedDataBase::ElementSizeInBytes(cid); \
220216
AlignmentCheck(offset_in_bytes, element_size); \
221217
LengthCheck(offset_in_bytes + length * element_size, backing_length); \
222218
return TypedDataView::New(cid, typed_data, offset_in_bytes, length); \

runtime/vm/class_id.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ namespace dart {
6464
V(Float32x4) \
6565
V(Int32x4) \
6666
V(Float64x2) \
67+
V(TypedDataBase) \
6768
V(TypedData) \
6869
V(ExternalTypedData) \
6970
V(TypedDataView) \

runtime/vm/clustered_snapshot.cc

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3372,6 +3372,7 @@ class TypedDataDeserializationCluster : public DeserializationCluster {
33723372
Deserializer::InitializeHeader(
33733373
data, cid_, TypedData::InstanceSize(length_in_bytes), is_canonical);
33743374
data->ptr()->length_ = Smi::New(length);
3375+
data->RecomputeDataField();
33753376
uint8_t* cdata = reinterpret_cast<uint8_t*>(data->ptr()->data());
33763377
d->ReadBytes(cdata, length_in_bytes);
33773378
}
@@ -3381,6 +3382,84 @@ class TypedDataDeserializationCluster : public DeserializationCluster {
33813382
const intptr_t cid_;
33823383
};
33833384

3385+
#if !defined(DART_PRECOMPILED_RUNTIME)
3386+
class TypedDataViewSerializationCluster : public SerializationCluster {
3387+
public:
3388+
explicit TypedDataViewSerializationCluster(intptr_t cid)
3389+
: SerializationCluster("TypedDataView"), cid_(cid) {}
3390+
~TypedDataViewSerializationCluster() {}
3391+
3392+
void Trace(Serializer* s, RawObject* object) {
3393+
RawTypedDataView* view = TypedDataView::RawCast(object);
3394+
objects_.Add(view);
3395+
3396+
PushFromTo(view);
3397+
}
3398+
3399+
void WriteAlloc(Serializer* s) {
3400+
const intptr_t count = objects_.length();
3401+
s->WriteCid(cid_);
3402+
s->WriteUnsigned(count);
3403+
for (intptr_t i = 0; i < count; i++) {
3404+
RawTypedDataView* view = objects_[i];
3405+
s->AssignRef(view);
3406+
}
3407+
}
3408+
3409+
void WriteFill(Serializer* s) {
3410+
const intptr_t count = objects_.length();
3411+
for (intptr_t i = 0; i < count; i++) {
3412+
RawTypedDataView* view = objects_[i];
3413+
AutoTraceObject(view);
3414+
s->Write<bool>(view->IsCanonical());
3415+
WriteFromTo(view);
3416+
}
3417+
}
3418+
3419+
private:
3420+
const intptr_t cid_;
3421+
GrowableArray<RawTypedDataView*> objects_;
3422+
};
3423+
#endif // !DART_PRECOMPILED_RUNTIME
3424+
3425+
class TypedDataViewDeserializationCluster : public DeserializationCluster {
3426+
public:
3427+
explicit TypedDataViewDeserializationCluster(intptr_t cid) : cid_(cid) {}
3428+
~TypedDataViewDeserializationCluster() {}
3429+
3430+
void ReadAlloc(Deserializer* d) {
3431+
start_index_ = d->next_index();
3432+
PageSpace* old_space = d->heap()->old_space();
3433+
const intptr_t count = d->ReadUnsigned();
3434+
for (intptr_t i = 0; i < count; i++) {
3435+
d->AssignRef(
3436+
AllocateUninitialized(old_space, TypedDataView::InstanceSize()));
3437+
}
3438+
stop_index_ = d->next_index();
3439+
}
3440+
3441+
void ReadFill(Deserializer* d) {
3442+
for (intptr_t id = start_index_; id < stop_index_; id++) {
3443+
RawTypedDataView* view = reinterpret_cast<RawTypedDataView*>(d->Ref(id));
3444+
const bool is_canonical = d->Read<bool>();
3445+
Deserializer::InitializeHeader(view, cid_, TypedDataView::InstanceSize(),
3446+
is_canonical);
3447+
ReadFromTo(view);
3448+
}
3449+
}
3450+
3451+
void PostLoad(const Array& refs, Snapshot::Kind kind, Zone* zone) {
3452+
auto& view = TypedDataView::Handle(zone);
3453+
for (intptr_t id = start_index_; id < stop_index_; id++) {
3454+
view ^= refs.At(id);
3455+
view.RecomputeDataField();
3456+
}
3457+
}
3458+
3459+
private:
3460+
const intptr_t cid_;
3461+
};
3462+
33843463
#if !defined(DART_PRECOMPILED_RUNTIME)
33853464
class ExternalTypedDataSerializationCluster : public SerializationCluster {
33863465
public:
@@ -4122,11 +4201,13 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) {
41224201
return NULL;
41234202
#else
41244203
Zone* Z = zone_;
4125-
if ((cid >= kNumPredefinedCids) || (cid == kInstanceCid) ||
4126-
RawObject::IsTypedDataViewClassId(cid)) {
4204+
if (cid >= kNumPredefinedCids || cid == kInstanceCid) {
41274205
Push(isolate()->class_table()->At(cid));
41284206
return new (Z) InstanceSerializationCluster(cid);
41294207
}
4208+
if (RawObject::IsTypedDataViewClassId(cid)) {
4209+
return new (Z) TypedDataViewSerializationCluster(cid);
4210+
}
41304211
if (RawObject::IsExternalTypedDataClassId(cid)) {
41314212
return new (Z) ExternalTypedDataSerializationCluster(cid);
41324213
}
@@ -4745,10 +4826,12 @@ Deserializer::~Deserializer() {
47454826
DeserializationCluster* Deserializer::ReadCluster() {
47464827
intptr_t cid = ReadCid();
47474828
Zone* Z = zone_;
4748-
if ((cid >= kNumPredefinedCids) || (cid == kInstanceCid) ||
4749-
RawObject::IsTypedDataViewClassId(cid)) {
4829+
if (cid >= kNumPredefinedCids || cid == kInstanceCid) {
47504830
return new (Z) InstanceDeserializationCluster(cid);
47514831
}
4832+
if (RawObject::IsTypedDataViewClassId(cid)) {
4833+
return new (Z) TypedDataViewDeserializationCluster(cid);
4834+
}
47524835
if (RawObject::IsExternalTypedDataClassId(cid)) {
47534836
return new (Z) ExternalTypedDataDeserializationCluster(cid);
47544837
}

runtime/vm/compiler/aot/aot_call_specializer.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,8 @@ Definition* AotCallSpecializer::TryOptimizeMod(TemplateDartCall<0>* instr,
442442
Smi::ZoneHandle(Z, Smi::New(modulus - 1)), kUnboxedInt32);
443443
InsertBefore(instr, right_definition, /*env=*/NULL, FlowGraph::kValue);
444444
right_definition = new (Z)
445-
UnboxedIntConverterInstr(kUnboxedInt32, kUnboxedInt64,
446-
new (Z) Value(right_definition), DeoptId::kNone);
445+
IntConverterInstr(kUnboxedInt32, kUnboxedInt64,
446+
new (Z) Value(right_definition), DeoptId::kNone);
447447
InsertBefore(instr, right_definition, /*env=*/NULL, FlowGraph::kValue);
448448
#else
449449
Definition* right_definition = new (Z) UnboxedConstantInstr(

runtime/vm/compiler/asm_intrinsifier_arm.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
153153
/* R4: allocation stats address. */ \
154154
__ ldr(R3, Address(SP, kArrayLengthStackOffset)); /* Array length. */ \
155155
__ StoreIntoObjectNoBarrier( \
156-
R0, FieldAddress(R0, target::TypedData::length_offset()), R3); \
156+
R0, FieldAddress(R0, target::TypedDataBase::length_offset()), R3); \
157157
/* Initialize all array elements to 0. */ \
158158
/* R0: new object start as a tagged pointer. */ \
159159
/* R1: new object end address. */ \
@@ -165,6 +165,8 @@ void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
165165
__ LoadImmediate(R8, 0); \
166166
__ mov(R9, Operand(R8)); \
167167
__ AddImmediate(R3, R0, target::TypedData::InstanceSize() - 1); \
168+
__ StoreInternalPointer( \
169+
R0, FieldAddress(R0, target::TypedDataBase::data_field_offset()), R3); \
168170
Label init_loop; \
169171
__ Bind(&init_loop); \
170172
__ AddImmediate(R3, 2 * target::kWordSize); \

runtime/vm/compiler/asm_intrinsifier_arm64.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ static int GetScaleFactor(intptr_t size) {
168168
/* R1: new object end address. */ \
169169
__ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */ \
170170
__ StoreIntoObjectNoBarrier( \
171-
R0, FieldAddress(R0, target::TypedData::length_offset()), R2); \
171+
R0, FieldAddress(R0, target::TypedDataBase::length_offset()), R2); \
172172
/* Initialize all array elements to 0. */ \
173173
/* R0: new object start as a tagged pointer. */ \
174174
/* R1: new object end address. */ \
@@ -177,6 +177,8 @@ static int GetScaleFactor(intptr_t size) {
177177
/* data area to be initialized. */ \
178178
__ mov(R3, ZR); \
179179
__ AddImmediate(R2, R0, target::TypedData::InstanceSize() - 1); \
180+
__ StoreInternalPointer( \
181+
R0, FieldAddress(R0, target::TypedDataBase::data_field_offset()), R2); \
180182
Label init_loop, done; \
181183
__ Bind(&init_loop); \
182184
__ cmp(R2, Operand(R1)); \

runtime/vm/compiler/asm_intrinsifier_ia32.cc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
158158
/* EBX: new object end address. */ \
159159
__ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \
160160
__ StoreIntoObjectNoBarrier( \
161-
EAX, FieldAddress(EAX, target::TypedData::length_offset()), EDI); \
161+
EAX, FieldAddress(EAX, target::TypedDataBase::length_offset()), EDI); \
162162
/* Initialize all array elements to 0. */ \
163163
/* EAX: new object start as a tagged pointer. */ \
164164
/* EBX: new object end address. */ \
@@ -167,6 +167,9 @@ void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
167167
/* data area to be initialized. */ \
168168
__ xorl(ECX, ECX); /* Zero. */ \
169169
__ leal(EDI, FieldAddress(EAX, target::TypedData::InstanceSize())); \
170+
__ StoreInternalPointer( \
171+
EAX, FieldAddress(EAX, target::TypedDataBase::data_field_offset()), \
172+
EDI); \
170173
Label done, init_loop; \
171174
__ Bind(&init_loop); \
172175
__ cmpl(EDI, EBX); \
@@ -2210,7 +2213,7 @@ void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
22102213
// On stack: user tag (+1), return-address (+0).
22112214
void AsmIntrinsifier::UserTag_makeCurrent(Assembler* assembler,
22122215
Label* normal_ir_body) {
2213-
// RDI: Isolate.
2216+
// EDI: Isolate.
22142217
__ LoadIsolate(EDI);
22152218
// EAX: Current user tag.
22162219
__ movl(EAX, Address(EDI, target::Isolate::current_tag_offset()));

runtime/vm/compiler/asm_intrinsifier_x64.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
160160
/* RCX: new object end address. */ \
161161
__ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */ \
162162
__ StoreIntoObjectNoBarrier( \
163-
RAX, FieldAddress(RAX, target::TypedData::length_offset()), RDI); \
163+
RAX, FieldAddress(RAX, target::TypedDataBase::length_offset()), RDI); \
164164
/* Initialize all array elements to 0. */ \
165165
/* RAX: new object start as a tagged pointer. */ \
166166
/* RCX: new object end address. */ \
@@ -169,6 +169,9 @@ void AsmIntrinsifier::GrowableArray_Allocate(Assembler* assembler,
169169
/* data area to be initialized. */ \
170170
__ xorq(RBX, RBX); /* Zero. */ \
171171
__ leaq(RDI, FieldAddress(RAX, target::TypedData::InstanceSize())); \
172+
__ StoreInternalPointer( \
173+
RAX, FieldAddress(RAX, target::TypedDataBase::data_field_offset()), \
174+
RDI); \
172175
Label done, init_loop; \
173176
__ Bind(&init_loop); \
174177
__ cmpq(RDI, RCX); \

runtime/vm/compiler/assembler/assembler_arm.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,12 @@ void Assembler::StoreIntoObjectNoBarrierOffset(Register object,
17991799
}
18001800
}
18011801

1802+
void Assembler::StoreInternalPointer(Register object,
1803+
const Address& dest,
1804+
Register value) {
1805+
str(value, dest);
1806+
}
1807+
18021808
void Assembler::InitializeFieldsNoBarrier(Register object,
18031809
Register begin,
18041810
Register end,

runtime/vm/compiler/assembler/assembler_arm.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,11 @@ class Assembler : public AssemblerBase {
808808
int32_t offset,
809809
const Object& value);
810810

811+
// Stores a non-tagged value into a heap object.
812+
void StoreInternalPointer(Register object,
813+
const Address& dest,
814+
Register value);
815+
811816
// Store value_even, value_odd, value_even, ... into the words in the address
812817
// range [begin, end), assumed to be uninitialized fields in object (tagged).
813818
// The stores must not need a generational store barrier (e.g., smi/null),
@@ -854,6 +859,13 @@ class Assembler : public AssemblerBase {
854859
Register base,
855860
int32_t offset,
856861
Condition cond = AL);
862+
void StoreFieldToOffset(OperandSize type,
863+
Register reg,
864+
Register base,
865+
int32_t offset,
866+
Condition cond = AL) {
867+
StoreToOffset(type, reg, base, offset - kHeapObjectTag, cond);
868+
}
857869
void LoadSFromOffset(SRegister reg,
858870
Register base,
859871
int32_t offset,

runtime/vm/compiler/assembler/assembler_arm64.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,12 @@ void Assembler::StoreIntoObjectOffsetNoBarrier(Register object,
11361136
}
11371137
}
11381138

1139+
void Assembler::StoreInternalPointer(Register object,
1140+
const Address& dest,
1141+
Register value) {
1142+
str(value, dest);
1143+
}
1144+
11391145
void Assembler::LoadClassId(Register result, Register object) {
11401146
ASSERT(RawObject::kClassIdTagPos == 16);
11411147
ASSERT(RawObject::kClassIdTagSize == 16);

runtime/vm/compiler/assembler/assembler_arm64.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,6 +1475,11 @@ class Assembler : public AssemblerBase {
14751475
int32_t offset,
14761476
const Object& value);
14771477

1478+
// Stores a non-tagged value into a heap object.
1479+
void StoreInternalPointer(Register object,
1480+
const Address& dest,
1481+
Register value);
1482+
14781483
// Object pool, loading from pool, etc.
14791484
void LoadPoolPointer(Register pp = PP);
14801485

runtime/vm/compiler/assembler/assembler_ia32.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,12 @@ void Assembler::StoreIntoObjectNoBarrier(Register object,
19801980
// No store buffer update.
19811981
}
19821982

1983+
void Assembler::StoreInternalPointer(Register object,
1984+
const Address& dest,
1985+
Register value) {
1986+
movl(dest, value);
1987+
}
1988+
19831989
void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
19841990
#if defined(DEBUG)
19851991
Label done;

runtime/vm/compiler/assembler/assembler_ia32.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,11 @@ class Assembler : public AssemblerBase {
620620
const Address& dest,
621621
const Object& value);
622622

623+
// Stores a non-tagged value into a heap object.
624+
void StoreInternalPointer(Register object,
625+
const Address& dest,
626+
Register value);
627+
623628
// Stores a Smi value into a heap object field that always contains a Smi.
624629
void StoreIntoSmiField(const Address& dest, Register value);
625630
void ZeroInitSmiField(const Address& dest);

runtime/vm/compiler/assembler/assembler_x64.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,12 @@ void Assembler::StoreIntoObjectNoBarrier(Register object,
13891389
StoreObject(dest, value);
13901390
}
13911391

1392+
void Assembler::StoreInternalPointer(Register object,
1393+
const Address& dest,
1394+
Register value) {
1395+
movq(dest, value);
1396+
}
1397+
13921398
void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
13931399
#if defined(DEBUG)
13941400
Label done;

runtime/vm/compiler/assembler/assembler_x64.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,11 @@ class Assembler : public AssemblerBase {
744744
const Address& dest,
745745
const Object& value);
746746

747+
// Stores a non-tagged value into a heap object.
748+
void StoreInternalPointer(Register object,
749+
const Address& dest,
750+
Register value);
751+
747752
// Stores a Smi value into a heap object field that always contains a Smi.
748753
void StoreIntoSmiField(const Address& dest, Register value);
749754
void ZeroInitSmiField(const Address& dest);

runtime/vm/compiler/backend/block_scheduler.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,17 @@ void BlockScheduler::AssignEdgeWeights() const {
5959
return;
6060
}
6161

62+
const Function& function = flow_graph()->parsed_function().function();
6263
const Array& ic_data_array =
63-
Array::Handle(flow_graph()->zone(),
64-
flow_graph()->parsed_function().function().ic_data_array());
64+
Array::Handle(flow_graph()->zone(), function.ic_data_array());
6565
if (Compiler::IsBackgroundCompilation() && ic_data_array.IsNull()) {
6666
// Deferred loading cleared ic_data_array.
6767
Compiler::AbortBackgroundCompilation(
6868
DeoptId::kNone, "BlockScheduler: ICData array cleared");
6969
}
7070
if (ic_data_array.IsNull()) {
71-
DEBUG_ASSERT(Isolate::Current()->HasAttemptedReload());
71+
DEBUG_ASSERT(Isolate::Current()->HasAttemptedReload() ||
72+
function.ForceOptimize());
7273
return;
7374
}
7475
Array& edge_counters = Array::Handle();

0 commit comments

Comments
 (0)