%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /home2/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/objects/
Upload File :
Create Path :
Current File : //home2/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/objects/slots-inl.h

// 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_SLOTS_INL_H_
#define V8_OBJECTS_SLOTS_INL_H_

#include "src/base/atomic-utils.h"
#include "src/common/globals.h"
#include "src/common/ptr-compr-inl.h"
#include "src/objects/compressed-slots.h"
#include "src/objects/heap-object.h"
#include "src/objects/map.h"
#include "src/objects/maybe-object.h"
#include "src/objects/objects.h"
#include "src/objects/slots.h"
#include "src/objects/tagged.h"
#include "src/sandbox/external-pointer-inl.h"
#include "src/sandbox/indirect-pointer-inl.h"
#include "src/utils/memcopy.h"

namespace v8 {
namespace internal {

//
// FullObjectSlot implementation.
//

FullObjectSlot::FullObjectSlot(TaggedBase* object)
    : SlotBase(reinterpret_cast<Address>(&object->ptr_)) {}

bool FullObjectSlot::contains_map_value(Address raw_value) const {
  return load_map().ptr() == raw_value;
}

bool FullObjectSlot::Relaxed_ContainsMapValue(Address raw_value) const {
  return base::AsAtomicPointer::Relaxed_Load(location()) == raw_value;
}

Tagged<Object> FullObjectSlot::operator*() const {
  return Tagged<Object>(*location());
}

Tagged<Object> FullObjectSlot::load(PtrComprCageBase cage_base) const {
  return **this;
}

void FullObjectSlot::store(Tagged<Object> value) const {
  *location() = value.ptr();
}

void FullObjectSlot::store_map(Tagged<Map> map) const {
#ifdef V8_MAP_PACKING
  *location() = MapWord::Pack(map.ptr());
#else
  store(map);
#endif
}

Tagged<Map> FullObjectSlot::load_map() const {
#ifdef V8_MAP_PACKING
  return Map::unchecked_cast(Tagged<Object>(MapWord::Unpack(*location())));
#else
  return Map::unchecked_cast(Tagged<Object>(*location()));
#endif
}

Tagged<Object> FullObjectSlot::Acquire_Load() const {
  return Tagged<Object>(base::AsAtomicPointer::Acquire_Load(location()));
}

Tagged<Object> FullObjectSlot::Acquire_Load(PtrComprCageBase cage_base) const {
  return Acquire_Load();
}

Tagged<Object> FullObjectSlot::Relaxed_Load() const {
  return Tagged<Object>(base::AsAtomicPointer::Relaxed_Load(location()));
}

Tagged<Object> FullObjectSlot::Relaxed_Load(PtrComprCageBase cage_base) const {
  return Relaxed_Load();
}

void FullObjectSlot::Relaxed_Store(Tagged<Object> value) const {
  base::AsAtomicPointer::Relaxed_Store(location(), value.ptr());
}

void FullObjectSlot::Release_Store(Tagged<Object> value) const {
  base::AsAtomicPointer::Release_Store(location(), value.ptr());
}

Tagged<Object> FullObjectSlot::Relaxed_CompareAndSwap(
    Tagged<Object> old, Tagged<Object> target) const {
  Address result = base::AsAtomicPointer::Relaxed_CompareAndSwap(
      location(), old.ptr(), target.ptr());
  return Tagged<Object>(result);
}

Tagged<Object> FullObjectSlot::Release_CompareAndSwap(
    Tagged<Object> old, Tagged<Object> target) const {
  Address result = base::AsAtomicPointer::Release_CompareAndSwap(
      location(), old.ptr(), target.ptr());
  return Tagged<Object>(result);
}

//
// FullMaybeObjectSlot implementation.
//

MaybeObject FullMaybeObjectSlot::operator*() const {
  return MaybeObject(*location());
}

MaybeObject FullMaybeObjectSlot::load(PtrComprCageBase cage_base) const {
  return **this;
}

void FullMaybeObjectSlot::store(MaybeObject value) const {
  *location() = value.ptr();
}

MaybeObject FullMaybeObjectSlot::Relaxed_Load() const {
  return MaybeObject(base::AsAtomicPointer::Relaxed_Load(location()));
}

MaybeObject FullMaybeObjectSlot::Relaxed_Load(
    PtrComprCageBase cage_base) const {
  return Relaxed_Load();
}

void FullMaybeObjectSlot::Relaxed_Store(MaybeObject value) const {
  base::AsAtomicPointer::Relaxed_Store(location(), value->ptr());
}

void FullMaybeObjectSlot::Release_CompareAndSwap(MaybeObject old,
                                                 MaybeObject target) const {
  base::AsAtomicPointer::Release_CompareAndSwap(location(), old.ptr(),
                                                target.ptr());
}

//
// FullHeapObjectSlot implementation.
//

HeapObjectReference FullHeapObjectSlot::operator*() const {
  return HeapObjectReference(*location());
}

HeapObjectReference FullHeapObjectSlot::load(PtrComprCageBase cage_base) const {
  return **this;
}

void FullHeapObjectSlot::store(HeapObjectReference value) const {
  *location() = value.ptr();
}

Tagged<HeapObject> FullHeapObjectSlot::ToHeapObject() const {
  TData value = *location();
  DCHECK(HAS_STRONG_HEAP_OBJECT_TAG(value));
  return HeapObject::cast(Tagged<Object>(value));
}

void FullHeapObjectSlot::StoreHeapObject(Tagged<HeapObject> value) const {
  *location() = value.ptr();
}

void ExternalPointerSlot::init(Isolate* isolate, Address value) {
#ifdef V8_ENABLE_SANDBOX
  ExternalPointerTable& table = GetExternalPointerTable(isolate);
  ExternalPointerHandle handle = table.AllocateAndInitializeEntry(
      GetDefaultExternalPointerSpace(isolate), value, tag_);
  // Use a Release_Store to ensure that the store of the pointer into the
  // table is not reordered after the store of the handle. Otherwise, other
  // threads may access an uninitialized table entry and crash.
  Release_StoreHandle(handle);
#else
  store(isolate, value);
#endif  // V8_ENABLE_SANDBOX
}

#ifdef V8_ENABLE_SANDBOX
ExternalPointerHandle ExternalPointerSlot::Relaxed_LoadHandle() const {
  return base::AsAtomic32::Relaxed_Load(location());
}

void ExternalPointerSlot::Relaxed_StoreHandle(
    ExternalPointerHandle handle) const {
  return base::AsAtomic32::Relaxed_Store(location(), handle);
}

void ExternalPointerSlot::Release_StoreHandle(
    ExternalPointerHandle handle) const {
  return base::AsAtomic32::Release_Store(location(), handle);
}
#endif  // V8_ENABLE_SANDBOX

Address ExternalPointerSlot::load(const Isolate* isolate) {
#ifdef V8_ENABLE_SANDBOX
  const ExternalPointerTable& table = GetExternalPointerTable(isolate);
  ExternalPointerHandle handle = Relaxed_LoadHandle();
  return table.Get(handle, tag_);
#else
  return ReadMaybeUnalignedValue<Address>(address());
#endif  // V8_ENABLE_SANDBOX
}

void ExternalPointerSlot::store(Isolate* isolate, Address value) {
#ifdef V8_ENABLE_SANDBOX
  ExternalPointerTable& table = GetExternalPointerTable(isolate);
  ExternalPointerHandle handle = Relaxed_LoadHandle();
  table.Set(handle, value, tag_);
#else
  WriteMaybeUnalignedValue<Address>(address(), value);
#endif  // V8_ENABLE_SANDBOX
}

ExternalPointerSlot::RawContent
ExternalPointerSlot::GetAndClearContentForSerialization(
    const DisallowGarbageCollection& no_gc) {
#ifdef V8_ENABLE_SANDBOX
  ExternalPointerHandle content = Relaxed_LoadHandle();
  Relaxed_StoreHandle(kNullExternalPointerHandle);
#else
  Address content = ReadMaybeUnalignedValue<Address>(address());
  WriteMaybeUnalignedValue<Address>(address(), kNullAddress);
#endif
  return content;
}

void ExternalPointerSlot::RestoreContentAfterSerialization(
    ExternalPointerSlot::RawContent content,
    const DisallowGarbageCollection& no_gc) {
#ifdef V8_ENABLE_SANDBOX
  return Relaxed_StoreHandle(content);
#else
  return WriteMaybeUnalignedValue<Address>(address(), content);
#endif
}

void ExternalPointerSlot::ReplaceContentWithIndexForSerialization(
    const DisallowGarbageCollection& no_gc, uint32_t index) {
#ifdef V8_ENABLE_SANDBOX
  static_assert(sizeof(ExternalPointerHandle) == sizeof(uint32_t));
  Relaxed_StoreHandle(index);
#else
  WriteMaybeUnalignedValue<Address>(address(), static_cast<Address>(index));
#endif
}

uint32_t ExternalPointerSlot::GetContentAsIndexAfterDeserialization(
    const DisallowGarbageCollection& no_gc) {
#ifdef V8_ENABLE_SANDBOX
  static_assert(sizeof(ExternalPointerHandle) == sizeof(uint32_t));
  return Relaxed_LoadHandle();
#else
  return static_cast<uint32_t>(ReadMaybeUnalignedValue<Address>(address()));
#endif
}

#ifdef V8_ENABLE_SANDBOX
const ExternalPointerTable& ExternalPointerSlot::GetExternalPointerTable(
    const Isolate* isolate) {
  DCHECK_NE(tag_, kExternalPointerNullTag);
  return IsSharedExternalPointerType(tag_)
             ? isolate->shared_external_pointer_table()
             : isolate->external_pointer_table();
}

ExternalPointerTable& ExternalPointerSlot::GetExternalPointerTable(
    Isolate* isolate) {
  DCHECK_NE(tag_, kExternalPointerNullTag);
  return IsSharedExternalPointerType(tag_)
             ? isolate->shared_external_pointer_table()
             : isolate->external_pointer_table();
}

ExternalPointerTable::Space*
ExternalPointerSlot::GetDefaultExternalPointerSpace(Isolate* isolate) {
  if (V8_UNLIKELY(IsSharedExternalPointerType(tag_))) {
    DCHECK(!ReadOnlyHeap::Contains(address()));
    return isolate->shared_external_pointer_space();
  }
  if (V8_UNLIKELY(ReadOnlyHeap::Contains(address()))) {
    DCHECK(tag_ == kAccessorInfoGetterTag || tag_ == kAccessorInfoSetterTag ||
           tag_ == kCallHandlerInfoCallbackTag);
    return isolate->heap()->read_only_external_pointer_space();
  }
  return isolate->heap()->external_pointer_space();
}
#endif  // V8_ENABLE_SANDBOX

Tagged<Object> IndirectPointerSlot::load(const Isolate* isolate) const {
  return Relaxed_Load(isolate);
}

void IndirectPointerSlot::store(Tagged<ExposedTrustedObject> value) const {
  return Relaxed_Store(value);
}

Tagged<Object> IndirectPointerSlot::Relaxed_Load(const Isolate* isolate) const {
  IndirectPointerHandle handle = Relaxed_LoadHandle();
  return ResolveHandle(handle, isolate);
}

Tagged<Object> IndirectPointerSlot::Acquire_Load(const Isolate* isolate) const {
  IndirectPointerHandle handle = Acquire_LoadHandle();
  return ResolveHandle(handle, isolate);
}

void IndirectPointerSlot::Relaxed_Store(
    Tagged<ExposedTrustedObject> value) const {
#ifdef V8_ENABLE_SANDBOX
  IndirectPointerHandle handle = value->ReadField<IndirectPointerHandle>(
      ExposedTrustedObject::kSelfIndirectPointerOffset);
  Relaxed_StoreHandle(handle);
#else
  UNREACHABLE();
#endif  // V8_ENABLE_SANDBOX
}

void IndirectPointerSlot::Release_Store(
    Tagged<ExposedTrustedObject> value) const {
#ifdef V8_ENABLE_SANDBOX
  IndirectPointerHandle handle = value->ReadField<IndirectPointerHandle>(
      ExposedTrustedObject::kSelfIndirectPointerOffset);
  Release_StoreHandle(handle);
#else
  UNREACHABLE();
#endif  // V8_ENABLE_SANDBOX
}

IndirectPointerHandle IndirectPointerSlot::Relaxed_LoadHandle() const {
  return base::AsAtomic32::Relaxed_Load(location());
}

IndirectPointerHandle IndirectPointerSlot::Acquire_LoadHandle() const {
  return base::AsAtomic32::Acquire_Load(location());
}

void IndirectPointerSlot::Relaxed_StoreHandle(
    IndirectPointerHandle handle) const {
  return base::AsAtomic32::Relaxed_Store(location(), handle);
}

void IndirectPointerSlot::Release_StoreHandle(
    IndirectPointerHandle handle) const {
  return base::AsAtomic32::Release_Store(location(), handle);
}

Tagged<Object> IndirectPointerSlot::ResolveHandle(
    IndirectPointerHandle handle, const Isolate* isolate) const {
#ifdef V8_ENABLE_SANDBOX
  // TODO(saelo) Maybe come up with a different entry encoding scheme that
  // returns Smi::zero for kNullCodePointerHandle?
  if (!handle) return Smi::zero();

  if (tag_ == kCodeIndirectPointerTag) {
    // These are special as they use the code pointer table.
    Address addr = GetProcessWideCodePointerTable()->GetCodeObject(handle);
    return Tagged<Object>(addr);
  }

  const IndirectPointerTable& table = isolate->indirect_pointer_table();
  return Tagged<Object>(table.Get(handle));
#else
  UNREACHABLE();
#endif  // V8_ENABLE_SANDBOX
}

//
// Utils.
//

// Copies tagged words from |src| to |dst|. The data spans must not overlap.
// |src| and |dst| must be kTaggedSize-aligned.
inline void CopyTagged(Address dst, const Address src, size_t num_tagged) {
  static const size_t kBlockCopyLimit = 16;
  CopyImpl<kBlockCopyLimit>(reinterpret_cast<Tagged_t*>(dst),
                            reinterpret_cast<const Tagged_t*>(src), num_tagged);
}

// Sets |counter| number of kTaggedSize-sized values starting at |start| slot.
inline void MemsetTagged(Tagged_t* start, Tagged<Object> value,
                         size_t counter) {
#ifdef V8_COMPRESS_POINTERS
  // CompressAny since many callers pass values which are not valid objects.
  Tagged_t raw_value = V8HeapCompressionScheme::CompressAny(value.ptr());
  MemsetUint32(start, raw_value, counter);
#else
  Address raw_value = value.ptr();
  MemsetPointer(start, raw_value, counter);
#endif
}

// Sets |counter| number of kTaggedSize-sized values starting at |start| slot.
template <typename T>
inline void MemsetTagged(SlotBase<T, Tagged_t> start, Tagged<Object> value,
                         size_t counter) {
  MemsetTagged(start.location(), value, counter);
}

// Sets |counter| number of kSystemPointerSize-sized values starting at |start|
// slot.
inline void MemsetPointer(FullObjectSlot start, Tagged<Object> value,
                          size_t counter) {
  MemsetPointer(start.location(), value.ptr(), counter);
}

}  // namespace internal
}  // namespace v8

#endif  // V8_OBJECTS_SLOTS_INL_H_

Zerion Mini Shell 1.0