Commit ea9f847d authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[ptr-compr] Introduce EmbedderDataSlot

an abstraction that hides the details about how embedder data fields are
encoded in EmbedderDataArrays and JSObjects.

Bug: v8:7703
Change-Id: Ic9f6d9511bec557c6671aa6488b9545e353f968c
Reviewed-on: https://chromium-review.googlesource.com/c/1344155
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57679}
parent 5065c20a
...@@ -2222,6 +2222,8 @@ v8_source_set("v8_base") { ...@@ -2222,6 +2222,8 @@ v8_source_set("v8_base") {
"src/objects/embedder-data-array-inl.h", "src/objects/embedder-data-array-inl.h",
"src/objects/embedder-data-array.cc", "src/objects/embedder-data-array.cc",
"src/objects/embedder-data-array.h", "src/objects/embedder-data-array.h",
"src/objects/embedder-data-slot-inl.h",
"src/objects/embedder-data-slot.h",
"src/objects/fixed-array-inl.h", "src/objects/fixed-array-inl.h",
"src/objects/fixed-array.h", "src/objects/fixed-array.h",
"src/objects/frame-array-inl.h", "src/objects/frame-array-inl.h",
......
...@@ -125,7 +125,7 @@ class Internals { ...@@ -125,7 +125,7 @@ class Internals {
static const int kJSObjectHeaderSize = 3 * kApiTaggedSize; static const int kJSObjectHeaderSize = 3 * kApiTaggedSize;
static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize; static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize;
static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize; static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize;
static const int kEmbedderSlotSize = kApiSystemPointerSize; static const int kEmbedderDataSlotSize = kApiSystemPointerSize;
static const int kContextHeaderSize = 2 * kApiTaggedSize; static const int kContextHeaderSize = 2 * kApiTaggedSize;
static const int kContextEmbedderDataIndex = 5; static const int kContextEmbedderDataIndex = 5;
static const int kFullStringRepresentationMask = 0x0f; static const int kFullStringRepresentationMask = 0x0f;
...@@ -276,7 +276,7 @@ class Internals { ...@@ -276,7 +276,7 @@ class Internals {
(internal::kApiTaggedSize * I::kContextEmbedderDataIndex); (internal::kApiTaggedSize * I::kContextEmbedderDataIndex);
A embedder_data = I::ReadField<A>(ctx, embedder_data_offset); A embedder_data = I::ReadField<A>(ctx, embedder_data_offset);
int value_offset = int value_offset =
I::kEmbedderDataArrayHeaderSize + (I::kEmbedderSlotSize * index); I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index);
return I::ReadField<T>(embedder_data, value_offset); return I::ReadField<T>(embedder_data, value_offset);
} }
#endif #endif
......
...@@ -9828,7 +9828,7 @@ Local<Value> Object::GetInternalField(int index) { ...@@ -9828,7 +9828,7 @@ Local<Value> Object::GetInternalField(int index) {
if (instance_type == I::kJSObjectType || if (instance_type == I::kJSObjectType ||
instance_type == I::kJSApiObjectType || instance_type == I::kJSApiObjectType ||
instance_type == I::kJSSpecialApiObjectType) { instance_type == I::kJSSpecialApiObjectType) {
int offset = I::kJSObjectHeaderSize + (I::kEmbedderSlotSize * index); int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
A value = I::ReadField<A>(obj, offset); A value = I::ReadField<A>(obj, offset);
A* result = HandleScope::CreateHandle( A* result = HandleScope::CreateHandle(
reinterpret_cast<internal::NeverReadOnlySpaceObject*>(obj), value); reinterpret_cast<internal::NeverReadOnlySpaceObject*>(obj), value);
...@@ -9850,7 +9850,7 @@ void* Object::GetAlignedPointerFromInternalField(int index) { ...@@ -9850,7 +9850,7 @@ void* Object::GetAlignedPointerFromInternalField(int index) {
if (V8_LIKELY(instance_type == I::kJSObjectType || if (V8_LIKELY(instance_type == I::kJSObjectType ||
instance_type == I::kJSApiObjectType || instance_type == I::kJSApiObjectType ||
instance_type == I::kJSSpecialApiObjectType)) { instance_type == I::kJSSpecialApiObjectType)) {
int offset = I::kJSObjectHeaderSize + (I::kEmbedderSlotSize * index); int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
return I::ReadField<void*>(obj, offset); return I::ReadField<void*>(obj, offset);
} }
#endif #endif
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "src/objects-inl.h" #include "src/objects-inl.h"
#include "src/objects/api-callbacks.h" #include "src/objects/api-callbacks.h"
#include "src/objects/embedder-data-array-inl.h" #include "src/objects/embedder-data-array-inl.h"
#include "src/objects/embedder-data-slot-inl.h"
#include "src/objects/hash-table-inl.h" #include "src/objects/hash-table-inl.h"
#include "src/objects/heap-object.h" #include "src/objects/heap-object.h"
#include "src/objects/js-array-inl.h" #include "src/objects/js-array-inl.h"
...@@ -1198,6 +1199,8 @@ static i::Smi EncodeAlignedAsSmi(void* value, const char* location) { ...@@ -1198,6 +1199,8 @@ static i::Smi EncodeAlignedAsSmi(void* value, const char* location) {
return smi; return smi;
} }
STATIC_ASSERT(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context, static i::Handle<i::EmbedderDataArray> EmbedderDataFor(Context* context,
int index, bool can_grow, int index, bool can_grow,
const char* location) { const char* location) {
...@@ -1236,7 +1239,8 @@ v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) { ...@@ -1236,7 +1239,8 @@ v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
EmbedderDataFor(this, index, false, location); EmbedderDataFor(this, index, false, location);
if (data.is_null()) return Local<Value>(); if (data.is_null()) return Local<Value>();
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
i::Handle<i::Object> result(data->get(index), isolate); i::Handle<i::Object> result(i::EmbedderDataSlot(*data, index).load_tagged(),
isolate);
return Utils::ToLocal(result); return Utils::ToLocal(result);
} }
...@@ -1247,7 +1251,7 @@ void Context::SetEmbedderData(int index, v8::Local<Value> value) { ...@@ -1247,7 +1251,7 @@ void Context::SetEmbedderData(int index, v8::Local<Value> value) {
EmbedderDataFor(this, index, true, location); EmbedderDataFor(this, index, true, location);
if (data.is_null()) return; if (data.is_null()) return;
i::Handle<i::Object> val = Utils::OpenHandle(*value); i::Handle<i::Object> val = Utils::OpenHandle(*value);
data->set(index, *val); i::EmbedderDataSlot::store_tagged(*data, index, *val);
DCHECK_EQ(*Utils::OpenHandle(*value), DCHECK_EQ(*Utils::OpenHandle(*value),
*Utils::OpenHandle(*GetEmbedderData(index))); *Utils::OpenHandle(*GetEmbedderData(index)));
} }
...@@ -1258,7 +1262,10 @@ void* Context::SlowGetAlignedPointerFromEmbedderData(int index) { ...@@ -1258,7 +1262,10 @@ void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
i::Handle<i::EmbedderDataArray> data = i::Handle<i::EmbedderDataArray> data =
EmbedderDataFor(this, index, false, location); EmbedderDataFor(this, index, false, location);
if (data.is_null()) return nullptr; if (data.is_null()) return nullptr;
return DecodeSmiToAligned(data->get(index), location); void* result;
Utils::ApiCheck(i::EmbedderDataSlot(*data, index).ToAlignedPointer(&result),
location, "Pointer is not aligned");
return result;
} }
...@@ -1266,7 +1273,8 @@ void Context::SetAlignedPointerInEmbedderData(int index, void* value) { ...@@ -1266,7 +1273,8 @@ void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
const char* location = "v8::Context::SetAlignedPointerInEmbedderData()"; const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
i::Handle<i::EmbedderDataArray> data = i::Handle<i::EmbedderDataArray> data =
EmbedderDataFor(this, index, true, location); EmbedderDataFor(this, index, true, location);
data->set(index, EncodeAlignedAsSmi(value, location)); bool ok = i::EmbedderDataSlot(*data, index).store_aligned_pointer(value);
Utils::ApiCheck(ok, location, "Pointer is not aligned");
DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index)); DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
} }
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "src/objects/data-handler-inl.h" #include "src/objects/data-handler-inl.h"
#include "src/objects/debug-objects-inl.h" #include "src/objects/debug-objects-inl.h"
#include "src/objects/embedder-data-array-inl.h" #include "src/objects/embedder-data-array-inl.h"
#include "src/objects/embedder-data-slot-inl.h"
#include "src/objects/hash-table-inl.h" #include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-inl.h" #include "src/objects/js-array-inl.h"
#ifdef V8_INTL_SUPPORT #ifdef V8_INTL_SUPPORT
...@@ -680,8 +681,10 @@ void AliasedArgumentsEntry::AliasedArgumentsEntryVerify(Isolate* isolate) { ...@@ -680,8 +681,10 @@ void AliasedArgumentsEntry::AliasedArgumentsEntryVerify(Isolate* isolate) {
} }
void EmbedderDataArray::EmbedderDataArrayVerify(Isolate* isolate) { void EmbedderDataArray::EmbedderDataArrayVerify(Isolate* isolate) {
for (int i = 0; i < length(); i++) { EmbedderDataSlot start(*this, 0);
Object* e = get(i); EmbedderDataSlot end(*this, length());
for (EmbedderDataSlot slot = start; slot < end; ++slot) {
Object* e = slot.load_tagged();
Object::VerifyPointer(isolate, e); Object::VerifyPointer(isolate, e);
} }
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "src/objects/data-handler-inl.h" #include "src/objects/data-handler-inl.h"
#include "src/objects/debug-objects-inl.h" #include "src/objects/debug-objects-inl.h"
#include "src/objects/embedder-data-array-inl.h" #include "src/objects/embedder-data-array-inl.h"
#include "src/objects/embedder-data-slot-inl.h"
#include "src/objects/hash-table-inl.h" #include "src/objects/hash-table-inl.h"
#include "src/objects/js-array-buffer-inl.h" #include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h" #include "src/objects/js-array-inl.h"
...@@ -635,6 +636,16 @@ void PrintEmbedderData(std::ostream& os, ObjectSlot slot) { ...@@ -635,6 +636,16 @@ void PrintEmbedderData(std::ostream& os, ObjectSlot slot) {
} }
} }
void PrintEmbedderData(std::ostream& os, EmbedderDataSlot slot) {
DisallowHeapAllocation no_gc;
Object* value = slot.load_tagged();
os << Brief(value);
void* raw_pointer;
if (slot.ToAlignedPointer(&raw_pointer)) {
os << ", aligned pointer: " << raw_pointer;
}
}
} // namespace } // namespace
void JSObject::PrintElements(std::ostream& os) { // NOLINT void JSObject::PrintElements(std::ostream& os) { // NOLINT
...@@ -728,9 +739,8 @@ static void JSObjectPrintBody(std::ostream& os, ...@@ -728,9 +739,8 @@ static void JSObjectPrintBody(std::ostream& os,
if (embedder_fields > 0) { if (embedder_fields > 0) {
os << " - embedder fields = {"; os << " - embedder fields = {";
for (int i = 0; i < embedder_fields; i++) { for (int i = 0; i < embedder_fields; i++) {
ObjectSlot embedder_data_slot = obj->GetEmbedderFieldSlot(i);
os << "\n "; os << "\n ";
PrintEmbedderData(os, embedder_data_slot); PrintEmbedderData(os, obj->GetEmbedderFieldSlot(i));
} }
os << "\n }\n"; os << "\n }\n";
} }
...@@ -994,9 +1004,9 @@ void PrintWeakArrayElements(std::ostream& os, T* array) { ...@@ -994,9 +1004,9 @@ void PrintWeakArrayElements(std::ostream& os, T* array) {
void EmbedderDataArray::EmbedderDataArrayPrint(std::ostream& os) { void EmbedderDataArray::EmbedderDataArrayPrint(std::ostream& os) {
PrintHeader(os, "EmbedderDataArray"); PrintHeader(os, "EmbedderDataArray");
os << "\n - length: " << length(); os << "\n - length: " << length();
ObjectSlot start(slots_start()); EmbedderDataSlot start(*this, 0);
ObjectSlot end(slots_end()); EmbedderDataSlot end(*this, length());
for (ObjectSlot slot = start; slot < end; ++slot) { for (EmbedderDataSlot slot = start; slot < end; ++slot) {
os << "\n "; os << "\n ";
PrintEmbedderData(os, slot); PrintEmbedderData(os, slot);
} }
......
...@@ -31,27 +31,6 @@ Address EmbedderDataArray::slots_end() { ...@@ -31,27 +31,6 @@ Address EmbedderDataArray::slots_end() {
return FIELD_ADDR(this, OffsetOfElementAt(length())); return FIELD_ADDR(this, OffsetOfElementAt(length()));
} }
Object* EmbedderDataArray::get(int index) const {
DCHECK_LT(static_cast<unsigned>(index),
static_cast<unsigned>(this->length()));
return RELAXED_READ_FIELD(this, OffsetOfElementAt(index));
}
void EmbedderDataArray::set(int index, Smi value) {
DCHECK_LT(static_cast<unsigned>(index),
static_cast<unsigned>(this->length()));
DCHECK(ObjectPtr(value).IsSmi());
RELAXED_WRITE_FIELD(this, OffsetOfElementAt(index), value);
}
void EmbedderDataArray::set(int index, Object* value) {
DCHECK_LT(static_cast<unsigned>(index),
static_cast<unsigned>(this->length()));
int offset = OffsetOfElementAt(index);
RELAXED_WRITE_FIELD(this, offset, value);
WRITE_BARRIER(this, offset, value);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "src/maybe-handles.h" #include "src/maybe-handles.h"
#include "src/objects.h" #include "src/objects.h"
#include "src/objects/embedder-data-slot.h"
// Has to be the last include (doesn't have include guards): // Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h" #include "src/objects/object-macros.h"
...@@ -47,12 +48,6 @@ class EmbedderDataArray : public HeapObjectPtr { ...@@ -47,12 +48,6 @@ class EmbedderDataArray : public HeapObjectPtr {
// Code Generation support. // Code Generation support.
static constexpr int OffsetOfElementAt(int index) { return SizeFor(index); } static constexpr int OffsetOfElementAt(int index) { return SizeFor(index); }
// TODO(ishell): remove these accessors once EmbedderDataSlot is introduced.
// Setter and getter for elements.
V8_INLINE Object* get(int index) const;
V8_INLINE void set(int index, Object* value);
V8_INLINE void set(int index, Smi value);
// Address of the first slot. // Address of the first slot.
V8_INLINE Address slots_start(); V8_INLINE Address slots_start();
...@@ -65,8 +60,6 @@ class EmbedderDataArray : public HeapObjectPtr { ...@@ -65,8 +60,6 @@ class EmbedderDataArray : public HeapObjectPtr {
class BodyDescriptor; class BodyDescriptor;
static constexpr int kEmbedderDataSlotSize = kPointerSize;
static const int kMaxSize = kMaxNewSpaceHeapObjectSize; static const int kMaxSize = kMaxNewSpaceHeapObjectSize;
static constexpr int kMaxLength = static constexpr int kMaxLength =
(kMaxSize - kHeaderSize) / kEmbedderDataSlotSize; (kMaxSize - kHeaderSize) / kEmbedderDataSlotSize;
......
// 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_EMBEDDER_DATA_SLOT_INL_H_
#define V8_OBJECTS_EMBEDDER_DATA_SLOT_INL_H_
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/embedder-data-array.h"
#include "src/objects/embedder-data-slot.h"
#include "src/objects/js-objects.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
EmbedderDataSlot::EmbedderDataSlot(EmbedderDataArray array, int entry_index)
: SlotBase(FIELD_ADDR(array,
EmbedderDataArray::OffsetOfElementAt(entry_index))) {}
EmbedderDataSlot::EmbedderDataSlot(JSObject* object, int embedder_field_index)
: SlotBase(FIELD_ADDR(
object, object->GetEmbedderFieldOffset(embedder_field_index))) {}
Object* EmbedderDataSlot::load_tagged() const {
return ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Load();
}
void EmbedderDataSlot::store_smi(Smi value) {
ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Store(value);
}
// static
void EmbedderDataSlot::store_tagged(EmbedderDataArray array, int entry_index,
Object* value) {
int slot_offset = EmbedderDataArray::OffsetOfElementAt(entry_index);
ObjectSlot(FIELD_ADDR(array, slot_offset + kTaggedPayloadOffset))
.Relaxed_Store(ObjectPtr(value->ptr()));
WRITE_BARRIER(array, slot_offset, value);
}
// static
void EmbedderDataSlot::store_tagged(JSObject* object, int embedder_field_index,
Object* value) {
int slot_offset = object->GetEmbedderFieldOffset(embedder_field_index);
ObjectSlot(FIELD_ADDR(object, slot_offset + kTaggedPayloadOffset))
.Relaxed_Store(ObjectPtr(value->ptr()));
WRITE_BARRIER(object, slot_offset, value);
}
bool EmbedderDataSlot::ToAlignedPointer(void** out_pointer) const {
Object* tagged_value =
ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Load();
if (!tagged_value->IsSmi()) return false;
*out_pointer = reinterpret_cast<void*>(tagged_value);
return true;
}
bool EmbedderDataSlot::store_aligned_pointer(void* ptr) {
Address value = reinterpret_cast<Address>(ptr);
if (!HAS_SMI_TAG(value)) return false;
ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Store(Smi(value));
return true;
}
EmbedderDataSlot::RawData EmbedderDataSlot::load_raw(
const DisallowHeapAllocation& no_gc) const {
return RawData{
ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Load()->ptr(),
};
}
void EmbedderDataSlot::store_raw(const EmbedderDataSlot::RawData& data,
const DisallowHeapAllocation& no_gc) {
ObjectSlot(address() + kTaggedPayloadOffset)
.Relaxed_Store(ObjectPtr(data.data_[0]));
}
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_EMBEDDER_DATA_SLOT_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_EMBEDDER_DATA_SLOT_H_
#define V8_OBJECTS_EMBEDDER_DATA_SLOT_H_
#include <utility>
#include "src/objects/fixed-array.h"
#include "src/objects/heap-object.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
namespace v8 {
namespace internal {
static constexpr int kEmbedderDataSlotSize = kTaggedSize;
static constexpr int kEmbedderDataSlotSizeInTaggedSlots =
kEmbedderDataSlotSize / kTaggedSize;
class EmbedderDataArray;
// An EmbedderDataSlot instance describes a kEmbedderDataSlotSize field ("slot")
// holding an embedder data which may contain raw aligned pointer or a tagged
// pointer (smi or heap object).
// Its address() is the address of the slot.
// The slot's contents can be read and written using respective load_XX() and
// store_XX() methods.
// Storing heap object through this slot may require triggering write barriers
// so this operation must be done via static store_tagged() methods.
class EmbedderDataSlot
: public SlotBase<EmbedderDataSlot, kEmbedderDataSlotSize> {
public:
EmbedderDataSlot() : SlotBase(kNullAddress) {}
V8_INLINE EmbedderDataSlot(EmbedderDataArray array, int entry_index);
V8_INLINE EmbedderDataSlot(JSObject* object, int embedder_field_index);
#ifdef V8_COMPRESS_POINTERS
static constexpr int kRawPayloadOffset = kTaggedSize;
#endif
static constexpr int kTaggedPayloadOffset = 0;
static constexpr int kRequiredPtrAlignment = kSmiTagSize;
// Opaque type used for storing raw embedder data.
struct RawData {
const Address data_[kEmbedderDataSlotSizeInTaggedSlots];
};
V8_INLINE Object* load_tagged() const;
V8_INLINE void store_smi(Smi value);
// Setting an arbitrary tagged value requires triggering a write barrier
// which requires separate object and offset values, therefore these static
// functions a
static V8_INLINE void store_tagged(EmbedderDataArray array, int entry_index,
Object* value);
static V8_INLINE void store_tagged(JSObject* object, int embedder_field_index,
Object* value);
// Tries reinterpret the value as an aligned pointer and on success sets
// *out_result to the pointer-like value and returns true. Note, that some
// Smis could still look like an aligned pointers.
// Returns false otherwise.
V8_INLINE bool ToAlignedPointer(void** out_result) const;
// Returns true if the pointer was successfully stored or false it the pointer
// was improperly aligned.
V8_INLINE V8_WARN_UNUSED_RESULT bool store_aligned_pointer(void* ptr);
V8_INLINE RawData load_raw(const DisallowHeapAllocation& no_gc) const;
V8_INLINE void store_raw(const RawData& data,
const DisallowHeapAllocation& no_gc);
};
} // namespace internal
} // namespace v8
#include "src/objects/object-macros-undef.h"
#endif // V8_OBJECTS_EMBEDDER_DATA_SLOT_H_
...@@ -2760,7 +2760,8 @@ TEST(InternalFieldsSubclassing) { ...@@ -2760,7 +2760,8 @@ TEST(InternalFieldsSubclassing) {
.FromJust()); .FromJust());
// Create various levels of subclasses to stress instance size calculation. // Create various levels of subclasses to stress instance size calculation.
const int kMaxNofProperties = const int kMaxNofProperties =
i::JSObject::kMaxInObjectProperties - nof_embedder_fields; i::JSObject::kMaxInObjectProperties -
nof_embedder_fields * i::kEmbedderDataSlotSizeInTaggedSlots;
// Select only a few values to speed up the test. // Select only a few values to speed up the test.
int sizes[] = {0, int sizes[] = {0,
1, 1,
...@@ -2869,7 +2870,7 @@ THREADED_TEST(GlobalObjectHasRealIndexedProperty) { ...@@ -2869,7 +2870,7 @@ THREADED_TEST(GlobalObjectHasRealIndexedProperty) {
static void CheckAlignedPointerInInternalField(Local<v8::Object> obj, static void CheckAlignedPointerInInternalField(Local<v8::Object> obj,
void* value) { void* value) {
CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1)); CHECK(HAS_SMI_TAG(reinterpret_cast<i::Address>(value)));
obj->SetAlignedPointerInInternalField(0, value); obj->SetAlignedPointerInInternalField(0, value);
CcTest::CollectAllGarbage(); CcTest::CollectAllGarbage();
CHECK_EQ(value, obj->GetAlignedPointerFromInternalField(0)); CHECK_EQ(value, obj->GetAlignedPointerFromInternalField(0));
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