Skip to content

Commit 7e5bbe3

Browse files
rmacnak-googlecommit-bot@chromium.org
authored andcommitted
[vm, bytecode] More passing vm/cc tests.
- Hook up allocation tracing. - Fix off-by-one when mapping bcpcs to token positions. - Fix missing class loading for predefined classes in Dart_Invoke type checks. Change-Id: Id9177001d493725a0545c5948b7f7c6b4693027c Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/107564 Commit-Queue: Ryan Macnak <[email protected]> Reviewed-by: Alexander Markov <[email protected]> Reviewed-by: Régis Crelier <[email protected]>
1 parent a5070b8 commit 7e5bbe3

File tree

7 files changed

+455
-253
lines changed

7 files changed

+455
-253
lines changed

runtime/vm/interpreter.cc

Lines changed: 53 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,28 @@ DART_FORCE_INLINE static RawObject* InitializeHeader(uword addr,
256256
return RawObject::FromAddr(addr);
257257
}
258258

259+
DART_FORCE_INLINE static bool TryAllocate(Thread* thread,
260+
intptr_t class_id,
261+
intptr_t instance_size,
262+
RawObject** result) {
263+
const uword start = thread->top();
264+
#ifndef PRODUCT
265+
ClassTable* table = thread->isolate()->class_table();
266+
if (UNLIKELY(table->TraceAllocationFor(class_id))) {
267+
return false;
268+
}
269+
#endif
270+
if (LIKELY((start + instance_size) < thread->end())) {
271+
thread->set_top(start + instance_size);
272+
#ifndef PRODUCT
273+
table->UpdateAllocatedNew(class_id, instance_size);
274+
#endif
275+
*result = InitializeHeader(start, class_id, instance_size);
276+
return true;
277+
}
278+
return false;
279+
}
280+
259281
void LookupCache::Clear() {
260282
for (intptr_t i = 0; i < kNumEntries; i++) {
261283
entries_[i].receiver_cid = kIllegalCid;
@@ -1351,14 +1373,9 @@ DART_NOINLINE bool Interpreter::AllocateMint(Thread* thread,
13511373
RawObject** FP,
13521374
RawObject** SP) {
13531375
ASSERT(!Smi::IsValid(value));
1354-
const intptr_t instance_size = Mint::InstanceSize();
1355-
const uword start = thread->top();
1356-
if (LIKELY((start + instance_size) < thread->end())) {
1357-
thread->set_top(start + instance_size);
1358-
NOT_IN_PRODUCT(thread->isolate()->class_table()->UpdateAllocatedNew(
1359-
kMintCid, instance_size));
1360-
RawMint* result =
1361-
Mint::RawCast(InitializeHeader(start, kMintCid, instance_size));
1376+
RawMint* result;
1377+
if (TryAllocate(thread, kMintCid, Mint::InstanceSize(),
1378+
reinterpret_cast<RawObject**>(&result))) {
13621379
result->ptr()->value_ = value;
13631380
SP[0] = result;
13641381
return true;
@@ -1383,14 +1400,9 @@ DART_NOINLINE bool Interpreter::AllocateDouble(Thread* thread,
13831400
const KBCInstr* pc,
13841401
RawObject** FP,
13851402
RawObject** SP) {
1386-
const intptr_t instance_size = Double::InstanceSize();
1387-
const uword start = thread->top();
1388-
if (LIKELY((start + instance_size) < thread->end())) {
1389-
thread->set_top(start + instance_size);
1390-
NOT_IN_PRODUCT(thread->isolate()->class_table()->UpdateAllocatedNew(
1391-
kDoubleCid, instance_size));
1392-
RawDouble* result =
1393-
Double::RawCast(InitializeHeader(start, kDoubleCid, instance_size));
1403+
RawDouble* result;
1404+
if (TryAllocate(thread, kDoubleCid, Double::InstanceSize(),
1405+
reinterpret_cast<RawObject**>(&result))) {
13941406
result->ptr()->value_ = value;
13951407
SP[0] = result;
13961408
return true;
@@ -1415,14 +1427,9 @@ DART_NOINLINE bool Interpreter::AllocateFloat32x4(Thread* thread,
14151427
const KBCInstr* pc,
14161428
RawObject** FP,
14171429
RawObject** SP) {
1418-
const intptr_t instance_size = Float32x4::InstanceSize();
1419-
const uword start = thread->top();
1420-
if (LIKELY((start + instance_size) < thread->end())) {
1421-
thread->set_top(start + instance_size);
1422-
NOT_IN_PRODUCT(thread->isolate()->class_table()->UpdateAllocatedNew(
1423-
kFloat32x4Cid, instance_size));
1424-
RawFloat32x4* result = Float32x4::RawCast(
1425-
InitializeHeader(start, kFloat32x4Cid, instance_size));
1430+
RawFloat32x4* result;
1431+
if (TryAllocate(thread, kFloat32x4Cid, Float32x4::InstanceSize(),
1432+
reinterpret_cast<RawObject**>(&result))) {
14261433
value.writeTo(result->ptr()->value_);
14271434
SP[0] = result;
14281435
return true;
@@ -1447,14 +1454,9 @@ DART_NOINLINE bool Interpreter::AllocateFloat64x2(Thread* thread,
14471454
const KBCInstr* pc,
14481455
RawObject** FP,
14491456
RawObject** SP) {
1450-
const intptr_t instance_size = Float64x2::InstanceSize();
1451-
const uword start = thread->top();
1452-
if (LIKELY((start + instance_size) < thread->end())) {
1453-
thread->set_top(start + instance_size);
1454-
NOT_IN_PRODUCT(thread->isolate()->class_table()->UpdateAllocatedNew(
1455-
kFloat64x2Cid, instance_size));
1456-
RawFloat64x2* result = Float64x2::RawCast(
1457-
InitializeHeader(start, kFloat64x2Cid, instance_size));
1457+
RawFloat64x2* result;
1458+
if (TryAllocate(thread, kFloat64x2Cid, Float64x2::InstanceSize(),
1459+
reinterpret_cast<RawObject**>(&result))) {
14581460
value.writeTo(result->ptr()->value_);
14591461
SP[0] = result;
14601462
return true;
@@ -1483,14 +1485,9 @@ bool Interpreter::AllocateArray(Thread* thread,
14831485
if (LIKELY(!length_object->IsHeapObject())) {
14841486
const intptr_t length = Smi::Value(Smi::RawCast(length_object));
14851487
if (LIKELY(Array::IsValidLength(length))) {
1486-
const intptr_t instance_size = Array::InstanceSize(length);
1487-
const uword start = thread->top();
1488-
if (LIKELY((start + instance_size) < thread->end())) {
1489-
thread->set_top(start + instance_size);
1490-
NOT_IN_PRODUCT(thread->isolate()->class_table()->UpdateAllocatedNew(
1491-
kArrayCid, instance_size));
1492-
RawArray* result =
1493-
Array::RawCast(InitializeHeader(start, kArrayCid, instance_size));
1488+
RawArray* result;
1489+
if (TryAllocate(thread, kArrayCid, Array::InstanceSize(length),
1490+
reinterpret_cast<RawObject**>(&result))) {
14941491
result->ptr()->type_arguments_ = type_args;
14951492
result->ptr()->length_ = Smi::New(length);
14961493
for (intptr_t i = 0; i < length; i++) {
@@ -1517,21 +1514,15 @@ bool Interpreter::AllocateContext(Thread* thread,
15171514
const KBCInstr* pc,
15181515
RawObject** FP,
15191516
RawObject** SP) {
1520-
const intptr_t instance_size = Context::InstanceSize(num_context_variables);
1521-
ASSERT(Utils::IsAligned(instance_size, kObjectAlignment));
1522-
const uword start = thread->top();
1523-
if (LIKELY((start + instance_size) < thread->end())) {
1524-
thread->set_top(start + instance_size);
1525-
NOT_IN_PRODUCT(thread->isolate()->class_table()->UpdateAllocatedNew(
1526-
kContextCid, instance_size));
1527-
RawContext* result =
1528-
Context::RawCast(InitializeHeader(start, kContextCid, instance_size));
1517+
RawContext* result;
1518+
if (TryAllocate(thread, kContextCid,
1519+
Context::InstanceSize(num_context_variables),
1520+
reinterpret_cast<RawObject**>(&result))) {
15291521
result->ptr()->num_variables_ = num_context_variables;
15301522
RawObject* null_value = Object::null();
15311523
result->ptr()->parent_ = static_cast<RawContext*>(null_value);
1532-
for (intptr_t offset = sizeof(RawContext); offset < instance_size;
1533-
offset += kWordSize) {
1534-
*reinterpret_cast<RawObject**>(start + offset) = null_value;
1524+
for (intptr_t i = 0; i < num_context_variables; i++) {
1525+
result->ptr()->data()[i] = null_value;
15351526
}
15361527
SP[0] = result;
15371528
return true;
@@ -1551,13 +1542,10 @@ bool Interpreter::AllocateClosure(Thread* thread,
15511542
RawObject** FP,
15521543
RawObject** SP) {
15531544
const intptr_t instance_size = Closure::InstanceSize();
1554-
const uword start = thread->top();
1555-
if (LIKELY((start + instance_size) < thread->end())) {
1556-
thread->set_top(start + instance_size);
1557-
NOT_IN_PRODUCT(thread->isolate()->class_table()->UpdateAllocatedNew(
1558-
kClosureCid, instance_size));
1559-
RawClosure* result =
1560-
Closure::RawCast(InitializeHeader(start, kClosureCid, instance_size));
1545+
RawClosure* result;
1546+
if (TryAllocate(thread, kClosureCid, instance_size,
1547+
reinterpret_cast<RawObject**>(&result))) {
1548+
uword start = RawObject::ToAddr(result);
15611549
RawObject* null_value = Object::null();
15621550
for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
15631551
offset += kWordSize) {
@@ -2492,12 +2480,9 @@ RawObject* Interpreter::Call(RawFunction* function,
24922480
const intptr_t class_id = cls->ptr()->id_;
24932481
const intptr_t instance_size = cls->ptr()->instance_size_in_words_
24942482
<< kWordSizeLog2;
2495-
const uword start = thread->top();
2496-
if (LIKELY((start + instance_size) < thread->end())) {
2497-
thread->set_top(start + instance_size);
2498-
NOT_IN_PRODUCT(thread->isolate()->class_table()->UpdateAllocatedNew(
2499-
class_id, instance_size));
2500-
RawObject* result = InitializeHeader(start, class_id, instance_size);
2483+
RawObject* result;
2484+
if (TryAllocate(thread, class_id, instance_size, &result)) {
2485+
uword start = RawObject::ToAddr(result);
25012486
for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
25022487
offset += kWordSize) {
25032488
*reinterpret_cast<RawObject**>(start + offset) = null_value;
@@ -2525,12 +2510,9 @@ RawObject* Interpreter::Call(RawFunction* function,
25252510
const intptr_t class_id = cls->ptr()->id_;
25262511
const intptr_t instance_size = cls->ptr()->instance_size_in_words_
25272512
<< kWordSizeLog2;
2528-
const uword start = thread->top();
2529-
if (LIKELY((start + instance_size) < thread->end())) {
2530-
thread->set_top(start + instance_size);
2531-
NOT_IN_PRODUCT(thread->isolate()->class_table()->UpdateAllocatedNew(
2532-
class_id, instance_size));
2533-
RawObject* result = InitializeHeader(start, class_id, instance_size);
2513+
RawObject* result;
2514+
if (TryAllocate(thread, class_id, instance_size, &result)) {
2515+
uword start = RawObject::ToAddr(result);
25342516
for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
25352517
offset += kWordSize) {
25362518
*reinterpret_cast<RawObject**>(start + offset) = null_value;

runtime/vm/isolate_reload.cc

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#include "vm/isolate_reload.h"
66

7+
#include <memory>
8+
79
#include "vm/bit_vector.h"
810
#include "vm/compiler/jit/compiler.h"
911
#include "vm/dart_api_impl.h"
@@ -171,10 +173,10 @@ void InstanceMorpher::RunNewFieldInitializers() const {
171173
for (intptr_t i = 0; i < new_fields_->length(); i++) {
172174
// Create a function that returns the expression.
173175
const Field* field = new_fields_->At(i);
174-
if (field->kernel_offset() > 0) {
175-
eval_func = kernel::CreateFieldInitializerFunction(thread, zone, *field);
176+
if (field->is_declared_in_bytecode()) {
177+
UNIMPLEMENTED();
176178
} else {
177-
UNREACHABLE();
179+
eval_func = kernel::CreateFieldInitializerFunction(thread, zone, *field);
178180
}
179181

180182
for (intptr_t j = 0; j < after_->length(); j++) {
@@ -2307,6 +2309,9 @@ void IsolateReloadContext::RebuildDirectSubclasses() {
23072309
for (intptr_t i = 1; i < num_cids; i++) {
23082310
if (class_table->HasValidClassAt(i)) {
23092311
cls = class_table->At(i);
2312+
if (!cls.is_declaration_loaded()) {
2313+
continue; // Can't have any subclasses or implementors yet.
2314+
}
23102315
subclasses = cls.direct_subclasses();
23112316
if (!subclasses.IsNull()) {
23122317
cls.ClearDirectSubclasses();
@@ -2330,6 +2335,9 @@ void IsolateReloadContext::RebuildDirectSubclasses() {
23302335
for (intptr_t i = 1; i < num_cids; i++) {
23312336
if (class_table->HasValidClassAt(i)) {
23322337
cls = class_table->At(i);
2338+
if (!cls.is_declaration_loaded()) {
2339+
continue; // Will register itself later when loaded.
2340+
}
23332341
super_type = cls.super_type();
23342342
if (!super_type.IsNull() && !super_type.IsObjectType()) {
23352343
super_cls = cls.SuperClass();

runtime/vm/object.cc

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3386,10 +3386,7 @@ RawObject* Class::InvokeSetter(const String& setter_name,
33863386
Thread* thread = Thread::Current();
33873387
Zone* zone = thread->zone();
33883388

3389-
const Error& error = Error::Handle(zone, EnsureIsFinalized(thread));
3390-
if (!error.IsNull()) {
3391-
return error.raw();
3392-
}
3389+
CHECK_ERROR(EnsureIsFinalized(thread));
33933390

33943391
// Check for real fields and user-defined setters.
33953392
const Field& field = Field::Handle(zone, LookupStaticField(setter_name));
@@ -15314,21 +15311,21 @@ RawExternalTypedData* Bytecode::GetBinary(Zone* zone) const {
1531415311
return info.metadata_payloads();
1531515312
}
1531615313

15317-
TokenPosition Bytecode::GetTokenIndexOfPC(uword pc) const {
15314+
TokenPosition Bytecode::GetTokenIndexOfPC(uword return_address) const {
1531815315
#if defined(DART_PRECOMPILED_RUNTIME)
1531915316
UNREACHABLE();
1532015317
#else
1532115318
if (!HasSourcePositions()) {
1532215319
return TokenPosition::kNoSource;
1532315320
}
15324-
uword pc_offset = pc - PayloadStart();
15321+
uword pc_offset = return_address - PayloadStart();
1532515322
// PC could equal to bytecode size if the last instruction is Throw.
1532615323
ASSERT(pc_offset <= static_cast<uword>(Size()));
1532715324
kernel::BytecodeSourcePositionsIterator iter(Thread::Current()->zone(),
1532815325
*this);
1532915326
TokenPosition token_pos = TokenPosition::kNoSource;
1533015327
while (iter.MoveNext()) {
15331-
if (pc_offset < iter.PcOffset()) {
15328+
if (pc_offset <= iter.PcOffset()) {
1533215329
break;
1533315330
}
1533415331
token_pos = iter.TokenPos();
@@ -16170,9 +16167,11 @@ const char* UnwindError::ToCString() const {
1617016167
RawObject* Instance::InvokeGetter(const String& getter_name,
1617116168
bool respect_reflectable,
1617216169
bool check_is_entrypoint) const {
16173-
Zone* zone = Thread::Current()->zone();
16170+
Thread* thread = Thread::Current();
16171+
Zone* zone = thread->zone();
1617416172

1617516173
Class& klass = Class::Handle(zone, clazz());
16174+
CHECK_ERROR(klass.EnsureIsFinalized(thread));
1617616175
TypeArguments& type_args = TypeArguments::Handle(zone);
1617716176
if (klass.NumTypeArguments() > 0) {
1617816177
type_args = GetTypeArguments();
@@ -16228,9 +16227,11 @@ RawObject* Instance::InvokeSetter(const String& setter_name,
1622816227
const Instance& value,
1622916228
bool respect_reflectable,
1623016229
bool check_is_entrypoint) const {
16231-
Zone* zone = Thread::Current()->zone();
16230+
Thread* thread = Thread::Current();
16231+
Zone* zone = thread->zone();
1623216232

1623316233
const Class& klass = Class::Handle(zone, clazz());
16234+
CHECK_ERROR(klass.EnsureIsFinalized(thread));
1623416235
TypeArguments& type_args = TypeArguments::Handle(zone);
1623516236
if (klass.NumTypeArguments() > 0) {
1623616237
type_args = GetTypeArguments();
@@ -16273,8 +16274,10 @@ RawObject* Instance::Invoke(const String& function_name,
1627316274
const Array& arg_names,
1627416275
bool respect_reflectable,
1627516276
bool check_is_entrypoint) const {
16276-
Zone* zone = Thread::Current()->zone();
16277+
Thread* thread = Thread::Current();
16278+
Zone* zone = thread->zone();
1627716279
Class& klass = Class::Handle(zone, clazz());
16280+
CHECK_ERROR(klass.EnsureIsFinalized(thread));
1627816281
Function& function = Function::Handle(
1627916282
zone, Resolver::ResolveDynamicAnyArgs(zone, klass, function_name));
1628016283

@@ -16528,6 +16531,12 @@ RawAbstractType* Instance::GetType(Heap::Space space) const {
1652816531
return Type::NullType();
1652916532
}
1653016533
const Class& cls = Class::Handle(clazz());
16534+
if (!cls.is_finalized()) {
16535+
// Various predefined classes can be instantiated by the VM or
16536+
// Dart_NewString/Integer/TypedData/... before the class is finalized.
16537+
ASSERT(cls.is_prefinalized());
16538+
cls.EnsureDeclarationLoaded();
16539+
}
1653116540
if (cls.IsClosureClass()) {
1653216541
Function& signature =
1653316542
Function::Handle(Closure::Cast(*this).GetInstantiatedSignature(

runtime/vm/object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5726,7 +5726,7 @@ class Bytecode : public Object {
57265726

57275727
RawExternalTypedData* GetBinary(Zone* zone) const;
57285728

5729-
TokenPosition GetTokenIndexOfPC(uword pc) const;
5729+
TokenPosition GetTokenIndexOfPC(uword return_address) const;
57305730
intptr_t GetTryIndexAtPc(uword return_address) const;
57315731

57325732
intptr_t instructions_binary_offset() const {

runtime/vm/profiler_service.cc

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1615,16 +1615,13 @@ class ProfileBuilder : public ValueObject {
16151615
ASSERT(function != NULL);
16161616
const intptr_t code_index = profile_code->code_table_index();
16171617
ASSERT(profile_code != NULL);
1618-
Code& code = Code::ZoneHandle();
1619-
if (profile_code->code().IsCode()) {
1620-
code ^= profile_code->code().raw();
1621-
} else {
1622-
// No inlining in bytecode.
1623-
}
1618+
16241619
GrowableArray<const Function*>* inlined_functions = NULL;
16251620
GrowableArray<TokenPosition>* inlined_token_positions = NULL;
16261621
TokenPosition token_position = TokenPosition::kNoSource;
1627-
if (!code.IsNull()) {
1622+
Code& code = Code::ZoneHandle();
1623+
if (profile_code->code().IsCode()) {
1624+
code ^= profile_code->code().raw();
16281625
inlined_functions_cache_.Get(pc, code, sample, frame_index,
16291626
&inlined_functions, &inlined_token_positions,
16301627
&token_position);
@@ -1637,6 +1634,11 @@ class ProfileBuilder : public ValueObject {
16371634
(*inlined_token_positions)[i].ToCString());
16381635
}
16391636
}
1637+
} else if (profile_code->code().IsBytecode()) {
1638+
// No inlining in bytecode.
1639+
const Bytecode& bc = Bytecode::CheckedHandle(Thread::Current()->zone(),
1640+
profile_code->code().raw());
1641+
token_position = bc.GetTokenIndexOfPC(pc);
16401642
}
16411643

16421644
if (code.IsNull() || (inlined_functions == NULL) ||

0 commit comments

Comments
 (0)