Fix missing write barrier in CopyObjectToObjectElements.
Passing the write barrier mode as a parameter does not make sense, as the elements kind specific copiers know best whether a write barrier is needed or not. BUG=119926 TEST=mjsunit/regress/regress-crbug-119926 R=danno@chromium.org Review URL: https://chromiumcodereview.appspot.com/9808111 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11134 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
8833c99552
commit
4e405b6945
@ -137,8 +137,7 @@ void CopyObjectToObjectElements(FixedArray* from,
|
|||||||
FixedArray* to,
|
FixedArray* to,
|
||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
uint32_t to_start,
|
uint32_t to_start,
|
||||||
int raw_copy_size,
|
int raw_copy_size) {
|
||||||
WriteBarrierMode mode) {
|
|
||||||
ASSERT(to->map() != HEAP->fixed_cow_array_map());
|
ASSERT(to->map() != HEAP->fixed_cow_array_map());
|
||||||
ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS);
|
ASSERT(from_kind == FAST_ELEMENTS || from_kind == FAST_SMI_ONLY_ELEMENTS);
|
||||||
ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
|
ASSERT(to_kind == FAST_ELEMENTS || to_kind == FAST_SMI_ONLY_ELEMENTS);
|
||||||
@ -166,8 +165,7 @@ void CopyObjectToObjectElements(FixedArray* from,
|
|||||||
CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
|
CopyWords(reinterpret_cast<Object**>(to_address) + to_start,
|
||||||
reinterpret_cast<Object**>(from_address) + from_start,
|
reinterpret_cast<Object**>(from_address) + from_start,
|
||||||
copy_size);
|
copy_size);
|
||||||
if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS &&
|
if (from_kind == FAST_ELEMENTS && to_kind == FAST_ELEMENTS) {
|
||||||
mode == UPDATE_WRITE_BARRIER) {
|
|
||||||
Heap* heap = from->GetHeap();
|
Heap* heap = from->GetHeap();
|
||||||
if (!heap->InNewSpace(to)) {
|
if (!heap->InNewSpace(to)) {
|
||||||
heap->RecordWrites(to->address(),
|
heap->RecordWrites(to->address(),
|
||||||
@ -184,8 +182,7 @@ static void CopyDictionaryToObjectElements(SeededNumberDictionary* from,
|
|||||||
FixedArray* to,
|
FixedArray* to,
|
||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
uint32_t to_start,
|
uint32_t to_start,
|
||||||
int raw_copy_size,
|
int raw_copy_size) {
|
||||||
WriteBarrierMode mode) {
|
|
||||||
int copy_size = raw_copy_size;
|
int copy_size = raw_copy_size;
|
||||||
Heap* heap = from->GetHeap();
|
Heap* heap = from->GetHeap();
|
||||||
if (raw_copy_size < 0) {
|
if (raw_copy_size < 0) {
|
||||||
@ -476,8 +473,7 @@ class ElementsAccessorBase : public ElementsAccessor {
|
|||||||
FixedArrayBase* to,
|
FixedArrayBase* to,
|
||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
uint32_t to_start,
|
uint32_t to_start,
|
||||||
int copy_size,
|
int copy_size) {
|
||||||
WriteBarrierMode mode) {
|
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -488,7 +484,6 @@ class ElementsAccessorBase : public ElementsAccessor {
|
|||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
uint32_t to_start,
|
uint32_t to_start,
|
||||||
int copy_size,
|
int copy_size,
|
||||||
WriteBarrierMode mode,
|
|
||||||
FixedArrayBase* from) {
|
FixedArrayBase* from) {
|
||||||
if (from == NULL) {
|
if (from == NULL) {
|
||||||
from = from_holder->elements();
|
from = from_holder->elements();
|
||||||
@ -497,7 +492,7 @@ class ElementsAccessorBase : public ElementsAccessor {
|
|||||||
return from;
|
return from;
|
||||||
}
|
}
|
||||||
return ElementsAccessorSubclass::CopyElementsImpl(
|
return ElementsAccessorSubclass::CopyElementsImpl(
|
||||||
from, from_start, to, to_kind, to_start, copy_size, mode);
|
from, from_start, to, to_kind, to_start, copy_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
|
virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
|
||||||
@ -734,14 +729,13 @@ class FastObjectElementsAccessor
|
|||||||
FixedArrayBase* to,
|
FixedArrayBase* to,
|
||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
uint32_t to_start,
|
uint32_t to_start,
|
||||||
int copy_size,
|
int copy_size) {
|
||||||
WriteBarrierMode mode) {
|
|
||||||
switch (to_kind) {
|
switch (to_kind) {
|
||||||
case FAST_SMI_ONLY_ELEMENTS:
|
case FAST_SMI_ONLY_ELEMENTS:
|
||||||
case FAST_ELEMENTS: {
|
case FAST_ELEMENTS: {
|
||||||
CopyObjectToObjectElements(
|
CopyObjectToObjectElements(
|
||||||
FixedArray::cast(from), ElementsTraits::Kind, from_start,
|
FixedArray::cast(from), ElementsTraits::Kind, from_start,
|
||||||
FixedArray::cast(to), to_kind, to_start, copy_size, mode);
|
FixedArray::cast(to), to_kind, to_start, copy_size);
|
||||||
return from;
|
return from;
|
||||||
}
|
}
|
||||||
case FAST_DOUBLE_ELEMENTS:
|
case FAST_DOUBLE_ELEMENTS:
|
||||||
@ -809,8 +803,7 @@ class FastDoubleElementsAccessor
|
|||||||
FixedArrayBase* to,
|
FixedArrayBase* to,
|
||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
uint32_t to_start,
|
uint32_t to_start,
|
||||||
int copy_size,
|
int copy_size) {
|
||||||
WriteBarrierMode mode) {
|
|
||||||
switch (to_kind) {
|
switch (to_kind) {
|
||||||
case FAST_SMI_ONLY_ELEMENTS:
|
case FAST_SMI_ONLY_ELEMENTS:
|
||||||
case FAST_ELEMENTS:
|
case FAST_ELEMENTS:
|
||||||
@ -1108,14 +1101,13 @@ class DictionaryElementsAccessor
|
|||||||
FixedArrayBase* to,
|
FixedArrayBase* to,
|
||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
uint32_t to_start,
|
uint32_t to_start,
|
||||||
int copy_size,
|
int copy_size) {
|
||||||
WriteBarrierMode mode) {
|
|
||||||
switch (to_kind) {
|
switch (to_kind) {
|
||||||
case FAST_SMI_ONLY_ELEMENTS:
|
case FAST_SMI_ONLY_ELEMENTS:
|
||||||
case FAST_ELEMENTS:
|
case FAST_ELEMENTS:
|
||||||
CopyDictionaryToObjectElements(
|
CopyDictionaryToObjectElements(
|
||||||
SeededNumberDictionary::cast(from), from_start,
|
SeededNumberDictionary::cast(from), from_start,
|
||||||
FixedArray::cast(to), to_kind, to_start, copy_size, mode);
|
FixedArray::cast(to), to_kind, to_start, copy_size);
|
||||||
return from;
|
return from;
|
||||||
case FAST_DOUBLE_ELEMENTS:
|
case FAST_DOUBLE_ELEMENTS:
|
||||||
CopyDictionaryToDoubleElements(
|
CopyDictionaryToDoubleElements(
|
||||||
@ -1253,13 +1245,12 @@ class NonStrictArgumentsElementsAccessor : public ElementsAccessorBase<
|
|||||||
FixedArrayBase* to,
|
FixedArrayBase* to,
|
||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
uint32_t to_start,
|
uint32_t to_start,
|
||||||
int copy_size,
|
int copy_size) {
|
||||||
WriteBarrierMode mode) {
|
|
||||||
FixedArray* parameter_map = FixedArray::cast(from);
|
FixedArray* parameter_map = FixedArray::cast(from);
|
||||||
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
|
FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
|
||||||
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
|
ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments);
|
||||||
return accessor->CopyElements(NULL, from_start, to, to_kind,
|
return accessor->CopyElements(NULL, from_start, to, to_kind,
|
||||||
to_start, copy_size, mode, arguments);
|
to_start, copy_size, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
|
static uint32_t GetCapacityImpl(FixedArray* parameter_map) {
|
||||||
|
@ -107,16 +107,14 @@ class ElementsAccessor {
|
|||||||
ElementsKind destination_kind,
|
ElementsKind destination_kind,
|
||||||
uint32_t destination_start,
|
uint32_t destination_start,
|
||||||
int copy_size,
|
int copy_size,
|
||||||
WriteBarrierMode mode,
|
|
||||||
FixedArrayBase* source = NULL) = 0;
|
FixedArrayBase* source = NULL) = 0;
|
||||||
|
|
||||||
MaybeObject* CopyElements(JSObject* from_holder,
|
MaybeObject* CopyElements(JSObject* from_holder,
|
||||||
FixedArrayBase* to,
|
FixedArrayBase* to,
|
||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
WriteBarrierMode mode,
|
|
||||||
FixedArrayBase* from = NULL) {
|
FixedArrayBase* from = NULL) {
|
||||||
return CopyElements(from_holder, 0, to, to_kind, 0,
|
return CopyElements(from_holder, 0, to, to_kind, 0,
|
||||||
kCopyToEndAndInitializeToHole, mode, from);
|
kCopyToEndAndInitializeToHole, from);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
|
virtual MaybeObject* AddElementsToFixedArray(Object* receiver,
|
||||||
@ -164,8 +162,7 @@ void CopyObjectToObjectElements(FixedArray* from_obj,
|
|||||||
FixedArray* to_obj,
|
FixedArray* to_obj,
|
||||||
ElementsKind to_kind,
|
ElementsKind to_kind,
|
||||||
uint32_t to_start,
|
uint32_t to_start,
|
||||||
int copy_size,
|
int copy_size);
|
||||||
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
|
|
||||||
|
|
||||||
|
|
||||||
} } // namespace v8::internal
|
} } // namespace v8::internal
|
||||||
|
@ -8454,7 +8454,7 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength(
|
|||||||
? FAST_SMI_ONLY_ELEMENTS
|
? FAST_SMI_ONLY_ELEMENTS
|
||||||
: FAST_ELEMENTS;
|
: FAST_ELEMENTS;
|
||||||
// int copy_size = Min(old_elements_raw->length(), new_elements->length());
|
// int copy_size = Min(old_elements_raw->length(), new_elements->length());
|
||||||
accessor->CopyElements(this, new_elements, to_kind, SKIP_WRITE_BARRIER);
|
accessor->CopyElements(this, new_elements, to_kind);
|
||||||
if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
|
if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
|
||||||
set_map_and_elements(new_map, new_elements);
|
set_map_and_elements(new_map, new_elements);
|
||||||
} else {
|
} else {
|
||||||
@ -8498,8 +8498,7 @@ MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength(
|
|||||||
FixedArrayBase* old_elements = elements();
|
FixedArrayBase* old_elements = elements();
|
||||||
ElementsKind elements_kind = GetElementsKind();
|
ElementsKind elements_kind = GetElementsKind();
|
||||||
ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
|
ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind);
|
||||||
accessor->CopyElements(this, elems, FAST_DOUBLE_ELEMENTS,
|
accessor->CopyElements(this, elems, FAST_DOUBLE_ELEMENTS);
|
||||||
SKIP_WRITE_BARRIER);
|
|
||||||
if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
|
if (elements_kind != NON_STRICT_ARGUMENTS_ELEMENTS) {
|
||||||
set_map_and_elements(new_map, elems);
|
set_map_and_elements(new_map, elems);
|
||||||
} else {
|
} else {
|
||||||
|
33
test/mjsunit/regress/regress-crbug-119926.js
Normal file
33
test/mjsunit/regress/regress-crbug-119926.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are
|
||||||
|
// met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
// * Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// Test that array elements don't break upon garbage collection.
|
||||||
|
|
||||||
|
var a = new Array(500);
|
||||||
|
for (var i = 0; i < 500000; i++) {
|
||||||
|
a[i] = new Object();
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user