Version 1.3.5

Optimize initialization of some arrays in the builtins.

Fix mac-nm script to support filenames with spaces.

Support for using the V8 profiler when V8 is embedded in a Windows DLL.

Changed typeof RegExp from 'object' to 'function' for compatibility. Fixed bug where regexps were not callable across contexts.

Added context independent script compilation to the API.

Added API call to get the stack trace for an exception.

Added API for getting object mirrors.

Make sure that SSE3 instructions are used whenever possible even when running off a snapshot generated without using SSE3 instructions.

Tweaked the handling of the initial size and growth policy of the heap.

Added native code generation for RegExp to 64-bit version.

Added JavaScript debugger support to 64-bit version.



git-svn-id: http://v8.googlecode.com/svn/trunk@2722 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/spaces.cc b/src/spaces.cc
index 9f266cb..9227a87 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -726,47 +726,25 @@
   Page* top_page = AllocationTopPage();
   ASSERT(top_page->is_valid());
 
-  // Loop over the pages from the top page to the end of the space to count
-  // the number of pages to keep and find the last page to keep.
-  int free_pages = 0;
-  int pages_to_keep = 0;  // Of the free pages.
-  Page* last_page_to_keep = top_page;
-  Page* current_page = top_page->next_page();
-  // Loop over the pages to the end of the space.
-  while (current_page->is_valid()) {
-#if defined(ANDROID)
-    // Free all chunks if possible
-#else
-    // Advance last_page_to_keep every other step to end up at the midpoint.
-    if ((free_pages & 0x1) == 1) {
-      pages_to_keep++;
-      last_page_to_keep = last_page_to_keep->next_page();
-    }
-#endif
-    free_pages++;
-    current_page = current_page->next_page();
+  // Count the number of pages we would like to free.
+  int pages_to_free = 0;
+  for (Page* p = top_page->next_page(); p->is_valid(); p = p->next_page()) {
+    pages_to_free++;
   }
 
-  // Free pages after last_page_to_keep, and adjust the next_page link.
-  Page* p = MemoryAllocator::FreePages(last_page_to_keep->next_page());
-  MemoryAllocator::SetNextPage(last_page_to_keep, p);
+  // Free pages after top_page.
+  Page* p = MemoryAllocator::FreePages(top_page->next_page());
+  MemoryAllocator::SetNextPage(top_page, p);
 
-  // Since pages are only freed in whole chunks, we may have kept more
-  // than pages_to_keep.  Count the extra pages and cache the new last
-  // page in the space.
-  last_page_ = last_page_to_keep;
-  while (p->is_valid()) {
-    pages_to_keep++;
+  // Find out how many pages we failed to free and update last_page_.
+  // Please note pages can only be freed in whole chunks.
+  last_page_ = top_page;
+  for (Page* p = top_page->next_page(); p->is_valid(); p = p->next_page()) {
+    pages_to_free--;
     last_page_ = p;
-    p = p->next_page();
   }
 
-  // The difference between free_pages and pages_to_keep is the number of
-  // pages actually freed.
-  ASSERT(pages_to_keep <= free_pages);
-  int bytes_freed = (free_pages - pages_to_keep) * Page::kObjectAreaSize;
-  accounting_stats_.ShrinkSpace(bytes_freed);
-
+  accounting_stats_.ShrinkSpace(pages_to_free * Page::kObjectAreaSize);
   ASSERT(Capacity() == CountTotalPages() * Page::kObjectAreaSize);
 }
 
@@ -884,8 +862,6 @@
 
   ASSERT(initial_semispace_capacity <= maximum_semispace_capacity);
   ASSERT(IsPowerOf2(maximum_semispace_capacity));
-  maximum_capacity_ = maximum_semispace_capacity;
-  capacity_ = initial_semispace_capacity;
 
   // Allocate and setup the histogram arrays if necessary.
 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
@@ -898,15 +874,17 @@
 #undef SET_NAME
 #endif
 
-  ASSERT(size == 2 * maximum_capacity_);
+  ASSERT(size == 2 * maximum_semispace_capacity);
   ASSERT(IsAddressAligned(start, size, 0));
 
-  if (!to_space_.Setup(start, capacity_, maximum_capacity_)) {
+  if (!to_space_.Setup(start,
+                       initial_semispace_capacity,
+                       maximum_semispace_capacity)) {
     return false;
   }
-  if (!from_space_.Setup(start + maximum_capacity_,
-                         capacity_,
-                         maximum_capacity_)) {
+  if (!from_space_.Setup(start + maximum_semispace_capacity,
+                         initial_semispace_capacity,
+                         maximum_semispace_capacity)) {
     return false;
   }
 
@@ -938,7 +916,6 @@
 #endif
 
   start_ = NULL;
-  capacity_ = 0;
   allocation_info_.top = NULL;
   allocation_info_.limit = NULL;
   mc_forwarding_info_.top = NULL;
@@ -975,12 +952,11 @@
 
 
 bool NewSpace::Grow() {
-  ASSERT(capacity_ < maximum_capacity_);
+  ASSERT(Capacity() < MaximumCapacity());
   // TODO(1240712): Failure to double the from space can result in
   // semispaces of different sizes.  In the event of that failure, the
   // to space doubling should be rolled back before returning false.
   if (!to_space_.Grow() || !from_space_.Grow()) return false;
-  capacity_ = to_space_.Capacity() + from_space_.Capacity();
   allocation_info_.limit = to_space_.high();
   ASSERT_SEMISPACE_ALLOCATION_INFO(allocation_info_, to_space_);
   return true;
@@ -1104,10 +1080,9 @@
 
 bool SemiSpace::Grow() {
   // Commit 50% extra space but only up to maximum capacity.
-  int extra = RoundUp(capacity_ / 2, OS::AllocateAlignment());
-  if (capacity_ + extra > maximum_capacity_) {
-    extra = maximum_capacity_ - capacity_;
-  }
+  int maximum_extra = maximum_capacity_ - capacity_;
+  int extra = Min(RoundUp(capacity_ / 2, OS::AllocateAlignment()),
+                  maximum_extra);
   if (!MemoryAllocator::CommitBlock(high(), extra, executable())) {
     return false;
   }