Commit 2646b62a authored by verwaest's avatar verwaest Committed by Commit bot

[runtime/heap] Introduce CopyFixedArrayUpTo to match CopyFixedArrayAndGrow,...

[runtime/heap] Introduce CopyFixedArrayUpTo to match CopyFixedArrayAndGrow, copying to a smaller array.

This allows the helper to avoid write barriers while copying, speeding up Object.keys by 5-10%.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#33916}
parent 0b271def
......@@ -1864,10 +1864,7 @@ BUILTIN(ObjectKeys) {
if (enum_length != 0) {
Handle<FixedArray> cache(
js_object->map()->instance_descriptors()->GetEnumCache());
keys = isolate->factory()->NewFixedArray(enum_length);
for (int i = 0; i < enum_length; i++) {
keys->set(i, cache->get(i));
}
keys = isolate->factory()->CopyFixedArrayUpTo(cache, enum_length);
}
}
}
......
......@@ -1041,6 +1041,13 @@ Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array,
FixedArray);
}
Handle<FixedArray> Factory::CopyFixedArrayUpTo(Handle<FixedArray> array,
int new_len,
PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(isolate(), isolate()->heap()->CopyFixedArrayUpTo(
*array, new_len, pretenure),
FixedArray);
}
Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
CALL_HEAP_FUNCTION(isolate(),
......
......@@ -323,6 +323,9 @@ class Factory final {
Handle<FixedArray> array, int grow_by,
PretenureFlag pretenure = NOT_TENURED);
Handle<FixedArray> CopyFixedArrayUpTo(Handle<FixedArray> array, int new_len,
PretenureFlag pretenure = NOT_TENURED);
Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
// This method expects a COW array in new space, and creates a copy
......
......@@ -3781,18 +3781,41 @@ AllocationResult Heap::CopyFixedArrayAndGrow(FixedArray* src, int grow_by,
AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure);
if (!allocation.To(&obj)) return allocation;
}
obj->set_map_no_write_barrier(fixed_array_map());
FixedArray* result = FixedArray::cast(obj);
result->set_length(new_len);
// Copy the content.
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
WriteBarrierMode mode = obj->GetWriteBarrierMode(no_gc);
for (int i = 0; i < old_len; i++) result->set(i, src->get(i), mode);
MemsetPointer(result->data_start() + old_len, undefined_value(), grow_by);
return result;
}
AllocationResult Heap::CopyFixedArrayUpTo(FixedArray* src, int new_len,
PretenureFlag pretenure) {
if (new_len == 0) return empty_fixed_array();
DCHECK_LE(new_len, src->length());
HeapObject* obj = nullptr;
{
AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure);
if (!allocation.To(&obj)) return allocation;
}
obj->set_map_no_write_barrier(fixed_array_map());
FixedArray* result = FixedArray::cast(obj);
result->set_length(new_len);
// Copy the content.
DisallowHeapAllocation no_gc;
WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
for (int i = 0; i < new_len; i++) result->set(i, src->get(i), mode);
return result;
}
AllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
int len = src->length();
......@@ -3801,13 +3824,12 @@ AllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED);
if (!allocation.To(&obj)) return allocation;
}
if (InNewSpace(obj)) {
obj->set_map_no_write_barrier(map);
if (InNewSpace(obj)) {
CopyBlock(obj->address() + kPointerSize, src->address() + kPointerSize,
FixedArray::SizeFor(len) - kPointerSize);
return obj;
}
obj->set_map_no_write_barrier(map);
FixedArray* result = FixedArray::cast(obj);
result->set_length(len);
......
......@@ -1877,6 +1877,11 @@ class Heap {
MUST_USE_RESULT AllocationResult
CopyFixedArrayAndGrow(FixedArray* src, int grow_by, PretenureFlag pretenure);
// Make a copy of src, also grow the copy, and return the copy.
MUST_USE_RESULT AllocationResult CopyFixedArrayUpTo(FixedArray* src,
int new_len,
PretenureFlag pretenure);
// Make a copy of src, set the map, and return the copy.
MUST_USE_RESULT AllocationResult
CopyFixedArrayWithMap(FixedArray* src, Map* map);
......
......@@ -8530,13 +8530,9 @@ static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
static Handle<FixedArray> ReduceFixedArrayTo(
Handle<FixedArray> array, int length) {
DCHECK(array->length() >= length);
DCHECK_LE(length, array->length());
if (array->length() == length) return array;
Handle<FixedArray> new_array =
array->GetIsolate()->factory()->NewFixedArray(length);
for (int i = 0; i < length; ++i) new_array->set(i, array->get(i));
return new_array;
return array->GetIsolate()->factory()->CopyFixedArrayUpTo(array, length);
}
bool Map::OnlyHasSimpleProperties() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment