Revision: 3408
Author: [email protected]
Date: Thu Dec  3 03:25:37 2009
Log: Push bleeding_edge revision 3387, 3390 to trunk in order to fix test.

Push bleeding_edge revision 3406 to trunk to add stack allocated
information about the state of the heap in OOM situations.  This will
be helpful in getting information from OOM crashes.

Review URL: http://codereview.chromium.org/465026
http://code.google.com/p/v8/source/detail?r=3408

Modified:
  /trunk/src/api.cc
  /trunk/src/global-handles.cc
  /trunk/src/global-handles.h
  /trunk/src/heap.cc
  /trunk/src/heap.h
  /trunk/src/version.cc
  /trunk/test/cctest/test-api.cc

=======================================
--- /trunk/src/api.cc   Mon Nov 30 00:07:20 2009
+++ /trunk/src/api.cc   Thu Dec  3 03:25:37 2009
@@ -125,7 +125,8 @@

  // When V8 cannot allocated memory FatalProcessOutOfMemory is called.
  // The default fatal error handler is called and execution is stopped.
-void i::V8::FatalProcessOutOfMemory(const char* location) {
+static void ExecuteFatalProcessOutOfMemory(const char* location,
+                                           i::HeapStats* heap_stats) {
    i::V8::SetFatalError();
    FatalErrorCallback callback = GetFatalErrorHandler();
    {
@@ -135,6 +136,13 @@
    // If the callback returns, we stop execution.
    UNREACHABLE();
  }
+
+
+void i::V8::FatalProcessOutOfMemory(const char* location) {
+  i::HeapStats heap_stats;
+  i::Heap::RecordStats(&heap_stats);
+  ExecuteFatalProcessOutOfMemory(location, &heap_stats);
+}


  void V8::SetFatalErrorHandler(FatalErrorCallback that) {
=======================================
--- /trunk/src/global-handles.cc        Wed Nov 18 06:12:51 2009
+++ /trunk/src/global-handles.cc        Thu Dec  3 03:25:37 2009
@@ -429,6 +429,26 @@
  GlobalHandles::Node* GlobalHandles::first_free_ = NULL;
  GlobalHandles::Node* GlobalHandles::first_deallocated_ = NULL;

+void GlobalHandles::RecordStats(HeapStats* stats) {
+  stats->global_handle_count = 0;
+  stats->weak_global_handle_count = 0;
+  stats->pending_global_handle_count = 0;
+  stats->near_death_global_handle_count = 0;
+  stats->destroyed_global_handle_count = 0;
+  for (Node* current = head_; current != NULL; current = current->next()) {
+    stats->global_handle_count++;
+    if (current->state_ == Node::WEAK) {
+      stats->weak_global_handle_count++;
+    } else if (current->state_ == Node::PENDING) {
+      stats->pending_global_handle_count++;
+    } else if (current->state_ == Node::NEAR_DEATH) {
+      stats->near_death_global_handle_count++;
+    } else if (current->state_ == Node::DESTROYED) {
+      stats->destroyed_global_handle_count++;
+    }
+  }
+}
+
  #ifdef DEBUG

  void GlobalHandles::PrintStats() {
=======================================
--- /trunk/src/global-handles.h Wed Nov 18 06:12:51 2009
+++ /trunk/src/global-handles.h Thu Dec  3 03:25:37 2009
@@ -77,6 +77,8 @@

    // Returns the current number of weak handles.
    static int NumberOfWeakHandles() { return number_of_weak_handles_; }
+
+  static void RecordStats(HeapStats* stats);

    // Returns the current number of weak handles to global objects.
    // These handles are also included in NumberOfWeakHandles().
=======================================
--- /trunk/src/heap.cc  Fri Nov 20 04:14:52 2009
+++ /trunk/src/heap.cc  Thu Dec  3 03:25:37 2009
@@ -3354,6 +3354,24 @@
  bool Heap::ConfigureHeapDefault() {
    return ConfigureHeap(FLAG_max_new_space_size / 2,  
FLAG_max_old_space_size);
  }
+
+
+void Heap::RecordStats(HeapStats* stats) {
+  stats->new_space_size = new_space_.Size();
+  stats->new_space_capacity = new_space_.Capacity();
+  stats->old_pointer_space_size = old_pointer_space_->Size();
+  stats->old_pointer_space_capacity = old_pointer_space_->Capacity();
+  stats->old_data_space_size = old_data_space_->Size();
+  stats->old_data_space_capacity = old_data_space_->Capacity();
+  stats->code_space_size = code_space_->Size();
+  stats->code_space_capacity = code_space_->Capacity();
+  stats->map_space_size = map_space_->Size();
+  stats->map_space_capacity = map_space_->Capacity();
+  stats->cell_space_size = cell_space_->Size();
+  stats->cell_space_capacity = cell_space_->Capacity();
+  stats->lo_space_size = lo_space_->Size();
+  GlobalHandles::RecordStats(stats);
+}


  int Heap::PromotedSpaceSize() {
=======================================
--- /trunk/src/heap.h   Fri Nov 20 04:14:52 2009
+++ /trunk/src/heap.h   Thu Dec  3 03:25:37 2009
@@ -219,6 +219,7 @@

  // Forward declaration of the GCTracer class.
  class GCTracer;
+class HeapStats;


  // The all static Heap captures the interface to the global object heap.
@@ -895,6 +896,8 @@
    static RootListIndex RootIndexForExternalArrayType(
        ExternalArrayType array_type);

+  static void RecordStats(HeapStats* stats);
+
   private:
    static int reserved_semispace_size_;
    static int max_semispace_size_;
@@ -1127,6 +1130,28 @@
  };


+struct HeapStats {
+  int new_space_size;
+  int new_space_capacity;
+  int old_pointer_space_size;
+  int old_pointer_space_capacity;
+  int old_data_space_size;
+  int old_data_space_capacity;
+  int code_space_size;
+  int code_space_capacity;
+  int map_space_size;
+  int map_space_capacity;
+  int cell_space_size;
+  int cell_space_capacity;
+  int lo_space_size;
+  int global_handle_count;
+  int weak_global_handle_count;
+  int pending_global_handle_count;
+  int near_death_global_handle_count;
+  int destroyed_global_handle_count;
+};
+
+
  class AlwaysAllocateScope {
   public:
    AlwaysAllocateScope() {
=======================================
--- /trunk/src/version.cc       Wed Dec  2 00:17:28 2009
+++ /trunk/src/version.cc       Thu Dec  3 03:25:37 2009
@@ -35,7 +35,7 @@
  #define MAJOR_VERSION     2
  #define MINOR_VERSION     0
  #define BUILD_NUMBER      2
-#define PATCH_LEVEL       2
+#define PATCH_LEVEL       3
  #define CANDIDATE_VERSION false

  // Define SONAME to have the SCons build the put a specific SONAME into the
=======================================
--- /trunk/test/cctest/test-api.cc      Wed Dec  2 00:17:28 2009
+++ /trunk/test/cctest/test-api.cc      Thu Dec  3 03:25:37 2009
@@ -8416,13 +8416,8 @@
    v8::internal::HeapIterator it;
    while (it.has_next()) {
      v8::internal::HeapObject* object = it.next();
-    if (object->IsJSGlobalObject()) {
-      count++;
-    }
-  }
-#ifdef DEBUG
-  if (count > 0) v8::internal::Heap::TracePathToGlobal();
-#endif
+    if (object->IsJSGlobalObject()) count++;
+  }
    return count;
  }

@@ -8432,10 +8427,16 @@

    v8::HandleScope scope;
    v8::Persistent<Context> context;
+  v8::Persistent<Context> other_context;
    int gc_count;

+  // Create a context used to keep the code from aging in the compilation
+  // cache.
+  other_context = Context::New();
+
    // Context-dependent context data creates reference from the compilation
    // cache to the global object.
+  const char* source_simple = "1";
    context = Context::New();
    {
      v8::HandleScope scope;
@@ -8443,44 +8444,52 @@
      context->Enter();
      Local<v8::String> obj = v8::String::New("");
      context->SetData(obj);
-    CompileRun("1");
+    CompileRun(source_simple);
      context->Exit();
    }
    context.Dispose();
    for (gc_count = 1; gc_count < 10; gc_count++) {
+    other_context->Enter();
+    CompileRun(source_simple);
+    other_context->Exit();
      v8::internal::Heap::CollectAllGarbage(false);
-    if (GetGlobalObjectsCount() == 0) break;
-  }
-  CHECK_EQ(0, GetGlobalObjectsCount());
-  CHECK_EQ(2, gc_count);
+    if (GetGlobalObjectsCount() == 1) break;
+  }
+  CHECK_GE(2, gc_count);
+  CHECK_EQ(1, GetGlobalObjectsCount());

    // Eval in a function creates reference from the compilation cache to the
    // global object.
+  const char* source_eval = "function f(){eval('1')}; f()";
    context = Context::New();
    {
      v8::HandleScope scope;

      context->Enter();
-    CompileRun("function f(){eval('1')}; f()");
+    CompileRun(source_eval);
      context->Exit();
    }
    context.Dispose();
    for (gc_count = 1; gc_count < 10; gc_count++) {
+    other_context->Enter();
+    CompileRun(source_eval);
+    other_context->Exit();
      v8::internal::Heap::CollectAllGarbage(false);
-    if (GetGlobalObjectsCount() == 0) break;
-  }
-  CHECK_GE(2, gc_count);
+    if (GetGlobalObjectsCount() == 1) break;
+  }
+  CHECK(gc_count <= 2);
    CHECK_EQ(1, GetGlobalObjectsCount());

    // Looking up the line number for an exception creates reference from the
    // compilation cache to the global object.
+  const char* source_exception = "function f(){throw 1;} f()";
    context = Context::New();
    {
      v8::HandleScope scope;

      context->Enter();
      v8::TryCatch try_catch;
-    CompileRun("function f(){throw 1;}; f()");
+    CompileRun(source_exception);
      CHECK(try_catch.HasCaught());
      v8::Handle<v8::Message> message = try_catch.Message();
      CHECK(!message.IsEmpty());
@@ -8489,9 +8498,14 @@
    }
    context.Dispose();
    for (gc_count = 1; gc_count < 10; gc_count++) {
+    other_context->Enter();
+    CompileRun(source_exception);
+    other_context->Exit();
      v8::internal::Heap::CollectAllGarbage(false);
-    if (GetGlobalObjectsCount() == 0) break;
-  }
-  CHECK_EQ(0, GetGlobalObjectsCount());
-  CHECK_EQ(2, gc_count);
-}
+    if (GetGlobalObjectsCount() == 1) break;
+  }
+  CHECK_GE(2, gc_count);
+  CHECK_EQ(1, GetGlobalObjectsCount());
+
+  other_context.Dispose();
+}

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

Reply via email to