[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:
Zichang Guo 2019-03-07 02:04:41 +00:00 committed by commit-bot@chromium.org
parent 253499fe68
commit 4ec72c1eb1
12 changed files with 37 additions and 39 deletions

View file

@ -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

View file

@ -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_);
}

View file

@ -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);
}
}

View file

@ -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());
}

View file

@ -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();
}

View file

@ -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 {

View file

@ -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.

View file

@ -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_);
}
}

View file

@ -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:

View file

@ -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_) \

View file

@ -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) {

View file

@ -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) {}