Commit a2f18248 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[ubsan] Replace internal::Object references in v8.h

with internal::Address. This is in preparation for the upcoming
changes to internal::Object. The public API is unchanged, and
there should be no change in behavior either.

Most of the casts newly introduced here will disappear again once
the migration is complete.

Bug: v8:3770
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: I2990b06a2511ccc5de3f98fd95a805f30ed589ab
Reviewed-on: https://chromium-review.googlesource.com/c/1036612Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56705}
parent db6db6ed
......@@ -20,7 +20,8 @@ class Isolate;
namespace internal {
class Object;
typedef uintptr_t Address;
static const Address kNullAddress = 0;
/**
* Configuration of tagging scheme.
......@@ -45,11 +46,11 @@ template <size_t tagged_ptr_size>
struct SmiTagging;
template <int kSmiShiftSize>
V8_INLINE internal::Object* IntToSmi(int value) {
V8_INLINE internal::Address IntToSmi(int value) {
int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
intptr_t tagged_value =
(static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
return reinterpret_cast<internal::Object*>(tagged_value);
uintptr_t tagged_value =
(static_cast<uintptr_t>(value) << smi_shift_bits) | kSmiTag;
return static_cast<internal::Address>(tagged_value);
}
// Smi constants for systems where tagged pointer is a 32-bit value.
......@@ -58,19 +59,19 @@ struct SmiTagging<4> {
enum { kSmiShiftSize = 0, kSmiValueSize = 31 };
static int SmiShiftSize() { return kSmiShiftSize; }
static int SmiValueSize() { return kSmiValueSize; }
V8_INLINE static int SmiToInt(const internal::Object* value) {
V8_INLINE static int SmiToInt(const internal::Address value) {
int shift_bits = kSmiTagSize + kSmiShiftSize;
// Throw away top 32 bits and shift down (requires >> to be sign extending).
return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits;
// Shift down (requires >> to be sign extending).
return static_cast<int>(static_cast<intptr_t>(value)) >> shift_bits;
}
V8_INLINE static internal::Object* IntToSmi(int value) {
V8_INLINE static internal::Address IntToSmi(int value) {
return internal::IntToSmi<kSmiShiftSize>(value);
}
V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
// To be representable as an tagged small integer, the two
// most-significant bits of 'value' must be either 00 or 11 due to
// sign-extension. To check this we add 01 to the two
// most-significant bits, and check if the most-significant bit is 0
// most-significant bits, and check if the most-significant bit is 0.
//
// CAUTION: The original code below:
// bool result = ((value + 0x40000000) & 0x80000000) == 0;
......@@ -88,12 +89,12 @@ struct SmiTagging<8> {
enum { kSmiShiftSize = 31, kSmiValueSize = 32 };
static int SmiShiftSize() { return kSmiShiftSize; }
static int SmiValueSize() { return kSmiValueSize; }
V8_INLINE static int SmiToInt(const internal::Object* value) {
V8_INLINE static int SmiToInt(const internal::Address value) {
int shift_bits = kSmiTagSize + kSmiShiftSize;
// Shift down and throw away top 32 bits.
return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits);
return static_cast<int>(static_cast<intptr_t>(value) >> shift_bits);
}
V8_INLINE static internal::Object* IntToSmi(int value) {
V8_INLINE static internal::Address IntToSmi(int value) {
return internal::IntToSmi<kSmiShiftSize>(value);
}
V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
......@@ -191,16 +192,15 @@ class Internals {
#endif
}
V8_INLINE static bool HasHeapObjectTag(const internal::Object* value) {
return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) ==
kHeapObjectTag);
V8_INLINE static bool HasHeapObjectTag(const internal::Address value) {
return (value & kHeapObjectTagMask) == static_cast<Address>(kHeapObjectTag);
}
V8_INLINE static int SmiValue(const internal::Object* value) {
V8_INLINE static int SmiValue(const internal::Address value) {
return PlatformSmiTagging::SmiToInt(value);
}
V8_INLINE static internal::Object* IntToSmi(int value) {
V8_INLINE static internal::Address IntToSmi(int value) {
return PlatformSmiTagging::IntToSmi(value);
}
......@@ -208,15 +208,14 @@ class Internals {
return PlatformSmiTagging::IsValidSmi(value);
}
V8_INLINE static int GetInstanceType(const internal::Object* obj) {
typedef internal::Object O;
O* map = ReadField<O*>(obj, kHeapObjectMapOffset);
V8_INLINE static int GetInstanceType(const internal::Address obj) {
typedef internal::Address A;
A map = ReadField<A>(obj, kHeapObjectMapOffset);
return ReadField<uint16_t>(map, kMapInstanceTypeOffset);
}
V8_INLINE static int GetOddballKind(const internal::Object* obj) {
typedef internal::Object O;
return SmiValue(ReadField<O*>(obj, kOddballKindOffset));
V8_INLINE static int GetOddballKind(const internal::Address obj) {
return SmiValue(ReadField<internal::Address>(obj, kOddballKindOffset));
}
V8_INLINE static bool IsExternalTwoByteString(int instance_type) {
......@@ -224,63 +223,66 @@ class Internals {
return representation == kExternalTwoByteRepresentationTag;
}
V8_INLINE static uint8_t GetNodeFlag(internal::Object** obj, int shift) {
V8_INLINE static uint8_t GetNodeFlag(internal::Address* obj, int shift) {
uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
return *addr & static_cast<uint8_t>(1U << shift);
}
V8_INLINE static void UpdateNodeFlag(internal::Object** obj, bool value,
V8_INLINE static void UpdateNodeFlag(internal::Address* obj, bool value,
int shift) {
uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
uint8_t mask = static_cast<uint8_t>(1U << shift);
*addr = static_cast<uint8_t>((*addr & ~mask) | (value << shift));
}
V8_INLINE static uint8_t GetNodeState(internal::Object** obj) {
V8_INLINE static uint8_t GetNodeState(internal::Address* obj) {
uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
return *addr & kNodeStateMask;
}
V8_INLINE static void UpdateNodeState(internal::Object** obj, uint8_t value) {
V8_INLINE static void UpdateNodeState(internal::Address* obj, uint8_t value) {
uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset;
*addr = static_cast<uint8_t>((*addr & ~kNodeStateMask) | value);
}
V8_INLINE static void SetEmbedderData(v8::Isolate* isolate, uint32_t slot,
void* data) {
uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) +
kIsolateEmbedderDataOffset + slot * kApiPointerSize;
internal::Address addr = reinterpret_cast<internal::Address>(isolate) +
kIsolateEmbedderDataOffset +
slot * kApiPointerSize;
*reinterpret_cast<void**>(addr) = data;
}
V8_INLINE static void* GetEmbedderData(const v8::Isolate* isolate,
uint32_t slot) {
const uint8_t* addr = reinterpret_cast<const uint8_t*>(isolate) +
kIsolateEmbedderDataOffset + slot * kApiPointerSize;
internal::Address addr = reinterpret_cast<internal::Address>(isolate) +
kIsolateEmbedderDataOffset +
slot * kApiPointerSize;
return *reinterpret_cast<void* const*>(addr);
}
V8_INLINE static internal::Object** GetRoot(v8::Isolate* isolate, int index) {
uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + kIsolateRootsOffset;
return reinterpret_cast<internal::Object**>(addr + index * kApiPointerSize);
V8_INLINE static internal::Address* GetRoot(v8::Isolate* isolate, int index) {
internal::Address addr =
reinterpret_cast<internal::Address>(isolate) + kIsolateRootsOffset;
return reinterpret_cast<internal::Address*>(addr + index * kApiPointerSize);
}
template <typename T>
V8_INLINE static T ReadField(const internal::Object* ptr, int offset) {
const uint8_t* addr =
reinterpret_cast<const uint8_t*>(ptr) + offset - kHeapObjectTag;
V8_INLINE static T ReadField(const internal::Address heap_object_ptr,
int offset) {
internal::Address addr = heap_object_ptr + offset - kHeapObjectTag;
return *reinterpret_cast<const T*>(addr);
}
template <typename T>
V8_INLINE static T ReadEmbedderData(const v8::Context* context, int index) {
typedef internal::Object O;
typedef internal::Address A;
typedef internal::Internals I;
O* ctx = *reinterpret_cast<O* const*>(context);
A ctx = *reinterpret_cast<const A*>(context);
int embedder_data_offset =
I::kContextHeaderSize +
(internal::kApiPointerSize * I::kContextEmbedderDataIndex);
O* embedder_data = I::ReadField<O*>(ctx, embedder_data_offset);
A embedder_data = I::ReadField<A>(ctx, embedder_data_offset);
int value_offset =
I::kFixedArrayHeaderSize + (internal::kApiPointerSize * index);
return I::ReadField<T>(embedder_data, value_offset);
......
......@@ -29,9 +29,8 @@ enum PersistentContainerCallbackType {
kWeak = kWeakWithParameter // For backwards compatibility. Deprecate.
};
/**
* A default trait implemenation for PersistentValueMap which uses std::map
* A default trait implementation for PersistentValueMap which uses std::map
* as a backing map.
*
* Users will have to implement their own weak callbacks & dispose traits.
......@@ -203,7 +202,7 @@ class PersistentValueMapBase {
void RegisterExternallyReferencedObject(K& key) {
assert(Contains(key));
V8::RegisterExternallyReferencedObject(
reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))),
reinterpret_cast<internal::Address*>(FromVal(Traits::Get(&impl_, key))),
reinterpret_cast<internal::Isolate*>(GetIsolate()));
}
......@@ -340,7 +339,7 @@ class PersistentValueMapBase {
bool hasValue = value != kPersistentContainerNotFound;
if (hasValue) {
returnValue->SetInternal(
*reinterpret_cast<internal::Object**>(FromVal(value)));
*reinterpret_cast<internal::Address*>(FromVal(value)));
}
return hasValue;
}
......
This diff is collapsed.
......@@ -61,7 +61,8 @@ inline JSObject* FunctionCallbackArguments::holder() {
} \
VMState<EXTERNAL> state(ISOLATE); \
ExternalCallbackScope call_scope(ISOLATE, FUNCTION_ADDR(F)); \
PropertyCallbackInfo<API_RETURN_TYPE> callback_info(begin());
PropertyCallbackInfo<API_RETURN_TYPE> callback_info( \
reinterpret_cast<Address*>(begin()));
#define PREPARE_CALLBACK_INFO_FAIL_SIDE_EFFECT_CHECK(ISOLATE, F, RETURN_VALUE, \
API_RETURN_TYPE) \
......@@ -70,7 +71,8 @@ inline JSObject* FunctionCallbackArguments::holder() {
} \
VMState<EXTERNAL> state(ISOLATE); \
ExternalCallbackScope call_scope(ISOLATE, FUNCTION_ADDR(F)); \
PropertyCallbackInfo<API_RETURN_TYPE> callback_info(begin());
PropertyCallbackInfo<API_RETURN_TYPE> callback_info( \
reinterpret_cast<Address*>(begin()));
#define CREATE_NAMED_CALLBACK(FUNCTION, TYPE, RETURN_TYPE, API_RETURN_TYPE, \
INFO_FOR_SIDE_EFFECT) \
......@@ -136,7 +138,9 @@ Handle<Object> FunctionCallbackArguments::Call(CallHandlerInfo* handler) {
}
VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
FunctionCallbackInfo<v8::Value> info(begin(), argv_, argc_);
FunctionCallbackInfo<v8::Value> info(reinterpret_cast<Address*>(begin()),
reinterpret_cast<Address*>(argv_),
argc_);
f(info);
return GetReturnValue<Object>(isolate);
}
......
This diff is collapsed.
......@@ -537,24 +537,31 @@ Handle<Object> GlobalHandles::Create(Object* value) {
return result->handle();
}
Handle<Object> GlobalHandles::Create(Address value) {
return Create(reinterpret_cast<Object*>(value));
}
Handle<Object> GlobalHandles::CopyGlobal(Object** location) {
Handle<Object> GlobalHandles::CopyGlobal(Address* location) {
DCHECK_NOT_NULL(location);
GlobalHandles* global_handles =
Node::FromLocation(location)->GetGlobalHandles();
Node::FromLocation(reinterpret_cast<Object**>(location))
->GetGlobalHandles();
#ifdef VERIFY_HEAP
if (i::FLAG_verify_heap) {
(*location)->ObjectVerify(global_handles->isolate());
(*reinterpret_cast<Object**>(location))
->ObjectVerify(global_handles->isolate());
}
#endif // VERIFY_HEAP
return global_handles->Create(*location);
}
void GlobalHandles::Destroy(Object** location) {
if (location != nullptr) Node::FromLocation(location)->Release();
}
void GlobalHandles::Destroy(Address* location) {
Destroy(reinterpret_cast<Object**>(location));
}
typedef v8::WeakCallbackInfo<void>::Callback GenericCallback;
......@@ -565,12 +572,24 @@ void GlobalHandles::MakeWeak(Object** location, void* parameter,
Node::FromLocation(location)->MakeWeak(parameter, phantom_callback, type);
}
void GlobalHandles::MakeWeak(Address* location, void* parameter,
GenericCallback phantom_callback,
v8::WeakCallbackType type) {
Node::FromLocation(reinterpret_cast<Object**>(location))
->MakeWeak(parameter, phantom_callback, type);
}
void GlobalHandles::MakeWeak(Object*** location_addr) {
Node::FromLocation(*location_addr)->MakeWeak(location_addr);
}
void* GlobalHandles::ClearWeakness(Object** location) {
return Node::FromLocation(location)->ClearWeakness();
void GlobalHandles::MakeWeak(Address** location_addr) {
MakeWeak(reinterpret_cast<Object***>(location_addr));
}
void* GlobalHandles::ClearWeakness(Address* location) {
return Node::FromLocation(reinterpret_cast<Object**>(location))
->ClearWeakness();
}
void GlobalHandles::AnnotateStrongRetainer(Object** location,
......@@ -578,6 +597,12 @@ void GlobalHandles::AnnotateStrongRetainer(Object** location,
Node::FromLocation(location)->AnnotateStrongRetainer(label);
}
void GlobalHandles::AnnotateStrongRetainer(Address* location,
const char* label) {
Node::FromLocation(reinterpret_cast<Object**>(location))
->AnnotateStrongRetainer(label);
}
bool GlobalHandles::IsNearDeath(Object** location) {
return Node::FromLocation(location)->IsNearDeath();
}
......
......@@ -47,6 +47,9 @@ class GlobalHandles {
// Creates a new global handle that is alive until Destroy is called.
Handle<Object> Create(Object* value);
// TODO(jkummerow): This and the other Object*/Address overloads below are
// temporary. Eventually the respective Object* version should go away.
Handle<Object> Create(Address value);
template <typename T>
Handle<T> Create(T* value) {
......@@ -57,10 +60,11 @@ class GlobalHandles {
}
// Copy a global handle
static Handle<Object> CopyGlobal(Object** location);
static Handle<Object> CopyGlobal(Address* location);
// Destroy a global handle.
static void Destroy(Object** location);
static void Destroy(Address* location);
// Make the global handle weak and set the callback parameter for the
// handle. When the garbage collector recognizes that only weak global
......@@ -74,10 +78,15 @@ class GlobalHandles {
static void MakeWeak(Object** location, void* parameter,
WeakCallbackInfo<void>::Callback weak_callback,
v8::WeakCallbackType type);
static void MakeWeak(Address* location, void* parameter,
WeakCallbackInfo<void>::Callback weak_callback,
v8::WeakCallbackType type);
static void MakeWeak(Object*** location_addr);
static void MakeWeak(Address** location_addr);
static void AnnotateStrongRetainer(Object** location, const char* label);
static void AnnotateStrongRetainer(Address* location, const char* label);
void RecordStats(HeapStats* stats);
......@@ -97,12 +106,14 @@ class GlobalHandles {
size_t NumberOfNewSpaceNodes() { return new_space_nodes_.size(); }
// Clear the weakness of a global handle.
static void* ClearWeakness(Object** location);
static void* ClearWeakness(Address* location);
// Tells whether global handle is near death.
// TODO(jkummerow): This seems to be unused.
static bool IsNearDeath(Object** location);
// Tells whether global handle is weak.
// TODO(jkummerow): This seems to be unused.
static bool IsWeak(Object** location);
// Process pending weak handles.
......
......@@ -96,8 +96,6 @@ class AllStatic {
};
typedef uint8_t byte;
typedef uintptr_t Address;
static const Address kNullAddress = 0;
// -----------------------------------------------------------------------------
// Constants
......
......@@ -122,6 +122,22 @@ Object** HandleScope::CreateHandle(Isolate* isolate, Object* value) {
return result;
}
Address* HandleScope::CreateHandle(Isolate* isolate, Address value_address) {
DCHECK(AllowHandleAllocation::IsAllowed());
HandleScopeData* data = isolate->handle_scope_data();
Address* result = reinterpret_cast<Address*>(data->next);
if (result == reinterpret_cast<Address*>(data->limit)) {
result = reinterpret_cast<Address*>(Extend(isolate));
}
// Update the current next field, set the value in the created handle,
// and return the result.
DCHECK_LT(reinterpret_cast<Address>(result),
reinterpret_cast<Address>(data->limit));
data->next = reinterpret_cast<Object**>(reinterpret_cast<Address>(result) +
sizeof(Address));
*result = value_address;
return result;
}
Object** HandleScope::GetHandle(Isolate* isolate, Object* value) {
DCHECK(AllowHandleAllocation::IsAllowed());
......
......@@ -121,6 +121,11 @@ class Handle final : public HandleBase {
V8_INLINE T** location() const {
return reinterpret_cast<T**>(HandleBase::location());
}
// TODO(jkummerow): This is temporary; eventually location() should
// return an Address*.
V8_INLINE Address* location_as_address_ptr() const {
return reinterpret_cast<Address*>(HandleBase::location());
}
template <typename S>
inline static const Handle<T> cast(Handle<S> that);
......@@ -185,6 +190,8 @@ class HandleScope {
// Creates a new handle with the given value.
V8_INLINE static Object** CreateHandle(Isolate* isolate, Object* value);
V8_INLINE static Address* CreateHandle(Isolate* isolate,
Address value_address);
// Deallocates any extensions used by the current scope.
V8_EXPORT_PRIVATE static void DeleteExtensions(Isolate* isolate);
......
......@@ -3652,7 +3652,7 @@ Address Heap::builtin_address(int index) {
void Heap::set_builtin(int index, HeapObject* builtin) {
DCHECK(Builtins::IsBuiltinId(index));
DCHECK(Internals::HasHeapObjectTag(builtin));
DCHECK(Internals::HasHeapObjectTag(reinterpret_cast<Address>(builtin)));
// The given builtin may be completely uninitialized thus we cannot check its
// type here.
builtins_table()[index] = builtin;
......@@ -4490,11 +4490,12 @@ void Heap::TracePossibleWrapper(JSObject* js_object) {
}
}
void Heap::RegisterExternallyReferencedObject(Object** object) {
void Heap::RegisterExternallyReferencedObject(Address* location) {
// The embedder is not aware of whether numbers are materialized as heap
// objects are just passed around as Smis.
if (!(*object)->IsHeapObject()) return;
HeapObject* heap_object = HeapObject::cast(*object);
Object* object = *reinterpret_cast<Object**>(location);
if (!object->IsHeapObject()) return;
HeapObject* heap_object = HeapObject::cast(object);
DCHECK(Contains(heap_object));
if (FLAG_incremental_marking_wrappers && incremental_marking()->IsMarking()) {
incremental_marking()->WhiteToGreyAndPush(heap_object);
......
......@@ -873,7 +873,7 @@ class Heap {
EmbedderHeapTracer* GetEmbedderHeapTracer() const;
void TracePossibleWrapper(JSObject* js_object);
void RegisterExternallyReferencedObject(Object** object);
void RegisterExternallyReferencedObject(Address* location);
void SetEmbedderStackStateForNextFinalizaton(
EmbedderHeapTracer::EmbedderStackState stack_state);
......
......@@ -1464,7 +1464,8 @@ class Object {
// In objects.h to be usable without objects-inl.h inclusion.
bool Object::IsSmi() const { return HAS_SMI_TAG(this); }
bool Object::IsHeapObject() const {
DCHECK_EQ(!IsSmi(), Internals::HasHeapObjectTag(this));
DCHECK_EQ(!IsSmi(),
Internals::HasHeapObjectTag(reinterpret_cast<Address>(this)));
return !IsSmi();
}
......@@ -1485,7 +1486,9 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, const Brief& v);
class Smi: public Object {
public:
// Returns the integer value.
inline int value() const { return Internals::SmiValue(this); }
inline int value() const {
return Internals::SmiValue(reinterpret_cast<Address>(this));
}
inline Smi* ToUint32Smi() {
if (value() <= 0) return Smi::kZero;
return Smi::FromInt(static_cast<uint32_t>(value()));
......
......@@ -130,7 +130,7 @@ class HeapObjectReference : public MaybeObject {
static void Update(HeapObjectReference** slot, HeapObject* value) {
DCHECK(!HAS_SMI_TAG(*slot));
DCHECK(Internals::HasHeapObjectTag(value));
DCHECK(Internals::HasHeapObjectTag(reinterpret_cast<Address>(value)));
#ifdef DEBUG
bool weak_before = HasWeakHeapObjectTag(*slot);
......
......@@ -265,7 +265,8 @@ bool TickSample::GetStackSample(Isolate* v8_isolate, RegisterState* regs,
if (HAS_HEAP_OBJECT_TAG(bytecode_array) && HAS_SMI_TAG(bytecode_offset)) {
frames[i++] = reinterpret_cast<void*>(
reinterpret_cast<i::Address>(bytecode_array) +
i::Internals::SmiValue(bytecode_offset));
i::Internals::SmiValue(
reinterpret_cast<i::Address>(bytecode_offset)));
continue;
}
}
......
......@@ -31,7 +31,7 @@ Address BuiltinDeserializerAllocator::Allocate(AllocationSpace space,
DCHECK(Builtins::IsBuiltinId(code_object_id));
Object* obj = isolate()->builtins()->builtin(code_object_id);
DCHECK(Internals::HasHeapObjectTag(obj));
DCHECK(Internals::HasHeapObjectTag(reinterpret_cast<Address>(obj)));
return HeapObject::cast(obj)->address();
}
......
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