Version 3.12.15

Added PRESERVE_ASCII_NULL option to String::WriteAscii. (issue 2252)

Added dependency to HLoadKeyed* instructions to prevent invalid hoisting. (Chromium issue 137768)

Enabled building d8 for Android on Mac.

Interpret negative hexadecimal literals as NaN. (issue 2240)

Expose counters in javascript when using --track-gc-object-stats.

Enabled building and testing V8 on Android IA.

Added --trace-parse flag to parser.

Performance and stability improvements on all platforms.

git-svn-id: http://v8.googlecode.com/svn/trunk@12180 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/objects-inl.h b/src/objects-inl.h
index feca271..f4e0767 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1952,12 +1952,12 @@
 // Perform a linear search in this fixed array. len is the number of entry
 // indices that are valid.
 template<typename T>
-int LinearSearch(T* array, SearchMode mode, String* name, int len) {
+int LinearSearch(T* array, String* name, int len) {
   uint32_t hash = name->Hash();
   for (int number = 0; number < len; number++) {
     String* entry = array->GetKey(number);
     uint32_t current_hash = entry->Hash();
-    if (mode == EXPECT_SORTED && current_hash > hash) break;
+    if (current_hash > hash) break;
     if (current_hash == hash && name->Equals(entry)) return number;
   }
   return T::kNotFound;
@@ -1975,7 +1975,7 @@
   // Fast case: do linear search for small arrays.
   const int kMaxElementsForLinearSearch = 8;
   if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
-    return LinearSearch(array, EXPECT_SORTED, name, nof);
+    return LinearSearch(array, name, nof);
   }
 
   // Slow case: perform binary search.
@@ -2110,13 +2110,26 @@
 }
 
 
-void DescriptorArray::Append(Descriptor* desc,
-                             const WhitenessWitness& witness) {
-  int descriptor_number = NumberOfSetDescriptors();
+int DescriptorArray::Append(Descriptor* desc,
+                            const WhitenessWitness& witness,
+                            int number_of_set_descriptors) {
+  int descriptor_number = number_of_set_descriptors;
   int enumeration_index = descriptor_number + 1;
   desc->SetEnumerationIndex(enumeration_index);
+
+  uint32_t hash = desc->GetKey()->Hash();
+
+  for (; descriptor_number > 0; --descriptor_number) {
+    String* key = GetKey(descriptor_number - 1);
+    if (key->Hash() <= hash) break;
+    Object* value = GetValue(descriptor_number - 1);
+    PropertyDetails details = GetDetails(descriptor_number - 1);
+    Descriptor moved_descriptor(key, value, details);
+    Set(descriptor_number, &moved_descriptor, witness);
+  }
+
   Set(descriptor_number, desc, witness);
-  SetLastAdded(descriptor_number);
+  return descriptor_number;
 }
 
 
@@ -2434,9 +2447,10 @@
 }
 
 
-void SlicedString::set_parent(String* parent) {
+void SlicedString::set_parent(String* parent, WriteBarrierMode mode) {
   ASSERT(parent->IsSeqString() || parent->IsExternalString());
   WRITE_FIELD(this, kParentOffset, parent);
+  CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kParentOffset, parent, mode);
 }
 
 
@@ -2940,16 +2954,12 @@
 
 
 void Map::set_function_with_prototype(bool value) {
-  if (value) {
-    set_bit_field3(bit_field3() | (1 << kFunctionWithPrototype));
-  } else {
-    set_bit_field3(bit_field3() & ~(1 << kFunctionWithPrototype));
-  }
+  set_bit_field3(FunctionWithPrototype::update(bit_field3(), value));
 }
 
 
 bool Map::function_with_prototype() {
-  return ((1 << kFunctionWithPrototype) & bit_field3()) != 0;
+  return FunctionWithPrototype::decode(bit_field3());
 }
 
 
@@ -2994,15 +3004,11 @@
 
 
 void Map::set_is_shared(bool value) {
-  if (value) {
-    set_bit_field3(bit_field3() | (1 << kIsShared));
-  } else {
-    set_bit_field3(bit_field3() & ~(1 << kIsShared));
-  }
+  set_bit_field3(IsShared::update(bit_field3(), value));
 }
 
 bool Map::is_shared() {
-  return ((1 << kIsShared) & bit_field3()) != 0;
+  return IsShared::decode(bit_field3());
 }
 
 
@@ -3488,6 +3494,40 @@
 }
 
 
+void Map::InitializeDescriptors(DescriptorArray* descriptors) {
+  int len = descriptors->number_of_descriptors();
+  ASSERT(len <= DescriptorArray::kMaxNumberOfDescriptors);
+  SLOW_ASSERT(descriptors->IsSortedNoDuplicates());
+
+#ifdef DEBUG
+  bool used_indices[DescriptorArray::kMaxNumberOfDescriptors];
+  for (int i = 0; i < len; ++i) used_indices[i] = false;
+
+  // Ensure that all enumeration indexes between 1 and length occur uniquely in
+  // the descriptor array.
+  for (int i = 0; i < len; ++i) {
+    int enum_index = descriptors->GetDetails(i).index() -
+                     PropertyDetails::kInitialIndex;
+    ASSERT(0 <= enum_index && enum_index < len);
+    ASSERT(!used_indices[enum_index]);
+    used_indices[enum_index] = true;
+  }
+#endif
+
+  set_instance_descriptors(descriptors);
+
+  for (int i = 0; i < len; ++i) {
+    if (descriptors->GetDetails(i).index() == len) {
+      SetLastAdded(i);
+      break;
+    }
+  }
+
+  ASSERT(len == 0 ||
+         len == descriptors->GetDetails(LastAdded()).index());
+}
+
+
 SMI_ACCESSORS(Map, bit_field3, kBitField3Offset)
 
 
@@ -3507,6 +3547,14 @@
 }
 
 
+void Map::AppendDescriptor(Descriptor* desc,
+                           const DescriptorArray::WhitenessWitness& witness) {
+  DescriptorArray* descriptors = instance_descriptors();
+  int set_descriptors = NumberOfSetDescriptors();
+  int new_last_added = descriptors->Append(desc, witness, set_descriptors);
+  SetLastAdded(new_last_added);
+}
+
 
 Object* Map::GetBackPointer() {
   Object* object = READ_FIELD(this, kInstanceDescriptorsOrBackPointerOffset);
@@ -4202,6 +4250,18 @@
 }
 
 
+bool JSFunction::IsMarkedForParallelRecompilation() {
+  return code() ==
+      GetIsolate()->builtins()->builtin(Builtins::kParallelRecompile);
+}
+
+
+bool JSFunction::IsInRecompileQueue() {
+  return code() == GetIsolate()->builtins()->builtin(
+      Builtins::kInRecompileQueue);
+}
+
+
 Code* JSFunction::code() {
   return Code::cast(unchecked_code());
 }