Push version 2.0.0 to trunk.

Added support for VFP on ARM.

Added TryCatch::ReThrow method to the API.

Reduced the size of snapshots and improved the snapshot load time.

Improved heap profiler support.

64-bit version now supported on Windows.

Fixed a number of debugger issues.

Fixed bugs.


git-svn-id: http://v8.googlecode.com/svn/trunk@3333 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/heap.cc b/src/heap.cc
index ae18fbe..43886c1 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -733,10 +733,7 @@
 
   ScavengeVisitor scavenge_visitor;
   // Copy roots.
-  IterateRoots(&scavenge_visitor);
-
-  // Copy objects reachable from weak pointers.
-  GlobalHandles::IterateWeakRoots(&scavenge_visitor);
+  IterateRoots(&scavenge_visitor, VISIT_ALL);
 
   // Copy objects reachable from the old generation.  By definition,
   // there are no intergenerational pointers in code or data spaces.
@@ -1730,6 +1727,7 @@
   // Statically ensure that it is safe to allocate proxies in paged spaces.
   STATIC_ASSERT(Proxy::kSize <= Page::kMaxHeapObjectSize);
   AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
+  if (always_allocate()) space = OLD_DATA_SPACE;
   Object* result = Allocate(proxy_map(), space);
   if (result->IsFailure()) return result;
 
@@ -1766,10 +1764,14 @@
 
 Object* Heap::AllocateConsString(String* first, String* second) {
   int first_length = first->length();
-  if (first_length == 0) return second;
+  if (first_length == 0) {
+    return second;
+  }
 
   int second_length = second->length();
-  if (second_length == 0) return first;
+  if (second_length == 0) {
+    return first;
+  }
 
   int length = first_length + second_length;
   bool is_ascii = first->IsAsciiRepresentation()
@@ -1821,54 +1823,18 @@
       : long_cons_string_map();
   }
 
-  Object* result = Allocate(map, NEW_SPACE);
+  Object* result = Allocate(map,
+                            always_allocate() ? OLD_POINTER_SPACE : NEW_SPACE);
   if (result->IsFailure()) return result;
-  ASSERT(InNewSpace(result));
   ConsString* cons_string = ConsString::cast(result);
-  cons_string->set_first(first, SKIP_WRITE_BARRIER);
-  cons_string->set_second(second, SKIP_WRITE_BARRIER);
+  WriteBarrierMode mode = cons_string->GetWriteBarrierMode();
+  cons_string->set_first(first, mode);
+  cons_string->set_second(second, mode);
   cons_string->set_length(length);
   return result;
 }
 
 
-Object* Heap::AllocateSlicedString(String* buffer,
-                                   int start,
-                                   int end) {
-  int length = end - start;
-
-  // If the resulting string is small make a sub string.
-  if (length <= String::kMinNonFlatLength) {
-    return Heap::AllocateSubString(buffer, start, end);
-  }
-
-  Map* map;
-  if (length <= String::kMaxShortSize) {
-    map = buffer->IsAsciiRepresentation() ?
-      short_sliced_ascii_string_map() :
-      short_sliced_string_map();
-  } else if (length <= String::kMaxMediumSize) {
-    map = buffer->IsAsciiRepresentation() ?
-      medium_sliced_ascii_string_map() :
-      medium_sliced_string_map();
-  } else {
-    map = buffer->IsAsciiRepresentation() ?
-      long_sliced_ascii_string_map() :
-      long_sliced_string_map();
-  }
-
-  Object* result = Allocate(map, NEW_SPACE);
-  if (result->IsFailure()) return result;
-
-  SlicedString* sliced_string = SlicedString::cast(result);
-  sliced_string->set_buffer(buffer);
-  sliced_string->set_start(start);
-  sliced_string->set_length(length);
-
-  return result;
-}
-
-
 Object* Heap::AllocateSubString(String* buffer,
                                 int start,
                                 int end) {
@@ -1888,22 +1854,19 @@
       ? AllocateRawAsciiString(length)
       : AllocateRawTwoByteString(length);
   if (result->IsFailure()) return result;
+  String* string_result = String::cast(result);
 
   // Copy the characters into the new object.
-  String* string_result = String::cast(result);
-  StringHasher hasher(length);
-  int i = 0;
-  for (; i < length && hasher.is_array_index(); i++) {
-    uc32 c = buffer->Get(start + i);
-    hasher.AddCharacter(c);
-    string_result->Set(i, c);
+  if (buffer->IsAsciiRepresentation()) {
+    ASSERT(string_result->IsAsciiRepresentation());
+    char* dest = SeqAsciiString::cast(string_result)->GetChars();
+    String::WriteToFlat(buffer, dest, start, end);
+  } else {
+    ASSERT(string_result->IsTwoByteRepresentation());
+    uc16* dest = SeqTwoByteString::cast(string_result)->GetChars();
+    String::WriteToFlat(buffer, dest, start, end);
   }
-  for (; i < length; i++) {
-    uc32 c = buffer->Get(start + i);
-    hasher.AddCharacterNoIndex(c);
-    string_result->Set(i, c);
-  }
-  string_result->set_length_field(hasher.GetHashField());
+
   return result;
 }
 
@@ -1911,20 +1874,24 @@
 Object* Heap::AllocateExternalStringFromAscii(
     ExternalAsciiString::Resource* resource) {
   Map* map;
-  int length = resource->length();
-  if (length <= String::kMaxShortSize) {
+  size_t length = resource->length();
+  if (length <= static_cast<size_t>(String::kMaxShortSize)) {
     map = short_external_ascii_string_map();
-  } else if (length <= String::kMaxMediumSize) {
+  } else if (length <= static_cast<size_t>(String::kMaxMediumSize)) {
     map = medium_external_ascii_string_map();
-  } else {
+  } else if (length <= static_cast<size_t>(String::kMaxLength)) {
     map = long_external_ascii_string_map();
+  } else {
+    Top::context()->mark_out_of_memory();
+    return Failure::OutOfMemoryException();
   }
 
-  Object* result = Allocate(map, NEW_SPACE);
+  Object* result = Allocate(map,
+                            always_allocate() ? OLD_DATA_SPACE : NEW_SPACE);
   if (result->IsFailure()) return result;
 
   ExternalAsciiString* external_string = ExternalAsciiString::cast(result);
-  external_string->set_length(length);
+  external_string->set_length(static_cast<int>(length));
   external_string->set_resource(resource);
 
   return result;
@@ -1933,14 +1900,18 @@
 
 Object* Heap::AllocateExternalStringFromTwoByte(
     ExternalTwoByteString::Resource* resource) {
-  int length = resource->length();
-
-  Map* map = ExternalTwoByteString::StringMap(length);
-  Object* result = Allocate(map, NEW_SPACE);
+  size_t length = resource->length();
+  if (length > static_cast<size_t>(String::kMaxLength)) {
+    Top::context()->mark_out_of_memory();
+    return Failure::OutOfMemoryException();
+  }
+  Map* map = ExternalTwoByteString::StringMap(static_cast<int>(length));
+  Object* result = Allocate(map,
+                            always_allocate() ? OLD_DATA_SPACE : NEW_SPACE);
   if (result->IsFailure()) return result;
 
   ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result);
-  external_string->set_length(length);
+  external_string->set_length(static_cast<int>(length));
   external_string->set_resource(resource);
 
   return result;
@@ -2321,6 +2292,7 @@
   AllocationSpace space =
       (pretenure == TENURED) ? OLD_POINTER_SPACE : NEW_SPACE;
   if (map->instance_size() > MaxObjectSizeInPagedSpace()) space = LO_SPACE;
+  if (always_allocate()) space = OLD_POINTER_SPACE;
   Object* obj = Allocate(map, space);
   if (obj->IsFailure()) return obj;
 
@@ -2603,20 +2575,6 @@
     return long_cons_ascii_symbol_map();
   }
 
-  if (map == short_sliced_string_map()) return short_sliced_symbol_map();
-  if (map == medium_sliced_string_map()) return medium_sliced_symbol_map();
-  if (map == long_sliced_string_map()) return long_sliced_symbol_map();
-
-  if (map == short_sliced_ascii_string_map()) {
-    return short_sliced_ascii_symbol_map();
-  }
-  if (map == medium_sliced_ascii_string_map()) {
-    return medium_sliced_ascii_symbol_map();
-  }
-  if (map == long_sliced_ascii_string_map()) {
-    return long_sliced_ascii_symbol_map();
-  }
-
   if (map == short_external_string_map()) {
     return short_external_symbol_map();
   }
@@ -3117,7 +3075,7 @@
   ASSERT(HasBeenSetup());
 
   VerifyPointersVisitor visitor;
-  IterateRoots(&visitor);
+  IterateRoots(&visitor, VISIT_ONLY_STRONG);
 
   new_space_.Verify();
 
@@ -3244,14 +3202,14 @@
 }
 
 
-void Heap::IterateRoots(ObjectVisitor* v) {
-  IterateStrongRoots(v);
+void Heap::IterateRoots(ObjectVisitor* v, VisitMode mode) {
+  IterateStrongRoots(v, mode);
   v->VisitPointer(reinterpret_cast<Object**>(&roots_[kSymbolTableRootIndex]));
   v->Synchronize("symbol_table");
 }
 
 
-void Heap::IterateStrongRoots(ObjectVisitor* v) {
+void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
   v->VisitPointers(&roots_[0], &roots_[kStrongRootListLength]);
   v->Synchronize("strong_root_list");
 
@@ -3284,7 +3242,11 @@
   v->Synchronize("builtins");
 
   // Iterate over global handles.
-  GlobalHandles::IterateRoots(v);
+  if (mode == VISIT_ONLY_STRONG) {
+    GlobalHandles::IterateStrongRoots(v);
+  } else {
+    GlobalHandles::IterateAllRoots(v);
+  }
   v->Synchronize("globalhandles");
 
   // Iterate over pointers being held by inactive threads.
@@ -3455,14 +3417,18 @@
 }
 
 
-void Heap::SetStackLimit(intptr_t limit) {
+void Heap::SetStackLimits() {
   // On 64 bit machines, pointers are generally out of range of Smis.  We write
   // something that looks like an out of range Smi to the GC.
 
-  // Set up the special root array entry containing the stack guard.
-  // This is actually an address, but the tag makes the GC ignore it.
+  // Set up the special root array entries containing the stack limits.
+  // These are actually addresses, but the tag makes the GC ignore it.
   roots_[kStackLimitRootIndex] =
-    reinterpret_cast<Object*>((limit & ~kSmiTagMask) | kSmiTag);
+      reinterpret_cast<Object*>(
+          (StackGuard::jslimit() & ~kSmiTagMask) | kSmiTag);
+  roots_[kRealStackLimitRootIndex] =
+      reinterpret_cast<Object*>(
+          (StackGuard::real_jslimit() & ~kSmiTagMask) | kSmiTag);
 }
 
 
@@ -3889,7 +3855,7 @@
   search_for_any_global = false;
 
   MarkRootVisitor root_visitor;
-  IterateRoots(&root_visitor);
+  IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
 }
 
 
@@ -3901,7 +3867,7 @@
   search_for_any_global = true;
 
   MarkRootVisitor root_visitor;
-  IterateRoots(&root_visitor);
+  IterateRoots(&root_visitor, VISIT_ONLY_STRONG);
 }
 #endif