Author: [email protected]
Date: Tue Jan 6 05:24:52 2009
New Revision: 1028
Modified:
branches/bleeding_edge/src/codegen-arm.cc
branches/bleeding_edge/src/codegen-arm.h
branches/bleeding_edge/src/codegen-ia32.cc
branches/bleeding_edge/src/codegen-ia32.h
branches/bleeding_edge/src/codegen.cc
branches/bleeding_edge/src/jsregexp.cc
branches/bleeding_edge/src/log.cc
branches/bleeding_edge/src/log.h
branches/bleeding_edge/src/regexp-delay.js
branches/bleeding_edge/src/runtime.cc
branches/bleeding_edge/src/runtime.h
branches/bleeding_edge/src/string.js
branches/bleeding_edge/test/mjsunit/fuzz-natives.js
Log:
Added runtime call to the logging infrastructure. Made some changes
to the way regexps are being logged.
Modified: branches/bleeding_edge/src/codegen-arm.cc
==============================================================================
--- branches/bleeding_edge/src/codegen-arm.cc (original)
+++ branches/bleeding_edge/src/codegen-arm.cc Tue Jan 6 05:24:52 2009
@@ -2577,6 +2577,19 @@
}
+void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) {
+ // See comment in CodeGenerator::GenerateLog in codegen-ia32.cc.
+ ASSERT_EQ(args->length(), 3);
+ if (ShouldGenerateLog(args->at(0))) {
+ Load(args->at(1));
+ Load(args->at(2));
+ __ CallRuntime(Runtime::kLog, 2);
+ }
+ __ mov(r0, Operand(Factory::undefined_value()));
+ frame_->Push(r0);
+}
+
+
void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
ASSERT(args->length() == 1);
Load(args->at(0));
Modified: branches/bleeding_edge/src/codegen-arm.h
==============================================================================
--- branches/bleeding_edge/src/codegen-arm.h (original)
+++ branches/bleeding_edge/src/codegen-arm.h Tue Jan 6 05:24:52 2009
@@ -195,6 +195,8 @@
Handle<Script> script,
bool is_eval);
+ static bool ShouldGenerateLog(Expression* type);
+
static void SetFunctionInfo(Handle<JSFunction> fun,
int length,
int function_token_position,
@@ -323,6 +325,8 @@
// Fast support for object equality testing.
void GenerateObjectEquals(ZoneList<Expression*>* args);
+
+ void GenerateLog(ZoneList<Expression*>* args);
// Methods and constants for fast case switch statement support.
//
Modified: branches/bleeding_edge/src/codegen-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/codegen-ia32.cc (original)
+++ branches/bleeding_edge/src/codegen-ia32.cc Tue Jan 6 05:24:52 2009
@@ -2900,6 +2900,25 @@
}
+void CodeGenerator::GenerateLog(ZoneList<Expression*>* args) {
+ // Conditionally generate a log call.
+ // Args:
+ // 0 (literal string): The type of logging (corresponds to the flags).
+ // This is used to determine whether or not to generate the log call.
+ // 1 (string): Format string. Access the string at argument index 2
+ // with '%2s' (see Logger::LogRuntime for all the formats).
+ // 2 (array): Arguments to the format string.
+ ASSERT_EQ(args->length(), 3);
+ if (ShouldGenerateLog(args->at(0))) {
+ Load(args->at(1));
+ Load(args->at(2));
+ __ CallRuntime(Runtime::kLog, 2);
+ }
+ // Finally, we're expected to leave a value on the top of the stack.
+ frame_->Push(Immediate(Factory::undefined_value()));
+}
+
+
void CodeGenerator::GenerateIsNonNegativeSmi(ZoneList<Expression*>* args) {
ASSERT(args->length() == 1);
Load(args->at(0));
Modified: branches/bleeding_edge/src/codegen-ia32.h
==============================================================================
--- branches/bleeding_edge/src/codegen-ia32.h (original)
+++ branches/bleeding_edge/src/codegen-ia32.h Tue Jan 6 05:24:52 2009
@@ -201,6 +201,8 @@
Handle<Script> script,
bool is_eval);
+ static bool ShouldGenerateLog(Expression* type);
+
static void SetFunctionInfo(Handle<JSFunction> fun,
int length,
int function_token_position,
@@ -347,6 +349,8 @@
// Fast support for object equality testing.
void GenerateObjectEquals(ZoneList<Expression*>* args);
+
+ void GenerateLog(ZoneList<Expression*>* args);
// Methods and constants for fast case switch statement support.
Modified: branches/bleeding_edge/src/codegen.cc
==============================================================================
--- branches/bleeding_edge/src/codegen.cc (original)
+++ branches/bleeding_edge/src/codegen.cc Tue Jan 6 05:24:52 2009
@@ -163,6 +163,19 @@
}
+bool CodeGenerator::ShouldGenerateLog(Expression* type) {
+ ASSERT(type != NULL);
+ if (!Logger::is_enabled()) return false;
+ Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
+ if (FLAG_log_regexp) {
+ static Vector<const char> kRegexp = CStrVector("regexp");
+ if (name->IsEqualTo(kRegexp))
+ return true;
+ }
+ return false;
+}
+
+
// Sets the function info on a function.
// The start_position points to the first '(' character after the function
name
// in the full script source. When counting characters in the script
source the
@@ -338,7 +351,9 @@
{&v8::internal::CodeGenerator::GenerateFastCharCodeAt,
"_FastCharCodeAt"},
{&v8::internal::CodeGenerator::GenerateObjectEquals,
- "_ObjectEquals"}
+ "_ObjectEquals"},
+ {&v8::internal::CodeGenerator::GenerateLog,
+ "_Log"}
};
Handle<String> name = node->name();
StringShape shape(*name);
Modified: branches/bleeding_edge/src/jsregexp.cc
==============================================================================
--- branches/bleeding_edge/src/jsregexp.cc (original)
+++ branches/bleeding_edge/src/jsregexp.cc Tue Jan 6 05:24:52 2009
@@ -373,7 +373,6 @@
return Handle<Smi>(Smi::FromInt(-1));
}
- LOG(RegExpExecEvent(re, start_index, subject));
int value = Runtime::StringMatch(subject, needle, start_index);
if (value == -1) return Factory::null_value();
@@ -393,7 +392,6 @@
int subject_length = subject->length();
int needle_length = needle->length();
while (true) {
- LOG(RegExpExecEvent(re, index, subject));
int value = -1;
if (index + needle_length <= subject_length) {
value = Runtime::StringMatch(subject, needle, index);
@@ -575,8 +573,6 @@
reinterpret_cast<v8::jscre::JscreRegExp*>(
internal->GetDataStartAddress());
- LOG(RegExpExecEvent(regexp, previous_index, subject));
-
rc = v8::jscre::jsRegExpExecute(js_regexp,
two_byte_subject,
subject->length(),
@@ -791,7 +787,6 @@
PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
}
#endif
- LOG(RegExpExecEvent(regexp, previous_index, subject));
if (!subject->IsFlat(StringShape(*subject))) {
FlattenString(subject);
@@ -845,7 +840,6 @@
PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
}
#endif
- LOG(RegExpExecEvent(regexp, previous_index, subject));
matches = IrregexpExecOnce(irregexp,
IrregexpNumberOfCaptures(irregexp),
subject,
Modified: branches/bleeding_edge/src/log.cc
==============================================================================
--- branches/bleeding_edge/src/log.cc (original)
+++ branches/bleeding_edge/src/log.cc Tue Jan 6 05:24:52 2009
@@ -350,11 +350,19 @@
#ifdef ENABLE_LOGGING_AND_PROFILING
-void Logger::LogString(Handle<String> str) {
+void Logger::LogString(Handle<String> str, bool show_impl_info) {
StringShape shape(*str);
int len = str->length(shape);
- if (len > 256)
- len = 256;
+ if (len > 0x1000)
+ len = 0x1000;
+ if (show_impl_info) {
+ fputc(shape.IsAsciiRepresentation() ? 'a' : '2', logfile_);
+ if (shape.IsExternal())
+ fputc('e', logfile_);
+ if (shape.IsSymbol())
+ fputc('#', logfile_);
+ fprintf(logfile_, ":%i:", str->length());
+ }
for (int i = 0; i < len; i++) {
uc32 c = str->Get(shape, i);
if (c > 0xff) {
@@ -389,7 +397,7 @@
break;
}
fprintf(logfile_, "/");
- LogString(Handle<String>::cast(source));
+ LogString(Handle<String>::cast(source), false);
fprintf(logfile_, "/");
// global flag
@@ -423,19 +431,40 @@
}
-void Logger::RegExpExecEvent(Handle<JSRegExp> regexp,
- int start_index,
- Handle<String> input_string) {
-#ifdef ENABLE_LOGGING_AND_PROFILING
- if (logfile_ == NULL || !FLAG_log_regexp) return;
+void Logger::LogRuntime(Vector<const char> format, JSArray* args) {
ScopedLock sl(mutex_);
-
- fprintf(logfile_, "regexp-run,");
- LogRegExpSource(regexp);
- fprintf(logfile_, ",");
- LogString(input_string);
- fprintf(logfile_, ",%d..%d\n", start_index, input_string->length());
-#endif
+ HandleScope scope;
+ for (int i = 0; i < format.length(); i++) {
+ char c = format[i];
+ if (c == '%' && i <= format.length() - 2) {
+ i++;
+ ASSERT('0' <= format[i] && format[i] <= '9');
+ Object* obj = args->GetElement(format[i] - '0');
+ i++;
+ switch (format[i]) {
+ case 's':
+ Logger::LogString(Handle<String>(String::cast(obj)), false);
+ break;
+ case 'S':
+ Logger::LogString(Handle<String>(String::cast(obj)), true);
+ break;
+ case 'r':
+ Logger::LogRegExpSource(Handle<JSRegExp>(JSRegExp::cast(obj)));
+ break;
+ case 'x':
+ fprintf(logfile_, "0x%x", Smi::cast(obj)->value());
+ break;
+ case 'i':
+ fprintf(logfile_, "%i", Smi::cast(obj)->value());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ } else {
+ fputc(c, logfile_);
+ }
+ }
+ fputc('\n', logfile_);
}
Modified: branches/bleeding_edge/src/log.h
==============================================================================
--- branches/bleeding_edge/src/log.h (original)
+++ branches/bleeding_edge/src/log.h Tue Jan 6 05:24:52 2009
@@ -72,7 +72,11 @@
#undef LOG
#ifdef ENABLE_LOGGING_AND_PROFILING
-#define LOG(Call) v8::internal::Logger::Call
+#define LOG(Call) \
+ do { \
+ if (v8::internal::Logger::is_enabled()) \
+ v8::internal::Logger::Call; \
+ } while (false)
#else
#define LOG(Call) ((void) 0)
#endif
@@ -189,9 +193,8 @@
static void RegExpCompileEvent(Handle<JSRegExp> regexp, bool in_cache);
- static void RegExpExecEvent(Handle<JSRegExp> regexp,
- int start_index,
- Handle<String> input_string);
+ // Log an event reported from generated code
+ static void LogRuntime(Vector<const char> format, JSArray* args);
#ifdef ENABLE_LOGGING_AND_PROFILING
static StateTag state() {
@@ -199,13 +202,15 @@
}
#endif
+ static bool is_enabled() { return logfile_ != NULL; }
+
#ifdef ENABLE_LOGGING_AND_PROFILING
private:
// Emits the source code of a regexp. Used by regexp events.
static void LogRegExpSource(Handle<JSRegExp> regexp);
- static void LogString(Handle<String> str);
+ static void LogString(Handle<String> str, bool show_impl_info);
// Emits a profiler tick event. Used by the profiler thread.
static void TickEvent(TickSample* sample, bool overflow);
Modified: branches/bleeding_edge/src/regexp-delay.js
==============================================================================
--- branches/bleeding_edge/src/regexp-delay.js (original)
+++ branches/bleeding_edge/src/regexp-delay.js Tue Jan 6 05:24:52 2009
@@ -178,6 +178,7 @@
return null;
}
+ %_Log('regexp', 'regexp-exec,%0r,%1S,%2i', [this, s, lastIndex]);
// matchIndices is an array of integers with length of captures*2,
// each pair of integers specified the start and the end of index
// in the string.
Modified: branches/bleeding_edge/src/runtime.cc
==============================================================================
--- branches/bleeding_edge/src/runtime.cc (original)
+++ branches/bleeding_edge/src/runtime.cc Tue Jan 6 05:24:52 2009
@@ -5840,6 +5840,16 @@
#endif
+static Object* Runtime_Log(Arguments args) {
+ ASSERT(args.length() == 2);
+ String* format = String::cast(args[0]);
+ Vector<const char> chars = format->ToAsciiVector();
+ JSArray* elms = JSArray::cast(args[1]);
+ Logger::LogRuntime(chars, elms);
+ return Heap::undefined_value();
+}
+
+
static Object* Runtime_IS_VAR(Arguments args) {
UNREACHABLE(); // implemented as macro in the parser
return NULL;
Modified: branches/bleeding_edge/src/runtime.h
==============================================================================
--- branches/bleeding_edge/src/runtime.h (original)
+++ branches/bleeding_edge/src/runtime.h Tue Jan 6 05:24:52 2009
@@ -285,6 +285,8 @@
F(DebugBreak, 0) \
F(FunctionGetAssemblerCode, 1) \
F(Abort, 2) \
+ /* Logging */ \
+ F(Log, 2) \
\
/* Pseudo functions - handled as macros by parser */ \
F(IS_VAR, 1)
Modified: branches/bleeding_edge/src/string.js
==============================================================================
--- branches/bleeding_edge/src/string.js (original)
+++ branches/bleeding_edge/src/string.js Tue Jan 6 05:24:52 2009
@@ -152,6 +152,7 @@
var subject = ToString(this);
if (!regexp.global) return regexp.exec(subject);
+ %_Log('regexp', 'regexp-match,%0S,%1r', [subject, regexp]);
var matches = DoRegExpExecGlobal(regexp, subject);
// If the regexp did not match, return null.
@@ -185,6 +186,7 @@
// Delegate to one of the regular expression variants if necessary.
if (IS_REGEXP(search)) {
+ %_Log('regexp', 'regexp-replace,%0r,%1S', [search, subject]);
if (IS_FUNCTION(replace)) {
return StringReplaceRegExpWithFunction(subject, search, replace);
} else {
@@ -513,7 +515,13 @@
var currentIndex = 0;
var startIndex = 0;
- var sep = IS_REGEXP(separator) ? separator : ToString(separator);
+ var sep;
+ if (IS_REGEXP(separator)) {
+ sep = separator;
+ %_Log('regexp', 'regexp-split,%0S,%1r', [subject, sep]);
+ } else {
+ sep = ToString(separator);
+ }
if (length === 0) {
if (splitMatch(sep, subject, 0, 0) != null) return result;
Modified: branches/bleeding_edge/test/mjsunit/fuzz-natives.js
==============================================================================
--- branches/bleeding_edge/test/mjsunit/fuzz-natives.js (original)
+++ branches/bleeding_edge/test/mjsunit/fuzz-natives.js Tue Jan 6 05:24:52
2009
@@ -123,7 +123,8 @@
"CreateObjectLiteralBoilerplate": true,
"CloneObjectLiteralBoilerplate": true,
"IS_VAR": true,
- "ResolvePossiblyDirectEval": true
+ "ResolvePossiblyDirectEval": true,
+ "Log": true
};
var currentlyUncallable = {
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---