Commit e21d76a0 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

1. Added support for object printing for release mode using the

   objectprint=on (defaults to off) option (which defines OBJECT_PRINT).
2. Added the ability to print objects to a specified file instead of
   just stdout.
3. Added a use_verbose_printer flag (true by default) to allow some
   object printouts to be less verbose when the flag is false.
4. Fixed a bug in VSNPrintF() where it can potentially write into an
   empty char vector.

Patch by Mark Lam from Hewlett-Packard Development Company, LP

Review URL: http://codereview.chromium.org/5998001


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6080 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c91f5606
......@@ -108,11 +108,14 @@ LIBRARY_FLAGS = {
'CPPDEFINES': ['V8_INTERPRETED_REGEXP']
},
'mode:debug': {
'CPPDEFINES': ['V8_ENABLE_CHECKS']
'CPPDEFINES': ['V8_ENABLE_CHECKS', 'OBJECT_PRINT']
},
'vmstate:on': {
'CPPDEFINES': ['ENABLE_VMSTATE_TRACKING'],
},
'objectprint:on': {
'CPPDEFINES': ['OBJECT_PRINT'],
},
'protectheap:on': {
'CPPDEFINES': ['ENABLE_VMSTATE_TRACKING', 'ENABLE_HEAP_PROTECTION'],
},
......@@ -711,6 +714,11 @@ SIMPLE_OPTIONS = {
'default': 'off',
'help': 'enable VM state tracking'
},
'objectprint': {
'values': ['on', 'off'],
'default': 'off',
'help': 'enable object printing'
},
'protectheap': {
'values': ['on', 'off'],
'default': 'off',
......
......@@ -230,7 +230,8 @@ SOURCES = {
'mode:release': [],
'mode:debug': [
'objects-debug.cc', 'prettyprinter.cc', 'regexp-macro-assembler-tracer.cc'
]
],
'objectprint:on': ['objects-debug.cc']
}
......
......@@ -467,34 +467,35 @@ const char* RelocInfo::RelocModeName(RelocInfo::Mode rmode) {
}
void RelocInfo::Print() {
PrintF("%p %s", pc_, RelocModeName(rmode_));
void RelocInfo::Print(FILE* out) {
PrintF(out, "%p %s", pc_, RelocModeName(rmode_));
if (IsComment(rmode_)) {
PrintF(" (%s)", reinterpret_cast<char*>(data_));
PrintF(out, " (%s)", reinterpret_cast<char*>(data_));
} else if (rmode_ == EMBEDDED_OBJECT) {
PrintF(" (");
target_object()->ShortPrint();
PrintF(")");
PrintF(out, " (");
target_object()->ShortPrint(out);
PrintF(out, ")");
} else if (rmode_ == EXTERNAL_REFERENCE) {
ExternalReferenceEncoder ref_encoder;
PrintF(" (%s) (%p)",
PrintF(out, " (%s) (%p)",
ref_encoder.NameOfAddress(*target_reference_address()),
*target_reference_address());
} else if (IsCodeTarget(rmode_)) {
Code* code = Code::GetCodeFromTargetAddress(target_address());
PrintF(" (%s) (%p)", Code::Kind2String(code->kind()), target_address());
PrintF(out, " (%s) (%p)", Code::Kind2String(code->kind()),
target_address());
} else if (IsPosition(rmode_)) {
PrintF(" (%" V8_PTR_PREFIX "d)", data());
PrintF(out, " (%" V8_PTR_PREFIX "d)", data());
} else if (rmode_ == RelocInfo::RUNTIME_ENTRY) {
// Depotimization bailouts are stored as runtime entries.
int id = Deoptimizer::GetDeoptimizationId(
target_address(), Deoptimizer::EAGER);
if (id != Deoptimizer::kNotDeoptimizationEntry) {
PrintF(" (deoptimization bailout %d)", id);
PrintF(out, " (deoptimization bailout %d)", id);
}
}
PrintF("\n");
PrintF(out, "\n");
}
#endif // ENABLE_DISASSEMBLER
......
......@@ -322,7 +322,7 @@ class RelocInfo BASE_EMBEDDED {
#ifdef ENABLE_DISASSEMBLER
// Printing
static const char* RelocModeName(Mode rmode);
void Print();
void Print(FILE* out);
#endif // ENABLE_DISASSEMBLER
#ifdef DEBUG
// Debugging
......
......@@ -1096,7 +1096,7 @@ int Translation::NumberOfOperandsFor(Opcode opcode) {
}
#ifdef DEBUG
#ifdef OBJECT_PRINT
const char* Translation::StringFor(Opcode opcode) {
switch (opcode) {
......
......@@ -476,7 +476,7 @@ class Translation BASE_EMBEDDED {
static int NumberOfOperandsFor(Opcode opcode);
#ifdef DEBUG
#ifdef OBJECT_PRINT
static const char* StringFor(Opcode opcode);
#endif
......
......@@ -296,6 +296,9 @@ DEFINE_int(max_map_space_pages, MapSpace::kMaxMapPageIndex - 1,
DEFINE_bool(h, false, "print this message")
DEFINE_bool(new_snapshot, true, "use new snapshot implementation")
// objects.cc
DEFINE_bool(use_verbose_printer, true, "allows verbose printing")
// parser.cc
DEFINE_bool(allow_natives_syntax, false, "allow natives syntax")
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -128,6 +128,19 @@ void OS::VPrint(const char* format, va_list args) {
}
void OS::FPrint(FILE* out, const char* format, ...) {
va_list args;
va_start(args, format);
VFPrint(out, format, args);
va_end(args);
}
void OS::VFPrint(FILE* out, const char* format, va_list args) {
vfprintf(out, format, args);
}
// Print error message to console.
void OS::PrintError(const char* format, ...) {
// Minimalistic implementation for bootstrapping.
......
......@@ -142,6 +142,23 @@ void OS::VPrint(const char* format, va_list args) {
}
void OS::FPrint(FILE* out, const char* format, ...) {
va_list args;
va_start(args, format);
VFPrint(out, format, args);
va_end(args);
}
void OS::VFPrint(FILE* out, const char* format, va_list args) {
#if defined(ANDROID)
LOG_PRI_VA(ANDROID_LOG_INFO, LOG_TAG, format, args);
#else
vfprintf(out, format, args);
#endif
}
void OS::PrintError(const char* format, ...) {
va_list args;
va_start(args, format);
......@@ -173,7 +190,9 @@ int OS::VSNPrintF(Vector<char> str,
va_list args) {
int n = vsnprintf(str.start(), str.length(), format, args);
if (n < 0 || n >= str.length()) {
str[str.length() - 1] = '\0';
// If the length is zero, the assignment fails.
if (str.length() > 0)
str[str.length() - 1] = '\0';
return -1;
} else {
return n;
......
......@@ -688,6 +688,19 @@ void OS::VPrint(const char* format, va_list args) {
}
void OS::FPrint(FILE* out, const char* format, ...) {
va_list args;
va_start(args, format);
VFPrint(out, format, args);
va_end(args);
}
void OS::VFPrint(FILE* out, const char* format, va_list args) {
VPrintHelper(out, format, args);
}
// Print error message to console.
void OS::PrintError(const char* format, ...) {
va_list args;
......@@ -716,7 +729,8 @@ int OS::VSNPrintF(Vector<char> str, const char* format, va_list args) {
// Make sure to zero-terminate the string if the output was
// truncated or if there was an error.
if (n < 0 || n >= str.length()) {
str[str.length() - 1] = '\0';
if (str.length() > 0)
str[str.length() - 1] = '\0';
return -1;
} else {
return n;
......
......@@ -184,6 +184,10 @@ class OS {
static void Print(const char* format, ...);
static void VPrint(const char* format, va_list args);
// Print output to a file. This is mostly used for debugging output.
static void FPrint(FILE* out, const char* format, ...);
static void VFPrint(FILE* out, const char* format, va_list args);
// Print error output to console. This is mostly used for error message
// output. On platforms that has standard terminal output, the output
// should go to stderr.
......
......@@ -31,62 +31,62 @@ namespace v8 {
namespace internal {
#ifdef DEBUG
void LookupResult::Print() {
#ifdef OBJECT_PRINT
void LookupResult::Print(FILE* out) {
if (!IsFound()) {
PrintF("Not Found\n");
PrintF(out, "Not Found\n");
return;
}
PrintF("LookupResult:\n");
PrintF(" -cacheable = %s\n", IsCacheable() ? "true" : "false");
PrintF(" -attributes = %x\n", GetAttributes());
PrintF(out, "LookupResult:\n");
PrintF(out, " -cacheable = %s\n", IsCacheable() ? "true" : "false");
PrintF(out, " -attributes = %x\n", GetAttributes());
switch (type()) {
case NORMAL:
PrintF(" -type = normal\n");
PrintF(" -entry = %d", GetDictionaryEntry());
PrintF(out, " -type = normal\n");
PrintF(out, " -entry = %d", GetDictionaryEntry());
break;
case MAP_TRANSITION:
PrintF(" -type = map transition\n");
PrintF(" -map:\n");
GetTransitionMap()->Print();
PrintF("\n");
PrintF(out, " -type = map transition\n");
PrintF(out, " -map:\n");
GetTransitionMap()->Print(out);
PrintF(out, "\n");
break;
case CONSTANT_FUNCTION:
PrintF(" -type = constant function\n");
PrintF(" -function:\n");
GetConstantFunction()->Print();
PrintF("\n");
PrintF(out, " -type = constant function\n");
PrintF(out, " -function:\n");
GetConstantFunction()->Print(out);
PrintF(out, "\n");
break;
case FIELD:
PrintF(" -type = field\n");
PrintF(" -index = %d", GetFieldIndex());
PrintF("\n");
PrintF(out, " -type = field\n");
PrintF(out, " -index = %d", GetFieldIndex());
PrintF(out, "\n");
break;
case CALLBACKS:
PrintF(" -type = call backs\n");
PrintF(" -callback object:\n");
GetCallbackObject()->Print();
PrintF(out, " -type = call backs\n");
PrintF(out, " -callback object:\n");
GetCallbackObject()->Print(out);
break;
case INTERCEPTOR:
PrintF(" -type = lookup interceptor\n");
PrintF(out, " -type = lookup interceptor\n");
break;
case CONSTANT_TRANSITION:
PrintF(" -type = constant property transition\n");
PrintF(out, " -type = constant property transition\n");
break;
case NULL_DESCRIPTOR:
PrintF(" =type = null descriptor\n");
PrintF(out, " =type = null descriptor\n");
break;
}
}
void Descriptor::Print() {
PrintF("Descriptor ");
GetKey()->ShortPrint();
PrintF(" @ ");
GetValue()->ShortPrint();
PrintF(" %d\n", GetDetails().index());
void Descriptor::Print(FILE* out) {
PrintF(out, "Descriptor ");
GetKey()->ShortPrint(out);
PrintF(out, " @ ");
GetValue()->ShortPrint(out);
PrintF(out, " %d\n", GetDetails().index());
}
......
......@@ -60,8 +60,8 @@ class Descriptor BASE_EMBEDDED {
Object* GetValue() { return value_; }
PropertyDetails GetDetails() { return details_; }
#ifdef DEBUG
void Print();
#ifdef OBJECT_PRINT
void Print(FILE* out);
#endif
void SetEnumerationIndex(int index) {
......@@ -310,8 +310,8 @@ class LookupResult BASE_EMBEDDED {
return GetValue();
}
#ifdef DEBUG
void Print();
#ifdef OBJECT_PRINT
void Print(FILE* out);
#endif
Object* GetValue() {
......
......@@ -264,7 +264,7 @@ void StringStream::Log() {
}
void StringStream::OutputToStdOut() {
void StringStream::OutputToFile(FILE* out) {
// Dump the output to stdout, but make sure to break it up into
// manageable chunks to avoid losing parts of the output in the OS
// printing code. This is a problem on Windows in particular; see
......@@ -273,10 +273,10 @@ void StringStream::OutputToStdOut() {
for (unsigned next; (next = position + 2048) < length_; position = next) {
char save = buffer_[next];
buffer_[next] = '\0';
internal::PrintF("%s", &buffer_[position]);
internal::PrintF(out, "%s", &buffer_[position]);
buffer_[next] = save;
}
internal::PrintF("%s", &buffer_[position]);
internal::PrintF(out, "%s", &buffer_[position]);
}
......
......@@ -138,7 +138,8 @@ class StringStream {
FmtElm arg3);
// Getting the message out.
void OutputToStdOut();
void OutputToFile(FILE* out);
void OutputToStdOut() { OutputToFile(stdout); }
void Log();
Handle<String> ToString();
SmartPointer<const char> ToCString() const;
......
......@@ -45,8 +45,16 @@ void PrintF(const char* format, ...) {
}
void Flush() {
fflush(stdout);
void PrintF(FILE* out, const char* format, ...) {
va_list arguments;
va_start(arguments, format);
OS::VFPrint(out, format, arguments);
va_end(arguments);
}
void Flush(FILE* out) {
fflush(out);
}
......
......@@ -42,18 +42,26 @@ namespace internal {
// so it works on MacOSX.
#if defined(__MACH__) && defined(__APPLE__)
#define PRINTF_CHECKING
#define FPRINTF_CHECKING
#else // MacOsX.
#define PRINTF_CHECKING __attribute__ ((format (printf, 1, 2)))
#define FPRINTF_CHECKING __attribute__ ((format (printf, 2, 3)))
#endif
#else
#define PRINTF_CHECKING
#define FPRINTF_CHECKING
#endif
// Our version of printf().
void PRINTF_CHECKING PrintF(const char* format, ...);
void FPRINTF_CHECKING PrintF(FILE* out, const char* format, ...);
// Our version of fflush.
void Flush();
void Flush(FILE* out);
inline void Flush() {
Flush(stdout);
}
// Read a line of characters after printing the prompt to stdout. The resulting
......
......@@ -70,7 +70,8 @@
'DEBUG',
'_DEBUG',
'ENABLE_DISASSEMBLER',
'V8_ENABLE_CHECKS'
'V8_ENABLE_CHECKS',
'OBJECT_PRINT',
],
'msvs_settings': {
'VCCLCompilerTool': {
......
......@@ -1850,6 +1850,7 @@
DEBUG,
ENABLE_LOGGING_AND_PROFILING,
V8_ENABLE_CHECKS,
OBJECT_PRINT,
ENABLE_VMSTATE_TRACKING,
);
GCC_SYMBOLS_PRIVATE_EXTERN = YES;
......@@ -1914,6 +1915,7 @@
V8_TARGET_ARCH_IA32,
DEBUG,
V8_ENABLE_CHECKS,
OBJECT_PRINT,
ENABLE_DEBUGGER_SUPPORT,
);
HEADER_SEARCH_PATHS = ../src;
......@@ -1976,6 +1978,7 @@
V8_TARGET_ARCH_IA32,
DEBUG,
V8_ENABLE_CHECKS,
OBJECT_PRINT,
ENABLE_DEBUGGER_SUPPORT,
);
HEADER_SEARCH_PATHS = ../src;
......
......@@ -7,7 +7,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="DEBUG;_DEBUG;ENABLE_DISASSEMBLER;V8_ENABLE_CHECKS"
PreprocessorDefinitions="DEBUG;_DEBUG;ENABLE_DISASSEMBLER;V8_ENABLE_CHECKS,OBJECT_PRINT"
RuntimeLibrary="1"
/>
<Tool
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment