Commit b090d7e7 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[objects.h splitting] Move DescriptorArray leftovers out of objects-inl.h

BUG=v8:5402,v8:8238

Change-Id: I61afd09ecd80dba4fbb89e3ae4b71fca1138cec2
Reviewed-on: https://chromium-review.googlesource.com/c/1367449Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58103}
parent 9efb53db
......@@ -2279,6 +2279,7 @@ v8_source_set("v8_base") {
"src/objects/debug-objects-inl.h",
"src/objects/debug-objects.cc",
"src/objects/debug-objects.h",
"src/objects/descriptor-array-inl.h",
"src/objects/descriptor-array.h",
"src/objects/dictionary-inl.h",
"src/objects/dictionary.h",
......
This diff is collapsed.
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_
#define V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_
#include "src/objects/descriptor-array.h"
#include "src/field-type.h"
#include "src/heap/heap-write-barrier.h"
#include "src/heap/heap.h"
#include "src/isolate.h"
#include "src/lookup-cache.h"
#include "src/objects/heap-object-inl.h"
#include "src/objects/maybe-object.h"
#include "src/property.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
OBJECT_CONSTRUCTORS_IMPL(DescriptorArray, HeapObjectPtr)
CAST_ACCESSOR2(DescriptorArray)
ACCESSORS(DescriptorArray, enum_cache, EnumCache, kEnumCacheOffset)
RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_all_descriptors,
kNumberOfAllDescriptorsOffset)
RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_descriptors,
kNumberOfDescriptorsOffset)
RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_marked_descriptors,
kNumberOfMarkedDescriptorsOffset)
RELAXED_INT16_ACCESSORS(DescriptorArray, filler16bits, kFiller16BitsOffset)
inline int16_t DescriptorArray::number_of_slack_descriptors() const {
return number_of_all_descriptors() - number_of_descriptors();
}
inline int DescriptorArray::number_of_entries() const {
return number_of_descriptors();
}
void DescriptorArray::CopyEnumCacheFrom(DescriptorArray array) {
set_enum_cache(array->enum_cache());
}
int DescriptorArray::Search(Name name, int valid_descriptors) {
DCHECK(name->IsUniqueName());
return internal::Search<VALID_ENTRIES>(this, name, valid_descriptors,
nullptr);
}
int DescriptorArray::Search(Name name, Map map) {
DCHECK(name->IsUniqueName());
int number_of_own_descriptors = map->NumberOfOwnDescriptors();
if (number_of_own_descriptors == 0) return kNotFound;
return Search(name, number_of_own_descriptors);
}
int DescriptorArray::SearchWithCache(Isolate* isolate, Name name, Map map) {
DCHECK(name->IsUniqueName());
int number_of_own_descriptors = map->NumberOfOwnDescriptors();
if (number_of_own_descriptors == 0) return kNotFound;
DescriptorLookupCache* cache = isolate->descriptor_lookup_cache();
int number = cache->Lookup(map, name);
if (number == DescriptorLookupCache::kAbsent) {
number = Search(name, number_of_own_descriptors);
cache->Update(map, name, number);
}
return number;
}
ObjectSlot DescriptorArray::GetFirstPointerSlot() {
return RawField(DescriptorArray::kPointersStartOffset);
}
ObjectSlot DescriptorArray::GetDescriptorSlot(int descriptor) {
// Allow descriptor == number_of_all_descriptors() for computing the slot
// address that comes after the last descriptor (for iterating).
DCHECK_LE(descriptor, number_of_all_descriptors());
return RawField(OffsetOfDescriptorAt(descriptor));
}
ObjectSlot DescriptorArray::GetKeySlot(int descriptor) {
DCHECK_LE(descriptor, number_of_all_descriptors());
ObjectSlot slot = GetDescriptorSlot(descriptor) + kEntryKeyIndex;
DCHECK((*slot)->IsObject());
return slot;
}
Name DescriptorArray::GetKey(int descriptor_number) const {
DCHECK(descriptor_number < number_of_descriptors());
return Name::cast(
get(ToKeyIndex(descriptor_number))->GetHeapObjectAssumeStrong());
}
int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
return GetDetails(descriptor_number).pointer();
}
Name DescriptorArray::GetSortedKey(int descriptor_number) {
return GetKey(GetSortedKeyIndex(descriptor_number));
}
void DescriptorArray::SetSortedKey(int descriptor_index, int pointer) {
PropertyDetails details = GetDetails(descriptor_index);
set(ToDetailsIndex(descriptor_index),
MaybeObject::FromObject(details.set_pointer(pointer).AsSmi()));
}
MaybeObjectSlot DescriptorArray::GetValueSlot(int descriptor) {
DCHECK_LT(descriptor, number_of_descriptors());
return MaybeObjectSlot(GetDescriptorSlot(descriptor) + kEntryValueIndex);
}
Object* DescriptorArray::GetStrongValue(int descriptor_number) {
DCHECK(descriptor_number < number_of_descriptors());
return get(ToValueIndex(descriptor_number))->cast<Object>();
}
void DescriptorArray::SetValue(int descriptor_index, Object* value) {
set(ToValueIndex(descriptor_index), MaybeObject::FromObject(value));
}
MaybeObject DescriptorArray::GetValue(int descriptor_number) {
DCHECK_LT(descriptor_number, number_of_descriptors());
return get(ToValueIndex(descriptor_number));
}
PropertyDetails DescriptorArray::GetDetails(int descriptor_number) {
DCHECK(descriptor_number < number_of_descriptors());
MaybeObject details = get(ToDetailsIndex(descriptor_number));
return PropertyDetails(details->ToSmi());
}
int DescriptorArray::GetFieldIndex(int descriptor_number) {
DCHECK_EQ(GetDetails(descriptor_number).location(), kField);
return GetDetails(descriptor_number).field_index();
}
FieldType DescriptorArray::GetFieldType(int descriptor_number) {
DCHECK_EQ(GetDetails(descriptor_number).location(), kField);
MaybeObject wrapped_type = GetValue(descriptor_number);
return Map::UnwrapFieldType(wrapped_type);
}
void DescriptorArray::Set(int descriptor_number, Name key, MaybeObject value,
PropertyDetails details) {
// Range check.
DCHECK(descriptor_number < number_of_descriptors());
set(ToKeyIndex(descriptor_number), MaybeObject::FromObject(key));
set(ToValueIndex(descriptor_number), value);
set(ToDetailsIndex(descriptor_number),
MaybeObject::FromObject(details.AsSmi()));
}
void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
Name key = *desc->GetKey();
MaybeObject value = *desc->GetValue();
Set(descriptor_number, key, value, desc->GetDetails());
}
void DescriptorArray::Append(Descriptor* desc) {
DisallowHeapAllocation no_gc;
int descriptor_number = number_of_descriptors();
DCHECK_LE(descriptor_number + 1, number_of_all_descriptors());
set_number_of_descriptors(descriptor_number + 1);
Set(descriptor_number, desc);
uint32_t hash = desc->GetKey()->Hash();
int insertion;
for (insertion = descriptor_number; insertion > 0; --insertion) {
Name key = GetSortedKey(insertion - 1);
if (key->Hash() <= hash) break;
SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
}
SetSortedKey(insertion, descriptor_number);
}
void DescriptorArray::SwapSortedKeys(int first, int second) {
int first_key = GetSortedKeyIndex(first);
SetSortedKey(first, GetSortedKeyIndex(second));
SetSortedKey(second, first_key);
}
int DescriptorArray::length() const {
return number_of_all_descriptors() * kEntrySize;
}
MaybeObject DescriptorArray::get(int index) const {
DCHECK(index >= 0 && index < this->length());
return RELAXED_READ_WEAK_FIELD(this, offset(index));
}
void DescriptorArray::set(int index, MaybeObject value) {
DCHECK(index >= 0 && index < this->length());
RELAXED_WRITE_WEAK_FIELD(this, offset(index), value);
WEAK_WRITE_BARRIER(this, offset(index), value);
}
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_
......@@ -203,6 +203,107 @@ void FixedArray::MoveElements(Heap* heap, int dst_index, int src_index, int len,
heap->MoveElements(*this, dst_index, src_index, len, mode);
}
// Perform a binary search in a fixed array.
template <SearchMode search_mode, typename T>
int BinarySearch(T* array, Name name, int valid_entries,
int* out_insertion_index) {
DCHECK(search_mode == ALL_ENTRIES || out_insertion_index == nullptr);
int low = 0;
int high = array->number_of_entries() - 1;
uint32_t hash = name->hash_field();
int limit = high;
DCHECK(low <= high);
while (low != high) {
int mid = low + (high - low) / 2;
Name mid_name = array->GetSortedKey(mid);
uint32_t mid_hash = mid_name->hash_field();
if (mid_hash >= hash) {
high = mid;
} else {
low = mid + 1;
}
}
for (; low <= limit; ++low) {
int sort_index = array->GetSortedKeyIndex(low);
Name entry = array->GetKey(sort_index);
uint32_t current_hash = entry->hash_field();
if (current_hash != hash) {
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
*out_insertion_index = sort_index + (current_hash > hash ? 0 : 1);
}
return T::kNotFound;
}
if (entry == name) {
if (search_mode == ALL_ENTRIES || sort_index < valid_entries) {
return sort_index;
}
return T::kNotFound;
}
}
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
*out_insertion_index = limit + 1;
}
return T::kNotFound;
}
// Perform a linear search in this fixed array. len is the number of entry
// indices that are valid.
template <SearchMode search_mode, typename T>
int LinearSearch(T* array, Name name, int valid_entries,
int* out_insertion_index) {
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
uint32_t hash = name->hash_field();
int len = array->number_of_entries();
for (int number = 0; number < len; number++) {
int sorted_index = array->GetSortedKeyIndex(number);
Name entry = array->GetKey(sorted_index);
uint32_t current_hash = entry->hash_field();
if (current_hash > hash) {
*out_insertion_index = sorted_index;
return T::kNotFound;
}
if (entry == name) return sorted_index;
}
*out_insertion_index = len;
return T::kNotFound;
} else {
DCHECK_LE(valid_entries, array->number_of_entries());
DCHECK_NULL(out_insertion_index); // Not supported here.
for (int number = 0; number < valid_entries; number++) {
if (array->GetKey(number) == name) return number;
}
return T::kNotFound;
}
}
template <SearchMode search_mode, typename T>
int Search(T* array, Name name, int valid_entries, int* out_insertion_index) {
SLOW_DCHECK(array->IsSortedNoDuplicates());
if (valid_entries == 0) {
if (search_mode == ALL_ENTRIES && out_insertion_index != nullptr) {
*out_insertion_index = 0;
}
return T::kNotFound;
}
// Fast case: do linear search for small arrays.
const int kMaxElementsForLinearSearch = 8;
if (valid_entries <= kMaxElementsForLinearSearch) {
return LinearSearch<search_mode>(array, name, valid_entries,
out_insertion_index);
}
// Slow case: perform binary search.
return BinarySearch<search_mode>(array, name, valid_entries,
out_insertion_index);
}
double FixedDoubleArray::get_scalar(int index) {
DCHECK(map() != GetReadOnlyRoots().fixed_cow_array_map() &&
map() != GetReadOnlyRoots().fixed_array_map());
......
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