Revision: 20831
Author: [email protected]
Date: Thu Apr 17 08:22:22 2014 UTC
Log: Track up to 5 stable maps as field type.
[email protected]
Review URL: https://codereview.chromium.org/240813002
http://code.google.com/p/v8/source/detail?r=20831
Modified:
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/arm64/stub-cache-arm64.cc
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/objects-debug.cc
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/types.cc
/branches/bleeding_edge/src/types.h
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed Apr 16 16:16:37
2014 UTC
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Thu Apr 17 08:22:22
2014 UTC
@@ -430,13 +430,22 @@
} else if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = descriptors->GetFieldType(descriptor);
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current(), &do_store);
+ it.Advance();
+ if (it.Done()) {
+ __ b(ne, miss_label);
+ break;
+ }
+ __ b(eq, &do_store);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
Label do_store, heap_number;
@@ -599,13 +608,22 @@
if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = lookup->GetFieldType();
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current(), &do_store);
+ it.Advance();
+ if (it.Done()) {
+ __ b(ne, miss_label);
+ break;
+ }
+ __ b(eq, &do_store);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
// Load the double storage.
=======================================
--- /branches/bleeding_edge/src/arm64/stub-cache-arm64.cc Wed Apr 16
16:16:37 2014 UTC
+++ /branches/bleeding_edge/src/arm64/stub-cache-arm64.cc Thu Apr 17
08:22:22 2014 UTC
@@ -392,13 +392,22 @@
} else if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = descriptors->GetFieldType(descriptor);
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ B(ne, miss_label);
+ break;
+ }
+ __ B(eq, &do_store);
+ }
+ __ Bind(&do_store);
}
} else if (representation.IsDouble()) {
UseScratchRegisterScope temps(masm);
@@ -548,13 +557,22 @@
if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = lookup->GetFieldType();
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, scratch1, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ __ Ldr(scratch1, FieldMemOperand(value_reg, HeapObject::kMapOffset));
+ Label do_store;
+ while (true) {
+ __ CompareMap(scratch1, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ B(ne, miss_label);
+ break;
+ }
+ __ B(eq, &do_store);
+ }
+ __ Bind(&do_store);
}
} else if (representation.IsDouble()) {
UseScratchRegisterScope temps(masm);
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Wed Apr 16 16:16:37
2014 UTC
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Apr 17 08:22:22
2014 UTC
@@ -528,13 +528,21 @@
} else if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = descriptors->GetFieldType(descriptor);
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
Label do_store, heap_number;
@@ -705,13 +713,21 @@
if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = lookup->GetFieldType();
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
// Load the double storage.
=======================================
--- /branches/bleeding_edge/src/objects-debug.cc Wed Apr 16 21:19:25 2014
UTC
+++ /branches/bleeding_edge/src/objects-debug.cc Thu Apr 17 08:22:22 2014
UTC
@@ -300,13 +300,10 @@
if (r.IsSmi()) ASSERT(value->IsSmi());
if (r.IsHeapObject()) ASSERT(value->IsHeapObject());
HeapType* field_type = descriptors->GetFieldType(i);
- if (field_type->IsClass()) {
- Map* map = *field_type->AsClass()->Map();
- CHECK(!map->is_stable() || HeapObject::cast(value)->map() ==
map);
- } else if (r.IsNone()) {
+ if (r.IsNone()) {
CHECK(field_type->Is(HeapType::None()));
- } else {
- CHECK(HeapType::Any()->Is(field_type));
+ } else if (!HeapType::Any()->Is(field_type)) {
+ CHECK(!field_type->NowStable() ||
field_type->NowContains(value));
}
}
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Wed Apr 16 21:19:25 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Thu Apr 17 08:22:22 2014 UTC
@@ -63,15 +63,16 @@
Handle<HeapType> Object::OptimalType(Isolate* isolate,
Representation representation) {
- if (!FLAG_track_field_types) return HeapType::Any(isolate);
- if (representation.IsNone()) return HeapType::None(isolate);
- if (representation.IsHeapObject() && IsHeapObject()) {
- // We can track only JavaScript objects with stable maps.
- Handle<Map> map(HeapObject::cast(this)->map(), isolate);
- if (map->is_stable() &&
- map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
- map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) {
- return HeapType::Class(map, isolate);
+ if (FLAG_track_field_types) {
+ if (representation.IsNone()) return HeapType::None(isolate);
+ if (representation.IsHeapObject() && IsHeapObject()) {
+ // We can track only JavaScript objects with stable maps.
+ Handle<Map> map(HeapObject::cast(this)->map(), isolate);
+ if (map->is_stable() &&
+ map->instance_type() >= FIRST_NONCALLABLE_SPEC_OBJECT_TYPE &&
+ map->instance_type() <= LAST_NONCALLABLE_SPEC_OBJECT_TYPE) {
+ return HeapType::Class(map, isolate);
+ }
}
}
return HeapType::Any(isolate);
@@ -2526,11 +2527,21 @@
// static
-Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> old_field_type,
- Handle<HeapType> new_field_type,
+Handle<HeapType> Map::GeneralizeFieldType(Handle<HeapType> type1,
+ Handle<HeapType> type2,
Isolate* isolate) {
- if (new_field_type->NowIs(old_field_type)) return old_field_type;
- if (old_field_type->NowIs(new_field_type)) return new_field_type;
+ static const int kMaxClassesPerFieldType = 5;
+ if (type1->NowIs(type2)) return type2;
+ if (type2->NowIs(type1)) return type1;
+ if (type1->NowStable() && type2->NowStable()) {
+ Handle<HeapType> type = HeapType::Union(type1, type2, isolate);
+ if (type->NumClasses() <= kMaxClassesPerFieldType) {
+ ASSERT(type->NowStable());
+ ASSERT(type1->NowIs(type));
+ ASSERT(type2->NowIs(type));
+ return type;
+ }
+ }
return HeapType::Any(isolate);
}
=======================================
--- /branches/bleeding_edge/src/objects.h Wed Apr 16 21:19:25 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Thu Apr 17 08:22:22 2014 UTC
@@ -6252,8 +6252,8 @@
int target_inobject,
int target_unused);
static Handle<Map> GeneralizeAllFieldRepresentations(Handle<Map> map);
- static Handle<HeapType> GeneralizeFieldType(Handle<HeapType>
old_field_type,
- Handle<HeapType>
new_field_type,
+ static Handle<HeapType> GeneralizeFieldType(Handle<HeapType> type1,
+ Handle<HeapType> type2,
Isolate* isolate)
V8_WARN_UNUSED_RESULT;
static void GeneralizeFieldType(Handle<Map> map,
=======================================
--- /branches/bleeding_edge/src/types.cc Wed Apr 16 16:16:37 2014 UTC
+++ /branches/bleeding_edge/src/types.cc Thu Apr 17 08:22:22 2014 UTC
@@ -357,6 +357,17 @@
}
return this->Is(that);
}
+
+
+// Check if this contains only (currently) stable classes.
+template<class Config>
+bool TypeImpl<Config>::NowStable() {
+ DisallowHeapAllocation no_allocation;
+ for (Iterator<i::Map> it = this->Classes(); !it.Done(); it.Advance()) {
+ if (!it.Current()->is_stable()) return false;
+ }
+ return true;
+}
// Check this overlaps that.
=======================================
--- /branches/bleeding_edge/src/types.h Wed Apr 16 16:36:27 2014 UTC
+++ /branches/bleeding_edge/src/types.h Thu Apr 17 08:22:22 2014 UTC
@@ -320,6 +320,8 @@
bool NowIs(TypeHandle that) { return this->NowIs(*that); }
inline bool NowContains(i::Object* val);
bool NowContains(i::Handle<i::Object> val) { return
this->NowContains(*val); }
+
+ bool NowStable();
bool IsClass() { return Config::is_class(this); }
bool IsConstant() { return Config::is_constant(this); }
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Wed Apr 16 16:16:37
2014 UTC
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Thu Apr 17 08:22:22
2014 UTC
@@ -494,13 +494,21 @@
} else if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = descriptors->GetFieldType(descriptor);
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
Label do_store, heap_number;
@@ -645,13 +653,21 @@
if (representation.IsSmi()) {
__ JumpIfNotSmi(value_reg, miss_label);
} else if (representation.IsHeapObject()) {
+ __ JumpIfSmi(value_reg, miss_label);
HeapType* field_type = lookup->GetFieldType();
- if (field_type->IsClass()) {
- __ CheckMap(value_reg, field_type->AsClass()->Map(),
- miss_label, DO_SMI_CHECK);
- } else {
- ASSERT(HeapType::Any()->Is(field_type));
- __ JumpIfSmi(value_reg, miss_label);
+ HeapType::Iterator<Map> it = field_type->Classes();
+ if (!it.Done()) {
+ Label do_store;
+ while (true) {
+ __ CompareMap(value_reg, it.Current());
+ it.Advance();
+ if (it.Done()) {
+ __ j(not_equal, miss_label);
+ break;
+ }
+ __ j(equal, &do_store, Label::kNear);
+ }
+ __ bind(&do_store);
}
} else if (representation.IsDouble()) {
// Load the double storage.
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.