Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(473)

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 189513003: Add alias disambiguation for VM fields. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_optimizer.cc
===================================================================
--- runtime/vm/flow_graph_optimizer.cc (revision 33416)
+++ runtime/vm/flow_graph_optimizer.cc (working copy)
@@ -4889,10 +4889,9 @@
// VMField load/stores alias each other when field offset matches.
// TODO(vegorov) storing a context variable does not alias loading array
// length.
- static Alias VMField(intptr_t offset_in_bytes) {
- ASSERT(offset_in_bytes >= 0);
- const intptr_t idx = offset_in_bytes / kWordSize;
- return Alias(kVMFieldAlias, idx);
+ static Alias VMField(intptr_t id) {
+ ASSERT(id != 0);
+ return Alias(kVMFieldAlias, id);
}
// Current context load/stores alias each other.
@@ -5264,7 +5263,9 @@
max_field_id_(0),
field_ids_(),
max_index_id_(0),
- index_ids_() { }
+ index_ids_(),
+ max_vm_field_id_(0),
+ vm_field_ids_() { }
Alias ComputeAlias(Place* place) {
switch (place->kind()) {
@@ -5280,7 +5281,8 @@
return Alias::Field(
GetInstanceFieldId(place->instance(), place->field()));
case Place::kVMField:
- return Alias::VMField(place->offset_in_bytes());
+ return Alias::VMField(
+ GetVMFieldId(place->instance(), place->offset_in_bytes()));
case Place::kContext:
return Alias::CurrentContext();
case Place::kNone:
@@ -5309,10 +5311,11 @@
if (store_instance_field != NULL) {
Definition* instance = store_instance_field->instance()->definition();
if (!store_instance_field->field().IsNull()) {
- return Alias::Field(GetInstanceFieldId(instance,
- store_instance_field->field()));
+ return Alias::Field(
+ GetInstanceFieldId(instance, store_instance_field->field()));
}
- return Alias::VMField(store_instance_field->offset_in_bytes());
+ return Alias::VMField(
+ GetVMFieldId(instance, store_instance_field->offset_in_bytes()));
}
if (instr->IsStoreContext()) {
@@ -5487,6 +5490,26 @@
return GetFieldId(instance_id, field);
}
+ intptr_t GetVMFieldId(Definition* defn, intptr_t offset) {
+ intptr_t instance_id = kAnyInstance;
+
+ if (defn != NULL) {
+ AllocateObjectInstr* alloc = defn->AsAllocateObject();
+ if ((alloc != NULL) && !CanBeAliased(alloc)) {
+ instance_id = alloc->ssa_temp_index();
+ ASSERT(instance_id != kAnyInstance);
+ }
+ }
+
+ intptr_t id = vm_field_ids_.Lookup(VMFieldIdPair::Key(instance_id, offset));
+ if (id == 0) {
+ id = ++max_vm_field_id_;
+ vm_field_ids_.Insert(
+ VMFieldIdPair(VMFieldIdPair::Key(instance_id, offset), id));
+ }
+ return id;
+ }
+
// Get or create an identifier for a static field.
intptr_t GetStaticFieldId(const Field& field) {
ASSERT(field.is_static());
@@ -5589,6 +5612,43 @@
Value value_;
};
+ class VMFieldIdPair {
+ public:
+ struct Key {
+ Key(intptr_t instance_id, intptr_t offset)
+ : instance_id_(instance_id), offset_(offset) { }
+
+ intptr_t instance_id_;
+ intptr_t offset_;
+ };
+
+ typedef intptr_t Value;
+ typedef VMFieldIdPair Pair;
+
+ VMFieldIdPair(Key key, Value value) : key_(key), value_(value) { }
+
+ static Key KeyOf(Pair kv) {
+ return kv.key_;
+ }
+
+ static Value ValueOf(Pair kv) {
+ return kv.value_;
+ }
+
+ static intptr_t Hashcode(Key key) {
+ return (key.instance_id_ + 1) * 1024 + key.offset_;
+ }
+
+ static inline bool IsKeyEqual(Pair kv, Key key) {
+ return (KeyOf(kv).offset_ == key.offset_) &&
+ (KeyOf(kv).instance_id_ == key.instance_id_);
+ }
+
+ private:
+ Key key_;
+ Value value_;
+ };
+
const ZoneGrowableArray<Place*>& places_;
const PhiPlaceMoves* phi_moves_;
@@ -5605,6 +5665,9 @@
intptr_t max_index_id_;
DirectChainedHashMap<IndexIdPair> index_ids_;
+
+ intptr_t max_vm_field_id_;
+ DirectChainedHashMap<VMFieldIdPair> vm_field_ids_;
};
@@ -8556,9 +8619,9 @@
}
-// Add the given field to the list of fields if it is not yet present there.
-static void AddField(ZoneGrowableArray<const Field*>* fields,
- const Field& field) {
+// Add a field/offset to the list of fields if it is not yet present there.
+static void AddField(ZoneGrowableArray<const Object*>* fields,
+ const Object& field) {
for (intptr_t i = 0; i < fields->length(); i++) {
if ((*fields)[i]->raw() == field.raw()) {
return;
@@ -8588,16 +8651,19 @@
Instruction* exit,
AllocateObjectInstr* alloc,
const Class& cls,
- const ZoneGrowableArray<const Field*>& fields) {
+ const ZoneGrowableArray<const Object*>& fields) {
ZoneGrowableArray<Value*>* values =
new ZoneGrowableArray<Value*>(fields.length());
// Insert load instruction for every field.
for (intptr_t i = 0; i < fields.length(); i++) {
- const Field* field = fields[i];
- LoadFieldInstr* load = new LoadFieldInstr(new Value(alloc),
- field,
- AbstractType::ZoneHandle());
+ LoadFieldInstr* load = fields[i]->IsField()
+ ? new LoadFieldInstr(new Value(alloc),
+ &Field::Cast(*fields[i]),
+ AbstractType::ZoneHandle())
+ : new LoadFieldInstr(new Value(alloc),
+ Smi::Cast(*fields[i]).Value(),
+ AbstractType::ZoneHandle());
flow_graph_->InsertBefore(
exit, load, NULL, Definition::kValue);
values->Add(new Value(load));
@@ -8628,29 +8694,24 @@
void AllocationSinking::InsertMaterializations(AllocateObjectInstr* alloc) {
// Collect all fields that are written for this instance.
- ZoneGrowableArray<const Field*>* fields =
- new ZoneGrowableArray<const Field*>(5);
+ ZoneGrowableArray<const Object*>* fields =
+ new ZoneGrowableArray<const Object*>(5);
for (Value* use = alloc->input_use_list();
use != NULL;
use = use->next_use()) {
- ASSERT(use->instruction()->IsStoreInstanceField());
- AddField(fields, use->instruction()->AsStoreInstanceField()->field());
+ StoreInstanceFieldInstr* store = use->instruction()->AsStoreInstanceField();
+ if (!store->field().IsNull()) {
+ AddField(fields, store->field());
+ } else {
+ AddField(fields, Smi::ZoneHandle(Smi::New(store->offset_in_bytes())));
+ }
}
if (alloc->ArgumentCount() > 0) {
ASSERT(alloc->ArgumentCount() == 1);
- const String& name = String::Handle(Symbols::New(":type_args"));
- const Field& type_args_field =
- Field::ZoneHandle(Field::New(
- name,
- false, // !static
- false, // !final
- false, // !const
- alloc->cls(),
- 0)); // No token position.
- type_args_field.SetOffset(alloc->cls().type_arguments_field_offset());
- AddField(fields, type_args_field);
+ intptr_t type_args_offset = alloc->cls().type_arguments_field_offset();
+ AddField(fields, Smi::ZoneHandle(Smi::New(type_args_offset)));
}
// Collect all instructions that mention this object in the environment.

Powered by Google App Engine
This is Rietveld 408576698