Smi* len = Smi::FromInt(number_of_elements);
Object* obj = Heap::AllocateFixedArrayWithHoles(len->value());
if (obj->IsFailure()) return obj;
+
+ AssertNoAllocation no_gc;
FixedArray* elms = FixedArray::cast(obj);
- WriteBarrierMode mode = elms->GetWriteBarrierMode();
+ WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
// Fill in the content
for (int index = 0; index < number_of_elements; index++) {
elms->set(index, args[index+1], mode);
// Set length and elements on the array.
array->set_elements(FixedArray::cast(obj));
- array->set_length(len, SKIP_WRITE_BARRIER);
+ array->set_length(len);
return array;
}
int capacity = new_length + (new_length >> 1) + 16;
Object* obj = Heap::AllocateFixedArrayWithHoles(capacity);
if (obj->IsFailure()) return obj;
+
+ AssertNoAllocation no_gc;
FixedArray* new_elms = FixedArray::cast(obj);
- WriteBarrierMode mode = new_elms->GetWriteBarrierMode();
+ WriteBarrierMode mode = new_elms->GetWriteBarrierMode(no_gc);
// 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.
array->set_elements(new_elms);
}
// Set the length.
- array->set_length(Smi::FromInt(new_length), SKIP_WRITE_BARRIER);
+ array->set_length(Smi::FromInt(new_length));
return array->length();
}
Object* top = elms->get(len - 1);
// Set the length.
- array->set_length(Smi::FromInt(len - 1), SKIP_WRITE_BARRIER);
+ array->set_length(Smi::FromInt(len - 1));
if (!top->IsTheHole()) {
// Delete the top element.
if (!Smi::IsValid(year) || !IsMonth(month) || !IsDay(day)) return false;
- 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);
+ output->set(YEAR, Smi::FromInt(year));
+ output->set(MONTH, Smi::FromInt(month - 1)); // 0-based
+ output->set(DAY, Smi::FromInt(day));
return true;
}
if (!IsHour(hour) || !IsMinute(minute) || !IsSecond(second)) return false;
- 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);
+ output->set(HOUR, Smi::FromInt(hour));
+ output->set(MINUTE, Smi::FromInt(minute));
+ output->set(SECOND, Smi::FromInt(second));
return true;
}
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),
- SKIP_WRITE_BARRIER);
+ output->set(UTC_OFFSET, Smi::FromInt(total_seconds));
} else {
- output->set(UTC_OFFSET,
- Heap::null_value(),
- SKIP_WRITE_BARRIER);
+ output->set_null(UTC_OFFSET);
}
return true;
}
class Allocation;
class Arguments;
class Assembler;
+class AssertNoAllocation;
class BreakableStatement;
class Code;
class CodeGenerator;
int mask = (number_string_cache()->length() >> 1) - 1;
if (number->IsSmi()) {
hash = smi_get_hash(Smi::cast(number)) & mask;
- number_string_cache()->set(hash * 2, number, SKIP_WRITE_BARRIER);
+ number_string_cache()->set(hash * 2, Smi::cast(number));
} else {
hash = double_get_hash(number->Number()) & mask;
number_string_cache()->set(hash * 2, number);
Object* result = Allocate(map, NEW_SPACE);
if (result->IsFailure()) return result;
+
+ AssertNoAllocation no_gc;
ConsString* cons_string = ConsString::cast(result);
- WriteBarrierMode mode = cons_string->GetWriteBarrierMode();
+ WriteBarrierMode mode = cons_string->GetWriteBarrierMode(no_gc);
cons_string->set_length(length);
cons_string->set_hash_field(String::kEmptyHashField);
cons_string->set_first(first, mode);
function->set_shared(shared);
function->set_prototype_or_initial_map(prototype);
function->set_context(undefined_value());
- function->set_literals(empty_fixed_array(), SKIP_WRITE_BARRIER);
+ function->set_literals(empty_fixed_array());
return function;
}
HeapObject::cast(obj)->set_map(src->map());
FixedArray* result = FixedArray::cast(obj);
result->set_length(len);
+
// Copy the content
- WriteBarrierMode mode = result->GetWriteBarrierMode();
+ AssertNoAllocation no_gc;
+ WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
for (int i = 0; i < len; i++) result->set(i, src->get(i), mode);
return result;
}
Object* value = undefined_value();
// Initialize body.
for (int index = 0; index < length; index++) {
+ ASSERT(!Heap::InNewSpace(value)); // value = undefined
array->set(index, value, SKIP_WRITE_BARRIER);
}
}
array->set_length(length);
Object* value = undefined_value();
for (int index = 0; index < length; index++) {
+ ASSERT(!Heap::InNewSpace(value)); // value = undefined
array->set(index, value, SKIP_WRITE_BARRIER);
}
return array;
// Initialize body.
Object* value = the_hole_value();
for (int index = 0; index < length; index++) {
+ ASSERT(!Heap::InNewSpace(value)); // value = the hole
array->set(index, value, SKIP_WRITE_BARRIER);
}
}
}
-WriteBarrierMode HeapObject::GetWriteBarrierMode() {
+WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
return UPDATE_WRITE_BARRIER;
}
}
void NumberDictionary::set_requires_slow_elements() {
- set(kMaxNumberKeyIndex,
- Smi::FromInt(kRequiresSlowElementsMask),
- SKIP_WRITE_BARRIER);
+ set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
}
PropertyDetails details) {
ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
int index = HashTable<Shape, Key>::EntryToIndex(entry);
- WriteBarrierMode mode = FixedArray::GetWriteBarrierMode();
+ AssertNoAllocation no_gc;
+ WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
FixedArray::set(index, key, mode);
FixedArray::set(index+1, value, mode);
FixedArray::fast_set(this, index+2, details.AsSmi());
}
+void JSArray::set_length(Smi* length) {
+ set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
+}
+
+
void JSArray::SetContent(FixedArray* storage) {
- set_length(Smi::FromInt(storage->length()), SKIP_WRITE_BARRIER);
+ set_length(Smi::FromInt(storage->length()));
set_elements(storage);
}
Object* obj = Heap::AllocateFixedArray(len0 + extra);
if (obj->IsFailure()) return obj;
// Fill in the content
+ AssertNoAllocation no_gc;
FixedArray* result = FixedArray::cast(obj);
- WriteBarrierMode mode = result->GetWriteBarrierMode();
+ WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
for (int i = 0; i < len0; i++) {
result->set(i, get(i), mode);
}
if (obj->IsFailure()) return obj;
FixedArray* result = FixedArray::cast(obj);
// Copy the content
+ AssertNoAllocation no_gc;
int len = length();
if (new_length < len) len = new_length;
result->set_map(map());
- WriteBarrierMode mode = result->GetWriteBarrierMode();
+ WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
for (int i = 0; i < len; i++) {
result->set(i, get(i), mode);
}
void FixedArray::CopyTo(int pos, FixedArray* dest, int dest_pos, int len) {
- WriteBarrierMode mode = dest->GetWriteBarrierMode();
+ AssertNoAllocation no_gc;
+ WriteBarrierMode mode = dest->GetWriteBarrierMode(no_gc);
for (int index = 0; index < len; index++) {
dest->set(dest_pos+index, get(pos+index), mode);
}
if (array->IsFailure()) return array;
result->set(kContentArrayIndex, array);
result->set(kEnumerationIndexIndex,
- Smi::FromInt(PropertyDetails::kInitialIndex),
- SKIP_WRITE_BARRIER);
+ Smi::FromInt(PropertyDetails::kInitialIndex));
return result;
}
ASSERT(target->IsHeapObject());
if (!target->IsMarked()) {
ASSERT(target->IsMap());
- contents->set(i + 1, NullDescriptorDetails, SKIP_WRITE_BARRIER);
- contents->set(i, Heap::null_value(), SKIP_WRITE_BARRIER);
+ contents->set(i + 1, NullDescriptorDetails);
+ contents->set_null(i);
ASSERT(target->prototype() == this ||
target->prototype() == real_prototype);
// Getter prototype() is read-only, set_prototype() has side effects.
uint32_t len = static_cast<uint32_t>(elems->length());
for (uint32_t i = 0; i < len; i++) ASSERT(elems->get(i)->IsTheHole());
#endif
- WriteBarrierMode mode = elems->GetWriteBarrierMode();
+ AssertNoAllocation no_gc;
+ WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc);
switch (GetElementsKind()) {
case FAST_ELEMENTS: {
FixedArray* old_elements = FixedArray::cast(elements());
Object* JSArray::Initialize(int capacity) {
ASSERT(capacity >= 0);
- set_length(Smi::FromInt(0), SKIP_WRITE_BARRIER);
+ set_length(Smi::FromInt(0));
FixedArray* new_elements;
if (capacity == 0) {
new_elements = Heap::empty_fixed_array();
for (int i = value; i < old_length; i++) {
FixedArray::cast(elements())->set_the_hole(i);
}
- JSArray::cast(this)->set_length(smi_length, SKIP_WRITE_BARRIER);
+ JSArray::cast(this)->set_length(Smi::cast(smi_length));
}
return this;
}
!ShouldConvertToSlowElements(new_capacity)) {
Object* obj = Heap::AllocateFixedArrayWithHoles(new_capacity);
if (obj->IsFailure()) return obj;
- if (IsJSArray()) JSArray::cast(this)->set_length(smi_length,
- SKIP_WRITE_BARRIER);
+ if (IsJSArray()) {
+ JSArray::cast(this)->set_length(Smi::cast(smi_length));
+ }
SetFastElements(FixedArray::cast(obj));
return this;
}
static_cast<uint32_t>(JSArray::cast(this)->length()->Number());
element_dictionary()->RemoveNumberEntries(value, old_length);
}
- JSArray::cast(this)->set_length(smi_length, SKIP_WRITE_BARRIER);
+ JSArray::cast(this)->set_length(Smi::cast(smi_length));
}
return this;
}
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),
- SKIP_WRITE_BARRIER);
+ if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1));
set_elements(FixedArray::cast(obj));
return this;
}
CHECK(Array::IndexFromObject(JSArray::cast(this)->length(),
&array_length));
if (index >= array_length) {
- JSArray::cast(this)->set_length(Smi::FromInt(index + 1),
- SKIP_WRITE_BARRIER);
+ JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
}
}
return 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),
- SKIP_WRITE_BARRIER);
+ if (IsJSArray()) {
+ JSArray::cast(this)->set_length(Smi::FromInt(index + 1));
+ }
FixedArray::cast(elements())->set(index, value);
return value;
}
void Dictionary<Shape, Key>::CopyValuesTo(FixedArray* elements) {
int pos = 0;
int capacity = HashTable<Shape, Key>::Capacity();
- WriteBarrierMode mode = elements->GetWriteBarrierMode();
+ AssertNoAllocation no_gc;
+ WriteBarrierMode mode = elements->GetWriteBarrierMode(no_gc);
for (int i = 0; i < capacity; i++) {
Object* k = Dictionary<Shape, Key>::KeyAt(i);
if (Dictionary<Shape, Key>::IsKey(k)) {
for (int i = 0; i < length; i++) {
if (!FixedArray::cast(elements())->get(i)->IsTheHole()) {
if (storage != NULL) {
- storage->set(counter, Smi::FromInt(i), SKIP_WRITE_BARRIER);
+ storage->set(counter, Smi::FromInt(i));
}
counter++;
}
int length = PixelArray::cast(elements())->length();
while (counter < length) {
if (storage != NULL) {
- storage->set(counter, Smi::FromInt(counter), SKIP_WRITE_BARRIER);
+ storage->set(counter, Smi::FromInt(counter));
}
counter++;
}
int length = ExternalArray::cast(elements())->length();
while (counter < length) {
if (storage != NULL) {
- storage->set(counter, Smi::FromInt(counter), SKIP_WRITE_BARRIER);
+ storage->set(counter, Smi::FromInt(counter));
}
counter++;
}
String* str = String::cast(val);
if (storage) {
for (int i = 0; i < str->length(); i++) {
- storage->set(counter + i, Smi::FromInt(i), SKIP_WRITE_BARRIER);
+ storage->set(counter + i, Smi::FromInt(i));
}
}
counter += str->length();
Object* obj = Allocate(nof * 2);
if (obj->IsFailure()) return obj;
+
+ AssertNoAllocation no_gc;
HashTable* table = HashTable::cast(obj);
- WriteBarrierMode mode = table->GetWriteBarrierMode();
+ WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc);
// Copy prefix to new array.
for (int i = kPrefixStartIndex;
// Split elements into defined, undefined and the_hole, in that order.
// Only count locations for undefined and the hole, and fill them afterwards.
- WriteBarrierMode write_barrier = elements->GetWriteBarrierMode();
+ WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc);
unsigned int undefs = limit;
unsigned int holes = limit;
// Assume most arrays contain no holes and undefined values, so minimize the
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), SKIP_WRITE_BARRIER);
+ iteration_order->set(i, Smi::FromInt(i));
}
// Allocate array with enumeration order.
int pos = 0;
for (int i = 0; i < capacity; i++) {
if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) {
- enumeration_order->set(pos++,
- Smi::FromInt(DetailsAt(i).index()),
- SKIP_WRITE_BARRIER);
+ enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index()));
}
}
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),
- SKIP_WRITE_BARRIER);
+ enumeration_order->set(index, Smi::FromInt(enum_index));
}
// Update the dictionary with new indices.
Object* max_index_object = get(kMaxNumberKeyIndex);
if (!max_index_object->IsSmi() || max_number_key() < key) {
FixedArray::set(kMaxNumberKeyIndex,
- Smi::FromInt(key << kRequiresSlowElementsTagSize),
- SKIP_WRITE_BARRIER);
+ Smi::FromInt(key << kRequiresSlowElementsTagSize));
}
}
PropertyDetails details = DetailsAt(i);
if (details.IsDeleted() || details.IsDontEnum()) continue;
storage->set(index, k);
- sort_array->set(index,
- Smi::FromInt(details.index()),
- SKIP_WRITE_BARRIER);
+ sort_array->set(index, Smi::FromInt(details.index()));
index++;
}
}
// Casting.
static inline HeapObject* cast(Object* obj);
- // Return the write barrier mode for this.
- inline WriteBarrierMode GetWriteBarrierMode();
+ // Return the write barrier mode for this. Callers of this function
+ // must be able to present a reference to an AssertNoAllocation
+ // object as a sign that they are not going to use this function
+ // from code that allocates and thus invalidates the returned write
+ // barrier mode.
+ inline WriteBarrierMode GetWriteBarrierMode(const AssertNoAllocation&);
// Dispatched behavior.
void HeapObjectShortPrint(StringStream* accumulator);
// [length]: The length property.
DECL_ACCESSORS(length, Object)
+ // Overload the length setter to skip write barrier when the length
+ // is set to a smi. This matches the set function on FixedArray.
+ inline void set_length(Smi* length);
+
Object* JSArrayUpdateLengthFromIndex(uint32_t index, Object* value);
// Initialize the array with the given capacity. The function may
// Deep copy local properties.
if (copy->HasFastProperties()) {
FixedArray* properties = copy->properties();
- WriteBarrierMode mode = properties->GetWriteBarrierMode();
for (int i = 0; i < properties->length(); i++) {
Object* value = properties->get(i);
if (value->IsJSObject()) {
- JSObject* jsObject = JSObject::cast(value);
- result = DeepCopyBoilerplate(jsObject);
+ JSObject* js_object = JSObject::cast(value);
+ result = DeepCopyBoilerplate(js_object);
if (result->IsFailure()) return result;
- properties->set(i, result, mode);
+ properties->set(i, result);
}
}
- mode = copy->GetWriteBarrierMode();
int nof = copy->map()->inobject_properties();
for (int i = 0; i < nof; i++) {
Object* value = copy->InObjectPropertyAt(i);
if (value->IsJSObject()) {
- JSObject* jsObject = JSObject::cast(value);
- result = DeepCopyBoilerplate(jsObject);
+ JSObject* js_object = JSObject::cast(value);
+ result = DeepCopyBoilerplate(js_object);
if (result->IsFailure()) return result;
- copy->InObjectPropertyAtPut(i, result, mode);
+ copy->InObjectPropertyAtPut(i, result);
}
}
} else {
copy->GetLocalPropertyNames(names, 0);
for (int i = 0; i < names->length(); i++) {
ASSERT(names->get(i)->IsString());
- String* keyString = String::cast(names->get(i));
+ String* key_string = String::cast(names->get(i));
PropertyAttributes attributes =
- copy->GetLocalPropertyAttribute(keyString);
+ copy->GetLocalPropertyAttribute(key_string);
// Only deep copy fields from the object literal expression.
// In particular, don't try to copy the length attribute of
// an array.
if (attributes != NONE) continue;
- Object* value = copy->GetProperty(keyString, &attributes);
+ Object* value = copy->GetProperty(key_string, &attributes);
ASSERT(!value->IsFailure());
if (value->IsJSObject()) {
- JSObject* jsObject = JSObject::cast(value);
- result = DeepCopyBoilerplate(jsObject);
+ JSObject* js_object = JSObject::cast(value);
+ result = DeepCopyBoilerplate(js_object);
if (result->IsFailure()) return result;
- result = copy->SetProperty(keyString, result, NONE);
+ result = copy->SetProperty(key_string, result, NONE);
if (result->IsFailure()) return result;
}
}
switch (copy->GetElementsKind()) {
case JSObject::FAST_ELEMENTS: {
FixedArray* elements = FixedArray::cast(copy->elements());
- WriteBarrierMode mode = elements->GetWriteBarrierMode();
for (int i = 0; i < elements->length(); i++) {
Object* value = elements->get(i);
if (value->IsJSObject()) {
- JSObject* jsObject = JSObject::cast(value);
- result = DeepCopyBoilerplate(jsObject);
+ JSObject* js_object = JSObject::cast(value);
+ result = DeepCopyBoilerplate(js_object);
if (result->IsFailure()) return result;
- elements->set(i, result, mode);
+ elements->set(i, result);
}
}
break;
if (element_dictionary->IsKey(k)) {
Object* value = element_dictionary->ValueAt(i);
if (value->IsJSObject()) {
- JSObject* jsObject = JSObject::cast(value);
- result = DeepCopyBoilerplate(jsObject);
+ JSObject* js_object = JSObject::cast(value);
+ result = DeepCopyBoilerplate(js_object);
if (result->IsFailure()) return result;
element_dictionary->ValueAtPut(i, result);
}
literals->set(JSFunction::kLiteralGlobalContextIndex,
context->global_context());
}
+ // It's okay to skip the write barrier here because the literals
+ // are guaranteed to be in old space.
target->set_literals(*literals, SKIP_WRITE_BARRIER);
}
if (obj->IsFailure()) return obj;
FixedArray* array = FixedArray::cast(obj);
ASSERT(array->length() == length);
- WriteBarrierMode mode = array->GetWriteBarrierMode();
+
+ AssertNoAllocation no_gc;
+ WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
for (int i = 0; i < length; i++) {
array->set(i, frame->GetParameter(i), mode);
}
// Allocate the fixed array.
Object* obj = Heap::AllocateRawFixedArray(length);
if (obj->IsFailure()) return obj;
+
+ AssertNoAllocation no_gc;
reinterpret_cast<Array*>(obj)->set_map(Heap::fixed_array_map());
FixedArray* array = FixedArray::cast(obj);
array->set_length(length);
- WriteBarrierMode mode = array->GetWriteBarrierMode();
+
+ WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
for (int i = 0; i < length; i++) {
array->set(i, *--parameters, mode);
}
to->SetContent(FixedArray::cast(from->elements()));
to->set_length(from->length());
from->SetContent(Heap::empty_fixed_array());
- from->set_length(0);
+ from->set_length(Smi::FromInt(0));
return to;
}
} else {
Handle<FixedArray> single_interval = Factory::NewFixedArray(2);
// -1 means start of array.
- single_interval->set(0,
- Smi::FromInt(-1),
- SKIP_WRITE_BARRIER);
+ single_interval->set(0, Smi::FromInt(-1));
uint32_t actual_length = static_cast<uint32_t>(array->elements()->length());
uint32_t min_length = actual_length < length ? actual_length : length;
Handle<Object> length_object =
const int length = frame->GetProvidedParametersCount();
Handle<JSObject> arguments = Factory::NewArgumentsObject(function, length);
Handle<FixedArray> array = Factory::NewFixedArray(length);
- WriteBarrierMode mode = array->GetWriteBarrierMode();
+
+ AssertNoAllocation no_gc;
+ WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
for (int i = 0; i < length; i++) {
array->set(i, frame->GetParameter(i), mode);
}
if (cursor + 2 < elements->length()) {
elements->set(cursor++, recv);
elements->set(cursor++, fun);
- elements->set(cursor++, offset, SKIP_WRITE_BARRIER);
+ elements->set(cursor++, offset);
} else {
HandleScope scope;
Handle<Object> recv_handle(recv);
iter.Advance();
}
- result->set_length(Smi::FromInt(cursor), SKIP_WRITE_BARRIER);
-
+ result->set_length(Smi::FromInt(cursor));
return *result;
}