From 209855a6b6708381515c97f68df9e68204f6ef2b Mon Sep 17 00:00:00 2001 From: "ishell@chromium.org" Date: Thu, 23 Oct 2014 11:31:33 +0000 Subject: [PATCH] More details printed for Map, DescriptorArray and TransitionArray. R=verwaest@chromium.org Review URL: https://codereview.chromium.org/659363002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24837 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/objects-printer.cc | 122 +++++++++++++++++++++-------------------- src/objects.cc | 2 +- src/objects.h | 3 + src/property-details.h | 4 ++ src/property.cc | 36 +++++++++++- src/transitions-inl.h | 6 ++ src/transitions.h | 6 +- tools/gdbinit | 18 ++++++ 8 files changed, 134 insertions(+), 63 deletions(-) diff --git a/src/objects-printer.cc b/src/objects-printer.cc index c8149bb329..d9a8676efc 100644 --- a/src/objects-printer.cc +++ b/src/objects-printer.cc @@ -347,39 +347,7 @@ void JSObject::PrintElements(std::ostream& os) { // NOLINT void JSObject::PrintTransitions(std::ostream& os) { // NOLINT if (!map()->HasTransitionArray()) return; - TransitionArray* transitions = map()->transitions(); - for (int i = 0; i < transitions->number_of_transitions(); i++) { - Name* key = transitions->GetKey(i); - os << " "; - key->NamePrint(os); - os << ": "; - if (key == GetHeap()->frozen_symbol()) { - os << " (transition to frozen)\n"; - } else if (key == GetHeap()->elements_transition_symbol()) { - os << " (transition to " - << ElementsKindToString(transitions->GetTarget(i)->elements_kind()) - << ")\n"; - } else if (key == GetHeap()->observed_symbol()) { - os << " (transition to Object.observe)\n"; - } else { - switch (transitions->GetTargetDetails(i).type()) { - case FIELD: { - os << " (transition to field)\n"; - break; - } - case CONSTANT: - os << " (transition to constant)\n"; - break; - case CALLBACKS: - os << " (transition to callback)\n"; - break; - // Values below are never in the target descriptor array. - case NORMAL: - UNREACHABLE(); - break; - } - } - } + map()->transitions()->PrintTransitions(os, false); } @@ -442,6 +410,8 @@ void Map::MapPrint(std::ostream& os) { // NOLINT os << "\n - pre-allocated property fields: " << pre_allocated_property_fields() << "\n"; os << " - unused property fields: " << unused_property_fields() << "\n"; + if (is_dictionary_map()) os << " - dictionary_map\n"; + if (is_prototype_map()) os << " - prototype_map\n"; if (is_hidden_prototype()) os << " - hidden_prototype\n"; if (has_named_interceptor()) os << " - named_interceptor\n"; if (has_indexed_interceptor()) os << " - indexed_interceptor\n"; @@ -605,10 +575,13 @@ void String::StringPrint(std::ostream& os) { // NOLINT void Name::NamePrint(std::ostream& os) { // NOLINT - if (IsString()) + if (IsString()) { String::cast(this)->StringPrint(os); - else + } else if (IsSymbol()) { + Symbol::cast(this)->name()->Print(os); + } else { os << Brief(this); + } } @@ -1082,41 +1055,70 @@ void BreakPointInfo::BreakPointInfoPrint(std::ostream& os) { // NOLINT } +void DescriptorArray::Print() { + OFStream os(stdout); + this->PrintDescriptors(os); + os << std::flush; +} + + void DescriptorArray::PrintDescriptors(std::ostream& os) { // NOLINT - os << "Descriptor array " << number_of_descriptors() << "\n"; + os << "Descriptor array " << number_of_descriptors() << "\n"; for (int i = 0; i < number_of_descriptors(); i++) { Descriptor desc; Get(i, &desc); - os << " " << i << ": " << desc; + os << " " << i << ": " << desc << "\n"; } os << "\n"; } -void TransitionArray::PrintTransitions(std::ostream& os) { // NOLINT - os << "Transition array %d\n", number_of_transitions(); - for (int i = 0; i < number_of_transitions(); i++) { - os << " " << i << ": "; - GetKey(i)->NamePrint(os); - os << ": "; - switch (GetTargetDetails(i).type()) { - case FIELD: { - os << " (transition to field)\n"; - break; - } - case CONSTANT: - os << " (transition to constant)\n"; - break; - case CALLBACKS: - os << " (transition to callback)\n"; - break; - // Values below are never in the target descriptor array. - case NORMAL: - UNREACHABLE(); - break; - } +void TransitionArray::Print() { + OFStream os(stdout); + this->PrintTransitions(os); + os << std::flush; +} + + +void TransitionArray::PrintTransitions(std::ostream& os, + bool print_header) { // NOLINT + if (print_header) { + os << "Transition array " << number_of_transitions() << "\n"; + } + for (int i = 0; i < number_of_transitions(); i++) { + Name* key = GetKey(i); + os << " "; + key->NamePrint(os); + os << ": "; + if (key == GetHeap()->frozen_symbol()) { + os << " (transition to frozen)"; + } else if (key == GetHeap()->elements_transition_symbol()) { + os << " (transition to " + << ElementsKindToString(GetTarget(i)->elements_kind()) << ")"; + } else if (key == GetHeap()->observed_symbol()) { + os << " (transition to Object.observe)"; + } else { + PropertyDetails details = GetTargetDetails(i); + switch (details.type()) { + case FIELD: { + os << " (transition to field)"; + break; + } + case CONSTANT: + os << " (transition to constant " << Brief(GetTargetValue(i)) << ")"; + break; + case CALLBACKS: + os << " (transition to callback " << Brief(GetTargetValue(i)) << ")"; + break; + // Values below are never in the target descriptor array. + case NORMAL: + UNREACHABLE(); + break; + } + os << ", attrs: " << details.attributes(); + } + os << " -> " << Brief(GetTarget(i)) << "\n"; } - os << "\n"; } diff --git a/src/objects.cc b/src/objects.cc index 371931c566..5496b7e364 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -13138,7 +13138,7 @@ void Dictionary::Print(std::ostream& os) { // NOLINT } else { os << Brief(k); } - os << ": " << Brief(ValueAt(i)) << "\n"; + os << ": " << Brief(ValueAt(i)) << " " << DetailsAt(i) << "\n"; } } } diff --git a/src/objects.h b/src/objects.h index b2b64c2197..6eb2697c6f 100644 --- a/src/objects.h +++ b/src/objects.h @@ -3051,6 +3051,9 @@ class DescriptorArray: public FixedArray { static const int kDescriptorSize = 3; #ifdef OBJECT_PRINT + // For our gdb macros, we should perhaps change these in the future. + void Print(); + // Print all the descriptors. void PrintDescriptors(std::ostream& os); // NOLINT #endif diff --git a/src/property-details.h b/src/property-details.h index f75bcff049..61fecedd1b 100644 --- a/src/property-details.h +++ b/src/property-details.h @@ -295,6 +295,10 @@ class PropertyDetails BASE_EMBEDDED { uint32_t value_; }; + +std::ostream& operator<<(std::ostream& os, + const PropertyAttributes& attributes); +std::ostream& operator<<(std::ostream& os, const PropertyDetails& details); } } // namespace v8::internal #endif // V8_PROPERTY_DETAILS_H_ diff --git a/src/property.cc b/src/property.cc index 81966d4017..e9e4b64690 100644 --- a/src/property.cc +++ b/src/property.cc @@ -31,9 +31,43 @@ std::ostream& operator<<(std::ostream& os, const LookupResult& r) { } +std::ostream& operator<<(std::ostream& os, + const PropertyAttributes& attributes) { + os << "["; + os << (((attributes & READ_ONLY) == 0) ? "W" : "_"); // writable + os << (((attributes & DONT_ENUM) == 0) ? "E" : "_"); // enumerable + os << (((attributes & DONT_DELETE) == 0) ? "C" : "_"); // configurable + os << "]"; + return os; +} + + +std::ostream& operator<<(std::ostream& os, const PropertyDetails& details) { + os << "("; + switch (details.type()) { + case NORMAL: + os << "normal: dictionary_index: " << details.dictionary_index(); + break; + case CONSTANT: + os << "constant: p: " << details.pointer(); + break; + case FIELD: + os << "field: " << details.representation().Mnemonic() + << ", field_index: " << details.field_index() + << ", p: " << details.pointer(); + break; + case CALLBACKS: + os << "callbacks: p: " << details.pointer(); + break; + } + os << ", attrs: " << details.attributes() << ")"; + return os; +} + + std::ostream& operator<<(std::ostream& os, const Descriptor& d) { return os << "Descriptor " << Brief(*d.GetKey()) << " @ " - << Brief(*d.GetValue()); + << Brief(*d.GetValue()) << " " << d.GetDetails(); } } } // namespace v8::internal diff --git a/src/transitions-inl.h b/src/transitions-inl.h index a16eb4477c..cc4d4b11d4 100644 --- a/src/transitions-inl.h +++ b/src/transitions-inl.h @@ -134,6 +134,12 @@ PropertyDetails TransitionArray::GetTargetDetails(int transition_number) { } +Object* TransitionArray::GetTargetValue(int transition_number) { + Map* map = GetTarget(transition_number); + return map->instance_descriptors()->GetValue(map->LastAdded()); +} + + int TransitionArray::Search(Name* name) { if (IsSimpleTransition()) { Name* key = GetKey(kSimpleTransitionIndex); diff --git a/src/transitions.h b/src/transitions.h index 4aad7274dd..aa9b7b86d6 100644 --- a/src/transitions.h +++ b/src/transitions.h @@ -48,6 +48,7 @@ class TransitionArray: public FixedArray { inline void SetTarget(int transition_number, Map* target); inline PropertyDetails GetTargetDetails(int transition_number); + inline Object* GetTargetValue(int transition_number); inline bool HasElementsTransition(); @@ -139,8 +140,11 @@ class TransitionArray: public FixedArray { static const int kTransitionSize = 2; #ifdef OBJECT_PRINT + // For our gdb macros, we should perhaps change these in the future. + void Print(); + // Print all the transitions. - void PrintTransitions(std::ostream& os); // NOLINT + void PrintTransitions(std::ostream& os, bool print_header = true); // NOLINT #endif #ifdef DEBUG diff --git a/tools/gdbinit b/tools/gdbinit index 20cdff618c..220959d81c 100644 --- a/tools/gdbinit +++ b/tools/gdbinit @@ -20,6 +20,24 @@ Print a v8 Code object from an internal code address Usage: jco pc end +# Print DescriptorArray. +define jda +print ((v8::internal::DescriptorArray*)($arg0))->Print() +end +document jda +Print a v8 DescriptorArray object +Usage: jda tagged_ptr +end + +# Print TransitionArray. +define jta +print ((v8::internal::TransitionArray*)($arg0))->Print() +end +document jta +Print a v8 TransitionArray object +Usage: jta tagged_ptr +end + # Print JavaScript stack trace. define jst print v8::internal::Isolate::Current()->PrintStack(stdout)