Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
Revert of Remove the weak list of views from array buffers (patchset #6
Browse files Browse the repository at this point in the history
… id:100001 of https://codereview.chromium.org/1094863002/)

Reason for revert:
I'm reverting this while working on the regression fix

Original issue's description:
> Remove the weak list of views from array buffers
>
> Instead, views have to check their array buffer for whether
> it's neutered or not.
>
> BUG=v8:3996
> [email protected],[email protected],[email protected]
> LOG=n
>
> Committed: https://crrev.com/5ae083a05a6743d6cb91585f449539f7846a5d8c
> Cr-Commit-Position: refs/heads/master@{#27995}

[email protected],[email protected],[email protected]
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:3996

Review URL: https://codereview.chromium.org/1061753008

Cr-Commit-Position: refs/heads/master@{#28014}
  • Loading branch information
jeisinger authored and Commit bot committed Apr 22, 2015
1 parent 5b6111e commit 47f2dfa
Show file tree
Hide file tree
Showing 22 changed files with 838 additions and 449 deletions.
22 changes: 22 additions & 0 deletions src/accessors.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,32 @@ bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
return
CheckForName(name, isolate->factory()->length_string(),
JSArray::kLengthOffset, object_offset);
case JS_TYPED_ARRAY_TYPE:
// %TypedArray%.prototype is non-configurable, and so are the following
// named properties on %TypedArray%.prototype, so we can directly inline
// the field-load for typed array maps that still use their
// %TypedArray%.prototype.
if (JSFunction::cast(map->GetConstructor())->prototype() !=
map->prototype()) {
return false;
}
return
CheckForName(name, isolate->factory()->length_string(),
JSTypedArray::kLengthOffset, object_offset) ||
CheckForName(name, isolate->factory()->byte_length_string(),
JSTypedArray::kByteLengthOffset, object_offset) ||
CheckForName(name, isolate->factory()->byte_offset_string(),
JSTypedArray::kByteOffsetOffset, object_offset);
case JS_ARRAY_BUFFER_TYPE:
return
CheckForName(name, isolate->factory()->byte_length_string(),
JSArrayBuffer::kByteLengthOffset, object_offset);
case JS_DATA_VIEW_TYPE:
return
CheckForName(name, isolate->factory()->byte_length_string(),
JSDataView::kByteLengthOffset, object_offset) ||
CheckForName(name, isolate->factory()->byte_offset_string(),
JSDataView::kByteOffsetOffset, object_offset);
default:
if (map->instance_type() < FIRST_NONSTRING_TYPE) {
return CheckForName(name, isolate->factory()->length_string(),
Expand Down
36 changes: 14 additions & 22 deletions src/elements.cc
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ class ElementsAccessorBase : public ElementsAccessor {
Handle<JSObject> obj,
uint32_t key,
Handle<FixedArrayBase> backing_store) {
if (key < ElementsAccessorSubclass::GetCapacityImpl(obj, backing_store)) {
if (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) {
return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
} else {
return backing_store->GetIsolate()->factory()->the_hole_value();
Expand All @@ -638,7 +638,7 @@ class ElementsAccessorBase : public ElementsAccessor {
Handle<JSObject> obj,
uint32_t key,
Handle<FixedArrayBase> backing_store) {
if (key >= ElementsAccessorSubclass::GetCapacityImpl(obj, backing_store)) {
if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) {
return ABSENT;
}
return
Expand Down Expand Up @@ -751,7 +751,7 @@ class ElementsAccessorBase : public ElementsAccessor {

// Optimize if 'other' is empty.
// We cannot optimize if 'this' is empty, as other may have holes.
uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(holder, from);
uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from);
if (len1 == 0) return to;

Isolate* isolate = from->GetIsolate();
Expand Down Expand Up @@ -817,14 +817,12 @@ class ElementsAccessorBase : public ElementsAccessor {
}

protected:
static uint32_t GetCapacityImpl(Handle<JSObject> holder,
Handle<FixedArrayBase> backing_store) {
static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) {
return backing_store->length();
}

uint32_t GetCapacity(Handle<JSObject> holder,
Handle<FixedArrayBase> backing_store) final {
return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store);
uint32_t GetCapacity(Handle<FixedArrayBase> backing_store) final {
return ElementsAccessorSubclass::GetCapacityImpl(backing_store);
}

static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store,
Expand Down Expand Up @@ -1262,7 +1260,7 @@ class TypedElementsAccessor
Handle<JSObject> obj,
uint32_t key,
Handle<FixedArrayBase> backing_store) {
if (key < AccessorClass::GetCapacityImpl(obj, backing_store)) {
if (key < AccessorClass::GetCapacityImpl(backing_store)) {
return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
} else {
return backing_store->GetIsolate()->factory()->undefined_value();
Expand All @@ -1273,8 +1271,9 @@ class TypedElementsAccessor
Handle<JSObject> obj,
uint32_t key,
Handle<FixedArrayBase> backing_store) {
return key < AccessorClass::GetCapacityImpl(obj, backing_store) ? NONE
: ABSENT;
return
key < AccessorClass::GetCapacityImpl(backing_store)
? NONE : ABSENT;
}

MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
Expand All @@ -1294,16 +1293,10 @@ class TypedElementsAccessor

static bool HasElementImpl(Handle<JSObject> holder, uint32_t key,
Handle<FixedArrayBase> backing_store) {
uint32_t capacity = AccessorClass::GetCapacityImpl(holder, backing_store);
uint32_t capacity =
AccessorClass::GetCapacityImpl(backing_store);
return key < capacity;
}

static uint32_t GetCapacityImpl(Handle<JSObject> holder,
Handle<FixedArrayBase> backing_store) {
Handle<JSArrayBufferView> view = Handle<JSArrayBufferView>::cast(holder);
if (view->WasNeutered()) return 0;
return backing_store->length();
}
};


Expand Down Expand Up @@ -1639,13 +1632,12 @@ class SloppyArgumentsElementsAccessor : public ElementsAccessorBase<
UNREACHABLE();
}

static uint32_t GetCapacityImpl(Handle<JSObject> holder,
Handle<FixedArrayBase> backing_store) {
static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) {
Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store);
Handle<FixedArrayBase> arguments(
FixedArrayBase::cast(parameter_map->get(1)));
return Max(static_cast<uint32_t>(parameter_map->length() - 2),
ForArray(arguments)->GetCapacity(holder, arguments));
ForArray(arguments)->GetCapacity(arguments));
}

static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict,
Expand Down
3 changes: 1 addition & 2 deletions src/elements.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,7 @@ class ElementsAccessor {
protected:
friend class SloppyArgumentsElementsAccessor;

virtual uint32_t GetCapacity(Handle<JSObject> holder,
Handle<FixedArrayBase> backing_store) = 0;
virtual uint32_t GetCapacity(Handle<FixedArrayBase> backing_store) = 0;

// Element handlers distinguish between indexes and keys when they manipulate
// elements. Indexes refer to elements in terms of their location in the
Expand Down
97 changes: 11 additions & 86 deletions src/factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1825,38 +1825,9 @@ size_t GetExternalArrayElementSize(ExternalArrayType type) {
case kExternal##Type##Array: \
return size;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
default:
UNREACHABLE();
return 0;
}
#undef TYPED_ARRAY_CASE
}


size_t GetFixedTypedArraysElementSize(ElementsKind kind) {
switch (kind) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case TYPE##_ELEMENTS: \
return size;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
default:
UNREACHABLE();
return 0;
}
#undef TYPED_ARRAY_CASE
}


ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) {
switch (kind) {
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
case TYPE##_ELEMENTS: \
return kExternal##Type##Array;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
default:
UNREACHABLE();
return kExternalInt8Array;
}
UNREACHABLE();
return 0;
#undef TYPED_ARRAY_CASE
}

Expand All @@ -1878,23 +1849,6 @@ JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) {
}


JSFunction* GetTypedArrayFun(ElementsKind elements_kind, Isolate* isolate) {
Context* native_context = isolate->context()->native_context();
switch (elements_kind) {
#define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size) \
case TYPE##_ELEMENTS: \
return native_context->type##_array_fun();

TYPED_ARRAYS(TYPED_ARRAY_FUN)
#undef TYPED_ARRAY_FUN

default:
UNREACHABLE();
return NULL;
}
}


void SetupArrayBufferView(i::Isolate* isolate,
i::Handle<i::JSArrayBufferView> obj,
i::Handle<i::JSArrayBuffer> buffer,
Expand All @@ -1904,6 +1858,15 @@ void SetupArrayBufferView(i::Isolate* isolate,

obj->set_buffer(*buffer);

Heap* heap = isolate->heap();
if (heap->InNewSpace(*obj)) {
obj->set_weak_next(heap->new_array_buffer_views_list());
heap->set_new_array_buffer_views_list(*obj);
} else {
obj->set_weak_next(buffer->weak_first_view());
buffer->set_weak_first_view(*obj);
}

i::Handle<i::Object> byte_offset_object =
isolate->factory()->NewNumberFromSize(byte_offset);
obj->set_byte_offset(*byte_offset_object);
Expand All @@ -1927,16 +1890,6 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type) {
}


Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind) {
Handle<JSFunction> typed_array_fun_handle(
GetTypedArrayFun(elements_kind, isolate()));

CALL_HEAP_FUNCTION(
isolate(), isolate()->heap()->AllocateJSObject(*typed_array_fun_handle),
JSTypedArray);
}


Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
Handle<JSArrayBuffer> buffer,
size_t byte_offset,
Expand Down Expand Up @@ -1965,34 +1918,6 @@ Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
}


Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind,
size_t number_of_elements) {
Handle<JSTypedArray> obj = NewJSTypedArray(elements_kind);

size_t element_size = GetFixedTypedArraysElementSize(elements_kind);
ExternalArrayType array_type = GetArrayTypeFromElementsKind(elements_kind);

CHECK(number_of_elements <=
(std::numeric_limits<size_t>::max() / element_size));
CHECK(number_of_elements <= static_cast<size_t>(Smi::kMaxValue));
size_t byte_length = number_of_elements * element_size;

obj->set_byte_offset(Smi::FromInt(0));
i::Handle<i::Object> byte_length_object =
isolate()->factory()->NewNumberFromSize(byte_length);
obj->set_byte_length(*byte_length_object);
Handle<Object> length_object = NewNumberFromSize(number_of_elements);
obj->set_length(*length_object);

obj->set_buffer(Smi::FromInt(0));
Handle<FixedTypedArrayBase> elements =
isolate()->factory()->NewFixedTypedArray(
static_cast<int>(number_of_elements), array_type);
obj->set_elements(*elements);
return obj;
}


Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
size_t byte_offset,
size_t byte_length) {
Expand Down
6 changes: 0 additions & 6 deletions src/factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,17 +448,11 @@ class Factory final {

Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type);

Handle<JSTypedArray> NewJSTypedArray(ElementsKind elements_kind);

// Creates a new JSTypedArray with the specified buffer.
Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type,
Handle<JSArrayBuffer> buffer,
size_t byte_offset, size_t length);

// Creates a new on-heap JSTypedArray.
Handle<JSTypedArray> NewJSTypedArray(ElementsKind elements_kind,
size_t number_of_elements);

Handle<JSDataView> NewJSDataView();
Handle<JSDataView> NewJSDataView(Handle<JSArrayBuffer> buffer,
size_t byte_offset, size_t byte_length);
Expand Down
5 changes: 5 additions & 0 deletions src/heap-snapshot-generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1175,6 +1175,8 @@ void V8HeapExplorer::ExtractJSObjectReferences(
JSArrayBufferView* view = JSArrayBufferView::cast(obj);
SetInternalReference(view, entry, "buffer", view->buffer(),
JSArrayBufferView::kBufferOffset);
SetWeakReference(view, entry, "weak_next", view->weak_next(),
JSArrayBufferView::kWeakNextOffset);
}
TagObject(js_obj->properties(), "(object properties)");
SetInternalReference(obj, entry,
Expand Down Expand Up @@ -1568,6 +1570,9 @@ void V8HeapExplorer::ExtractJSArrayBufferReferences(
int entry, JSArrayBuffer* buffer) {
SetWeakReference(buffer, entry, "weak_next", buffer->weak_next(),
JSArrayBuffer::kWeakNextOffset);
SetWeakReference(buffer, entry,
"weak_first_view", buffer->weak_first_view(),
JSArrayBuffer::kWeakFirstViewOffset);
// Setup a reference to a native memory backing_store object.
if (!buffer->backing_store())
return;
Expand Down
30 changes: 29 additions & 1 deletion src/heap/heap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ Heap::Heap()
chunks_queued_for_free_(NULL),
gc_callbacks_depth_(0),
deserialization_complete_(false),
concurrent_sweeping_enabled_(false) {
concurrent_sweeping_enabled_(false),
migration_failure_(false),
previous_migration_failure_(false) {
// Allow build-time customization of the max semispace size. Building
// V8 with snapshots and a non-default max semispace size is much
// easier if you can define it as part of the build environment.
Expand Down Expand Up @@ -703,6 +705,13 @@ void Heap::GarbageCollectionEpilogue() {
// Remember the last top pointer so that we can later find out
// whether we allocated in new space since the last GC.
new_space_top_after_last_gc_ = new_space()->top();

if (migration_failure_) {
set_previous_migration_failure(true);
} else {
set_previous_migration_failure(false);
}
set_migration_failure(false);
}


Expand Down Expand Up @@ -1677,13 +1686,15 @@ void Heap::UpdateReferencesInExternalStringTable(

void Heap::ProcessAllWeakReferences(WeakObjectRetainer* retainer) {
ProcessArrayBuffers(retainer, false);
ProcessNewArrayBufferViews(retainer);
ProcessNativeContexts(retainer);
ProcessAllocationSites(retainer);
}


void Heap::ProcessYoungWeakReferences(WeakObjectRetainer* retainer) {
ProcessArrayBuffers(retainer, true);
ProcessNewArrayBufferViews(retainer);
ProcessNativeContexts(retainer);
}

Expand All @@ -1710,6 +1721,7 @@ void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer,
Object* undefined = undefined_value();
Object* next = array_buffers_list();
bool old_objects_recorded = false;
if (migration_failure()) return;
while (next != undefined) {
if (!old_objects_recorded) {
old_objects_recorded = !InNewSpace(next);
Expand All @@ -1720,6 +1732,20 @@ void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer,
}


void Heap::ProcessNewArrayBufferViews(WeakObjectRetainer* retainer) {
// Retain the list of new space views.
Object* typed_array_obj = VisitWeakList<JSArrayBufferView>(
this, new_array_buffer_views_list_, retainer, false, NULL);
set_new_array_buffer_views_list(typed_array_obj);

// Some objects in the list may be in old space now. Find them
// and move them to the corresponding array buffer.
Object* view = VisitNewArrayBufferViewsWeakList(
this, new_array_buffer_views_list_, retainer);
set_new_array_buffer_views_list(view);
}


void Heap::TearDownArrayBuffers() {
Object* undefined = undefined_value();
for (Object* o = array_buffers_list(); o != undefined;) {
Expand Down Expand Up @@ -2151,6 +2177,7 @@ class ScavengingVisitor : public StaticVisitorBase {
if (SemiSpaceCopyObject<alignment>(map, slot, object, object_size)) {
return;
}
heap->set_migration_failure(true);
}

if (PromoteObject<object_contents, alignment>(map, slot, object,
Expand Down Expand Up @@ -5375,6 +5402,7 @@ bool Heap::CreateHeapObjects() {
set_native_contexts_list(undefined_value());
set_array_buffers_list(undefined_value());
set_last_array_buffer_in_list(undefined_value());
set_new_array_buffer_views_list(undefined_value());
set_allocation_sites_list(undefined_value());
return true;
}
Expand Down
Loading

0 comments on commit 47f2dfa

Please sign in to comment.