mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:44:27 +00:00
[vm/concurrency] Remove usage of current isolate field state from compiler
As part of making the compiler independent of the current isolate (since JITed code will be shared across all isolate) we make the compiler not depend on global field state, with one exception: we preserve an existing optimization that utilizes knowledge whether a global final field was already initialized (if --enable-isolate-groups is turned off) - we do so by asking the isolate group for it's own isolate member. Issue https://github.com/dart-lang/sdk/issues/36097 TEST=Refactoring of existing code. Change-Id: I2f08d854af6102e05e5a1df8d5b66b514d6f3ce4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182540 Commit-Queue: Martin Kustermann <kustermann@google.com> Reviewed-by: Alexander Aprelev <aam@google.com> Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
parent
6ce8d74761
commit
5f78a23bb9
6 changed files with 31 additions and 29 deletions
|
@ -854,8 +854,8 @@ void ConstantPropagator::VisitLoadStaticField(LoadStaticFieldInstr* instr) {
|
|||
if (!FLAG_fields_may_be_reset) {
|
||||
const Field& field = instr->field();
|
||||
ASSERT(field.is_static());
|
||||
if (field.is_final() && instr->IsFieldInitialized()) {
|
||||
Instance& obj = Instance::Handle(Z, field.StaticValue());
|
||||
auto& obj = Instance::Handle(Z);
|
||||
if (field.is_final() && instr->IsFieldInitialized(&obj)) {
|
||||
if (obj.IsSmi() || (obj.IsOld() && obj.IsCanonical())) {
|
||||
SetValue(instr, obj);
|
||||
return;
|
||||
|
|
|
@ -1135,10 +1135,32 @@ bool LoadStaticFieldInstr::AttributesEqual(Instruction* other) const {
|
|||
return field().ptr() == other->AsLoadStaticField()->field().ptr();
|
||||
}
|
||||
|
||||
bool LoadStaticFieldInstr::IsFieldInitialized() const {
|
||||
bool LoadStaticFieldInstr::IsFieldInitialized(Instance* field_value) const {
|
||||
if (FLAG_fields_may_be_reset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Since new isolates will be spawned, the JITed code cannot depend on whether
|
||||
// global field was initialized when running with --enable-isolate-groups.
|
||||
if (IsolateGroup::AreIsolateGroupsEnabled()) return false;
|
||||
|
||||
const Field& field = this->field();
|
||||
return (field.StaticValue() != Object::sentinel().ptr()) &&
|
||||
(field.StaticValue() != Object::transition_sentinel().ptr());
|
||||
Isolate* only_isolate = IsolateGroup::Current()->FirstIsolate();
|
||||
if (only_isolate == nullptr) {
|
||||
// This can happen if background compiler executes this code but the mutator
|
||||
// is being shutdown and the isolate was already unregistered from the group
|
||||
// (and is trying to stop this BG compiler).
|
||||
if (field_value != nullptr) {
|
||||
*field_value = Object::sentinel().ptr();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (field_value == nullptr) {
|
||||
field_value = &Instance::Handle();
|
||||
}
|
||||
*field_value = only_isolate->field_table()->At(field.field_id());
|
||||
return (field_value->ptr() != Object::sentinel().ptr()) &&
|
||||
(field_value->ptr() != Object::transition_sentinel().ptr());
|
||||
}
|
||||
|
||||
Definition* LoadStaticFieldInstr::Canonicalize(FlowGraph* flow_graph) {
|
||||
|
@ -1146,8 +1168,7 @@ Definition* LoadStaticFieldInstr::Canonicalize(FlowGraph* flow_graph) {
|
|||
// make it safe to omit code that checks if the field needs initialization
|
||||
// because the field will be reset so it starts uninitialized in the process
|
||||
// running the precompiled code. We must be prepared to reinitialize fields.
|
||||
if (calls_initializer() && !FLAG_fields_may_be_reset &&
|
||||
IsFieldInitialized()) {
|
||||
if (calls_initializer() && IsFieldInitialized()) {
|
||||
set_calls_initializer(false);
|
||||
}
|
||||
return this;
|
||||
|
|
|
@ -5543,7 +5543,7 @@ class LoadStaticFieldInstr : public TemplateDefinition<0, Throws> {
|
|||
virtual CompileType ComputeType() const;
|
||||
|
||||
const Field& field() const { return field_; }
|
||||
bool IsFieldInitialized() const;
|
||||
bool IsFieldInitialized(Instance* field_value = nullptr) const;
|
||||
|
||||
bool calls_initializer() const { return calls_initializer_; }
|
||||
void set_calls_initializer(bool value) { calls_initializer_ = value; }
|
||||
|
|
|
@ -1446,9 +1446,9 @@ CompileType LoadStaticFieldInstr::ComputeType() const {
|
|||
AbstractType* abstract_type = &AbstractType::ZoneHandle(field.type());
|
||||
TraceStrongModeType(this, *abstract_type);
|
||||
ASSERT(field.is_static());
|
||||
const bool is_initialized = IsFieldInitialized() && !FLAG_fields_may_be_reset;
|
||||
auto& obj = Instance::Handle();
|
||||
const bool is_initialized = IsFieldInitialized(&obj);
|
||||
if (field.is_final() && is_initialized) {
|
||||
const Instance& obj = Instance::Handle(field.StaticValue());
|
||||
if (!obj.IsNull()) {
|
||||
is_nullable = CompileType::kNonNullable;
|
||||
cid = obj.GetClassId();
|
||||
|
|
|
@ -70,20 +70,6 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraphOfFieldInitializer() {
|
|||
B->last_used_block_id_, prologue_info);
|
||||
}
|
||||
|
||||
void StreamingFlowGraphBuilder::EvaluateConstFieldValue(const Field& field) {
|
||||
ASSERT(field.is_const() && field.IsUninitialized());
|
||||
|
||||
FieldHelper field_helper(this);
|
||||
field_helper.ReadUntilExcluding(FieldHelper::kInitializer);
|
||||
Tag initializer_tag = ReadTag(); // read first part of initializer.
|
||||
|
||||
ASSERT(initializer_tag == kSomething);
|
||||
|
||||
Instance& value =
|
||||
Instance::Handle(Z, constant_reader_.ReadConstantExpression());
|
||||
field.SetStaticValue(value);
|
||||
}
|
||||
|
||||
void StreamingFlowGraphBuilder::SetupDefaultParameterValues() {
|
||||
intptr_t optional_parameter_count =
|
||||
parsed_function()->function().NumOptionalParameters();
|
||||
|
@ -1024,10 +1010,6 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraph() {
|
|||
case UntaggedFunction::kImplicitGetter:
|
||||
case UntaggedFunction::kImplicitStaticGetter:
|
||||
case UntaggedFunction::kImplicitSetter: {
|
||||
const Field& field = Field::Handle(Z, function.accessor_field());
|
||||
if (field.is_const() && field.IsUninitialized()) {
|
||||
EvaluateConstFieldValue(field);
|
||||
}
|
||||
return B->BuildGraphOfFieldAccessor(function);
|
||||
}
|
||||
case UntaggedFunction::kFieldInitializer:
|
||||
|
|
|
@ -59,7 +59,6 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper {
|
|||
|
||||
void ParseKernelASTFunction();
|
||||
void ReadForwardingStubTarget(const Function& function);
|
||||
void EvaluateConstFieldValue(const Field& field);
|
||||
void SetupDefaultParameterValues();
|
||||
|
||||
FlowGraph* BuildGraphOfFieldInitializer();
|
||||
|
|
Loading…
Reference in a new issue