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,
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
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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++;
}
}
......
......@@ -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);
......
......@@ -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);
}
......
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