mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
[VM-Runtime]Fix source report coverage to not include field without function initializer
Fix issue created by 89173. Also rename HasInitializer to HasInitializerFunction to distinguish from has_initializer. Bug= https://github.com/flutter/flutter/issues/28542 Change-Id: Id9f898937c2f4f350a6d619019dc12611505801f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/95680 Reviewed-by: Siva Annamalai <asiva@google.com> Commit-Queue: Zichang Guo <zichangguo@google.com>
This commit is contained in:
parent
253499fe68
commit
4ec72c1eb1
|
@ -91,9 +91,9 @@ var tests = <IsolateTest>[
|
|||
final numRanges = coverage['ranges'].length;
|
||||
expect(coverage['type'], equals('SourceReport'));
|
||||
|
||||
// Running in app_jitk mode will result in the number of ranges being 10
|
||||
// during the training run and 11 when running from the snapshot.
|
||||
expect(((numRanges == 10) || (numRanges == 11)), isTrue);
|
||||
// Running in app_jitk mode will result in the number of ranges being 9
|
||||
// during the training run and 10 when running from the snapshot.
|
||||
expect(((numRanges == 9) || (numRanges == 10)), isTrue);
|
||||
expect(coverage['ranges'][0], equals(expectedRange));
|
||||
expect(coverage['scripts'].length, 1);
|
||||
expect(
|
||||
|
@ -108,7 +108,7 @@ var tests = <IsolateTest>[
|
|||
};
|
||||
coverage = await isolate.invokeRpcNoUpgrade('getSourceReport', params);
|
||||
expect(coverage['type'], equals('SourceReport'));
|
||||
expect(coverage['ranges'].length, numRanges + 3);
|
||||
expect(coverage['ranges'].length, numRanges + 2);
|
||||
expect(allRangesCompiled(coverage), isTrue);
|
||||
|
||||
// One function
|
||||
|
|
|
@ -866,7 +866,7 @@ class FieldSerializationCluster : public SerializationCluster {
|
|||
s->Push(field->ptr()->value_.offset_);
|
||||
}
|
||||
// Write out the initializer function
|
||||
s->Push(field->ptr()->initializer_);
|
||||
s->Push(field->ptr()->initializer_function_);
|
||||
if (kind != Snapshot::kFullAOT) {
|
||||
// Write out the saved initial value
|
||||
s->Push(field->ptr()->saved_initial_value_);
|
||||
|
@ -916,8 +916,8 @@ class FieldSerializationCluster : public SerializationCluster {
|
|||
} else {
|
||||
WriteField(field, value_.offset_);
|
||||
}
|
||||
// Write out the initializer function or saved initial value.
|
||||
WriteField(field, initializer_);
|
||||
// Write out the initializer function and initial value if not in AOT.
|
||||
WriteField(field, initializer_function_);
|
||||
if (kind != Snapshot::kFullAOT) {
|
||||
WriteField(field, saved_initial_value_);
|
||||
}
|
||||
|
|
|
@ -864,8 +864,8 @@ void Precompiler::AddField(const Field& field) {
|
|||
// Should not be in the middle of initialization while precompiling.
|
||||
ASSERT(value.raw() != Object::transition_sentinel().raw());
|
||||
|
||||
if (!field.HasInitializer() ||
|
||||
!Function::Handle(Z, field.Initializer()).HasCode()) {
|
||||
if (!field.HasInitializerFunction() ||
|
||||
!Function::Handle(Z, field.InitializerFunction()).HasCode()) {
|
||||
if (FLAG_trace_precompiler) {
|
||||
THR_Print("Precompiling initializer for %s\n", field.ToCString());
|
||||
}
|
||||
|
@ -877,7 +877,7 @@ void Precompiler::AddField(const Field& field) {
|
|||
const Function& initializer =
|
||||
Function::Handle(Z, CompileStaticInitializer(field));
|
||||
ASSERT(!initializer.IsNull());
|
||||
field.SetInitializer(initializer);
|
||||
field.SetInitializerFunction(initializer);
|
||||
AddCalleesOf(initializer, gop_offset);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1200,8 +1200,9 @@ RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
|
|||
ASSERT(thread->IsMutatorThread());
|
||||
NoOOBMessageScope no_msg_scope(thread);
|
||||
NoReloadScope no_reload_scope(thread->isolate(), thread);
|
||||
if (field.HasInitializer()) {
|
||||
const Function& initializer = Function::Handle(field.Initializer());
|
||||
if (field.HasInitializerFunction()) {
|
||||
const Function& initializer =
|
||||
Function::Handle(field.InitializerFunction());
|
||||
return DartEntry::InvokeFunction(initializer, Object::empty_array());
|
||||
}
|
||||
{
|
||||
|
@ -1706,8 +1707,8 @@ RawError* Compiler::CompileAllFunctions(const Class& cls) {
|
|||
}
|
||||
|
||||
RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
|
||||
ASSERT(field.HasInitializer());
|
||||
const Function& initializer = Function::Handle(field.Initializer());
|
||||
ASSERT(field.HasInitializerFunction());
|
||||
const Function& initializer = Function::Handle(field.InitializerFunction());
|
||||
return DartEntry::InvokeFunction(initializer, Object::empty_array());
|
||||
}
|
||||
|
||||
|
|
|
@ -2209,8 +2209,8 @@ RawFunction::Kind KernelLoader::GetFunctionType(
|
|||
RawFunction* CreateFieldInitializerFunction(Thread* thread,
|
||||
Zone* zone,
|
||||
const Field& field) {
|
||||
if (field.Initializer() != Function::null()) {
|
||||
return field.Initializer();
|
||||
if (field.InitializerFunction() != Function::null()) {
|
||||
return field.InitializerFunction();
|
||||
}
|
||||
String& init_name = String::Handle(zone, field.name());
|
||||
init_name = Symbols::FromConcat(thread, Symbols::InitPrefix(), init_name);
|
||||
|
@ -2248,7 +2248,7 @@ RawFunction* CreateFieldInitializerFunction(Thread* thread,
|
|||
initializer_fun.set_is_inlinable(false);
|
||||
initializer_fun.set_token_pos(field.token_pos());
|
||||
initializer_fun.set_end_token_pos(field.end_token_pos());
|
||||
field.SetInitializer(initializer_fun);
|
||||
field.SetInitializerFunction(initializer_fun);
|
||||
return initializer_fun.raw();
|
||||
}
|
||||
|
||||
|
|
|
@ -8584,13 +8584,13 @@ bool Field::IsUninitialized() const {
|
|||
return value.raw() == Object::sentinel().raw();
|
||||
}
|
||||
|
||||
void Field::SetInitializer(const Function& initializer) const {
|
||||
void Field::SetInitializerFunction(const Function& initializer) const {
|
||||
ASSERT(IsOriginal());
|
||||
StorePointer(&raw_ptr()->initializer_, initializer.raw());
|
||||
StorePointer(&raw_ptr()->initializer_function_, initializer.raw());
|
||||
}
|
||||
|
||||
bool Field::HasInitializer() const {
|
||||
return raw_ptr()->initializer_ != Function::null();
|
||||
bool Field::HasInitializerFunction() const {
|
||||
return raw_ptr()->initializer_function_ != Function::null();
|
||||
}
|
||||
|
||||
RawError* Field::EvaluateInitializer() const {
|
||||
|
|
|
@ -3265,9 +3265,11 @@ class Field : public Object {
|
|||
|
||||
DART_WARN_UNUSED_RESULT RawError* EvaluateInitializer() const;
|
||||
|
||||
RawFunction* Initializer() const { return raw_ptr()->initializer_; }
|
||||
void SetInitializer(const Function& initializer) const;
|
||||
bool HasInitializer() const;
|
||||
RawFunction* InitializerFunction() const {
|
||||
return raw_ptr()->initializer_function_;
|
||||
}
|
||||
void SetInitializerFunction(const Function& initializer) const;
|
||||
bool HasInitializerFunction() const;
|
||||
|
||||
// For static fields only. Constructs a closure that gets/sets the
|
||||
// field value.
|
||||
|
|
|
@ -81,8 +81,8 @@ class ClassFunctionVisitor : public ClassVisitor {
|
|||
fields_ = cls.fields();
|
||||
for (intptr_t j = 0; j < fields_.Length(); j++) {
|
||||
field_ ^= fields_.At(j);
|
||||
if (field_.is_static() && field_.HasInitializer()) {
|
||||
function_ ^= field_.Initializer();
|
||||
if (field_.is_static() && field_.HasInitializerFunction()) {
|
||||
function_ ^= field_.InitializerFunction();
|
||||
visitor_->Visit(function_);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1051,7 +1051,7 @@ class RawField : public RawObject {
|
|||
RawInstance* static_value_; // Value for static fields.
|
||||
RawSmi* offset_; // Offset in words for instance fields.
|
||||
} value_;
|
||||
RawFunction* initializer_; // Static initializer function.
|
||||
RawFunction* initializer_function_; // Static initializer function.
|
||||
// When generating APPJIT snapshots after running the application it is
|
||||
// necessary to save the initial value of static fields so that we can
|
||||
// restore the value back to the original initial value.
|
||||
|
@ -1067,7 +1067,7 @@ class RawField : public RawObject {
|
|||
case Snapshot::kFullJIT:
|
||||
return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
|
||||
case Snapshot::kFullAOT:
|
||||
return reinterpret_cast<RawObject**>(&ptr()->initializer_);
|
||||
return reinterpret_cast<RawObject**>(&ptr()->initializer_function_);
|
||||
case Snapshot::kMessage:
|
||||
case Snapshot::kNone:
|
||||
case Snapshot::kInvalid:
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace dart {
|
|||
F(Field, guarded_list_length_) \
|
||||
F(Field, dependent_code_) \
|
||||
F(Field, type_test_cache_) \
|
||||
F(Field, initializer_) \
|
||||
F(Field, initializer_function_) \
|
||||
F(Script, url_) \
|
||||
F(Script, resolved_url_) \
|
||||
F(Script, compile_time_constants_) \
|
||||
|
|
|
@ -491,16 +491,12 @@ void SourceReport::VisitFunction(JSONArray* jsarr, const Function& func) {
|
|||
}
|
||||
|
||||
void SourceReport::VisitField(JSONArray* jsarr, const Field& field) {
|
||||
if (ShouldSkipField(field) || !field.has_initializer()) return;
|
||||
const Function& func =
|
||||
Function::Handle(zone(), GetInitializerFunction(field));
|
||||
VisitFunction(jsarr, func);
|
||||
}
|
||||
|
||||
RawFunction* SourceReport::GetInitializerFunction(const Field& field) {
|
||||
if (ShouldSkipField(field) || !field.HasInitializerFunction()) return;
|
||||
Thread* const thread = Thread::Current();
|
||||
// Create a function to evaluate the initializer
|
||||
return kernel::CreateFieldInitializerFunction(thread, thread->zone(), field);
|
||||
const Function& func = Function::Handle(
|
||||
zone(),
|
||||
kernel::CreateFieldInitializerFunction(thread, thread->zone(), field));
|
||||
VisitFunction(jsarr, func);
|
||||
}
|
||||
|
||||
void SourceReport::VisitLibrary(JSONArray* jsarr, const Library& lib) {
|
||||
|
|
|
@ -86,7 +86,6 @@ class SourceReport {
|
|||
void VisitField(JSONArray* jsarr, const Field& field);
|
||||
void VisitLibrary(JSONArray* jsarr, const Library& lib);
|
||||
void VisitClosures(JSONArray* jsarr);
|
||||
RawFunction* GetInitializerFunction(const Field& field);
|
||||
// An entry in the script table.
|
||||
struct ScriptTableEntry {
|
||||
ScriptTableEntry() : key(NULL), index(-1), script(NULL) {}
|
||||
|
|
Loading…
Reference in a new issue