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) { ...@@ -1864,10 +1864,7 @@ BUILTIN(ObjectKeys) {
if (enum_length != 0) { if (enum_length != 0) {
Handle<FixedArray> cache( Handle<FixedArray> cache(
js_object->map()->instance_descriptors()->GetEnumCache()); js_object->map()->instance_descriptors()->GetEnumCache());
keys = isolate->factory()->NewFixedArray(enum_length); keys = isolate->factory()->CopyFixedArrayUpTo(cache, enum_length);
for (int i = 0; i < enum_length; i++) {
keys->set(i, cache->get(i));
}
} }
} }
} }
......
...@@ -1041,6 +1041,13 @@ Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array, ...@@ -1041,6 +1041,13 @@ Handle<FixedArray> Factory::CopyFixedArrayAndGrow(Handle<FixedArray> array,
FixedArray); 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) { Handle<FixedArray> Factory::CopyFixedArray(Handle<FixedArray> array) {
CALL_HEAP_FUNCTION(isolate(), CALL_HEAP_FUNCTION(isolate(),
......
...@@ -323,6 +323,9 @@ class Factory final { ...@@ -323,6 +323,9 @@ class Factory final {
Handle<FixedArray> array, int grow_by, Handle<FixedArray> array, int grow_by,
PretenureFlag pretenure = NOT_TENURED); PretenureFlag pretenure = NOT_TENURED);
Handle<FixedArray> CopyFixedArrayUpTo(Handle<FixedArray> array, int new_len,
PretenureFlag pretenure = NOT_TENURED);
Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array); Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
// This method expects a COW array in new space, and creates a copy // 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, ...@@ -3781,18 +3781,41 @@ AllocationResult Heap::CopyFixedArrayAndGrow(FixedArray* src, int grow_by,
AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure); AllocationResult allocation = AllocateRawFixedArray(new_len, pretenure);
if (!allocation.To(&obj)) return allocation; if (!allocation.To(&obj)) return allocation;
} }
obj->set_map_no_write_barrier(fixed_array_map()); obj->set_map_no_write_barrier(fixed_array_map());
FixedArray* result = FixedArray::cast(obj); FixedArray* result = FixedArray::cast(obj);
result->set_length(new_len); result->set_length(new_len);
// Copy the content. // Copy the content.
DisallowHeapAllocation no_gc; 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); 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); MemsetPointer(result->data_start() + old_len, undefined_value(), grow_by);
return result; 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) { AllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
int len = src->length(); int len = src->length();
...@@ -3801,13 +3824,12 @@ AllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) { ...@@ -3801,13 +3824,12 @@ AllocationResult Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED); AllocationResult allocation = AllocateRawFixedArray(len, NOT_TENURED);
if (!allocation.To(&obj)) return allocation; if (!allocation.To(&obj)) return allocation;
} }
if (InNewSpace(obj)) {
obj->set_map_no_write_barrier(map); obj->set_map_no_write_barrier(map);
if (InNewSpace(obj)) {
CopyBlock(obj->address() + kPointerSize, src->address() + kPointerSize, CopyBlock(obj->address() + kPointerSize, src->address() + kPointerSize,
FixedArray::SizeFor(len) - kPointerSize); FixedArray::SizeFor(len) - kPointerSize);
return obj; return obj;
} }
obj->set_map_no_write_barrier(map);
FixedArray* result = FixedArray::cast(obj); FixedArray* result = FixedArray::cast(obj);
result->set_length(len); result->set_length(len);
......
...@@ -1877,6 +1877,11 @@ class Heap { ...@@ -1877,6 +1877,11 @@ class Heap {
MUST_USE_RESULT AllocationResult MUST_USE_RESULT AllocationResult
CopyFixedArrayAndGrow(FixedArray* src, int grow_by, PretenureFlag pretenure); 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. // Make a copy of src, set the map, and return the copy.
MUST_USE_RESULT AllocationResult MUST_USE_RESULT AllocationResult
CopyFixedArrayWithMap(FixedArray* src, Map* map); CopyFixedArrayWithMap(FixedArray* src, Map* map);
......
...@@ -8530,13 +8530,9 @@ static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { ...@@ -8530,13 +8530,9 @@ static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
static Handle<FixedArray> ReduceFixedArrayTo( static Handle<FixedArray> ReduceFixedArrayTo(
Handle<FixedArray> array, int length) { Handle<FixedArray> array, int length) {
DCHECK(array->length() >= length); DCHECK_LE(length, array->length());
if (array->length() == length) return array; if (array->length() == length) return array;
return array->GetIsolate()->factory()->CopyFixedArrayUpTo(array, length);
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;
} }
bool Map::OnlyHasSimpleProperties() { 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