Improved handling of relocation information to enable more peep-hole optimizations.

Optimized switch statements where all labels are constant small integers.

Optimized String.prototype.indexOf for common cases.

Fixed more build issues (issue 80).

Fixed a couple of profiler issues.

Fixed bug where the body of a function created using the Function constructor was not allowed to end with a single-line comment (issue 85).

Improved handling of object literals by canonicalizing object literal maps.  This will allow JSON objects with the same set of properties to share the same map making inline caching work better for JSON objects.



git-svn-id: http://v8.googlecode.com/svn/trunk@373 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 5bcf0a7..2645363 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -293,6 +293,12 @@
 }
 
 
+bool Object::IsJSRegExp() {
+  return Object::IsHeapObject()
+    && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
+}
+
+
 template <> inline bool Is<JSArray>(Object* obj) {
   return obj->IsJSArray();
 }
@@ -319,6 +325,11 @@
 }
 
 
+bool Object::IsMapCache() {
+  return IsHashTable();
+}
+
+
 bool Object::IsPrimitive() {
   return IsOddball() || IsNumber() || IsString();
 }
@@ -487,7 +498,7 @@
 
 
 Object* HeapObject::GetHeapObjectField(HeapObject* obj, int index) {
-  return READ_FIELD(obj, HeapObject::kSize + kPointerSize * index);
+  return READ_FIELD(obj, HeapObject::kHeaderSize + kPointerSize * index);
 }
 
 
@@ -756,7 +767,9 @@
   ASSERT(map() == from->map());
   ASSERT(Size() == from->Size());
   int object_size = Size();
-  for (int offset = kSize; offset < object_size;  offset += kPointerSize) {
+  for (int offset = kHeaderSize;
+       offset < object_size;
+       offset += kPointerSize) {
     Object* value = READ_FIELD(from, offset);
     // Note: WRITE_FIELD does not update the write barrier.
     WRITE_FIELD(this, offset, value);
@@ -848,6 +861,8 @@
       return JSValue::kSize;
     case JS_ARRAY_TYPE:
       return JSValue::kSize;
+    case JS_REGEXP_TYPE:
+      return JSValue::kSize;
     case JS_OBJECT_TYPE:
       return JSObject::kHeaderSize;
     default:
@@ -885,7 +900,7 @@
 
 
 void Struct::InitializeBody(int object_size) {
-  for (int offset = kSize; offset < object_size; offset += kPointerSize) {
+  for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
     WRITE_FIELD(this, offset, Heap::undefined_value());
   }
 }
@@ -977,6 +992,13 @@
 }
 
 
+void FixedArray::set_null(int index) {
+  ASSERT(index >= 0 && index < this->length());
+  ASSERT(!Heap::InNewSpace(Heap::null_value()));
+  WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
+}
+
+
 void FixedArray::set_the_hole(int index) {
   ASSERT(index >= 0 && index < this->length());
   ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
@@ -1095,6 +1117,7 @@
 CAST_ACCESSOR(Dictionary)
 CAST_ACCESSOR(SymbolTable)
 CAST_ACCESSOR(CompilationCacheTable)
+CAST_ACCESSOR(MapCache)
 CAST_ACCESSOR(String)
 CAST_ACCESSOR(SeqString)
 CAST_ACCESSOR(AsciiString)
@@ -1117,6 +1140,7 @@
 CAST_ACCESSOR(JSBuiltinsObject)
 CAST_ACCESSOR(Code)
 CAST_ACCESSOR(JSArray)
+CAST_ACCESSOR(JSRegExp)
 CAST_ACCESSOR(Proxy)
 CAST_ACCESSOR(ByteArray)
 CAST_ACCESSOR(Struct)
@@ -1191,7 +1215,12 @@
 
 
 void String::TryFlatten() {
-  Flatten();
+  // We don't need to flatten strings that are already flat.  Since this code
+  // is inlined, it can be helpful in the flat case to not call out to Flatten.
+  StringRepresentationTag str_type = representation_tag();
+  if (str_type != kSeqStringTag && str_type != kExternalStringTag) {
+    Flatten();
+  }
 }
 
 
@@ -1993,6 +2022,20 @@
 ACCESSORS(JSArray, length, Object, kLengthOffset)
 
 
+ACCESSORS(JSRegExp, data, Object, kDataOffset)
+ACCESSORS(JSRegExp, type, Object, kTypeOffset)
+
+
+JSRegExp::Type JSRegExp::type_tag() {
+  return static_cast<JSRegExp::Type>(Smi::cast(type())->value());
+}
+
+
+void JSRegExp::set_type_tag(JSRegExp::Type value) {
+  set_type(Smi::FromInt(value));
+}
+
+
 bool JSObject::HasFastElements() {
   return !elements()->IsDictionary();
 }