// Copyright 2014 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.

#include "src/objects/layout-descriptor.h"

#include <sstream>

#include "src/base/bits.h"
#include "src/base/platform/wrappers.h"
#include "src/handles/handles-inl.h"
#include "src/objects/objects-inl.h"

namespace v8 {
namespace internal {

Handle<LayoutDescriptor> LayoutDescriptor::New(
    Isolate* isolate, Handle<Map> map, Handle<DescriptorArray> descriptors,
    int num_descriptors) {
  if (!FLAG_unbox_double_fields) return handle(FastPointerLayout(), isolate);

  int layout_descriptor_length =
      CalculateCapacity(*map, *descriptors, num_descriptors);

  if (layout_descriptor_length == 0) {
    // No double fields were found, use fast pointer layout.
    return handle(FastPointerLayout(), isolate);
  }

  // Initially, layout descriptor corresponds to an object with all fields
  // tagged.
  Handle<LayoutDescriptor> layout_descriptor_handle =
      LayoutDescriptor::New(isolate, layout_descriptor_length);

  LayoutDescriptor layout_descriptor = Initialize(
      *layout_descriptor_handle, *map, *descriptors, num_descriptors);

  return handle(layout_descriptor, isolate);
}

Handle<LayoutDescriptor> LayoutDescriptor::ShareAppend(
    Isolate* isolate, Handle<Map> map, PropertyDetails details) {
  DCHECK(map->owns_descriptors());
  Handle<LayoutDescriptor> layout_descriptor(map->GetLayoutDescriptor(),
                                             isolate);

  if (!InobjectUnboxedField(map->GetInObjectProperties(), details)) {
    DCHECK(details.location() != kField ||
           layout_descriptor->IsTagged(details.field_index()));
    return layout_descriptor;
  }
  int field_index = details.field_index();
  layout_descriptor = LayoutDescriptor::EnsureCapacity(
      isolate, layout_descriptor, field_index + details.field_width_in_words());

  DisallowHeapAllocation no_allocation;
  LayoutDescriptor layout_desc = *layout_descriptor;
  layout_desc = layout_desc.SetRawData(field_index);
  if (details.field_width_in_words() > 1) {
    layout_desc = layout_desc.SetRawData(field_index + 1);
  }
  return handle(layout_desc, isolate);
}

Handle<LayoutDescriptor> LayoutDescriptor::AppendIfFastOrUseFull(
    Isolate* isolate, Handle<Map> map, PropertyDetails details,
    Handle<LayoutDescriptor> full_layout_descriptor) {
  DisallowHeapAllocation no_allocation;
  LayoutDescriptor layout_descriptor = map->layout_descriptor(kAcquireLoad);
  if (layout_descriptor.IsSlowLayout()) {
    return full_layout_descriptor;
  }
  if (!InobjectUnboxedField(map->GetInObjectProperties(), details)) {
    DCHECK(details.location() != kField ||
           layout_descriptor.IsTagged(details.field_index()));
    return handle(layout_descriptor, isolate);
  }
  int field_index = details.field_index();
  int new_capacity = field_index + details.field_width_in_words();
  if (new_capacity > layout_descriptor.capacity()) {
    // Current map's layout descriptor runs out of space, so use the full
    // layout descriptor.
    return full_layout_descriptor;
  }

  layout_descriptor = layout_descriptor.SetRawData(field_index);
  if (details.field_width_in_words() > 1) {
    layout_descriptor = layout_descriptor.SetRawData(field_index + 1);
  }
  return handle(layout_descriptor, isolate);
}

Handle<LayoutDescriptor> LayoutDescriptor::EnsureCapacity(
    Isolate* isolate, Handle<LayoutDescriptor> layout_descriptor,
    int new_capacity) {
  int old_capacity = layout_descriptor->capacity();
  if (new_capacity <= old_capacity) {
    return layout_descriptor;
  }
  Handle<LayoutDescriptor> new_layout_descriptor =
      LayoutDescriptor::New(isolate, new_capacity);
  DCHECK(new_layout_descriptor->IsSlowLayout());

  if (layout_descriptor->IsSlowLayout()) {
    memcpy(new_layout_descriptor->GetDataStartAddress(),
                 layout_descriptor->GetDataStartAddress(),
                 layout_descriptor->DataSize());
    return new_layout_descriptor;
  } else {
    // Fast layout.
    uint32_t value = static_cast<uint32_t>(Smi::ToInt(*layout_descriptor));
    new_layout_descriptor->set_layout_word(0, value);
    return new_layout_descriptor;
  }
}

bool LayoutDescriptor::IsTagged(int field_index, int max_sequence_length,
                                int* out_sequence_length) {
  DCHECK_GT(max_sequence_length, 0);
  if (IsFastPointerLayout()) {
    *out_sequence_length = max_sequence_length;
    return true;
  }

  int layout_word_index;
  int layout_bit_index;

  if (!GetIndexes(field_index, &layout_word_index, &layout_bit_index)) {
    // Out of bounds queries are considered tagged.
    *out_sequence_length = max_sequence_length;
    return true;
  }
  uint32_t layout_mask = static_cast<uint32_t>(1) << layout_bit_index;

  uint32_t value = IsSlowLayout() ? get_layout_word(layout_word_index)
                                  : static_cast<uint32_t>(Smi::ToInt(*this));

  bool is_tagged = (value & layout_mask) == 0;
  if (!is_tagged) value = ~value;  // Count set bits instead of cleared bits.
  value = value & ~(layout_mask - 1);  // Clear bits we are not interested in.
  int sequence_length;
  if (IsSlowLayout()) {
    sequence_length = base::bits::CountTrailingZeros(value) - layout_bit_index;

    if (layout_bit_index + sequence_length == kBitsPerLayoutWord) {
      // This is a contiguous sequence till the end of current word, proceed
      // counting in the subsequent words.
      ++layout_word_index;
      int num_words = number_of_layout_words();
      for (; layout_word_index < num_words; layout_word_index++) {
        value = get_layout_word(layout_word_index);
        bool cur_is_tagged = (value & 1) == 0;
        if (cur_is_tagged != is_tagged) break;
        if (!is_tagged) value = ~value;  // Count set bits instead.
        int cur_sequence_length = base::bits::CountTrailingZeros(value);
        sequence_length += cur_sequence_length;
        if (sequence_length >= max_sequence_length) break;
        if (cur_sequence_length != kBitsPerLayoutWord) break;
      }
      if (is_tagged && (field_index + sequence_length == capacity())) {
        // The contiguous sequence of tagged fields lasts till the end of the
        // layout descriptor which means that all the fields starting from
        // field_index are tagged.
        sequence_length = std::numeric_limits<int>::max();
      }
    }
  } else {  // Fast layout.
    sequence_length = std::min(base::bits::CountTrailingZeros(value),
                               static_cast<unsigned>(kBitsInSmiLayout)) -
                      layout_bit_index;
    if (is_tagged && (field_index + sequence_length == capacity())) {
      // The contiguous sequence of tagged fields lasts till the end of the
      // layout descriptor which means that all the fields starting from
      // field_index are tagged.
      sequence_length = std::numeric_limits<int>::max();
    }
  }
  *out_sequence_length = std::min(sequence_length, max_sequence_length);
  return is_tagged;
}

Handle<LayoutDescriptor> LayoutDescriptor::NewForTesting(Isolate* isolate,
                                                         int length) {
  return New(isolate, length);
}

LayoutDescriptor LayoutDescriptor::SetTaggedForTesting(int field_index,
                                                       bool tagged) {
  return SetTagged(field_index, tagged);
}

bool LayoutDescriptorHelper::IsTagged(
    int offset_in_bytes, int end_offset,
    int* out_end_of_contiguous_region_offset) {
  DCHECK(IsAligned(offset_in_bytes, kTaggedSize));
  DCHECK(IsAligned(end_offset, kTaggedSize));
  DCHECK(offset_in_bytes < end_offset);
  if (all_fields_tagged_) {
    *out_end_of_contiguous_region_offset = end_offset;
    DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset);
    return true;
  }
  int max_sequence_length = (end_offset - offset_in_bytes) / kTaggedSize;
  int field_index = std::max(0, (offset_in_bytes - header_size_) / kTaggedSize);
  int sequence_length;
  bool tagged = layout_descriptor_.IsTagged(field_index, max_sequence_length,
                                            &sequence_length);
  DCHECK_GT(sequence_length, 0);
  if (offset_in_bytes < header_size_) {
    // Object headers do not contain non-tagged fields. Check if the contiguous
    // region continues after the header.
    if (tagged) {
      // First field is tagged, calculate end offset from there.
      *out_end_of_contiguous_region_offset =
          header_size_ + sequence_length * kTaggedSize;

    } else {
      *out_end_of_contiguous_region_offset = header_size_;
    }
    DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset);
    return true;
  }
  *out_end_of_contiguous_region_offset =
      offset_in_bytes + sequence_length * kTaggedSize;
  DCHECK(offset_in_bytes < *out_end_of_contiguous_region_offset);
  return tagged;
}

LayoutDescriptor LayoutDescriptor::Trim(Heap* heap, Map map,
                                        DescriptorArray descriptors,
                                        int num_descriptors) {
  DisallowHeapAllocation no_allocation;
  // Fast mode descriptors are never shared and therefore always fully
  // correspond to their map.
  if (!IsSlowLayout()) return *this;

  int layout_descriptor_length =
      CalculateCapacity(map, descriptors, num_descriptors);
  // It must not become fast-mode descriptor here, because otherwise it has to
  // be fast pointer layout descriptor already but it's is slow mode now.
  DCHECK_LT(kBitsInSmiLayout, layout_descriptor_length);

  // Trim, clean and reinitialize this slow-mode layout descriptor.
  int new_backing_store_length =
      GetSlowModeBackingStoreLength(layout_descriptor_length);
  int backing_store_length = length();
  if (new_backing_store_length != backing_store_length) {
    DCHECK_LT(new_backing_store_length, backing_store_length);
    int delta = backing_store_length - new_backing_store_length;
    heap->RightTrimFixedArray(*this, delta);
  }
  memset(GetDataStartAddress(), 0, DataSize());
  LayoutDescriptor layout_descriptor =
      Initialize(*this, map, descriptors, num_descriptors);
  DCHECK_EQ(*this, layout_descriptor);
  return layout_descriptor;
}

bool LayoutDescriptor::IsConsistentWithMap(Map map, bool check_tail) {
  if (FLAG_unbox_double_fields) {
    DescriptorArray descriptors = map.instance_descriptors(kRelaxedLoad);
    int last_field_index = 0;
    for (InternalIndex i : map.IterateOwnDescriptors()) {
      PropertyDetails details = descriptors.GetDetails(i);
      if (details.location() != kField) continue;
      FieldIndex field_index = FieldIndex::ForDescriptor(map, i);
      bool tagged_expected =
          !field_index.is_inobject() || !details.representation().IsDouble();
      for (int bit = 0; bit < details.field_width_in_words(); bit++) {
        bool tagged_actual = IsTagged(details.field_index() + bit);
        DCHECK_EQ(tagged_expected, tagged_actual);
        if (tagged_actual != tagged_expected) return false;
      }
      last_field_index =
          std::max(last_field_index,
                   details.field_index() + details.field_width_in_words());
    }
    if (check_tail) {
      int n = capacity();
      for (int i = last_field_index; i < n; i++) {
        DCHECK(IsTagged(i));
      }
    }
  }
  return true;
}
}  // namespace internal
}  // namespace v8
