Some optimizations for the array alloc path.
- Force Array::Alloc() to be inlined.
- Simplify the array size overflow check.
- Turn fill_usable into a template parameter.
- Remove a branch in Array::DataOffset() and avoid
Primitive::ComponentSize(), which has a switch, in the array alloc
path.
- Strength reductions in the array size computation by using component
size shifts instead of component sizes. Store component size shift
in the upper 16 bits of primitive_type field.
- Speedup: ~4% (3435->3284) in MemAllocTest on N4.
Bug: 9986565
Change-Id: I4b142ffac4ab8b5b915836f1660a949d6442344c
diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h
index 4ef7d74..9fb9a3b 100644
--- a/runtime/entrypoints/entrypoint_utils-inl.h
+++ b/runtime/entrypoints/entrypoint_utils-inl.h
@@ -230,11 +230,11 @@
}
gc::Heap* heap = Runtime::Current()->GetHeap();
return mirror::Array::Alloc<kInstrumented>(self, klass, component_count,
- klass->GetComponentSize(),
+ klass->GetComponentSizeShift(),
heap->GetCurrentAllocator());
}
return mirror::Array::Alloc<kInstrumented>(self, klass, component_count,
- klass->GetComponentSize(), allocator_type);
+ klass->GetComponentSizeShift(), allocator_type);
}
template <bool kAccessCheck, bool kInstrumented>
@@ -259,7 +259,7 @@
// No need to retry a slow-path allocation as the above code won't cause a GC or thread
// suspension.
return mirror::Array::Alloc<kInstrumented>(self, klass, component_count,
- klass->GetComponentSize(), allocator_type);
+ klass->GetComponentSizeShift(), allocator_type);
}
template<FindFieldType type, bool access_check>
diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc
index a78c2c0..835d6e2 100644
--- a/runtime/entrypoints/entrypoint_utils.cc
+++ b/runtime/entrypoints/entrypoint_utils.cc
@@ -90,7 +90,8 @@
gc::Heap* heap = Runtime::Current()->GetHeap();
// Use the current allocator type in case CheckFilledNewArrayAlloc caused us to suspend and then
// the heap switched the allocator type while we were suspended.
- return mirror::Array::Alloc<false>(self, klass, component_count, klass->GetComponentSize(),
+ return mirror::Array::Alloc<false>(self, klass, component_count,
+ klass->GetComponentSizeShift(),
heap->GetCurrentAllocator());
}
@@ -109,7 +110,8 @@
gc::Heap* heap = Runtime::Current()->GetHeap();
// Use the current allocator type in case CheckFilledNewArrayAlloc caused us to suspend and then
// the heap switched the allocator type while we were suspended.
- return mirror::Array::Alloc<true>(self, klass, component_count, klass->GetComponentSize(),
+ return mirror::Array::Alloc<true>(self, klass, component_count,
+ klass->GetComponentSizeShift(),
heap->GetCurrentAllocator());
}