Author: [EMAIL PROTECTED]
Date: Thu Sep 11 01:45:22 2008
New Revision: 266
Added:
changes/lrn/
changes/lrn/lrn_relog/
changes/lrn/lrn_relog/bleeding_edge/
- copied from r263, /branches/bleeding_edge/
Modified:
changes/lrn/lrn_relog/bleeding_edge/src/jsregexp.cc
changes/lrn/lrn_relog/bleeding_edge/src/log.cc
changes/lrn/lrn_relog/bleeding_edge/src/log.h
changes/lrn/lrn_relog/bleeding_edge/src/messages.cc
changes/lrn/lrn_relog/bleeding_edge/src/objects.cc
changes/lrn/lrn_relog/bleeding_edge/src/objects.h
changes/lrn/lrn_relog/bleeding_edge/src/smart-pointer.h
Log:
Added -log-regexp option to log all compilations and executions of regular
expressions.
Slightly modified SmartPointer.
Made String.ToWideCString return a SmartPointer instead of a plain pointer.
Modified: changes/lrn/lrn_relog/bleeding_edge/src/jsregexp.cc
==============================================================================
--- /branches/bleeding_edge/src/jsregexp.cc (original)
+++ changes/lrn/lrn_relog/bleeding_edge/src/jsregexp.cc Thu Sep 11 01:45:22
2008
@@ -205,6 +205,8 @@
value->set(INTERNAL_INDEX, *internal);
re->set_value(*value);
+ LOG(RegExpCompileEvent(re));
+
return re;
}
@@ -222,6 +224,8 @@
ByteArray* internal = JsreInternal(regexp);
const JSRegExp* js_regexp =
reinterpret_cast<JSRegExp*>(internal->GetDataStartAddress());
+
+ LOG(RegExpExecEvent(regexp, previous_index, subject));
rc = jsRegExpExecute(js_regexp, two_byte_subject,
subject->length(),
Modified: changes/lrn/lrn_relog/bleeding_edge/src/log.cc
==============================================================================
--- /branches/bleeding_edge/src/log.cc (original)
+++ changes/lrn/lrn_relog/bleeding_edge/src/log.cc Thu Sep 11 01:45:22 2008
@@ -52,6 +52,8 @@
DEFINE_bool(log_suspect, false, "Log suspect operations.");
DEFINE_bool(prof, false,
"Log statistical profiling information (implies --log-code).");
+DEFINE_bool(log_regexp, false,
+ "Log regular expression execution.");
DEFINE_bool(sliding_state_window, false,
"Update sliding state window counters.");
@@ -368,6 +370,76 @@
#endif
}
+void Logger::LogRegExpSource(const Handle<JSValue> val) {
+ // Prints "/" + re.source + "/" +
+ // (re.global?"g":"") + (re.ignorecase?"i":"") +
(re.multiline?"m":"")
+
+ Handle<Object> source = GetProperty(val, "source");
+ if (!source->IsString()) {
+ fprintf(logfile_, "no source");
+ return;
+ }
+ Handle<String> sourceString = Handle<String>::cast(source);
+
+ SmartPointer<uc16> cstringAlloc = sourceString->ToWideCString();
+ fprintf(logfile_, "/");
+ for(size_t i = 0, n = sourceString->length(); i < n; i++) {
+ uc16 c = cstringAlloc[i];
+ if (c < 32 || (c > 126 && c <= 255)) {
+ fprintf(logfile_, "\\x%02x", c);
+ } else if (c > 255) {
+ fprintf(logfile_, "\\u%04x", c);
+ } else {
+ fprintf(logfile_, "%lc", c);
+ }
+ }
+ fprintf(logfile_, "/");
+
+ // global flag
+ Handle<Object> global = GetProperty(val, "global");
+ if (global->IsTrue()) {
+ fprintf(logfile_, "g");
+ }
+ // ignorecase flag
+ Handle<Object> ignorecase = GetProperty(val, "ignoreCase");
+ if (ignorecase->IsTrue()) {
+ fprintf(logfile_, "i");
+ }
+ // multiline flag
+ Handle<Object> multiline = GetProperty(val, "multiline");
+ if (multiline->IsTrue()) {
+ fprintf(logfile_, "m");
+ }
+}
+
+
+void Logger::RegExpCompileEvent(const Handle<JSValue> pattern) {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+ if (logfile_ == NULL || !FLAG_log_regexp) { return; }
+ ScopedLock sl(mutex_);
+
+ fprintf(logfile_, "regexp-compile,");
+ LogRegExpSource(pattern);
+ fprintf(logfile_, "\n");
+
+#endif
+}
+
+
+void Logger::RegExpExecEvent(const Handle<JSValue> val,
+ int start_index,
+ Handle<String> string)
{
+#ifdef ENABLE_LOGGING_AND_PROFILING
+ if (logfile_ == NULL || !FLAG_log_regexp) { return; }
+ ScopedLock sl(mutex_);
+
+ fprintf(logfile_, "regexp-run,");
+ LogRegExpSource(val);
+ fprintf(logfile_, ",0x%08x,%d..%d\n", string->Hash(), start_index,
string->length());
+#endif
+}
+
+
void Logger::ApiIndexedSecurityCheck(uint32_t index) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (logfile_ == NULL || !FLAG_log_api) return;
@@ -612,6 +684,7 @@
FLAG_log_gc = true;
FLAG_log_suspect = true;
FLAG_log_handles = true;
+ FLAG_log_regexp = true;
}
// --prof implies --log-code.
@@ -620,7 +693,7 @@
// Each of the individual log flags implies --log. Check after
// checking --log-all and --prof in case they set --log-code.
if (FLAG_log_api || FLAG_log_code || FLAG_log_gc ||
- FLAG_log_handles || FLAG_log_suspect) {
+ FLAG_log_handles || FLAG_log_suspect || FLAG_log_regexp) {
FLAG_log = true;
}
Modified: changes/lrn/lrn_relog/bleeding_edge/src/log.h
==============================================================================
--- /branches/bleeding_edge/src/log.h (original)
+++ changes/lrn/lrn_relog/bleeding_edge/src/log.h Thu Sep 11 01:45:22 2008
@@ -174,6 +174,14 @@
unsigned start,
unsigned end);
+ // ==== Events logged by --log-regexp ====
+ // Regexp compilation and execution events.
+
+ static void RegExpCompileEvent(const Handle<JSValue> regexp);
+
+ static void RegExpExecEvent(
+ const Handle<JSValue> regexp, int start_index, Handle<String> string);
+
#ifdef ENABLE_LOGGING_AND_PROFILING
static StateTag state() {
return current_state_ ? current_state_->state() : OTHER;
@@ -182,6 +190,10 @@
#ifdef ENABLE_LOGGING_AND_PROFILING
private:
+
+ // Emits the source code of a regexp. Used by regexp events.
+ static void Logger::LogRegExpSource(const Handle<JSValue> regexp);
+
// Emits a profiler tick event. Used by the profiler thread.
static void TickEvent(TickSample* sample, bool overflow);
Modified: changes/lrn/lrn_relog/bleeding_edge/src/messages.cc
==============================================================================
--- /branches/bleeding_edge/src/messages.cc (original)
+++ changes/lrn/lrn_relog/bleeding_edge/src/messages.cc Thu Sep 11 01:45:22
2008
@@ -46,7 +46,7 @@
} else {
HandleScope scope;
Handle<Object> data(loc->script()->name());
- SmartPointer<char> data_str = NULL;
+ SmartPointer<char> data_str;
if (data->IsString())
data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS);
PrintF("%s:%i: %s\n", *data_str ? *data_str : "<unknown>",
Modified: changes/lrn/lrn_relog/bleeding_edge/src/objects.cc
==============================================================================
--- /branches/bleeding_edge/src/objects.cc (original)
+++ changes/lrn/lrn_relog/bleeding_edge/src/objects.cc Thu Sep 11 01:45:22
2008
@@ -3023,11 +3023,11 @@
}
-uc16* String::ToWideCString(RobustnessFlag robust_flag) {
+SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) {
ASSERT(NativeAllocationChecker::allocation_allowed());
if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) {
- return NULL;
+ return SmartPointer<uc16>();
}
Access<StringInputBuffer> buffer(&string_input_buffer);
@@ -3041,7 +3041,7 @@
result[i++] = character;
}
result[i] = 0;
- return result;
+ return SmartPointer<uc16>(result);
}
Modified: changes/lrn/lrn_relog/bleeding_edge/src/objects.h
==============================================================================
--- /branches/bleeding_edge/src/objects.h (original)
+++ changes/lrn/lrn_relog/bleeding_edge/src/objects.h Thu Sep 11 01:45:22
2008
@@ -2864,7 +2864,7 @@
// ROBUST_STRING_TRAVERSAL invokes behaviour that is robust This means
it
// handles unexpected data without causing assert failures and it does
not
// do any heap allocations. This is useful when printing stack traces.
- uc16* ToWideCString(RobustnessFlag robustness_flag =
FAST_STRING_TRAVERSAL);
+ SmartPointer<uc16> ToWideCString(RobustnessFlag robustness_flag =
FAST_STRING_TRAVERSAL);
// Tells whether the hash code has been computed.
inline bool HasHashCode();
Modified: changes/lrn/lrn_relog/bleeding_edge/src/smart-pointer.h
==============================================================================
--- /branches/bleeding_edge/src/smart-pointer.h (original)
+++ changes/lrn/lrn_relog/bleeding_edge/src/smart-pointer.h Thu Sep 11
01:45:22 2008
@@ -31,19 +31,18 @@
namespace v8 { namespace internal {
-// A 'scoped pointer' that calls delete[] on its pointer when the
+// A 'scoped array pointer' that calls DeleteArray on its pointer when the
// destructor is called.
template<typename T>
class SmartPointer {
public:
- // Construct a scoped pointer from a plain one.
- inline SmartPointer(T* pointer) : p(pointer) {}
+ // Default constructor. Construct an empty scoped pointer.
+ inline SmartPointer() : p(NULL) {}
- // When the destructor of the scoped pointer is executed the plain
pointer
- // is deleted using DeleteArray. This implies that you must allocate
with
- // NewArray.
- inline ~SmartPointer() { if (p) DeleteArray(p); }
+
+ // Construct a scoped pointer from a plain one.
+ explicit inline SmartPointer(T* pointer) : p(pointer) {}
// Copy constructor removes the pointer from the original to avoid double
@@ -53,13 +52,20 @@
}
+ // When the destructor of the scoped pointer is executed the plain
pointer
+ // is deleted using DeleteArray. This implies that you must allocate
with
+ // NewArray.
+ inline ~SmartPointer() { if (p) DeleteArray(p); }
+
+
// You can get the underlying pointer out with the * operator.
inline T* operator*() { return p; }
- // You can use -> as if it was a plain pointer.
- inline T* operator->() { return p; }
-
+ // You can use [n] to index as if it was a plain pointer
+ inline T& operator[](size_t i) {
+ return p[i];
+ }
// We don't have implicit conversion to a T* since that hinders
migration:
// You would not be able to change a method from returning a T* to
@@ -81,9 +87,10 @@
// double freeing.
inline SmartPointer& operator=(const SmartPointer<T>& rhs) {
ASSERT(p == NULL);
- p = rhs.p;
- const_cast<SmartPointer<T>&>(rhs).p = NULL;
- return *this;
+ T* tmp = rhs.p; // swap to handle self-assignment
+ const_cast<SmartPointer<T>&>(rhs).p = NULL;
+ p = tmp;
+ return *this;
}
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---