Revision: 3351
Author: [email protected]
Date: Tue Nov 24 06:29:16 2009
Log: Push version 2.0.2 to trunk.

Improved profiler support.

Fixed bug that broke compilation of d8 with readline support.

http://code.google.com/p/v8/source/detail?r=3351

Modified:
  /trunk/ChangeLog
  /trunk/src/allocation.h
  /trunk/src/builtins.cc
  /trunk/src/compiler.cc
  /trunk/src/flag-definitions.h
  /trunk/src/log-inl.h
  /trunk/src/log.cc
  /trunk/src/log.h
  /trunk/src/serialize.cc
  /trunk/src/v8.cc
  /trunk/src/version.cc
  /trunk/test/cctest/test-log.cc
  /trunk/test/cctest/test-thread-termination.cc
  /trunk/tools/gyp/v8.gyp

=======================================
--- /trunk/ChangeLog    Fri Nov 20 04:14:52 2009
+++ /trunk/ChangeLog    Tue Nov 24 06:29:16 2009
@@ -1,3 +1,10 @@
+2009-11-24: Version 2.0.2
+
+        Improved profiler support.
+
+        Fixed bug that broke compilation of d8 with readline support.
+
+
  2009-11-20: Version 2.0.1

          Fixed crash bug in String.prototype.replace.
=======================================
--- /trunk/src/allocation.h     Mon May 25 22:44:31 2009
+++ /trunk/src/allocation.h     Tue Nov 24 06:29:16 2009
@@ -124,7 +124,7 @@
  // and StrNDup uses new and calls the FatalProcessOutOfMemory handler
  // if allocation fails.
  char* StrDup(const char* str);
-char* StrNDup(const char* str, size_t n);
+char* StrNDup(const char* str, int n);


  // Allocation policy for allocating in the C free store using malloc
=======================================
--- /trunk/src/builtins.cc      Wed Oct 28 07:53:37 2009
+++ /trunk/src/builtins.cc      Tue Nov 24 06:29:16 2009
@@ -380,6 +380,9 @@
      {
        // Leaving JavaScript.
        VMState state(EXTERNAL);
+#ifdef ENABLE_LOGGING_AND_PROFILING
+      state.set_external_callback(v8::ToCData<Address>(callback_obj));
+#endif
        value = callback(new_args);
      }
      if (value.IsEmpty()) {
@@ -446,6 +449,9 @@
      {
        // Leaving JavaScript.
        VMState state(EXTERNAL);
+#ifdef ENABLE_LOGGING_AND_PROFILING
+      state.set_external_callback(v8::ToCData<Address>(callback_obj));
+#endif
        value = callback(new_args);
      }
      if (value.IsEmpty()) {
=======================================
--- /trunk/src/compiler.cc      Fri Nov 20 04:14:52 2009
+++ /trunk/src/compiler.cc      Tue Nov 24 06:29:16 2009
@@ -646,9 +646,8 @@


  void CodeGenSelector::VisitDeclaration(Declaration* decl) {
-  Variable* var = decl->proxy()->var();
-  if (!var->is_global() || var->mode() == Variable::CONST) {
-    BAILOUT("Non-global declaration");
+  if (decl->fun() != NULL) {
+    ProcessExpression(decl->fun(), Expression::kValue);
    }
  }

=======================================
--- /trunk/src/flag-definitions.h       Wed Nov 18 06:12:51 2009
+++ /trunk/src/flag-definitions.h       Tue Nov 24 06:29:16 2009
@@ -143,7 +143,7 @@
  DEFINE_bool(strict, false, "strict error checking")
  DEFINE_int(min_preparse_length, 1024,
             "minimum length for automatic enable preparsing")
-DEFINE_bool(fast_compiler, true,
+DEFINE_bool(fast_compiler, false,
              "use the fast-mode compiler for some top-level code")
  DEFINE_bool(trace_bailout, false,
              "print reasons for failing to use fast compilation")
=======================================
--- /trunk/src/log-inl.h        Wed Sep  9 12:27:10 2009
+++ /trunk/src/log-inl.h        Tue Nov 24 06:29:16 2009
@@ -55,7 +55,7 @@
    }
  }

-VMState::VMState(StateTag state) : disabled_(true) {
+VMState::VMState(StateTag state) : disabled_(true),  
external_callback_(NULL) {
    if (!Logger::is_logging()) {
      return;
    }
=======================================
--- /trunk/src/log.cc   Wed Nov 18 06:12:51 2009
+++ /trunk/src/log.cc   Tue Nov 24 06:29:16 2009
@@ -30,6 +30,7 @@
  #include "v8.h"

  #include "bootstrapper.h"
+#include "global-handles.h"
  #include "log.h"
  #include "macro-assembler.h"
  #include "serialize.h"
@@ -153,13 +154,19 @@
      sample->frames_count = 0;
      return;
    }
+
+  int i = 0;
+  const Address callback = Logger::current_state_ != NULL ?
+      Logger::current_state_->external_callback() : NULL;
+  if (callback != NULL) {
+    sample->stack[i++] = callback;
+  }

    SafeStackTraceFrameIterator it(
        reinterpret_cast<Address>(sample->fp),
        reinterpret_cast<Address>(sample->sp),
        reinterpret_cast<Address>(sample->sp),
        js_entry_sp);
-  int i = 0;
    while (!it.done() && i < TickSample::kMaxFramesCount) {
      sample->stack[i++] = it.frame()->pc();
      it.Advance();
@@ -673,6 +680,26 @@
  #endif  // ENABLE_LOGGING_AND_PROFILING


+void Logger::CallbackEvent(String* name, Address entry_point) {
+#ifdef ENABLE_LOGGING_AND_PROFILING
+  if (!Log::IsEnabled() || !FLAG_log_code) return;
+  LogMessageBuilder msg;
+  msg.Append("%s,%s,",
+             log_events_[CODE_CREATION_EVENT], log_events_[CALLBACK_TAG]);
+  msg.AppendAddress(entry_point);
+  SmartPointer<char> str =
+      name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
+  msg.Append(",1,\"%s\"", *str);
+  if (FLAG_compress_log) {
+    ASSERT(compression_helper_ != NULL);
+    if (!compression_helper_->HandleMessage(&msg)) return;
+  }
+  msg.Append('\n');
+  msg.WriteToLogFile();
+#endif
+}
+
+
  void Logger::CodeCreateEvent(LogEventsAndTags tag,
                               Code* code,
                               const char* comment) {
@@ -1191,11 +1218,25 @@
            LOG(CodeCreateEvent(Logger::SCRIPT_TAG,
                                shared->code(), *script_name));
          }
-        continue;
-      }
-    }
-    // If no script or script has no name.
-    LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG, shared->code(),  
*func_name));
+      } else {
+        LOG(CodeCreateEvent(
+            Logger::LAZY_COMPILE_TAG, shared->code(), *func_name));
+      }
+    } else if (shared->function_data()->IsFunctionTemplateInfo()) {
+      // API function.
+      FunctionTemplateInfo* fun_data =
+          FunctionTemplateInfo::cast(shared->function_data());
+      Object* raw_call_data = fun_data->call_code();
+      if (!raw_call_data->IsUndefined()) {
+        CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
+        Object* callback_obj = call_data->callback();
+        Address entry_point = v8::ToCData<Address>(callback_obj);
+        LOG(CallbackEvent(*func_name, entry_point));
+      }
+    } else {
+      LOG(CodeCreateEvent(
+          Logger::LAZY_COMPILE_TAG, shared->code(), *func_name));
+    }
    }

    DeleteArray(sfis);
=======================================
--- /trunk/src/log.h    Wed Nov 18 06:12:51 2009
+++ /trunk/src/log.h    Tue Nov 24 06:29:16 2009
@@ -91,15 +91,20 @@
  class VMState BASE_EMBEDDED {
  #ifdef ENABLE_LOGGING_AND_PROFILING
   public:
-  inline explicit VMState(StateTag state);
+  inline VMState(StateTag state);
    inline ~VMState();

    StateTag state() { return state_; }
+  Address external_callback() { return external_callback_; }
+  void set_external_callback(Address external_callback) {
+    external_callback_ = external_callback;
+  }

   private:
    bool disabled_;
    StateTag state_;
    VMState* previous_;
+  Address external_callback_;
  #else
   public:
    explicit VMState(StateTag state) {}
@@ -122,6 +127,7 @@
    V(CALL_MISS_TAG,                  "CallMiss",               "cm")       \
    V(CALL_NORMAL_TAG,                "CallNormal",             "cn")       \
    V(CALL_PRE_MONOMORPHIC_TAG,       "CallPreMonomorphic",     "cpm")      \
+  V(CALLBACK_TAG,                   "Callback",               "cb")       \
    V(EVAL_TAG,                       "Eval",                   "e")        \
    V(FUNCTION_TAG,                   "Function",               "f")        \
    V(KEYED_LOAD_IC_TAG,              "KeyedLoadIC",            "klic")     \
@@ -200,6 +206,8 @@


    // ==== Events logged by --log-code. ====
+  // Emits a code event for a callback function.
+  static void CallbackEvent(String* name, Address entry_point);
    // Emits a code create event.
    static void CodeCreateEvent(LogEventsAndTags tag,
                                Code* code, const char* source);
@@ -330,6 +338,7 @@
    friend class TimeLog;
    friend class Profiler;
    friend class SlidingStateWindow;
+  friend class StackTracer;
    friend class VMState;

    friend class LoggerTestHelper;
=======================================
--- /trunk/src/serialize.cc     Wed Nov 18 06:12:51 2009
+++ /trunk/src/serialize.cc     Tue Nov 24 06:29:16 2009
@@ -668,7 +668,7 @@
          break;
        case OBJECT_SERIALIZATION + CODE_SPACE:
          ReadObject(CODE_SPACE, Heap::code_space(), current++);
-        Logger::LogCodeObject(current[-1]);
+        LOG(LogCodeObject(current[-1]));
          break;
        case OBJECT_SERIALIZATION + CELL_SPACE:
          ReadObject(CELL_SPACE, Heap::cell_space(), current++);
@@ -678,7 +678,7 @@
          break;
        case OBJECT_SERIALIZATION + kLargeCode:
          ReadObject(kLargeCode, Heap::lo_space(), current++);
-        Logger::LogCodeObject(current[-1]);
+        LOG(LogCodeObject(current[-1]));
          break;
        case OBJECT_SERIALIZATION + kLargeFixedArray:
          ReadObject(kLargeFixedArray, Heap::lo_space(), current++);
@@ -687,7 +687,7 @@
          Object* new_code_object = NULL;
          ReadObject(kLargeCode, Heap::lo_space(), &new_code_object);
          Code* code_object = reinterpret_cast<Code*>(new_code_object);
-        Logger::LogCodeObject(code_object);
+        LOG(LogCodeObject(code_object));
          // Setting a branch/call to another code object from code.
          Address location_of_branch_data =  
reinterpret_cast<Address>(current);
          Assembler::set_target_at(location_of_branch_data,
@@ -700,7 +700,7 @@
          Object* new_code_object = NULL;
          ReadObject(CODE_SPACE, Heap::code_space(), &new_code_object);
          Code* code_object = reinterpret_cast<Code*>(new_code_object);
-        Logger::LogCodeObject(code_object);
+        LOG(LogCodeObject(code_object));
          // Setting a branch/call to another code object from code.
          Address location_of_branch_data =  
reinterpret_cast<Address>(current);
          Assembler::set_target_at(location_of_branch_data,
=======================================
--- /trunk/src/v8.cc    Wed Nov 18 06:12:51 2009
+++ /trunk/src/v8.cc    Tue Nov 24 06:29:16 2009
@@ -116,7 +116,7 @@

    if (FLAG_log_code) {
      HandleScope scope;
-    Logger::LogCompiledFunctions();
+    LOG(LogCompiledFunctions());
    }

    return true;
=======================================
--- /trunk/src/version.cc       Fri Nov 20 04:14:52 2009
+++ /trunk/src/version.cc       Tue Nov 24 06:29:16 2009
@@ -34,7 +34,7 @@
  // cannot be changed without changing the SCons build script.
  #define MAJOR_VERSION     2
  #define MINOR_VERSION     0
-#define BUILD_NUMBER      1
+#define BUILD_NUMBER      2
  #define PATCH_LEVEL       0
  #define CANDIDATE_VERSION false

=======================================
--- /trunk/test/cctest/test-log.cc      Wed Nov 18 06:12:51 2009
+++ /trunk/test/cctest/test-log.cc      Tue Nov 24 06:29:16 2009
@@ -247,7 +247,7 @@
    i::FLAG_logfile = "*";

    // If tests are being run manually, V8 will be already initialized
-  // by the test below.
+  // by the bottom test.
    const bool need_to_set_up_logger = i::V8::IsRunning();
    v8::HandleScope scope;
    v8::Handle<v8::Context> env = v8::Context::New();
@@ -472,6 +472,70 @@
    // Must not crash.
    i::Logger::LogCompiledFunctions();
  }
+
+
+static v8::Handle<v8::Value> ObjMethod1(const v8::Arguments& args) {
+  return v8::Handle<v8::Value>();
+}
+
+TEST(LogCallbacks) {
+  const bool saved_prof_lazy = i::FLAG_prof_lazy;
+  const bool saved_prof = i::FLAG_prof;
+  const bool saved_prof_auto = i::FLAG_prof_auto;
+  i::FLAG_prof = true;
+  i::FLAG_prof_lazy = false;
+  i::FLAG_prof_auto = false;
+  i::FLAG_logfile = "*";
+
+  // If tests are being run manually, V8 will be already initialized
+  // by the bottom test.
+  const bool need_to_set_up_logger = i::V8::IsRunning();
+  v8::HandleScope scope;
+  v8::Handle<v8::Context> env = v8::Context::New();
+  if (need_to_set_up_logger) Logger::Setup();
+  env->Enter();
+
+  // Skip all initially logged stuff.
+  EmbeddedVector<char, 102400> buffer;
+  int log_pos = GetLogLines(0, &buffer);
+
+  v8::Persistent<v8::FunctionTemplate> obj =
+       
v8::Persistent<v8::FunctionTemplate>::New(v8::FunctionTemplate::New());
+  obj->SetClassName(v8::String::New("Obj"));
+  v8::Handle<v8::ObjectTemplate> proto = obj->PrototypeTemplate();
+  v8::Local<v8::Signature> signature = v8::Signature::New(obj);
+  proto->Set(v8::String::New("method1"),
+             v8::FunctionTemplate::New(ObjMethod1,
+                                       v8::Handle<v8::Value>(),
+                                       signature),
+             static_cast<v8::PropertyAttribute>(v8::DontDelete));
+
+  env->Global()->Set(v8_str("Obj"), obj->GetFunction());
+  CompileAndRunScript("Obj.prototype.method1.toString();");
+
+  i::Logger::LogCompiledFunctions();
+  log_pos = GetLogLines(log_pos, &buffer);
+  CHECK_GT(log_pos, 0);
+  buffer[log_pos] = 0;
+
+  const char* callback_rec = "code-creation,Callback,";
+  char* pos = strstr(buffer.start(), callback_rec);
+  CHECK_NE(NULL, pos);
+  pos += strlen(callback_rec);
+  EmbeddedVector<char, 100> ref_data;
+  i::OS::SNPrintF(ref_data,
+                  "0x%" V8PRIxPTR ",1,\"method1\"", ObjMethod1);
+  *(pos + strlen(ref_data.start())) = '\0';
+  CHECK_EQ(ref_data.start(), pos);
+
+  obj.Dispose();
+
+  env->Exit();
+  Logger::TearDown();
+  i::FLAG_prof_lazy = saved_prof_lazy;
+  i::FLAG_prof = saved_prof;
+  i::FLAG_prof_auto = saved_prof_auto;
+}


  static inline bool IsStringEqualTo(const char* r, const char* s) {
=======================================
--- /trunk/test/cctest/test-thread-termination.cc       Wed Sep  2 01:22:29 2009
+++ /trunk/test/cctest/test-thread-termination.cc       Tue Nov 24 06:29:16 2009
@@ -80,16 +80,32 @@
    CHECK(!try_catch.CanContinue());
    return v8::Undefined();
  }
+
+
+v8::Handle<v8::Value> DoLoopNoCall(const v8::Arguments& args) {
+  v8::TryCatch try_catch;
+  v8::Script::Compile(v8::String::New("var term = true;"
+                                      "while(true) {"
+                                      "  if (term) terminate();"
+                                      "  term = false;"
+                                      "}"))->Run();
+  CHECK(try_catch.HasCaught());
+  CHECK(try_catch.Exception()->IsNull());
+  CHECK(try_catch.Message().IsEmpty());
+  CHECK(!try_catch.CanContinue());
+  return v8::Undefined();
+}


  v8::Handle<v8::ObjectTemplate> CreateGlobalTemplate(
-    v8::InvocationCallback terminate) {
+    v8::InvocationCallback terminate,
+    v8::InvocationCallback doloop) {
    v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
    global->Set(v8::String::New("terminate"),
                v8::FunctionTemplate::New(terminate));
    global->Set(v8::String::New("fail"), v8::FunctionTemplate::New(Fail));
    global->Set(v8::String::New("loop"), v8::FunctionTemplate::New(Loop));
-  global->Set(v8::String::New("doloop"),  
v8::FunctionTemplate::New(DoLoop));
+  global->Set(v8::String::New("doloop"),  
v8::FunctionTemplate::New(doloop));
    return global;
  }

@@ -99,7 +115,7 @@
  TEST(TerminateOnlyV8ThreadFromThreadItself) {
    v8::HandleScope scope;
    v8::Handle<v8::ObjectTemplate> global =
-      CreateGlobalTemplate(TerminateCurrentThread);
+      CreateGlobalTemplate(TerminateCurrentThread, DoLoop);
    v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
    v8::Context::Scope context_scope(context);
    // Run a loop that will be infinite if thread termination does not work.
@@ -110,6 +126,24 @@
    v8::Script::Compile(source)->Run();
    context.Dispose();
  }
+
+
+// Test that a single thread of JavaScript execution can terminate
+// itself in a loop that performs no calls.
+TEST(TerminateOnlyV8ThreadFromThreadItselfNoLoop) {
+  v8::HandleScope scope;
+  v8::Handle<v8::ObjectTemplate> global =
+      CreateGlobalTemplate(TerminateCurrentThread, DoLoopNoCall);
+  v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
+  v8::Context::Scope context_scope(context);
+  // Run a loop that will be infinite if thread termination does not work.
+  v8::Handle<v8::String> source =
+      v8::String::New("try { loop(); fail(); } catch(e) { fail(); }");
+  v8::Script::Compile(source)->Run();
+  // Test that we can run the code again after thread termination.
+  v8::Script::Compile(source)->Run();
+  context.Dispose();
+}


  class TerminatorThread : public v8::internal::Thread {
@@ -128,7 +162,7 @@
    thread.Start();

    v8::HandleScope scope;
-  v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal);
+  v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal,  
DoLoop);
    v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
    v8::Context::Scope context_scope(context);
    // Run a loop that will be infinite if thread termination does not work.
@@ -149,7 +183,8 @@
      v8::Locker locker;
      v8::HandleScope scope;
      v8_thread_id_ = v8::V8::GetCurrentThreadId();
-    v8::Handle<v8::ObjectTemplate> global = CreateGlobalTemplate(Signal);
+    v8::Handle<v8::ObjectTemplate> global =
+        CreateGlobalTemplate(Signal, DoLoop);
      v8::Persistent<v8::Context> context = v8::Context::New(NULL, global);
      v8::Context::Scope context_scope(context);
      // Run a loop that will be infinite if thread termination does not  
work.
=======================================
--- /trunk/tools/gyp/v8.gyp     Wed Nov 18 06:12:51 2009
+++ /trunk/tools/gyp/v8.gyp     Tue Nov 24 06:29:16 2009
@@ -81,6 +81,7 @@
            ['OS=="linux"', {
              'cflags!': [
                '-O2',
+              '-Os',
              ],
              'cflags': [
                '-fomit-frame-pointer',

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to