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