Save Initializer for field and pass into debugger to enable breakpoint setting.

Change-Id: I9f7afcdd057f161873d3c6e47cb0ce171806f301
Reviewed-on: https://dart-review.googlesource.com/c/91120
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Zichang Guo <zichangguo@google.com>
This commit is contained in:
Zichang Guo
2019-02-06 03:20:35 +00:00
committed by commit-bot@chromium.org
parent 631c550ff9
commit 7e81f56ad7
10 changed files with 64 additions and 61 deletions
@@ -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 9
// during the training run and 10 when running from the snapshot.
expect(((numRanges == 9) || (numRanges == 10)), isTrue);
// 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);
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 + 2);
expect(coverage['ranges'].length, numRanges + 3);
expect(allRangesCompiled(coverage), isTrue);
// One function
@@ -31,6 +31,7 @@ List<String> expected = [
"$file:${LINE+0}:5", // after 'code'
"$file:${LINE+1}:11", // on switchOnMe
"$file:${LINE+17}:27", // on switchOnMe initializer starting '['
"$file:${LINE+1}:22", // on length
"$file:${LINE+2}:10", // on 0
+10 -11
View File
@@ -876,16 +876,16 @@ class FieldSerializationCluster : public SerializationCluster {
s->Push(field->ptr()->value_.static_value_);
} else {
// Otherwise, for static fields we write out the initial static value.
s->Push(field->ptr()->initializer_.saved_value_);
s->Push(field->ptr()->saved_initial_value_);
}
} else {
s->Push(field->ptr()->value_.offset_);
}
// Write out the initializer function or saved initial value.
if (kind == Snapshot::kFullAOT) {
s->Push(field->ptr()->initializer_.precompiled_);
} else {
s->Push(field->ptr()->initializer_.saved_value_);
// Write out the initializer function
s->Push(field->ptr()->initializer_);
if (kind != Snapshot::kFullAOT) {
// Write out the saved initial value
s->Push(field->ptr()->saved_initial_value_);
}
if (kind != Snapshot::kFullAOT) {
// Write out the guarded list length.
@@ -927,16 +927,15 @@ class FieldSerializationCluster : public SerializationCluster {
WriteField(field, value_.static_value_);
} else {
// Otherwise, for static fields we write out the initial static value.
WriteField(field, initializer_.saved_value_);
WriteField(field, saved_initial_value_);
}
} else {
WriteField(field, value_.offset_);
}
// Write out the initializer function or saved initial value.
if (kind == Snapshot::kFullAOT) {
WriteField(field, initializer_.precompiled_);
} else {
WriteField(field, initializer_.saved_value_);
WriteField(field, initializer_);
if (kind != Snapshot::kFullAOT) {
WriteField(field, saved_initial_value_);
}
if (kind != Snapshot::kFullAOT) {
// Write out the guarded list length.
+3 -3
View File
@@ -878,8 +878,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.HasPrecompiledInitializer() ||
!Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) {
if (!field.HasInitializer() ||
!Function::Handle(Z, field.Initializer()).HasCode()) {
if (FLAG_trace_precompiler) {
THR_Print("Precompiling initializer for %s\n", field.ToCString());
}
@@ -891,7 +891,7 @@ void Precompiler::AddField(const Field& field) {
const Function& initializer =
Function::Handle(Z, CompileStaticInitializer(field));
ASSERT(!initializer.IsNull());
field.SetPrecompiledInitializer(initializer);
field.SetInitializer(initializer);
AddCalleesOf(initializer, gop_offset);
}
}
+19 -17
View File
@@ -700,6 +700,19 @@ RawCode* CompileParsedFunctionHelper::Compile(CompilationPipeline* pipeline) {
}
}
}
if (!result->IsNull()) {
#if !defined(PRODUCT)
if (!function.HasOptimizedCode()) {
isolate()->debugger()->NotifyCompilation(function);
}
#endif
if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
Disassembler::DisassembleCode(function, *result, optimized());
} else if (FLAG_disassemble_optimized && optimized() &&
FlowGraphPrinter::ShouldPrint(function)) {
Disassembler::DisassembleCode(function, *result, true);
}
}
// Exit the loop and the function with the correct result value.
done = true;
} else {
@@ -874,17 +887,6 @@ static RawObject* CompileFunctionHelper(CompilationPipeline* pipeline,
per_compile_timer.TotalElapsedTime());
}
#if !defined(PRODUCT)
isolate->debugger()->NotifyCompilation(function);
#endif
if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
Disassembler::DisassembleCode(function, result, optimized);
} else if (FLAG_disassemble_optimized && optimized &&
FlowGraphPrinter::ShouldPrint(function)) {
Disassembler::DisassembleCode(function, result, true);
}
return result.raw();
} else {
Thread* const thread = Thread::Current();
@@ -1193,9 +1195,10 @@ RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
ASSERT(thread->IsMutatorThread());
NoOOBMessageScope no_msg_scope(thread);
NoReloadScope no_reload_scope(thread->isolate(), thread);
// Under lazy compilation initializer has not yet been created, so create
// it now, but don't bother remembering it because it won't be used again.
ASSERT(!field.HasPrecompiledInitializer());
if (field.HasInitializer()) {
const Function& initializer = Function::Handle(field.Initializer());
return DartEntry::InvokeFunction(initializer, Object::empty_array());
}
{
#if defined(SUPPORT_TIMELINE)
VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
@@ -1698,9 +1701,8 @@ RawError* Compiler::CompileAllFunctions(const Class& cls) {
}
RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
ASSERT(field.HasPrecompiledInitializer());
const Function& initializer =
Function::Handle(field.PrecompiledInitializer());
ASSERT(field.HasInitializer());
const Function& initializer = Function::Handle(field.Initializer());
return DartEntry::InvokeFunction(initializer, Object::empty_array());
}
+6 -1
View File
@@ -2123,6 +2123,9 @@ RawFunction::Kind KernelLoader::GetFunctionType(
RawFunction* CreateFieldInitializerFunction(Thread* thread,
Zone* zone,
const Field& field) {
if (field.Initializer() != Function::null()) {
return field.Initializer();
}
String& init_name = String::Handle(zone, field.name());
init_name = Symbols::FromConcat(thread, Symbols::InitPrefix(), init_name);
@@ -2155,9 +2158,11 @@ RawFunction* CreateFieldInitializerFunction(Thread* thread,
initializer_owner, TokenPosition::kNoSource));
initializer_fun.set_kernel_offset(field.kernel_offset());
initializer_fun.set_result_type(AbstractType::Handle(zone, field.type()));
initializer_fun.set_is_debuggable(false);
initializer_fun.set_is_reflectable(false);
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);
return initializer_fun.raw();
}
+4 -5
View File
@@ -8481,14 +8481,13 @@ bool Field::IsUninitialized() const {
return value.raw() == Object::sentinel().raw();
}
void Field::SetPrecompiledInitializer(const Function& initializer) const {
void Field::SetInitializer(const Function& initializer) const {
ASSERT(IsOriginal());
StorePointer(&raw_ptr()->initializer_.precompiled_, initializer.raw());
StorePointer(&raw_ptr()->initializer_, initializer.raw());
}
bool Field::HasPrecompiledInitializer() const {
return raw_ptr()->initializer_.precompiled_->IsHeapObject() &&
raw_ptr()->initializer_.precompiled_->IsFunction();
bool Field::HasInitializer() const {
return raw_ptr()->initializer_ != Function::null();
}
RawError* Field::EvaluateInitializer() const {
+6 -7
View File
@@ -3354,11 +3354,9 @@ class Field : public Object {
DART_WARN_UNUSED_RESULT RawError* EvaluateInitializer() const;
RawFunction* PrecompiledInitializer() const {
return raw_ptr()->initializer_.precompiled_;
}
void SetPrecompiledInitializer(const Function& initializer) const;
bool HasPrecompiledInitializer() const;
RawFunction* Initializer() const { return raw_ptr()->initializer_; }
void SetInitializer(const Function& initializer) const;
bool HasInitializer() const;
// For static fields only. Constructs a closure that gets/sets the
// field value.
@@ -9149,8 +9147,9 @@ void Field::SetStaticValue(const Instance& value,
ASSERT(is_static()); // Valid only for static dart fields.
StorePointer(&raw_ptr()->value_.static_value_, value.raw());
if (save_initial_value) {
ASSERT(!HasPrecompiledInitializer());
StorePointer(&raw_ptr()->initializer_.saved_value_, value.raw());
#if !defined(DART_PRECOMPILED_RUNTIME)
StorePointer(&raw_ptr()->saved_initial_value_, value.raw());
#endif
}
}
+4 -4
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_.HasPrecompiledInitializer()) {
function_ ^= field_.PrecompiledInitializer();
if (field_.is_static() && field_.HasInitializer()) {
function_ ^= field_.Initializer();
visitor_->Visit(function_);
}
}
@@ -885,7 +885,7 @@ void ProgramVisitor::DedupInstructionsWithSameMetadata() {
ProgramVisitor::VisitFunctions(&visitor);
#endif // defined(DART_PRECOMPILER)
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
#endif // !defined(DART_PRECOMPILED_RUNTIME)
void ProgramVisitor::Dedup() {
#if !defined(DART_PRECOMPILED_RUNTIME)
@@ -912,7 +912,7 @@ void ProgramVisitor::Dedup() {
DedupInstructions();
}
#endif
#endif // !defined(DART_PRECOMPILED_RUNTIME)
#endif // !defined(DART_PRECOMPILED_RUNTIME)
}
} // namespace dart
+7 -9
View File
@@ -1013,15 +1013,13 @@ class RawField : public RawObject {
RawInstance* static_value_; // Value for static fields.
RawSmi* offset_; // Offset in words for instance fields.
} value_;
union {
// When precompiling we need to save the static initializer function here
// so that code for it can be generated.
RawFunction* precompiled_; // Static initializer function - precompiling.
// When generating script 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.
RawInstance* saved_value_; // Saved initial value - static fields.
} initializer_;
RawFunction* initializer_; // 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.
NOT_IN_PRECOMPILED(
RawInstance*
saved_initial_value_); // Saved initial value - static fields.
RawSmi* guarded_list_length_;
RawArray* dependent_code_;
RawObject** to_snapshot(Snapshot::Kind kind) {