| Index: src/heap.cc
|
| diff --git a/src/heap.cc b/src/heap.cc
|
| index ac2504f9b571f6e5cca8fb1878b2219f4a25119b..506b97dbfc46ca8ad7a60f1d9a2a24e85dc85f6c 100644
|
| --- a/src/heap.cc
|
| +++ b/src/heap.cc
|
| @@ -1568,6 +1568,8 @@ static Object* VisitWeakList(Heap* heap,
|
| // tail is a live object, visit it.
|
| WeakListVisitor<T>::VisitLiveObject(
|
| heap, tail, retainer, record_slots);
|
| + } else {
|
| + WeakListVisitor<T>::VisitPhantomObject(heap, candidate);
|
| }
|
|
|
| // Move to next element in the list.
|
| @@ -1599,6 +1601,9 @@ struct WeakListVisitor<JSFunction> {
|
| static void VisitLiveObject(Heap*, JSFunction*,
|
| WeakObjectRetainer*, bool) {
|
| }
|
| +
|
| + static void VisitPhantomObject(Heap*, JSFunction*) {
|
| + }
|
| };
|
|
|
|
|
| @@ -1637,6 +1642,9 @@ struct WeakListVisitor<Context> {
|
| }
|
| }
|
|
|
| + static void VisitPhantomObject(Heap*, Context*) {
|
| + }
|
| +
|
| static int WeakNextOffset() {
|
| return FixedArray::SizeFor(Context::NEXT_CONTEXT_LINK);
|
| }
|
| @@ -1666,22 +1674,24 @@ void Heap::ProcessNativeContexts(WeakObjectRetainer* retainer,
|
|
|
|
|
| template<>
|
| -struct WeakListVisitor<JSTypedArray> {
|
| - static void SetWeakNext(JSTypedArray* obj, Object* next) {
|
| +struct WeakListVisitor<JSArrayBufferView> {
|
| + static void SetWeakNext(JSArrayBufferView* obj, Object* next) {
|
| obj->set_weak_next(next);
|
| }
|
|
|
| - static Object* WeakNext(JSTypedArray* obj) {
|
| + static Object* WeakNext(JSArrayBufferView* obj) {
|
| return obj->weak_next();
|
| }
|
|
|
| static void VisitLiveObject(Heap*,
|
| - JSTypedArray* obj,
|
| + JSArrayBufferView* obj,
|
| WeakObjectRetainer* retainer,
|
| bool record_slots) {}
|
|
|
| + static void VisitPhantomObject(Heap*, JSArrayBufferView*) {}
|
| +
|
| static int WeakNextOffset() {
|
| - return JSTypedArray::kWeakNextOffset;
|
| + return JSArrayBufferView::kWeakNextOffset;
|
| }
|
| };
|
|
|
| @@ -1701,18 +1711,22 @@ struct WeakListVisitor<JSArrayBuffer> {
|
| WeakObjectRetainer* retainer,
|
| bool record_slots) {
|
| Object* typed_array_obj =
|
| - VisitWeakList<JSTypedArray>(
|
| + VisitWeakList<JSArrayBufferView>(
|
| heap,
|
| - array_buffer->weak_first_array(),
|
| + array_buffer->weak_first_view(),
|
| retainer, record_slots);
|
| - array_buffer->set_weak_first_array(typed_array_obj);
|
| + array_buffer->set_weak_first_view(typed_array_obj);
|
| if (typed_array_obj != heap->undefined_value() && record_slots) {
|
| Object** slot = HeapObject::RawField(
|
| - array_buffer, JSArrayBuffer::kWeakFirstArrayOffset);
|
| + array_buffer, JSArrayBuffer::kWeakFirstViewOffset);
|
| heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj);
|
| }
|
| }
|
|
|
| + static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) {
|
| + Runtime::FreeArrayBuffer(heap->isolate(), phantom);
|
| + }
|
| +
|
| static int WeakNextOffset() {
|
| return JSArrayBuffer::kWeakNextOffset;
|
| }
|
| @@ -1729,6 +1743,17 @@ void Heap::ProcessArrayBuffers(WeakObjectRetainer* retainer,
|
| }
|
|
|
|
|
| +void Heap::TearDownArrayBuffers() {
|
| + Object* undefined = undefined_value();
|
| + for (Object* o = array_buffers_list(); o != undefined;) {
|
| + JSArrayBuffer* buffer = JSArrayBuffer::cast(o);
|
| + Runtime::FreeArrayBuffer(isolate(), buffer);
|
| + o = buffer->weak_next();
|
| + }
|
| + array_buffers_list_ = undefined;
|
| +}
|
| +
|
| +
|
| void Heap::VisitExternalResources(v8::ExternalResourceVisitor* visitor) {
|
| DisallowHeapAllocation no_allocation;
|
|
|
| @@ -1912,6 +1937,10 @@ class ScavengingVisitor : public StaticVisitorBase {
|
| &ObjectEvacuationStrategy<POINTER_OBJECT>::
|
| Visit);
|
|
|
| + table_.Register(kVisitJSDataView,
|
| + &ObjectEvacuationStrategy<POINTER_OBJECT>::
|
| + Visit);
|
| +
|
| table_.Register(kVisitJSRegExp,
|
| &ObjectEvacuationStrategy<POINTER_OBJECT>::
|
| Visit);
|
| @@ -2830,8 +2859,11 @@ MaybeObject* Heap::AllocatePropertyCell(Object* value) {
|
| }
|
| HeapObject::cast(result)->set_map_no_write_barrier(
|
| global_property_cell_map());
|
| - PropertyCell::cast(result)->set_value(value);
|
| - PropertyCell::cast(result)->set_type(Type::None());
|
| + PropertyCell* cell = PropertyCell::cast(result);
|
| + cell->set_dependent_code(DependentCode::cast(empty_fixed_array()),
|
| + SKIP_WRITE_BARRIER);
|
| + cell->set_value(value);
|
| + cell->set_type(Type::None());
|
| return result;
|
| }
|
|
|
| @@ -3131,7 +3163,7 @@ bool Heap::CreateInitialObjects() {
|
| set_empty_slow_element_dictionary(SeededNumberDictionary::cast(obj));
|
|
|
| // Handling of script id generation is in Factory::NewScript.
|
| - set_last_script_id(undefined_value());
|
| + set_last_script_id(Smi::FromInt(v8::Script::kNoScriptId));
|
|
|
| // Initialize keyed lookup cache.
|
| isolate_->keyed_lookup_cache()->Clear();
|
| @@ -4401,7 +4433,10 @@ MaybeObject* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) {
|
| ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE);
|
|
|
| // Allocate the backing storage for the properties.
|
| - int prop_size = map->InitialPropertiesLength();
|
| + int prop_size =
|
| + map->pre_allocated_property_fields() +
|
| + map->unused_property_fields() -
|
| + map->inobject_properties();
|
| ASSERT(prop_size >= 0);
|
| Object* properties;
|
| { MaybeObject* maybe_properties = AllocateFixedArray(prop_size, pretenure);
|
| @@ -4438,7 +4473,10 @@ MaybeObject* Heap::AllocateJSObjectFromMapWithAllocationSite(Map* map,
|
| ASSERT(map->instance_type() != JS_BUILTINS_OBJECT_TYPE);
|
|
|
| // Allocate the backing storage for the properties.
|
| - int prop_size = map->InitialPropertiesLength();
|
| + int prop_size =
|
| + map->pre_allocated_property_fields() +
|
| + map->unused_property_fields() -
|
| + map->inobject_properties();
|
| ASSERT(prop_size >= 0);
|
| Object* properties;
|
| { MaybeObject* maybe_properties = AllocateFixedArray(prop_size);
|
| @@ -6625,7 +6663,12 @@ bool Heap::ConfigureHeap(int max_semispace_size,
|
| max_semispace_size_ = RoundUpToPowerOf2(max_semispace_size_);
|
| reserved_semispace_size_ = RoundUpToPowerOf2(reserved_semispace_size_);
|
| initial_semispace_size_ = Min(initial_semispace_size_, max_semispace_size_);
|
| - external_allocation_limit_ = 16 * max_semispace_size_;
|
| +
|
| + // The external allocation limit should be below 256 MB on all architectures
|
| + // to avoid unnecessary low memory notifications, as that is the threshold
|
| + // for some embedders.
|
| + external_allocation_limit_ = 12 * max_semispace_size_;
|
| + ASSERT(external_allocation_limit_ <= 256 * MB);
|
|
|
| // The old generation is paged and needs at least one page for each space.
|
| int paged_space_count = LAST_PAGED_SPACE - FIRST_PAGED_SPACE + 1;
|
| @@ -6874,6 +6917,8 @@ void Heap::TearDown() {
|
| PrintF("\n\n");
|
| }
|
|
|
| + TearDownArrayBuffers();
|
| +
|
| isolate_->global_handles()->TearDown();
|
|
|
| external_string_table_.TearDown();
|
|
|