- Added conditional write barrier to object accessors.
authorbak@chromium.org <bak@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Oct 2008 08:46:32 +0000 (08:46 +0000)
committerbak@chromium.org <bak@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 23 Oct 2008 08:46:32 +0000 (08:46 +0000)
- Sped up allocation of Arguments object.

Review URL: http://codereview.chromium.org/8098

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@567 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/bootstrapper.cc
src/builtins.cc
src/dateparser.cc
src/heap.cc
src/jsregexp.cc
src/objects-inl.h
src/objects.cc
src/objects.h
src/runtime.cc

index 58754386815dd19eab964d267553e8b1a48eddab..0562c236ce97d3bb608f1e00c939d9335b1f2548 100644 (file)
@@ -739,25 +739,46 @@ void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template,
     Handle<JSObject> prototype =
         Handle<JSObject>(
             JSObject::cast(global_context()->object_function()->prototype()));
+
     Handle<JSFunction> function =
-        Factory::NewFunctionWithPrototype(symbol, JS_OBJECT_TYPE,
-                                          JSObject::kHeaderSize, prototype,
-                                          code, true);
+        Factory::NewFunctionWithPrototype(symbol,
+                                          JS_OBJECT_TYPE,
+                                          JSObject::kHeaderSize,
+                                          prototype,
+                                          code,
+                                          false);
+    ASSERT(!function->has_initial_map());
     function->shared()->set_instance_class_name(*symbol);
-
+    function->shared()->set_expected_nof_properties(2);
     Handle<JSObject> result = Factory::NewJSObject(function);
 
     global_context()->set_arguments_boilerplate(*result);
     // Note: callee must be added as the first property and
     //       length must be added as the second property.
-    SetProperty(result, Factory::callee_symbol(), Factory::undefined_value(),
+    SetProperty(result, Factory::callee_symbol(),
+                Factory::undefined_value(),
                 DONT_ENUM);
-    SetProperty(result, Factory::length_symbol(), Factory::undefined_value(),
+    SetProperty(result, Factory::length_symbol(),
+                Factory::undefined_value(),
                 DONT_ENUM);
 
+#ifdef DEBUG
+    LookupResult lookup;
+    result->LocalLookup(Heap::callee_symbol(), &lookup);
+    ASSERT(lookup.IsValid() && (lookup.type() == FIELD));
+    ASSERT(lookup.GetFieldIndex() == Heap::arguments_callee_index);
+
+    result->LocalLookup(Heap::length_symbol(), &lookup);
+    ASSERT(lookup.IsValid() && (lookup.type() == FIELD));
+    ASSERT(lookup.GetFieldIndex() == Heap::arguments_length_index);
+
+    ASSERT(result->map()->inobject_properties() > Heap::arguments_callee_index);
+    ASSERT(result->map()->inobject_properties() > Heap::arguments_length_index);
+
     // Check the state of the object.
     ASSERT(result->HasFastProperties());
     ASSERT(result->HasFastElements());
+#endif
   }
 
   {  // --- context extension
index b274d3a120cd0162d54fffe78ecb7ef34c3d5cd4..03bce65403e4cfe3591584784f47e6ec49b7d03e 100644 (file)
@@ -177,7 +177,7 @@ BUILTIN(ArrayCode) {
   Object* obj = Heap::AllocateFixedArrayWithHoles(len->value());
   if (obj->IsFailure()) return obj;
   FixedArray* elms = FixedArray::cast(obj);
-  FixedArray::WriteBarrierMode mode = elms->GetWriteBarrierMode();
+  WriteBarrierMode mode = elms->GetWriteBarrierMode();
   // Fill in the content
   for (int index = 0; index < number_of_elements; index++) {
     elms->set(index, BUILTIN_ARG(index+1), mode);
@@ -185,7 +185,7 @@ BUILTIN(ArrayCode) {
 
   // Set length and elements on the array.
   array->set_elements(FixedArray::cast(obj));
-  array->set_length(len);
+  array->set_length(len, SKIP_WRITE_BARRIER);
 
   return array;
 }
@@ -214,7 +214,7 @@ BUILTIN(ArrayPush) {
     Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
     if (obj->IsFailure()) return obj;
     FixedArray* new_elms = FixedArray::cast(obj);
-    FixedArray::WriteBarrierMode mode = new_elms->GetWriteBarrierMode();
+    WriteBarrierMode mode = new_elms->GetWriteBarrierMode();
     // Fill out the new array with old elements.
     for (int i = 0; i < len; i++) new_elms->set(i, elms->get(i), mode);
     // Add the provided values.
@@ -225,7 +225,7 @@ BUILTIN(ArrayPush) {
     array->set_elements(new_elms);
   }
   // Set the length.
-  array->set_length(Smi::FromInt(new_length));
+  array->set_length(Smi::FromInt(new_length), SKIP_WRITE_BARRIER);
   return array->length();
 }
 BUILTIN_END
@@ -244,12 +244,11 @@ BUILTIN(ArrayPop) {
   Object* top = elms->get(len - 1);
 
   // Set the length.
-  array->set_length(Smi::FromInt(len - 1));
+  array->set_length(Smi::FromInt(len - 1), SKIP_WRITE_BARRIER);
 
   if (!top->IsTheHole()) {
     // Delete the top element.
     elms->set_the_hole(len - 1);
-
     return top;
   }
 
index 69cf748629c22cf8a002e108612bcfdca8b088f8..4b64785bb2d01b46297ceae64dbbbbb312c13cf4 100644 (file)
@@ -149,9 +149,15 @@ bool DateParser::DayComposer::Write(FixedArray* output) {
 
   if (!Smi::IsValid(year) || !IsMonth(month) || !IsDay(day)) return false;
 
-  output->set(YEAR, Smi::FromInt(year));
-  output->set(MONTH, Smi::FromInt(month - 1));  // 0-based
-  output->set(DAY, Smi::FromInt(day));
+  output->set(YEAR,
+              Smi::FromInt(year),
+              SKIP_WRITE_BARRIER);
+  output->set(MONTH,
+              Smi::FromInt(month - 1),
+              SKIP_WRITE_BARRIER);  // 0-based
+  output->set(DAY,
+              Smi::FromInt(day),
+              SKIP_WRITE_BARRIER);
   return true;
 }
 
@@ -174,9 +180,15 @@ bool DateParser::TimeComposer::Write(FixedArray* output) {
 
   if (!IsHour(hour) || !IsMinute(minute) || !IsSecond(second)) return false;
 
-  output->set(HOUR, Smi::FromInt(hour));
-  output->set(MINUTE, Smi::FromInt(minute));
-  output->set(SECOND, Smi::FromInt(second));
+  output->set(HOUR,
+              Smi::FromInt(hour),
+              SKIP_WRITE_BARRIER);
+  output->set(MINUTE,
+              Smi::FromInt(minute),
+              SKIP_WRITE_BARRIER);
+  output->set(SECOND,
+              Smi::FromInt(second),
+              SKIP_WRITE_BARRIER);
   return true;
 }
 
@@ -187,9 +199,13 @@ bool DateParser::TimeZoneComposer::Write(FixedArray* output) {
     if (minute_ == kNone) minute_ = 0;
     int total_seconds = sign_ * (hour_ * 3600 + minute_ * 60);
     if (!Smi::IsValid(total_seconds)) return false;
-    output->set(UTC_OFFSET, Smi::FromInt(total_seconds));
+    output->set(UTC_OFFSET,
+                Smi::FromInt(total_seconds),
+                SKIP_WRITE_BARRIER);
   } else {
-    output->set(UTC_OFFSET, Heap::null_value());
+    output->set(UTC_OFFSET,
+                Heap::null_value(),
+                SKIP_WRITE_BARRIER);
   }
   return true;
 }
index bc8dd76d2bfe8619954f008bac368c8b4c393b16..00cf78be58d909127668ce74e635b215bf2ab58f 100644 (file)
@@ -1242,7 +1242,7 @@ void Heap::SetNumberStringCache(Object* number, String* string) {
   int hash;
   if (number->IsSmi()) {
     hash = smi_get_hash(Smi::cast(number));
-    number_string_cache_->set(hash * 2, number, FixedArray::SKIP_WRITE_BARRIER);
+    number_string_cache_->set(hash * 2, number, SKIP_WRITE_BARRIER);
   } else {
     hash = double_get_hash(number->Number());
     number_string_cache_->set(hash * 2, number);
@@ -1655,17 +1655,34 @@ Object* Heap::AllocateArgumentsObject(Object* callee, int length) {
 
   JSObject* boilerplate =
       Top::context()->global_context()->arguments_boilerplate();
-  Object* result = CopyJSObject(boilerplate);
+
+  // Make the clone.
+  Map* map = boilerplate->map();
+  int object_size = map->instance_size();
+  Object* result = new_space_.AllocateRaw(object_size);
   if (result->IsFailure()) return result;
+  ASSERT(Heap::InNewSpace(result));
+
+  // Copy the content.
+  CopyBlock(reinterpret_cast<Object**>(HeapObject::cast(result)->address()),
+            reinterpret_cast<Object**>(boilerplate->address()),
+            object_size);
 
-  Object* obj = JSObject::cast(result)->properties();
-  FixedArray::cast(obj)->set(arguments_callee_index, callee);
-  FixedArray::cast(obj)->set(arguments_length_index, Smi::FromInt(length));
+  // Set the two properties.
+  JSObject::cast(result)->InObjectPropertyAtPut(arguments_callee_index,
+                                                callee,
+                                                SKIP_WRITE_BARRIER);
+  JSObject::cast(result)->InObjectPropertyAtPut(arguments_length_index,
+                                                Smi::FromInt(length),
+                                                SKIP_WRITE_BARRIER);
 
-  // Allocate the fixed array.
-  obj = Heap::AllocateFixedArray(length);
-  if (obj->IsFailure()) return obj;
-  JSObject::cast(result)->set_elements(FixedArray::cast(obj));
+  // Allocate the elements if needed.
+  if (length > 0) {
+    // Allocate the fixed array.
+    Object* obj = Heap::AllocateFixedArray(length);
+    if (obj->IsFailure()) return obj;
+    JSObject::cast(result)->set_elements(FixedArray::cast(obj));
+  }
 
   // Check the state of the object
   ASSERT(JSObject::cast(result)->HasFastProperties());
@@ -2111,7 +2128,7 @@ Object* Heap::CopyFixedArray(FixedArray* src) {
   FixedArray* result = FixedArray::cast(obj);
   result->set_length(len);
   // Copy the content
-  FixedArray::WriteBarrierMode mode = result->GetWriteBarrierMode();
+  WriteBarrierMode mode = result->GetWriteBarrierMode();
   for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
   return result;
 }
@@ -2124,8 +2141,11 @@ Object* Heap::AllocateFixedArray(int length) {
     reinterpret_cast<Array*>(result)->set_map(fixed_array_map());
     FixedArray* array = FixedArray::cast(result);
     array->set_length(length);
+    Object* value = undefined_value();
     // Initialize body.
-    for (int index = 0; index < length; index++) array->set_undefined(index);
+    for (int index = 0; index < length; index++) {
+      array->set(index, value, SKIP_WRITE_BARRIER);
+    }
   }
   return result;
 }
@@ -2150,7 +2170,10 @@ Object* Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
   reinterpret_cast<Array*>(result)->set_map(fixed_array_map());
   FixedArray* array = FixedArray::cast(result);
   array->set_length(length);
-  for (int index = 0; index < length; index++) array->set_undefined(index);
+  Object* value = undefined_value();
+  for (int index = 0; index < length; index++) {
+    array->set(index, value, SKIP_WRITE_BARRIER);
+  }
   return array;
 }
 
@@ -2164,7 +2187,10 @@ Object* Heap::AllocateFixedArrayWithHoles(int length) {
     FixedArray* array = FixedArray::cast(result);
     array->set_length(length);
     // Initialize body.
-    for (int index = 0; index < length; index++) array->set_the_hole(index);
+    Object* value = the_hole_value();
+    for (int index = 0; index < length; index++)  {
+      array->set(index, value, SKIP_WRITE_BARRIER);
+    }
   }
   return result;
 }
index 768c719fc2058aab7cf08a493f9408c0679f934c..675f82ac1b4e19e683a7813499b7432dec666c51 100644 (file)
@@ -222,8 +222,12 @@ Handle<Object> RegExpImpl::AtomExec(Handle<JSRegExp> re,
   if (value == -1) return Factory::null_value();
 
   Handle<FixedArray> array = Factory::NewFixedArray(2);
-  array->set(0, Smi::FromInt(value));
-  array->set(1, Smi::FromInt(value + needle->length()));
+  array->set(0,
+             Smi::FromInt(value),
+             SKIP_WRITE_BARRIER);
+  array->set(1,
+             Smi::FromInt(value + needle->length()),
+             SKIP_WRITE_BARRIER);
   return Factory::NewJSArrayWithElements(array);
 }
 
@@ -247,8 +251,12 @@ Handle<Object> RegExpImpl::AtomExecGlobal(Handle<JSRegExp> re,
     int end = value + needle_length;
 
     Handle<FixedArray> array = Factory::NewFixedArray(2);
-    array->set(0, Smi::FromInt(value));
-    array->set(1, Smi::FromInt(end));
+    array->set(0,
+               Smi::FromInt(value),
+               SKIP_WRITE_BARRIER);
+    array->set(1,
+               Smi::FromInt(end),
+               SKIP_WRITE_BARRIER);
     Handle<JSArray> pair = Factory::NewJSArrayWithElements(array);
     SetElement(result, match_count, pair);
     match_count++;
@@ -372,8 +380,12 @@ Handle<Object> RegExpImpl::JsreExecOnce(Handle<JSRegExp> regexp,
   Handle<FixedArray> array = Factory::NewFixedArray(2 * (num_captures+1));
   // The captures come in (start, end+1) pairs.
   for (int i = 0; i < 2 * (num_captures+1); i += 2) {
-    array->set(i, Smi::FromInt(offsets_vector[i]));
-    array->set(i+1, Smi::FromInt(offsets_vector[i+1]));
+    array->set(i,
+               Smi::FromInt(offsets_vector[i]),
+               SKIP_WRITE_BARRIER);
+    array->set(i+1,
+               Smi::FromInt(offsets_vector[i+1]),
+               SKIP_WRITE_BARRIER);
   }
   return Factory::NewJSArrayWithElements(array);
 }
index 880f4e684c9926e283b0e7fa605ba5dc42310a47..0cfa12b01d5162cb8f0598852a33489b021d7d05 100644 (file)
@@ -66,12 +66,13 @@ Smi* PropertyDetails::AsSmi() {
 
 #define ACCESSORS(holder, name, type, offset)                           \
   type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
-  void holder::set_##name(type* value) {                                \
+  void holder::set_##name(type* value, WriteBarrierMode mode) {         \
     WRITE_FIELD(this, offset, value);                                   \
-    WRITE_BARRIER(this, offset);                                        \
+    CONDITIONAL_WRITE_BARRIER(this, offset, mode);                      \
   }
 
 
+
 #define SMI_ACCESSORS(holder, name, offset)             \
   int holder::name() {                                  \
     Object* value = READ_FIELD(this, offset);           \
@@ -505,9 +506,21 @@ Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
 #define WRITE_FIELD(p, offset, value) \
   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
 
+
 #define WRITE_BARRIER(object, offset) \
   Heap::RecordWrite(object->address(), offset);
 
+// CONITIONAL_WRITE_BARRIER must be issued after the actual
+// write due to the assert validating the written value.
+#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
+  if (mode == UPDATE_WRITE_BARRIER) { \
+    Heap::RecordWrite(object->address(), offset); \
+  } else { \
+    ASSERT(mode == SKIP_WRITE_BARRIER); \
+    ASSERT(Heap::InNewSpace(object) || \
+           !Heap::InNewSpace(READ_FIELD(object, offset))); \
+  }
+
 #define READ_DOUBLE_FIELD(p, offset) \
   (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
 
@@ -940,7 +953,7 @@ void JSObject::SetInternalField(int index, Object* value) {
 // Access fast-case object properties at index. The use of these routines
 // is needed to correctly distinguish between properties stored in-object and
 // properties stored in the properties array.
-inline Object* JSObject::FastPropertyAt(int index) {
+Object* JSObject::FastPropertyAt(int index) {
   // Adjust for the number of properties stored in the object.
   index -= map()->inobject_properties();
   if (index < 0) {
@@ -953,7 +966,7 @@ inline Object* JSObject::FastPropertyAt(int index) {
 }
 
 
-inline Object* JSObject::FastPropertyAtPut(int index, Object* value) {
+Object* JSObject::FastPropertyAtPut(int index, Object* value) {
   // Adjust for the number of properties stored in the object.
   index -= map()->inobject_properties();
   if (index < 0) {
@@ -968,6 +981,20 @@ inline Object* JSObject::FastPropertyAtPut(int index, Object* value) {
 }
 
 
+Object* JSObject::InObjectPropertyAtPut(int index,
+                                        Object* value,
+                                        WriteBarrierMode mode) {
+  // Adjust for the number of properties stored in the object.
+  index -= map()->inobject_properties();
+  ASSERT(index < 0);
+  int offset = map()->instance_size() + (index * kPointerSize);
+  WRITE_FIELD(this, offset, value);
+  CONDITIONAL_WRITE_BARRIER(this, offset, mode);
+  return value;
+}
+
+
+
 void JSObject::InitializeBody(int object_size) {
   Object* value = Heap::undefined_value();
   for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
@@ -1035,7 +1062,7 @@ void FixedArray::set(int index, Object* value) {
 }
 
 
-FixedArray::WriteBarrierMode FixedArray::GetWriteBarrierMode() {
+WriteBarrierMode HeapObject::GetWriteBarrierMode() {
   if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
   return UPDATE_WRITE_BARRIER;
 }
@@ -1043,16 +1070,11 @@ FixedArray::WriteBarrierMode FixedArray::GetWriteBarrierMode() {
 
 void FixedArray::set(int index,
                      Object* value,
-                     FixedArray::WriteBarrierMode mode) {
+                     WriteBarrierMode mode) {
   ASSERT(index >= 0 && index < this->length());
   int offset = kHeaderSize + index * kPointerSize;
   WRITE_FIELD(this, offset, value);
-  if (mode == UPDATE_WRITE_BARRIER) {
-    WRITE_BARRIER(this, offset);
-  } else {
-    ASSERT(mode == SKIP_WRITE_BARRIER);
-    ASSERT(Heap::InNewSpace(this) || !Heap::InNewSpace(value));
-  }
+  CONDITIONAL_WRITE_BARRIER(this, offset, mode);
 }
 
 
@@ -1805,10 +1827,10 @@ Object* Map::prototype() {
 }
 
 
-void Map::set_prototype(Object* value) {
+void Map::set_prototype(Object* value, WriteBarrierMode mode) {
   ASSERT(value->IsNull() || value->IsJSObject());
   WRITE_FIELD(this, kPrototypeOffset, value);
-  WRITE_BARRIER(this, kPrototypeOffset);
+  CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
 }
 
 
@@ -1949,9 +1971,9 @@ Code* SharedFunctionInfo::code() {
 }
 
 
-void SharedFunctionInfo::set_code(Code* value) {
+void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
   WRITE_FIELD(this, kCodeOffset, value);
-  WRITE_BARRIER(this, kCodeOffset);
+  CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
 }
 
 
@@ -2348,6 +2370,7 @@ Object* FixedArray::Copy() {
 #undef READ_FIELD
 #undef WRITE_FIELD
 #undef WRITE_BARRIER
+#undef CONDITIONAL_WRITE_BARRIER
 #undef READ_MEMADDR_FIELD
 #undef WRITE_MEMADDR_FIELD
 #undef READ_DOUBLE_FIELD
index 0bf936c828533fda84c839729bc80f37b214c49f..d12c3ebccd83835461f49cece5609dd02202b0d0 100644 (file)
@@ -2647,7 +2647,8 @@ Object* DescriptorArray::Allocate(int number_of_descriptors) {
   if (array->IsFailure()) return array;
   result->set(kContentArrayIndex, array);
   result->set(kEnumerationIndexIndex,
-              Smi::FromInt(PropertyDetails::kInitialIndex));
+              Smi::FromInt(PropertyDetails::kInitialIndex),
+              SKIP_WRITE_BARRIER);
   return result;
 }
 
@@ -4451,7 +4452,7 @@ void JSObject::SetFastElements(FixedArray* elems) {
   uint32_t len = static_cast<uint32_t>(elems->length());
   for (uint32_t i = 0; i < len; i++) ASSERT(elems->get(i)->IsTheHole());
 #endif
-  FixedArray::WriteBarrierMode mode = elems->GetWriteBarrierMode();
+  WriteBarrierMode mode = elems->GetWriteBarrierMode();
   if (HasFastElements()) {
     FixedArray* old_elements = FixedArray::cast(elements());
     uint32_t old_length = static_cast<uint32_t>(old_elements->length());
@@ -4500,7 +4501,7 @@ Object* JSObject::SetSlowElements(Object* len) {
 
 Object* JSArray::Initialize(int capacity) {
   ASSERT(capacity >= 0);
-  set_length(Smi::FromInt(0));
+  set_length(Smi::FromInt(0), SKIP_WRITE_BARRIER);
   FixedArray* new_elements;
   if (capacity == 0) {
     new_elements = Heap::empty_fixed_array();
@@ -4544,7 +4545,7 @@ Object* JSObject::SetElementsLength(Object* len) {
           for (int i = value; i < old_length; i++) {
             FixedArray::cast(elements())->set_the_hole(i);
           }
-          JSArray::cast(this)->set_length(smi_length);
+          JSArray::cast(this)->set_length(smi_length, SKIP_WRITE_BARRIER);
         }
         return this;
       }
@@ -4554,7 +4555,8 @@ Object* JSObject::SetElementsLength(Object* len) {
           !ShouldConvertToSlowElements(new_capacity)) {
         Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity);
         if (obj->IsFailure()) return obj;
-        if (IsJSArray()) JSArray::cast(this)->set_length(smi_length);
+        if (IsJSArray()) JSArray::cast(this)->set_length(smi_length,
+                                                         SKIP_WRITE_BARRIER);
         SetFastElements(FixedArray::cast(obj));
         return this;
       }
@@ -4571,7 +4573,7 @@ Object* JSObject::SetElementsLength(Object* len) {
               static_cast<uint32_t>(JSArray::cast(this)->length()->Number());
           element_dictionary()->RemoveNumberEntries(value, old_length);
         }
-        JSArray::cast(this)->set_length(smi_length);
+        JSArray::cast(this)->set_length(smi_length, SKIP_WRITE_BARRIER);
       }
       return this;
     }
@@ -4592,7 +4594,8 @@ Object* JSObject::SetElementsLength(Object* len) {
   Object* obj = Heap::AllocateFixedArray(1);
   if (obj->IsFailure()) return obj;
   FixedArray::cast(obj)->set(0, len);
-  if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
+  if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1),
+                                                   SKIP_WRITE_BARRIER);
   set_elements(FixedArray::cast(obj));
   return this;
 }
@@ -4793,7 +4796,8 @@ Object* JSObject::SetFastElement(uint32_t index, Object* value) {
       CHECK(Array::IndexFromObject(JSArray::cast(this)->length(),
                                    &array_length));
       if (index >= array_length) {
-        JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
+        JSArray::cast(this)->set_length(Smi::FromInt(index + 1),
+                                        SKIP_WRITE_BARRIER);
       }
     }
     return value;
@@ -4809,7 +4813,8 @@ Object* JSObject::SetFastElement(uint32_t index, Object* value) {
       Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity);
       if (obj->IsFailure()) return obj;
       SetFastElements(FixedArray::cast(obj));
-      if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
+      if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(index + 1),
+                                                       SKIP_WRITE_BARRIER);
       FixedArray::cast(elements())->set(index, value);
       return value;
     }
@@ -5091,7 +5096,7 @@ Object* JSArray::RemoveHoles() {
         pos++;
       }
     }
-    set_length(Smi::FromInt(pos));
+    set_length(Smi::FromInt(pos), SKIP_WRITE_BARRIER);
     for (int index = pos; index < len; index++) {
       elms->set_the_hole(index);
     }
@@ -5107,7 +5112,7 @@ Object* JSArray::RemoveHoles() {
     Object* obj = Heap::AllocateFixedArray(length);
     if (obj->IsFailure()) return obj;
     dict->CopyValuesTo(FixedArray::cast(obj));
-    set_length(Smi::FromInt(length));
+    set_length(Smi::FromInt(length), SKIP_WRITE_BARRIER);
     set_elements(FixedArray::cast(obj));
     return this;
   }
@@ -5115,7 +5120,7 @@ Object* JSArray::RemoveHoles() {
   // Make another dictionary with smaller indices.
   Object* obj = dict->RemoveHoles();
   if (obj->IsFailure()) return obj;
-  set_length(Smi::FromInt(length));
+  set_length(Smi::FromInt(length), SKIP_WRITE_BARRIER);
   set_elements(Dictionary::cast(obj));
   return this;
 }
@@ -5443,9 +5448,7 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
     for (int i = 0; i < length; i++) {
       if (!FixedArray::cast(elements())->get(i)->IsTheHole()) {
         if (storage) {
-          storage->set(counter,
-                       Smi::FromInt(i),
-                       FixedArray::SKIP_WRITE_BARRIER);
+          storage->set(counter, Smi::FromInt(i), SKIP_WRITE_BARRIER);
         }
         counter++;
       }
@@ -5464,9 +5467,7 @@ int JSObject::GetLocalElementKeys(FixedArray* storage,
       String* str = String::cast(val);
       if (storage) {
         for (int i = 0; i < str->length(); i++) {
-          storage->set(counter + i,
-                       Smi::FromInt(i),
-                       FixedArray::SKIP_WRITE_BARRIER);
+          storage->set(counter + i, Smi::FromInt(i), SKIP_WRITE_BARRIER);
         }
       }
       counter += str->length();
@@ -5997,7 +5998,9 @@ Object* Dictionary::GenerateNewEnumerationIndices() {
   Object* obj = Heap::AllocateFixedArray(length);
   if (obj->IsFailure()) return obj;
   FixedArray* iteration_order = FixedArray::cast(obj);
-  for (int i = 0; i < length; i++) iteration_order->set(i, Smi::FromInt(i));
+  for (int i = 0; i < length; i++) {
+    iteration_order->set(i, Smi::FromInt(i), SKIP_WRITE_BARRIER);
+  }
 
   // Allocate array with enumeration order.
   obj = Heap::AllocateFixedArray(length);
@@ -6009,7 +6012,9 @@ Object* Dictionary::GenerateNewEnumerationIndices() {
   int pos = 0;
   for (int i = 0; i < capacity; i++) {
     if (IsKey(KeyAt(i))) {
-      enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index()));
+      enumeration_order->set(pos++,
+                             Smi::FromInt(DetailsAt(i).index()),
+                             SKIP_WRITE_BARRIER);
     }
   }
 
@@ -6020,7 +6025,9 @@ Object* Dictionary::GenerateNewEnumerationIndices() {
   for (int i = 0; i < length; i++) {
     int index = Smi::cast(iteration_order->get(i))->value();
     int enum_index = PropertyDetails::kInitialIndex + i;
-    enumeration_order->set(index, Smi::FromInt(enum_index));
+    enumeration_order->set(index,
+                           Smi::FromInt(enum_index),
+                           SKIP_WRITE_BARRIER);
   }
 
   // Update the dictionary with new indices.
@@ -6158,13 +6165,17 @@ void Dictionary::UpdateMaxNumberKey(uint32_t key) {
   // Check if this index is high enough that we should require slow
   // elements.
   if (key > kRequiresSlowElementsLimit) {
-    set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
+    set(kMaxNumberKeyIndex,
+        Smi::FromInt(kRequiresSlowElementsMask),
+        SKIP_WRITE_BARRIER);
     return;
   }
   // Update max key value.
   Object* max_index_object = get(kMaxNumberKeyIndex);
   if (!max_index_object->IsSmi() || max_number_key() < key) {
-    set(kMaxNumberKeyIndex, Smi::FromInt(key << kRequiresSlowElementsTagSize));
+    set(kMaxNumberKeyIndex,
+        Smi::FromInt(key << kRequiresSlowElementsTagSize),
+        SKIP_WRITE_BARRIER);
   }
 }
 
@@ -6261,7 +6272,9 @@ void Dictionary::CopyEnumKeysTo(FixedArray* storage, FixedArray* sort_array) {
        PropertyDetails details = DetailsAt(i);
        if (!details.IsDontEnum()) {
          storage->set(index, k);
-         sort_array->set(index, Smi::FromInt(details.index()));
+         sort_array->set(index,
+                         Smi::FromInt(details.index()),
+                         SKIP_WRITE_BARRIER);
          index++;
        }
      }
index 971eab04b0f4d6ec6de7443b46246dd8739d3047..e3bd522a84111560f2f2a1ac9e740699f7a4997f 100644 (file)
@@ -166,6 +166,9 @@ class PropertyDetails BASE_EMBEDDED {
   uint32_t value_;
 };
 
+// Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
+enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };
+
 // All Maps have a field instance_type containing a InstanceType.
 // It describes the type of the instances.
 //
@@ -555,9 +558,10 @@ enum CompareResult {
   inline void set_##name(bool value);  \
 
 
-#define DECL_ACCESSORS(name, type)  \
-  inline type* name();                 \
-  inline void set_##name(type* value);
+#define DECL_ACCESSORS(name, type)    \
+  inline type* name();                \
+  inline void set_##name(type* value, \
+                         WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
 
 
 class StringStream;
@@ -1041,6 +1045,9 @@ class HeapObject: public Object {
   // Casting.
   static inline HeapObject* cast(Object* obj);
 
+  // Return the write barrier mode for this.
+  inline WriteBarrierMode GetWriteBarrierMode();
+
   // Dispatched behavior.
   void HeapObjectShortPrint(StringStream* accumulator);
 #ifdef DEBUG
@@ -1355,6 +1362,11 @@ class JSObject: public HeapObject {
   inline Object* FastPropertyAt(int index);
   inline Object* FastPropertyAtPut(int index, Object* value);
 
+  // Access to set in object properties.
+  inline Object* InObjectPropertyAtPut(int index,
+                                       Object* value,
+                                       WriteBarrierMode mode
+                                       = UPDATE_WRITE_BARRIER);
 
   // initializes the body after properties slot, properties slot is
   // initialized by set_properties
@@ -1479,17 +1491,14 @@ class FixedArray: public Array {
   inline Object* get(int index);
   inline void set(int index, Object* value);
 
+  // Setter with barrier mode.
+  inline void set(int index, Object* value, WriteBarrierMode mode);
+
   // Setters for frequently used oddballs located in old space.
   inline void set_undefined(int index);
   inline void set_null(int index);
   inline void set_the_hole(int index);
 
-  // Setter that skips the write barrier if mode is SKIP_WRITE_BARRIER.
-  enum WriteBarrierMode { SKIP_WRITE_BARRIER, UPDATE_WRITE_BARRIER };
-  inline void set(int index, Object* value, WriteBarrierMode mode);
-  // Return the write barrier mode for this.
-  inline WriteBarrierMode GetWriteBarrierMode();
-
   // Copy operations.
   inline Object* Copy();
   Object* CopySize(int new_length);
index d0118dccbcf6c813478712c5c52678910ec2dc8e..32246f34872b7ae863e99b2e1be302cd853ff4ab 100644 (file)
@@ -3136,7 +3136,7 @@ static Object* Runtime_NewArguments(Arguments args) {
   if (result->IsFailure()) return result;
   FixedArray* array = FixedArray::cast(JSObject::cast(result)->elements());
   ASSERT(array->length() == length);
-  FixedArray::WriteBarrierMode mode = array->GetWriteBarrierMode();
+  WriteBarrierMode mode = array->GetWriteBarrierMode();
   for (int i = 0; i < length; i++) {
     array->set(i, frame->GetParameter(i), mode);
   }
@@ -3156,7 +3156,7 @@ static Object* Runtime_NewArgumentsFast(Arguments args) {
   if (result->IsFailure()) return result;
   FixedArray* array = FixedArray::cast(JSObject::cast(result)->elements());
   ASSERT(array->length() == length);
-  FixedArray::WriteBarrierMode mode = array->GetWriteBarrierMode();
+  WriteBarrierMode mode = array->GetWriteBarrierMode();
   for (int i = 0; i < length; i++) {
     array->set(i, *--parameters, mode);
   }
@@ -4051,7 +4051,9 @@ static Object* Runtime_GetArrayKeys(Arguments args) {
   } else {
     Handle<FixedArray> single_interval = Factory::NewFixedArray(2);
     // -1 means start of array.
-    single_interval->set(0, Smi::FromInt(-1));
+    single_interval->set(0,
+                         Smi::FromInt(-1),
+                         SKIP_WRITE_BARRIER);
     Handle<Object> length_object =
         Factory::NewNumber(static_cast<double>(length));
     single_interval->set(1, *length_object);
@@ -4901,7 +4903,7 @@ static Handle<Object> GetArgumentsObject(JavaScriptFrame* frame,
   Handle<Object> arguments = Factory::NewArgumentsObject(function, length);
   FixedArray* array = FixedArray::cast(JSObject::cast(*arguments)->elements());
   ASSERT(array->length() == length);
-  FixedArray::WriteBarrierMode mode = array->GetWriteBarrierMode();
+  WriteBarrierMode mode = array->GetWriteBarrierMode();
   for (int i = 0; i < length; i++) {
     array->set(i, frame->GetParameter(i), mode);
   }