From 187879a25a06ccf12510dd5b47a2b583fe567c86 Mon Sep 17 00:00:00 2001 From: "bak@chromium.org" Date: Thu, 23 Oct 2008 08:46:32 +0000 Subject: [PATCH] - 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 --- src/bootstrapper.cc | 33 +++++++++++++++++++----- src/builtins.cc | 11 ++++---- src/dateparser.cc | 32 ++++++++++++++++++------ src/heap.cc | 52 ++++++++++++++++++++++++++++---------- src/jsregexp.cc | 24 +++++++++++++----- src/objects-inl.h | 55 ++++++++++++++++++++++++++++------------ src/objects.cc | 61 +++++++++++++++++++++++++++------------------ src/objects.h | 27 +++++++++++++------- src/runtime.cc | 10 +++++--- 9 files changed, 213 insertions(+), 92 deletions(-) diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 587543868..0562c236c 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -739,25 +739,46 @@ void Genesis::CreateRoots(v8::Handle global_template, Handle prototype = Handle( JSObject::cast(global_context()->object_function()->prototype())); + Handle 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 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 diff --git a/src/builtins.cc b/src/builtins.cc index b274d3a12..03bce6540 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -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; } diff --git a/src/dateparser.cc b/src/dateparser.cc index 69cf74862..4b64785bb 100644 --- a/src/dateparser.cc +++ b/src/dateparser.cc @@ -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; } diff --git a/src/heap.cc b/src/heap.cc index bc8dd76d2..00cf78be5 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -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(HeapObject::cast(result)->address()), + reinterpret_cast(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(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(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; } diff --git a/src/jsregexp.cc b/src/jsregexp.cc index 768c719fc..675f82ac1 100644 --- a/src/jsregexp.cc +++ b/src/jsregexp.cc @@ -222,8 +222,12 @@ Handle RegExpImpl::AtomExec(Handle re, if (value == -1) return Factory::null_value(); Handle 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 RegExpImpl::AtomExecGlobal(Handle re, int end = value + needle_length; Handle 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 pair = Factory::NewJSArrayWithElements(array); SetElement(result, match_count, pair); match_count++; @@ -372,8 +380,12 @@ Handle RegExpImpl::JsreExecOnce(Handle regexp, Handle 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); } diff --git a/src/objects-inl.h b/src/objects-inl.h index 880f4e684..0cfa12b01 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -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(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(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 diff --git a/src/objects.cc b/src/objects.cc index 0bf936c82..d12c3ebcc 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -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(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(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(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++; } } diff --git a/src/objects.h b/src/objects.h index 971eab04b..e3bd522a8 100644 --- a/src/objects.h +++ b/src/objects.h @@ -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); diff --git a/src/runtime.cc b/src/runtime.cc index d0118dccb..32246f348 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -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 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 length_object = Factory::NewNumber(static_cast(length)); single_interval->set(1, *length_object); @@ -4901,7 +4903,7 @@ static Handle GetArgumentsObject(JavaScriptFrame* frame, Handle 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); } -- 2.34.1