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