Reviewers: Vyacheslav Egorov,

Description:
Elide write barriers and remove some heap_object->GetHeap() calls on
Smi write barriers.

Please review this at http://codereview.chromium.org/8822008/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/

Affected files:
  M     src/heap-inl.h
  M     src/objects-inl.h
  M     src/objects.cc


Index: src/heap-inl.h
===================================================================
--- src/heap-inl.h      (revision 10171)
+++ src/heap-inl.h      (working copy)
@@ -125,7 +125,8 @@
     if (!maybe_result->ToObject(&result)) return maybe_result;
   }

-  reinterpret_cast<HeapObject*>(result)->set_map(map);
+  // String maps are all immortal immovable objects.
+  reinterpret_cast<HeapObject*>(result)->set_map_unsafe(map);
   // Set length and hash fields of the allocated string.
   String* answer = String::cast(result);
   answer->set_length(str.length());
Index: src/objects-inl.h
===================================================================
--- src/objects-inl.h   (revision 10171)
+++ src/objects-inl.h   (working copy)
@@ -90,7 +90,7 @@
   type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
   void holder::set_##name(type* value, WriteBarrierMode mode) {         \
     WRITE_FIELD(this, offset, value);                                   \
-    CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);    \
+    CONDITIONAL_WRITE_BARRIER(this, offset, value, mode);               \
   }


@@ -846,15 +846,25 @@
 #define WRITE_FIELD(p, offset, value) \
   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)

-#define WRITE_BARRIER(heap, object, offset, value)                      \
-  heap->incremental_marking()->RecordWrite(                             \
-      object, HeapObject::RawField(object, offset), value);             \
-  if (heap->InNewSpace(value)) {                                        \
-    heap->RecordWrite(object->address(), offset);                       \
+#define WRITE_BARRIER(object, offset, value)                            \
+  Address value_addr = reinterpret_cast<HeapObject*>(value)->address(); \
+  if (!value->IsSmi() && Page::FromAddress(value_addr)->IsFlagSet(      \
+        MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING)) {               \
+    Heap* heap = object->GetHeap();                                     \
+    heap->incremental_marking()->RecordWrite(                           \
+        object, HeapObject::RawField(object, offset), value);           \
+    if (heap->InNewSpace(value)) {                                      \
+      heap->RecordWrite(object->address(), offset);                     \
+    }                                                                   \
   }

-#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode)    \
-  if (mode == UPDATE_WRITE_BARRIER) {                                   \
+#define CONDITIONAL_WRITE_BARRIER(object, offset, value, mode)          \
+  Address value_addr = reinterpret_cast<HeapObject*>(value)->address(); \
+  if (mode == UPDATE_WRITE_BARRIER &&                                   \
+      !value->IsSmi() &&                                                \
+      Page::FromAddress(value_addr)->IsFlagSet(                         \
+          MemoryChunk::POINTERS_TO_HERE_ARE_INTERESTING)) {             \
+    Heap* heap = object->GetHeap();                                     \
     heap->incremental_marking()->RecordWrite(                           \
       object, HeapObject::RawField(object, offset), value);             \
     if (heap->InNewSpace(value)) {                                      \
@@ -862,6 +872,15 @@
     }                                                                   \
   }

+#define CONDITIONAL_WRITE_BARRIER_WITH_HEAP(heap, object, offset, value, mode) \ + if (mode == UPDATE_WRITE_BARRIER) { \ + heap->incremental_marking()->RecordWrite( \ + object, HeapObject::RawField(object, offset), value); \ + if (heap->InNewSpace(value)) { \ + heap->RecordWrite(object->address(), offset); \ + } \
+  }
+
 #ifndef V8_TARGET_ARCH_MIPS
   #define READ_DOUBLE_FIELD(p, offset) \
     (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
@@ -1258,7 +1277,7 @@
   ValidateSmiOnlyElements();
 #endif
   WRITE_FIELD(this, kElementsOffset, value);
-  CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
+  CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, value, mode);
 }


@@ -1381,7 +1400,7 @@
   // to adjust the index here.
   int offset = GetHeaderSize() + (kPointerSize * index);
   WRITE_FIELD(this, offset, value);
-  WRITE_BARRIER(GetHeap(), this, offset, value);
+  WRITE_BARRIER(this, offset, value);
 }


@@ -1417,7 +1436,7 @@
   if (index < 0) {
     int offset = map()->instance_size() + (index * kPointerSize);
     WRITE_FIELD(this, offset, value);
-    WRITE_BARRIER(GetHeap(), this, offset, value);
+    WRITE_BARRIER(this, offset, value);
   } else {
     ASSERT(index < properties()->length());
     properties()->set(index, value);
@@ -1451,7 +1470,7 @@
   ASSERT(index < 0);
   int offset = map()->instance_size() + (index * kPointerSize);
   WRITE_FIELD(this, offset, value);
-  CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
+  CONDITIONAL_WRITE_BARRIER(this, offset, value, mode);
   return value;
 }

@@ -1562,7 +1581,7 @@
   ASSERT(index >= 0 && index < this->length());
   int offset = kHeaderSize + index * kPointerSize;
   WRITE_FIELD(this, offset, value);
-  WRITE_BARRIER(GetHeap(), this, offset, value);
+  WRITE_BARRIER(this, offset, value);
 }


@@ -1699,7 +1718,7 @@
   ASSERT(index >= 0 && index < this->length());
   int offset = kHeaderSize + index * kPointerSize;
   WRITE_FIELD(this, offset, value);
-  CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
+  CONDITIONAL_WRITE_BARRIER(this, offset, value, mode);
 }


@@ -1762,7 +1781,7 @@
                                WriteBarrierMode mode) {
   int offset = kHeaderSize + index * kPointerSize;
   WRITE_FIELD(this, offset, value);
-  CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
+  CONDITIONAL_WRITE_BARRIER_WITH_HEAP(heap, this, offset, value, mode);
 }


@@ -2277,7 +2296,7 @@

 void ConsString::set_first(String* value, WriteBarrierMode mode) {
   WRITE_FIELD(this, kFirstOffset, value);
-  CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
+  CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, value, mode);
 }


@@ -2293,7 +2312,7 @@

 void ConsString::set_second(String* value, WriteBarrierMode mode) {
   WRITE_FIELD(this, kSecondOffset, value);
-  CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
+  CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, value, mode);
 }


@@ -3209,7 +3228,7 @@
 void Map::set_prototype(Object* value, WriteBarrierMode mode) {
   ASSERT(value->IsNull() || value->IsJSReceiver());
   WRITE_FIELD(this, kPrototypeOffset, value);
- CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
+  CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, value, mode);
 }


@@ -3258,7 +3277,7 @@
   }
   ASSERT(!is_shared());
   WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
-  CONDITIONAL_WRITE_BARRIER(
+  CONDITIONAL_WRITE_BARRIER_WITH_HEAP(
       heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
 }

@@ -3630,7 +3649,7 @@

 void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
   WRITE_FIELD(this, kCodeOffset, value);
- CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
+  CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, value, mode);
 }


@@ -3642,8 +3661,7 @@
 void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
                                         WriteBarrierMode mode) {
   WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
-  CONDITIONAL_WRITE_BARRIER(GetHeap(),
-                            this,
+  CONDITIONAL_WRITE_BARRIER(this,
                             kScopeInfoOffset,
                             reinterpret_cast<Object*>(value),
                             mode);
@@ -3789,7 +3807,7 @@
 void JSFunction::set_context(Object* value) {
   ASSERT(value->IsUndefined() || value->IsContext());
   WRITE_FIELD(this, kContextOffset, value);
-  WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
+  WRITE_BARRIER(this, kContextOffset, value);
 }

 ACCESSORS(JSFunction, prototype_or_initial_map, Object,
@@ -3892,7 +3910,7 @@
                                               Object* value) {
   ASSERT(id < kJSBuiltinsCount);  // id is unsigned.
   WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
-  WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
+  WRITE_BARRIER(this, OffsetOfFunctionWithId(id), value);
 }


Index: src/objects.cc
===================================================================
--- src/objects.cc      (revision 10171)
+++ src/objects.cc      (working copy)
@@ -5395,7 +5395,9 @@
   AssertNoAllocation no_gc;
   int len = length();
   if (new_length < len) len = new_length;
-  result->set_map(map());
+  // We are taking the map from the old fixed array so the map is sure to
+  // be an immortal immutable object.
+  result->set_map_unsafe(map());
   WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
   for (int i = 0; i < len; i++) {
     result->set(i, get(i), mode);
@@ -8115,9 +8117,20 @@
 static void CopyFastElementsToFast(FixedArray* source,
                                    FixedArray* destination,
                                    WriteBarrierMode mode) {
-  uint32_t count = static_cast<uint32_t>(source->length());
-  for (uint32_t i = 0; i < count; ++i) {
-    destination->set(i, source->get(i), mode);
+  int count = source->length();
+  if (mode == SKIP_WRITE_BARRIER ||
+      !Page::FromAddress(destination->address())->IsFlagSet(
+          MemoryChunk::POINTERS_FROM_HERE_ARE_INTERESTING)) {
+    ASSERT(count <= destination->length());
+    Address to = destination->address() + FixedArray::kHeaderSize;
+    Address from = source->address() + FixedArray::kHeaderSize;
+    memcpy(reinterpret_cast<void*>(to),
+           reinterpret_cast<void*>(from),
+           kPointerSize * count);
+  } else {
+    for (int i = 0; i < count; ++i) {
+      destination->set(i, source->get(i), mode);
+    }
   }
 }



--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to