Improve generalization / migration tracing.
R=yangguo@chromium.org Review URL: https://chromiumcodereview.appspot.com/23047002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16219 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
94fb05f823
commit
20ca26f494
@ -1567,14 +1567,27 @@ MaybeObject* JSObject::MigrateInstance() {
|
||||
// Converting any field to the most specific type will cause the
|
||||
// GeneralizeFieldRepresentation algorithm to create the most general existing
|
||||
// transition that matches the object. This achieves what is needed.
|
||||
return GeneralizeFieldRepresentation(0, Representation::None());
|
||||
Map* original_map = map();
|
||||
MaybeObject* maybe_result = GeneralizeFieldRepresentation(
|
||||
0, Representation::None());
|
||||
JSObject* result;
|
||||
if (FLAG_trace_migration && maybe_result->To(&result)) {
|
||||
PrintInstanceMigration(stdout, original_map, result->map());
|
||||
}
|
||||
return maybe_result;
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* JSObject::TryMigrateInstance() {
|
||||
Map* new_map = map()->CurrentMapForDeprecated();
|
||||
if (new_map == NULL) return Smi::FromInt(0);
|
||||
return MigrateToMap(new_map);
|
||||
Map* original_map = map();
|
||||
MaybeObject* maybe_result = MigrateToMap(new_map);
|
||||
JSObject* result;
|
||||
if (FLAG_trace_migration && maybe_result->To(&result)) {
|
||||
PrintInstanceMigration(stdout, original_map, result->map());
|
||||
}
|
||||
return maybe_result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1449,6 +1449,54 @@ void JSObject::PrintElementsTransition(
|
||||
}
|
||||
|
||||
|
||||
void Map::PrintGeneralization(FILE* file,
|
||||
int modify_index,
|
||||
int split,
|
||||
int descriptors,
|
||||
Representation old_representation,
|
||||
Representation new_representation) {
|
||||
PrintF(file, "[generalizing ");
|
||||
constructor_name()->PrintOn(file);
|
||||
PrintF(file, "] ");
|
||||
String::cast(instance_descriptors()->GetKey(modify_index))->PrintOn(file);
|
||||
PrintF(file, ":%s->%s (+%i maps) [",
|
||||
old_representation.Mnemonic(),
|
||||
new_representation.Mnemonic(),
|
||||
descriptors - split);
|
||||
JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
|
||||
PrintF(file, "]\n");
|
||||
}
|
||||
|
||||
|
||||
void JSObject::PrintInstanceMigration(FILE* file,
|
||||
Map* original_map,
|
||||
Map* new_map) {
|
||||
PrintF(file, "[migrating ");
|
||||
map()->constructor_name()->PrintOn(file);
|
||||
PrintF(file, "] ");
|
||||
DescriptorArray* o = original_map->instance_descriptors();
|
||||
DescriptorArray* n = new_map->instance_descriptors();
|
||||
for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) {
|
||||
Representation o_r = o->GetDetails(i).representation();
|
||||
Representation n_r = n->GetDetails(i).representation();
|
||||
if (!o_r.Equals(n_r)) {
|
||||
String::cast(o->GetKey(i))->PrintOn(file);
|
||||
PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic());
|
||||
} else if (o->GetDetails(i).type() == CONSTANT &&
|
||||
n->GetDetails(i).type() == FIELD) {
|
||||
Name* name = o->GetKey(i);
|
||||
if (name->IsString()) {
|
||||
String::cast(name)->PrintOn(file);
|
||||
} else {
|
||||
PrintF(file, "???");
|
||||
}
|
||||
PrintF(file, " ");
|
||||
}
|
||||
}
|
||||
PrintF(file, "\n");
|
||||
}
|
||||
|
||||
|
||||
void HeapObject::HeapObjectShortPrint(StringStream* accumulator) {
|
||||
Heap* heap = GetHeap();
|
||||
if (!heap->Contains(this)) {
|
||||
@ -1783,14 +1831,14 @@ String* JSReceiver::class_name() {
|
||||
}
|
||||
|
||||
|
||||
String* JSReceiver::constructor_name() {
|
||||
if (map()->constructor()->IsJSFunction()) {
|
||||
JSFunction* constructor = JSFunction::cast(map()->constructor());
|
||||
String* Map::constructor_name() {
|
||||
if (constructor()->IsJSFunction()) {
|
||||
JSFunction* constructor = JSFunction::cast(this->constructor());
|
||||
String* name = String::cast(constructor->shared()->name());
|
||||
if (name->length() > 0) return name;
|
||||
String* inferred_name = constructor->shared()->inferred_name();
|
||||
if (inferred_name->length() > 0) return inferred_name;
|
||||
Object* proto = GetPrototype();
|
||||
Object* proto = prototype();
|
||||
if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name();
|
||||
}
|
||||
// TODO(rossberg): what about proxies?
|
||||
@ -1799,6 +1847,11 @@ String* JSReceiver::constructor_name() {
|
||||
}
|
||||
|
||||
|
||||
String* JSReceiver::constructor_name() {
|
||||
return map()->constructor_name();
|
||||
}
|
||||
|
||||
|
||||
MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
|
||||
Name* name,
|
||||
Object* value,
|
||||
@ -2626,12 +2679,6 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
|
||||
if (old_representation.IsNone() &&
|
||||
!new_representation.IsNone() &&
|
||||
!new_representation.IsDouble()) {
|
||||
if (FLAG_trace_generalization) {
|
||||
PrintF("initializing representation %i: %p -> %s\n",
|
||||
modify_index,
|
||||
static_cast<void*>(this),
|
||||
new_representation.Mnemonic());
|
||||
}
|
||||
old_descriptors->SetRepresentation(modify_index, new_representation);
|
||||
return old_map;
|
||||
}
|
||||
@ -2661,11 +2708,9 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
|
||||
if (FLAG_trace_generalization &&
|
||||
!(modify_index == 0 && new_representation.IsNone())) {
|
||||
PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
|
||||
PrintF("migrating to existing map %p(%s) -> %p(%s)\n",
|
||||
static_cast<void*>(this),
|
||||
old_details.representation().Mnemonic(),
|
||||
static_cast<void*>(updated),
|
||||
updated_representation.Mnemonic());
|
||||
PrintGeneralization(stdout, modify_index, descriptors, descriptors,
|
||||
old_details.representation(),
|
||||
updated_representation);
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
@ -2698,13 +2743,8 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
|
||||
|
||||
if (FLAG_trace_generalization &&
|
||||
!(modify_index == 0 && new_representation.IsNone())) {
|
||||
PrintF("migrating to new map %i: %p(%s) -> %p(%s) (%i steps)\n",
|
||||
modify_index,
|
||||
static_cast<void*>(this),
|
||||
old_representation.Mnemonic(),
|
||||
static_cast<void*>(new_descriptors),
|
||||
updated_representation.Mnemonic(),
|
||||
descriptors - descriptor);
|
||||
PrintGeneralization(stdout, modify_index, descriptor, descriptors,
|
||||
old_representation, updated_representation);
|
||||
}
|
||||
|
||||
Map* new_map = split_map;
|
||||
@ -3726,11 +3766,6 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
|
||||
|
||||
|
||||
void JSObject::MigrateInstance(Handle<JSObject> object) {
|
||||
if (FLAG_trace_migration) {
|
||||
PrintF("migrating instance %p (%p)\n",
|
||||
static_cast<void*>(*object),
|
||||
static_cast<void*>(object->map()));
|
||||
}
|
||||
CALL_HEAP_FUNCTION_VOID(
|
||||
object->GetIsolate(),
|
||||
object->MigrateInstance());
|
||||
@ -3738,11 +3773,6 @@ void JSObject::MigrateInstance(Handle<JSObject> object) {
|
||||
|
||||
|
||||
Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
|
||||
if (FLAG_trace_migration) {
|
||||
PrintF("migrating instance (no new maps) %p (%p)\n",
|
||||
static_cast<void*>(*object),
|
||||
static_cast<void*>(object->map()));
|
||||
}
|
||||
CALL_HEAP_FUNCTION(
|
||||
object->GetIsolate(),
|
||||
object->MigrateInstance(),
|
||||
|
@ -2672,6 +2672,8 @@ class JSObject: public JSReceiver {
|
||||
FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements,
|
||||
ElementsKind to_kind, FixedArrayBase* to_elements);
|
||||
|
||||
void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
|
||||
|
||||
#ifdef DEBUG
|
||||
// Structure for collecting spill information about JSObjects.
|
||||
class SpillInformation {
|
||||
@ -5623,6 +5625,17 @@ class Map: public HeapObject {
|
||||
Representation representation);
|
||||
MUST_USE_RESULT MaybeObject* CopyGeneralizeAllRepresentations();
|
||||
|
||||
void PrintGeneralization(FILE* file,
|
||||
int modify_index,
|
||||
int split,
|
||||
int descriptors,
|
||||
Representation old_representation,
|
||||
Representation new_representation);
|
||||
|
||||
// Returns the constructor name (the name (possibly, inferred name) of the
|
||||
// function that was used to instantiate the object).
|
||||
String* constructor_name();
|
||||
|
||||
// Tells whether the map is attached to SharedFunctionInfo
|
||||
// (for inobject slack tracking).
|
||||
inline void set_attached_to_shared_function_info(bool value);
|
||||
|
Loading…
Reference in New Issue
Block a user