Commit 187879a2 authored by bak@chromium.org's avatar bak@chromium.org

- Added conditional write barrier to object accessors.

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