Commit 5c46c24d authored by Jakob Kummerow's avatar Jakob Kummerow Committed by Commit Bot

[ubsan] Use Address type inside of IdentityMap and HandleBase

This refactors the innards of HandleBase and IdentityMap
to use Address instead of Object*, as part of the quest
to get rid of Object* entirely.

Bug: v8:3770
Change-Id: I82bd9547ef0d208b1e42636792e21c9064af4cea
Reviewed-on: https://chromium-review.googlesource.com/c/1285396
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56797}
parent aa302310
......@@ -65,6 +65,9 @@ class RootIndexMap {
}
return false;
}
bool Lookup(Address obj, RootIndex* out_root_list) {
return Lookup(reinterpret_cast<HeapObject*>(obj), out_root_list);
}
private:
HeapObjectToIndexHashMap* map_;
......
......@@ -12,22 +12,21 @@
namespace v8 {
namespace internal {
HandleBase::HandleBase(Object* object, Isolate* isolate)
HandleBase::HandleBase(Address object, Isolate* isolate)
: location_(HandleScope::GetHandle(isolate, object)) {}
template <typename T>
// Allocate a new handle for the object, do not canonicalize.
template <typename T>
Handle<T> Handle<T>::New(T* object, Isolate* isolate) {
return Handle(
reinterpret_cast<T**>(HandleScope::CreateHandle(isolate, object)));
return Handle(reinterpret_cast<T**>(
HandleScope::CreateHandle(isolate, reinterpret_cast<Address>(object))));
}
template <typename T>
template <typename S>
const Handle<T> Handle<T>::cast(Handle<S> that) {
T::cast(*reinterpret_cast<T**>(that.location()));
return Handle<T>(reinterpret_cast<T**>(that.location_));
return Handle<T>(that.location_);
}
HandleScope::HandleScope(Isolate* isolate) {
......@@ -39,7 +38,8 @@ HandleScope::HandleScope(Isolate* isolate) {
}
template <typename T>
Handle<T>::Handle(T* object, Isolate* isolate) : HandleBase(object, isolate) {}
Handle<T>::Handle(T* object, Isolate* isolate)
: HandleBase(reinterpret_cast<Address>(object), isolate) {}
template <typename T>
V8_INLINE Handle<T> handle(T* object, Isolate* isolate) {
......@@ -107,22 +107,7 @@ Handle<T> HandleScope::CloseAndEscape(Handle<T> handle_value) {
return result;
}
Object** HandleScope::CreateHandle(Isolate* isolate, Object* value) {
DCHECK(AllowHandleAllocation::IsAllowed());
HandleScopeData* data = isolate->handle_scope_data();
Object** result = data->next;
if (result == data->limit) result = Extend(isolate);
// Update the current next field, set the value in the created
// handle, and return the result.
DCHECK(result < data->limit);
data->next = result + 1;
*result = value;
return result;
}
Address* HandleScope::CreateHandle(Isolate* isolate, Address value_address) {
Address* HandleScope::CreateHandle(Isolate* isolate, Address value) {
DCHECK(AllowHandleAllocation::IsAllowed());
HandleScopeData* data = isolate->handle_scope_data();
Address* result = reinterpret_cast<Address*>(data->next);
......@@ -135,11 +120,11 @@ Address* HandleScope::CreateHandle(Isolate* isolate, Address value_address) {
reinterpret_cast<Address>(data->limit));
data->next = reinterpret_cast<Object**>(reinterpret_cast<Address>(result) +
sizeof(Address));
*result = value_address;
*result = value;
return result;
}
Object** HandleScope::GetHandle(Isolate* isolate, Object* value) {
Address* HandleScope::GetHandle(Isolate* isolate, Address value) {
DCHECK(AllowHandleAllocation::IsAllowed());
HandleScopeData* data = isolate->handle_scope_data();
CanonicalHandleScope* canonical = data->canonical_scope;
......
......@@ -24,13 +24,14 @@ ASSERT_TRIVIALLY_COPYABLE(MaybeHandle<Object>);
#ifdef DEBUG
bool HandleBase::IsDereferenceAllowed(DereferenceCheckMode mode) const {
DCHECK_NOT_NULL(location_);
Object* object = *location_;
Object* object = reinterpret_cast<Object*>(*location_);
if (object->IsSmi()) return true;
HeapObject* heap_object = HeapObject::cast(object);
Isolate* isolate;
if (!Isolate::FromWritableHeapObject(heap_object, &isolate)) return true;
RootIndex root_index;
if (isolate->roots_table().IsRootHandleLocation(location_, &root_index) &&
if (isolate->roots_table().IsRootHandleLocation(
reinterpret_cast<Object**>(location_), &root_index) &&
RootsTable::IsImmortalImmovable(root_index)) {
return true;
}
......@@ -41,7 +42,7 @@ bool HandleBase::IsDereferenceAllowed(DereferenceCheckMode mode) const {
if (heap_object->IsCell()) return true;
if (heap_object->IsMap()) return true;
if (heap_object->IsInternalizedString()) return true;
return !isolate->IsDeferredHandle(location_);
return !isolate->IsDeferredHandle(reinterpret_cast<Object**>(location_));
}
return true;
}
......@@ -133,7 +134,7 @@ CanonicalHandleScope::CanonicalHandleScope(Isolate* isolate)
prev_canonical_scope_ = handle_scope_data->canonical_scope;
handle_scope_data->canonical_scope = this;
root_index_map_ = new RootIndexMap(isolate);
identity_map_ = new IdentityMap<Object**, ZoneAllocationPolicy>(
identity_map_ = new IdentityMap<Address*, ZoneAllocationPolicy>(
isolate->heap(), ZoneAllocationPolicy(&zone_));
canonical_level_ = handle_scope_data->level;
}
......@@ -145,26 +146,25 @@ CanonicalHandleScope::~CanonicalHandleScope() {
isolate_->handle_scope_data()->canonical_scope = prev_canonical_scope_;
}
Object** CanonicalHandleScope::Lookup(Object* object) {
Address* CanonicalHandleScope::Lookup(Address object) {
DCHECK_LE(canonical_level_, isolate_->handle_scope_data()->level);
if (isolate_->handle_scope_data()->level != canonical_level_) {
// We are in an inner handle scope. Do not canonicalize since we will leave
// this handle scope while still being in the canonical scope.
return HandleScope::CreateHandle(isolate_, object);
}
if (object->IsHeapObject()) {
if (Internals::HasHeapObjectTag(object)) {
RootIndex root_index;
if (root_index_map_->Lookup(HeapObject::cast(object), &root_index)) {
return isolate_->root_handle(root_index).location();
if (root_index_map_->Lookup(object, &root_index)) {
return isolate_->root_handle(root_index).location_as_address_ptr();
}
}
Object*** entry = identity_map_->Get(object);
Address** entry = identity_map_->Get(reinterpret_cast<Object*>(object));
if (*entry == nullptr) {
// Allocate new handle location.
*entry = HandleScope::CreateHandle(isolate_, object);
}
return reinterpret_cast<Object**>(*entry);
return *entry;
}
......
......@@ -29,8 +29,10 @@ class Object;
// Base class for Handle instantiations. Don't use directly.
class HandleBase {
public:
V8_INLINE explicit HandleBase(Object** location) : location_(location) {}
V8_INLINE explicit HandleBase(Object* object, Isolate* isolate);
V8_INLINE explicit HandleBase(Object** location)
: location_(reinterpret_cast<Address*>(location)) {}
V8_INLINE explicit HandleBase(Address* location) : location_(location) {}
V8_INLINE explicit HandleBase(Address object, Isolate* isolate);
// Check if this handle refers to the exact same object as the other handle.
V8_INLINE bool is_identical_to(const HandleBase that) const {
......@@ -52,13 +54,13 @@ class HandleBase {
protected:
// Provides the C++ dereference operator.
V8_INLINE Object* operator*() const {
V8_INLINE Address operator*() const {
SLOW_DCHECK(IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
return *location_;
}
// Returns the address to where the raw pointer is stored.
V8_INLINE Object** location() const {
V8_INLINE Address* location() const {
SLOW_DCHECK(location_ == nullptr ||
IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
return location_;
......@@ -74,7 +76,10 @@ class HandleBase {
}
#endif // DEBUG
Object** location_;
// This uses type Address* as opposed to a pointer type to a typed
// wrapper class, because it doesn't point to instances of such a
// wrapper class. Design overview: https://goo.gl/Ph4CGz
Address* location_;
};
......@@ -98,6 +103,11 @@ class Handle final : public HandleBase {
static_assert(std::is_convertible<T*, Object*>::value,
"static type violation");
}
V8_INLINE explicit Handle(Address* location) : HandleBase(location) {
// Type check:
static_assert(std::is_convertible<T*, Object*>::value,
"static type violation");
}
V8_INLINE Handle(T* object, Isolate* isolate);
......@@ -124,7 +134,7 @@ class Handle final : public HandleBase {
// 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());
return HandleBase::location();
}
template <typename S>
......@@ -186,12 +196,10 @@ class HandleScope {
V8_EXPORT_PRIVATE static int NumberOfHandles(Isolate* isolate);
// Create a new handle or lookup a canonical handle.
V8_INLINE static Object** GetHandle(Isolate* isolate, Object* value);
V8_INLINE static Address* GetHandle(Isolate* isolate, Address value);
// 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);
V8_INLINE static Address* CreateHandle(Isolate* isolate, Address value);
// Deallocates any extensions used by the current scope.
V8_EXPORT_PRIVATE static void DeleteExtensions(Isolate* isolate);
......@@ -263,12 +271,12 @@ class V8_EXPORT_PRIVATE CanonicalHandleScope final {
~CanonicalHandleScope();
private:
Object** Lookup(Object* object);
Address* Lookup(Address object);
Isolate* isolate_;
Zone zone_;
RootIndexMap* root_index_map_;
IdentityMap<Object**, ZoneAllocationPolicy>* identity_map_;
IdentityMap<Address*, ZoneAllocationPolicy>* identity_map_;
// Ordinary nested handle scopes within the current one are not canonical.
int canonical_level_;
// We may have nested canonical scopes. Handles are canonical within each one.
......
......@@ -22,7 +22,7 @@ IdentityMapBase::~IdentityMapBase() {
void IdentityMapBase::Clear() {
if (keys_) {
DCHECK(!is_iterable());
heap_->UnregisterStrongRoots(keys_);
heap_->UnregisterStrongRoots(reinterpret_cast<Object**>(keys_));
DeleteArray(keys_);
DeleteArray(values_);
keys_ = nullptr;
......@@ -43,9 +43,10 @@ void IdentityMapBase::DisableIteration() {
is_iterable_ = false;
}
int IdentityMapBase::ScanKeysFor(Object* address) const {
int IdentityMapBase::ScanKeysFor(Address address) const {
int start = Hash(address) & mask_;
Object* not_mapped = ReadOnlyRoots(heap_).not_mapped_symbol();
Address not_mapped =
reinterpret_cast<Address>(ReadOnlyRoots(heap_).not_mapped_symbol());
for (int index = start; index < capacity_; index++) {
if (keys_[index] == address) return index; // Found.
if (keys_[index] == not_mapped) return -1; // Not found.
......@@ -57,8 +58,9 @@ int IdentityMapBase::ScanKeysFor(Object* address) const {
return -1;
}
int IdentityMapBase::InsertKey(Object* address) {
Object* not_mapped = ReadOnlyRoots(heap_).not_mapped_symbol();
int IdentityMapBase::InsertKey(Address address) {
Address not_mapped =
reinterpret_cast<Address>(ReadOnlyRoots(heap_).not_mapped_symbol());
while (true) {
int start = Hash(address) & mask_;
int limit = capacity_ / 2;
......@@ -80,7 +82,8 @@ int IdentityMapBase::InsertKey(Object* address) {
bool IdentityMapBase::DeleteIndex(int index, void** deleted_value) {
if (deleted_value != nullptr) *deleted_value = values_[index];
Object* not_mapped = ReadOnlyRoots(heap_).not_mapped_symbol();
Address not_mapped =
reinterpret_cast<Address>(ReadOnlyRoots(heap_).not_mapped_symbol());
DCHECK_NE(keys_[index], not_mapped);
keys_[index] = not_mapped;
values_[index] = nullptr;
......@@ -97,7 +100,7 @@ bool IdentityMapBase::DeleteIndex(int index, void** deleted_value) {
int next_index = index;
for (;;) {
next_index = (next_index + 1) & mask_;
Object* key = keys_[next_index];
Address key = keys_[next_index];
if (key == not_mapped) break;
int expected_index = Hash(key) & mask_;
......@@ -118,7 +121,7 @@ bool IdentityMapBase::DeleteIndex(int index, void** deleted_value) {
return true;
}
int IdentityMapBase::Lookup(Object* key) const {
int IdentityMapBase::Lookup(Address key) const {
int index = ScanKeysFor(key);
if (index < 0 && gc_counter_ != heap_->gc_count()) {
// Miss; rehash if there was a GC, then lookup again.
......@@ -128,7 +131,7 @@ int IdentityMapBase::Lookup(Object* key) const {
return index;
}
int IdentityMapBase::LookupOrInsert(Object* key) {
int IdentityMapBase::LookupOrInsert(Address key) {
// Perform an optimistic lookup.
int index = ScanKeysFor(key);
if (index < 0) {
......@@ -140,17 +143,17 @@ int IdentityMapBase::LookupOrInsert(Object* key) {
return index;
}
int IdentityMapBase::Hash(Object* address) const {
CHECK_NE(address, ReadOnlyRoots(heap_).not_mapped_symbol());
uintptr_t raw_address = reinterpret_cast<uintptr_t>(address);
return static_cast<int>(hasher_(raw_address));
int IdentityMapBase::Hash(Address address) const {
CHECK_NE(address,
reinterpret_cast<Address>(ReadOnlyRoots(heap_).not_mapped_symbol()));
return static_cast<int>(hasher_(address));
}
// Searches this map for the given key using the object's address
// as the identity, returning:
// found => a pointer to the storage location for the value
// not found => a pointer to a new storage location for the value
IdentityMapBase::RawEntry IdentityMapBase::GetEntry(Object* key) {
IdentityMapBase::RawEntry IdentityMapBase::GetEntry(Address key) {
CHECK(!is_iterable()); // Don't allow insertion while iterable.
if (capacity_ == 0) {
// Allocate the initial storage for keys and values.
......@@ -158,13 +161,15 @@ IdentityMapBase::RawEntry IdentityMapBase::GetEntry(Object* key) {
mask_ = kInitialIdentityMapSize - 1;
gc_counter_ = heap_->gc_count();
keys_ = reinterpret_cast<Object**>(NewPointerArray(capacity_));
Object* not_mapped = ReadOnlyRoots(heap_).not_mapped_symbol();
keys_ = reinterpret_cast<Address*>(NewPointerArray(capacity_));
Address not_mapped =
reinterpret_cast<Address>(ReadOnlyRoots(heap_).not_mapped_symbol());
for (int i = 0; i < capacity_; i++) keys_[i] = not_mapped;
values_ = NewPointerArray(capacity_);
memset(values_, 0, sizeof(void*) * capacity_);
heap_->RegisterStrongRoots(keys_, keys_ + capacity_);
heap_->RegisterStrongRoots(reinterpret_cast<Object**>(keys_),
reinterpret_cast<Object**>(keys_ + capacity_));
}
int index = LookupOrInsert(key);
return &values_[index];
......@@ -174,7 +179,7 @@ IdentityMapBase::RawEntry IdentityMapBase::GetEntry(Object* key) {
// as the identity, returning:
// found => a pointer to the storage location for the value
// not found => {nullptr}
IdentityMapBase::RawEntry IdentityMapBase::FindEntry(Object* key) const {
IdentityMapBase::RawEntry IdentityMapBase::FindEntry(Address key) const {
// Don't allow find by key while iterable (might rehash).
CHECK(!is_iterable());
if (size_ == 0) return nullptr;
......@@ -186,7 +191,7 @@ IdentityMapBase::RawEntry IdentityMapBase::FindEntry(Object* key) const {
// Deletes the given key from the map using the object's address as the
// identity, returning true iff the key was found (in which case, the value
// argument will be set to the deleted entry's value).
bool IdentityMapBase::DeleteEntry(Object* key, void** deleted_value) {
bool IdentityMapBase::DeleteEntry(Address key, void** deleted_value) {
CHECK(!is_iterable()); // Don't allow deletion by key while iterable.
if (size_ == 0) return false;
int index = Lookup(key);
......@@ -194,10 +199,11 @@ bool IdentityMapBase::DeleteEntry(Object* key, void** deleted_value) {
return DeleteIndex(index, deleted_value);
}
Object* IdentityMapBase::KeyAtIndex(int index) const {
Address IdentityMapBase::KeyAtIndex(int index) const {
DCHECK_LE(0, index);
DCHECK_LT(index, capacity_);
DCHECK_NE(keys_[index], ReadOnlyRoots(heap_).not_mapped_symbol());
DCHECK_NE(keys_[index], reinterpret_cast<Address>(
ReadOnlyRoots(heap_).not_mapped_symbol()));
CHECK(is_iterable()); // Must be iterable to access by index;
return keys_[index];
}
......@@ -205,7 +211,8 @@ Object* IdentityMapBase::KeyAtIndex(int index) const {
IdentityMapBase::RawEntry IdentityMapBase::EntryAtIndex(int index) const {
DCHECK_LE(0, index);
DCHECK_LT(index, capacity_);
DCHECK_NE(keys_[index], ReadOnlyRoots(heap_).not_mapped_symbol());
DCHECK_NE(keys_[index], reinterpret_cast<Address>(
ReadOnlyRoots(heap_).not_mapped_symbol()));
CHECK(is_iterable()); // Must be iterable to access by index;
return &values_[index];
}
......@@ -214,7 +221,8 @@ int IdentityMapBase::NextIndex(int index) const {
DCHECK_LE(-1, index);
DCHECK_LE(index, capacity_);
CHECK(is_iterable()); // Must be iterable to access by index;
Object* not_mapped = ReadOnlyRoots(heap_).not_mapped_symbol();
Address not_mapped =
reinterpret_cast<Address>(ReadOnlyRoots(heap_).not_mapped_symbol());
for (++index; index < capacity_; ++index) {
if (keys_[index] != not_mapped) {
return index;
......@@ -228,11 +236,12 @@ void IdentityMapBase::Rehash() {
// Record the current GC counter.
gc_counter_ = heap_->gc_count();
// Assume that most objects won't be moved.
std::vector<std::pair<Object*, void*>> reinsert;
std::vector<std::pair<Address, void*>> reinsert;
// Search the table looking for keys that wouldn't be found with their
// current hashcode and evacuate them.
int last_empty = -1;
Object* not_mapped = ReadOnlyRoots(heap_).not_mapped_symbol();
Address not_mapped =
reinterpret_cast<Address>(ReadOnlyRoots(heap_).not_mapped_symbol());
for (int i = 0; i < capacity_; i++) {
if (keys_[i] == not_mapped) {
last_empty = i;
......@@ -240,7 +249,7 @@ void IdentityMapBase::Rehash() {
int pos = Hash(keys_[i]) & mask_;
if (pos <= last_empty || pos > i) {
// Evacuate an entry that is in the wrong place.
reinsert.push_back(std::pair<Object*, void*>(keys_[i], values_[i]));
reinsert.push_back(std::pair<Address, void*>(keys_[i], values_[i]));
keys_[i] = not_mapped;
values_[i] = nullptr;
last_empty = i;
......@@ -261,7 +270,7 @@ void IdentityMapBase::Resize(int new_capacity) {
// Resize the internal storage and reinsert all the key/value pairs.
DCHECK_GT(new_capacity, size_);
int old_capacity = capacity_;
Object** old_keys = keys_;
Address* old_keys = keys_;
void** old_values = values_;
capacity_ = new_capacity;
......@@ -269,8 +278,9 @@ void IdentityMapBase::Resize(int new_capacity) {
gc_counter_ = heap_->gc_count();
size_ = 0;
keys_ = reinterpret_cast<Object**>(NewPointerArray(capacity_));
Object* not_mapped = ReadOnlyRoots(heap_).not_mapped_symbol();
keys_ = reinterpret_cast<Address*>(NewPointerArray(capacity_));
Address not_mapped =
reinterpret_cast<Address>(ReadOnlyRoots(heap_).not_mapped_symbol());
for (int i = 0; i < capacity_; i++) keys_[i] = not_mapped;
values_ = NewPointerArray(capacity_);
memset(values_, 0, sizeof(void*) * capacity_);
......@@ -283,8 +293,9 @@ void IdentityMapBase::Resize(int new_capacity) {
}
// Unregister old keys and register new keys.
heap_->UnregisterStrongRoots(old_keys);
heap_->RegisterStrongRoots(keys_, keys_ + capacity_);
heap_->UnregisterStrongRoots(reinterpret_cast<Object**>(old_keys));
heap_->RegisterStrongRoots(reinterpret_cast<Object**>(keys_),
reinterpret_cast<Object**>(keys_ + capacity_));
// Delete old storage;
DeleteArray(old_keys);
......
......@@ -41,12 +41,12 @@ class IdentityMapBase {
is_iterable_(false) {}
virtual ~IdentityMapBase();
RawEntry GetEntry(Object* key);
RawEntry FindEntry(Object* key) const;
bool DeleteEntry(Object* key, void** deleted_value);
RawEntry GetEntry(Address key);
RawEntry FindEntry(Address key) const;
bool DeleteEntry(Address key, void** deleted_value);
void Clear();
Object* KeyAtIndex(int index) const;
Address KeyAtIndex(int index) const;
V8_EXPORT_PRIVATE RawEntry EntryAtIndex(int index) const;
V8_EXPORT_PRIVATE int NextIndex(int index) const;
......@@ -59,14 +59,14 @@ class IdentityMapBase {
private:
// Internal implementation should not be called directly by subclasses.
int ScanKeysFor(Object* address) const;
int InsertKey(Object* address);
int Lookup(Object* key) const;
int LookupOrInsert(Object* key);
int ScanKeysFor(Address address) const;
int InsertKey(Address address);
int Lookup(Address key) const;
int LookupOrInsert(Address key);
bool DeleteIndex(int index, void** deleted_value);
void Rehash();
void Resize(int new_capacity);
int Hash(Object* address) const;
int Hash(Address address) const;
base::hash<uintptr_t> hasher_;
Heap* heap_;
......@@ -74,7 +74,7 @@ class IdentityMapBase {
int size_;
int capacity_;
int mask_;
Object** keys_;
Address* keys_;
void** values_;
bool is_iterable_;
......@@ -100,25 +100,31 @@ class IdentityMap : public IdentityMapBase {
// found => a pointer to the storage location for the value
// not found => a pointer to a new storage location for the value
V* Get(Handle<Object> key) { return Get(*key); }
V* Get(Object* key) { return reinterpret_cast<V*>(GetEntry(key)); }
V* Get(Object* key) {
return reinterpret_cast<V*>(GetEntry(reinterpret_cast<Address>(key)));
}
// Searches this map for the given key using the object's address
// as the identity, returning:
// found => a pointer to the storage location for the value
// not found => {nullptr}
V* Find(Handle<Object> key) const { return Find(*key); }
V* Find(Object* key) const { return reinterpret_cast<V*>(FindEntry(key)); }
V* Find(Object* key) const {
return reinterpret_cast<V*>(FindEntry(reinterpret_cast<Address>(key)));
}
// Set the value for the given key.
void Set(Handle<Object> key, V v) { Set(*key, v); }
void Set(Object* key, V v) { *(reinterpret_cast<V*>(GetEntry(key))) = v; }
void Set(Object* key, V v) {
*(reinterpret_cast<V*>(GetEntry(reinterpret_cast<Address>(key)))) = v;
}
bool Delete(Handle<Object> key, V* deleted_value) {
return Delete(*key, deleted_value);
}
bool Delete(Object* key, V* deleted_value) {
void* v = nullptr;
bool deleted_something = DeleteEntry(key, &v);
bool deleted_something = DeleteEntry(reinterpret_cast<Address>(key), &v);
if (deleted_value != nullptr && deleted_something) {
*deleted_value = *reinterpret_cast<V*>(&v);
}
......@@ -137,7 +143,9 @@ class IdentityMap : public IdentityMapBase {
return *this;
}
Object* key() const { return map_->KeyAtIndex(index_); }
Object* key() const {
return reinterpret_cast<Object*>(map_->KeyAtIndex(index_));
}
V* entry() const {
return reinterpret_cast<V*>(map_->EntryAtIndex(index_));
}
......
......@@ -142,8 +142,9 @@ class IdentityMapTester : public HandleAndZoneScope {
void SimulateGCByIncrementingSmisBy(int shift) {
for (int i = 0; i < map.capacity_; i++) {
if (map.keys_[i]->IsSmi()) {
map.keys_[i] = Smi::FromInt(Smi::ToInt(map.keys_[i]) + shift);
Address key = map.keys_[i];
if (!Internals::HasHeapObjectTag(key)) {
map.keys_[i] = Internals::IntToSmi(Internals::SmiValue(key) + shift);
}
}
map.gc_counter_ = -1;
......
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