Fixed two crash-bugs in irregexp (issue 231 and 233).

Fixed a number of minor bugs (issue 87, 227 and 228).

Added support for morphing strings to external strings on demand to avoid having to create copies in the embedding code.

Removed experimental support for external symbol callbacks.


git-svn-id: http://v8.googlecode.com/svn/trunk@1266 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/heap.cc b/src/heap.cc
index 8009544..72f427e 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -84,8 +84,6 @@
 GCCallback Heap::global_gc_prologue_callback_ = NULL;
 GCCallback Heap::global_gc_epilogue_callback_ = NULL;
 
-ExternalSymbolCallback Heap::global_external_symbol_callback_ = NULL;
-
 // Variables set based on semispace_size_ and old_generation_size_ in
 // ConfigureHeap.
 int Heap::young_generation_size_ = 0;  // Will be 2 * semispace_size_.
@@ -1519,16 +1517,9 @@
 
 Object* Heap::AllocateExternalStringFromTwoByte(
     ExternalTwoByteString::Resource* resource) {
-  Map* map;
   int length = resource->length();
-  if (length <= String::kMaxShortStringSize) {
-    map = short_external_string_map();
-  } else if (length <= String::kMaxMediumStringSize) {
-    map = medium_external_string_map();
-  } else {
-    map = long_external_string_map();
-  }
 
+  Map* map = ExternalTwoByteString::StringMap(length);
   Object* result = Allocate(map, NEW_SPACE);
   if (result->IsFailure()) return result;
 
@@ -1540,29 +1531,6 @@
 }
 
 
-Object* Heap::AllocateExternalSymbolFromTwoByte(
-    ExternalTwoByteString::Resource* resource) {
-  Map* map;
-  int length = resource->length();
-  if (length <= String::kMaxShortStringSize) {
-    map = short_external_symbol_map();
-  } else if (length <= String::kMaxMediumStringSize) {
-    map = medium_external_symbol_map();
-  } else {
-    map = long_external_symbol_map();
-  }
-
-  Object* result = Allocate(map, OLD_DATA_SPACE);
-  if (result->IsFailure()) return result;
-
-  ExternalTwoByteString* external_string = ExternalTwoByteString::cast(result);
-  external_string->set_length(length);
-  external_string->set_resource(resource);
-
-  return result;
-}
-
-
 Object* Heap::LookupSingleCharacterStringFromCode(uint16_t code) {
   if (code <= String::kMaxAsciiCharCode) {
     Object* value = Heap::single_character_string_cache()->get(code);
@@ -1618,6 +1586,18 @@
 }
 
 
+void Heap::CreateFillerObjectAt(Address addr, int size) {
+  if (size == 0) return;
+  HeapObject* filler = HeapObject::FromAddress(addr);
+  if (size == kPointerSize) {
+    filler->set_map(Heap::one_word_filler_map());
+  } else {
+    filler->set_map(Heap::byte_array_map());
+    ByteArray::cast(filler)->set_length(ByteArray::LengthFor(size));
+  }
+}
+
+
 Object* Heap::CreateCode(const CodeDesc& desc,
                          ScopeInfo<>* sinfo,
                          Code::Flags flags,
@@ -2069,18 +2049,24 @@
     return long_sliced_ascii_symbol_map();
   }
 
-  if (map == short_external_string_map()) return short_external_string_map();
-  if (map == medium_external_string_map()) return medium_external_string_map();
-  if (map == long_external_string_map()) return long_external_string_map();
+  if (map == short_external_string_map()) {
+    return short_external_symbol_map();
+  }
+  if (map == medium_external_string_map()) {
+    return medium_external_symbol_map();
+  }
+  if (map == long_external_string_map()) {
+    return long_external_symbol_map();
+  }
 
   if (map == short_external_ascii_string_map()) {
-    return short_external_ascii_string_map();
+    return short_external_ascii_symbol_map();
   }
   if (map == medium_external_ascii_string_map()) {
-    return medium_external_ascii_string_map();
+    return medium_external_ascii_symbol_map();
   }
   if (map == long_external_ascii_string_map()) {
-    return long_external_ascii_string_map();
+    return long_external_ascii_symbol_map();
   }
 
   // No match found.
@@ -2095,7 +2081,7 @@
   ASSERT(static_cast<unsigned>(chars) == buffer->Length());
   // Determine whether the string is ascii.
   bool is_ascii = true;
-  while (buffer->has_more()) {
+  while (buffer->has_more() && is_ascii) {
     if (buffer->GetNext() > unibrow::Utf8::kMaxOneByteChar) is_ascii = false;
   }
   buffer->Rewind();
@@ -2146,44 +2132,6 @@
 }
 
 
-// External string resource that only contains a length field.  These
-// are used temporarily when allocating external symbols.
-class DummyExternalStringResource
-    : public v8::String::ExternalStringResource {
- public:
-  explicit DummyExternalStringResource(size_t length) : length_(length) { }
-
-  virtual const uint16_t* data() const {
-    UNREACHABLE();
-    return NULL;
-  }
-
-  virtual size_t length() const { return length_; }
- private:
-  size_t length_;
-};
-
-
-Object* Heap::AllocateExternalSymbol(Vector<const char> string, int chars) {
-  // Attempt to allocate the resulting external string first.  Use a
-  // dummy string resource that has the correct length so that we only
-  // have to patch the external string resource after the callback.
-  DummyExternalStringResource dummy_resource(chars);
-  Object* obj = AllocateExternalSymbolFromTwoByte(&dummy_resource);
-  if (obj->IsFailure()) return obj;
-  // Perform callback.
-  v8::String::ExternalStringResource* resource =
-      global_external_symbol_callback_(string.start(), string.length());
-  // Patch the resource pointer of the result.
-  ExternalTwoByteString* result = ExternalTwoByteString::cast(obj);
-  result->set_resource(resource);
-  // Force hash code to be computed.
-  result->Hash();
-  ASSERT(result->IsEqualTo(string));
-  return result;
-}
-
-
 Object* Heap::AllocateRawAsciiString(int length, PretenureFlag pretenure) {
   AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
   int size = SeqAsciiString::SizeFor(length);